mirror of
https://github.com/redphx/better-xcloud.git
synced 2025-08-08 06:08:27 +02:00
6.0
This commit is contained in:
0
src/modules/game-bar/action-base.ts → src/modules/game-bar/base-action.ts
Normal file → Executable file
0
src/modules/game-bar/action-base.ts → src/modules/game-bar/base-action.ts
Normal file → Executable file
53
src/modules/game-bar/game-bar.ts
Normal file → Executable file
53
src/modules/game-bar/game-bar.ts
Normal file → Executable file
@@ -1,22 +1,34 @@
|
||||
import { CE, createSvgIcon } from "@utils/html";
|
||||
import { ScreenshotAction } from "./action-screenshot";
|
||||
import { TouchControlAction } from "./action-touch-control";
|
||||
import { ScreenshotAction } from "./screenshot-action";
|
||||
import { TouchControlAction } from "./touch-control-action";
|
||||
import { BxEvent } from "@utils/bx-event";
|
||||
import { BxIcon } from "@utils/bx-icon";
|
||||
import type { BaseGameBarAction } from "./action-base";
|
||||
import type { BaseGameBarAction } from "./base-action";
|
||||
import { STATES } from "@utils/global";
|
||||
import { MicrophoneAction } from "./action-microphone";
|
||||
import { MicrophoneAction } from "./microphone-action";
|
||||
import { PrefKey } from "@/enums/pref-keys";
|
||||
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";
|
||||
import { getPref } from "@/utils/settings-storages/global-settings-storage";
|
||||
import { TrueAchievementsAction } from "./true-achievements-action";
|
||||
import { SpeakerAction } from "./speaker-action";
|
||||
import { RendererAction } from "./renderer-action";
|
||||
import { BxLogger } from "@/utils/bx-logger";
|
||||
import { GameBarPosition, TouchControllerMode } from "@/enums/pref-values";
|
||||
|
||||
|
||||
export class GameBar {
|
||||
private static instance: GameBar;
|
||||
public static getInstance = () => GameBar.instance ?? (GameBar.instance = new GameBar());
|
||||
private static instance: GameBar | null | undefined;
|
||||
public static getInstance(): typeof GameBar['instance'] {
|
||||
if (typeof GameBar.instance === 'undefined') {
|
||||
if (getPref<GameBarPosition>(PrefKey.GAME_BAR_POSITION) !== GameBarPosition.OFF) {
|
||||
GameBar.instance = new GameBar();
|
||||
} else {
|
||||
GameBar.instance = null;
|
||||
}
|
||||
}
|
||||
|
||||
return GameBar.instance;
|
||||
}
|
||||
|
||||
private readonly LOG_TAG = 'GameBar';
|
||||
|
||||
private static readonly VISIBLE_DURATION = 2000;
|
||||
@@ -33,7 +45,7 @@ export class GameBar {
|
||||
|
||||
let $container;
|
||||
|
||||
const position = getPref(PrefKey.GAME_BAR_POSITION) as GameBarPosition;
|
||||
const position = getPref<GameBarPosition>(PrefKey.GAME_BAR_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'}),
|
||||
@@ -42,7 +54,7 @@ export class GameBar {
|
||||
|
||||
this.actions = [
|
||||
new ScreenshotAction(),
|
||||
...(STATES.userAgent.capabilities.touch && (getPref(PrefKey.STREAM_TOUCH_CONTROLLER) !== StreamTouchController.OFF) ? [new TouchControlAction()] : []),
|
||||
...(STATES.userAgent.capabilities.touch && (getPref<TouchControllerMode>(PrefKey.TOUCH_CONTROLLER_MODE) !== TouchControllerMode.OFF) ? [new TouchControlAction()] : []),
|
||||
new SpeakerAction(),
|
||||
new RendererAction(),
|
||||
new MicrophoneAction(),
|
||||
@@ -69,10 +81,10 @@ export class GameBar {
|
||||
});
|
||||
|
||||
// Hide game bar after clicking on an action
|
||||
window.addEventListener(BxEvent.GAME_BAR_ACTION_ACTIVATED, this.hideBar.bind(this));
|
||||
window.addEventListener(BxEvent.GAME_BAR_ACTION_ACTIVATED, this.hideBar);
|
||||
|
||||
$container.addEventListener('pointerover', this.clearHideTimeout.bind(this));
|
||||
$container.addEventListener('pointerout', this.beginHideTimeout.bind(this));
|
||||
$container.addEventListener('pointerover', this.clearHideTimeout);
|
||||
$container.addEventListener('pointerout', this.beginHideTimeout);
|
||||
|
||||
// Add animation when hiding game bar
|
||||
$container.addEventListener('transitionend', e => {
|
||||
@@ -84,16 +96,15 @@ export class GameBar {
|
||||
this.$container = $container;
|
||||
|
||||
// Enable/disable Game Bar when playing/pausing
|
||||
getPref(PrefKey.GAME_BAR_POSITION) !== 'off' && window.addEventListener(BxEvent.XCLOUD_POLLING_MODE_CHANGED, ((e: Event) => {
|
||||
position !== GameBarPosition.OFF && window.addEventListener(BxEvent.XCLOUD_POLLING_MODE_CHANGED, ((e: Event) => {
|
||||
// Toggle Game bar
|
||||
if (STATES.isPlaying) {
|
||||
const mode = (e as any).mode;
|
||||
mode !== 'none' ? this.disable() : this.enable();
|
||||
window.BX_STREAM_SETTINGS.xCloudPollingMode !== 'none' ? this.disable() : this.enable();
|
||||
}
|
||||
}).bind(this));
|
||||
}
|
||||
|
||||
private beginHideTimeout() {
|
||||
private beginHideTimeout = () => {
|
||||
this.clearHideTimeout();
|
||||
|
||||
this.timeoutId = window.setTimeout(() => {
|
||||
@@ -102,7 +113,7 @@ export class GameBar {
|
||||
}, GameBar.VISIBLE_DURATION);
|
||||
}
|
||||
|
||||
private clearHideTimeout() {
|
||||
private clearHideTimeout = () => {
|
||||
this.timeoutId && clearTimeout(this.timeoutId);
|
||||
this.timeoutId = null;
|
||||
}
|
||||
@@ -123,7 +134,7 @@ export class GameBar {
|
||||
this.beginHideTimeout();
|
||||
}
|
||||
|
||||
hideBar() {
|
||||
hideBar = () => {
|
||||
this.clearHideTimeout();
|
||||
this.$container.classList.replace('bx-show', 'bx-hide');
|
||||
}
|
||||
|
10
src/modules/game-bar/action-microphone.ts → src/modules/game-bar/microphone-action.ts
Normal file → Executable file
10
src/modules/game-bar/action-microphone.ts → src/modules/game-bar/microphone-action.ts
Normal file → Executable file
@@ -1,8 +1,8 @@
|
||||
import { BxEvent } from "@utils/bx-event";
|
||||
import { BxIcon } from "@utils/bx-icon";
|
||||
import { createButton, ButtonStyle, CE } from "@utils/html";
|
||||
import { BaseGameBarAction } from "./action-base";
|
||||
import { MicrophoneShortcut, MicrophoneState } from "../shortcuts/shortcut-microphone";
|
||||
import { BaseGameBarAction } from "./base-action";
|
||||
import { MicrophoneShortcut, MicrophoneState } from "../shortcuts/microphone-shortcut";
|
||||
|
||||
|
||||
export class MicrophoneAction extends BaseGameBarAction {
|
||||
@@ -14,14 +14,14 @@ export class MicrophoneAction extends BaseGameBarAction {
|
||||
const $btnDefault = createButton({
|
||||
style: ButtonStyle.GHOST,
|
||||
icon: BxIcon.MICROPHONE,
|
||||
onClick: this.onClick.bind(this),
|
||||
onClick: this.onClick,
|
||||
classes: ['bx-activated'],
|
||||
});
|
||||
|
||||
const $btnMuted = createButton({
|
||||
style: ButtonStyle.GHOST,
|
||||
icon: BxIcon.MICROPHONE_MUTED,
|
||||
onClick: this.onClick.bind(this),
|
||||
onClick: this.onClick,
|
||||
});
|
||||
|
||||
this.$content = CE('div', {}, $btnMuted, $btnDefault);
|
||||
@@ -36,7 +36,7 @@ export class MicrophoneAction extends BaseGameBarAction {
|
||||
});
|
||||
}
|
||||
|
||||
onClick(e: Event) {
|
||||
onClick = (e: Event) => {
|
||||
super.onClick(e);
|
||||
const enabled = MicrophoneShortcut.toggle(false);
|
||||
this.$content.dataset.activated = enabled.toString();
|
19
src/modules/game-bar/action-renderer.ts → src/modules/game-bar/renderer-action.ts
Normal file → Executable file
19
src/modules/game-bar/action-renderer.ts → src/modules/game-bar/renderer-action.ts
Normal file → Executable file
@@ -1,7 +1,8 @@
|
||||
import { BxIcon } from "@utils/bx-icon";
|
||||
import { createButton, ButtonStyle, CE } from "@utils/html";
|
||||
import { BaseGameBarAction } from "./action-base";
|
||||
import { RendererShortcut } from "../shortcuts/shortcut-renderer";
|
||||
import { BaseGameBarAction } from "./base-action";
|
||||
import { RendererShortcut } from "../shortcuts/renderer-shortcut";
|
||||
import { BxEvent } from "@/utils/bx-event";
|
||||
|
||||
|
||||
export class RendererAction extends BaseGameBarAction {
|
||||
@@ -13,23 +14,27 @@ export class RendererAction extends BaseGameBarAction {
|
||||
const $btnDefault = createButton({
|
||||
style: ButtonStyle.GHOST,
|
||||
icon: BxIcon.EYE,
|
||||
onClick: this.onClick.bind(this),
|
||||
onClick: this.onClick,
|
||||
});
|
||||
|
||||
const $btnActivated = createButton({
|
||||
style: ButtonStyle.GHOST,
|
||||
icon: BxIcon.EYE_SLASH,
|
||||
onClick: this.onClick.bind(this),
|
||||
onClick: this.onClick,
|
||||
classes: ['bx-activated'],
|
||||
});
|
||||
|
||||
this.$content = CE('div', {}, $btnDefault, $btnActivated);
|
||||
|
||||
window.addEventListener(BxEvent.VIDEO_VISIBILITY_CHANGED, e => {
|
||||
const isShowing = (e as any).isShowing;
|
||||
this.$content.dataset.activated = (!isShowing).toString();
|
||||
});
|
||||
}
|
||||
|
||||
onClick(e: Event) {
|
||||
onClick = (e: Event) => {
|
||||
super.onClick(e);
|
||||
const isVisible = RendererShortcut.toggleVisibility();
|
||||
this.$content.dataset.activated = (!isVisible).toString();
|
||||
RendererShortcut.toggleVisibility();
|
||||
}
|
||||
|
||||
reset(): void {
|
6
src/modules/game-bar/action-screenshot.ts → src/modules/game-bar/screenshot-action.ts
Normal file → Executable file
6
src/modules/game-bar/action-screenshot.ts → src/modules/game-bar/screenshot-action.ts
Normal file → Executable file
@@ -1,6 +1,6 @@
|
||||
import { BxIcon } from "@utils/bx-icon";
|
||||
import { createButton, ButtonStyle } from "@utils/html";
|
||||
import { BaseGameBarAction } from "./action-base";
|
||||
import { BaseGameBarAction } from "./base-action";
|
||||
import { t } from "@utils/translation";
|
||||
import { ScreenshotManager } from "@/utils/screenshot-manager";
|
||||
|
||||
@@ -14,11 +14,11 @@ export class ScreenshotAction extends BaseGameBarAction {
|
||||
style: ButtonStyle.GHOST,
|
||||
icon: BxIcon.SCREENSHOT,
|
||||
title: t('take-screenshot'),
|
||||
onClick: this.onClick.bind(this),
|
||||
onClick: this.onClick,
|
||||
});
|
||||
}
|
||||
|
||||
onClick(e: Event): void {
|
||||
onClick = (e: Event) => {
|
||||
super.onClick(e);
|
||||
ScreenshotManager.getInstance().takeScreenshot();
|
||||
}
|
10
src/modules/game-bar/action-speaker.ts → src/modules/game-bar/speaker-action.ts
Normal file → Executable file
10
src/modules/game-bar/action-speaker.ts → src/modules/game-bar/speaker-action.ts
Normal file → Executable file
@@ -1,8 +1,8 @@
|
||||
import { BxEvent } from "@utils/bx-event";
|
||||
import { BxIcon } from "@utils/bx-icon";
|
||||
import { createButton, ButtonStyle, CE } from "@utils/html";
|
||||
import { BaseGameBarAction } from "./action-base";
|
||||
import { SoundShortcut, SpeakerState } from "../shortcuts/shortcut-sound";
|
||||
import { BaseGameBarAction } from "./base-action";
|
||||
import { SoundShortcut, SpeakerState } from "../shortcuts/sound-shortcut";
|
||||
|
||||
|
||||
export class SpeakerAction extends BaseGameBarAction {
|
||||
@@ -14,13 +14,13 @@ export class SpeakerAction extends BaseGameBarAction {
|
||||
const $btnEnable = createButton({
|
||||
style: ButtonStyle.GHOST,
|
||||
icon: BxIcon.AUDIO,
|
||||
onClick: this.onClick.bind(this),
|
||||
onClick: this.onClick,
|
||||
});
|
||||
|
||||
const $btnMuted = createButton({
|
||||
style: ButtonStyle.GHOST,
|
||||
icon: BxIcon.SPEAKER_MUTED,
|
||||
onClick: this.onClick.bind(this),
|
||||
onClick: this.onClick,
|
||||
classes: ['bx-activated'],
|
||||
});
|
||||
|
||||
@@ -34,7 +34,7 @@ export class SpeakerAction extends BaseGameBarAction {
|
||||
});
|
||||
}
|
||||
|
||||
onClick(e: Event) {
|
||||
onClick = (e: Event) => {
|
||||
super.onClick(e);
|
||||
SoundShortcut.muteUnmute();
|
||||
}
|
8
src/modules/game-bar/action-touch-control.ts → src/modules/game-bar/touch-control-action.ts
Normal file → Executable file
8
src/modules/game-bar/action-touch-control.ts → src/modules/game-bar/touch-control-action.ts
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
import { BxIcon } from "@utils/bx-icon";
|
||||
import { createButton, ButtonStyle, CE } from "@utils/html";
|
||||
import { TouchController } from "@modules/touch-controller";
|
||||
import { BaseGameBarAction } from "./action-base";
|
||||
import { BaseGameBarAction } from "./base-action";
|
||||
import { t } from "@utils/translation";
|
||||
|
||||
export class TouchControlAction extends BaseGameBarAction {
|
||||
@@ -14,21 +14,21 @@ export class TouchControlAction extends BaseGameBarAction {
|
||||
style: ButtonStyle.GHOST,
|
||||
icon: BxIcon.TOUCH_CONTROL_ENABLE,
|
||||
title: t('show-touch-controller'),
|
||||
onClick: this.onClick.bind(this),
|
||||
onClick: this.onClick,
|
||||
});
|
||||
|
||||
const $btnDisable = createButton({
|
||||
style: ButtonStyle.GHOST,
|
||||
icon: BxIcon.TOUCH_CONTROL_DISABLE,
|
||||
title: t('hide-touch-controller'),
|
||||
onClick: this.onClick.bind(this),
|
||||
onClick: this.onClick,
|
||||
classes: ['bx-activated'],
|
||||
});
|
||||
|
||||
this.$content = CE('div', {}, $btnEnable, $btnDisable);
|
||||
}
|
||||
|
||||
onClick(e: Event) {
|
||||
onClick = (e: Event) => {
|
||||
super.onClick(e);
|
||||
const isVisible = TouchController.toggleVisibility();
|
||||
this.$content.dataset.activated = (!isVisible).toString();
|
6
src/modules/game-bar/action-true-achievements.ts → src/modules/game-bar/true-achievements-action.ts
Normal file → Executable file
6
src/modules/game-bar/action-true-achievements.ts → src/modules/game-bar/true-achievements-action.ts
Normal file → Executable file
@@ -1,6 +1,6 @@
|
||||
import { BxIcon } from "@/utils/bx-icon";
|
||||
import { createButton, ButtonStyle } from "@/utils/html";
|
||||
import { BaseGameBarAction } from "./action-base";
|
||||
import { BaseGameBarAction } from "./base-action";
|
||||
import { TrueAchievements } from "@/utils/true-achievements";
|
||||
|
||||
export class TrueAchievementsAction extends BaseGameBarAction {
|
||||
@@ -12,11 +12,11 @@ export class TrueAchievementsAction extends BaseGameBarAction {
|
||||
this.$content = createButton({
|
||||
style: ButtonStyle.GHOST,
|
||||
icon: BxIcon.TRUE_ACHIEVEMENTS,
|
||||
onClick: this.onClick.bind(this),
|
||||
onClick: this.onClick,
|
||||
});
|
||||
}
|
||||
|
||||
onClick(e: Event) {
|
||||
onClick = (e: Event) => {
|
||||
super.onClick(e);
|
||||
TrueAchievements.getInstance().open(false);
|
||||
}
|
Reference in New Issue
Block a user