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

Commit e73a70e

Browse files
committed
Rest
Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>
1 parent f33d662 commit e73a70e

File tree

3 files changed

+140
-7
lines changed

3 files changed

+140
-7
lines changed

res/css/views/settings/tabs/user/_KeyboardUserSettingsTab.scss

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,17 @@ limitations under the License.
1818
.mx_KeyboardUserSettingsTab .mx_SettingsTab_section {
1919
.mx_KeyboardShortcut_shortcutRow {
2020
display: flex;
21-
justify-content: space-between;
2221
align-items: center;
22+
23+
.mx_KeyboardShortcut_shortcutRow_displayName {
24+
margin-right: auto;
25+
}
26+
27+
.mx_AccessibleButton {
28+
margin: 0 4px;
29+
}
30+
31+
margin: 4px 0;
2332
}
2433

2534
kbd {
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
Copyright 2022 Šimon Brandner <simon.bra.ag@gmail.com>
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
import React, { KeyboardEvent, useState } from "react";
18+
19+
import { KeyCombo } from "../../../../../KeyBindingsManager";
20+
import { Key } from "../../../../../Keyboard";
21+
import { _t } from "../../../../../languageHandler";
22+
import BaseDialog from "../../../dialogs/BaseDialog";
23+
import { IDialogProps } from "../../../dialogs/IDialogProps";
24+
import DialogButtons from "../../../elements/DialogButtons";
25+
import KeyboardShortcut from "../../KeyboardShortcut";
26+
27+
const eventIntoKeyCombo = (event: KeyboardEvent): KeyCombo | null => {
28+
const hasModifier = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
29+
const isKeyAModifier = [Key.ALT, Key.CONTROL, Key.META, Key.SHIFT].includes(event.key);
30+
// Don't allow KeyCombos without modifiers
31+
if (!hasModifier) return null;
32+
// Don't allow KeyCombos without a key pressed
33+
if (isKeyAModifier || !event.key) return null;
34+
35+
return {
36+
key: event.key,
37+
altKey: event.altKey,
38+
ctrlKey: event.ctrlKey,
39+
metaKey: event.metaKey,
40+
shiftKey: event.shiftKey,
41+
};
42+
};
43+
44+
export interface IProps extends IDialogProps {
45+
value: KeyCombo;
46+
}
47+
48+
export const ChangeKeyboardShortcutDialog: React.FC<IProps> = ({ onFinished, value }) => {
49+
const [currentValue, setValue] = useState<KeyCombo | null>(value);
50+
51+
const onDialogFinished = () => {
52+
onFinished(currentValue);
53+
};
54+
55+
const onKeyDown = (event: KeyboardEvent): void => {
56+
event.preventDefault();
57+
event.stopPropagation();
58+
59+
const key = event.key;
60+
if (!key) return;
61+
62+
setValue(eventIntoKeyCombo(event));
63+
};
64+
65+
const onCancel = (): void => {
66+
onFinished(null);
67+
};
68+
69+
const onPrimaryButtonClick = (): void => {
70+
if (!currentValue) return;
71+
onFinished(currentValue);
72+
};
73+
74+
return <BaseDialog onFinished={onDialogFinished} onKeyDown={onKeyDown}>
75+
<KeyboardShortcut value={currentValue} />
76+
<DialogButtons primaryButton={_t("Done")} hasCancel onPrimaryButtonClick={onPrimaryButtonClick} onCancel={onCancel} />
77+
</BaseDialog>;
78+
};
79+
80+
export default ChangeKeyboardShortcutDialog;

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

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,41 +25,80 @@ import {
2525
import SdkConfig from "../../../../../SdkConfig";
2626
import { _t } from "../../../../../languageHandler";
2727
import {
28-
getKeyboardShortcutDisplayName, getKeyboardShortcutValue,
28+
getKeyboardShortcutDisplayName,
29+
getKeyboardShortcutHideEditUI,
30+
getKeyboardShortcutValue,
2931
} from "../../../../../accessibility/KeyboardShortcutUtils";
3032
import { KeyboardShortcut } from "../../KeyboardShortcut";
33+
import AccessibleButton from "../../../elements/AccessibleButton";
34+
import SettingsStore from "../../../../../settings/SettingsStore";
35+
import { SettingLevel } from "../../../../../settings/SettingLevel";
36+
import Modal from "../../../../../Modal";
37+
import {
38+
ChangeKeyboardShortcutDialog,
39+
IProps as IChangeKeyboardShortcutDialogProps,
40+
} from "./ChangeKeyboardShortcutDialog";
3141

3242
interface IKeyboardShortcutRowProps {
3343
name: string;
44+
allowCustomization: boolean;
3445
}
3546

3647
// Filter out the labs section if labs aren't enabled.
3748
const visibleCategories = Object.entries(CATEGORIES).filter(([categoryName]) =>
3849
categoryName !== CategoryName.LABS || SdkConfig.get()['showLabsSettings']);
3950

40-
const KeyboardShortcutRow: React.FC<IKeyboardShortcutRowProps> = ({ name }) => {
51+
const KeyboardShortcutRow: React.FC<IKeyboardShortcutRowProps> = ({ name, allowCustomization }) => {
4152
const displayName = getKeyboardShortcutDisplayName(name);
53+
const hideEditUI = getKeyboardShortcutHideEditUI(name);
4254
const value = getKeyboardShortcutValue(name);
4355
if (!displayName || !value) return null;
4456

57+
const onEditClick = async (): Promise<void> => {
58+
const { finished } = Modal.createDialog(ChangeKeyboardShortcutDialog, {
59+
value,
60+
} as IChangeKeyboardShortcutDialogProps);
61+
const [newValue] = await finished;
62+
if (!newValue) return;
63+
64+
//SettingsStore.setValue(name, null, SettingLevel.DEVICE, newValue);
65+
};
66+
67+
const onResetClick = (): void => {
68+
SettingsStore.setValue(name, null, SettingLevel.DEVICE, SettingsStore.getDefaultValue(name));
69+
};
70+
4571
return <div className="mx_KeyboardShortcut_shortcutRow">
46-
{ displayName }
72+
<div className="mx_KeyboardShortcut_shortcutRow_displayName">
73+
{ displayName }
74+
</div>
4775
<KeyboardShortcut value={value} />
76+
{ allowCustomization && <React.Fragment>
77+
<AccessibleButton kind="primary_outline" disabled={hideEditUI} onClick={onEditClick}> { _t("Edit") } </AccessibleButton>
78+
<AccessibleButton kind="primary_outline" disabled={hideEditUI} onClick={onResetClick}> { _t("Reset") } </AccessibleButton>
79+
</React.Fragment> }
4880
</div>;
4981
};
5082

5183
interface IKeyboardShortcutSectionProps {
5284
categoryName: CategoryName;
5385
category: ICategory;
86+
allowCustomization: boolean;
5487
}
5588

56-
const KeyboardShortcutSection: React.FC<IKeyboardShortcutSectionProps> = ({ categoryName, category }) => {
89+
const KeyboardShortcutSection: React.FC<IKeyboardShortcutSectionProps> = (
90+
{ categoryName, category, allowCustomization },
91+
) => {
5792
if (!category.categoryLabel) return null;
5893

5994
return <div className="mx_SettingsTab_section" key={categoryName}>
6095
<div className="mx_SettingsTab_subheading">{ _t(category.categoryLabel) }</div>
6196
<div> { category.settingNames.map((shortcutName) => {
62-
return <KeyboardShortcutRow key={shortcutName} name={shortcutName} />;
97+
return <KeyboardShortcutRow
98+
key={shortcutName}
99+
name={shortcutName}
100+
allowCustomization={allowCustomization}
101+
/>;
63102
}) } </div>
64103
</div>;
65104
};
@@ -68,7 +107,12 @@ const KeyboardUserSettingsTab: React.FC = () => {
68107
return <div className="mx_SettingsTab mx_KeyboardUserSettingsTab">
69108
<div className="mx_SettingsTab_heading">{ _t("Keyboard") }</div>
70109
{ visibleCategories.map(([categoryName, category]: [CategoryName, ICategory]) => {
71-
return <KeyboardShortcutSection key={categoryName} categoryName={categoryName} category={category} />;
110+
return <KeyboardShortcutSection
111+
key={categoryName}
112+
categoryName={categoryName}
113+
category={category}
114+
allowCustomization={SettingsStore.getValue("feature_customizable_keybindings")}
115+
/>;
72116
}) }
73117
</div>;
74118
};

0 commit comments

Comments
 (0)