All files / src/desktop Shortcuts.ts

100% Statements 20/20
100% Branches 20/20
100% Functions 6/6
100% Lines 17/17

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63          4x             4x           4x     1259x 365x   1049x                     9x 7x 7x           9x 5x       62x 62x         1x       4x 141x 556x    
import type { KeyboardEvent } from 'react';
import { DEFAULT_SHORTCUTS, type Action } from '../platform/Desktop';
 
export type Shortcuts = Record<Action, string>;
 
export const ACTION_LABELS: Record<Action, string> = {
  selection: 'Select area',
  window: 'Window',
  screen: 'Screen',
  'copy-selection': 'Copy selected area',
};
 
const MAC_KEYS: Record<string, string> = {
  Control: '⌃',
  Alt: '⌥',
  Shift: '⇧',
  Super: '⌘',
};
const MODIFIERS = ['Control', 'Alt', 'Shift', 'Meta'];
 
export function formatShortcut(accelerator: string, mac: boolean) {
  if (!mac) return accelerator;
  return accelerator
    .split('+')
    .map((k) => MAC_KEYS[k] ?? k)
    .join('');
}
 
/** A key press as an accelerator such as "Alt+Shift+S", or undefined if it can't be a global shortcut. */
export function toAccelerator(
  e: Pick<
    KeyboardEvent,
    'key' | 'code' | 'ctrlKey' | 'altKey' | 'shiftKey' | 'metaKey'
  >,
) {
  if (MODIFIERS.includes(e.key)) return undefined;
  const key = e.code.replace(/^(Key|Digit)/, '');
  const mods = [
    e.ctrlKey && 'Control',
    e.altKey && 'Alt',
    e.shiftKey && 'Shift',
    e.metaKey && 'Super',
  ].filter(Boolean);
  if (!mods.length && !/^(F\d+|PrintScreen)$/.test(key)) return undefined;
  return [...mods, key].join('+');
}
 
export function loadShortcuts(): Shortcuts {
  try {
    return {
      ...DEFAULT_SHORTCUTS,
      ...JSON.parse(localStorage.getItem('shortcuts') ?? '{}'),
    };
  } catch {
    return DEFAULT_SHORTCUTS;
  }
}
 
export const isDefault = (s: Shortcuts) =>
  (Object.keys(DEFAULT_SHORTCUTS) as Action[]).every(
    (a) => s[a] === DEFAULT_SHORTCUTS[a],
  );