You've already forked matrix-react-sdk
							
							
				mirror of
				https://github.com/matrix-org/matrix-react-sdk.git
				synced 2025-11-03 00:33:22 +03:00 
			
		
		
		
	Split KeyAction into multiple enums
This gives some additional type safety and makes enum member usage more clear.
This commit is contained in:
		@@ -1,24 +1,8 @@
 | 
				
			|||||||
import { isMac, Key } from './Keyboard';
 | 
					import { isMac, Key } from './Keyboard';
 | 
				
			||||||
import SettingsStore from './settings/SettingsStore';
 | 
					import SettingsStore from './settings/SettingsStore';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export enum KeyBindingContext {
 | 
					/** Actions for the chat message composer component */
 | 
				
			||||||
    /** Key bindings for the chat message composer component */
 | 
					export enum MessageComposerAction {
 | 
				
			||||||
    MessageComposer = 'MessageComposer',
 | 
					 | 
				
			||||||
    /** Key bindings for text editing autocompletion */
 | 
					 | 
				
			||||||
    AutoComplete = 'AutoComplete',
 | 
					 | 
				
			||||||
    /** Left room list sidebar */
 | 
					 | 
				
			||||||
    RoomList = 'RoomList',
 | 
					 | 
				
			||||||
    /** Current room view */
 | 
					 | 
				
			||||||
    Room = 'Room',
 | 
					 | 
				
			||||||
    /** Shortcuts to navigate do various menus / dialogs / screens */
 | 
					 | 
				
			||||||
    Navigation = 'Navigation',
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export enum KeyAction {
 | 
					 | 
				
			||||||
    None = 'None',
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // SendMessageComposer actions:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /** Send a message */
 | 
					    /** Send a message */
 | 
				
			||||||
    Send = 'Send',
 | 
					    Send = 'Send',
 | 
				
			||||||
    /** Go backwards through the send history and use the message in composer view */
 | 
					    /** Go backwards through the send history and use the message in composer view */
 | 
				
			||||||
@@ -46,70 +30,74 @@ export enum KeyAction {
 | 
				
			|||||||
    NewLine = 'NewLine',
 | 
					    NewLine = 'NewLine',
 | 
				
			||||||
    MoveCursorToStart = 'MoveCursorToStart',
 | 
					    MoveCursorToStart = 'MoveCursorToStart',
 | 
				
			||||||
    MoveCursorToEnd = 'MoveCursorToEnd',
 | 
					    MoveCursorToEnd = 'MoveCursorToEnd',
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Autocomplete
 | 
					/** Actions for text editing autocompletion */
 | 
				
			||||||
 | 
					export enum AutocompleteAction {
 | 
				
			||||||
    /** Apply the current autocomplete selection */
 | 
					    /** Apply the current autocomplete selection */
 | 
				
			||||||
    AutocompleteApply = 'AutocompleteApply',
 | 
					    ApplySelection = 'ApplySelection',
 | 
				
			||||||
    /** Cancel autocompletion */
 | 
					    /** Cancel autocompletion */
 | 
				
			||||||
    AutocompleteCancel = 'AutocompleteCancel',
 | 
					    Cancel = 'Cancel',
 | 
				
			||||||
    /** Move to the previous autocomplete selection */
 | 
					    /** Move to the previous autocomplete selection */
 | 
				
			||||||
    AutocompletePrevSelection = 'AutocompletePrevSelection',
 | 
					    PrevSelection = 'PrevSelection',
 | 
				
			||||||
    /** Move to the next autocomplete selection */
 | 
					    /** Move to the next autocomplete selection */
 | 
				
			||||||
    AutocompleteNextSelection = 'AutocompleteNextSelection',
 | 
					    NextSelection = 'NextSelection',
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
    // Room list
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Actions for the left room list sidebar */
 | 
				
			||||||
 | 
					export enum RoomListAction {
 | 
				
			||||||
    /** Clear room list filter field */
 | 
					    /** Clear room list filter field */
 | 
				
			||||||
    RoomListClearSearch = 'RoomListClearSearch',
 | 
					    ClearSearch = 'ClearSearch',
 | 
				
			||||||
    /** Navigate up/down in the room list */
 | 
					    /** Navigate up/down in the room list */
 | 
				
			||||||
    RoomListPrevRoom = 'RoomListPrevRoom',
 | 
					    PrevRoom = 'PrevRoom',
 | 
				
			||||||
    /** Navigate down in the room list */
 | 
					    /** Navigate down in the room list */
 | 
				
			||||||
    RoomListNextRoom = 'RoomListNextRoom',
 | 
					    NextRoom = 'NextRoom',
 | 
				
			||||||
    /** Select room from the room list */
 | 
					    /** Select room from the room list */
 | 
				
			||||||
    RoomListSelectRoom = 'RoomListSelectRoom',
 | 
					    SelectRoom = 'SelectRoom',
 | 
				
			||||||
    /** Collapse room list section */
 | 
					    /** Collapse room list section */
 | 
				
			||||||
    RoomListCollapseSection = 'RoomListCollapseSection',
 | 
					    CollapseSection = 'CollapseSection',
 | 
				
			||||||
    /** Expand room list section, if already expanded, jump to first room in the selection */
 | 
					    /** Expand room list section, if already expanded, jump to first room in the selection */
 | 
				
			||||||
    RoomListExpandSection = 'RoomListExpandSection',
 | 
					    ExpandSection = 'ExpandSection',
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Room
 | 
					/** Actions for the current room view */
 | 
				
			||||||
 | 
					export enum RoomAction {
 | 
				
			||||||
    /** Jump to room search */
 | 
					    /** Jump to room search (search for a room)*/
 | 
				
			||||||
    RoomFocusRoomSearch = 'RoomFocusRoomSearch',
 | 
					    FocusRoomSearch = 'FocusRoomSearch', // TODO: move to NavigationAction?
 | 
				
			||||||
    /** Scroll up in the timeline */
 | 
					    /** Scroll up in the timeline */
 | 
				
			||||||
    RoomScrollUp = 'RoomScrollUp',
 | 
					    ScrollUp = 'ScrollUp',
 | 
				
			||||||
    /** Scroll down in the timeline */
 | 
					    /** Scroll down in the timeline */
 | 
				
			||||||
    RoomScrollDown = 'RoomScrollDown',
 | 
					    RoomScrollDown = 'RoomScrollDown',
 | 
				
			||||||
    /** Dismiss read marker and jump to bottom */
 | 
					    /** Dismiss read marker and jump to bottom */
 | 
				
			||||||
    RoomDismissReadMarker = 'RoomDismissReadMarker',
 | 
					    DismissReadMarker = 'DismissReadMarker',
 | 
				
			||||||
    /* Upload a file */
 | 
					    /* Upload a file */
 | 
				
			||||||
    RoomUploadFile = 'RoomUploadFile',
 | 
					    UploadFile = 'UploadFile',
 | 
				
			||||||
    /* Search (must be enabled) */
 | 
					    /* Focus search message in a room (must be enabled) */
 | 
				
			||||||
    RoomSearch = 'RoomSearch',
 | 
					    FocusSearch = 'FocusSearch',
 | 
				
			||||||
    /* Jump to the first (downloaded) message in the room */
 | 
					    /* Jump to the first (downloaded) message in the room */
 | 
				
			||||||
    RoomJumpToFirstMessage = 'RoomJumpToFirstMessage',
 | 
					    JumpToFirstMessage = 'JumpToFirstMessage',
 | 
				
			||||||
    /* Jump to the latest message in the room */
 | 
					    /* Jump to the latest message in the room */
 | 
				
			||||||
    RoomJumpToLatestMessage = 'RoomJumpToLatestMessage',
 | 
					    JumpToLatestMessage = 'JumpToLatestMessage',
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
    // Navigation
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Actions for navigating do various menus / dialogs / screens */
 | 
				
			||||||
 | 
					export enum NavigationAction {
 | 
				
			||||||
    /** Toggle the room side panel */
 | 
					    /** Toggle the room side panel */
 | 
				
			||||||
    NavToggleRoomSidePanel = 'NavToggleRoomSidePanel',
 | 
					    ToggleRoomSidePanel = 'ToggleRoomSidePanel',
 | 
				
			||||||
    /** Toggle the user menu */
 | 
					    /** Toggle the user menu */
 | 
				
			||||||
    NavToggleUserMenu = 'NavToggleUserMenu',
 | 
					    ToggleUserMenu = 'ToggleUserMenu',
 | 
				
			||||||
    /* Toggle the short cut help dialog */
 | 
					    /* Toggle the short cut help dialog */
 | 
				
			||||||
    NavToggleShortCutDialog = 'NavToggleShortCutDialog',
 | 
					    ToggleShortCutDialog = 'ToggleShortCutDialog',
 | 
				
			||||||
    /* Got to the Element home screen */
 | 
					    /* Got to the Element home screen */
 | 
				
			||||||
    NavGoToHome = 'NavGoToHome',
 | 
					    GoToHome = 'GoToHome',
 | 
				
			||||||
    /* Select prev room */
 | 
					    /* Select prev room */
 | 
				
			||||||
    NavSelectPrevRoom = 'NavSelectPrevRoom',
 | 
					    SelectPrevRoom = 'SelectPrevRoom',
 | 
				
			||||||
    /* Select next room */
 | 
					    /* Select next room */
 | 
				
			||||||
    NavSelectNextRoom = 'NavSelectNextRoom',
 | 
					    SelectNextRoom = 'SelectNextRoom',
 | 
				
			||||||
    /* Select prev room with unread messages*/
 | 
					    /* Select prev room with unread messages*/
 | 
				
			||||||
    NavSelectPrevUnreadRoom = 'NavSelectPrevUnreadRoom',
 | 
					    SelectPrevUnreadRoom = 'SelectPrevUnreadRoom',
 | 
				
			||||||
    /* Select next room with unread messages*/
 | 
					    /* Select next room with unread messages*/
 | 
				
			||||||
    NavSelectNextUnreadRoom = 'NavSelectNextUnreadRoom',
 | 
					    SelectNextUnreadRoom = 'SelectNextUnreadRoom',
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@@ -129,15 +117,15 @@ export type KeyCombo = {
 | 
				
			|||||||
    shiftKey?: boolean;
 | 
					    shiftKey?: boolean;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type KeyBinding = {
 | 
					export type KeyBinding<T extends string> = {
 | 
				
			||||||
    action: KeyAction;
 | 
					    action: T;
 | 
				
			||||||
    keyCombo: KeyCombo;
 | 
					    keyCombo: KeyCombo;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const messageComposerBindings = (): KeyBinding[] => {
 | 
					const messageComposerBindings = (): KeyBinding<MessageComposerAction>[] => {
 | 
				
			||||||
    const bindings: KeyBinding[] = [
 | 
					    const bindings: KeyBinding<MessageComposerAction>[] = [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.SelectPrevSendHistory,
 | 
					            action: MessageComposerAction.SelectPrevSendHistory,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.ARROW_UP,
 | 
					                key: Key.ARROW_UP,
 | 
				
			||||||
                altKey: true,
 | 
					                altKey: true,
 | 
				
			||||||
@@ -145,7 +133,7 @@ const messageComposerBindings = (): KeyBinding[] => {
 | 
				
			|||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.SelectNextSendHistory,
 | 
					            action: MessageComposerAction.SelectNextSendHistory,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.ARROW_DOWN,
 | 
					                key: Key.ARROW_DOWN,
 | 
				
			||||||
                altKey: true,
 | 
					                altKey: true,
 | 
				
			||||||
@@ -153,39 +141,39 @@ const messageComposerBindings = (): KeyBinding[] => {
 | 
				
			|||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.EditPrevMessage,
 | 
					            action: MessageComposerAction.EditPrevMessage,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.ARROW_UP,
 | 
					                key: Key.ARROW_UP,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.EditNextMessage,
 | 
					            action: MessageComposerAction.EditNextMessage,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.ARROW_DOWN,
 | 
					                key: Key.ARROW_DOWN,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.CancelEditing,
 | 
					            action: MessageComposerAction.CancelEditing,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.ESCAPE,
 | 
					                key: Key.ESCAPE,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.FormatBold,
 | 
					            action: MessageComposerAction.FormatBold,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.B,
 | 
					                key: Key.B,
 | 
				
			||||||
                ctrlOrCmd: true,
 | 
					                ctrlOrCmd: true,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.FormatItalics,
 | 
					            action: MessageComposerAction.FormatItalics,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.I,
 | 
					                key: Key.I,
 | 
				
			||||||
                ctrlOrCmd: true,
 | 
					                ctrlOrCmd: true,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.FormatQuote,
 | 
					            action: MessageComposerAction.FormatQuote,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.GREATER_THAN,
 | 
					                key: Key.GREATER_THAN,
 | 
				
			||||||
                ctrlOrCmd: true,
 | 
					                ctrlOrCmd: true,
 | 
				
			||||||
@@ -193,7 +181,7 @@ const messageComposerBindings = (): KeyBinding[] => {
 | 
				
			|||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.EditUndo,
 | 
					            action: MessageComposerAction.EditUndo,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.Z,
 | 
					                key: Key.Z,
 | 
				
			||||||
                ctrlOrCmd: true,
 | 
					                ctrlOrCmd: true,
 | 
				
			||||||
@@ -201,14 +189,14 @@ const messageComposerBindings = (): KeyBinding[] => {
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
        // Note: the following two bindings also work with just HOME and END, add them here?
 | 
					        // Note: the following two bindings also work with just HOME and END, add them here?
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.MoveCursorToStart,
 | 
					            action: MessageComposerAction.MoveCursorToStart,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.HOME,
 | 
					                key: Key.HOME,
 | 
				
			||||||
                ctrlOrCmd: true,
 | 
					                ctrlOrCmd: true,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.MoveCursorToEnd,
 | 
					            action: MessageComposerAction.MoveCursorToEnd,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.END,
 | 
					                key: Key.END,
 | 
				
			||||||
                ctrlOrCmd: true,
 | 
					                ctrlOrCmd: true,
 | 
				
			||||||
@@ -217,7 +205,7 @@ const messageComposerBindings = (): KeyBinding[] => {
 | 
				
			|||||||
    ];
 | 
					    ];
 | 
				
			||||||
    if (isMac) {
 | 
					    if (isMac) {
 | 
				
			||||||
        bindings.push({
 | 
					        bindings.push({
 | 
				
			||||||
            action: KeyAction.EditRedo,
 | 
					            action: MessageComposerAction.EditRedo,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.Z,
 | 
					                key: Key.Z,
 | 
				
			||||||
                ctrlOrCmd: true,
 | 
					                ctrlOrCmd: true,
 | 
				
			||||||
@@ -226,7 +214,7 @@ const messageComposerBindings = (): KeyBinding[] => {
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        bindings.push({
 | 
					        bindings.push({
 | 
				
			||||||
            action: KeyAction.EditRedo,
 | 
					            action: MessageComposerAction.EditRedo,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.Y,
 | 
					                key: Key.Y,
 | 
				
			||||||
                ctrlOrCmd: true,
 | 
					                ctrlOrCmd: true,
 | 
				
			||||||
@@ -235,27 +223,27 @@ const messageComposerBindings = (): KeyBinding[] => {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    if (SettingsStore.getValue('MessageComposerInput.ctrlEnterToSend')) {
 | 
					    if (SettingsStore.getValue('MessageComposerInput.ctrlEnterToSend')) {
 | 
				
			||||||
        bindings.push({
 | 
					        bindings.push({
 | 
				
			||||||
            action: KeyAction.Send,
 | 
					            action: MessageComposerAction.Send,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.ENTER,
 | 
					                key: Key.ENTER,
 | 
				
			||||||
                ctrlOrCmd: true,
 | 
					                ctrlOrCmd: true,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        bindings.push({
 | 
					        bindings.push({
 | 
				
			||||||
            action: KeyAction.NewLine,
 | 
					            action: MessageComposerAction.NewLine,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.ENTER,
 | 
					                key: Key.ENTER,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        bindings.push({
 | 
					        bindings.push({
 | 
				
			||||||
            action: KeyAction.Send,
 | 
					            action: MessageComposerAction.Send,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.ENTER,
 | 
					                key: Key.ENTER,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        bindings.push({
 | 
					        bindings.push({
 | 
				
			||||||
            action: KeyAction.NewLine,
 | 
					            action: MessageComposerAction.NewLine,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.ENTER,
 | 
					                key: Key.ENTER,
 | 
				
			||||||
                shiftKey: true,
 | 
					                shiftKey: true,
 | 
				
			||||||
@@ -263,7 +251,7 @@ const messageComposerBindings = (): KeyBinding[] => {
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
        if (isMac) {
 | 
					        if (isMac) {
 | 
				
			||||||
            bindings.push({
 | 
					            bindings.push({
 | 
				
			||||||
                action: KeyAction.NewLine,
 | 
					                action: MessageComposerAction.NewLine,
 | 
				
			||||||
                keyCombo: {
 | 
					                keyCombo: {
 | 
				
			||||||
                    key: Key.ENTER,
 | 
					                    key: Key.ENTER,
 | 
				
			||||||
                    altKey: true,
 | 
					                    altKey: true,
 | 
				
			||||||
@@ -274,42 +262,42 @@ const messageComposerBindings = (): KeyBinding[] => {
 | 
				
			|||||||
    return bindings;
 | 
					    return bindings;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const autocompleteBindings = (): KeyBinding[] => {
 | 
					const autocompleteBindings = (): KeyBinding<AutocompleteAction>[] => {
 | 
				
			||||||
    return [
 | 
					    return [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.AutocompleteApply,
 | 
					            action: AutocompleteAction.ApplySelection,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.TAB,
 | 
					                key: Key.TAB,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.AutocompleteApply,
 | 
					            action: AutocompleteAction.ApplySelection,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.TAB,
 | 
					                key: Key.TAB,
 | 
				
			||||||
                ctrlKey: true,
 | 
					                ctrlKey: true,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.AutocompleteApply,
 | 
					            action: AutocompleteAction.ApplySelection,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.TAB,
 | 
					                key: Key.TAB,
 | 
				
			||||||
                shiftKey: true,
 | 
					                shiftKey: true,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.AutocompleteCancel,
 | 
					            action: AutocompleteAction.Cancel,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.ESCAPE,
 | 
					                key: Key.ESCAPE,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.AutocompletePrevSelection,
 | 
					            action: AutocompleteAction.PrevSelection,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.ARROW_UP,
 | 
					                key: Key.ARROW_UP,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.AutocompleteNextSelection,
 | 
					            action: AutocompleteAction.NextSelection,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.ARROW_DOWN,
 | 
					                key: Key.ARROW_DOWN,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
@@ -317,40 +305,40 @@ const autocompleteBindings = (): KeyBinding[] => {
 | 
				
			|||||||
    ];
 | 
					    ];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const roomListBindings = (): KeyBinding[] => {
 | 
					const roomListBindings = (): KeyBinding<RoomListAction>[] => {
 | 
				
			||||||
    return [
 | 
					    return [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.RoomListClearSearch,
 | 
					            action: RoomListAction.ClearSearch,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.ESCAPE,
 | 
					                key: Key.ESCAPE,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.RoomListPrevRoom,
 | 
					            action: RoomListAction.PrevRoom,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.ARROW_UP,
 | 
					                key: Key.ARROW_UP,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.RoomListNextRoom,
 | 
					            action: RoomListAction.NextRoom,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.ARROW_DOWN,
 | 
					                key: Key.ARROW_DOWN,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.RoomListSelectRoom,
 | 
					            action: RoomListAction.SelectRoom,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.ENTER,
 | 
					                key: Key.ENTER,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.RoomListCollapseSection,
 | 
					            action: RoomListAction.CollapseSection,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.ARROW_LEFT,
 | 
					                key: Key.ARROW_LEFT,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.RoomListExpandSection,
 | 
					            action: RoomListAction.ExpandSection,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.ARROW_RIGHT,
 | 
					                key: Key.ARROW_RIGHT,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
@@ -358,35 +346,35 @@ const roomListBindings = (): KeyBinding[] => {
 | 
				
			|||||||
    ];
 | 
					    ];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const roomBindings = (): KeyBinding[] => {
 | 
					const roomBindings = (): KeyBinding<RoomAction>[] => {
 | 
				
			||||||
    const bindings = [
 | 
					    const bindings = [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.RoomFocusRoomSearch,
 | 
					            action: RoomAction.FocusRoomSearch,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.K,
 | 
					                key: Key.K,
 | 
				
			||||||
                ctrlOrCmd: true,
 | 
					                ctrlOrCmd: true,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.RoomScrollUp,
 | 
					            action: RoomAction.ScrollUp,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.PAGE_UP,
 | 
					                key: Key.PAGE_UP,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.RoomScrollDown,
 | 
					            action: RoomAction.RoomScrollDown,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.PAGE_DOWN,
 | 
					                key: Key.PAGE_DOWN,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.RoomDismissReadMarker,
 | 
					            action: RoomAction.DismissReadMarker,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.ESCAPE,
 | 
					                key: Key.ESCAPE,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.RoomUploadFile,
 | 
					            action: RoomAction.UploadFile,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.U,
 | 
					                key: Key.U,
 | 
				
			||||||
                ctrlOrCmd: true,
 | 
					                ctrlOrCmd: true,
 | 
				
			||||||
@@ -394,14 +382,14 @@ const roomBindings = (): KeyBinding[] => {
 | 
				
			|||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.RoomJumpToFirstMessage,
 | 
					            action: RoomAction.JumpToFirstMessage,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.HOME,
 | 
					                key: Key.HOME,
 | 
				
			||||||
                ctrlKey: true,
 | 
					                ctrlKey: true,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.RoomJumpToLatestMessage,
 | 
					            action: RoomAction.JumpToLatestMessage,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.END,
 | 
					                key: Key.END,
 | 
				
			||||||
                ctrlKey: true,
 | 
					                ctrlKey: true,
 | 
				
			||||||
@@ -411,7 +399,7 @@ const roomBindings = (): KeyBinding[] => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if (SettingsStore.getValue('ctrlFForSearch')) {
 | 
					    if (SettingsStore.getValue('ctrlFForSearch')) {
 | 
				
			||||||
        bindings.push({
 | 
					        bindings.push({
 | 
				
			||||||
            action: KeyAction.RoomSearch,
 | 
					            action: RoomAction.FocusSearch,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.F,
 | 
					                key: Key.F,
 | 
				
			||||||
                ctrlOrCmd: true,
 | 
					                ctrlOrCmd: true,
 | 
				
			||||||
@@ -422,17 +410,17 @@ const roomBindings = (): KeyBinding[] => {
 | 
				
			|||||||
    return bindings;
 | 
					    return bindings;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const navigationBindings = (): KeyBinding[] => {
 | 
					const navigationBindings = (): KeyBinding<NavigationAction>[] => {
 | 
				
			||||||
    return [
 | 
					    return [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.NavToggleRoomSidePanel,
 | 
					            action: NavigationAction.ToggleRoomSidePanel,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.PERIOD,
 | 
					                key: Key.PERIOD,
 | 
				
			||||||
                ctrlOrCmd: true,
 | 
					                ctrlOrCmd: true,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.NavToggleUserMenu,
 | 
					            action: NavigationAction.ToggleUserMenu,
 | 
				
			||||||
            // Ideally this would be CTRL+P for "Profile", but that's
 | 
					            // Ideally this would be CTRL+P for "Profile", but that's
 | 
				
			||||||
            // taken by the print dialog. CTRL+I for "Information"
 | 
					            // taken by the print dialog. CTRL+I for "Information"
 | 
				
			||||||
            // was previously chosen but conflicted with italics in
 | 
					            // was previously chosen but conflicted with italics in
 | 
				
			||||||
@@ -443,14 +431,14 @@ const navigationBindings = (): KeyBinding[] => {
 | 
				
			|||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.NavToggleShortCutDialog,
 | 
					            action: NavigationAction.ToggleShortCutDialog,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.SLASH,
 | 
					                key: Key.SLASH,
 | 
				
			||||||
                ctrlOrCmd: true,
 | 
					                ctrlOrCmd: true,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.NavToggleShortCutDialog,
 | 
					            action: NavigationAction.ToggleShortCutDialog,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.SLASH,
 | 
					                key: Key.SLASH,
 | 
				
			||||||
                ctrlOrCmd: true,
 | 
					                ctrlOrCmd: true,
 | 
				
			||||||
@@ -458,7 +446,7 @@ const navigationBindings = (): KeyBinding[] => {
 | 
				
			|||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.NavGoToHome,
 | 
					            action: NavigationAction.GoToHome,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.H,
 | 
					                key: Key.H,
 | 
				
			||||||
                ctrlOrCmd: true,
 | 
					                ctrlOrCmd: true,
 | 
				
			||||||
@@ -467,21 +455,21 @@ const navigationBindings = (): KeyBinding[] => {
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.NavSelectPrevRoom,
 | 
					            action: NavigationAction.SelectPrevRoom,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.ARROW_UP,
 | 
					                key: Key.ARROW_UP,
 | 
				
			||||||
                altKey: true,
 | 
					                altKey: true,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.NavSelectNextRoom,
 | 
					            action: NavigationAction.SelectNextRoom,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.ARROW_DOWN,
 | 
					                key: Key.ARROW_DOWN,
 | 
				
			||||||
                altKey: true,
 | 
					                altKey: true,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.NavSelectPrevUnreadRoom,
 | 
					            action: NavigationAction.SelectPrevUnreadRoom,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.ARROW_UP,
 | 
					                key: Key.ARROW_UP,
 | 
				
			||||||
                altKey: true,
 | 
					                altKey: true,
 | 
				
			||||||
@@ -489,7 +477,7 @@ const navigationBindings = (): KeyBinding[] => {
 | 
				
			|||||||
            },
 | 
					            },
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            action: KeyAction.NavSelectNextUnreadRoom,
 | 
					            action: NavigationAction.SelectNextUnreadRoom,
 | 
				
			||||||
            keyCombo: {
 | 
					            keyCombo: {
 | 
				
			||||||
                key: Key.ARROW_DOWN,
 | 
					                key: Key.ARROW_DOWN,
 | 
				
			||||||
                altKey: true,
 | 
					                altKey: true,
 | 
				
			||||||
@@ -551,38 +539,42 @@ export function isKeyComboMatch(ev: KeyboardEvent | React.KeyboardEvent, combo:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
export type KeyBindingsGetter = () => KeyBinding[];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export class KeyBindingsManager {
 | 
					export class KeyBindingsManager {
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Map of KeyBindingContext to a KeyBinding getter arrow function.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * Returning a getter function allowed to have dynamic bindings, e.g. when settings change the bindings can be
 | 
					 | 
				
			||||||
     * recalculated.
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    contextBindings: Record<KeyBindingContext, KeyBindingsGetter> = {
 | 
					 | 
				
			||||||
        [KeyBindingContext.MessageComposer]: messageComposerBindings,
 | 
					 | 
				
			||||||
        [KeyBindingContext.AutoComplete]: autocompleteBindings,
 | 
					 | 
				
			||||||
        [KeyBindingContext.RoomList]: roomListBindings,
 | 
					 | 
				
			||||||
        [KeyBindingContext.Room]: roomBindings,
 | 
					 | 
				
			||||||
        [KeyBindingContext.Navigation]: navigationBindings,
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Finds a matching KeyAction for a given KeyboardEvent
 | 
					     * Finds a matching KeyAction for a given KeyboardEvent
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    getAction(context: KeyBindingContext, ev: KeyboardEvent | React.KeyboardEvent): KeyAction {
 | 
					    private getAction<T extends string>(bindings: KeyBinding<T>[], ev: KeyboardEvent | React.KeyboardEvent)
 | 
				
			||||||
        const bindings = this.contextBindings[context]?.();
 | 
					        : T | undefined {
 | 
				
			||||||
        if (!bindings) {
 | 
					 | 
				
			||||||
            return KeyAction.None;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        const binding = bindings.find(it => isKeyComboMatch(ev, it.keyCombo, isMac));
 | 
					        const binding = bindings.find(it => isKeyComboMatch(ev, it.keyCombo, isMac));
 | 
				
			||||||
        if (binding) {
 | 
					        if (binding) {
 | 
				
			||||||
            return binding.action;
 | 
					            return binding.action;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        return undefined;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return KeyAction.None;
 | 
					    getMessageComposerAction(ev: KeyboardEvent | React.KeyboardEvent): MessageComposerAction | undefined {
 | 
				
			||||||
 | 
					        const bindings = messageComposerBindings();
 | 
				
			||||||
 | 
					        return this.getAction(bindings, ev);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    getAutocompleteAction(ev: KeyboardEvent | React.KeyboardEvent): AutocompleteAction | undefined {
 | 
				
			||||||
 | 
					        const bindings = autocompleteBindings();
 | 
				
			||||||
 | 
					        return this.getAction(bindings, ev);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    getRoomListAction(ev: KeyboardEvent | React.KeyboardEvent): RoomListAction | undefined {
 | 
				
			||||||
 | 
					        const bindings = roomListBindings();
 | 
				
			||||||
 | 
					        return this.getAction(bindings, ev);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    getRoomAction(ev: KeyboardEvent | React.KeyboardEvent): RoomAction | undefined {
 | 
				
			||||||
 | 
					        const bindings = roomBindings();
 | 
				
			||||||
 | 
					        return this.getAction(bindings, ev);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    getNavigationAction(ev: KeyboardEvent | React.KeyboardEvent): NavigationAction | undefined {
 | 
				
			||||||
 | 
					        const bindings = navigationBindings();
 | 
				
			||||||
 | 
					        return this.getAction(bindings, ev);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -55,7 +55,7 @@ import { IThreepidInvite } from "../../stores/ThreepidInviteStore";
 | 
				
			|||||||
import Modal from "../../Modal";
 | 
					import Modal from "../../Modal";
 | 
				
			||||||
import { ICollapseConfig } from "../../resizer/distributors/collapse";
 | 
					import { ICollapseConfig } from "../../resizer/distributors/collapse";
 | 
				
			||||||
import HostSignupContainer from '../views/host_signup/HostSignupContainer';
 | 
					import HostSignupContainer from '../views/host_signup/HostSignupContainer';
 | 
				
			||||||
import { getKeyBindingsManager, KeyAction, KeyBindingContext } from '../../KeyBindingsManager';
 | 
					import { getKeyBindingsManager, NavigationAction, RoomAction } from '../../KeyBindingsManager';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// We need to fetch each pinned message individually (if we don't already have it)
 | 
					// We need to fetch each pinned message individually (if we don't already have it)
 | 
				
			||||||
// so each pinned message may trigger a request. Limit the number per room for sanity.
 | 
					// so each pinned message may trigger a request. Limit the number per room for sanity.
 | 
				
			||||||
@@ -401,22 +401,22 @@ class LoggedInView extends React.Component<IProps, IState> {
 | 
				
			|||||||
    _onKeyDown = (ev) => {
 | 
					    _onKeyDown = (ev) => {
 | 
				
			||||||
        let handled = false;
 | 
					        let handled = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const roomAction = getKeyBindingsManager().getAction(KeyBindingContext.Room, ev);
 | 
					        const roomAction = getKeyBindingsManager().getRoomAction(ev);
 | 
				
			||||||
        switch (roomAction) {
 | 
					        switch (roomAction) {
 | 
				
			||||||
            case KeyAction.RoomFocusRoomSearch:
 | 
					            case RoomAction.FocusRoomSearch:
 | 
				
			||||||
                dis.dispatch({
 | 
					                dis.dispatch({
 | 
				
			||||||
                    action: 'focus_room_filter',
 | 
					                    action: 'focus_room_filter',
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
                handled = true;
 | 
					                handled = true;
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case KeyAction.RoomScrollUp:
 | 
					            case RoomAction.ScrollUp:
 | 
				
			||||||
            case KeyAction.RoomScrollDown:
 | 
					            case RoomAction.RoomScrollDown:
 | 
				
			||||||
            case KeyAction.RoomJumpToFirstMessage:
 | 
					            case RoomAction.JumpToFirstMessage:
 | 
				
			||||||
            case KeyAction.RoomJumpToLatestMessage:
 | 
					            case RoomAction.JumpToLatestMessage:
 | 
				
			||||||
                this._onScrollKeyPressed(ev);
 | 
					                this._onScrollKeyPressed(ev);
 | 
				
			||||||
                handled = true;
 | 
					                handled = true;
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case KeyAction.RoomSearch:
 | 
					            case RoomAction.FocusSearch:
 | 
				
			||||||
                dis.dispatch({
 | 
					                dis.dispatch({
 | 
				
			||||||
                    action: 'focus_search',
 | 
					                    action: 'focus_search',
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
@@ -429,24 +429,24 @@ class LoggedInView extends React.Component<IProps, IState> {
 | 
				
			|||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const navAction = getKeyBindingsManager().getAction(KeyBindingContext.Navigation, ev);
 | 
					        const navAction = getKeyBindingsManager().getNavigationAction(ev);
 | 
				
			||||||
        switch (navAction) {
 | 
					        switch (navAction) {
 | 
				
			||||||
            case KeyAction.NavToggleUserMenu:
 | 
					            case NavigationAction.ToggleUserMenu:
 | 
				
			||||||
                dis.fire(Action.ToggleUserMenu);
 | 
					                dis.fire(Action.ToggleUserMenu);
 | 
				
			||||||
                handled = true;
 | 
					                handled = true;
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case KeyAction.NavToggleShortCutDialog:
 | 
					            case NavigationAction.ToggleShortCutDialog:
 | 
				
			||||||
                KeyboardShortcuts.toggleDialog();
 | 
					                KeyboardShortcuts.toggleDialog();
 | 
				
			||||||
                handled = true;
 | 
					                handled = true;
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case KeyAction.NavGoToHome:
 | 
					            case NavigationAction.GoToHome:
 | 
				
			||||||
                dis.dispatch({
 | 
					                dis.dispatch({
 | 
				
			||||||
                    action: 'view_home_page',
 | 
					                    action: 'view_home_page',
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
                Modal.closeCurrentModal("homeKeyboardShortcut");
 | 
					                Modal.closeCurrentModal("homeKeyboardShortcut");
 | 
				
			||||||
                handled = true;
 | 
					                handled = true;
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case KeyAction.NavToggleRoomSidePanel:
 | 
					            case NavigationAction.ToggleRoomSidePanel:
 | 
				
			||||||
                if (this.props.page_type === "room_view" || this.props.page_type === "group_view") {
 | 
					                if (this.props.page_type === "room_view" || this.props.page_type === "group_view") {
 | 
				
			||||||
                    dis.dispatch<ToggleRightPanelPayload>({
 | 
					                    dis.dispatch<ToggleRightPanelPayload>({
 | 
				
			||||||
                        action: Action.ToggleRightPanel,
 | 
					                        action: Action.ToggleRightPanel,
 | 
				
			||||||
@@ -455,7 +455,7 @@ class LoggedInView extends React.Component<IProps, IState> {
 | 
				
			|||||||
                    handled = true;
 | 
					                    handled = true;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case KeyAction.NavSelectPrevRoom:
 | 
					            case NavigationAction.SelectPrevRoom:
 | 
				
			||||||
                dis.dispatch<ViewRoomDeltaPayload>({
 | 
					                dis.dispatch<ViewRoomDeltaPayload>({
 | 
				
			||||||
                    action: Action.ViewRoomDelta,
 | 
					                    action: Action.ViewRoomDelta,
 | 
				
			||||||
                    delta: -1,
 | 
					                    delta: -1,
 | 
				
			||||||
@@ -463,7 +463,7 @@ class LoggedInView extends React.Component<IProps, IState> {
 | 
				
			|||||||
                });
 | 
					                });
 | 
				
			||||||
                handled = true;
 | 
					                handled = true;
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case KeyAction.NavSelectNextRoom:
 | 
					            case NavigationAction.SelectNextRoom:
 | 
				
			||||||
                dis.dispatch<ViewRoomDeltaPayload>({
 | 
					                dis.dispatch<ViewRoomDeltaPayload>({
 | 
				
			||||||
                    action: Action.ViewRoomDelta,
 | 
					                    action: Action.ViewRoomDelta,
 | 
				
			||||||
                    delta: 1,
 | 
					                    delta: 1,
 | 
				
			||||||
@@ -471,14 +471,14 @@ class LoggedInView extends React.Component<IProps, IState> {
 | 
				
			|||||||
                });
 | 
					                });
 | 
				
			||||||
                handled = true;
 | 
					                handled = true;
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case KeyAction.NavSelectPrevUnreadRoom:
 | 
					            case NavigationAction.SelectPrevUnreadRoom:
 | 
				
			||||||
                dis.dispatch<ViewRoomDeltaPayload>({
 | 
					                dis.dispatch<ViewRoomDeltaPayload>({
 | 
				
			||||||
                    action: Action.ViewRoomDelta,
 | 
					                    action: Action.ViewRoomDelta,
 | 
				
			||||||
                    delta: -1,
 | 
					                    delta: -1,
 | 
				
			||||||
                    unread: true,
 | 
					                    unread: true,
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case KeyAction.NavSelectNextUnreadRoom:
 | 
					            case NavigationAction.SelectNextUnreadRoom:
 | 
				
			||||||
                dis.dispatch<ViewRoomDeltaPayload>({
 | 
					                dis.dispatch<ViewRoomDeltaPayload>({
 | 
				
			||||||
                    action: Action.ViewRoomDelta,
 | 
					                    action: Action.ViewRoomDelta,
 | 
				
			||||||
                    delta: 1,
 | 
					                    delta: 1,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,7 +24,7 @@ import AccessibleButton from "../views/elements/AccessibleButton";
 | 
				
			|||||||
import { Action } from "../../dispatcher/actions";
 | 
					import { Action } from "../../dispatcher/actions";
 | 
				
			||||||
import RoomListStore from "../../stores/room-list/RoomListStore";
 | 
					import RoomListStore from "../../stores/room-list/RoomListStore";
 | 
				
			||||||
import { NameFilterCondition } from "../../stores/room-list/filters/NameFilterCondition";
 | 
					import { NameFilterCondition } from "../../stores/room-list/filters/NameFilterCondition";
 | 
				
			||||||
import { getKeyBindingsManager, KeyAction, KeyBindingContext } from "../../KeyBindingsManager";
 | 
					import { getKeyBindingsManager, RoomListAction } from "../../KeyBindingsManager";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface IProps {
 | 
					interface IProps {
 | 
				
			||||||
    isMinimized: boolean;
 | 
					    isMinimized: boolean;
 | 
				
			||||||
@@ -106,17 +106,17 @@ export default class RoomSearch extends React.PureComponent<IProps, IState> {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private onKeyDown = (ev: React.KeyboardEvent) => {
 | 
					    private onKeyDown = (ev: React.KeyboardEvent) => {
 | 
				
			||||||
        const action = getKeyBindingsManager().getAction(KeyBindingContext.RoomList, ev);
 | 
					        const action = getKeyBindingsManager().getRoomListAction(ev);
 | 
				
			||||||
        switch (action) {
 | 
					        switch (action) {
 | 
				
			||||||
            case KeyAction.RoomListClearSearch:
 | 
					            case RoomListAction.ClearSearch:
 | 
				
			||||||
                this.clearInput();
 | 
					                this.clearInput();
 | 
				
			||||||
                defaultDispatcher.fire(Action.FocusComposer);
 | 
					                defaultDispatcher.fire(Action.FocusComposer);
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case KeyAction.RoomListNextRoom:
 | 
					            case RoomListAction.NextRoom:
 | 
				
			||||||
            case KeyAction.RoomListPrevRoom:
 | 
					            case RoomListAction.PrevRoom:
 | 
				
			||||||
                this.props.onVerticalArrow(ev);
 | 
					                this.props.onVerticalArrow(ev);
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case KeyAction.RoomListSelectRoom: {
 | 
					            case RoomListAction.SelectRoom: {
 | 
				
			||||||
                const shouldClear = this.props.onEnter(ev);
 | 
					                const shouldClear = this.props.onEnter(ev);
 | 
				
			||||||
                if (shouldClear) {
 | 
					                if (shouldClear) {
 | 
				
			||||||
                    // wrap in set immediate to delay it so that we don't clear the filter & then change room
 | 
					                    // wrap in set immediate to delay it so that we don't clear the filter & then change room
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -78,7 +78,7 @@ import Notifier from "../../Notifier";
 | 
				
			|||||||
import { showToast as showNotificationsToast } from "../../toasts/DesktopNotificationsToast";
 | 
					import { showToast as showNotificationsToast } from "../../toasts/DesktopNotificationsToast";
 | 
				
			||||||
import { RoomNotificationStateStore } from "../../stores/notifications/RoomNotificationStateStore";
 | 
					import { RoomNotificationStateStore } from "../../stores/notifications/RoomNotificationStateStore";
 | 
				
			||||||
import { Container, WidgetLayoutStore } from "../../stores/widgets/WidgetLayoutStore";
 | 
					import { Container, WidgetLayoutStore } from "../../stores/widgets/WidgetLayoutStore";
 | 
				
			||||||
import { getKeyBindingsManager, KeyAction, KeyBindingContext } from '../../KeyBindingsManager';
 | 
					import { getKeyBindingsManager, RoomAction } from '../../KeyBindingsManager';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const DEBUG = false;
 | 
					const DEBUG = false;
 | 
				
			||||||
let debuglog = function(msg: string) {};
 | 
					let debuglog = function(msg: string) {};
 | 
				
			||||||
@@ -661,18 +661,18 @@ export default class RoomView extends React.Component<IProps, IState> {
 | 
				
			|||||||
    private onReactKeyDown = ev => {
 | 
					    private onReactKeyDown = ev => {
 | 
				
			||||||
        let handled = false;
 | 
					        let handled = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const action = getKeyBindingsManager().getAction(KeyBindingContext.Room, ev);
 | 
					        const action = getKeyBindingsManager().getRoomAction(ev);
 | 
				
			||||||
        switch (action) {
 | 
					        switch (action) {
 | 
				
			||||||
            case KeyAction.RoomDismissReadMarker:
 | 
					            case RoomAction.DismissReadMarker:
 | 
				
			||||||
                this.messagePanel.forgetReadMarker();
 | 
					                this.messagePanel.forgetReadMarker();
 | 
				
			||||||
                this.jumpToLiveTimeline();
 | 
					                this.jumpToLiveTimeline();
 | 
				
			||||||
                handled = true;
 | 
					                handled = true;
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case KeyAction.RoomScrollUp:
 | 
					            case RoomAction.ScrollUp:
 | 
				
			||||||
                this.jumpToReadMarker();
 | 
					                this.jumpToReadMarker();
 | 
				
			||||||
                handled = true;
 | 
					                handled = true;
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case KeyAction.RoomUploadFile:
 | 
					            case RoomAction.UploadFile:
 | 
				
			||||||
                dis.dispatch({ action: "upload_file" }, true);
 | 
					                dis.dispatch({ action: "upload_file" }, true);
 | 
				
			||||||
                handled = true;
 | 
					                handled = true;
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -46,7 +46,7 @@ import {IDiff} from "../../../editor/diff";
 | 
				
			|||||||
import AutocompleteWrapperModel from "../../../editor/autocomplete";
 | 
					import AutocompleteWrapperModel from "../../../editor/autocomplete";
 | 
				
			||||||
import DocumentPosition from "../../../editor/position";
 | 
					import DocumentPosition from "../../../editor/position";
 | 
				
			||||||
import {ICompletion} from "../../../autocomplete/Autocompleter";
 | 
					import {ICompletion} from "../../../autocomplete/Autocompleter";
 | 
				
			||||||
import { getKeyBindingsManager, KeyBindingContext, KeyAction } from '../../../KeyBindingsManager';
 | 
					import { AutocompleteAction, getKeyBindingsManager, MessageComposerAction } from '../../../KeyBindingsManager';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// matches emoticons which follow the start of a line or whitespace
 | 
					// matches emoticons which follow the start of a line or whitespace
 | 
				
			||||||
const REGEX_EMOTICON_WHITESPACE = new RegExp('(?:^|\\s)(' + EMOTICON_REGEX.source + ')\\s$');
 | 
					const REGEX_EMOTICON_WHITESPACE = new RegExp('(?:^|\\s)(' + EMOTICON_REGEX.source + ')\\s$');
 | 
				
			||||||
@@ -421,21 +421,21 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
 | 
				
			|||||||
    private onKeyDown = (event: React.KeyboardEvent) => {
 | 
					    private onKeyDown = (event: React.KeyboardEvent) => {
 | 
				
			||||||
        const model = this.props.model;
 | 
					        const model = this.props.model;
 | 
				
			||||||
        let handled = false;
 | 
					        let handled = false;
 | 
				
			||||||
        const action = getKeyBindingsManager().getAction(KeyBindingContext.MessageComposer, event);
 | 
					        const action = getKeyBindingsManager().getMessageComposerAction(event);
 | 
				
			||||||
        switch (action) {
 | 
					        switch (action) {
 | 
				
			||||||
            case KeyAction.FormatBold:
 | 
					            case MessageComposerAction.FormatBold:
 | 
				
			||||||
                this.onFormatAction(Formatting.Bold);
 | 
					                this.onFormatAction(Formatting.Bold);
 | 
				
			||||||
                handled = true;
 | 
					                handled = true;
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case KeyAction.FormatItalics:
 | 
					            case MessageComposerAction.FormatItalics:
 | 
				
			||||||
                this.onFormatAction(Formatting.Italics);
 | 
					                this.onFormatAction(Formatting.Italics);
 | 
				
			||||||
                handled = true;
 | 
					                handled = true;
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case KeyAction.FormatQuote:
 | 
					            case MessageComposerAction.FormatQuote:
 | 
				
			||||||
                this.onFormatAction(Formatting.Quote);
 | 
					                this.onFormatAction(Formatting.Quote);
 | 
				
			||||||
                handled = true;
 | 
					                handled = true;
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case KeyAction.EditRedo:
 | 
					            case MessageComposerAction.EditRedo:
 | 
				
			||||||
                if (this.historyManager.canRedo()) {
 | 
					                if (this.historyManager.canRedo()) {
 | 
				
			||||||
                    const {parts, caret} = this.historyManager.redo();
 | 
					                    const {parts, caret} = this.historyManager.redo();
 | 
				
			||||||
                    // pass matching inputType so historyManager doesn't push echo
 | 
					                    // pass matching inputType so historyManager doesn't push echo
 | 
				
			||||||
@@ -444,7 +444,7 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
                handled = true;
 | 
					                handled = true;
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case KeyAction.EditUndo:
 | 
					            case MessageComposerAction.EditUndo:
 | 
				
			||||||
                if (this.historyManager.canUndo()) {
 | 
					                if (this.historyManager.canUndo()) {
 | 
				
			||||||
                    const {parts, caret} = this.historyManager.undo(this.props.model);
 | 
					                    const {parts, caret} = this.historyManager.undo(this.props.model);
 | 
				
			||||||
                    // pass matching inputType so historyManager doesn't push echo
 | 
					                    // pass matching inputType so historyManager doesn't push echo
 | 
				
			||||||
@@ -453,18 +453,18 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
                handled = true;
 | 
					                handled = true;
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case KeyAction.NewLine:
 | 
					            case MessageComposerAction.NewLine:
 | 
				
			||||||
                this.insertText("\n");
 | 
					                this.insertText("\n");
 | 
				
			||||||
                handled = true;
 | 
					                handled = true;
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case KeyAction.MoveCursorToStart:
 | 
					            case MessageComposerAction.MoveCursorToStart:
 | 
				
			||||||
                setSelection(this.editorRef.current, model, {
 | 
					                setSelection(this.editorRef.current, model, {
 | 
				
			||||||
                    index: 0,
 | 
					                    index: 0,
 | 
				
			||||||
                    offset: 0,
 | 
					                    offset: 0,
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
                handled = true;
 | 
					                handled = true;
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case KeyAction.MoveCursorToEnd:
 | 
					            case MessageComposerAction.MoveCursorToEnd:
 | 
				
			||||||
                setSelection(this.editorRef.current, model, {
 | 
					                setSelection(this.editorRef.current, model, {
 | 
				
			||||||
                    index: model.parts.length - 1,
 | 
					                    index: model.parts.length - 1,
 | 
				
			||||||
                    offset: model.parts[model.parts.length - 1].text.length,
 | 
					                    offset: model.parts[model.parts.length - 1].text.length,
 | 
				
			||||||
@@ -478,30 +478,30 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
 | 
				
			|||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const autocompleteAction = getKeyBindingsManager().getAction(KeyBindingContext.AutoComplete, event);
 | 
					        const autocompleteAction = getKeyBindingsManager().getAutocompleteAction(event);
 | 
				
			||||||
        if (model.autoComplete && model.autoComplete.hasCompletions()) {
 | 
					        if (model.autoComplete && model.autoComplete.hasCompletions()) {
 | 
				
			||||||
            const autoComplete = model.autoComplete;
 | 
					            const autoComplete = model.autoComplete;
 | 
				
			||||||
            switch (autocompleteAction) {
 | 
					            switch (autocompleteAction) {
 | 
				
			||||||
                case KeyAction.AutocompletePrevSelection:
 | 
					                case AutocompleteAction.PrevSelection:
 | 
				
			||||||
                    autoComplete.onUpArrow(event);
 | 
					                    autoComplete.onUpArrow(event);
 | 
				
			||||||
                    handled = true;
 | 
					                    handled = true;
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
                case KeyAction.AutocompleteNextSelection:
 | 
					                case AutocompleteAction.NextSelection:
 | 
				
			||||||
                    autoComplete.onDownArrow(event);
 | 
					                    autoComplete.onDownArrow(event);
 | 
				
			||||||
                    handled = true;
 | 
					                    handled = true;
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
                case KeyAction.AutocompleteApply:
 | 
					                case AutocompleteAction.ApplySelection:
 | 
				
			||||||
                    autoComplete.onTab(event);
 | 
					                    autoComplete.onTab(event);
 | 
				
			||||||
                    handled = true;
 | 
					                    handled = true;
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
                case KeyAction.AutocompleteCancel:
 | 
					                case AutocompleteAction.Cancel:
 | 
				
			||||||
                    autoComplete.onEscape(event);
 | 
					                    autoComplete.onEscape(event);
 | 
				
			||||||
                    handled = true;
 | 
					                    handled = true;
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
                default:
 | 
					                default:
 | 
				
			||||||
                    return; // don't preventDefault on anything else
 | 
					                    return; // don't preventDefault on anything else
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } else if (autocompleteAction === KeyAction.AutocompleteApply) {
 | 
					        } else if (autocompleteAction === AutocompleteAction.ApplySelection) {
 | 
				
			||||||
            this.tabCompleteName(event);
 | 
					            this.tabCompleteName(event);
 | 
				
			||||||
            handled = true;
 | 
					            handled = true;
 | 
				
			||||||
        } else if (event.key === Key.BACKSPACE || event.key === Key.DELETE) {
 | 
					        } else if (event.key === Key.BACKSPACE || event.key === Key.DELETE) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,7 +32,7 @@ import BasicMessageComposer from "./BasicMessageComposer";
 | 
				
			|||||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
 | 
					import MatrixClientContext from "../../../contexts/MatrixClientContext";
 | 
				
			||||||
import {Action} from "../../../dispatcher/actions";
 | 
					import {Action} from "../../../dispatcher/actions";
 | 
				
			||||||
import CountlyAnalytics from "../../../CountlyAnalytics";
 | 
					import CountlyAnalytics from "../../../CountlyAnalytics";
 | 
				
			||||||
import {getKeyBindingsManager, KeyAction, KeyBindingContext} from '../../../KeyBindingsManager';
 | 
					import {getKeyBindingsManager, MessageComposerAction} from '../../../KeyBindingsManager';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function _isReply(mxEvent) {
 | 
					function _isReply(mxEvent) {
 | 
				
			||||||
    const relatesTo = mxEvent.getContent()["m.relates_to"];
 | 
					    const relatesTo = mxEvent.getContent()["m.relates_to"];
 | 
				
			||||||
@@ -133,16 +133,16 @@ export default class EditMessageComposer extends React.Component {
 | 
				
			|||||||
        if (this._editorRef.isComposing(event)) {
 | 
					        if (this._editorRef.isComposing(event)) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        const action = getKeyBindingsManager().getAction(KeyBindingContext.MessageComposer, event);
 | 
					        const action = getKeyBindingsManager().getMessageComposerAction(event);
 | 
				
			||||||
        switch (action) {
 | 
					        switch (action) {
 | 
				
			||||||
            case KeyAction.Send:
 | 
					            case MessageComposerAction.Send:
 | 
				
			||||||
                this._sendEdit();
 | 
					                this._sendEdit();
 | 
				
			||||||
                event.preventDefault();
 | 
					                event.preventDefault();
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case KeyAction.CancelEditing:
 | 
					            case MessageComposerAction.CancelEditing:
 | 
				
			||||||
                this._cancelEdit();
 | 
					                this._cancelEdit();
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case KeyAction.EditPrevMessage: {
 | 
					            case MessageComposerAction.EditPrevMessage: {
 | 
				
			||||||
                if (this._editorRef.isModified() || !this._editorRef.isCaretAtStart()) {
 | 
					                if (this._editorRef.isModified() || !this._editorRef.isCaretAtStart()) {
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@@ -154,7 +154,7 @@ export default class EditMessageComposer extends React.Component {
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            case KeyAction.EditNextMessage: {
 | 
					            case MessageComposerAction.EditNextMessage: {
 | 
				
			||||||
                if (this._editorRef.isModified() || !this._editorRef.isCaretAtEnd()) {
 | 
					                if (this._editorRef.isModified() || !this._editorRef.isCaretAtEnd()) {
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -51,7 +51,7 @@ import { objectExcluding, objectHasDiff } from "../../../utils/objects";
 | 
				
			|||||||
import TemporaryTile from "./TemporaryTile";
 | 
					import TemporaryTile from "./TemporaryTile";
 | 
				
			||||||
import { ListNotificationState } from "../../../stores/notifications/ListNotificationState";
 | 
					import { ListNotificationState } from "../../../stores/notifications/ListNotificationState";
 | 
				
			||||||
import IconizedContextMenu from "../context_menus/IconizedContextMenu";
 | 
					import IconizedContextMenu from "../context_menus/IconizedContextMenu";
 | 
				
			||||||
import { getKeyBindingsManager, KeyAction, KeyBindingContext } from "../../../KeyBindingsManager";
 | 
					import { getKeyBindingsManager, RoomListAction } from "../../../KeyBindingsManager";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const SHOW_N_BUTTON_HEIGHT = 28; // As defined by CSS
 | 
					const SHOW_N_BUTTON_HEIGHT = 28; // As defined by CSS
 | 
				
			||||||
const RESIZE_HANDLE_HEIGHT = 4; // As defined by CSS
 | 
					const RESIZE_HANDLE_HEIGHT = 4; // As defined by CSS
 | 
				
			||||||
@@ -471,16 +471,16 @@ export default class RoomSublist extends React.Component<IProps, IState> {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private onHeaderKeyDown = (ev: React.KeyboardEvent) => {
 | 
					    private onHeaderKeyDown = (ev: React.KeyboardEvent) => {
 | 
				
			||||||
        const action = getKeyBindingsManager().getAction(KeyBindingContext.RoomList, ev);
 | 
					        const action = getKeyBindingsManager().getRoomListAction(ev);
 | 
				
			||||||
        switch (action) {
 | 
					        switch (action) {
 | 
				
			||||||
            case KeyAction.RoomListCollapseSection:
 | 
					            case RoomListAction.CollapseSection:
 | 
				
			||||||
                ev.stopPropagation();
 | 
					                ev.stopPropagation();
 | 
				
			||||||
                if (this.state.isExpanded) {
 | 
					                if (this.state.isExpanded) {
 | 
				
			||||||
                    // Collapse the room sublist if it isn't already
 | 
					                    // Collapse the room sublist if it isn't already
 | 
				
			||||||
                    this.toggleCollapsed();
 | 
					                    this.toggleCollapsed();
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case KeyAction.RoomListExpandSection: {
 | 
					            case RoomListAction.ExpandSection: {
 | 
				
			||||||
                ev.stopPropagation();
 | 
					                ev.stopPropagation();
 | 
				
			||||||
                if (!this.state.isExpanded) {
 | 
					                if (!this.state.isExpanded) {
 | 
				
			||||||
                    // Expand the room sublist if it isn't already
 | 
					                    // Expand the room sublist if it isn't already
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -46,7 +46,7 @@ import {CHAT_EFFECTS} from '../../../effects';
 | 
				
			|||||||
import CountlyAnalytics from "../../../CountlyAnalytics";
 | 
					import CountlyAnalytics from "../../../CountlyAnalytics";
 | 
				
			||||||
import {MatrixClientPeg} from "../../../MatrixClientPeg";
 | 
					import {MatrixClientPeg} from "../../../MatrixClientPeg";
 | 
				
			||||||
import EMOJI_REGEX from 'emojibase-regex';
 | 
					import EMOJI_REGEX from 'emojibase-regex';
 | 
				
			||||||
import {getKeyBindingsManager, KeyAction, KeyBindingContext} from '../../../KeyBindingsManager';
 | 
					import {getKeyBindingsManager, MessageComposerAction} from '../../../KeyBindingsManager';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function addReplyToMessageContent(content, repliedToEvent, permalinkCreator) {
 | 
					function addReplyToMessageContent(content, repliedToEvent, permalinkCreator) {
 | 
				
			||||||
    const replyContent = ReplyThread.makeReplyMixIn(repliedToEvent);
 | 
					    const replyContent = ReplyThread.makeReplyMixIn(repliedToEvent);
 | 
				
			||||||
@@ -143,23 +143,23 @@ export default class SendMessageComposer extends React.Component {
 | 
				
			|||||||
        if (this._editorRef.isComposing(event)) {
 | 
					        if (this._editorRef.isComposing(event)) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        const action = getKeyBindingsManager().getAction(KeyBindingContext.MessageComposer, event);
 | 
					        const action = getKeyBindingsManager().getMessageComposerAction(event);
 | 
				
			||||||
        switch (action) {
 | 
					        switch (action) {
 | 
				
			||||||
            case KeyAction.Send:
 | 
					            case MessageComposerAction.Send:
 | 
				
			||||||
                this._sendMessage();
 | 
					                this._sendMessage();
 | 
				
			||||||
                event.preventDefault();
 | 
					                event.preventDefault();
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case KeyAction.SelectPrevSendHistory:
 | 
					            case MessageComposerAction.SelectPrevSendHistory:
 | 
				
			||||||
            case KeyAction.SelectNextSendHistory: {
 | 
					            case MessageComposerAction.SelectNextSendHistory: {
 | 
				
			||||||
                // Try select composer history
 | 
					                // Try select composer history
 | 
				
			||||||
                const selected = this.selectSendHistory(action === KeyAction.SelectPrevSendHistory);
 | 
					                const selected = this.selectSendHistory(action === MessageComposerAction.SelectPrevSendHistory);
 | 
				
			||||||
                if (selected) {
 | 
					                if (selected) {
 | 
				
			||||||
                    // We're selecting history, so prevent the key event from doing anything else
 | 
					                    // We're selecting history, so prevent the key event from doing anything else
 | 
				
			||||||
                    event.preventDefault();
 | 
					                    event.preventDefault();
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            case KeyAction.EditPrevMessage:
 | 
					            case MessageComposerAction.EditPrevMessage:
 | 
				
			||||||
                // selection must be collapsed and caret at start
 | 
					                // selection must be collapsed and caret at start
 | 
				
			||||||
                if (this._editorRef.isSelectionCollapsed() && this._editorRef.isCaretAtStart()) {
 | 
					                if (this._editorRef.isSelectionCollapsed() && this._editorRef.isCaretAtStart()) {
 | 
				
			||||||
                    const editEvent = findEditableEvent(this.props.room, false);
 | 
					                    const editEvent = findEditableEvent(this.props.room, false);
 | 
				
			||||||
@@ -173,7 +173,7 @@ export default class SendMessageComposer extends React.Component {
 | 
				
			|||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case KeyAction.CancelEditing:
 | 
					            case MessageComposerAction.CancelEditing:
 | 
				
			||||||
                dis.dispatch({
 | 
					                dis.dispatch({
 | 
				
			||||||
                    action: 'reply_to_event',
 | 
					                    action: 'reply_to_event',
 | 
				
			||||||
                    event: null,
 | 
					                    event: null,
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user