Use singleton in GameBar

This commit is contained in:
redphx 2024-05-11 11:48:07 +07:00
parent b3033089ed
commit 40b61b173f
4 changed files with 84 additions and 71 deletions

View File

@ -150,9 +150,10 @@ window.addEventListener(BxEvent.STREAM_PLAYING, e => {
injectStreamMenuButtons(); injectStreamMenuButtons();
if (getPref(PrefKey.GAME_BAR_ENABLED)) { if (getPref(PrefKey.GAME_BAR_ENABLED)) {
GameBar.reset(); const gameBar = GameBar.getInstance();
GameBar.enable(); gameBar.reset();
GameBar.showBar(); gameBar.enable();
gameBar.showBar();
} }
if (STATES.currentStream.$screenshotCanvas) { if (STATES.currentStream.$screenshotCanvas) {
@ -188,7 +189,7 @@ window.addEventListener(BxEvent.STREAM_STOPPED, e => {
MouseCursorHider.stop(); MouseCursorHider.stop();
TouchController.reset(); TouchController.reset();
GameBar.disable(); GameBar.getInstance().disable();
}); });

View File

@ -9,96 +9,56 @@ import { PrefKey, getPref } from "@utils/preferences";
export class GameBar { export class GameBar {
static readonly #VISIBLE_DURATION = 2000; private static instance: GameBar;
static #timeout: number | null;
static #$gameBar: HTMLElement; public static getInstance(): GameBar {
static #$container: HTMLElement; if (!GameBar.instance) {
GameBar.instance = new GameBar();
static #$actions: BaseGameBarAction[] = [];
static #beginHideTimeout() {
GameBar.#clearHideTimeout();
GameBar.#timeout = window.setTimeout(() => {
GameBar.#timeout = null;
GameBar.hideBar();
}, GameBar.#VISIBLE_DURATION);
}
static #clearHideTimeout() {
GameBar.#timeout && clearTimeout(GameBar.#timeout);
GameBar.#timeout = null;
}
static enable() {
GameBar.#$gameBar && GameBar.#$gameBar.classList.remove('bx-gone');
}
static disable() {
GameBar.#$gameBar && GameBar.#$gameBar.classList.add('bx-gone');
GameBar.hideBar();
}
static showBar() {
if (!GameBar.#$container) {
return;
} }
GameBar.#$container.classList.remove('bx-offscreen', 'bx-hide'); return GameBar.instance;
GameBar.#$container.classList.add('bx-show');
GameBar.#beginHideTimeout();
} }
static hideBar() { private static readonly VISIBLE_DURATION = 2000;
if (!GameBar.#$container) {
return;
}
GameBar.#$container.classList.remove('bx-show'); private $gameBar: HTMLElement;
GameBar.#$container.classList.add('bx-hide'); private $container: HTMLElement;
}
// Reset all states private timeout: number | null = null;
static reset() {
for (const action of GameBar.#$actions) {
action.reset();
}
}
static setup() { private actions: BaseGameBarAction[] = [];
private constructor() {
let $container; let $container;
const $gameBar = CE('div', {id: 'bx-game-bar', class: 'bx-gone'}, const $gameBar = CE('div', {id: 'bx-game-bar', class: 'bx-gone'},
$container = CE('div', {class: 'bx-game-bar-container bx-offscreen'}), $container = CE('div', {class: 'bx-game-bar-container bx-offscreen'}),
createSvgIcon(BxIcon.CARET_RIGHT), createSvgIcon(BxIcon.CARET_RIGHT),
); );
GameBar.#$actions = [ this.actions = [
new ScreenshotAction(), new ScreenshotAction(),
...(STATES.hasTouchSupport && (getPref(PrefKey.STREAM_TOUCH_CONTROLLER) !== 'off') ? [new TouchControlAction()] : []), ...(STATES.hasTouchSupport && (getPref(PrefKey.STREAM_TOUCH_CONTROLLER) !== 'off') ? [new TouchControlAction()] : []),
]; ];
for (const action of GameBar.#$actions) { // Render actions
for (const action of this.actions) {
$container.appendChild(action.render()); $container.appendChild(action.render());
} }
// Toggle game bar when clicking on the game bar box // Toggle game bar when clicking on the game bar box
$gameBar.addEventListener('click', e => { $gameBar.addEventListener('click', e => {
if (e.target === $gameBar) { if (e.target !== $gameBar) {
if ($container.classList.contains('bx-show')) { return;
GameBar.hideBar();
} else {
GameBar.showBar();
}
} }
$container.classList.contains('bx-show') ? this.hideBar() : this.showBar();
}); });
// Hide game bar after clicking on an action // Hide game bar after clicking on an action
window.addEventListener(BxEvent.GAME_BAR_ACTION_ACTIVATED, GameBar.hideBar); window.addEventListener(BxEvent.GAME_BAR_ACTION_ACTIVATED, this.hideBar.bind(this));
$container.addEventListener('pointerover', GameBar.#clearHideTimeout); $container.addEventListener('pointerover', this.clearHideTimeout.bind(this));
$container.addEventListener('pointerout', GameBar.#beginHideTimeout); $container.addEventListener('pointerout', this.beginHideTimeout.bind(this));
// Add animation when hiding game bar // Add animation when hiding game bar
$container.addEventListener('transitionend', e => { $container.addEventListener('transitionend', e => {
@ -110,7 +70,57 @@ export class GameBar {
}); });
document.documentElement.appendChild($gameBar); document.documentElement.appendChild($gameBar);
GameBar.#$gameBar = $gameBar; this.$gameBar = $gameBar;
GameBar.#$container = $container; this.$container = $container;
}
private beginHideTimeout() {
this.clearHideTimeout();
this.timeout = window.setTimeout(() => {
this.timeout = null;
this.hideBar();
}, GameBar.VISIBLE_DURATION);
}
private clearHideTimeout() {
this.timeout && clearTimeout(this.timeout);
this.timeout = null;
}
enable() {
this.$gameBar && this.$gameBar.classList.remove('bx-gone');
}
disable() {
this.hideBar();
this.$gameBar && this.$gameBar.classList.add('bx-gone');
}
showBar() {
if (!this.$container) {
return;
}
this.$container.classList.remove('bx-offscreen', 'bx-hide');
this.$container.classList.add('bx-show');
this.beginHideTimeout();
}
hideBar() {
if (!this.$container) {
return;
}
this.$container.classList.remove('bx-show');
this.$container.classList.add('bx-hide');
}
// Reset all states
reset() {
for (const action of this.actions) {
action.reset();
}
} }
} }

View File

@ -475,7 +475,7 @@ export function setupStreamUi() {
setupQuickSettingsBar(); setupQuickSettingsBar();
StreamStats.render(); StreamStats.render();
getPref(PrefKey.GAME_BAR_ENABLED) && GameBar.setup(); getPref(PrefKey.GAME_BAR_ENABLED) && GameBar.getInstance();
} }
updateVideoPlayerCss(); updateVideoPlayerCss();

View File

@ -20,13 +20,15 @@ export const BxExposed = {
return; return;
} }
const gameBar = GameBar.getInstance();
if (!STATES.isPlaying) { if (!STATES.isPlaying) {
GameBar.disable(); gameBar.disable();
return; return;
} }
// Toggle Game bar // Toggle Game bar
mode !== 'None' ? GameBar.disable() : GameBar.enable(); mode !== 'None' ? gameBar.disable() : gameBar.enable();
}, },
getTitleInfo: () => STATES.currentStream.titleInfo, getTitleInfo: () => STATES.currentStream.titleInfo,