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

Commit 1f29825

Browse files
Make the Keyboard Shortcuts dialog into a settings tab (#7198)
1 parent cb42173 commit 1f29825

File tree

13 files changed

+191
-155
lines changed

13 files changed

+191
-155
lines changed

res/css/_components.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@
9595
@import "./views/dialogs/_IncomingSasDialog.scss";
9696
@import "./views/dialogs/_InviteDialog.scss";
9797
@import "./views/dialogs/_JoinRuleDropdown.scss";
98-
@import "./views/dialogs/_KeyboardShortcutsDialog.scss";
9998
@import "./views/dialogs/_LeaveSpaceDialog.scss";
10099
@import "./views/dialogs/_LocationViewDialog.scss";
101100
@import "./views/dialogs/_ManageRestrictedJoinRuleDialog.scss";
@@ -286,6 +285,7 @@
286285
@import "./views/settings/tabs/user/_AppearanceUserSettingsTab.scss";
287286
@import "./views/settings/tabs/user/_GeneralUserSettingsTab.scss";
288287
@import "./views/settings/tabs/user/_HelpUserSettingsTab.scss";
288+
@import "./views/settings/tabs/user/_KeyboardUserSettingsTab.scss";
289289
@import "./views/settings/tabs/user/_LabsUserSettingsTab.scss";
290290
@import "./views/settings/tabs/user/_MjolnirUserSettingsTab.scss";
291291
@import "./views/settings/tabs/user/_NotificationUserSettingsTab.scss";

res/css/views/dialogs/_UserSettingsDialog.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ limitations under the License.
3737
mask-image: url('$(res)/img/element-icons/settings/preference.svg');
3838
}
3939

40+
.mx_UserSettingsDialog_keyboardIcon::before {
41+
mask-image: url('$(res)/img/element-icons/settings/keyboard.svg');
42+
}
43+
4044
.mx_UserSettingsDialog_sidebarIcon::before {
4145
mask-image: url('$(res)/img/element-icons/settings/sidebar.svg');
4246
}

res/css/views/dialogs/_KeyboardShortcutsDialog.scss renamed to res/css/views/settings/tabs/user/_KeyboardUserSettingsTab.scss

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
Copyright 2020 The Matrix.org Foundation C.I.C.
3+
Copyright 2021 Šimon Brandner <[email protected]>
34
45
Licensed under the Apache License, Version 2.0 (the "License");
56
you may not use this file except in compliance with the License.
@@ -14,7 +15,7 @@ See the License for the specific language governing permissions and
1415
limitations under the License.
1516
*/
1617

