Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Add customizable keyboard shortcuts #8040

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion res/css/views/settings/tabs/user/_KeyboardUserSettingsTab.scss
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,16 @@ limitations under the License.
.mx_KeyboardUserSettingsTab .mx_SettingsTab_section {
.mx_KeyboardShortcut_shortcutRow {
display: flex;
justify-content: space-between;
align-items: center;

.mx_KeyboardShortcut_shortcutRow_displayName {
margin-right: auto;
}

.mx_AccessibleButton {
margin: 0 4px;
}

margin: 4px 0;
}
}
4 changes: 2 additions & 2 deletions src/KeyBindingsDefaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ import {
CategoryName,
KeyBindingAction,
} from "./accessibility/KeyboardShortcuts";
import { getKeyboardShortcuts } from "./accessibility/KeyboardShortcutUtils";
import { getKeyboardShortcutValue } from "./accessibility/KeyboardShortcutUtils";

export const getBindingsByCategory = (category: CategoryName): KeyBinding[] => {
return CATEGORIES[category].settingNames.reduce((bindings, name) => {
const value = getKeyboardShortcuts()[name]?.default;
const value = getKeyboardShortcutValue(name, false);
if (value) {
bindings.push({
action: name as KeyBindingAction,
Expand Down
69 changes: 34 additions & 35 deletions src/accessibility/KeyboardShortcutUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,19 @@ import {
DIGITS,
IKeyboardShortcuts,
KeyBindingAction,
KEYBOARD_SHORTCUTS,
MAC_ONLY_SHORTCUTS,
} from "./KeyboardShortcuts";

const isShortcutEnabled = (name): boolean => {
const overrideBrowserShortcuts = PlatformPeg.get().overrideBrowserShortcuts();

if (!SettingsStore.isEnabled(name)) return false;
if (MAC_ONLY_SHORTCUTS.includes(name) && !isMac) return false;
if (DESKTOP_SHORTCUTS.includes(name) && !overrideBrowserShortcuts) return false;

return true;
};

/**
* This function gets the keyboard shortcuts that should be presented in the UI
* but they shouldn't be consumed by KeyBindingDefaults. That means that these
Expand All @@ -43,32 +52,37 @@ const getUIOnlyShortcuts = (): IKeyboardShortcuts => {
ctrlOrCmdKey: ctrlEnterToSend,
},
displayName: _td("Send message"),
hideEditUI: true,
},
[KeyBindingAction.NewLine]: {
default: {
key: Key.ENTER,
shiftKey: !ctrlEnterToSend,
},
displayName: _td("New line"),
hideEditUI: true,
},
[KeyBindingAction.CompleteAutocomplete]: {
default: {
key: Key.ENTER,
},
displayName: _td("Complete"),
hideEditUI: true,
},
[KeyBindingAction.ForceCompleteAutocomplete]: {
default: {
key: Key.TAB,
},
displayName: _td("Force complete"),
hideEditUI: true,
},
[KeyBindingAction.SearchInRoom]: {
default: {
ctrlOrCmdKey: true,
key: Key.F,
},
displayName: _td("Search (must be enabled)"),
hideEditUI: true,
},
};

Expand All @@ -82,50 +96,35 @@ const getUIOnlyShortcuts = (): IKeyboardShortcuts => {
key: DIGITS,
},
displayName: _td("Switch to space by number"),
hideEditUI: true,
};
}

return keyboardShortcuts;
};

/**
* This function gets keyboard shortcuts that can be consumed by the KeyBindingDefaults.
*/
export const getKeyboardShortcuts = (): IKeyboardShortcuts => {
const overrideBrowserShortcuts = PlatformPeg.get().overrideBrowserShortcuts();

return Object.keys(KEYBOARD_SHORTCUTS).filter((k: KeyBindingAction) => {
if (KEYBOARD_SHORTCUTS[k]?.controller?.settingDisabled) return false;
if (MAC_ONLY_SHORTCUTS.includes(k) && !isMac) return false;
if (DESKTOP_SHORTCUTS.includes(k) && !overrideBrowserShortcuts) return false;
export const getKeyboardShortcutValue = (name: string, fallbackToUIOnly = true): KeyCombo | null => {
if (!isShortcutEnabled(name)) return null;

return true;
}).reduce((o, key) => {
o[key] = KEYBOARD_SHORTCUTS[key];
return o;
}, {} as IKeyboardShortcuts);
try {
return SettingsStore.getValue("feature_customizable_keybindings")
? SettingsStore.getValue(name)
: SettingsStore.getDefaultValue(name);
} catch (error) {
if (!fallbackToUIOnly) return null;
return getUIOnlyShortcuts()[name]?.default;
}
};

/**
* Gets keyboard shortcuts that should be presented to the user in the UI.
*/
export const getKeyboardShortcutsForUI = (): IKeyboardShortcuts => {
const entries = [
...Object.entries(getUIOnlyShortcuts()),
...Object.entries(getKeyboardShortcuts()),
];

return entries.reduce((acc, [key, value]) => {
acc[key] = value;
return acc;
}, {} as IKeyboardShortcuts);
};
export const getKeyboardShortcutDisplayName = (name: string): string | null => {
if (!isShortcutEnabled(name)) return null;

export const getKeyboardShortcutValue = (name: string): KeyCombo => {
return getKeyboardShortcutsForUI()[name]?.default;
const keyboardShortcutDisplayName = SettingsStore.getDisplayName(name) ?? getUIOnlyShortcuts()[name]?.displayName;
return keyboardShortcutDisplayName && _t(keyboardShortcutDisplayName);
};

export const getKeyboardShortcutDisplayName = (name: string): string | null => {
const keyboardShortcutDisplayName = getKeyboardShortcutsForUI()[name]?.displayName;
return keyboardShortcutDisplayName && _t(keyboardShortcutDisplayName);
export const getKeyboardShortcutHideEditUI = (name: string): boolean | null => {
if (!isShortcutEnabled(name)) return null;

return SettingsStore.getHideEditUI(name) ?? false;
};
Loading