addons/isl/src/ISLShortcuts.tsxblame
View source
b69ab311/**
b69ab312 * Copyright (c) Meta Platforms, Inc. and affiliates.
b69ab313 *
b69ab314 * This source code is licensed under the MIT license found in the
b69ab315 * LICENSE file in the root directory of this source tree.
b69ab316 */
b69ab317
b69ab318import {Kbd} from 'isl-components/Kbd';
b69ab319import {KeyCode, makeCommandDispatcher, Modifier} from 'isl-components/KeyboardShortcuts';
b69ab3110import {isMac} from 'isl-components/OperatingSystem';
b69ab3111import {useMemo} from 'react';
b69ab3112import {TypedEventEmitter} from 'shared/TypedEventEmitter';
b69ab3113import {t} from './i18n';
b69ab3114import {useModal} from './useModal';
b69ab3115
b69ab3116import './ISLShortcuts.css';
b69ab3117
b69ab3118const CMD = isMac ? Modifier.CMD : Modifier.CTRL;
b69ab3119
b69ab3120/* eslint-disable no-bitwise */
b69ab3121export const [ISLCommandContext, useCommand, dispatchCommand, allCommands] = makeCommandDispatcher({
b69ab3122 OpenShortcutHelp: [Modifier.SHIFT, KeyCode.QuestionMark],
b69ab3123 ToggleSidebar: [CMD, KeyCode.Period],
b69ab3124 OpenUncommittedChangesComparisonView: [CMD, KeyCode.SingleQuote],
b69ab3125 OpenHeadChangesComparisonView: [[CMD, Modifier.SHIFT], KeyCode.SingleQuote],
b69ab3126 Escape: [Modifier.NONE, KeyCode.Escape],
b69ab3127 SelectUpwards: [Modifier.NONE, KeyCode.UpArrow],
b69ab3128 SelectDownwards: [Modifier.NONE, KeyCode.DownArrow],
b69ab3129 OpenDetails: [Modifier.NONE, KeyCode.RightArrow],
b69ab3130 ContinueSelectionUpwards: [Modifier.SHIFT, KeyCode.UpArrow],
b69ab3131 ContinueSelectionDownwards: [Modifier.SHIFT, KeyCode.DownArrow],
b69ab3132 SelectAllCommits: [Modifier.ALT, KeyCode.A],
b69ab3133 HideSelectedCommits: [Modifier.NONE, KeyCode.Backspace],
b69ab3134 ZoomIn: [Modifier.ALT, KeyCode.Plus],
b69ab3135 ZoomOut: [Modifier.ALT, KeyCode.Minus],
b69ab3136 ToggleTheme: [Modifier.ALT, KeyCode.T],
b69ab3137 ToggleShelvedChangesDropdown: [Modifier.ALT, KeyCode.S],
b69ab3138 ToggleDownloadCommitsDropdown: [Modifier.ALT, KeyCode.D],
b69ab3139 ToggleCwdDropdown: [Modifier.ALT, KeyCode.C],
b69ab3140 ToggleBulkActionsDropdown: [Modifier.ALT, KeyCode.B],
b69ab3141 ToggleFocusMode: [Modifier.ALT, KeyCode.F],
b69ab3142 ToggleBookmarksManagerDropdown: [Modifier.ALT, KeyCode.M],
b69ab3143 RebaseOntoCurrentStackBase: [Modifier.ALT, KeyCode.R],
b69ab3144});
b69ab3145
b69ab3146export type ISLCommandName = Parameters<typeof useCommand>[0];
b69ab3147
b69ab3148/** Like useCommand, but returns an eventEmitter you can subscribe to */
b69ab3149export function useCommandEvent(commandName: ISLCommandName): TypedEventEmitter<'change', null> {
b69ab3150 const emitter = useMemo(() => new TypedEventEmitter<'change', null>(), []);
b69ab3151 useCommand(commandName, () => {
b69ab3152 emitter.emit('change', null);
b69ab3153 });
b69ab3154 return emitter;
b69ab3155}
b69ab3156
b69ab3157export const ISLShortcutLabels: Partial<Record<ISLCommandName, string>> = {
b69ab3158 Escape: t('Dismiss Tooltips and Popups'),
b69ab3159 OpenShortcutHelp: t('Open Shortcut Help'),
b69ab3160 ToggleSidebar: t('Toggle Commit Info Sidebar'),
b69ab3161 OpenUncommittedChangesComparisonView: t('Open Uncommitted Changes Comparison View'),
b69ab3162 OpenHeadChangesComparisonView: t('Open Head Changes Comparison View'),
b69ab3163 SelectAllCommits: t('Select All Commits'),
b69ab3164 ToggleTheme: t('Toggle Light/Dark Theme'),
b69ab3165 ZoomIn: t('Zoom In'),
b69ab3166 ZoomOut: t('Zoom Out'),
b69ab3167 ToggleShelvedChangesDropdown: t('Toggle Shelved Changes Dropdown'),
b69ab3168 ToggleDownloadCommitsDropdown: t('Toggle Download Commits Dropdown'),
b69ab3169 ToggleCwdDropdown: t('Toggle CWD Dropdown'),
b69ab3170 ToggleBulkActionsDropdown: t('Toggle Bulk Actions Dropdown'),
b69ab3171 ToggleFocusMode: t('Toggle Focus Mode'),
b69ab3172 ToggleBookmarksManagerDropdown: t('Toggle Bookmarks Manager Dropdown'),
b69ab3173 RebaseOntoCurrentStackBase: t('Rebase Selected Commits onto Current Stack Base'),
b69ab3174};
b69ab3175
b69ab3176export function useShowKeyboardShortcutsHelp(): () => unknown {
b69ab3177 const showModal = useModal();
b69ab3178 const showShortcutsModal = () => {
b69ab3179 showModal({
b69ab3180 type: 'custom',
b69ab3181 component: () => (
b69ab3182 <div className="keyboard-shortcuts-menu">
b69ab3183 <table>
b69ab3184 {(Object.entries(ISLShortcutLabels) as Array<[ISLCommandName, string]>).map(
b69ab3185 ([name, label]) => {
b69ab3186 const [modifiers, keyCode] = allCommands[name];
b69ab3187 {
b69ab3188 return (
b69ab3189 <tr key={name}>
b69ab3190 <td>{label}</td>
b69ab3191 <td>
b69ab3192 <Kbd
b69ab3193 modifiers={Array.isArray(modifiers) ? modifiers : [modifiers]}
b69ab3194 keycode={keyCode}
b69ab3195 />
b69ab3196 </td>
b69ab3197 </tr>
b69ab3198 );
b69ab3199 }
b69ab31100 },
b69ab31101 )}
b69ab31102 </table>
b69ab31103 </div>
b69ab31104 ),
b69ab31105 icon: 'keyboard',
b69ab31106 title: t('Keyboard Shortcuts'),
b69ab31107 });
b69ab31108 };
b69ab31109 useCommand('OpenShortcutHelp', showShortcutsModal);
b69ab31110 return showShortcutsModal;
b69ab31111}