From 27a277309b32ad8776925be4b9af0ce204c95b0e Mon Sep 17 00:00:00 2001 From: redphx <96280+redphx@users.noreply.github.com> Date: Sun, 21 Apr 2024 11:21:59 +0700 Subject: [PATCH] Update MKB codes --- src/modules/dialog.ts | 6 +- src/modules/mkb/definitions.ts | 8 +- src/modules/mkb/mkb-handler.ts | 29 ++--- src/modules/mkb/mkb-preset.ts | 20 ++-- src/modules/mkb/mkb-remapper.ts | 200 ++++++++++++++++---------------- src/modules/preferences.ts | 25 +--- src/types/index.d.ts | 2 + src/types/mkb.d.ts | 27 +++++ src/types/preferences.d.ts | 18 +++ src/utils/html.ts | 34 +++--- src/utils/local-db.ts | 28 ++--- 11 files changed, 222 insertions(+), 175 deletions(-) create mode 100644 src/types/mkb.d.ts create mode 100644 src/types/preferences.d.ts diff --git a/src/modules/dialog.ts b/src/modules/dialog.ts index 9af60ba..65624e3 100644 --- a/src/modules/dialog.ts +++ b/src/modules/dialog.ts @@ -34,9 +34,9 @@ export class Dialog { this.$overlay = CE('div', {'class': 'bx-dialog-overlay bx-gone'}); // Disable right click - this.$overlay.addEventListener('contextmenu', e => e.preventDefault()); + this.$overlay!.addEventListener('contextmenu', e => e.preventDefault()); - document.documentElement.appendChild(this.$overlay); + document.documentElement.appendChild(this.$overlay!); } let $close; @@ -45,7 +45,7 @@ export class Dialog { this.$title = CE('h2', {}, CE('b', {}, title), helpUrl && createButton({ icon: Icon.QUESTION, - style: (ButtonStyle.GHOST as number), + style: ButtonStyle.GHOST, title: t('help'), url: helpUrl, }), diff --git a/src/modules/mkb/definitions.ts b/src/modules/mkb/definitions.ts index e1c979e..a36d5e1 100644 --- a/src/modules/mkb/definitions.ts +++ b/src/modules/mkb/definitions.ts @@ -1,4 +1,6 @@ -export const GamepadKey: {[index: string | number]: string | number} = {}; +import type { GamepadKeyNameType } from "../../types/mkb"; + +export const GamepadKey: DualEnum = {}; GamepadKey[GamepadKey.A = 0] = 'A'; GamepadKey[GamepadKey.B = 1] = 'B'; GamepadKey[GamepadKey.X = 2] = 'X'; @@ -27,7 +29,7 @@ GamepadKey[GamepadKey.RS_LEFT = 202] = 'RS_LEFT'; GamepadKey[GamepadKey.RS_RIGHT = 203] = 'RS_RIGHT'; -export const GamepadKeyName: {[index: string | number]: string[]} = { +export const GamepadKeyName: GamepadKeyNameType = { [GamepadKey.A]: ['A', '⇓'], [GamepadKey.B]: ['B', '⇒'], [GamepadKey.X]: ['X', '⇐'], @@ -72,7 +74,7 @@ export enum MouseButtonCode { MIDDLE_CLICK = 'Mouse1', }; -export const MouseMapTo: {[index: string | number]: string | number} = {}; +export const MouseMapTo: DualEnum = {}; MouseMapTo[MouseMapTo.OFF = 0] = 'OFF'; MouseMapTo[MouseMapTo.LS = 1] = 'LS'; MouseMapTo[MouseMapTo.RS = 2] = 'RS'; diff --git a/src/modules/mkb/mkb-handler.ts b/src/modules/mkb/mkb-handler.ts index 1db697a..a12a1bf 100644 --- a/src/modules/mkb/mkb-handler.ts +++ b/src/modules/mkb/mkb-handler.ts @@ -7,6 +7,7 @@ import { Toast } from "../../utils/toast"; import { t } from "../translation"; import { LocalDb } from "../../utils/local-db"; import { KeyHelper } from "./key-helper"; +import type { MkbStoredPreset } from "../../types/mkb"; /* This class uses some code from Yuzu emulator to handle mouse's movements @@ -164,7 +165,7 @@ export class MkbHandler { return; } - const buttonIndex = this.#CURRENT_PRESET_DATA.mapping[e.code]; + const buttonIndex = this.#CURRENT_PRESET_DATA.mapping[e.code]!; if (typeof buttonIndex === 'undefined') { return; } @@ -178,14 +179,14 @@ export class MkbHandler { this.#pressButton(buttonIndex, isKeyDown); } - #onMouseEvent = e => { + #onMouseEvent = (e: MouseEvent) => { const isMouseDown = e.type === 'mousedown'; const key = KeyHelper.getKeyFromEvent(e); if (!key) { return; } - const buttonIndex = this.#CURRENT_PRESET_DATA.mapping[key.code]; + const buttonIndex = this.#CURRENT_PRESET_DATA.mapping[key.code]!; if (typeof buttonIndex === 'undefined') { return; } @@ -200,7 +201,7 @@ export class MkbHandler { return; } - const buttonIndex = this.#CURRENT_PRESET_DATA.mapping[key.code]; + const buttonIndex = this.#CURRENT_PRESET_DATA.mapping[key.code]!; if (typeof buttonIndex === 'undefined') { return; } @@ -212,7 +213,7 @@ export class MkbHandler { this.#pressButton(buttonIndex, true); } - this.#wheelStoppedTimeout = setTimeout(e => { + this.#wheelStoppedTimeout = setTimeout(() => { this.#prevWheelCode = null; this.#pressButton(buttonIndex, false); }, 20); @@ -308,30 +309,30 @@ export class MkbHandler { } } - #getCurrentPreset = () => { + #getCurrentPreset = (): Promise => { return new Promise(resolve => { const presetId = getPref(PrefKey.MKB_DEFAULT_PRESET_ID); - LocalDb.INSTANCE.getPreset(presetId).then(preset => { - resolve(preset ? preset : MkbPreset.DEFAULT_PRESET); + LocalDb.INSTANCE.getPreset(presetId).then((preset: MkbStoredPreset) => { + resolve(preset); }); }); } refreshPresetData = () => { - this.#getCurrentPreset().then(preset => { - this.#CURRENT_PRESET_DATA = MkbPreset.convert(preset.data); + this.#getCurrentPreset().then((preset: MkbStoredPreset) => { + this.#CURRENT_PRESET_DATA = MkbPreset.convert(preset ? preset.data : MkbPreset.DEFAULT_PRESET); this.#resetGamepad(); }); } - #onPointerLockChange = e => { + #onPointerLockChange = (e: Event) => { if (this.#enabled && !document.pointerLockElement) { this.stop(); this.#waitForPointerLock(true); } } - #onPointerLockError = e => { + #onPointerLockError = (e: Event) => { console.log(e); this.stop(); } @@ -369,7 +370,7 @@ export class MkbHandler { this.#$message = CE('div', {'class': 'bx-mkb-pointer-lock-msg bx-gone'}, createButton({ icon: Icon.MOUSE_SETTINGS, - style: ButtonStyle.PRIMARY as number, + style: ButtonStyle.PRIMARY, onClick: e => { e.preventDefault(); e.stopPropagation(); @@ -458,7 +459,7 @@ export class MkbHandler { static setupEvents() { window.addEventListener(BxEvent.STREAM_PLAYING, e => { // Enable MKB - if (getPref(PrefKey.MKB_ENABLED) && (!ENABLE_NATIVE_MKB_BETA || !window.NATIVE_MKB_TITLES.includes(GAME_PRODUCT_ID))) { + if (getPref(PrefKey.MKB_ENABLED)) { console.log('Emulate MKB'); MkbHandler.INSTANCE.init(); } diff --git a/src/modules/mkb/mkb-preset.ts b/src/modules/mkb/mkb-preset.ts index b8160c0..2ec5a43 100644 --- a/src/modules/mkb/mkb-preset.ts +++ b/src/modules/mkb/mkb-preset.ts @@ -2,10 +2,12 @@ import { t } from "../translation"; import { SettingElementType } from "../settings"; import { GamepadKey, MouseButtonCode, MouseMapTo, MkbPresetKey } from "./definitions"; import { MkbHandler } from "./mkb-handler"; +import type { MkbPresetData, MkbConvertedPresetData } from "../../types/mkb"; +import type { PreferenceSettings } from "../../types/preferences"; export class MkbPreset { - static MOUSE_SETTINGS = { + static MOUSE_SETTINGS: PreferenceSettings = { [MkbPresetKey.MOUSE_MAP_TO]: { label: t('map-mouse-to'), type: SettingElementType.OPTIONS, @@ -82,7 +84,7 @@ export class MkbPreset { }, }; - static DEFAULT_PRESET = { + static DEFAULT_PRESET: MkbPresetData = { 'mapping': { // Use "e.code" value from https://keyjs.dev [GamepadKey.UP]: ['ArrowUp'], @@ -130,15 +132,15 @@ export class MkbPreset { }, }; - static convert(preset) { - const obj = { - 'mapping': {}, - 'mouse': Object.assign({}, preset.mouse), + static convert(preset: MkbPresetData): MkbConvertedPresetData { + const obj: MkbConvertedPresetData = { + mapping: {}, + mouse: Object.assign({}, preset.mouse), }; for (const buttonIndex in preset.mapping) { - for (const keyName of preset.mapping[buttonIndex]) { - obj.mapping[keyName] = parseInt(buttonIndex); + for (const keyName of preset.mapping[parseInt(buttonIndex)]) { + obj.mapping[keyName!] = parseInt(buttonIndex); } } @@ -150,7 +152,7 @@ export class MkbPreset { mouse[MkbPresetKey.MOUSE_STICK_DECAY_STRENGTH] *= 0.01; mouse[MkbPresetKey.MOUSE_STICK_DECAY_MIN] *= 0.01; - const mouseMapTo = MouseMapTo[mouse[MkbPresetKey.MOUSE_MAP_TO]]; + const mouseMapTo = MouseMapTo[mouse[MkbPresetKey.MOUSE_MAP_TO]!]; if (typeof mouseMapTo !== 'undefined') { mouse[MkbPresetKey.MOUSE_MAP_TO] = mouseMapTo; } else { diff --git a/src/modules/mkb/mkb-remapper.ts b/src/modules/mkb/mkb-remapper.ts index 93453c0..ddefa35 100644 --- a/src/modules/mkb/mkb-remapper.ts +++ b/src/modules/mkb/mkb-remapper.ts @@ -10,52 +10,60 @@ import { MkbHandler } from "./mkb-handler"; import { LocalDb } from "../../utils/local-db"; import { Icon } from "../../utils/html"; import { SettingElement } from "../settings"; +import type { MkbConvertedPresetData, MkbPresetData, MkbStoredPresets } from "../../types/mkb"; + type MkbRemapperElements = { - wrapper: HTMLElement | null, - presetsSelect: HTMLSelectElement | null, - activateButton: HTMLButtonElement | null, - currentBindingKey: HTMLElement | null, + wrapper: HTMLElement | null; + presetsSelect: HTMLSelectElement | null; + activateButton: HTMLButtonElement | null; + currentBindingKey: HTMLElement | null; - allKeyElements: HTMLElement[], - allMouseElements: {[key in MkbPresetKey]?: HTMLElement}, -} + allKeyElements: HTMLElement[]; + allMouseElements: {[key in MkbPresetKey]?: HTMLElement}; +}; + +type MkbRemapperStates = { + currentPresetId: number; + presets: MkbStoredPresets; + + editingPresetData?: MkbPresetData | null; + isEditing: boolean; +}; export class MkbRemapper { - get #BUTTON_ORDERS() { - return [ - GamepadKey.UP, - GamepadKey.DOWN, - GamepadKey.LEFT, - GamepadKey.RIGHT, + readonly #BUTTON_ORDERS = [ + GamepadKey.UP, + GamepadKey.DOWN, + GamepadKey.LEFT, + GamepadKey.RIGHT, - GamepadKey.A, - GamepadKey.B, - GamepadKey.X, - GamepadKey.Y, + GamepadKey.A, + GamepadKey.B, + GamepadKey.X, + GamepadKey.Y, - GamepadKey.LB, - GamepadKey.RB, - GamepadKey.LT, - GamepadKey.RT, + GamepadKey.LB, + GamepadKey.RB, + GamepadKey.LT, + GamepadKey.RT, - GamepadKey.SELECT, - GamepadKey.START, - GamepadKey.HOME, + GamepadKey.SELECT, + GamepadKey.START, + GamepadKey.HOME, - GamepadKey.L3, - GamepadKey.LS_UP, - GamepadKey.LS_DOWN, - GamepadKey.LS_LEFT, - GamepadKey.LS_RIGHT, + 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, - ]; - }; + GamepadKey.R3, + GamepadKey.RS_UP, + GamepadKey.RS_DOWN, + GamepadKey.RS_LEFT, + GamepadKey.RS_RIGHT, + ]; static #instance: MkbRemapper; static get INSTANCE() { @@ -66,11 +74,11 @@ export class MkbRemapper { return MkbRemapper.#instance; }; - #STATE = { + #STATE: MkbRemapperStates = { currentPresetId: 0, - presets: [], + presets: {}, - editingPresetData: {}, + editingPresetData: null, isEditing: false, }; @@ -123,7 +131,7 @@ export class MkbRemapper { } } - this.#STATE.editingPresetData.mapping[buttonIndex][keySlot] = key.code; + this.#STATE.editingPresetData!.mapping[buttonIndex][keySlot] = key.code; $elm.textContent = key.name; $elm.setAttribute('data-key-code', key.code); } @@ -133,7 +141,7 @@ export class MkbRemapper { const keySlot = parseInt($elm.getAttribute('data-key-slot')!); // Remove key from preset - this.#STATE.editingPresetData.mapping[buttonIndex][keySlot] = null; + this.#STATE.editingPresetData!.mapping[buttonIndex][keySlot] = null; $elm.textContent = ''; $elm.removeAttribute('data-key-code'); } @@ -146,7 +154,7 @@ export class MkbRemapper { setTimeout(() => this.bindingDialog.hide(), 200); }; - #onMouseDown = e => { + #onMouseDown = (e: MouseEvent) => { e.preventDefault(); this.#clearEventListeners(); @@ -154,7 +162,7 @@ export class MkbRemapper { setTimeout(() => this.bindingDialog.hide(), 200); }; - #onKeyDown = e => { + #onKeyDown = (e: KeyboardEvent) => { e.preventDefault(); e.stopPropagation(); this.#clearEventListeners(); @@ -166,20 +174,20 @@ export class MkbRemapper { setTimeout(() => this.bindingDialog.hide(), 200); }; - #onBindingKey = e => { + #onBindingKey = (e: MouseEvent) => { if (!this.#STATE.isEditing || e.button !== 0) { return; } console.log(e); - this.#$.currentBindingKey = e.target; + this.#$.currentBindingKey = e.target as HTMLElement; window.addEventListener('keydown', this.#onKeyDown); window.addEventListener('mousedown', this.#onMouseDown); window.addEventListener('wheel', this.#onWheel); - this.bindingDialog.show({title: e.target.getAttribute('data-prompt')}); + this.bindingDialog.show({title: this.#$.currentBindingKey.getAttribute('data-prompt')!}); }; #onContextMenu = (e: Event) => { @@ -191,7 +199,7 @@ export class MkbRemapper { this.#unbindKey(e.target as HTMLElement); }; - #getPreset = (presetId: string) => { + #getPreset = (presetId: number) => { return this.#STATE.presets[presetId]; } @@ -199,31 +207,30 @@ export class MkbRemapper { return this.#getPreset(this.#STATE.currentPresetId); } - #switchPreset = presetId => { - presetId = parseInt(presetId); - + #switchPreset = (presetId: number) => { this.#STATE.currentPresetId = presetId; const presetData = this.#getCurrentPreset().data; for (const $elm of this.#$.allKeyElements) { - const buttonIndex = $elm.getAttribute('data-button-index'); - const keySlot = $elm.getAttribute('data-key-slot'); + const buttonIndex = parseInt($elm.getAttribute('data-button-index')!); + const keySlot = parseInt($elm.getAttribute('data-key-slot')!); const buttonKeys = presetData.mapping[buttonIndex]; if (buttonKeys && buttonKeys[keySlot]) { - $elm.textContent = KeyHelper.codeToKeyName(buttonKeys[keySlot]); - $elm.setAttribute('data-key-code', buttonKeys[keySlot]); + $elm.textContent = KeyHelper.codeToKeyName(buttonKeys[keySlot]!); + $elm.setAttribute('data-key-code', buttonKeys[keySlot]!); } else { $elm.textContent = ''; $elm.removeAttribute('data-key-code'); } } - for (const key in this.#$.allMouseElements) { - const $elm = this.#$.allMouseElements[key as MkbPresetKey]!; + let key: MkbPresetKey; + for (key in this.#$.allMouseElements) { + const $elm = this.#$.allMouseElements[key]!; let value = presetData.mouse[key]; if (typeof value === 'undefined') { - value = MkbPreset.MOUSE_SETTINGS[key as MkbPresetKey].default; + value = MkbPreset.MOUSE_SETTINGS[key].default; } 'setValue' in $elm && ($elm as any).setValue(value); @@ -241,46 +248,43 @@ export class MkbRemapper { this.#$.presetsSelect!.removeChild(this.#$.presetsSelect!.firstChild); } - LocalDb.INSTANCE.getPresets() - .then(presets => { - this.#STATE.presets = presets; - const $fragment = document.createDocumentFragment(); + LocalDb.INSTANCE.getPresets().then(presets => { + this.#STATE.presets = presets; + const $fragment = document.createDocumentFragment(); - let defaultPresetId; - if (this.#STATE.currentPresetId === 0) { - this.#STATE.currentPresetId = parseInt(Object.keys(presets)[0]); + let defaultPresetId; + if (this.#STATE.currentPresetId === 0) { + this.#STATE.currentPresetId = parseInt(Object.keys(presets)[0]); - defaultPresetId = this.#STATE.currentPresetId; - setPref(PrefKey.MKB_DEFAULT_PRESET_ID, defaultPresetId); - MkbHandler.INSTANCE.refreshPresetData(); - } else { - defaultPresetId = getPref(PrefKey.MKB_DEFAULT_PRESET_ID); + defaultPresetId = this.#STATE.currentPresetId; + setPref(PrefKey.MKB_DEFAULT_PRESET_ID, defaultPresetId); + MkbHandler.INSTANCE.refreshPresetData(); + } else { + defaultPresetId = getPref(PrefKey.MKB_DEFAULT_PRESET_ID); + } + + for (let id in presets) { + const preset = presets[id]; + let name = preset.name; + if (id === defaultPresetId) { + name = `🎮 ` + name; } - for (let id in presets) { - id = parseInt(id); + const $options = CE('option', {value: id}, name); + $options.selected = parseInt(id) === this.#STATE.currentPresetId; - const preset = presets[id]; - let name = preset.name; - if (id === defaultPresetId) { - name = `🎮 ` + name; - } + $fragment.appendChild($options); + }; - const $options = CE('option', {value: id}, name); - $options.selected = id === this.#STATE.currentPresetId; + this.#$.presetsSelect!.appendChild($fragment); - $fragment.appendChild($options); - }; + // Update state of Activate button + const activated = defaultPresetId === this.#STATE.currentPresetId; + this.#$.activateButton!.disabled = activated; + this.#$.activateButton!.querySelector('span')!.textContent = activated ? t('activated') : t('activate'); - this.#$.presetsSelect!.appendChild($fragment); - - // Update state of Activate button - const activated = defaultPresetId === this.#STATE.currentPresetId; - this.#$.activateButton!.disabled = activated; - this.#$.activateButton!.querySelector('span')!.textContent = activated ? t('activated') : t('activate'); - - !this.#STATE.isEditing && this.#switchPreset(this.#STATE.currentPresetId); - }); + !this.#STATE.isEditing && this.#switchPreset(this.#STATE.currentPresetId); + }); } #toggleEditing = (force?: boolean) => { @@ -290,7 +294,7 @@ export class MkbRemapper { if (this.#STATE.isEditing) { this.#STATE.editingPresetData = structuredClone(this.#getCurrentPreset().data); } else { - this.#STATE.editingPresetData = {}; + this.#STATE.editingPresetData = null; } @@ -315,7 +319,7 @@ export class MkbRemapper { this.#$.presetsSelect = CE('select', {}); this.#$.presetsSelect!.addEventListener('change', e => { - this.#switchPreset((e.target as HTMLSelectElement).value); + this.#switchPreset(parseInt((e.target as HTMLSelectElement).value)); }); const promptNewName = (value?: string) => { @@ -446,13 +450,15 @@ export class MkbRemapper { // Render mouse settings const $mouseSettings = document.createDocumentFragment(); - for (const key in MkbPreset.MOUSE_SETTINGS) { - const setting = MkbPreset.MOUSE_SETTINGS[key as MkbPresetKey]; + + let key: MkbPresetKey; + for (key in MkbPreset.MOUSE_SETTINGS) { + const setting = MkbPreset.MOUSE_SETTINGS[key]; const value = setting.default; let $elm; - const onChange = (e, value) => { - this.#STATE.editingPresetData.mouse[key] = value; + const onChange = (e: Event, value: any) => { + (this.#STATE.editingPresetData!.mouse as any)[key] = value; }; const $row = CE('div', {'class': 'bx-quick-settings-row'}, CE('label', {'for': `bx_setting_${key}`}, setting.label), @@ -460,7 +466,7 @@ export class MkbRemapper { ); $mouseSettings.appendChild($row); - this.#$.allMouseElements[key as MkbPresetKey] = $elm; + this.#$.allMouseElements[key] = $elm; } $rows.appendChild($mouseSettings); @@ -506,7 +512,7 @@ export class MkbRemapper { style: ButtonStyle.PRIMARY, onClick: e => { const updatedPreset = structuredClone(this.#getCurrentPreset()); - updatedPreset.data = this.#STATE.editingPresetData; + updatedPreset.data = this.#STATE.editingPresetData as MkbPresetData; LocalDb.INSTANCE.updatePreset(updatedPreset).then(id => { // If this is the default preset => refresh preset data diff --git a/src/modules/preferences.ts b/src/modules/preferences.ts index efd685c..e90fd58 100644 --- a/src/modules/preferences.ts +++ b/src/modules/preferences.ts @@ -3,22 +3,7 @@ import { t } from "./translation"; import { SettingElement, SettingElementType } from "./settings"; import { UserAgentProfile } from "../utils/user-agent"; import { StreamStat } from "./stream-stats"; - -export type PreferenceSetting = { - default: any; - options?: {[index: string]: string}; - multiple_options?: {[index: string]: string}; - unsupported?: string | boolean; - note?: string | HTMLElement; - type?: SettingElementType; - ready?: () => void; - migrate?: (savedPrefs: any, value: any) => {}; - min?: number; - max?: number; - steps?: number; - experimental?: boolean; - params?: any; -}; +import type { PreferenceSetting, PreferenceSettings } from "../types/preferences"; declare var HAS_TOUCH_SUPPORT: boolean; @@ -103,7 +88,7 @@ export enum PrefKey { } export class Preferences { - static SETTINGS: {[index: string]: PreferenceSetting} = { + static SETTINGS: PreferenceSettings = { [PrefKey.LAST_UPDATE_CHECK]: { 'default': 0, }, @@ -714,7 +699,7 @@ export class Preferences { toElement(key: keyof typeof Preferences.SETTINGS, onChange: any, overrideParams={}) { const setting = Preferences.SETTINGS[key]; - let currentValue = this.get(key as string); + let currentValue = this.get(key); let $control; let type; @@ -736,14 +721,14 @@ export class Preferences { } $control = SettingElement.render(type!, key as string, setting, currentValue, (e: any, value: any) => { - this.set(key as string, value); + this.set(key, value); onChange && onChange(e, value); }, params); return $control; } - toNumberStepper(key: string, onChange: any, options={}) { + toNumberStepper(key: keyof typeof Preferences.SETTINGS, onChange: any, options={}) { return SettingElement.render(SettingElementType.NUMBER_STEPPER, key, Preferences.SETTINGS[key], this.get(key), (e: any, value: any) => { this.set(key, value); onChange && onChange(e, value); diff --git a/src/types/index.d.ts b/src/types/index.d.ts index 1aa73d6..bdf7068 100644 --- a/src/types/index.d.ts +++ b/src/types/index.d.ts @@ -39,6 +39,8 @@ type BxStates = { appContext: any | null; } +type DualEnum = {[index: string]: number} & {[index: number]: string}; + declare var window: Window & typeof globalThis; declare var AppInterface: any; declare var STREAM_WEBRTC: RTCPeerConnection; diff --git a/src/types/mkb.d.ts b/src/types/mkb.d.ts new file mode 100644 index 0000000..6ef65c1 --- /dev/null +++ b/src/types/mkb.d.ts @@ -0,0 +1,27 @@ +import { MkbPresetKey } from "../modules/mkb/definitions"; + +type GamepadKeyNameType = {[index: string | number]: string[]}; + +type MkbStoredPreset = { + id?: number; + name: string; + data: MkbPresetData; +}; + +type MkbStoredPresets = { + [index: number]: MkbStoredPreset; +} + +type MkbPresetData = { + mapping: {[index: number]: (string | null)[]}; + mouse: Omit<{ + [index in MkbPresetKey]: number | null; + }, MkbPresetKey.MOUSE_MAP_TO> & { + [MkbPresetKey.MOUSE_MAP_TO]?: string; + }; +}; + +type MkbConvertedPresetData = { + mapping: {[index: string]: number?}; + mouse: MkbNormalPreset.mouse; +}; diff --git a/src/types/preferences.d.ts b/src/types/preferences.d.ts new file mode 100644 index 0000000..898e8ce --- /dev/null +++ b/src/types/preferences.d.ts @@ -0,0 +1,18 @@ +export type PreferenceSetting = { + default: any; + options?: {[index: string]: string}; + multiple_options?: {[index: string]: string}; + unsupported?: string | boolean; + note?: string | HTMLElement; + type?: SettingElementType; + ready?: () => void; + migrate?: (savedPrefs: any, value: any) => {}; + min?: number; + max?: number; + steps?: number; + experimental?: boolean; + params?: any; + label?: string; +}; + +export type PreferenceSettings = {[index in PrefKey]: PreferenceSetting}; diff --git a/src/utils/html.ts b/src/utils/html.ts index c115f65..ba247da 100644 --- a/src/utils/html.ts +++ b/src/utils/html.ts @@ -9,6 +9,8 @@ type BxButton = { onClick?: EventListener; } +type ButtonStyle = {[index: string]: number} & {[index: number]: string}; + // Quickly create a tree of elements without having to use innerHTML function createElement(elmName: string, props: {[index: string]: any}={}, ..._: any): T { let $elm; @@ -50,24 +52,24 @@ function createElement(elmName: string, props: {[index: string]: export const CE = createElement; // Credit: https://phosphoricons.com -export const Icon = { - STREAM_SETTINGS: '', - STREAM_STATS: '', - CONTROLLER: '', - DISPLAY: '', - MOUSE: '', - MOUSE_SETTINGS: '', - NEW: '', - COPY: '', - TRASH: '', - CURSOR_TEXT: '', - QUESTION: '', +export enum Icon { + STREAM_SETTINGS = '', + STREAM_STATS = '', + CONTROLLER = '', + DISPLAY = '', + MOUSE = '', + MOUSE_SETTINGS = '', + NEW = '', + COPY = '', + TRASH = '', + CURSOR_TEXT = '', + QUESTION = '', - REMOTE_PLAY: '', + REMOTE_PLAY = '', - HAND_TAP: '', + HAND_TAP = '', - SCREENSHOT_B64: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDMyIDMyIiBmaWxsPSIjZmZmIj48cGF0aCBkPSJNMjguMzA4IDUuMDM4aC00LjI2NWwtMi4wOTctMy4xNDVhMS4yMyAxLjIzIDAgMCAwLTEuMDIzLS41NDhoLTkuODQ2YTEuMjMgMS4yMyAwIDAgMC0xLjAyMy41NDhMNy45NTYgNS4wMzhIMy42OTJBMy43MSAzLjcxIDAgMCAwIDAgOC43MzF2MTcuMjMxYTMuNzEgMy43MSAwIDAgMCAzLjY5MiAzLjY5MmgyNC42MTVBMy43MSAzLjcxIDAgMCAwIDMyIDI1Ljk2MlY4LjczMWEzLjcxIDMuNzEgMCAwIDAtMy42OTItMy42OTJ6bS02Ljc2OSAxMS42OTJjMCAzLjAzOS0yLjUgNS41MzgtNS41MzggNS41MzhzLTUuNTM4LTIuNS01LjUzOC01LjUzOCAyLjUtNS41MzggNS41MzgtNS41MzggNS41MzggMi41IDUuNTM4IDUuNTM4eiIvPjwvc3ZnPgo=', + SCREENSHOT_B64 = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDMyIDMyIiBmaWxsPSIjZmZmIj48cGF0aCBkPSJNMjguMzA4IDUuMDM4aC00LjI2NWwtMi4wOTctMy4xNDVhMS4yMyAxLjIzIDAgMCAwLTEuMDIzLS41NDhoLTkuODQ2YTEuMjMgMS4yMyAwIDAgMC0xLjAyMy41NDhMNy45NTYgNS4wMzhIMy42OTJBMy43MSAzLjcxIDAgMCAwIDAgOC43MzF2MTcuMjMxYTMuNzEgMy43MSAwIDAgMCAzLjY5MiAzLjY5MmgyNC42MTVBMy43MSAzLjcxIDAgMCAwIDMyIDI1Ljk2MlY4LjczMWEzLjcxIDMuNzEgMCAwIDAtMy42OTItMy42OTJ6bS02Ljc2OSAxMS42OTJjMCAzLjAzOS0yLjUgNS41MzgtNS41MzggNS41MzhzLTUuNTM4LTIuNS01LjUzOC01LjUzOCAyLjUtNS41MzggNS41MzgtNS41MzggNS41MzggMi41IDUuNTM4IDUuNTM4eiIvPjwvc3ZnPgo=', }; export const createSvgIcon = (icon: string, strokeWidth=2) => { @@ -86,7 +88,7 @@ export const createSvgIcon = (icon: string, strokeWidth=2) => { return $svg; }; -export const ButtonStyle: {[index: string | number]: string | number} = {}; +export const ButtonStyle: DualEnum = {}; ButtonStyle[ButtonStyle.PRIMARY = 1] = 'bx-primary'; ButtonStyle[ButtonStyle.DANGER = 2] = 'bx-danger'; ButtonStyle[ButtonStyle.GHOST = 4] = 'bx-ghost'; diff --git a/src/utils/local-db.ts b/src/utils/local-db.ts index 9c4889c..fc8c850 100644 --- a/src/utils/local-db.ts +++ b/src/utils/local-db.ts @@ -1,5 +1,7 @@ +import { MkbPreset } from "../modules/mkb/mkb-preset"; import { PrefKey, setPref } from "../modules/preferences"; import { t } from "../modules/translation"; +import type { MkbStoredPreset, MkbStoredPresets } from "../types/mkb"; export class LocalDb { static #instance: LocalDb; @@ -73,22 +75,22 @@ export class LocalDb { return this.#call(table.count, ...arguments); } - #add(table: IDBObjectStore, data: any): Promise { + #add(table: IDBObjectStore, data: any): Promise<[IDBObjectStore, number]> { // @ts-ignore return this.#call(table.add, ...arguments); } - #put(table: IDBObjectStore, data: any): Promise { + #put(table: IDBObjectStore, data: any): Promise<[IDBObjectStore, number]> { // @ts-ignore return this.#call(table.put, ...arguments); } - #delete(table: IDBObjectStore, data: any): Promise { + #delete(table: IDBObjectStore, data: any): Promise<[IDBObjectStore, number]> { // @ts-ignore return this.#call(table.delete, ...arguments); } - #get(table: IDBObjectStore, id: string): Promise { + #get(table: IDBObjectStore, id: number): Promise { // @ts-ignore return this.#call(table.get, ...arguments); } @@ -102,31 +104,31 @@ export class LocalDb { return this.#open() .then(() => this.#table(LocalDb.TABLE_PRESETS, 'readwrite')) .then(table => this.#add(table, {name, data})) - .then(([table, id]) => new Promise(resolve => resolve(id))); + .then(([table, id]) => new Promise(resolve => resolve(id))); } - updatePreset(preset: string) { + updatePreset(preset: MkbStoredPreset) { return this.#open() .then(() => this.#table(LocalDb.TABLE_PRESETS, 'readwrite')) .then(table => this.#put(table, preset)) .then(([table, id]) => new Promise(resolve => resolve(id))); } - deletePreset(id: string) { + deletePreset(id: number) { return this.#open() .then(() => this.#table(LocalDb.TABLE_PRESETS, 'readwrite')) .then(table => this.#delete(table, id)) .then(([table, id]) => new Promise(resolve => resolve(id))); } - getPreset(id: string) { + getPreset(id: number): Promise { return this.#open() .then(() => this.#table(LocalDb.TABLE_PRESETS, 'readwrite')) .then(table => this.#get(table, id)) .then(([table, preset]) => new Promise(resolve => resolve(preset))); } - getPresets() { + getPresets(): Promise { return this.#open() .then(() => this.#table(LocalDb.TABLE_PRESETS, 'readwrite')) .then(table => this.#count(table)) @@ -135,20 +137,20 @@ export class LocalDb { return new Promise(resolve => { this.#getAll(table) .then(([table, items]) => { - const presets = {}; - items.forEach((item: any) => (presets[item.id] = item)); + const presets: MkbStoredPresets = {}; + items.forEach((item: MkbStoredPreset) => (presets[item.id!] = item)); resolve(presets); }); }); } // Create "Default" preset when the table is empty - const preset = { + const preset: MkbStoredPreset = { name: t('default'), data: MkbPreset.DEFAULT_PRESET, } - return new Promise(resolve => { + return new Promise(resolve => { this.#add(table, preset) .then(([table, id]) => { preset.id = id;