This commit is contained in:
redphx
2024-12-05 17:10:39 +07:00
parent c836e33f7b
commit 9199351af1
207 changed files with 9833 additions and 6953 deletions

View File

@@ -0,0 +1,151 @@
import { t } from "@/utils/translation";
import { BaseProfileManagerDialog } from "./base-profile-manager-dialog";
import type { KeyboardShortcutPresetData, KeyboardShortcutPresetRecord } from "@/types/presets";
import { CE, createSettingRow } from "@/utils/html";
import { KeyboardShortcutDefaultId, KeyboardShortcutsTable } from "@/utils/local-db/keyboard-shortcuts-table";
import { SHORTCUT_ACTIONS } from "@/modules/shortcuts/shortcut-actions";
import { BxKeyBindingButton, BxKeyBindingButtonFlag } from "@/web-components/bx-key-binding-button";
import type { ShortcutAction } from "@/enums/shortcut-actions";
import { deepClone } from "@/utils/global";
import { StreamSettings } from "@/utils/stream-settings";
type KeyboardShortcutButtonDataset = {
action: ShortcutAction,
}
export class KeyboardShortcutsManagerDialog extends BaseProfileManagerDialog<KeyboardShortcutPresetRecord> {
private static instance: KeyboardShortcutsManagerDialog;
public static getInstance = () => KeyboardShortcutsManagerDialog.instance ?? (KeyboardShortcutsManagerDialog.instance = new KeyboardShortcutsManagerDialog(t('keyboard-shortcuts')));
// private readonly LOG_TAG = 'KeyboardShortcutsManagerDialog';
protected $content: HTMLElement;
private readonly allKeyElements: BxKeyBindingButton[] = [];
protected readonly BLANK_PRESET_DATA: KeyboardShortcutPresetData = {
mapping: {},
};
constructor(title: string) {
super(title, KeyboardShortcutsTable.getInstance());
const $rows = CE('div', { class: 'bx-keyboard-shortcuts-manager-container' });
for (const groupLabel in SHORTCUT_ACTIONS) {
const items = SHORTCUT_ACTIONS[groupLabel];
if (!items) {
continue;
}
const $fieldSet = CE<HTMLFieldSetElement>('fieldset', {}, CE('legend', {}, groupLabel));
for (const action in items) {
const crumbs = items[action as keyof typeof items];
if (!crumbs) {
continue;
}
const label = crumbs.join(' ');
const $btn = BxKeyBindingButton.create({
title: label,
isPrompt: false,
onChanged: this.onKeyChanged,
allowedFlags: [BxKeyBindingButtonFlag.KEYBOARD_PRESS, BxKeyBindingButtonFlag.KEYBOARD_MODIFIER],
});
$btn.classList.add('bx-full-width');
$btn.dataset.action = action;
this.allKeyElements.push($btn);
const $row = createSettingRow(label, CE('div', { class: 'bx-binding-button-wrapper' }, $btn));
$fieldSet.appendChild($row);
}
// Don't append empty <fieldset>
if ($fieldSet.childElementCount > 1) {
$rows.appendChild($fieldSet);
}
}
this.$content = CE('div', {}, $rows);
}
private onKeyChanged = (e: Event) => {
const $current = e.target as BxKeyBindingButton;
const keyInfo = $current.keyInfo;
// Unbind duplicated keys
if (keyInfo) {
for (const $elm of this.allKeyElements) {
if ($elm === $current) {
continue;
}
if ($elm.keyInfo?.code === keyInfo.code && $elm.keyInfo?.modifiers === keyInfo.modifiers) {
// Unbind manually
$elm.unbindKey(true);
}
}
}
// Save preset
this.savePreset();
}
private parseDataset($btn: BxKeyBindingButton): KeyboardShortcutButtonDataset {
const dataset = $btn.dataset;
return {
action: dataset.action as ShortcutAction,
};
}
protected switchPreset(id: number): void {
const preset = this.allPresets.data[id];
if (!preset) {
this.currentPresetId = KeyboardShortcutDefaultId.OFF;
return;
}
const presetData = preset.data;
this.currentPresetId = id;
const isDefaultPreset = id <= 0;
this.updateButtonStates();
// Update buttons
for (const $elm of this.allKeyElements) {
const { action } = this.parseDataset($elm);
const keyInfo = presetData.mapping[action];
if (keyInfo) {
$elm.bindKey(keyInfo, true)
} else {
$elm.unbindKey(true);
}
$elm.disabled = isDefaultPreset;
}
}
private savePreset() {
const presetData = deepClone(this.BLANK_PRESET_DATA) as KeyboardShortcutPresetData;
// Get mapping
for (const $elm of this.allKeyElements) {
const { action } = this.parseDataset($elm);
const mapping = presetData.mapping;
if ($elm.keyInfo) {
mapping[action] = $elm.keyInfo;
}
}
const oldPreset = this.allPresets.data[this.currentPresetId];
const newPreset = {
id: this.currentPresetId,
name: oldPreset.name,
data: presetData,
};
this.presetsDb.updatePreset(newPreset);
this.allPresets.data[this.currentPresetId] = newPreset;
StreamSettings.refreshKeyboardShortcuts();
}
}