Work towards unifying KeyboardShortcuts and KeyBindingsDefaults #2 (#7674)

This commit is contained in:
Šimon Brandner
2022-01-31 15:55:45 +00:00
committed by GitHub
parent 7e5de9294c
commit a17d585a12
15 changed files with 450 additions and 732 deletions
+276 -168
View File
@@ -19,15 +19,104 @@ import { _td } from "../languageHandler";
import { isMac, Key } from "../Keyboard";
import { ISetting } from "../settings/Settings";
import SettingsStore from "../settings/SettingsStore";
import {
AutocompleteAction,
KeyBindingAction,
LabsAction,
MessageComposerAction,
NavigationAction,
RoomAction,
RoomListAction,
} from "../KeyBindingsManager";
export enum KeyBindingAction {
/** Send a message */
SendMessage = 'KeyBinding.sendMessageInComposer',
/** Go backwards through the send history and use the message in composer view */
SelectPrevSendHistory = 'KeyBinding.previousMessageInComposerHistory',
/** Go forwards through the send history */
SelectNextSendHistory = 'KeyBinding.nextMessageInComposerHistory',
/** Start editing the user's last sent message */
EditPrevMessage = 'KeyBinding.editPreviousMessage',
/** Start editing the user's next sent message */
EditNextMessage = 'KeyBinding.editNextMessage',
/** Cancel editing a message or cancel replying to a message */
CancelReplyOrEdit = 'KeyBinding.cancelReplyInComposer',
/** Set bold format the current selection */
FormatBold = 'KeyBinding.toggleBoldInComposer',
/** Set italics format the current selection */
FormatItalics = 'KeyBinding.toggleItalicsInComposer',
/** Format the current selection as quote */
FormatQuote = 'KeyBinding.toggleQuoteInComposer',
/** Undo the last editing */
EditUndo = 'KeyBinding.editUndoInComposer',
/** Redo editing */
EditRedo = 'KeyBinding.editRedoInComposer',
/** Insert new line */
NewLine = 'KeyBinding.newLineInComposer',
/** Move the cursor to the start of the message */
MoveCursorToStart = 'KeyBinding.jumpToStartInComposer',
/** Move the cursor to the end of the message */
MoveCursorToEnd = 'KeyBinding.jumpToEndInComposer',
/** Accepts chosen autocomplete selection */
CompleteAutocomplete = 'KeyBinding.completeAutocomplete',
/** Accepts chosen autocomplete selection or,
* if the autocompletion window is not shown, open the window and select the first selection */
ForceCompleteAutocomplete = 'KeyBinding.forceCompleteAutocomplete',
/** Move to the previous autocomplete selection */
PrevSelectionInAutocomplete = 'KeyBinding.previousOptionInAutoComplete',
/** Move to the next autocomplete selection */
NextSelectionInAutocomplete = 'KeyBinding.nextOptionInAutoComplete',
/** Close the autocompletion window */
CancelAutocomplete = 'KeyBinding.cancelAutoComplete',
/** Clear room list filter field */
ClearRoomFilter = 'KeyBinding.clearRoomFilter',
/** Navigate up/down in the room list */
PrevRoom = 'KeyBinding.downerRoom',
/** Navigate down in the room list */
NextRoom = 'KeyBinding.upperRoom',
/** Select room from the room list */
SelectRoomInRoomList = 'KeyBinding.selectRoomInRoomList',
/** Collapse room list section */
CollapseRoomListSection = 'KeyBinding.collapseSectionInRoomList',
/** Expand room list section, if already expanded, jump to first room in the selection */
ExpandRoomListSection = 'KeyBinding.expandSectionInRoomList',
/** Scroll up in the timeline */
ScrollUp = 'KeyBinding.scrollUpInTimeline',
/** Scroll down in the timeline */
ScrollDown = 'KeyBinding.scrollDownInTimeline',
/** Dismiss read marker and jump to bottom */
DismissReadMarker = 'KeyBinding.dismissReadMarkerAndJumpToBottom',
/** Jump to oldest unread message */
JumpToOldestUnread = 'KeyBinding.jumpToOldestUnreadMessage',
/** Upload a file */
UploadFile = 'KeyBinding.uploadFileToRoom',
/** Focus search message in a room (must be enabled) */
SearchInRoom = 'KeyBinding.searchInRoom',
/** Jump to the first (downloaded) message in the room */
JumpToFirstMessage = 'KeyBinding.jumpToFirstMessageInTimeline',
/** Jump to the latest message in the room */
JumpToLatestMessage = 'KeyBinding.jumpToLastMessageInTimeline',
/** Jump to room search (search for a room) */
FilterRooms = 'KeyBinding.filterRooms',
/** Toggle the space panel */
ToggleSpacePanel = 'KeyBinding.toggleSpacePanel',
/** Toggle the room side panel */
ToggleRoomSidePanel = 'KeyBinding.toggleRightPanel',
/** Toggle the user menu */
ToggleUserMenu = 'KeyBinding.toggleTopLeftMenu',
/** Toggle the short cut help dialog */
ShowKeyboardSettings = 'KeyBinding.showKeyBindingsSettings',
/** Got to the Element home screen */
GoToHome = 'KeyBinding.goToHomeView',
/** Select prev room */
SelectPrevRoom = 'KeyBinding.previousRoom',
/** Select next room */
SelectNextRoom = 'KeyBinding.nextRoom',
/** Select prev room with unread messages */
SelectPrevUnreadRoom = 'KeyBinding.previousUnreadRoom',
/** Select next room with unread messages */
SelectNextUnreadRoom = 'KeyBinding.nextUnreadRoom',
/** Toggle visibility of hidden events */
ToggleHiddenEventVisibility = 'KeyBinding.toggleHiddenEventVisibility',
}
type IKeyboardShortcuts = {
// TODO: We should figure out what to do with the keyboard shortcuts that are not handled by KeybindingManager
@@ -81,20 +170,20 @@ export const CATEGORIES: Record<CategoryName, ICategory> = {
[CategoryName.COMPOSER]: {
categoryLabel: _td("Composer"),
settingNames: [
MessageComposerAction.Send,
MessageComposerAction.FormatBold,
MessageComposerAction.FormatItalics,
MessageComposerAction.FormatQuote,
MessageComposerAction.NewLine,
MessageComposerAction.CancelEditing,
MessageComposerAction.EditNextMessage,
MessageComposerAction.EditPrevMessage,
MessageComposerAction.MoveCursorToStart,
MessageComposerAction.MoveCursorToEnd,
MessageComposerAction.SelectNextSendHistory,
MessageComposerAction.EditPrevMessage,
MessageComposerAction.EditUndo,
MessageComposerAction.EditRedo,
KeyBindingAction.SendMessage,
KeyBindingAction.NewLine,
KeyBindingAction.FormatBold,
KeyBindingAction.FormatItalics,
KeyBindingAction.FormatQuote,
KeyBindingAction.EditUndo,
KeyBindingAction.EditRedo,
KeyBindingAction.MoveCursorToStart,
KeyBindingAction.MoveCursorToEnd,
KeyBindingAction.CancelReplyOrEdit,
KeyBindingAction.EditNextMessage,
KeyBindingAction.EditPrevMessage,
KeyBindingAction.SelectNextSendHistory,
KeyBindingAction.SelectPrevSendHistory,
],
}, [CategoryName.CALLS]: {
categoryLabel: _td("Calls"),
@@ -105,54 +194,54 @@ export const CATEGORIES: Record<CategoryName, ICategory> = {
}, [CategoryName.ROOM]: {
categoryLabel: _td("Room"),
settingNames: [
RoomAction.DismissReadMarker,
RoomAction.JumpToOldestUnread,
RoomAction.UploadFile,
RoomAction.FocusSearch,
RoomAction.ScrollUp,
RoomAction.RoomScrollDown,
RoomAction.JumpToFirstMessage,
RoomAction.JumpToLatestMessage,
KeyBindingAction.SearchInRoom,
KeyBindingAction.UploadFile,
KeyBindingAction.DismissReadMarker,
KeyBindingAction.JumpToOldestUnread,
KeyBindingAction.ScrollUp,
KeyBindingAction.ScrollDown,
KeyBindingAction.JumpToFirstMessage,
KeyBindingAction.JumpToLatestMessage,
],
}, [CategoryName.ROOM_LIST]: {
categoryLabel: _td("Room List"),
settingNames: [
RoomListAction.SelectRoom,
RoomListAction.CollapseSection,
RoomListAction.ExpandSection,
RoomListAction.ClearSearch,
RoomListAction.NextRoom,
RoomListAction.PrevRoom,
KeyBindingAction.SelectRoomInRoomList,
KeyBindingAction.ClearRoomFilter,
KeyBindingAction.CollapseRoomListSection,
KeyBindingAction.ExpandRoomListSection,
KeyBindingAction.NextRoom,
KeyBindingAction.PrevRoom,
],
}, [CategoryName.NAVIGATION]: {
categoryLabel: _td("Navigation"),
settingNames: [
NavigationAction.ToggleUserMenu,
KeyBindingAction.ToggleUserMenu,
"KeyBinding.closeDialogOrContextMenu",
"KeyBinding.activateSelectedButton",
NavigationAction.ToggleRoomSidePanel,
NavigationAction.OpenShortCutDialog,
NavigationAction.GoToHome,
NavigationAction.SelectNextUnreadRoom,
NavigationAction.SelectPrevUnreadRoom,
NavigationAction.SelectNextRoom,
NavigationAction.SelectPrevRoom,
NavigationAction.ToggleSpacePanel,
NavigationAction.FocusRoomSearch,
KeyBindingAction.ToggleRoomSidePanel,
KeyBindingAction.ToggleSpacePanel,
KeyBindingAction.ShowKeyboardSettings,
KeyBindingAction.GoToHome,
KeyBindingAction.FilterRooms,
KeyBindingAction.SelectNextUnreadRoom,
KeyBindingAction.SelectPrevUnreadRoom,
KeyBindingAction.SelectNextRoom,
KeyBindingAction.SelectPrevRoom,
],
}, [CategoryName.AUTOCOMPLETE]: {
categoryLabel: _td("Autocomplete"),
settingNames: [
AutocompleteAction.Cancel,
AutocompleteAction.NextSelection,
AutocompleteAction.PrevSelection,
AutocompleteAction.Complete,
AutocompleteAction.ForceComplete,
KeyBindingAction.CancelAutocomplete,
KeyBindingAction.NextSelectionInAutocomplete,
KeyBindingAction.PrevSelectionInAutocomplete,
KeyBindingAction.CompleteAutocomplete,
KeyBindingAction.ForceCompleteAutocomplete,
],
}, [CategoryName.LABS]: {
categoryLabel: _td("Labs"),
settingNames: [
LabsAction.ToggleHiddenEventVisibility,
KeyBindingAction.ToggleHiddenEventVisibility,
],
},
};
@@ -161,73 +250,73 @@ export const CATEGORIES: Record<CategoryName, ICategory> = {
// to implement customizable keyboard shortcuts
// TODO: TravisR will fix this nightmare when the new version of the SettingsStore becomes a thing
const KEYBOARD_SHORTCUTS: IKeyboardShortcuts = {
[MessageComposerAction.FormatBold]: {
[KeyBindingAction.FormatBold]: {
default: {
ctrlOrCmdKey: true,
key: Key.B,
},
displayName: _td("Toggle Bold"),
},
[MessageComposerAction.FormatItalics]: {
[KeyBindingAction.FormatItalics]: {
default: {
ctrlOrCmdKey: true,
key: Key.I,
},
displayName: _td("Toggle Italics"),
},
[MessageComposerAction.FormatQuote]: {
[KeyBindingAction.FormatQuote]: {
default: {
ctrlOrCmdKey: true,
key: Key.GREATER_THAN,
},
displayName: _td("Toggle Quote"),
},
[MessageComposerAction.CancelEditing]: {
[KeyBindingAction.CancelReplyOrEdit]: {
default: {
key: Key.ESCAPE,
},
displayName: _td("Cancel replying to a message"),
},
[MessageComposerAction.EditNextMessage]: {
default: {
key: Key.ARROW_UP,
},
displayName: _td("Navigate to next message to edit"),
},
[MessageComposerAction.EditPrevMessage]: {
[KeyBindingAction.EditNextMessage]: {
default: {
key: Key.ARROW_DOWN,
},
displayName: _td("Navigate to next message to edit"),
},
[KeyBindingAction.EditPrevMessage]: {
default: {
key: Key.ARROW_UP,
},
displayName: _td("Navigate to previous message to edit"),
},
[MessageComposerAction.MoveCursorToStart]: {
[KeyBindingAction.MoveCursorToStart]: {
default: {
ctrlOrCmdKey: true,
key: Key.HOME,
},
displayName: _td("Jump to start of the composer"),
},
[MessageComposerAction.MoveCursorToEnd]: {
[KeyBindingAction.MoveCursorToEnd]: {
default: {
ctrlOrCmdKey: true,
key: Key.END,
},
displayName: _td("Jump to end of the composer"),
},
[MessageComposerAction.SelectNextSendHistory]: {
default: {
altKey: true,
ctrlKey: true,
key: Key.ARROW_UP,
},
displayName: _td("Navigate to next message in composer history"),
},
[MessageComposerAction.SelectPrevSendHistory]: {
[KeyBindingAction.SelectNextSendHistory]: {
default: {
altKey: true,
ctrlKey: true,
key: Key.ARROW_DOWN,
},
displayName: _td("Navigate to next message in composer history"),
},
[KeyBindingAction.SelectPrevSendHistory]: {
default: {
altKey: true,
ctrlKey: true,
key: Key.ARROW_UP,
},
displayName: _td("Navigate to previous message in composer history"),
},
"KeyBinding.toggleMicInCall": {
@@ -244,20 +333,20 @@ const KEYBOARD_SHORTCUTS: IKeyboardShortcuts = {
},
displayName: _td("Toggle webcam on/off"),
},
[RoomAction.DismissReadMarker]: {
[KeyBindingAction.DismissReadMarker]: {
default: {
key: Key.ESCAPE,
},
displayName: _td("Dismiss read marker and jump to bottom"),
},
[RoomAction.JumpToOldestUnread]: {
[KeyBindingAction.JumpToOldestUnread]: {
default: {
shiftKey: true,
key: Key.PAGE_UP,
},
displayName: _td("Jump to oldest unread message"),
},
[RoomAction.UploadFile]: {
[KeyBindingAction.UploadFile]: {
default: {
ctrlOrCmdKey: true,
shiftKey: true,
@@ -265,102 +354,83 @@ const KEYBOARD_SHORTCUTS: IKeyboardShortcuts = {
},
displayName: _td("Upload a file"),
},
[RoomAction.FocusSearch]: {
default: {
ctrlOrCmdKey: true,
key: Key.F,
},
displayName: _td("Search (must be enabled)"),
},
[RoomAction.ScrollUp]: {
[KeyBindingAction.ScrollUp]: {
default: {
key: Key.PAGE_UP,
},
displayName: _td("Scroll up in the timeline"),
},
[RoomAction.RoomScrollDown]: {
[KeyBindingAction.ScrollDown]: {
default: {
key: Key.PAGE_DOWN,
},
displayName: _td("Scroll down in the timeline"),
},
[NavigationAction.FocusRoomSearch]: {
[KeyBindingAction.FilterRooms]: {
default: {
ctrlOrCmdKey: true,
key: Key.K,
},
displayName: _td("Jump to room search"),
},
[RoomListAction.SelectRoom]: {
[KeyBindingAction.SelectRoomInRoomList]: {
default: {
key: Key.ENTER,
},
displayName: _td("Select room from the room list"),
},
[RoomListAction.CollapseSection]: {
[KeyBindingAction.CollapseRoomListSection]: {
default: {
key: Key.ARROW_LEFT,
},
displayName: _td("Collapse room list section"),
},
[RoomListAction.ExpandSection]: {
[KeyBindingAction.ExpandRoomListSection]: {
default: {
key: Key.ARROW_RIGHT,
},
displayName: _td("Expand room list section"),
},
[RoomListAction.ClearSearch]: {
[KeyBindingAction.ClearRoomFilter]: {
default: {
key: Key.ESCAPE,
},
displayName: _td("Clear room list filter field"),
},
[RoomListAction.NextRoom]: {
default: {
key: Key.ARROW_UP,
},
displayName: _td("Navigate up in the room list"),
},
[RoomListAction.PrevRoom]: {
[KeyBindingAction.NextRoom]: {
default: {
key: Key.ARROW_DOWN,
},
displayName: _td("Navigate up in the room list"),
},
[KeyBindingAction.PrevRoom]: {
default: {
key: Key.ARROW_UP,
},
displayName: _td("Navigate down in the room list"),
},
[NavigationAction.ToggleUserMenu]: {
[KeyBindingAction.ToggleUserMenu]: {
default: {
ctrlOrCmdKey: true,
key: Key.BACKTICK,
},
displayName: _td("Toggle the top left menu"),
},
"KeyBinding.closeDialogOrContextMenu": {
default: {
key: Key.ESCAPE,
},
displayName: _td("Close dialog or context menu"),
},
"KeyBinding.activateSelectedButton": {
default: {
key: Key.ENTER,
},
displayName: _td("Activate selected button"),
},
[NavigationAction.ToggleRoomSidePanel]: {
[KeyBindingAction.ToggleRoomSidePanel]: {
default: {
ctrlOrCmdKey: true,
key: Key.PERIOD,
},
displayName: _td("Toggle right panel"),
},
[NavigationAction.OpenShortCutDialog]: {
[KeyBindingAction.ShowKeyboardSettings]: {
default: {
ctrlOrCmdKey: true,
key: Key.SLASH,
},
displayName: _td("Open this settings tab"),
},
[NavigationAction.GoToHome]: {
[KeyBindingAction.GoToHome]: {
default: {
ctrlOrCmdKey: true,
altKey: !isMac,
@@ -369,55 +439,55 @@ const KEYBOARD_SHORTCUTS: IKeyboardShortcuts = {
},
displayName: _td("Go to Home View"),
},
[NavigationAction.SelectNextUnreadRoom]: {
[KeyBindingAction.SelectNextUnreadRoom]: {
default: {
shiftKey: true,
altKey: true,
key: Key.ARROW_UP,
key: Key.ARROW_DOWN,
},
displayName: _td("Next unread room or DM"),
},
[NavigationAction.SelectPrevUnreadRoom]: {
[KeyBindingAction.SelectPrevUnreadRoom]: {
default: {
shiftKey: true,
altKey: true,
key: Key.ARROW_DOWN,
key: Key.ARROW_UP,
},
displayName: _td("Previous unread room or DM"),
},
[NavigationAction.SelectNextRoom]: {
[KeyBindingAction.SelectNextRoom]: {
default: {
altKey: true,
key: Key.ARROW_DOWN,
},
displayName: _td("Next room or DM"),
},
[KeyBindingAction.SelectPrevRoom]: {
default: {
altKey: true,
key: Key.ARROW_UP,
},
displayName: _td("Next room or DM"),
},
[NavigationAction.SelectPrevRoom]: {
default: {
altKey: true,
key: Key.ARROW_DOWN,
},
displayName: _td("Previous room or DM"),
},
[AutocompleteAction.Cancel]: {
[KeyBindingAction.CancelAutocomplete]: {
default: {
key: Key.ESCAPE,
},
displayName: _td("Cancel autocomplete"),
},
[AutocompleteAction.NextSelection]: {
default: {
key: Key.ARROW_UP,
},
displayName: _td("Next autocomplete suggestion"),
},
[AutocompleteAction.PrevSelection]: {
[KeyBindingAction.NextSelectionInAutocomplete]: {
default: {
key: Key.ARROW_DOWN,
},
displayName: _td("Next autocomplete suggestion"),
},
[KeyBindingAction.PrevSelectionInAutocomplete]: {
default: {
key: Key.ARROW_UP,
},
displayName: _td("Previous autocomplete suggestion"),
},
[NavigationAction.ToggleSpacePanel]: {
[KeyBindingAction.ToggleSpacePanel]: {
default: {
ctrlOrCmdKey: true,
shiftKey: true,
@@ -425,7 +495,7 @@ const KEYBOARD_SHORTCUTS: IKeyboardShortcuts = {
},
displayName: _td("Toggle space panel"),
},
[LabsAction.ToggleHiddenEventVisibility]: {
[KeyBindingAction.ToggleHiddenEventVisibility]: {
default: {
ctrlOrCmdKey: true,
shiftKey: true,
@@ -433,61 +503,86 @@ const KEYBOARD_SHORTCUTS: IKeyboardShortcuts = {
},
displayName: _td("Toggle hidden event visibility"),
},
[RoomAction.JumpToFirstMessage]: {
[KeyBindingAction.JumpToFirstMessage]: {
default: {
key: Key.HOME,
ctrlKey: true,
},
displayName: _td("Jump to first message"),
},
[RoomAction.JumpToOldestUnread]: {
[KeyBindingAction.JumpToOldestUnread]: {
default: {
key: Key.END,
ctrlKey: true,
},
displayName: _td("Jump to last message"),
},
[MessageComposerAction.EditUndo]: {
[KeyBindingAction.EditUndo]: {
default: {
key: Key.Z,
ctrlOrCmdKey: true,
},
displayName: _td("Undo edit"),
},
[AutocompleteAction.Complete]: {
default: {
key: Key.ENTER,
},
displayName: _td("Complete"),
},
[AutocompleteAction.ForceComplete]: {
default: {
key: Key.TAB,
},
displayName: _td("Force complete"),
},
};
export const getKeyboardShortcuts = (): IKeyboardShortcuts => {
const keyboardShortcuts = KEYBOARD_SHORTCUTS;
// XXX: These have to be manually mirrored in KeyBindingDefaults
const getNonCustomizableShortcuts = (): IKeyboardShortcuts => {
const ctrlEnterToSend = SettingsStore.getValue('MessageComposerInput.ctrlEnterToSend');
keyboardShortcuts[MessageComposerAction.Send] = {
default: {
key: Key.ENTER,
ctrlOrCmdKey: ctrlEnterToSend,
return {
[KeyBindingAction.SendMessage]: {
default: {
key: Key.ENTER,
ctrlOrCmdKey: ctrlEnterToSend,
},
displayName: _td("Send message"),
},
displayName: _td("Send message"),
[KeyBindingAction.NewLine]: {
default: {
key: Key.ENTER,
shiftKey: !ctrlEnterToSend,
},
displayName: _td("New line"),
},
[KeyBindingAction.CompleteAutocomplete]: {
default: {
key: Key.ENTER,
},
displayName: _td("Complete"),
},
[KeyBindingAction.ForceCompleteAutocomplete]: {
default: {
key: Key.TAB,
},
displayName: _td("Force complete"),
},
[KeyBindingAction.SearchInRoom]: {
default: {
ctrlOrCmdKey: true,
key: Key.F,
},
displayName: _td("Search (must be enabled)"),
},
"KeyBinding.closeDialogOrContextMenu": {
default: {
key: Key.ESCAPE,
},
displayName: _td("Close dialog or context menu"),
},
"KeyBinding.activateSelectedButton": {
default: {
key: Key.ENTER,
},
displayName: _td("Activate selected button"),
},
};
};
};
keyboardShortcuts[MessageComposerAction.NewLine] = {
default: {
key: Key.ENTER,
shiftKey: !ctrlEnterToSend,
},
displayName: _td("New line"),
};
keyboardShortcuts[MessageComposerAction.EditRedo] = {
export const getCustomizableShortcuts = (): IKeyboardShortcuts => {
const keyboardShortcuts = KEYBOARD_SHORTCUTS;
keyboardShortcuts[KeyBindingAction.EditRedo] = {
default: {
key: isMac ? Key.Z : Key.Y,
ctrlOrCmdKey: true,
@@ -499,6 +594,19 @@ export const getKeyboardShortcuts = (): IKeyboardShortcuts => {
return keyboardShortcuts;
};
export const getKeyboardShortcuts = (): IKeyboardShortcuts => {
const entries = [
...Object.entries(getNonCustomizableShortcuts()),
...Object.entries(getCustomizableShortcuts()),
];
const keyboardShortcuts: IKeyboardShortcuts = {};
for (const [key, value] of entries) {
keyboardShortcuts[key] = value;
}
return keyboardShortcuts;
};
export const registerShortcut = (shortcutName: string, categoryName: CategoryName, shortcut: ISetting): void => {
KEYBOARD_SHORTCUTS[shortcutName] = shortcut;
CATEGORIES[categoryName].settingNames.push(shortcutName);