diff --git a/client/app/services/KeyboardShortcuts.js b/client/app/services/KeyboardShortcuts.js index c20d9c65ed..b8998986ac 100644 --- a/client/app/services/KeyboardShortcuts.js +++ b/client/app/services/KeyboardShortcuts.js @@ -2,7 +2,7 @@ import { each, filter, map, toLower, toString, trim, upperFirst, without } from import Mousetrap from "mousetrap"; import "mousetrap/plugins/global-bind/mousetrap-global-bind"; -const modKey = /Mac|iPod|iPhone|iPad/.test(navigator.platform) ? "Cmd" : "Ctrl"; +const modKey = /Mac|iPod|iPhone|iPad/.test(navigator.platform) ? "Command" : "Ctrl"; const altKey = /Mac|iPod|iPhone|iPad/.test(navigator.platform) ? "Option" : "Alt"; export function humanReadableShortcut(shortcut, limit = Infinity) { @@ -35,11 +35,17 @@ const KeyboardShortcuts = { bind: keymap => { each(keymap, (fn, key) => { - const keys = key + // Resolve platform-specific modifiers and remove duplicates. + const rawKeys = key .toLowerCase() .split(",") .map(trim); - each(keys, k => { + // Translate platform-specific modifiers and dedupe. + const transformed = rawKeys.map(k => + k.replace(/mod/g, modKey.toLowerCase()) + ); + const uniqueKeys = [...new Set(transformed)]; + each(uniqueKeys, k => { handlers[k] = [...without(handlers[k], fn), fn]; Mousetrap.bindGlobal(k, onShortcut); }); @@ -48,13 +54,18 @@ const KeyboardShortcuts = { unbind: keymap => { each(keymap, (fn, key) => { - const keys = key + const rawKeys = key .toLowerCase() .split(",") .map(trim); - each(keys, k => { + // Apply the same transformation as in bind + const transformed = rawKeys.map(k => + k.replace(/mod/g, modKey.toLowerCase()) + ); + const uniqueKeys = [...new Set(transformed)]; + each(uniqueKeys, k => { handlers[k] = without(handlers[k], fn); - if (handlers[k].length === 0) { + if (!handlers[k] || handlers[k].length === 0) { handlers[k] = undefined; Mousetrap.unbind(k); }