Refactor Game Bar

This commit is contained in:
redphx 2024-10-14 16:45:57 +07:00
parent 34159fad22
commit 1acb30e3af
9 changed files with 29 additions and 91 deletions

View File

@ -1,6 +1,8 @@
import { BxEvent } from "@/utils/bx-event"; import { BxEvent } from "@/utils/bx-event";
export abstract class BaseGameBarAction { export abstract class BaseGameBarAction {
abstract $content: HTMLElement;
constructor() {} constructor() {}
reset() {} reset() {}
@ -8,5 +10,7 @@ export abstract class BaseGameBarAction {
BxEvent.dispatch(window, BxEvent.GAME_BAR_ACTION_ACTIVATED); BxEvent.dispatch(window, BxEvent.GAME_BAR_ACTION_ACTIVATED);
}; };
abstract render(): HTMLElement; render(): HTMLElement {
return this.$content;
};
} }

View File

@ -8,8 +8,6 @@ import { MicrophoneShortcut, MicrophoneState } from "../shortcuts/shortcut-micro
export class MicrophoneAction extends BaseGameBarAction { export class MicrophoneAction extends BaseGameBarAction {
$content: HTMLElement; $content: HTMLElement;
visible: boolean = false;
constructor() { constructor() {
super(); super();
@ -26,12 +24,7 @@ export class MicrophoneAction extends BaseGameBarAction {
onClick: this.onClick.bind(this), onClick: this.onClick.bind(this),
}); });
this.$content = CE('div', {}, this.$content = CE('div', {}, $btnMuted, $btnDefault);
$btnMuted,
$btnDefault,
);
this.reset();
window.addEventListener(BxEvent.MICROPHONE_STATE_CHANGED, e => { window.addEventListener(BxEvent.MICROPHONE_STATE_CHANGED, e => {
const microphoneState = (e as any).microphoneState; const microphoneState = (e as any).microphoneState;
@ -49,12 +42,7 @@ export class MicrophoneAction extends BaseGameBarAction {
this.$content.dataset.activated = enabled.toString(); this.$content.dataset.activated = enabled.toString();
} }
render(): HTMLElement {
return this.$content;
}
reset(): void { reset(): void {
this.visible = false;
this.$content.classList.add('bx-gone'); this.$content.classList.add('bx-gone');
this.$content.dataset.activated = 'false'; this.$content.dataset.activated = 'false';
} }

View File

@ -23,12 +23,7 @@ export class RendererAction extends BaseGameBarAction {
classes: ['bx-activated'], classes: ['bx-activated'],
}); });
this.$content = CE('div', {}, this.$content = CE('div', {}, $btnDefault, $btnActivated);
$btnDefault,
$btnActivated,
);
this.reset();
} }
onClick(e: Event) { onClick(e: Event) {
@ -37,10 +32,6 @@ export class RendererAction extends BaseGameBarAction {
this.$content.dataset.activated = (!isVisible).toString(); this.$content.dataset.activated = (!isVisible).toString();
} }
render(): HTMLElement {
return this.$content;
}
reset(): void { reset(): void {
this.$content.dataset.activated = 'false'; this.$content.dataset.activated = 'false';
} }

View File

@ -22,8 +22,4 @@ export class ScreenshotAction extends BaseGameBarAction {
super.onClick(e); super.onClick(e);
Screenshot.takeScreenshot(); Screenshot.takeScreenshot();
} }
render(): HTMLElement {
return this.$content;
}
} }

View File

