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 
			
		
		
		
	Add key bindings for RoomList, Room and Navigation
This commit is contained in:
		@@ -21,7 +21,7 @@ import * as PropTypes from 'prop-types';
 | 
			
		||||
import { MatrixClient } from 'matrix-js-sdk/src/client';
 | 
			
		||||
import { DragDropContext } from 'react-beautiful-dnd';
 | 
			
		||||
 | 
			
		||||
import {Key, isOnlyCtrlOrCmdKeyEvent, isOnlyCtrlOrCmdIgnoreShiftKeyEvent, isMac} from '../../Keyboard';
 | 
			
		||||
import {Key} from '../../Keyboard';
 | 
			
		||||
import PageTypes from '../../PageTypes';
 | 
			
		||||
import CallMediaHandler from '../../CallMediaHandler';
 | 
			
		||||
import { fixupColorFonts } from '../../utils/FontManager';
 | 
			
		||||
@@ -55,6 +55,7 @@ import { IThreepidInvite } from "../../stores/ThreepidInviteStore";
 | 
			
		||||
import Modal from "../../Modal";
 | 
			
		||||
import { ICollapseConfig } from "../../resizer/distributors/collapse";
 | 
			
		||||
import HostSignupContainer from '../views/host_signup/HostSignupContainer';
 | 
			
		||||
import { getKeyBindingsManager, KeyAction, KeyBindingContext } from '../../KeyBindingsManager';
 | 
			
		||||
 | 
			
		||||
// 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.
 | 
			
		||||