17-
.mx_KeyboardShortcutsDialog {
18+
.mx_KeyboardUserSettingsTab .mx_SettingsTab_section {
1819
display: flex;
1920
flex-wrap: wrap;
2021
-webkit-box-orient: vertical;
Lines changed: 3 additions & 0 deletions
Loading

src/KeyBindingsDefaults.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -355,14 +355,14 @@ const navigationBindings = (): KeyBinding<NavigationAction>[] => {
355355
},
356356
},
357357
{
358-
action: NavigationAction.ToggleShortCutDialog,
358+
action: NavigationAction.OpenShortCutDialog,
359359
keyCombo: {
360360
key: Key.SLASH,
361361
ctrlOrCmd: true,
362362
},
363363
},
364364
{
365-
action: NavigationAction.ToggleShortCutDialog,
365+
action: NavigationAction.OpenShortCutDialog,
366366
keyCombo: {
367367
key: Key.SLASH,
368368
ctrlOrCmd: true,

src/KeyBindingsManager.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ export enum NavigationAction {
112112
/** Toggle the user menu */
113113
ToggleUserMenu = 'ToggleUserMenu',
114114
/** Toggle the short cut help dialog */
115-
ToggleShortCutDialog = 'ToggleShortCutDialog',
115+
OpenShortCutDialog = 'OpenShortCutDialog',
116116
/** Got to the Element home screen */
117117
GoToHome = 'GoToHome',
118118
/** Select prev room */

src/accessibility/KeyboardShortcuts.tsx renamed to src/accessibility/KeyboardShortcuts.ts

Lines changed: 4 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,8 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
import * as React from "react";
18-
import classNames from "classnames";
19-
20-
import Modal from "../Modal";
21-
import { _t, _td } from "../languageHandler";
17+
import { _td } from "../languageHandler";
2218
import { isMac, Key } from "../Keyboard";
23-
import InfoDialog from "../components/views/dialogs/InfoDialog";
24-
25-
// TS: once languageHandler is TS we can probably inline this into the enum
26-
_td("Navigation");
27-
_td("Calls");
28-
_td("Composer");
29-
_td("Room List");
30-
_td("Autocomplete");
3119

3220
export enum Categories {
3321
NAVIGATION = "Navigation",
@@ -38,13 +26,6 @@ export enum Categories {
3826
AUTOCOMPLETE = "Autocomplete",
3927
}
4028

41-
// TS: once languageHandler is TS we can probably inline this into the enum
42-
_td("Alt");
43-
_td("Alt Gr");
44-
_td("Shift");
45-
_td("Super");
46-
_td("Ctrl");
47-
4829
export enum Modifiers {
4930
ALT = "Alt", // Option on Mac and displayed as an Icon
5031
ALT_GR = "Alt Gr",
@@ -65,12 +46,12 @@ interface IKeybind {
6546
key: string; // TS: fix this once Key is an enum
6647
}
6748

68-
interface IShortcut {
49+
export interface IShortcut {
6950
keybinds: IKeybind[];
7051
description: string;
7152
}
7253

73-
const shortcuts: Record<Categories, IShortcut[]> = {
54+
export const shortcuts: Record<Categories, IShortcut[]> = {
7455
[Categories.COMPOSER]: [
7556
{
7657
keybinds: [{
@@ -270,7 +251,7 @@ const shortcuts: Record<Categories, IShortcut[]> = {
270251
modifiers: [CMD_OR_CTRL],
271252
key: Key.SLASH,
272253
}],
273-
description: _td("Toggle this dialog"),
254+
description: _td("Open this settings tab"),
274255
}, {
275256
keybinds: [{
276257
modifiers: [Modifiers.CONTROL, isMac ? Modifiers.SHIFT : Modifiers.ALT],
@@ -297,107 +278,6 @@ const shortcuts: Record<Categories, IShortcut[]> = {
297278
],
298279
};
299280

300-
const categoryOrder = [
301-
Categories.COMPOSER,
302-
Categories.AUTOCOMPLETE,
303-
Categories.ROOM,
304-
Categories.ROOM_LIST,
305-
Categories.NAVIGATION,
306-
Categories.CALLS,
307-
];
308-
309-
interface IModal {
310-
close: () => void;
311-
finished: Promise<any[]>;
312-
}
313-
314-
const modifierIcon: Record<string, string> = {
315-
[Modifiers.COMMAND]: "⌘",
316-
};
317-
318-
if (isMac) {
319-
modifierIcon[Modifiers.ALT] = "⌥";
320-
}
321-
322-
const alternateKeyName: Record<string, string> = {
323-
[Key.PAGE_UP]: _td("Page Up"),
324-
[Key.PAGE_DOWN]: _td("Page Down"),
325-
[Key.ESCAPE]: _td("Esc"),
326-
[Key.ENTER]: _td("Enter"),
327-
[Key.SPACE]: _td("Space"),
328-
[Key.HOME]: _td("Home"),
329-
[Key.END]: _td("End"),
330-
[DIGITS]: _td("[number]"),
331-
};
332-
const keyIcon: Record<string, string> = {
333-
[Key.ARROW_UP]: "↑",
334-
[Key.ARROW_DOWN]: "↓",
335-
[Key.ARROW_LEFT]: "←",
336-
[Key.ARROW_RIGHT]: "→",
337-
};
338-
339-
const Shortcut: React.FC<{
340-
shortcut: IShortcut;
341-
}> = ({ shortcut }) => {
342-
const classes = classNames({
343-
"mx_KeyboardShortcutsDialog_inline": shortcut.keybinds.every(k => !k.modifiers || k.modifiers.length === 0),
344-
});
345-
346-
return <div className={classes}>
347-
<h5>{ _t(shortcut.description) }</h5>
348-
{ shortcut.keybinds.map(s => {
349-
let text = s.key;
350-
if (alternateKeyName[s.key]) {
351-
text = _t(alternateKeyName[s.key]);
352-
} else if (keyIcon[s.key]) {
353-
text = keyIcon[s.key];
354-
}
355-
356-
return <div key={s.key}>
357-
{ s.modifiers?.map(m => {
358-
return <React.Fragment key={m}>
359-
<kbd>{ modifierIcon[m] || _t(m) }</kbd>+
360-
</React.Fragment>;
361-
}) }
362-
<kbd>{ text }</kbd>
363-
</div>;
364-
}) }
365-
</div>;
366-
};
367-
368-
let activeModal: IModal = null;
369-
export const toggleDialog = () => {
370-
if (activeModal) {
371-
activeModal.close();
372-
activeModal = null;
373-
return;
374-
}
375-
376-
const sections = categoryOrder.map(category => {
377-
const list = shortcuts[category];
378-
return <div className="mx_KeyboardShortcutsDialog_category" key={category}>
379-
<h3>{ _t(category) }</h3>
380-
<div>{ list.map(shortcut => <Shortcut key={shortcut.description} shortcut={shortcut} />) }</div>
381-
</div>;
382-
});
383-
384-
activeModal = Modal.createTrackedDialog("Keyboard Shortcuts", "", InfoDialog, {
385-
className: "mx_KeyboardShortcutsDialog",
386-
title: _t("Keyboard Shortcuts"),
387-
description: sections,
388-
hasCloseButton: true,
389-
onKeyDown: (ev) => {
390-
if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey && ev.key === Key.SLASH) { // Ctrl + /
391-
ev.stopPropagation();
392-
activeModal.close();
393-
}
394-
},
395-
onFinished: () => {
396-
activeModal = null;
397-
},
398-
});
399-
};
400-
401281
export const registerShortcut = (category: Categories, defn: IShortcut) => {
402282
shortcuts[category].push(defn);
403283
};

src/components/structures/LoggedInView.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ import SettingsStore from "../../settings/SettingsStore";
3232
import ResizeHandle from '../views/elements/ResizeHandle';
3333
import { CollapseDistributor, Resizer } from '../../resizer';
3434
import MatrixClientContext from "../../contexts/MatrixClientContext";
35-
import * as KeyboardShortcuts from "../../accessibility/KeyboardShortcuts";
3635
import HomePage from "./HomePage";
3736
import ResizeNotifier from "../../utils/ResizeNotifier";
3837
import PlatformPeg from "../../PlatformPeg";
@@ -67,6 +66,8 @@ import GroupFilterPanel from './GroupFilterPanel';
6766
import CustomRoomTagPanel from './CustomRoomTagPanel';
6867
import { mediaFromMxc } from "../../customisations/Media";
6968
import LegacyCommunityPreview from "./LegacyCommunityPreview";
69+
import { UserTab } from "../views/dialogs/UserSettingsDialog";
70+
import { OpenToTabPayload } from "../../dispatcher/payloads/OpenToTabPayload";
7071
import RightPanelStore from '../../stores/right-panel/RightPanelStore';
7172

7273
// We need to fetch each pinned message individually (if we don't already have it)
@@ -472,8 +473,11 @@ class LoggedInView extends React.Component<IProps, IState> {
472473
dis.fire(Action.ToggleUserMenu);
473474
handled = true;
474475
break;
475-
case NavigationAction.ToggleShortCutDialog:
476-
KeyboardShortcuts.toggleDialog();
476+
case NavigationAction.OpenShortCutDialog:
477+
dis.dispatch<OpenToTabPayload>({
478+
action: Action.ViewUserSettings,
479+
initialTabId: UserTab.Keyboard,
480+
});
477481
handled = true;
478482
break;
479483
case NavigationAction.GoToHome:

src/components/views/dialogs/UserSettingsDialog.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,15 @@ import { replaceableComponent } from "../../../utils/replaceableComponent";
3636
import BaseDialog from "./BaseDialog";
3737
import { IDialogProps } from "./IDialogProps";
3838
import SidebarUserSettingsTab from "../settings/tabs/user/SidebarUserSettingsTab";
39+
import KeyboardUserSettingsTab from "../settings/tabs/user/KeyboardUserSettingsTab";
3940

4041
export enum UserTab {
4142
General = "USER_GENERAL_TAB",
4243
Appearance = "USER_APPEARANCE_TAB",
4344
Flair = "USER_FLAIR_TAB",
4445
Notifications = "USER_NOTIFICATIONS_TAB",
4546
Preferences = "USER_PREFERENCES_TAB",
47+
Keyboard = "USER_KEYBOARD_TAB",
4648
Sidebar = "USER_SIDEBAR_TAB",
4749
Voice = "USER_VOICE_TAB",
4850
Security = "USER_SECURITY_TAB",
@@ -119,6 +121,12 @@ export default class UserSettingsDialog extends React.Component<IProps, IState>
119121
"mx_UserSettingsDialog_preferencesIcon",
120122
<PreferencesUserSettingsTab closeSettingsFn={this.props.onFinished} />,
121123
));
124+
tabs.push(new Tab(
125+
UserTab.Keyboard,
126+
_td("Keyboard"),
127+
"mx_UserSettingsDialog_keyboardIcon",
128+
<KeyboardUserSettingsTab />,
129+
));
122130

123131
if (SettingsStore.getValue("feature_spaces_metaspaces")) {
124132
tabs.push(new Tab(

src/components/views/settings/tabs/user/HelpUserSettingsTab.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,17 @@ import SdkConfig from "../../../../../SdkConfig";
2525
import createRoom from "../../../../../createRoom";
2626
import Modal from "../../../../../Modal";
2727
import PlatformPeg from "../../../../../PlatformPeg";
28-
import * as KeyboardShortcuts from "../../../../../accessibility/KeyboardShortcuts";
2928
import UpdateCheckButton from "../../UpdateCheckButton";
3029
import { replaceableComponent } from "../../../../../utils/replaceableComponent";
3130
import { copyPlaintext } from "../../../../../utils/strings";
3231
import * as ContextMenu from "../../../../structures/ContextMenu";
3332
import { toRightOf } from "../../../../structures/ContextMenu";
3433
import BugReportDialog from '../../../dialogs/BugReportDialog';
3534
import GenericTextContextMenu from "../../../context_menus/GenericTextContextMenu";
35+
import { OpenToTabPayload } from "../../../../../dispatcher/payloads/OpenToTabPayload";
36+
import { Action } from "../../../../../dispatcher/actions";
37+
import { UserTab } from "../../../dialogs/UserSettingsDialog";
38+
import dis from "../../../../../dispatcher/dispatcher";
3639

3740
interface IProps {
3841
closeSettingsFn: () => void;
@@ -211,6 +214,13 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState>
211214
this.copy(`${appVersion}\n${olmVersion}`, e);
212215
};
213216

217+
private onKeyboardShortcutsClicked = (): void => {
218+
dis.dispatch<OpenToTabPayload>({
219+
action: Action.ViewUserSettings,
220+
initialTabId: UserTab.Keyboard,
221+
});
222+
};
223+
214224
render() {
215225
const brand = SdkConfig.get().brand;
216226

@@ -307,7 +317,7 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState>
307317
<div className='mx_SettingsTab_subsectionText'>
308318
{ faqText }
309319
</div>
310-
<AccessibleButton kind="primary" onClick={KeyboardShortcuts.toggleDialog}>
320+
<AccessibleButton kind="primary" onClick={this.onKeyboardShortcutsClicked}>
311321
{ _t("Keyboard Shortcuts") }
312322
</AccessibleButton>
313323
</div>

0 commit comments

Comments
 (0)