@ -24,12 +24,7 @@ export class SpeakerAction extends BaseGameBarAction {
classes: ['bx-activated'], classes: ['bx-activated'],
}); });
this.$content = CE('div', {}, this.$content = CE('div', {}, $btnEnable, $btnMuted);
$btnEnable,
$btnMuted,
);
this.reset();
window.addEventListener(BxEvent.SPEAKER_STATE_CHANGED, e => { window.addEventListener(BxEvent.SPEAKER_STATE_CHANGED, e => {
const speakerState = (e as any).speakerState; const speakerState = (e as any).speakerState;
@ -44,10 +39,6 @@ export class SpeakerAction extends BaseGameBarAction {
SoundShortcut.muteUnmute(); SoundShortcut.muteUnmute();
} }
render(): HTMLElement {
return this.$content;
}
reset(): void { reset(): void {
this.$content.dataset.activated = 'false'; this.$content.dataset.activated = 'false';
} }

View File

@ -25,12 +25,7 @@ export class TouchControlAction extends BaseGameBarAction {
classes: ['bx-activated'], classes: ['bx-activated'],
}); });
this.$content = CE('div', {}, this.$content = CE('div', {}, $btnEnable, $btnDisable);
$btnEnable,
$btnDisable,
);
this.reset();
} }
onClick(e: Event) { onClick(e: Event) {
@ -39,10 +34,6 @@ export class TouchControlAction extends BaseGameBarAction {
this.$content.dataset.activated = (!isVisible).toString(); this.$content.dataset.activated = (!isVisible).toString();
} }
render(): HTMLElement {
return this.$content;
}
reset(): void { reset(): void {
this.$content.dataset.activated = 'false'; this.$content.dataset.activated = 'false';
} }

View File

@ -1,6 +1,5 @@
import { BxIcon } from "@/utils/bx-icon"; import { BxIcon } from "@/utils/bx-icon";
import { createButton, ButtonStyle } from "@/utils/html"; import { createButton, ButtonStyle } from "@/utils/html";
import { t } from "@/utils/translation";
import { BaseGameBarAction } from "./action-base"; import { BaseGameBarAction } from "./action-base";
import { TrueAchievements } from "@/utils/true-achievements"; import { TrueAchievements } from "@/utils/true-achievements";
@ -13,7 +12,6 @@ export class TrueAchievementsAction extends BaseGameBarAction {
this.$content = createButton({ this.$content = createButton({
style: ButtonStyle.GHOST, style: ButtonStyle.GHOST,
icon: BxIcon.TRUE_ACHIEVEMENTS, icon: BxIcon.TRUE_ACHIEVEMENTS,
title: t('true-achievements'),
onClick: this.onClick.bind(this), onClick: this.onClick.bind(this),
}); });
} }
@ -22,8 +20,4 @@ export class TrueAchievementsAction extends BaseGameBarAction {
super.onClick(e); super.onClick(e);
TrueAchievements.open(false); TrueAchievements.open(false);
} }
render(): HTMLElement {
return this.$content;
}
} }

View File