@@ -399,86 +400,54 @@ class LoggedInView extends React.Component<IProps, IState> {
 | 
			
		||||
 | 
			
		||||
    _onKeyDown = (ev) => {
 | 
			
		||||
        let handled = false;
 | 
			
		||||
        const ctrlCmdOnly = isOnlyCtrlOrCmdKeyEvent(ev);
 | 
			
		||||
        const hasModifier = ev.altKey || ev.ctrlKey || ev.metaKey || ev.shiftKey;
 | 
			
		||||
        const isModifier = ev.key === Key.ALT || ev.key === Key.CONTROL || ev.key === Key.META || ev.key === Key.SHIFT;
 | 
			
		||||
        const modKey = isMac ? ev.metaKey : ev.ctrlKey;
 | 
			
		||||
 | 
			
		||||
        switch (ev.key) {
 | 
			
		||||
            case Key.PAGE_UP:
 | 
			
		||||
            case Key.PAGE_DOWN:
 | 
			
		||||
                if (!hasModifier && !isModifier) {
 | 
			
		||||
                    this._onScrollKeyPressed(ev);
 | 
			
		||||
                    handled = true;
 | 
			
		||||
                }
 | 
			
		||||
        const roomAction = getKeyBindingsManager().getAction(KeyBindingContext.Room, ev);
 | 
			
		||||
        switch (roomAction) {
 | 
			
		||||
            case KeyAction.RoomFocusRoomSearch:
 | 
			
		||||
                dis.dispatch({
 | 
			
		||||
                    action: 'focus_room_filter',
 | 
			
		||||
                });
 | 
			
		||||
                handled = true;
 | 
			
		||||
                break;
 | 
			
		||||
            case KeyAction.RoomScrollUp:
 | 
			
		||||
            case KeyAction.RoomScrollDown:
 | 
			
		||||
            case KeyAction.RoomJumpToFirstMessage:
 | 
			
		||||
            case KeyAction.RoomJumpToLatestMessage:
 | 
			
		||||
                this._onScrollKeyPressed(ev);
 | 
			
		||||
                handled = true;
 | 
			
		||||
                break;
 | 
			
		||||
            case KeyAction.RoomSearch:
 | 
			
		||||
                dis.dispatch({
 | 
			
		||||
                    action: 'focus_search',
 | 
			
		||||
                });
 | 
			
		||||
                handled = true;
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
        if (handled) {
 | 
			
		||||
            ev.stopPropagation();
 | 
			
		||||
            ev.preventDefault();
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
            case Key.HOME:
 | 
			
		||||
            case Key.END:
 | 
			
		||||
                if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey) {
 | 
			
		||||
                    this._onScrollKeyPressed(ev);
 | 
			
		||||
                    handled = true;
 | 
			
		||||
                }
 | 
			
		||||
        const navAction = getKeyBindingsManager().getAction(KeyBindingContext.Navigation, ev);
 | 
			
		||||
        switch (navAction) {
 | 
			
		||||
            case KeyAction.NavToggleUserMenu:
 | 
			
		||||
                dis.fire(Action.ToggleUserMenu);
 | 
			
		||||
                handled = true;
 | 
			
		||||
                break;
 | 
			
		||||
            case Key.K:
 | 
			
		||||
                if (ctrlCmdOnly) {
 | 
			
		||||
                    dis.dispatch({
 | 
			
		||||
                        action: 'focus_room_filter',
 | 
			
		||||
                    });
 | 
			
		||||
                    handled = true;
 | 
			
		||||
                }
 | 
			
		||||
            case KeyAction.NavToggleShortCutDialog:
 | 
			
		||||
                KeyboardShortcuts.toggleDialog();
 | 
			
		||||
                handled = true;
 | 
			
		||||
                break;
 | 
			
		||||
            case Key.F:
 | 
			
		||||
                if (ctrlCmdOnly && SettingsStore.getValue("ctrlFForSearch")) {
 | 
			
		||||
                    dis.dispatch({
 | 
			
		||||
                        action: 'focus_search',
 | 
			
		||||
                    });
 | 
			
		||||
                    handled = true;
 | 
			
		||||
                }
 | 
			
		||||
            case KeyAction.NavGoToHome:
 | 
			
		||||
                dis.dispatch({
 | 
			
		||||
                    action: 'view_home_page',
 | 
			
		||||
                });
 | 
			
		||||
                Modal.closeCurrentModal("homeKeyboardShortcut");
 | 
			
		||||
                handled = true;
 | 
			
		||||
                break;
 | 
			
		||||
            case Key.BACKTICK:
 | 
			
		||||
                // Ideally this would be CTRL+P for "Profile", but that's
 | 
			
		||||
                // taken by the print dialog. CTRL+I for "Information"
 | 
			
		||||
                // was previously chosen but conflicted with italics in
 | 
			
		||||
                // composer, so CTRL+` it is
 | 
			
		||||
 | 
			
		||||
                if (ctrlCmdOnly) {
 | 
			
		||||
                    dis.fire(Action.ToggleUserMenu);
 | 
			
		||||
                    handled = true;
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case Key.SLASH:
 | 
			
		||||
                if (isOnlyCtrlOrCmdIgnoreShiftKeyEvent(ev)) {
 | 
			
		||||
                    KeyboardShortcuts.toggleDialog();
 | 
			
		||||
                    handled = true;
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case Key.H:
 | 
			
		||||
                if (ev.altKey && modKey) {
 | 
			
		||||
                    dis.dispatch({
 | 
			
		||||
                        action: 'view_home_page',
 | 
			
		||||
                    });
 | 
			
		||||
                    Modal.closeCurrentModal("homeKeyboardShortcut");
 | 
			
		||||
                    handled = true;
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case Key.ARROW_UP:
 | 
			
		||||
            case Key.ARROW_DOWN:
 | 
			
		||||
                if (ev.altKey && !ev.ctrlKey && !ev.metaKey) {
 | 
			
		||||
                    dis.dispatch<ViewRoomDeltaPayload>({
 | 
			
		||||
                        action: Action.ViewRoomDelta,
 | 
			
		||||
                        delta: ev.key === Key.ARROW_UP ? -1 : 1,
 | 
			
		||||
                        unread: ev.shiftKey,
 | 
			
		||||
                    });
 | 
			
		||||
                    handled = true;
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case Key.PERIOD:
 | 
			
		||||
                if (ctrlCmdOnly && (this.props.page_type === "room_view" || this.props.page_type === "group_view")) {
 | 
			
		||||
            case KeyAction.NavToggleRoomSidePanel:
 | 
			
		||||
                if (this.props.page_type === "room_view" || this.props.page_type === "group_view") {
 | 
			
		||||
                    dis.dispatch<ToggleRightPanelPayload>({
 | 
			
		||||
                        action: Action.ToggleRightPanel,
 | 
			
		||||
                        type: this.props.page_type === "room_view" ? "room" : "group",
 | 
			
		||||
@@ -486,16 +455,47 @@ class LoggedInView extends React.Component<IProps, IState> {
 | 
			
		||||
                    handled = true;
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            default:
 | 
			
		||||
                // if we do not have a handler for it, pass it to the platform which might
 | 
			
		||||
                handled = PlatformPeg.get().onKeyDown(ev);
 | 
			
		||||
            case KeyAction.NavSelectPrevRoom:
 | 
			
		||||
                dis.dispatch<ViewRoomDeltaPayload>({
 | 
			
		||||
                    action: Action.ViewRoomDelta,
 | 
			
		||||
                    delta: -1,
 | 
			
		||||
                    unread: false,
 | 
			
		||||
                });
 | 
			
		||||
                handled = true;
 | 
			
		||||
                break;
 | 
			
		||||
            case KeyAction.NavSelectNextRoom:
 | 
			
		||||
                dis.dispatch<ViewRoomDeltaPayload>({
 | 
			
		||||
                    action: Action.ViewRoomDelta,
 | 
			
		||||
                    delta: 1,
 | 
			
		||||
                    unread: false,
 | 
			
		||||
                });
 | 
			
		||||
                handled = true;
 | 
			
		||||
                break;
 | 
			
		||||
            case KeyAction.NavSelectPrevUnreadRoom:
 | 
			
		||||
                dis.dispatch<ViewRoomDeltaPayload>({
 | 
			
		||||
                    action: Action.ViewRoomDelta,
 | 
			
		||||
                    delta: -1,
 | 
			
		||||
                    unread: true,
 | 
			
		||||
                });
 | 
			
		||||
                break;
 | 
			
		||||
            case KeyAction.NavSelectNextUnreadRoom:
 | 
			
		||||
                dis.dispatch<ViewRoomDeltaPayload>({
 | 
			
		||||
                    action: Action.ViewRoomDelta,
 | 
			
		||||
                    delta: 1,
 | 
			
		||||
                    unread: true,
 | 
			
		||||
                });
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // if we do not have a handler for it, pass it to the platform which might
 | 
			
		||||
        handled = PlatformPeg.get().onKeyDown(ev);
 | 
			
		||||
        if (handled) {
 | 
			
		||||
            ev.stopPropagation();
 | 
			
		||||
            ev.preventDefault();
 | 
			
		||||
        } else if (!isModifier && !ev.altKey && !ev.ctrlKey && !ev.metaKey) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const isModifier = ev.key === Key.ALT || ev.key === Key.CONTROL || ev.key === Key.META || ev.key === Key.SHIFT;
 | 
			
		||||
        if (!isModifier && !ev.altKey && !ev.ctrlKey && !ev.metaKey) {
 | 
			
		||||
            // The above condition is crafted to _allow_ characters with Shift
 | 
			
		||||
            // already pressed (but not the Shift key down itself).
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user