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,205 @@
import { ButtonStyle, CE, createButton, renderPresetsList } from "@/utils/html";
import { NavigationDialog } from "../navigation-dialog";
import { BxIcon } from "@/utils/bx-icon";
import { t } from "@/utils/translation";
import type { AllPresets, PresetRecord } from "@/types/presets";
import type { BasePresetsTable } from "@/utils/local-db/base-presets-table";
import { BxSelectElement } from "@/web-components/bx-select";
export abstract class BaseProfileManagerDialog<T extends PresetRecord> extends NavigationDialog {
$container!: HTMLElement;
private title: string;
protected presetsDb: BasePresetsTable<T>;
protected allPresets!: AllPresets<T>;
protected currentPresetId: number = 0;
private $presets!: HTMLSelectElement;
private $header!: HTMLElement;
protected $content!: HTMLElement;
private $btnRename!: HTMLButtonElement;
private $btnDelete!: HTMLButtonElement;
protected abstract readonly BLANK_PRESET_DATA: T['data'];
constructor(title: string, presetsDb: BasePresetsTable<T>) {
super();
this.title = title;
this.presetsDb = presetsDb;
}
protected abstract switchPreset(id: number): void;
protected updateButtonStates() {
const isDefaultPreset = this.currentPresetId <= 0;
this.$btnRename.disabled = isDefaultPreset;
this.$btnDelete.disabled = isDefaultPreset;
}
private async renderPresetsList() {
this.allPresets = await this.presetsDb.getPresets();
if (!this.currentPresetId) {
this.currentPresetId = this.allPresets.default[0];
}
renderPresetsList<T>(this.$presets, this.allPresets, this.currentPresetId);
}
private promptNewName(action: string,value='') {
let newName: string | null = '';
while (!newName) {
newName = prompt(`[${action}] ${t('prompt-preset-name')}`, value);
if (newName === null) {
return false;
}
newName = newName.trim();
}
return newName ? newName : false;
};
private async renderDialog() {
this.$presets = CE<HTMLSelectElement>('select', { tabindex: -1 });
const $select = BxSelectElement.create(this.$presets);
$select.classList.add('bx-full-width');
$select.addEventListener('input', e => {
this.switchPreset(parseInt(($select as HTMLSelectElement).value));
});
const $header = CE('div', {
class: 'bx-dialog-preset-tools',
_nearby: {
orientation: 'horizontal',
focus: $select,
},
},
$select,
// Rename button
this.$btnRename = createButton({
title: t('rename'),
icon: BxIcon.CURSOR_TEXT,
style: ButtonStyle.FOCUSABLE,
onClick: async () => {
const preset = this.allPresets.data[this.currentPresetId];
const newName = this.promptNewName(t('rename'), preset.name);
if (!newName) {
return;
}
// Update preset with new name
preset.name = newName;
await this.presetsDb.updatePreset(preset);
await this.refresh();
},
}),
// Delete button
this.$btnDelete = createButton({
icon: BxIcon.TRASH,
title: t('delete'),
style: ButtonStyle.DANGER | ButtonStyle.FOCUSABLE,
onClick: async (e) => {
if (!confirm(t('confirm-delete-preset'))) {
return;
}
await this.presetsDb.deletePreset(this.currentPresetId);
delete this.allPresets.data[this.currentPresetId];
this.currentPresetId = parseInt(Object.keys(this.allPresets.data)[0]);
await this.refresh();
},
}),
// New button
createButton({
icon: BxIcon.NEW,
title: t('new'),
style: ButtonStyle.FOCUSABLE,
onClick: async (e) => {
const newName = this.promptNewName(t('new'));
if (!newName) {
return;
}
// Create new preset selected name
const newId = await this.presetsDb.newPreset(newName, this.BLANK_PRESET_DATA);
this.currentPresetId = newId;
await this.refresh();
},
}),
// Copy button
createButton({
icon: BxIcon.COPY,
title: t('copy'),
style: ButtonStyle.FOCUSABLE,
onClick: async (e) => {
const preset = this.allPresets.data[this.currentPresetId];
const newName = this.promptNewName(t('copy'), `${preset.name} (2)`);
if (!newName) {
return;
}
// Create new preset with selected name
const newId = await this.presetsDb.newPreset(newName, preset.data);
this.currentPresetId = newId;
await this.refresh();
},
}),
);
this.$header = $header;
this.$container = CE('div', { class: 'bx-centered-dialog' },
CE('div', { class: 'bx-dialog-title' },
CE('p', {}, this.title),
createButton({
icon: BxIcon.CLOSE,
style: ButtonStyle.FOCUSABLE | ButtonStyle.CIRCULAR | ButtonStyle.GHOST,
onClick: e => this.hide(),
}),
),
$header,
CE('div', { class: 'bx-dialog-content bx-hide-scroll-bar' }, this.$content),
);
}
async refresh() {
await this.renderPresetsList();
this.switchPreset(this.currentPresetId);
}
async onBeforeMount(configs:{ id?: number }={}) {
if (configs?.id) {
this.currentPresetId = configs.id;
}
// Select first preset
this.refresh();
}
getDialog(): NavigationDialog {
return this;
}
getContent(): HTMLElement {
if (!this.$container) {
this.renderDialog();
}
return this.$container;
}
focusIfNeeded(): void {
this.dialogManager.focus(this.$header);
}
}

