Switch to keyboard shortcuts based on event.key

This commit is contained in:
Henrik Giesel 2021-05-20 18:28:59 +02:00
parent 398cdc8992
commit ae19ed527d
11 changed files with 51 additions and 35 deletions

View file

@ -8,7 +8,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import { onDestroy } from "svelte"; import { onDestroy } from "svelte";
import { registerShortcut, getPlatformString } from "lib/shortcuts"; import { registerShortcut, getPlatformString } from "lib/shortcuts";
export let shortcut: string; export let shortcut: string[][];
export let optionalModifiers: Modifier[] | undefined = []; export let optionalModifiers: Modifier[] | undefined = [];
const shortcutLabel = getPlatformString(shortcut); const shortcutLabel = getPlatformString(shortcut);

View file

@ -36,7 +36,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
let registerCleanup: () => void; let registerCleanup: () => void;
onMount(() => { onMount(() => {
registerCleanup = registerShortcut(() => state.save(false), "Control+Enter"); registerCleanup = registerShortcut(() => state.save(false), [
["Control", "Enter"],
]);
}); });
onDestroy(() => registerCleanup?.()); onDestroy(() => registerCleanup?.());
</script> </script>

View file

@ -51,5 +51,5 @@ code {
// override the default down arrow colour in <select> elements // override the default down arrow colour in <select> elements
.night-mode select { .night-mode select {
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23FFFFFF' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e") background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23FFFFFF' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");
} }

View file

@ -42,7 +42,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</script> </script>
<WithShortcut <WithShortcut
shortcut="Control+Shift+KeyC" shortcut={[['Control', 'Shift', 'C']]}
optionalModifiers={['Alt']} optionalModifiers={['Alt']}
let:createShortcut let:createShortcut
let:shortcutLabel> let:shortcutLabel>

View file

@ -36,7 +36,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<ButtonGroup {api}> <ButtonGroup {api}>
<ButtonGroupItem> <ButtonGroupItem>
<WithShortcut shortcut="F7" let:createShortcut let:shortcutLabel> <WithShortcut shortcut={[['F7']]} let:createShortcut let:shortcutLabel>
<IconButton <IconButton
class="forecolor" class="forecolor"
tooltip={appendInParentheses(tr.editingSetForegroundColor(), shortcutLabel)} tooltip={appendInParentheses(tr.editingSetForegroundColor(), shortcutLabel)}
@ -48,7 +48,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</ButtonGroupItem> </ButtonGroupItem>
<ButtonGroupItem> <ButtonGroupItem>
<WithShortcut shortcut="F8" let:createShortcut let:shortcutLabel> <WithShortcut shortcut={[['F8']]} let:createShortcut let:shortcutLabel>
<ColorPicker <ColorPicker
tooltip={appendInParentheses(tr.editingChangeColor(), shortcutLabel)} tooltip={appendInParentheses(tr.editingChangeColor(), shortcutLabel)}
on:change={setWithCurrentColor} on:change={setWithCurrentColor}

View file

@ -26,7 +26,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<ButtonGroup {api}> <ButtonGroup {api}>
<ButtonGroupItem> <ButtonGroupItem>
<WithShortcut shortcut="Control+KeyB" let:createShortcut let:shortcutLabel> <WithShortcut
shortcut={[['Control', 'b']]}
let:createShortcut
let:shortcutLabel>
<WithState <WithState
key="bold" key="bold"
update={() => document.queryCommandState('bold')} update={() => document.queryCommandState('bold')}
@ -47,7 +50,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</ButtonGroupItem> </ButtonGroupItem>
<ButtonGroupItem> <ButtonGroupItem>
<WithShortcut shortcut="Control+KeyI" let:createShortcut let:shortcutLabel> <WithShortcut
shortcut={[['Control', 'i']]}
let:createShortcut
let:shortcutLabel>
<WithState <WithState
key="italic" key="italic"
update={() => document.queryCommandState('italic')} update={() => document.queryCommandState('italic')}
@ -68,7 +74,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</ButtonGroupItem> </ButtonGroupItem>
<ButtonGroupItem> <ButtonGroupItem>
<WithShortcut shortcut="Control+KeyU" let:createShortcut let:shortcutLabel> <WithShortcut
shortcut={[['Control', 'u']]}
let:createShortcut
let:shortcutLabel>
<WithState <WithState
key="underline" key="underline"
update={() => document.queryCommandState('underline')} update={() => document.queryCommandState('underline')}
@ -90,7 +99,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<ButtonGroupItem> <ButtonGroupItem>
<WithShortcut <WithShortcut
shortcut="Control+Shift+Equal" shortcut={[['Control', '+']]}
let:createShortcut let:createShortcut
let:shortcutLabel> let:shortcutLabel>
<WithState <WithState
@ -113,7 +122,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</ButtonGroupItem> </ButtonGroupItem>
<ButtonGroupItem> <ButtonGroupItem>
<WithShortcut shortcut="Control+Equal" let:createShortcut let:shortcutLabel> <WithShortcut
shortcut={[['Control', '=']]}
let:createShortcut
let:shortcutLabel>
<WithState <WithState
key="subscript" key="subscript"
update={() => document.queryCommandState('subscript')} update={() => document.queryCommandState('subscript')}
@ -134,7 +146,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</ButtonGroupItem> </ButtonGroupItem>
<ButtonGroupItem> <ButtonGroupItem>
<WithShortcut shortcut="Control+KeyR" let:createShortcut let:shortcutLabel> <WithShortcut
shortcut={[['Control', 'r']]}
let:createShortcut
let:shortcutLabel>
<IconButton <IconButton
tooltip={appendInParentheses(tr.editingRemoveFormatting(), shortcutLabel)} tooltip={appendInParentheses(tr.editingRemoveFormatting(), shortcutLabel)}
on:click={() => { on:click={() => {

View file

@ -25,7 +25,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</ButtonGroupItem> </ButtonGroupItem>
<ButtonGroupItem> <ButtonGroupItem>
<WithShortcut shortcut="Control+KeyL" let:createShortcut let:shortcutLabel> <WithShortcut
shortcut={[['Control', 'l']]}
let:createShortcut
let:shortcutLabel>
<LabelButton <LabelButton
disables={false} disables={false}
tooltip={`${tr.editingCustomizeCardTemplates()} (${shortcutLabel})`} tooltip={`${tr.editingCustomizeCardTemplates()} (${shortcutLabel})`}

View file

@ -10,7 +10,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import LabelButton from "components/LabelButton.svelte"; import LabelButton from "components/LabelButton.svelte";
</script> </script>
<WithShortcut shortcut="Control+Shift+KeyP" let:createShortcut let:shortcutLabel> <WithShortcut
shortcut={[['Control', 'Shift', 'P']]}
let:createShortcut
let:shortcutLabel>
<LabelButton <LabelButton
tooltip={tr.browsingPreviewSelectedCard({ val: shortcutLabel })} tooltip={tr.browsingPreviewSelectedCard({ val: shortcutLabel })}
disables={false} disables={false}

View file

@ -36,7 +36,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<ButtonGroup {api}> <ButtonGroup {api}>
<ButtonGroupItem> <ButtonGroupItem>
<WithShortcut shortcut="F3" let:createShortcut let:shortcutLabel> <WithShortcut shortcut={[['F3']]} let:createShortcut let:shortcutLabel>
<IconButton <IconButton
tooltip={appendInParentheses(tr.editingAttachPicturesaudiovideo(), shortcutLabel)} tooltip={appendInParentheses(tr.editingAttachPicturesaudiovideo(), shortcutLabel)}
on:click={onAttachment} on:click={onAttachment}
@ -47,7 +47,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</ButtonGroupItem> </ButtonGroupItem>
<ButtonGroupItem> <ButtonGroupItem>
<WithShortcut shortcut="F5" let:createShortcut let:shortcutLabel> <WithShortcut shortcut={[['F5']]} let:createShortcut let:shortcutLabel>
<IconButton <IconButton
tooltip={appendInParentheses(tr.editingRecordAudio(), shortcutLabel)} tooltip={appendInParentheses(tr.editingRecordAudio(), shortcutLabel)}
on:click={onRecord} on:click={onRecord}
@ -69,7 +69,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<DropdownMenu id={menuId}> <DropdownMenu id={menuId}>
<WithShortcut <WithShortcut
shortcut="Control+KeyM, KeyM" shortcut={[['Control', 'm'], ['m']]}
let:createShortcut let:createShortcut
let:shortcutLabel> let:shortcutLabel>
<DropdownItem <DropdownItem
@ -81,7 +81,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</WithShortcut> </WithShortcut>
<WithShortcut <WithShortcut
shortcut="Control+KeyM, KeyE" shortcut={[['Control', 'm'], ['e']]}
let:createShortcut let:createShortcut
let:shortcutLabel> let:shortcutLabel>
<DropdownItem <DropdownItem
@ -93,7 +93,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</WithShortcut> </WithShortcut>
<WithShortcut <WithShortcut
shortcut="Control+KeyM, KeyC" shortcut={[['Control', 'm'], ['c']]}
let:createShortcut let:createShortcut
let:shortcutLabel> let:shortcutLabel>
<DropdownItem <DropdownItem
@ -105,7 +105,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</WithShortcut> </WithShortcut>
<WithShortcut <WithShortcut
shortcut="Control+KeyT, KeyT" shortcut={[['Control', 't'], ['t']]}
let:createShortcut let:createShortcut
let:shortcutLabel> let:shortcutLabel>
<DropdownItem <DropdownItem
@ -117,7 +117,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</WithShortcut> </WithShortcut>
<WithShortcut <WithShortcut
shortcut="Control+KeyT, KeyE" shortcut={[['Control', 't'], ['e']]}
let:createShortcut let:createShortcut
let:shortcutLabel> let:shortcutLabel>
<DropdownItem <DropdownItem
@ -129,7 +129,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</WithShortcut> </WithShortcut>
<WithShortcut <WithShortcut
shortcut="Control+KeyT, KeyM" shortcut={[['Control', 't'], ['m']]}
let:createShortcut let:createShortcut
let:shortcutLabel> let:shortcutLabel>
<DropdownItem <DropdownItem
@ -145,7 +145,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<ButtonGroupItem> <ButtonGroupItem>
<WithShortcut <WithShortcut
shortcut="Control+Shift+KeyX" shortcut={[['Control', 'Shift', 'X']]}
let:createShortcut let:createShortcut
let:shortcutLabel> let:shortcutLabel>
<IconButton <IconButton

View file

@ -66,7 +66,7 @@ function updateFocus(evt: FocusEvent) {
registerShortcut( registerShortcut(
() => document.addEventListener("focusin", updateFocus, { once: true }), () => document.addEventListener("focusin", updateFocus, { once: true }),
"Tab", [["Tab"]],
["Shift"] ["Shift"]
); );

View file

@ -18,10 +18,6 @@ const platformModifiers = isApplePlatform()
? ["Meta", "Alt", "Shift", "Control"] ? ["Meta", "Alt", "Shift", "Control"]
: ["Control", "Alt", "Shift", "OS"]; : ["Control", "Alt", "Shift", "OS"];
function splitKeyCombinationString(keyCombinationString: string): string[][] {
return keyCombinationString.split(", ").map((segment) => segment.split("+"));
}
function modifiersToPlatformString(modifiers: string[]): string { function modifiersToPlatformString(modifiers: string[]): string {
const displayModifiers = isApplePlatform() const displayModifiers = isApplePlatform()
? ["^", "⌥", "⇧", "⌘"] ? ["^", "⌥", "⇧", "⌘"]
@ -70,14 +66,12 @@ function toPlatformString(modifiersAndKey: string[]): string {
)}${keyToPlatformString(modifiersAndKey[modifiersAndKey.length - 1])}`; )}${keyToPlatformString(modifiersAndKey[modifiersAndKey.length - 1])}`;
} }
export function getPlatformString(keyCombinationString: string): string { export function getPlatformString(keyCombination: string[][]): string {
return splitKeyCombinationString(keyCombinationString) return keyCombination.map(toPlatformString).join(", ");
.map(toPlatformString)
.join(", ");
} }
function checkKey(event: KeyboardEvent, key: string): boolean { function checkKey(event: KeyboardEvent, key: string): boolean {
return event.code === key; return event.key === key;
} }
function checkModifiers( function checkModifiers(
@ -139,10 +133,9 @@ function innerShortcut(
export function registerShortcut( export function registerShortcut(
callback: (event: KeyboardEvent) => void, callback: (event: KeyboardEvent) => void,
keyCombinationString: string, keyCombination: string[][],
optionalModifiers: Modifier[] = [] optionalModifiers: Modifier[] = []
): () => void { ): () => void {
const keyCombination = splitKeyCombinationString(keyCombinationString);
const [firstKey, ...restKeys] = keyCombination; const [firstKey, ...restKeys] = keyCombination;
const handler = (event: KeyboardEvent): void => { const handler = (event: KeyboardEvent): void => {