From 1acb30e3af7ec713ae00ae17b7df31d67ba807be Mon Sep 17 00:00:00 2001 From: redphx <96280+redphx@users.noreply.github.com> Date: Mon, 14 Oct 2024 16:45:57 +0700 Subject: [PATCH] Refactor Game Bar --- src/modules/game-bar/action-base.ts | 6 ++- src/modules/game-bar/action-microphone.ts | 14 +----- src/modules/game-bar/action-renderer.ts | 11 +---- src/modules/game-bar/action-screenshot.ts | 4 -- src/modules/game-bar/action-speaker.ts | 11 +---- src/modules/game-bar/action-touch-control.ts | 11 +---- .../game-bar/action-true-achievements.ts | 6 --- src/modules/game-bar/game-bar.ts | 49 ++++++------------- .../global-settings-storage.ts | 8 ++- 9 files changed, 29 insertions(+), 91 deletions(-) diff --git a/src/modules/game-bar/action-base.ts b/src/modules/game-bar/action-base.ts index 52137e2..aee6ae6 100644 --- a/src/modules/game-bar/action-base.ts +++ b/src/modules/game-bar/action-base.ts @@ -1,6 +1,8 @@ import { BxEvent } from "@/utils/bx-event"; export abstract class BaseGameBarAction { + abstract $content: HTMLElement; + constructor() {} reset() {} @@ -8,5 +10,7 @@ export abstract class BaseGameBarAction { BxEvent.dispatch(window, BxEvent.GAME_BAR_ACTION_ACTIVATED); }; - abstract render(): HTMLElement; + render(): HTMLElement { + return this.$content; + }; } diff --git a/src/modules/game-bar/action-microphone.ts b/src/modules/game-bar/action-microphone.ts index ca52b5b..6a630d5 100644 --- a/src/modules/game-bar/action-microphone.ts +++ b/src/modules/game-bar/action-microphone.ts @@ -8,8 +8,6 @@ import { MicrophoneShortcut, MicrophoneState } from "../shortcuts/shortcut-micro export class MicrophoneAction extends BaseGameBarAction { $content: HTMLElement; - visible: boolean = false; - constructor() { super(); @@ -26,12 +24,7 @@ export class MicrophoneAction extends BaseGameBarAction { onClick: this.onClick.bind(this), }); - this.$content = CE('div', {}, - $btnMuted, - $btnDefault, - ); - - this.reset(); + this.$content = CE('div', {}, $btnMuted, $btnDefault); window.addEventListener(BxEvent.MICROPHONE_STATE_CHANGED, e => { const microphoneState = (e as any).microphoneState; @@ -49,12 +42,7 @@ export class MicrophoneAction extends BaseGameBarAction { this.$content.dataset.activated = enabled.toString(); } - render(): HTMLElement { - return this.$content; - } - reset(): void { - this.visible = false; this.$content.classList.add('bx-gone'); this.$content.dataset.activated = 'false'; } diff --git a/src/modules/game-bar/action-renderer.ts b/src/modules/game-bar/action-renderer.ts index c110854..430d254 100644 --- a/src/modules/game-bar/action-renderer.ts +++ b/src/modules/game-bar/action-renderer.ts @@ -23,12 +23,7 @@ export class RendererAction extends BaseGameBarAction { classes: ['bx-activated'], }); - this.$content = CE('div', {}, - $btnDefault, - $btnActivated, - ); - - this.reset(); + this.$content = CE('div', {}, $btnDefault, $btnActivated); } onClick(e: Event) { @@ -37,10 +32,6 @@ export class RendererAction extends BaseGameBarAction { this.$content.dataset.activated = (!isVisible).toString(); } - render(): HTMLElement { - return this.$content; - } - reset(): void { this.$content.dataset.activated = 'false'; } diff --git a/src/modules/game-bar/action-screenshot.ts b/src/modules/game-bar/action-screenshot.ts index f0bdee2..4275618 100644 --- a/src/modules/game-bar/action-screenshot.ts +++ b/src/modules/game-bar/action-screenshot.ts @@ -22,8 +22,4 @@ export class ScreenshotAction extends BaseGameBarAction { super.onClick(e); Screenshot.takeScreenshot(); } - - render(): HTMLElement { - return this.$content; - } } diff --git a/src/modules/game-bar/action-speaker.ts b/src/modules/game-bar/action-speaker.ts index a3b7f29..2a6ac70 100644 --- a/src/modules/game-bar/action-speaker.ts +++ b/src/modules/game-bar/action-speaker.ts @@ -24,12 +24,7 @@ export class SpeakerAction extends BaseGameBarAction { classes: ['bx-activated'], }); - this.$content = CE('div', {}, - $btnEnable, - $btnMuted, - ); - - this.reset(); + this.$content = CE('div', {}, $btnEnable, $btnMuted); window.addEventListener(BxEvent.SPEAKER_STATE_CHANGED, e => { const speakerState = (e as any).speakerState; @@ -44,10 +39,6 @@ export class SpeakerAction extends BaseGameBarAction { SoundShortcut.muteUnmute(); } - render(): HTMLElement { - return this.$content; - } - reset(): void { this.$content.dataset.activated = 'false'; } diff --git a/src/modules/game-bar/action-touch-control.ts b/src/modules/game-bar/action-touch-control.ts index 7c646f7..c5225d2 100644 --- a/src/modules/game-bar/action-touch-control.ts +++ b/src/modules/game-bar/action-touch-control.ts @@ -25,12 +25,7 @@ export class TouchControlAction extends BaseGameBarAction { classes: ['bx-activated'], }); - this.$content = CE('div', {}, - $btnEnable, - $btnDisable, - ); - - this.reset(); + this.$content = CE('div', {}, $btnEnable, $btnDisable); } onClick(e: Event) { @@ -39,10 +34,6 @@ export class TouchControlAction extends BaseGameBarAction { this.$content.dataset.activated = (!isVisible).toString(); } - render(): HTMLElement { - return this.$content; - } - reset(): void { this.$content.dataset.activated = 'false'; } diff --git a/src/modules/game-bar/action-true-achievements.ts b/src/modules/game-bar/action-true-achievements.ts index 2ea81e2..bd33bbe 100644 --- a/src/modules/game-bar/action-true-achievements.ts +++ b/src/modules/game-bar/action-true-achievements.ts @@ -1,6 +1,5 @@ import { BxIcon } from "@/utils/bx-icon"; import { createButton, ButtonStyle } from "@/utils/html"; -import { t } from "@/utils/translation"; import { BaseGameBarAction } from "./action-base"; import { TrueAchievements } from "@/utils/true-achievements"; @@ -13,7 +12,6 @@ export class TrueAchievementsAction extends BaseGameBarAction { this.$content = createButton({ style: ButtonStyle.GHOST, icon: BxIcon.TRUE_ACHIEVEMENTS, - title: t('true-achievements'), onClick: this.onClick.bind(this), }); } @@ -22,8 +20,4 @@ export class TrueAchievementsAction extends BaseGameBarAction { super.onClick(e); TrueAchievements.open(false); } - - render(): HTMLElement { - return this.$content; - } } diff --git a/src/modules/game-bar/game-bar.ts b/src/modules/game-bar/game-bar.ts index 10e1e13..4ad368b 100644 --- a/src/modules/game-bar/game-bar.ts +++ b/src/modules/game-bar/game-bar.ts @@ -7,7 +7,7 @@ import type { BaseGameBarAction } from "./action-base"; import { STATES } from "@utils/global"; import { MicrophoneAction } from "./action-microphone"; import { PrefKey } from "@/enums/pref-keys"; -import { getPref, StreamTouchController } from "@/utils/settings-storages/global-settings-storage"; +import { getPref, StreamTouchController, type GameBarPosition } from "@/utils/settings-storages/global-settings-storage"; import { TrueAchievementsAction } from "./action-true-achievements"; import { SpeakerAction } from "./action-speaker"; import { RendererAction } from "./action-renderer"; @@ -15,13 +15,7 @@ import { RendererAction } from "./action-renderer"; export class GameBar { private static instance: GameBar; - public static getInstance(): GameBar { - if (!GameBar.instance) { - GameBar.instance = new GameBar(); - } - - return GameBar.instance; - } + public static getInstance = () => GameBar.instance ?? (GameBar.instance = new GameBar()); private static readonly VISIBLE_DURATION = 2000; @@ -35,12 +29,12 @@ export class GameBar { private constructor() { let $container; - const position = getPref(PrefKey.GAME_BAR_POSITION); + const position = getPref(PrefKey.GAME_BAR_POSITION) as GameBarPosition; const $gameBar = CE('div', {id: 'bx-game-bar', class: 'bx-gone', 'data-position': position}, - $container = CE('div', {class: 'bx-game-bar-container bx-offscreen'}), - createSvgIcon(position === 'bottom-left' ? BxIcon.CARET_RIGHT : BxIcon.CARET_LEFT), - ); + $container = CE('div', {class: 'bx-game-bar-container bx-offscreen'}), + createSvgIcon(position === 'bottom-left' ? BxIcon.CARET_RIGHT : BxIcon.CARET_LEFT), + ); this.actions = [ new ScreenshotAction(), @@ -78,11 +72,7 @@ export class GameBar { // Add animation when hiding game bar $container.addEventListener('transitionend', e => { - const classList = $container.classList; - if (classList.contains('bx-hide')) { - classList.remove('bx-hide'); - classList.add('bx-offscreen'); - } + $container.classList.replace('bx-hide', 'bx-offscreen'); }); document.documentElement.appendChild($gameBar); @@ -106,9 +96,9 @@ export class GameBar { this.clearHideTimeout(); this.timeoutId = window.setTimeout(() => { - this.timeoutId = null; - this.hideBar(); - }, GameBar.VISIBLE_DURATION); + this.timeoutId = null; + this.hideBar(); + }, GameBar.VISIBLE_DURATION); } private clearHideTimeout() { @@ -117,19 +107,15 @@ export class GameBar { } enable() { - this.$gameBar && this.$gameBar.classList.remove('bx-gone'); + this.$gameBar.classList.remove('bx-gone'); } disable() { this.hideBar(); - this.$gameBar && this.$gameBar.classList.add('bx-gone'); + this.$gameBar.classList.add('bx-gone'); } showBar() { - if (!this.$container) { - return; - } - this.$container.classList.remove('bx-offscreen', 'bx-hide' , 'bx-gone'); this.$container.classList.add('bx-show'); @@ -142,18 +128,11 @@ export class GameBar { // Stop focusing Game Bar clearFocus(); - if (!this.$container) { - return; - } - - this.$container.classList.remove('bx-show'); - this.$container.classList.add('bx-hide'); + this.$container.classList.replace('bx-show', 'bx-hide'); } // Reset all states reset() { - for (const action of this.actions) { - action.reset(); - } + this.actions.forEach(action => action.reset()); } } diff --git a/src/utils/settings-storages/global-settings-storage.ts b/src/utils/settings-storages/global-settings-storage.ts index 6b12cae..de19450 100644 --- a/src/utils/settings-storages/global-settings-storage.ts +++ b/src/utils/settings-storages/global-settings-storage.ts @@ -39,6 +39,10 @@ export const enum ControllerDeviceVibration { } +export type GameBarPosition = 'bottom-left' | 'bottom-right' | 'off'; +export type GameBarPositionOptions = Record; + + function getSupportedCodecProfiles() { const options: PartialRecord = { default: t('default'), @@ -323,12 +327,12 @@ export class GlobalSettingsStorage extends BaseSettingsStorage { [PrefKey.GAME_BAR_POSITION]: { requiredVariants: 'full', label: t('position'), - default: 'bottom-left', + default: 'bottom-left' satisfies GameBarPosition, options: { 'bottom-left': t('bottom-left'), 'bottom-right': t('bottom-right'), 'off': t('off'), - }, + } satisfies GameBarPositionOptions, }, [PrefKey.LOCAL_CO_OP_ENABLED]: {