View File

@@ -0,0 +1,194 @@
import { t } from "@/utils/translation";
import { BaseProfileManagerDialog } from "./base-profile-manager-dialog";
import { CE } from "@/utils/html";
import { GamepadKey, GamepadKeyName } from "@/enums/gamepad";
import { PrefKey } from "@/enums/pref-keys";
import { PrompFont } from "@/enums/prompt-font";
import { ShortcutAction } from "@/enums/shortcut-actions";
import { deepClone } from "@/utils/global";
import { setNearby } from "@/utils/navigation-utils";
import { getPref } from "@/utils/settings-storages/global-settings-storage";
import { BxSelectElement } from "@/web-components/bx-select";
import type { ControllerShortcutPresetData, ControllerShortcutPresetRecord } from "@/types/presets";
import { ControllerShortcutsTable } from "@/utils/local-db/controller-shortcuts-table";
import { BxEvent } from "@/utils/bx-event";
import { StreamSettings } from "@/utils/stream-settings";
import { SHORTCUT_ACTIONS } from "@/modules/shortcuts/shortcut-actions";
export class ControllerShortcutsManagerDialog extends BaseProfileManagerDialog<ControllerShortcutPresetRecord> {
private static instance: ControllerShortcutsManagerDialog;
public static getInstance = () => ControllerShortcutsManagerDialog.instance ?? (ControllerShortcutsManagerDialog.instance = new ControllerShortcutsManagerDialog(t('controller-shortcuts')));
// private readonly LOG_TAG = 'ControllerShortcutsManagerDialog';
protected $content: HTMLElement;
private selectActions: Partial<Record<GamepadKey, [HTMLSelectElement, HTMLSelectElement | null]>> = {};
protected readonly BLANK_PRESET_DATA = {
mapping: {},
};
private readonly BUTTONS_ORDER = [
GamepadKey.Y, GamepadKey.A, GamepadKey.X, GamepadKey.B,
GamepadKey.UP, GamepadKey.DOWN, GamepadKey.LEFT, GamepadKey.RIGHT,
GamepadKey.SELECT, GamepadKey.START,
GamepadKey.LB, GamepadKey.RB,
GamepadKey.LT, GamepadKey.RT,
GamepadKey.L3, GamepadKey.R3,
];
constructor(title: string) {
super(title, ControllerShortcutsTable.getInstance());
const PREF_CONTROLLER_FRIENDLY_UI = getPref(PrefKey.UI_CONTROLLER_FRIENDLY);
// Read actions from localStorage
// ControllerShortcut.ACTIONS = ControllerShortcut.getActionsFromStorage();
const $baseSelect = CE<HTMLSelectElement>('select', { autocomplete: 'off' }, CE('option', { value: '' }, '---'));
for (const groupLabel in SHORTCUT_ACTIONS) {
const items = SHORTCUT_ACTIONS[groupLabel];
if (!items) {
continue;
}
const $optGroup = CE<HTMLOptGroupElement>('optgroup', { label: groupLabel });
for (const action in items) {
const crumbs = items[action as keyof typeof items];
if (!crumbs) {
continue;
}
const label = crumbs.join(' ');
const $option = CE<HTMLOptionElement>('option', { value: action }, label);
$optGroup.appendChild($option);
}
$baseSelect.appendChild($optGroup);
}
const $content = CE('div', {
class: 'bx-controller-shortcuts-manager-container',
});
const onActionChanged = (e: Event) => {
const $target = e.target as HTMLSelectElement;
// const profile = $selectProfile.value;
// const button: unknown = $target.dataset.button;
const action = $target.value as ShortcutAction;
if (!PREF_CONTROLLER_FRIENDLY_UI) {
const $fakeSelect = $target.previousElementSibling! as HTMLSelectElement;
let fakeText = '---';
if (action) {
const $selectedOption = $target.options[$target.selectedIndex];
const $optGroup = $selectedOption.parentElement as HTMLOptGroupElement;
fakeText = $optGroup.label + ' ' + $selectedOption.text;
}
($fakeSelect.firstElementChild as HTMLOptionElement).text = fakeText;
}
// Update preset
if (!(e as any).ignoreOnChange) {
this.updatePreset();
}
};
const fragment = document.createDocumentFragment();
fragment.appendChild(CE('p', {class: 'bx-shortcut-note'},
CE('span', {class: 'bx-prompt'}, PrompFont.HOME),
': ' + t('controller-shortcuts-xbox-note'),
));
for (const button of this.BUTTONS_ORDER) {
const prompt = GamepadKeyName[button][1];
const $row = CE('div', {
class: 'bx-shortcut-row',
_nearby: {
orientation: 'horizontal',
},
});
const $label = CE('label', {class: 'bx-prompt'}, `${PrompFont.HOME}${prompt}`);
const $div = CE('div', {class: 'bx-shortcut-actions'});
let $fakeSelect: HTMLSelectElement | null = null;
if (!PREF_CONTROLLER_FRIENDLY_UI) {
$fakeSelect = CE<HTMLSelectElement>('select', { autocomplete: 'off' },
CE('option', {}, '---'),
);
$div.appendChild($fakeSelect);
}
const $select = BxSelectElement.create($baseSelect.cloneNode(true) as HTMLSelectElement);
$select.dataset.button = button.toString();
$select.classList.add('bx-full-width');
$select.addEventListener('input', onActionChanged);
this.selectActions[button] = [$select, $fakeSelect];
$div.appendChild($select);
setNearby($row, {
focus: $select,
});
$row.append($label, $div);
fragment.appendChild($row);
}
$content.appendChild(fragment);
this.$content = $content;
}
protected switchPreset(id: number): void {
const preset = this.allPresets.data[id];
if (!preset) {
this.currentPresetId = 0;
return;
}
this.currentPresetId = id;
const isDefaultPreset = id <= 0;
const actions = preset.data;
// Reset selects' values
let button: unknown;
for (button in this.selectActions) {
const [$select, $fakeSelect] = this.selectActions[button as GamepadKey]!;
$select.value = actions.mapping[button as GamepadKey] || '';
$select.disabled = isDefaultPreset;
$fakeSelect && ($fakeSelect.disabled = isDefaultPreset);
BxEvent.dispatch($select, 'input', {
ignoreOnChange: true,
manualTrigger: true,
});
}
super.updateButtonStates();
}
private updatePreset() {
const newData: ControllerShortcutPresetData = deepClone(this.BLANK_PRESET_DATA);
let button: unknown;
for (button in this.selectActions) {
const [$select, _] = this.selectActions[button as GamepadKey]!;
const action = $select.value;
if (!action) {
continue;
}
newData.mapping[button as GamepadKey] = action as ShortcutAction;
}
const preset = this.allPresets.data[this.currentPresetId];
preset.data = newData;
this.presetsDb.updatePreset(preset);
StreamSettings.refreshControllerSettings();
}
}

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();
}
}