@ -7,7 +7,7 @@ import type { BaseGameBarAction } from "./action-base";
import { STATES } from "@utils/global"; import { STATES } from "@utils/global";
import { MicrophoneAction } from "./action-microphone"; import { MicrophoneAction } from "./action-microphone";
import { PrefKey } from "@/enums/pref-keys"; 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 { TrueAchievementsAction } from "./action-true-achievements";
import { SpeakerAction } from "./action-speaker"; import { SpeakerAction } from "./action-speaker";
import { RendererAction } from "./action-renderer"; import { RendererAction } from "./action-renderer";
@ -15,13 +15,7 @@ import { RendererAction } from "./action-renderer";
export class GameBar { export class GameBar {
private static instance: GameBar; private static instance: GameBar;
public static getInstance(): GameBar { public static getInstance = () => GameBar.instance ?? (GameBar.instance = new GameBar());
if (!GameBar.instance) {
GameBar.instance = new GameBar();
}
return GameBar.instance;
}
private static readonly VISIBLE_DURATION = 2000; private static readonly VISIBLE_DURATION = 2000;
@ -35,12 +29,12 @@ export class GameBar {
private constructor() { private constructor() {
let $container; 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}, const $gameBar = CE('div', {id: 'bx-game-bar', class: 'bx-gone', 'data-position': position},
$container = CE('div', {class: 'bx-game-bar-container bx-offscreen'}), $container = CE('div', {class: 'bx-game-bar-container bx-offscreen'}),
createSvgIcon(position === 'bottom-left' ? BxIcon.CARET_RIGHT : BxIcon.CARET_LEFT), createSvgIcon(position === 'bottom-left' ? BxIcon.CARET_RIGHT : BxIcon.CARET_LEFT),
); );
this.actions = [ this.actions = [
new ScreenshotAction(), new ScreenshotAction(),
@ -78,11 +72,7 @@ export class GameBar {
// Add animation when hiding game bar // Add animation when hiding game bar
$container.addEventListener('transitionend', e => { $container.addEventListener('transitionend', e => {
const classList = $container.classList; $container.classList.replace('bx-hide', 'bx-offscreen');
if (classList.contains('bx-hide')) {
classList.remove('bx-hide');
classList.add('bx-offscreen');
}
}); });
document.documentElement.appendChild($gameBar); document.documentElement.appendChild($gameBar);
@ -106,9 +96,9 @@ export class GameBar {
this.clearHideTimeout(); this.clearHideTimeout();
this.timeoutId = window.setTimeout(() => { this.timeoutId = window.setTimeout(() => {
this.timeoutId = null; this.timeoutId = null;
this.hideBar(); this.hideBar();
}, GameBar.VISIBLE_DURATION); }, GameBar.VISIBLE_DURATION);
} }
private clearHideTimeout() { private clearHideTimeout() {
@ -117,19 +107,15 @@ export class GameBar {
} }
enable() { enable() {
this.$gameBar && this.$gameBar.classList.remove('bx-gone'); this.$gameBar.classList.remove('bx-gone');
} }
disable() { disable() {
this.hideBar(); this.hideBar();
this.$gameBar && this.$gameBar.classList.add('bx-gone'); this.$gameBar.classList.add('bx-gone');
} }
showBar() { showBar() {
if (!this.$container) {
return;
}
this.$container.classList.remove('bx-offscreen', 'bx-hide' , 'bx-gone'); this.$container.classList.remove('bx-offscreen', 'bx-hide' , 'bx-gone');
this.$container.classList.add('bx-show'); this.$container.classList.add('bx-show');
@ -142,18 +128,11 @@ export class GameBar {
// Stop focusing Game Bar // Stop focusing Game Bar
clearFocus(); clearFocus();
if (!this.$container) { this.$container.classList.replace('bx-show', 'bx-hide');
return;
}
this.$container.classList.remove('bx-show');
this.$container.classList.add('bx-hide');
} }
// Reset all states // Reset all states
reset() { reset() {
for (const action of this.actions) { this.actions.forEach(action => action.reset());
action.reset();
}
} }
} }

View File

@ -39,6 +39,10 @@ export const enum ControllerDeviceVibration {
} }
export type GameBarPosition = 'bottom-left' | 'bottom-right' | 'off';
export type GameBarPositionOptions = Record<GameBarPosition, string>;
function getSupportedCodecProfiles() { function getSupportedCodecProfiles() {
const options: PartialRecord<CodecProfile, string> = { const options: PartialRecord<CodecProfile, string> = {
default: t('default'), default: t('default'),
@ -323,12 +327,12 @@ export class GlobalSettingsStorage extends BaseSettingsStorage {
[PrefKey.GAME_BAR_POSITION]: { [PrefKey.GAME_BAR_POSITION]: {
requiredVariants: 'full', requiredVariants: 'full',
label: t('position'), label: t('position'),
default: 'bottom-left', default: 'bottom-left' satisfies GameBarPosition,
options: { options: {
'bottom-left': t('bottom-left'), 'bottom-left': t('bottom-left'),
'bottom-right': t('bottom-right'), 'bottom-right': t('bottom-right'),
'off': t('off'), 'off': t('off'),
}, } satisfies GameBarPositionOptions,
}, },
[PrefKey.LOCAL_CO_OP_ENABLED]: { [PrefKey.LOCAL_CO_OP_ENABLED]: {