diff --git a/dist/better-xcloud.lite.user.js b/dist/better-xcloud.lite.user.js
index 26245c8..53ddc86 100644
--- a/dist/better-xcloud.lite.user.js
+++ b/dist/better-xcloud.lite.user.js
@@ -3059,6 +3059,8 @@ var BxIcon = {
CONTROLLER: "",
CREATE_SHORTCUT: "",
DISPLAY: "",
+ EYE: "",
+ EYE_SLASH: "",
HOME: "",
NATIVE_MKB: "",
NEW: "",
diff --git a/dist/better-xcloud.user.js b/dist/better-xcloud.user.js
index fad28d7..c183cd6 100644
--- a/dist/better-xcloud.user.js
+++ b/dist/better-xcloud.user.js
@@ -3342,6 +3342,8 @@ var BxIcon = {
CONTROLLER: "",
CREATE_SHORTCUT: "",
DISPLAY: "",
+ EYE: "",
+ EYE_SLASH: "",
HOME: "",
NATIVE_MKB: "",
NEW: "",
@@ -7465,6 +7467,38 @@ class SpeakerAction extends BaseGameBarAction {
this.$content.dataset.enabled = "true";
}
}
+class RendererShortcut {
+ static toggleVisibility() {
+ const $mediaContainer = document.querySelector('#game-stream div[data-testid="media-container"]');
+ if (!$mediaContainer) return !0;
+ return $mediaContainer.classList.toggle("bx-gone"), !$mediaContainer.classList.contains("bx-gone");
+ }
+}
+class RendererAction extends BaseGameBarAction {
+ $content;
+ constructor() {
+ super();
+ const onClick = (e) => {
+ BxEvent.dispatch(window, BxEvent.GAME_BAR_ACTION_ACTIVATED), this.$content.dataset.enabled = RendererShortcut.toggleVisibility().toString();
+ }, $btnDefault = createButton({
+ style: 4,
+ icon: BxIcon.EYE,
+ onClick
+ }), $btnActivated = createButton({
+ style: 4,
+ icon: BxIcon.EYE_SLASH,
+ onClick,
+ classes: ["bx-activated"]
+ });
+ this.$content = CE("div", {}, $btnDefault, $btnActivated), this.reset();
+ }
+ render() {
+ return this.$content;
+ }
+ reset() {
+ this.$content.dataset.enabled = "true";
+ }
+}
class GameBar {
static instance;
static getInstance() {
@@ -7474,7 +7508,7 @@ class GameBar {
static VISIBLE_DURATION = 2000;
$gameBar;
$container;
- timeout = null;
+ timeoutId = null;
actions = [];
constructor() {
let $container;
@@ -7483,6 +7517,7 @@ class GameBar {
new ScreenshotAction,
...STATES.userAgent.capabilities.touch && getPref("stream_touch_controller") !== "off" ? [new TouchControlAction] : [],
new SpeakerAction,
+ new RendererAction,
new MicrophoneAction,
new TrueAchievementsAction
], position === "bottom-right")
@@ -7504,12 +7539,12 @@ class GameBar {
}).bind(this));
}
beginHideTimeout() {
- this.clearHideTimeout(), this.timeout = window.setTimeout(() => {
- this.timeout = null, this.hideBar();
+ this.clearHideTimeout(), this.timeoutId = window.setTimeout(() => {
+ this.timeoutId = null, this.hideBar();
}, GameBar.VISIBLE_DURATION);
}
clearHideTimeout() {
- this.timeout && clearTimeout(this.timeout), this.timeout = null;
+ this.timeoutId && clearTimeout(this.timeoutId), this.timeoutId = null;
}
enable() {
this.$gameBar && this.$gameBar.classList.remove("bx-gone");
diff --git a/src/assets/svg/eye-slash.svg b/src/assets/svg/eye-slash.svg
new file mode 100644
index 0000000..68775d2
--- /dev/null
+++ b/src/assets/svg/eye-slash.svg
@@ -0,0 +1,8 @@
+
diff --git a/src/assets/svg/eye.svg b/src/assets/svg/eye.svg
new file mode 100644
index 0000000..7eae1e6
--- /dev/null
+++ b/src/assets/svg/eye.svg
@@ -0,0 +1,8 @@
+
diff --git a/src/modules/game-bar/action-renderer.ts b/src/modules/game-bar/action-renderer.ts
new file mode 100644
index 0000000..f43b331
--- /dev/null
+++ b/src/modules/game-bar/action-renderer.ts
@@ -0,0 +1,47 @@
+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 { RendererShortcut } from "../shortcuts/shortcut-renderer";
+
+
+export class RendererAction extends BaseGameBarAction {
+ $content: HTMLElement;
+
+ constructor() {
+ super();
+
+ const onClick = (e: Event) => {
+ BxEvent.dispatch(window, BxEvent.GAME_BAR_ACTION_ACTIVATED);
+ this.$content.dataset.enabled = RendererShortcut.toggleVisibility().toString();
+ };
+
+ const $btnDefault = createButton({
+ style: ButtonStyle.GHOST,
+ icon: BxIcon.EYE,
+ onClick: onClick,
+ });
+
+ const $btnActivated = createButton({
+ style: ButtonStyle.GHOST,
+ icon: BxIcon.EYE_SLASH,
+ onClick: onClick,
+ classes: ['bx-activated'],
+ });
+
+ this.$content = CE('div', {},
+ $btnDefault,
+ $btnActivated,
+ );
+
+ this.reset();
+ }
+
+ render(): HTMLElement {
+ return this.$content;
+ }
+
+ reset(): void {
+ this.$content.dataset.enabled = 'true';
+ }
+}
diff --git a/src/modules/game-bar/game-bar.ts b/src/modules/game-bar/game-bar.ts
index 23d1dc9..10e1e13 100644
--- a/src/modules/game-bar/game-bar.ts
+++ b/src/modules/game-bar/game-bar.ts
@@ -10,6 +10,7 @@ import { PrefKey } from "@/enums/pref-keys";
import { getPref, StreamTouchController } from "@/utils/settings-storages/global-settings-storage";
import { TrueAchievementsAction } from "./action-true-achievements";
import { SpeakerAction } from "./action-speaker";
+import { RendererAction } from "./action-renderer";
export class GameBar {
@@ -27,7 +28,7 @@ export class GameBar {
private $gameBar: HTMLElement;
private $container: HTMLElement;
- private timeout: number | null = null;
+ private timeoutId: number | null = null;
private actions: BaseGameBarAction[] = [];
@@ -45,6 +46,7 @@ export class GameBar {
new ScreenshotAction(),
...(STATES.userAgent.capabilities.touch && (getPref(PrefKey.STREAM_TOUCH_CONTROLLER) !== StreamTouchController.OFF) ? [new TouchControlAction()] : []),
new SpeakerAction(),
+ new RendererAction(),
new MicrophoneAction(),
new TrueAchievementsAction(),
];
@@ -103,15 +105,15 @@ export class GameBar {
private beginHideTimeout() {
this.clearHideTimeout();
- this.timeout = window.setTimeout(() => {
- this.timeout = null;
+ this.timeoutId = window.setTimeout(() => {
+ this.timeoutId = null;
this.hideBar();
}, GameBar.VISIBLE_DURATION);
}
private clearHideTimeout() {
- this.timeout && clearTimeout(this.timeout);
- this.timeout = null;
+ this.timeoutId && clearTimeout(this.timeoutId);
+ this.timeoutId = null;
}
enable() {
diff --git a/src/modules/shortcuts/shortcut-renderer.ts b/src/modules/shortcuts/shortcut-renderer.ts
new file mode 100644
index 0000000..765fc12
--- /dev/null
+++ b/src/modules/shortcuts/shortcut-renderer.ts
@@ -0,0 +1,11 @@
+export class RendererShortcut {
+ static toggleVisibility(): boolean {
+ const $mediaContainer = document.querySelector('#game-stream div[data-testid="media-container"]');
+ if (!$mediaContainer) {
+ return true;
+ }
+
+ $mediaContainer.classList.toggle('bx-gone');
+ return !$mediaContainer.classList.contains('bx-gone');
+ }
+}
diff --git a/src/utils/bx-icon.ts b/src/utils/bx-icon.ts
index 495d0ac..3c517be 100644
--- a/src/utils/bx-icon.ts
+++ b/src/utils/bx-icon.ts
@@ -7,6 +7,8 @@ import iconCopy from "@assets/svg/copy.svg" with { type: "text" };
import iconCreateShortcut from "@assets/svg/create-shortcut.svg" with { type: "text" };
import iconCursorText from "@assets/svg/cursor-text.svg" with { type: "text" };
import iconDisplay from "@assets/svg/display.svg" with { type: "text" };
+import iconEye from "@assets/svg/eye.svg" with { type: "text" };
+import iconEyeSlash from "@assets/svg/eye-slash.svg" with { type: "text" };
import iconHome from "@assets/svg/home.svg" with { type: "text" };
import iconNativeMkb from "@assets/svg/native-mkb.svg" with { type: "text" };
import iconNew from "@assets/svg/new.svg" with { type: "text" };
@@ -48,6 +50,8 @@ export const BxIcon = {
CONTROLLER: iconController,
CREATE_SHORTCUT: iconCreateShortcut,
DISPLAY: iconDisplay,
+ EYE: iconEye,
+ EYE_SLASH: iconEyeSlash,
HOME: iconHome,
NATIVE_MKB: iconNativeMkb,
NEW: iconNew,