View File

@@ -0,0 +1,254 @@
import type { MkbPresetData, MkbPresetRecord } from "@/types/presets";
import { BaseProfileManagerDialog } from "./base-profile-manager-dialog";
import { t } from "@/utils/translation";
import { MkbMappingPresetsTable } from "@/utils/local-db/mkb-mapping-presets-table";
import { GamepadKey, GamepadKeyName } from "@/enums/gamepad";
import { CE, createSettingRow } from "@/utils/html";
import { MouseMapTo, MkbPresetKey, type KeyCode } from "@/enums/mkb";
import { BxKeyBindingButton, BxKeyBindingButtonFlag } from "@/web-components/bx-key-binding-button";
import { StreamSettings } from "@/utils/stream-settings";
import { BxNumberStepper } from "@/web-components/bx-number-stepper";
import { deepClone } from "@/utils/global";
import { BxSelectElement } from "@/web-components/bx-select";
type MkbButtonDataset = {
keySlot: number,
buttonIndex: GamepadKey,
}
export class MkbMappingManagerDialog extends BaseProfileManagerDialog<MkbPresetRecord> {
private static instance: MkbMappingManagerDialog;
public static getInstance = () => MkbMappingManagerDialog.instance ?? (MkbMappingManagerDialog.instance = new MkbMappingManagerDialog(t('virtual-controller')));
declare protected $content: HTMLElement;
private readonly KEYS_PER_BUTTON = 2;
private readonly BUTTONS_ORDER = [
GamepadKey.HOME,
GamepadKey.UP, GamepadKey.DOWN, GamepadKey.LEFT, GamepadKey.RIGHT,
GamepadKey.A, GamepadKey.B, GamepadKey.X, GamepadKey.Y,
GamepadKey.LB, GamepadKey.RB, GamepadKey.LT, GamepadKey.RT,
GamepadKey.SELECT, GamepadKey.START,
GamepadKey.L3, GamepadKey.LS_UP, GamepadKey.LS_DOWN, GamepadKey.LS_LEFT, GamepadKey.LS_RIGHT,
GamepadKey.R3, GamepadKey.RS_UP, GamepadKey.RS_DOWN, GamepadKey.RS_LEFT, GamepadKey.RS_RIGHT,
];
protected readonly BLANK_PRESET_DATA: MkbPresetData = {
mapping: {},
mouse: {
[MkbPresetKey.MOUSE_MAP_TO]: MouseMapTo.RS,
[MkbPresetKey.MOUSE_SENSITIVITY_X]: 100,
[MkbPresetKey.MOUSE_SENSITIVITY_Y]: 100,
[MkbPresetKey.MOUSE_DEADZONE_COUNTERWEIGHT]: 20,
},
};
private readonly allKeyElements: BxKeyBindingButton[] = [];
private $mouseMapTo!: BxSelectElement;
private $mouseSensitivityX!: BxNumberStepper;
private $mouseSensitivityY!: BxNumberStepper;
private $mouseDeadzone!: BxNumberStepper;
constructor(title: string) {
super(title, MkbMappingPresetsTable.getInstance());
this.render();
}
private onBindingKey = (e: MouseEvent) => {
const $btn = e.target as HTMLButtonElement;
if ($btn.disabled) {
return;
}
if (e.button !== 0) {
return;
}
};
private parseDataset($btn: BxKeyBindingButton): MkbButtonDataset {
const dataset = $btn.dataset;
return {
keySlot: parseInt(dataset.keySlot!),
buttonIndex: parseInt(dataset.buttonIndex!),
};
}
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 && $elm.keyInfo?.code === keyInfo.code) {
// Unbind manually
$elm.unbindKey(true);
}
}
}
// Save preset
this.savePreset();
}
private render() {
const $rows = CE('div', {},
CE('i', { class: 'bx-mkb-note' }, t('right-click-to-unbind')),
);
for (const buttonIndex of this.BUTTONS_ORDER) {
const [buttonName, buttonPrompt] = GamepadKeyName[buttonIndex];
let $elm;
const $fragment = document.createDocumentFragment();
for (let i = 0; i < this.KEYS_PER_BUTTON; i++) {
$elm = BxKeyBindingButton.create({
title: buttonPrompt,
isPrompt: true,
allowedFlags: [BxKeyBindingButtonFlag.KEYBOARD_PRESS, BxKeyBindingButtonFlag.MOUSE_CLICK, BxKeyBindingButtonFlag.MOUSE_WHEEL],
onChanged: this.onKeyChanged,
});
$elm.dataset.buttonIndex = buttonIndex.toString();
$elm.dataset.keySlot = i.toString();
$elm.addEventListener('mouseup', this.onBindingKey);
$fragment.appendChild($elm);
this.allKeyElements.push($elm);
}
const $keyRow = CE('div', {
class: 'bx-mkb-key-row',
_nearby: {
orientation: 'horizontal',
},
},
CE('label', { title: buttonName }, buttonPrompt),
$fragment,
);
$rows.appendChild($keyRow);
}
const savePreset = () => this.savePreset();
const $extraSettings = CE('div', {},
createSettingRow(
t('map-mouse-to'),
this.$mouseMapTo = BxSelectElement.create(CE('select', { _on: { input: savePreset } },
CE('option', { value: MouseMapTo.RS }, t('right-stick')),
CE('option', { value: MouseMapTo.LS }, t('left-stick')),
CE('option', { value: MouseMapTo.OFF }, t('off')),
)),
),
createSettingRow(
t('horizontal-sensitivity'),
this.$mouseSensitivityX = BxNumberStepper.create('hor_sensitivity', 0, 1, 300, {
suffix: '%',
exactTicks: 50,
}, savePreset),
),
createSettingRow(
t('vertical-sensitivity'),
this.$mouseSensitivityY = BxNumberStepper.create('ver_sensitivity', 0, 1, 300, {
suffix: '%',
exactTicks: 50,
}, savePreset),
),
createSettingRow(
t('deadzone-counterweight'),
this.$mouseDeadzone = BxNumberStepper.create('deadzone_counterweight', 0, 1, 50, {
suffix: '%',
exactTicks: 10,
}, savePreset),
),
);
this.$content = CE('div', {},
$rows,
$extraSettings,
);
}
protected switchPreset(id: number): void {
const preset = this.allPresets.data[id];
if (!preset) {
this.currentPresetId = 0;
return;
}
const presetData = preset.data;
this.currentPresetId = id;
const isDefaultPreset = id <= 0;
this.updateButtonStates();
// Update buttons
for (const $elm of this.allKeyElements) {
const { buttonIndex, keySlot } = this.parseDataset($elm);
const buttonKeys = presetData.mapping[buttonIndex];
if (buttonKeys && buttonKeys[keySlot]) {
$elm.bindKey({
code: buttonKeys[keySlot],
}, true)
} else {
$elm.unbindKey(true);
}
$elm.disabled = isDefaultPreset;
}
// Update mouse settings
const mouse = presetData.mouse;
this.$mouseMapTo.value = mouse.mapTo.toString();
this.$mouseSensitivityX.value = mouse.sensitivityX.toString();
this.$mouseSensitivityY.value = mouse.sensitivityY.toString();
this.$mouseDeadzone.value = mouse.deadzoneCounterweight.toString();
this.$mouseMapTo.disabled = isDefaultPreset;
this.$mouseSensitivityX.dataset.disabled = isDefaultPreset.toString();
this.$mouseSensitivityY.dataset.disabled = isDefaultPreset.toString();
this.$mouseDeadzone.dataset.disabled = isDefaultPreset.toString();
}
private savePreset() {
const presetData = deepClone(this.BLANK_PRESET_DATA) as MkbPresetData;
// Get mapping
for (const $elm of this.allKeyElements) {
const { buttonIndex, keySlot } = this.parseDataset($elm);
const mapping = presetData.mapping;
if (!mapping[buttonIndex]) {
mapping[buttonIndex] = [];
}
if (!$elm.keyInfo) {
// Remove empty key from mapping
delete mapping[buttonIndex][keySlot];
} else {
mapping[buttonIndex][keySlot] = $elm.keyInfo.code as KeyCode;
}
}
// Get mouse settings
const mouse = presetData.mouse;
mouse.mapTo = parseInt(this.$mouseMapTo.value) as MouseMapTo;
mouse.sensitivityX = parseInt(this.$mouseSensitivityX.value);
mouse.sensitivityY = parseInt(this.$mouseSensitivityY.value);
mouse.deadzoneCounterweight = parseInt(this.$mouseDeadzone.value);
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.refreshMkbSettings();
}
}