Replace "#" with "private"

This commit is contained in:
redphx 2024-10-13 10:51:50 +07:00
parent 2eea9ce8f5
commit e4d73f9e36
7 changed files with 299 additions and 299 deletions

View File

@ -1960,43 +1960,43 @@ class StreamStats {
} }
} }
class Toast { class Toast {
static #$wrapper; static $wrapper;
static #$msg; static $msg;
static #$status; static $status;
static #stack = []; static stack = [];
static #isShowing = !1; static isShowing = !1;
static #timeout; static timeout;
static #DURATION = 3000; static DURATION = 3000;
static show(msg, status, options = {}) { static show(msg, status, options = {}) {
options = options || {}; options = options || {};
const args = Array.from(arguments); const args = Array.from(arguments);
if (options.instant) Toast.#stack = [args], Toast.#showNext(); if (options.instant) Toast.stack = [args], Toast.showNext();
else Toast.#stack.push(args), !Toast.#isShowing && Toast.#showNext(); else Toast.stack.push(args), !Toast.isShowing && Toast.showNext();
} }
static #showNext() { static showNext() {
if (!Toast.#stack.length) { if (!Toast.stack.length) {
Toast.#isShowing = !1; Toast.isShowing = !1;
return; return;
} }
Toast.#isShowing = !0, Toast.#timeout && clearTimeout(Toast.#timeout), Toast.#timeout = window.setTimeout(Toast.#hide, Toast.#DURATION); Toast.isShowing = !0, Toast.timeout && clearTimeout(Toast.timeout), Toast.timeout = window.setTimeout(Toast.hide, Toast.DURATION);
const [msg, status, options] = Toast.#stack.shift(); const [msg, status, options] = Toast.stack.shift();
if (options && options.html) Toast.#$msg.innerHTML = msg; if (options && options.html) Toast.$msg.innerHTML = msg;
else Toast.#$msg.textContent = msg; else Toast.$msg.textContent = msg;
if (status) Toast.#$status.classList.remove("bx-gone"), Toast.#$status.textContent = status; if (status) Toast.$status.classList.remove("bx-gone"), Toast.$status.textContent = status;
else Toast.#$status.classList.add("bx-gone"); else Toast.$status.classList.add("bx-gone");
const classList = Toast.#$wrapper.classList; const classList = Toast.$wrapper.classList;
classList.remove("bx-offscreen", "bx-hide"), classList.add("bx-show"); classList.remove("bx-offscreen", "bx-hide"), classList.add("bx-show");
} }
static #hide() { static hide() {
Toast.#timeout = null; Toast.timeout = null;
const classList = Toast.#$wrapper.classList; const classList = Toast.$wrapper.classList;
classList.remove("bx-show"), classList.add("bx-hide"); classList.remove("bx-show"), classList.add("bx-hide");
} }
static setup() { static setup() {
Toast.#$wrapper = CE("div", { class: "bx-toast bx-offscreen" }, Toast.#$msg = CE("span", { class: "bx-toast-msg" }), Toast.#$status = CE("span", { class: "bx-toast-status" })), Toast.#$wrapper.addEventListener("transitionend", (e) => { Toast.$wrapper = CE("div", { class: "bx-toast bx-offscreen" }, Toast.$msg = CE("span", { class: "bx-toast-msg" }), Toast.$status = CE("span", { class: "bx-toast-status" })), Toast.$wrapper.addEventListener("transitionend", (e) => {
const classList = Toast.#$wrapper.classList; const classList = Toast.$wrapper.classList;
if (classList.contains("bx-hide")) classList.remove("bx-offscreen", "bx-hide"), classList.add("bx-offscreen"), Toast.#showNext(); if (classList.contains("bx-hide")) classList.remove("bx-offscreen", "bx-hide"), classList.add("bx-offscreen"), Toast.showNext();
}), document.documentElement.appendChild(Toast.#$wrapper); }), document.documentElement.appendChild(Toast.$wrapper);
} }
} }
function ceilToNearest(value, interval) { function ceilToNearest(value, interval) {
@ -2392,17 +2392,17 @@ class PointerClient {
if (!PointerClient.instance) PointerClient.instance = new PointerClient; if (!PointerClient.instance) PointerClient.instance = new PointerClient;
return PointerClient.instance; return PointerClient.instance;
} }
#socket; socket;
#mkbHandler; mkbHandler;
start(port, mkbHandler) { start(port, mkbHandler) {
if (!port) throw new Error("PointerServer port is 0"); if (!port) throw new Error("PointerServer port is 0");
this.#mkbHandler = mkbHandler, this.#socket = new WebSocket(`ws://localhost:${port}`), this.#socket.binaryType = "arraybuffer", this.#socket.addEventListener("open", (event) => { this.mkbHandler = mkbHandler, this.socket = new WebSocket(`ws://localhost:${port}`), this.socket.binaryType = "arraybuffer", this.socket.addEventListener("open", (event) => {
BxLogger.info(LOG_TAG, "connected"); BxLogger.info(LOG_TAG, "connected");
}), this.#socket.addEventListener("error", (event) => { }), this.socket.addEventListener("error", (event) => {
BxLogger.error(LOG_TAG, event), Toast.show("Cannot setup mouse: " + event); BxLogger.error(LOG_TAG, event), Toast.show("Cannot setup mouse: " + event);
}), this.#socket.addEventListener("close", (event) => { }), this.socket.addEventListener("close", (event) => {
this.#socket = null; this.socket = null;
}), this.#socket.addEventListener("message", (event) => { }), this.socket.addEventListener("message", (event) => {
const dataView = new DataView(event.data); const dataView = new DataView(event.data);
let messageType = dataView.getInt8(0), offset = Int8Array.BYTES_PER_ELEMENT; let messageType = dataView.getInt8(0), offset = Int8Array.BYTES_PER_ELEMENT;
switch (messageType) { switch (messageType) {
@ -2425,14 +2425,14 @@ class PointerClient {
const x = dataView.getInt16(offset); const x = dataView.getInt16(offset);
offset += Int16Array.BYTES_PER_ELEMENT; offset += Int16Array.BYTES_PER_ELEMENT;
const y = dataView.getInt16(offset); const y = dataView.getInt16(offset);
this.#mkbHandler?.handleMouseMove({ this.mkbHandler?.handleMouseMove({
movementX: x, movementX: x,
movementY: y movementY: y
}); });
} }
onPress(messageType, dataView, offset) { onPress(messageType, dataView, offset) {
const button = dataView.getUint8(offset); const button = dataView.getUint8(offset);
this.#mkbHandler?.handleMouseClick({ this.mkbHandler?.handleMouseClick({
pointerButton: button, pointerButton: button,
pressed: messageType === 2 pressed: messageType === 2
}); });
@ -2441,19 +2441,19 @@ class PointerClient {
const vScroll = dataView.getInt16(offset); const vScroll = dataView.getInt16(offset);
offset += Int16Array.BYTES_PER_ELEMENT; offset += Int16Array.BYTES_PER_ELEMENT;
const hScroll = dataView.getInt16(offset); const hScroll = dataView.getInt16(offset);
this.#mkbHandler?.handleMouseWheel({ this.mkbHandler?.handleMouseWheel({
vertical: vScroll, vertical: vScroll,
horizontal: hScroll horizontal: hScroll
}); });
} }
onPointerCaptureChanged(dataView, offset) { onPointerCaptureChanged(dataView, offset) {
dataView.getInt8(offset) !== 1 && this.#mkbHandler?.stop(); dataView.getInt8(offset) !== 1 && this.mkbHandler?.stop();
} }
stop() { stop() {
try { try {
this.#socket?.close(); this.socket?.close();
} catch (e) {} } catch (e) {}
this.#socket = null; this.socket = null;
} }
} }
class MouseDataProvider { class MouseDataProvider {
@ -4375,29 +4375,29 @@ class RemotePlayManager {
} }
} }
class LoadingScreen { class LoadingScreen {
static #$bgStyle; static $bgStyle;
static #$waitTimeBox; static $waitTimeBox;
static #waitTimeInterval = null; static waitTimeInterval = null;
static #orgWebTitle; static orgWebTitle;
static #secondsToString(seconds) { static secondsToString(seconds) {
const m = Math.floor(seconds / 60), s = Math.floor(seconds % 60), mDisplay = m > 0 ? `${m}m` : "", sDisplay = `${s}s`.padStart(s >= 0 ? 3 : 4, "0"); const m = Math.floor(seconds / 60), s = Math.floor(seconds % 60), mDisplay = m > 0 ? `${m}m` : "", sDisplay = `${s}s`.padStart(s >= 0 ? 3 : 4, "0");
return mDisplay + sDisplay; return mDisplay + sDisplay;
} }
static setup() { static setup() {
const titleInfo = STATES.currentStream.titleInfo; const titleInfo = STATES.currentStream.titleInfo;
if (!titleInfo) return; if (!titleInfo) return;
if (!LoadingScreen.#$bgStyle) { if (!LoadingScreen.$bgStyle) {
const $bgStyle = CE("style"); const $bgStyle = CE("style");
document.documentElement.appendChild($bgStyle), LoadingScreen.#$bgStyle = $bgStyle; document.documentElement.appendChild($bgStyle), LoadingScreen.$bgStyle = $bgStyle;
} }
if (LoadingScreen.#setBackground(titleInfo.product.heroImageUrl || titleInfo.product.titledHeroImageUrl || titleInfo.product.tileImageUrl), getPref("ui_loading_screen_rocket") === "hide") LoadingScreen.#hideRocket(); if (LoadingScreen.setBackground(titleInfo.product.heroImageUrl || titleInfo.product.titledHeroImageUrl || titleInfo.product.tileImageUrl), getPref("ui_loading_screen_rocket") === "hide") LoadingScreen.hideRocket();
} }
static #hideRocket() { static hideRocket() {
let $bgStyle = LoadingScreen.#$bgStyle; let $bgStyle = LoadingScreen.$bgStyle;
$bgStyle.textContent += "#game-stream div[class*=RocketAnimation-module__container] > svg{display:none}#game-stream video[class*=RocketAnimationVideo-module__video]{display:none}"; $bgStyle.textContent += "#game-stream div[class*=RocketAnimation-module__container] > svg{display:none}#game-stream video[class*=RocketAnimationVideo-module__video]{display:none}";
} }
static #setBackground(imageUrl) { static setBackground(imageUrl) {
let $bgStyle = LoadingScreen.#$bgStyle; let $bgStyle = LoadingScreen.$bgStyle;
imageUrl = imageUrl + "?w=1920", $bgStyle.textContent += '#game-stream{background-color:transparent !important;background-position:center center !important;background-repeat:no-repeat !important;background-size:cover !important}#game-stream rect[width="800"]{transition:opacity .3s ease-in-out !important}' + `#game-stream {background-image: linear-gradient(#00000033, #000000e6), url(${imageUrl}) !important;}`; imageUrl = imageUrl + "?w=1920", $bgStyle.textContent += '#game-stream{background-color:transparent !important;background-position:center center !important;background-repeat:no-repeat !important;background-size:cover !important}#game-stream rect[width="800"]{transition:opacity .3s ease-in-out !important}' + `#game-stream {background-image: linear-gradient(#00000033, #000000e6), url(${imageUrl}) !important;}`;
const bg = new Image; const bg = new Image;
bg.onload = (e) => { bg.onload = (e) => {
@ -4405,31 +4405,31 @@ class LoadingScreen {
}, bg.src = imageUrl; }, bg.src = imageUrl;
} }
static setupWaitTime(waitTime) { static setupWaitTime(waitTime) {
if (getPref("ui_loading_screen_rocket") === "hide-queue") LoadingScreen.#hideRocket(); if (getPref("ui_loading_screen_rocket") === "hide-queue") LoadingScreen.hideRocket();
let secondsLeft = waitTime, $countDown, $estimated; let secondsLeft = waitTime, $countDown, $estimated;
LoadingScreen.#orgWebTitle = document.title; LoadingScreen.orgWebTitle = document.title;
const endDate = new Date, timeZoneOffsetSeconds = endDate.getTimezoneOffset() * 60; const endDate = new Date, timeZoneOffsetSeconds = endDate.getTimezoneOffset() * 60;
endDate.setSeconds(endDate.getSeconds() + waitTime - timeZoneOffsetSeconds); endDate.setSeconds(endDate.getSeconds() + waitTime - timeZoneOffsetSeconds);
let endDateStr = endDate.toISOString().slice(0, 19); let endDateStr = endDate.toISOString().slice(0, 19);
endDateStr = endDateStr.substring(0, 10) + " " + endDateStr.substring(11, 19), endDateStr += ` (${LoadingScreen.#secondsToString(waitTime)})`; endDateStr = endDateStr.substring(0, 10) + " " + endDateStr.substring(11, 19), endDateStr += ` (${LoadingScreen.secondsToString(waitTime)})`;
let $waitTimeBox = LoadingScreen.#$waitTimeBox; let $waitTimeBox = LoadingScreen.$waitTimeBox;
if (!$waitTimeBox) $waitTimeBox = CE("div", { class: "bx-wait-time-box" }, CE("label", {}, t("server")), CE("span", {}, getPreferredServerRegion()), CE("label", {}, t("wait-time-estimated")), $estimated = CE("span", {}), CE("label", {}, t("wait-time-countdown")), $countDown = CE("span", {})), document.documentElement.appendChild($waitTimeBox), LoadingScreen.#$waitTimeBox = $waitTimeBox; if (!$waitTimeBox) $waitTimeBox = CE("div", { class: "bx-wait-time-box" }, CE("label", {}, t("server")), CE("span", {}, getPreferredServerRegion()), CE("label", {}, t("wait-time-estimated")), $estimated = CE("span", {}), CE("label", {}, t("wait-time-countdown")), $countDown = CE("span", {})), document.documentElement.appendChild($waitTimeBox), LoadingScreen.$waitTimeBox = $waitTimeBox;
else $waitTimeBox.classList.remove("bx-gone"), $estimated = $waitTimeBox.querySelector(".bx-wait-time-estimated"), $countDown = $waitTimeBox.querySelector(".bx-wait-time-countdown"); else $waitTimeBox.classList.remove("bx-gone"), $estimated = $waitTimeBox.querySelector(".bx-wait-time-estimated"), $countDown = $waitTimeBox.querySelector(".bx-wait-time-countdown");
$estimated.textContent = endDateStr, $countDown.textContent = LoadingScreen.#secondsToString(secondsLeft), document.title = `[${$countDown.textContent}] ${LoadingScreen.#orgWebTitle}`, LoadingScreen.#waitTimeInterval = window.setInterval(() => { $estimated.textContent = endDateStr, $countDown.textContent = LoadingScreen.secondsToString(secondsLeft), document.title = `[${$countDown.textContent}] ${LoadingScreen.orgWebTitle}`, LoadingScreen.waitTimeInterval = window.setInterval(() => {
if (secondsLeft--, $countDown.textContent = LoadingScreen.#secondsToString(secondsLeft), document.title = `[${$countDown.textContent}] ${LoadingScreen.#orgWebTitle}`, secondsLeft <= 0) LoadingScreen.#waitTimeInterval && clearInterval(LoadingScreen.#waitTimeInterval), LoadingScreen.#waitTimeInterval = null; if (secondsLeft--, $countDown.textContent = LoadingScreen.secondsToString(secondsLeft), document.title = `[${$countDown.textContent}] ${LoadingScreen.orgWebTitle}`, secondsLeft <= 0) LoadingScreen.waitTimeInterval && clearInterval(LoadingScreen.waitTimeInterval), LoadingScreen.waitTimeInterval = null;
}, 1000); }, 1000);
} }
static hide() { static hide() {
if (LoadingScreen.#orgWebTitle && (document.title = LoadingScreen.#orgWebTitle), LoadingScreen.#$waitTimeBox && LoadingScreen.#$waitTimeBox.classList.add("bx-gone"), getPref("ui_loading_screen_game_art") && LoadingScreen.#$bgStyle) { if (LoadingScreen.orgWebTitle && (document.title = LoadingScreen.orgWebTitle), LoadingScreen.$waitTimeBox && LoadingScreen.$waitTimeBox.classList.add("bx-gone"), getPref("ui_loading_screen_game_art") && LoadingScreen.$bgStyle) {
const $rocketBg = document.querySelector('#game-stream rect[width="800"]'); const $rocketBg = document.querySelector('#game-stream rect[width="800"]');
$rocketBg && $rocketBg.addEventListener("transitionend", (e) => { $rocketBg && $rocketBg.addEventListener("transitionend", (e) => {
LoadingScreen.#$bgStyle.textContent += "#game-stream{background:#000 !important}"; LoadingScreen.$bgStyle.textContent += "#game-stream{background:#000 !important}";
}), LoadingScreen.#$bgStyle.textContent += '#game-stream rect[width="800"]{opacity:1 !important}'; }), LoadingScreen.$bgStyle.textContent += '#game-stream rect[width="800"]{opacity:1 !important}';
} }
setTimeout(LoadingScreen.reset, 2000); setTimeout(LoadingScreen.reset, 2000);
} }
static reset() { static reset() {
LoadingScreen.#$bgStyle && (LoadingScreen.#$bgStyle.textContent = ""), LoadingScreen.#$waitTimeBox && LoadingScreen.#$waitTimeBox.classList.add("bx-gone"), LoadingScreen.#waitTimeInterval && clearInterval(LoadingScreen.#waitTimeInterval), LoadingScreen.#waitTimeInterval = null; LoadingScreen.$bgStyle && (LoadingScreen.$bgStyle.textContent = ""), LoadingScreen.$waitTimeBox && LoadingScreen.$waitTimeBox.classList.add("bx-gone"), LoadingScreen.waitTimeInterval && clearInterval(LoadingScreen.waitTimeInterval), LoadingScreen.waitTimeInterval = null;
} }
} }
class GuideMenu { class GuideMenu {

View File

@ -2031,43 +2031,43 @@ class StreamStats {
} }
} }
class Toast { class Toast {
static #$wrapper; static $wrapper;
static #$msg; static $msg;
static #$status; static $status;
static #stack = []; static stack = [];
static #isShowing = !1; static isShowing = !1;
static #timeout; static timeout;
static #DURATION = 3000; static DURATION = 3000;
static show(msg, status, options = {}) { static show(msg, status, options = {}) {
options = options || {}; options = options || {};
const args = Array.from(arguments); const args = Array.from(arguments);
if (options.instant) Toast.#stack = [args], Toast.#showNext(); if (options.instant) Toast.stack = [args], Toast.showNext();
else Toast.#stack.push(args), !Toast.#isShowing && Toast.#showNext(); else Toast.stack.push(args), !Toast.isShowing && Toast.showNext();
} }
static #showNext() { static showNext() {
if (!Toast.#stack.length) { if (!Toast.stack.length) {
Toast.#isShowing = !1; Toast.isShowing = !1;
return; return;
} }
Toast.#isShowing = !0, Toast.#timeout && clearTimeout(Toast.#timeout), Toast.#timeout = window.setTimeout(Toast.#hide, Toast.#DURATION); Toast.isShowing = !0, Toast.timeout && clearTimeout(Toast.timeout), Toast.timeout = window.setTimeout(Toast.hide, Toast.DURATION);
const [msg, status, options] = Toast.#stack.shift(); const [msg, status, options] = Toast.stack.shift();
if (options && options.html) Toast.#$msg.innerHTML = msg; if (options && options.html) Toast.$msg.innerHTML = msg;
else Toast.#$msg.textContent = msg; else Toast.$msg.textContent = msg;
if (status) Toast.#$status.classList.remove("bx-gone"), Toast.#$status.textContent = status; if (status) Toast.$status.classList.remove("bx-gone"), Toast.$status.textContent = status;
else Toast.#$status.classList.add("bx-gone"); else Toast.$status.classList.add("bx-gone");
const classList = Toast.#$wrapper.classList; const classList = Toast.$wrapper.classList;
classList.remove("bx-offscreen", "bx-hide"), classList.add("bx-show"); classList.remove("bx-offscreen", "bx-hide"), classList.add("bx-show");
} }
static #hide() { static hide() {
Toast.#timeout = null; Toast.timeout = null;
const classList = Toast.#$wrapper.classList; const classList = Toast.$wrapper.classList;
classList.remove("bx-show"), classList.add("bx-hide"); classList.remove("bx-show"), classList.add("bx-hide");
} }
static setup() { static setup() {
Toast.#$wrapper = CE("div", { class: "bx-toast bx-offscreen" }, Toast.#$msg = CE("span", { class: "bx-toast-msg" }), Toast.#$status = CE("span", { class: "bx-toast-status" })), Toast.#$wrapper.addEventListener("transitionend", (e) => { Toast.$wrapper = CE("div", { class: "bx-toast bx-offscreen" }, Toast.$msg = CE("span", { class: "bx-toast-msg" }), Toast.$status = CE("span", { class: "bx-toast-status" })), Toast.$wrapper.addEventListener("transitionend", (e) => {
const classList = Toast.#$wrapper.classList; const classList = Toast.$wrapper.classList;
if (classList.contains("bx-hide")) classList.remove("bx-offscreen", "bx-hide"), classList.add("bx-offscreen"), Toast.#showNext(); if (classList.contains("bx-hide")) classList.remove("bx-offscreen", "bx-hide"), classList.add("bx-offscreen"), Toast.showNext();
}), document.documentElement.appendChild(Toast.#$wrapper); }), document.documentElement.appendChild(Toast.$wrapper);
} }
} }
class MicrophoneShortcut { class MicrophoneShortcut {
@ -2509,17 +2509,17 @@ class PointerClient {
if (!PointerClient.instance) PointerClient.instance = new PointerClient; if (!PointerClient.instance) PointerClient.instance = new PointerClient;
return PointerClient.instance; return PointerClient.instance;
} }
#socket; socket;
#mkbHandler; mkbHandler;
start(port, mkbHandler) { start(port, mkbHandler) {
if (!port) throw new Error("PointerServer port is 0"); if (!port) throw new Error("PointerServer port is 0");
this.#mkbHandler = mkbHandler, this.#socket = new WebSocket(`ws://localhost:${port}`), this.#socket.binaryType = "arraybuffer", this.#socket.addEventListener("open", (event) => { this.mkbHandler = mkbHandler, this.socket = new WebSocket(`ws://localhost:${port}`), this.socket.binaryType = "arraybuffer", this.socket.addEventListener("open", (event) => {
BxLogger.info(LOG_TAG, "connected"); BxLogger.info(LOG_TAG, "connected");
}), this.#socket.addEventListener("error", (event) => { }), this.socket.addEventListener("error", (event) => {
BxLogger.error(LOG_TAG, event), Toast.show("Cannot setup mouse: " + event); BxLogger.error(LOG_TAG, event), Toast.show("Cannot setup mouse: " + event);
}), this.#socket.addEventListener("close", (event) => { }), this.socket.addEventListener("close", (event) => {
this.#socket = null; this.socket = null;
}), this.#socket.addEventListener("message", (event) => { }), this.socket.addEventListener("message", (event) => {
const dataView = new DataView(event.data); const dataView = new DataView(event.data);
let messageType = dataView.getInt8(0), offset = Int8Array.BYTES_PER_ELEMENT; let messageType = dataView.getInt8(0), offset = Int8Array.BYTES_PER_ELEMENT;
switch (messageType) { switch (messageType) {
@ -2542,14 +2542,14 @@ class PointerClient {
const x = dataView.getInt16(offset); const x = dataView.getInt16(offset);
offset += Int16Array.BYTES_PER_ELEMENT; offset += Int16Array.BYTES_PER_ELEMENT;
const y = dataView.getInt16(offset); const y = dataView.getInt16(offset);
this.#mkbHandler?.handleMouseMove({ this.mkbHandler?.handleMouseMove({
movementX: x, movementX: x,
movementY: y movementY: y
}); });
} }
onPress(messageType, dataView, offset) { onPress(messageType, dataView, offset) {
const button = dataView.getUint8(offset); const button = dataView.getUint8(offset);
this.#mkbHandler?.handleMouseClick({ this.mkbHandler?.handleMouseClick({
pointerButton: button, pointerButton: button,
pressed: messageType === 2 pressed: messageType === 2
}); });
@ -2558,19 +2558,19 @@ class PointerClient {
const vScroll = dataView.getInt16(offset); const vScroll = dataView.getInt16(offset);
offset += Int16Array.BYTES_PER_ELEMENT; offset += Int16Array.BYTES_PER_ELEMENT;
const hScroll = dataView.getInt16(offset); const hScroll = dataView.getInt16(offset);
this.#mkbHandler?.handleMouseWheel({ this.mkbHandler?.handleMouseWheel({
vertical: vScroll, vertical: vScroll,
horizontal: hScroll horizontal: hScroll
}); });
} }
onPointerCaptureChanged(dataView, offset) { onPointerCaptureChanged(dataView, offset) {
dataView.getInt8(offset) !== 1 && this.#mkbHandler?.stop(); dataView.getInt8(offset) !== 1 && this.mkbHandler?.stop();
} }
stop() { stop() {
try { try {
this.#socket?.close(); this.socket?.close();
} catch (e) {} } catch (e) {}
this.#socket = null; this.socket = null;
} }
} }
class MouseDataProvider { class MouseDataProvider {
@ -5513,30 +5513,30 @@ class SettingsNavigationDialog extends NavigationDialog {
} }
} }
class ControllerShortcut { class ControllerShortcut {
static #STORAGE_KEY = "better_xcloud_controller_shortcuts"; static STORAGE_KEY = "better_xcloud_controller_shortcuts";
static #buttonsCache = {}; static buttonsCache = {};
static #buttonsStatus = {}; static buttonsStatus = {};
static #$selectProfile; static $selectProfile;
static #$selectActions = {}; static $selectActions = {};
static #$container; static $container;
static #ACTIONS = null; static ACTIONS = null;
static reset(index) { static reset(index) {
ControllerShortcut.#buttonsCache[index] = [], ControllerShortcut.#buttonsStatus[index] = []; ControllerShortcut.buttonsCache[index] = [], ControllerShortcut.buttonsStatus[index] = [];
} }
static handle(gamepad) { static handle(gamepad) {
if (!ControllerShortcut.#ACTIONS) ControllerShortcut.#ACTIONS = ControllerShortcut.#getActionsFromStorage(); if (!ControllerShortcut.ACTIONS) ControllerShortcut.ACTIONS = ControllerShortcut.getActionsFromStorage();
const gamepadIndex = gamepad.index, actions = ControllerShortcut.#ACTIONS[gamepad.id]; const gamepadIndex = gamepad.index, actions = ControllerShortcut.ACTIONS[gamepad.id];
if (!actions) return !1; if (!actions) return !1;
ControllerShortcut.#buttonsCache[gamepadIndex] = ControllerShortcut.#buttonsStatus[gamepadIndex].slice(0), ControllerShortcut.#buttonsStatus[gamepadIndex] = []; ControllerShortcut.buttonsCache[gamepadIndex] = ControllerShortcut.buttonsStatus[gamepadIndex].slice(0), ControllerShortcut.buttonsStatus[gamepadIndex] = [];
const pressed = []; const pressed = [];
let otherButtonPressed = !1; let otherButtonPressed = !1;
return gamepad.buttons.forEach((button, index) => { return gamepad.buttons.forEach((button, index) => {
if (button.pressed && index !== 16) { if (button.pressed && index !== 16) {
if (otherButtonPressed = !0, pressed[index] = !0, actions[index] && !ControllerShortcut.#buttonsCache[gamepadIndex][index]) setTimeout(() => ControllerShortcut.#runAction(actions[index]), 0); if (otherButtonPressed = !0, pressed[index] = !0, actions[index] && !ControllerShortcut.buttonsCache[gamepadIndex][index]) setTimeout(() => ControllerShortcut.runAction(actions[index]), 0);
} }
}), ControllerShortcut.#buttonsStatus[gamepadIndex] = pressed, otherButtonPressed; }), ControllerShortcut.buttonsStatus[gamepadIndex] = pressed, otherButtonPressed;
} }
static #runAction(action) { static runAction(action) {
switch (action) { switch (action) {
case "bx-settings-show": case "bx-settings-show":
SettingsNavigationDialog.getInstance().show(); SettingsNavigationDialog.getInstance().show();
@ -5571,24 +5571,24 @@ class ControllerShortcut {
break; break;
} }
} }
static #updateAction(profile, button, action) { static updateAction(profile, button, action) {
const actions = ControllerShortcut.#ACTIONS; const actions = ControllerShortcut.ACTIONS;
if (!(profile in actions)) actions[profile] = []; if (!(profile in actions)) actions[profile] = [];
if (!action) action = null; if (!action) action = null;
actions[profile][button] = action; actions[profile][button] = action;
for (let key in ControllerShortcut.#ACTIONS) { for (let key in ControllerShortcut.ACTIONS) {
let empty = !0; let empty = !0;
for (let value of ControllerShortcut.#ACTIONS[key]) for (let value of ControllerShortcut.ACTIONS[key])
if (value) { if (value) {
empty = !1; empty = !1;
break; break;
} }
if (empty) delete ControllerShortcut.#ACTIONS[key]; if (empty) delete ControllerShortcut.ACTIONS[key];
} }
window.localStorage.setItem(ControllerShortcut.#STORAGE_KEY, JSON.stringify(ControllerShortcut.#ACTIONS)), console.log(ControllerShortcut.#ACTIONS); window.localStorage.setItem(ControllerShortcut.STORAGE_KEY, JSON.stringify(ControllerShortcut.ACTIONS)), console.log(ControllerShortcut.ACTIONS);
} }
static #updateProfileList(e) { static updateProfileList(e) {
const $select = ControllerShortcut.#$selectProfile, $container = ControllerShortcut.#$container, $fragment = document.createDocumentFragment(); const { $selectProfile: $select, $container } = ControllerShortcut, $fragment = document.createDocumentFragment();
removeChildElements($select); removeChildElements($select);
const gamepads = navigator.getGamepads(); const gamepads = navigator.getGamepads();
let hasGamepad = !1; let hasGamepad = !1;
@ -5601,24 +5601,24 @@ class ControllerShortcut {
} }
if ($container.dataset.hasGamepad = hasGamepad.toString(), hasGamepad) $select.appendChild($fragment), $select.selectedIndex = 0, $select.dispatchEvent(new Event("input")); if ($container.dataset.hasGamepad = hasGamepad.toString(), hasGamepad) $select.appendChild($fragment), $select.selectedIndex = 0, $select.dispatchEvent(new Event("input"));
} }
static #switchProfile(profile) { static switchProfile(profile) {
let actions = ControllerShortcut.#ACTIONS[profile]; let actions = ControllerShortcut.ACTIONS[profile];
if (!actions) actions = []; if (!actions) actions = [];
let button; let button;
for (button in ControllerShortcut.#$selectActions) { for (button in ControllerShortcut.$selectActions) {
const $select = ControllerShortcut.#$selectActions[button]; const $select = ControllerShortcut.$selectActions[button];
$select.value = actions[button] || "", BxEvent.dispatch($select, "input", { $select.value = actions[button] || "", BxEvent.dispatch($select, "input", {
ignoreOnChange: !0, ignoreOnChange: !0,
manualTrigger: !0 manualTrigger: !0
}); });
} }
} }
static #getActionsFromStorage() { static getActionsFromStorage() {
return JSON.parse(window.localStorage.getItem(ControllerShortcut.#STORAGE_KEY) || "{}"); return JSON.parse(window.localStorage.getItem(ControllerShortcut.STORAGE_KEY) || "{}");
} }
static renderSettings() { static renderSettings() {
const PREF_CONTROLLER_FRIENDLY_UI = getPref("ui_controller_friendly"); const PREF_CONTROLLER_FRIENDLY_UI = getPref("ui_controller_friendly");
ControllerShortcut.#ACTIONS = ControllerShortcut.#getActionsFromStorage(); ControllerShortcut.ACTIONS = ControllerShortcut.getActionsFromStorage();
const buttons = new Map; const buttons = new Map;
buttons.set(3, "⇑"), buttons.set(0, "⇓"), buttons.set(1, "⇒"), buttons.set(2, "⇐"), buttons.set(12, "≻"), buttons.set(13, "≽"), buttons.set(14, "≺"), buttons.set(15, "≼"), buttons.set(8, "⇺"), buttons.set(9, "⇻"), buttons.set(4, "↘"), buttons.set(5, "↙"), buttons.set(6, "↖"), buttons.set(7, "↗"), buttons.set(10, "↺"), buttons.set(11, "↻"); buttons.set(3, "⇑"), buttons.set(0, "⇓"), buttons.set(1, "⇒"), buttons.set(2, "⇐"), buttons.set(12, "≻"), buttons.set(13, "≽"), buttons.set(14, "≺"), buttons.set(15, "≼"), buttons.set(8, "⇺"), buttons.set(9, "⇻"), buttons.set(4, "↘"), buttons.set(5, "↙"), buttons.set(6, "↖"), buttons.set(7, "↗"), buttons.set(10, "↺"), buttons.set(11, "↻");
const actions = { const actions = {
@ -5669,7 +5669,7 @@ class ControllerShortcut {
} }
}, $profile), CE("p", { class: "bx-shortcut-note" }, CE("span", { class: "bx-prompt" }, ""), ": " + t("controller-shortcuts-xbox-note")))); }, $profile), CE("p", { class: "bx-shortcut-note" }, CE("span", { class: "bx-prompt" }, ""), ": " + t("controller-shortcuts-xbox-note"))));
$selectProfile.addEventListener("input", (e) => { $selectProfile.addEventListener("input", (e) => {
ControllerShortcut.#switchProfile($selectProfile.value); ControllerShortcut.switchProfile($selectProfile.value);
}); });
const onActionChanged = (e) => { const onActionChanged = (e) => {
const $target = e.target, profile = $selectProfile.value, button = $target.dataset.button, action = $target.value; const $target = e.target, profile = $selectProfile.value, button = $target.dataset.button, action = $target.value;
@ -5682,7 +5682,7 @@ class ControllerShortcut {
} }
$fakeSelect.firstElementChild.text = fakeText; $fakeSelect.firstElementChild.text = fakeText;
} }
!e.ignoreOnChange && ControllerShortcut.#updateAction(profile, button, action); !e.ignoreOnChange && ControllerShortcut.updateAction(profile, button, action);
}; };
for (let [button, prompt2] of buttons) { for (let [button, prompt2] of buttons) {
const $row = CE("div", { const $row = CE("div", {
@ -5693,7 +5693,7 @@ class ControllerShortcut {
$div.appendChild($fakeSelect); $div.appendChild($fakeSelect);
} }
const $select = $baseSelect.cloneNode(!0); const $select = $baseSelect.cloneNode(!0);
if ($select.dataset.button = button.toString(), $select.addEventListener("input", onActionChanged), ControllerShortcut.#$selectActions[button] = $select, PREF_CONTROLLER_FRIENDLY_UI) { if ($select.dataset.button = button.toString(), $select.addEventListener("input", onActionChanged), ControllerShortcut.$selectActions[button] = $select, PREF_CONTROLLER_FRIENDLY_UI) {
const $bxSelect = BxSelectElement.wrap($select); const $bxSelect = BxSelectElement.wrap($select);
$bxSelect.classList.add("bx-full-width"), $div.appendChild($bxSelect), setNearby($row, { $bxSelect.classList.add("bx-full-width"), $div.appendChild($bxSelect), setNearby($row, {
focus: $bxSelect focus: $bxSelect
@ -5703,7 +5703,7 @@ class ControllerShortcut {
}); });
$row.appendChild($label), $row.appendChild($div), $remap.appendChild($row); $row.appendChild($label), $row.appendChild($div), $remap.appendChild($row);
} }
return $container.appendChild($remap), ControllerShortcut.#$selectProfile = $selectProfile, ControllerShortcut.#$container = $container, window.addEventListener("gamepadconnected", ControllerShortcut.#updateProfileList), window.addEventListener("gamepaddisconnected", ControllerShortcut.#updateProfileList), ControllerShortcut.#updateProfileList(), $container; return $container.appendChild($remap), ControllerShortcut.$selectProfile = $selectProfile, ControllerShortcut.$container = $container, window.addEventListener("gamepadconnected", ControllerShortcut.updateProfileList), window.addEventListener("gamepaddisconnected", ControllerShortcut.updateProfileList), ControllerShortcut.updateProfileList(), $container;
} }
} }
var BxExposed = { var BxExposed = {
@ -6155,29 +6155,29 @@ class XhomeInterceptor {
} }
} }
class LoadingScreen { class LoadingScreen {
static #$bgStyle; static $bgStyle;
static #$waitTimeBox; static $waitTimeBox;
static #waitTimeInterval = null; static waitTimeInterval = null;
static #orgWebTitle; static orgWebTitle;
static #secondsToString(seconds) { static secondsToString(seconds) {
const m = Math.floor(seconds / 60), s = Math.floor(seconds % 60), mDisplay = m > 0 ? `${m}m` : "", sDisplay = `${s}s`.padStart(s >= 0 ? 3 : 4, "0"); const m = Math.floor(seconds / 60), s = Math.floor(seconds % 60), mDisplay = m > 0 ? `${m}m` : "", sDisplay = `${s}s`.padStart(s >= 0 ? 3 : 4, "0");
return mDisplay + sDisplay; return mDisplay + sDisplay;
} }
static setup() { static setup() {
const titleInfo = STATES.currentStream.titleInfo; const titleInfo = STATES.currentStream.titleInfo;
if (!titleInfo) return; if (!titleInfo) return;
if (!LoadingScreen.#$bgStyle) { if (!LoadingScreen.$bgStyle) {
const $bgStyle = CE("style"); const $bgStyle = CE("style");
document.documentElement.appendChild($bgStyle), LoadingScreen.#$bgStyle = $bgStyle; document.documentElement.appendChild($bgStyle), LoadingScreen.$bgStyle = $bgStyle;
} }
if (LoadingScreen.#setBackground(titleInfo.product.heroImageUrl || titleInfo.product.titledHeroImageUrl || titleInfo.product.tileImageUrl), getPref("ui_loading_screen_rocket") === "hide") LoadingScreen.#hideRocket(); if (LoadingScreen.setBackground(titleInfo.product.heroImageUrl || titleInfo.product.titledHeroImageUrl || titleInfo.product.tileImageUrl), getPref("ui_loading_screen_rocket") === "hide") LoadingScreen.hideRocket();
} }
static #hideRocket() { static hideRocket() {
let $bgStyle = LoadingScreen.#$bgStyle; let $bgStyle = LoadingScreen.$bgStyle;
$bgStyle.textContent += "#game-stream div[class*=RocketAnimation-module__container] > svg{display:none}#game-stream video[class*=RocketAnimationVideo-module__video]{display:none}"; $bgStyle.textContent += "#game-stream div[class*=RocketAnimation-module__container] > svg{display:none}#game-stream video[class*=RocketAnimationVideo-module__video]{display:none}";
} }
static #setBackground(imageUrl) { static setBackground(imageUrl) {
let $bgStyle = LoadingScreen.#$bgStyle; let $bgStyle = LoadingScreen.$bgStyle;
imageUrl = imageUrl + "?w=1920", $bgStyle.textContent += '#game-stream{background-color:transparent !important;background-position:center center !important;background-repeat:no-repeat !important;background-size:cover !important}#game-stream rect[width="800"]{transition:opacity .3s ease-in-out !important}' + `#game-stream {background-image: linear-gradient(#00000033, #000000e6), url(${imageUrl}) !important;}`; imageUrl = imageUrl + "?w=1920", $bgStyle.textContent += '#game-stream{background-color:transparent !important;background-position:center center !important;background-repeat:no-repeat !important;background-size:cover !important}#game-stream rect[width="800"]{transition:opacity .3s ease-in-out !important}' + `#game-stream {background-image: linear-gradient(#00000033, #000000e6), url(${imageUrl}) !important;}`;
const bg = new Image; const bg = new Image;
bg.onload = (e) => { bg.onload = (e) => {
@ -6185,31 +6185,31 @@ class LoadingScreen {
}, bg.src = imageUrl; }, bg.src = imageUrl;
} }
static setupWaitTime(waitTime) { static setupWaitTime(waitTime) {
if (getPref("ui_loading_screen_rocket") === "hide-queue") LoadingScreen.#hideRocket(); if (getPref("ui_loading_screen_rocket") === "hide-queue") LoadingScreen.hideRocket();
let secondsLeft = waitTime, $countDown, $estimated; let secondsLeft = waitTime, $countDown, $estimated;
LoadingScreen.#orgWebTitle = document.title; LoadingScreen.orgWebTitle = document.title;
const endDate = new Date, timeZoneOffsetSeconds = endDate.getTimezoneOffset() * 60; const endDate = new Date, timeZoneOffsetSeconds = endDate.getTimezoneOffset() * 60;
endDate.setSeconds(endDate.getSeconds() + waitTime - timeZoneOffsetSeconds); endDate.setSeconds(endDate.getSeconds() + waitTime - timeZoneOffsetSeconds);
let endDateStr = endDate.toISOString().slice(0, 19); let endDateStr = endDate.toISOString().slice(0, 19);
endDateStr = endDateStr.substring(0, 10) + " " + endDateStr.substring(11, 19), endDateStr += ` (${LoadingScreen.#secondsToString(waitTime)})`; endDateStr = endDateStr.substring(0, 10) + " " + endDateStr.substring(11, 19), endDateStr += ` (${LoadingScreen.secondsToString(waitTime)})`;
let $waitTimeBox = LoadingScreen.#$waitTimeBox; let $waitTimeBox = LoadingScreen.$waitTimeBox;
if (!$waitTimeBox) $waitTimeBox = CE("div", { class: "bx-wait-time-box" }, CE("label", {}, t("server")), CE("span", {}, getPreferredServerRegion()), CE("label", {}, t("wait-time-estimated")), $estimated = CE("span", {}), CE("label", {}, t("wait-time-countdown")), $countDown = CE("span", {})), document.documentElement.appendChild($waitTimeBox), LoadingScreen.#$waitTimeBox = $waitTimeBox; if (!$waitTimeBox) $waitTimeBox = CE("div", { class: "bx-wait-time-box" }, CE("label", {}, t("server")), CE("span", {}, getPreferredServerRegion()), CE("label", {}, t("wait-time-estimated")), $estimated = CE("span", {}), CE("label", {}, t("wait-time-countdown")), $countDown = CE("span", {})), document.documentElement.appendChild($waitTimeBox), LoadingScreen.$waitTimeBox = $waitTimeBox;
else $waitTimeBox.classList.remove("bx-gone"), $estimated = $waitTimeBox.querySelector(".bx-wait-time-estimated"), $countDown = $waitTimeBox.querySelector(".bx-wait-time-countdown"); else $waitTimeBox.classList.remove("bx-gone"), $estimated = $waitTimeBox.querySelector(".bx-wait-time-estimated"), $countDown = $waitTimeBox.querySelector(".bx-wait-time-countdown");
$estimated.textContent = endDateStr, $countDown.textContent = LoadingScreen.#secondsToString(secondsLeft), document.title = `[${$countDown.textContent}] ${LoadingScreen.#orgWebTitle}`, LoadingScreen.#waitTimeInterval = window.setInterval(() => { $estimated.textContent = endDateStr, $countDown.textContent = LoadingScreen.secondsToString(secondsLeft), document.title = `[${$countDown.textContent}] ${LoadingScreen.orgWebTitle}`, LoadingScreen.waitTimeInterval = window.setInterval(() => {
if (secondsLeft--, $countDown.textContent = LoadingScreen.#secondsToString(secondsLeft), document.title = `[${$countDown.textContent}] ${LoadingScreen.#orgWebTitle}`, secondsLeft <= 0) LoadingScreen.#waitTimeInterval && clearInterval(LoadingScreen.#waitTimeInterval), LoadingScreen.#waitTimeInterval = null; if (secondsLeft--, $countDown.textContent = LoadingScreen.secondsToString(secondsLeft), document.title = `[${$countDown.textContent}] ${LoadingScreen.orgWebTitle}`, secondsLeft <= 0) LoadingScreen.waitTimeInterval && clearInterval(LoadingScreen.waitTimeInterval), LoadingScreen.waitTimeInterval = null;
}, 1000); }, 1000);
} }
static hide() { static hide() {
if (LoadingScreen.#orgWebTitle && (document.title = LoadingScreen.#orgWebTitle), LoadingScreen.#$waitTimeBox && LoadingScreen.#$waitTimeBox.classList.add("bx-gone"), getPref("ui_loading_screen_game_art") && LoadingScreen.#$bgStyle) { if (LoadingScreen.orgWebTitle && (document.title = LoadingScreen.orgWebTitle), LoadingScreen.$waitTimeBox && LoadingScreen.$waitTimeBox.classList.add("bx-gone"), getPref("ui_loading_screen_game_art") && LoadingScreen.$bgStyle) {
const $rocketBg = document.querySelector('#game-stream rect[width="800"]'); const $rocketBg = document.querySelector('#game-stream rect[width="800"]');
$rocketBg && $rocketBg.addEventListener("transitionend", (e) => { $rocketBg && $rocketBg.addEventListener("transitionend", (e) => {
LoadingScreen.#$bgStyle.textContent += "#game-stream{background:#000 !important}"; LoadingScreen.$bgStyle.textContent += "#game-stream{background:#000 !important}";
}), LoadingScreen.#$bgStyle.textContent += '#game-stream rect[width="800"]{opacity:1 !important}'; }), LoadingScreen.$bgStyle.textContent += '#game-stream rect[width="800"]{opacity:1 !important}';
} }
setTimeout(LoadingScreen.reset, 2000); setTimeout(LoadingScreen.reset, 2000);
} }
static reset() { static reset() {
LoadingScreen.#$bgStyle && (LoadingScreen.#$bgStyle.textContent = ""), LoadingScreen.#$waitTimeBox && LoadingScreen.#$waitTimeBox.classList.add("bx-gone"), LoadingScreen.#waitTimeInterval && clearInterval(LoadingScreen.#waitTimeInterval), LoadingScreen.#waitTimeInterval = null; LoadingScreen.$bgStyle && (LoadingScreen.$bgStyle.textContent = ""), LoadingScreen.$waitTimeBox && LoadingScreen.$waitTimeBox.classList.add("bx-gone"), LoadingScreen.waitTimeInterval && clearInterval(LoadingScreen.waitTimeInterval), LoadingScreen.waitTimeInterval = null;
} }
} }
class TrueAchievements { class TrueAchievements {
@ -7558,10 +7558,10 @@ class XcloudApi {
if (!XcloudApi.instance) XcloudApi.instance = new XcloudApi; if (!XcloudApi.instance) XcloudApi.instance = new XcloudApi;
return XcloudApi.instance; return XcloudApi.instance;
} }
#CACHE_TITLES = {}; CACHE_TITLES = {};
#CACHE_WAIT_TIME = {}; CACHE_WAIT_TIME = {};
async getTitleInfo(id2) { async getTitleInfo(id2) {
if (id2 in this.#CACHE_TITLES) return this.#CACHE_TITLES[id2]; if (id2 in this.CACHE_TITLES) return this.CACHE_TITLES[id2];
const baseUri = STATES.selectedRegion.baseUri; const baseUri = STATES.selectedRegion.baseUri;
if (!baseUri || !STATES.gsToken) return null; if (!baseUri || !STATES.gsToken) return null;
let json; let json;
@ -7580,10 +7580,10 @@ class XcloudApi {
} catch (e) { } catch (e) {
json = {}; json = {};
} }
return this.#CACHE_TITLES[id2] = json, json; return this.CACHE_TITLES[id2] = json, json;
} }
async getWaitTime(id2) { async getWaitTime(id2) {
if (id2 in this.#CACHE_WAIT_TIME) return this.#CACHE_WAIT_TIME[id2]; if (id2 in this.CACHE_WAIT_TIME) return this.CACHE_WAIT_TIME[id2];
const baseUri = STATES.selectedRegion.baseUri; const baseUri = STATES.selectedRegion.baseUri;
if (!baseUri || !STATES.gsToken) return null; if (!baseUri || !STATES.gsToken) return null;
let json; let json;
@ -7597,7 +7597,7 @@ class XcloudApi {
} catch (e) { } catch (e) {
json = {}; json = {};
} }
return this.#CACHE_WAIT_TIME[id2] = json, json; return this.CACHE_WAIT_TIME[id2] = json, json;
} }
} }
class GameTile { class GameTile {

View File

@ -38,37 +38,37 @@ const enum ShortcutAction {
} }
export class ControllerShortcut { export class ControllerShortcut {
static readonly #STORAGE_KEY = 'better_xcloud_controller_shortcuts'; private static readonly STORAGE_KEY = 'better_xcloud_controller_shortcuts';
static #buttonsCache: {[key: string]: boolean[]} = {}; private static buttonsCache: {[key: string]: boolean[]} = {};
static #buttonsStatus: {[key: string]: boolean[]} = {}; private static buttonsStatus: {[key: string]: boolean[]} = {};
static #$selectProfile: HTMLSelectElement; private static $selectProfile: HTMLSelectElement;
static #$selectActions: Partial<{[key in GamepadKey]: HTMLSelectElement}> = {}; private static $selectActions: Partial<{[key in GamepadKey]: HTMLSelectElement}> = {};
static #$container: HTMLElement; private static $container: HTMLElement;
static #ACTIONS: {[key: string]: (ShortcutAction | null)[]} | null = null; private static ACTIONS: {[key: string]: (ShortcutAction | null)[]} | null = null;
static reset(index: number) { static reset(index: number) {
ControllerShortcut.#buttonsCache[index] = []; ControllerShortcut.buttonsCache[index] = [];
ControllerShortcut.#buttonsStatus[index] = []; ControllerShortcut.buttonsStatus[index] = [];
} }
static handle(gamepad: Gamepad): boolean { static handle(gamepad: Gamepad): boolean {
if (!ControllerShortcut.#ACTIONS) { if (!ControllerShortcut.ACTIONS) {
ControllerShortcut.#ACTIONS = ControllerShortcut.#getActionsFromStorage(); ControllerShortcut.ACTIONS = ControllerShortcut.getActionsFromStorage();
} }
const gamepadIndex = gamepad.index; const gamepadIndex = gamepad.index;
const actions = ControllerShortcut.#ACTIONS![gamepad.id]; const actions = ControllerShortcut.ACTIONS![gamepad.id];
if (!actions) { if (!actions) {
return false; return false;
} }
// Move the buttons status from the previous frame to the cache // Move the buttons status from the previous frame to the cache
ControllerShortcut.#buttonsCache[gamepadIndex] = ControllerShortcut.#buttonsStatus[gamepadIndex].slice(0); ControllerShortcut.buttonsCache[gamepadIndex] = ControllerShortcut.buttonsStatus[gamepadIndex].slice(0);
// Clear the buttons status // Clear the buttons status
ControllerShortcut.#buttonsStatus[gamepadIndex] = []; ControllerShortcut.buttonsStatus[gamepadIndex] = [];
const pressed: boolean[] = []; const pressed: boolean[] = [];
let otherButtonPressed = false; let otherButtonPressed = false;
@ -80,17 +80,17 @@ export class ControllerShortcut {
pressed[index] = true; pressed[index] = true;
// If this is newly pressed button -> run action // If this is newly pressed button -> run action
if (actions[index] && !ControllerShortcut.#buttonsCache[gamepadIndex][index]) { if (actions[index] && !ControllerShortcut.buttonsCache[gamepadIndex][index]) {
setTimeout(() => ControllerShortcut.#runAction(actions[index]!), 0); setTimeout(() => ControllerShortcut.runAction(actions[index]!), 0);
} }
} }
}); });
ControllerShortcut.#buttonsStatus[gamepadIndex] = pressed; ControllerShortcut.buttonsStatus[gamepadIndex] = pressed;
return otherButtonPressed; return otherButtonPressed;
} }
static #runAction(action: ShortcutAction) { private static runAction(action: ShortcutAction) {
switch (action) { switch (action) {
case ShortcutAction.BETTER_XCLOUD_SETTINGS_SHOW: case ShortcutAction.BETTER_XCLOUD_SETTINGS_SHOW:
SettingsNavigationDialog.getInstance().show(); SettingsNavigationDialog.getInstance().show();
@ -134,8 +134,8 @@ export class ControllerShortcut {
} }
} }
static #updateAction(profile: string, button: GamepadKey, action: ShortcutAction | null) { private static updateAction(profile: string, button: GamepadKey, action: ShortcutAction | null) {
const actions = ControllerShortcut.#ACTIONS!; const actions = ControllerShortcut.ACTIONS!;
if (!(profile in actions)) { if (!(profile in actions)) {
actions[profile] = []; actions[profile] = [];
} }
@ -147,9 +147,9 @@ export class ControllerShortcut {
actions[profile][button] = action; actions[profile][button] = action;
// Remove empty profiles // Remove empty profiles
for (const key in ControllerShortcut.#ACTIONS) { for (const key in ControllerShortcut.ACTIONS) {
let empty = true; let empty = true;
for (const value of ControllerShortcut.#ACTIONS[key]) { for (const value of ControllerShortcut.ACTIONS[key]) {
if (!!value) { if (!!value) {
empty = false; empty = false;
break; break;
@ -157,19 +157,19 @@ export class ControllerShortcut {
} }
if (empty) { if (empty) {
delete ControllerShortcut.#ACTIONS[key]; delete ControllerShortcut.ACTIONS[key];
} }
} }
// Save to storage // Save to storage
window.localStorage.setItem(ControllerShortcut.#STORAGE_KEY, JSON.stringify(ControllerShortcut.#ACTIONS)); window.localStorage.setItem(ControllerShortcut.STORAGE_KEY, JSON.stringify(ControllerShortcut.ACTIONS));
console.log(ControllerShortcut.#ACTIONS); console.log(ControllerShortcut.ACTIONS);
} }
static #updateProfileList(e?: GamepadEvent) { private static updateProfileList(e?: GamepadEvent) {
const $select = ControllerShortcut.#$selectProfile; const $select = ControllerShortcut.$selectProfile;
const $container = ControllerShortcut.#$container; const $container = ControllerShortcut.$container;
const $fragment = document.createDocumentFragment(); const $fragment = document.createDocumentFragment();
@ -205,16 +205,16 @@ export class ControllerShortcut {
} }
static #switchProfile(profile: string) { private static switchProfile(profile: string) {
let actions = ControllerShortcut.#ACTIONS![profile]; let actions = ControllerShortcut.ACTIONS![profile];
if (!actions) { if (!actions) {
actions = []; actions = [];
} }
// Reset selects' values // Reset selects' values
let button: any; let button: any;
for (button in ControllerShortcut.#$selectActions) { for (button in ControllerShortcut.$selectActions) {
const $select = ControllerShortcut.#$selectActions[button as GamepadKey]!; const $select = ControllerShortcut.$selectActions[button as GamepadKey]!;
$select.value = actions[button] || ''; $select.value = actions[button] || '';
BxEvent.dispatch($select, 'input', { BxEvent.dispatch($select, 'input', {
@ -224,15 +224,15 @@ export class ControllerShortcut {
} }
} }
static #getActionsFromStorage() { private static getActionsFromStorage() {
return JSON.parse(window.localStorage.getItem(ControllerShortcut.#STORAGE_KEY) || '{}'); return JSON.parse(window.localStorage.getItem(ControllerShortcut.STORAGE_KEY) || '{}');
} }
static renderSettings() { static renderSettings() {
const PREF_CONTROLLER_FRIENDLY_UI = getPref(PrefKey.UI_CONTROLLER_FRIENDLY); const PREF_CONTROLLER_FRIENDLY_UI = getPref(PrefKey.UI_CONTROLLER_FRIENDLY);
// Read actions from localStorage // Read actions from localStorage
ControllerShortcut.#ACTIONS = ControllerShortcut.#getActionsFromStorage(); ControllerShortcut.ACTIONS = ControllerShortcut.getActionsFromStorage();
const buttons: Map<GamepadKey, PrompFont> = new Map(); const buttons: Map<GamepadKey, PrompFont> = new Map();
buttons.set(GamepadKey.Y, PrompFont.Y); buttons.set(GamepadKey.Y, PrompFont.Y);
@ -340,7 +340,7 @@ export class ControllerShortcut {
); );
$selectProfile.addEventListener('input', e => { $selectProfile.addEventListener('input', e => {
ControllerShortcut.#switchProfile($selectProfile.value); ControllerShortcut.switchProfile($selectProfile.value);
}); });
const onActionChanged = (e: Event) => { const onActionChanged = (e: Event) => {
@ -361,7 +361,7 @@ export class ControllerShortcut {
($fakeSelect.firstElementChild as HTMLOptionElement).text = fakeText; ($fakeSelect.firstElementChild as HTMLOptionElement).text = fakeText;
} }
!(e as any).ignoreOnChange && ControllerShortcut.#updateAction(profile, button as GamepadKey, action); !(e as any).ignoreOnChange && ControllerShortcut.updateAction(profile, button as GamepadKey, action);
}; };
@ -387,7 +387,7 @@ export class ControllerShortcut {
$select.dataset.button = button.toString(); $select.dataset.button = button.toString();
$select.addEventListener('input', onActionChanged); $select.addEventListener('input', onActionChanged);
ControllerShortcut.#$selectActions[button] = $select; ControllerShortcut.$selectActions[button] = $select;
if (PREF_CONTROLLER_FRIENDLY_UI) { if (PREF_CONTROLLER_FRIENDLY_UI) {
const $bxSelect = BxSelectElement.wrap($select); const $bxSelect = BxSelectElement.wrap($select);
@ -412,14 +412,14 @@ export class ControllerShortcut {
$container.appendChild($remap); $container.appendChild($remap);
ControllerShortcut.#$selectProfile = $selectProfile; ControllerShortcut.$selectProfile = $selectProfile;
ControllerShortcut.#$container = $container; ControllerShortcut.$container = $container;
// Detect when gamepad connected/disconnect // Detect when gamepad connected/disconnect
window.addEventListener('gamepadconnected', ControllerShortcut.#updateProfileList); window.addEventListener('gamepadconnected', ControllerShortcut.updateProfileList);
window.addEventListener('gamepaddisconnected', ControllerShortcut.#updateProfileList); window.addEventListener('gamepaddisconnected', ControllerShortcut.updateProfileList);
ControllerShortcut.#updateProfileList(); ControllerShortcut.updateProfileList();
return $container; return $container;
} }

View File

@ -7,13 +7,13 @@ import { getPref } from "@/utils/settings-storages/global-settings-storage";
import { compressCss } from "@macros/build" with {type: "macro"}; import { compressCss } from "@macros/build" with {type: "macro"};
export class LoadingScreen { export class LoadingScreen {
static #$bgStyle: HTMLElement; private static $bgStyle: HTMLElement;
static #$waitTimeBox: HTMLElement; private static $waitTimeBox: HTMLElement;
static #waitTimeInterval?: number | null = null; private static waitTimeInterval?: number | null = null;
static #orgWebTitle: string; private static orgWebTitle: string;
static #secondsToString(seconds: number) { private static secondsToString(seconds: number) {
const m = Math.floor(seconds / 60); const m = Math.floor(seconds / 60);
const s = Math.floor(seconds % 60); const s = Math.floor(seconds % 60);
@ -28,21 +28,21 @@ export class LoadingScreen {
return; return;
} }
if (!LoadingScreen.#$bgStyle) { if (!LoadingScreen.$bgStyle) {
const $bgStyle = CE('style'); const $bgStyle = CE('style');
document.documentElement.appendChild($bgStyle); document.documentElement.appendChild($bgStyle);
LoadingScreen.#$bgStyle = $bgStyle; LoadingScreen.$bgStyle = $bgStyle;
} }
LoadingScreen.#setBackground(titleInfo.product.heroImageUrl || titleInfo.product.titledHeroImageUrl || titleInfo.product.tileImageUrl); LoadingScreen.setBackground(titleInfo.product.heroImageUrl || titleInfo.product.titledHeroImageUrl || titleInfo.product.tileImageUrl);
if (getPref(PrefKey.UI_LOADING_SCREEN_ROCKET) === 'hide') { if (getPref(PrefKey.UI_LOADING_SCREEN_ROCKET) === 'hide') {
LoadingScreen.#hideRocket(); LoadingScreen.hideRocket();
} }
} }
static #hideRocket() { private static hideRocket() {
let $bgStyle = LoadingScreen.#$bgStyle; let $bgStyle = LoadingScreen.$bgStyle;
$bgStyle.textContent! += compressCss(` $bgStyle.textContent! += compressCss(`
#game-stream div[class*=RocketAnimation-module__container] > svg { #game-stream div[class*=RocketAnimation-module__container] > svg {
@ -55,9 +55,9 @@ export class LoadingScreen {
`); `);
} }
static #setBackground(imageUrl: string) { private static setBackground(imageUrl: string) {
// Setup style tag // Setup style tag
let $bgStyle = LoadingScreen.#$bgStyle; let $bgStyle = LoadingScreen.$bgStyle;
// Limit max width to reduce image size // Limit max width to reduce image size
imageUrl = imageUrl + '?w=1920'; imageUrl = imageUrl + '?w=1920';
@ -89,14 +89,14 @@ export class LoadingScreen {
static setupWaitTime(waitTime: number) { static setupWaitTime(waitTime: number) {
// Hide rocket when queing // Hide rocket when queing
if (getPref(PrefKey.UI_LOADING_SCREEN_ROCKET) === 'hide-queue') { if (getPref(PrefKey.UI_LOADING_SCREEN_ROCKET) === 'hide-queue') {
LoadingScreen.#hideRocket(); LoadingScreen.hideRocket();
} }
let secondsLeft = waitTime; let secondsLeft = waitTime;
let $countDown; let $countDown;
let $estimated; let $estimated;
LoadingScreen.#orgWebTitle = document.title; LoadingScreen.orgWebTitle = document.title;
const endDate = new Date(); const endDate = new Date();
const timeZoneOffsetSeconds = endDate.getTimezoneOffset() * 60; const timeZoneOffsetSeconds = endDate.getTimezoneOffset() * 60;
@ -104,9 +104,9 @@ export class LoadingScreen {
let endDateStr = endDate.toISOString().slice(0, 19); let endDateStr = endDate.toISOString().slice(0, 19);
endDateStr = endDateStr.substring(0, 10) + ' ' + endDateStr.substring(11, 19); endDateStr = endDateStr.substring(0, 10) + ' ' + endDateStr.substring(11, 19);
endDateStr += ` (${LoadingScreen.#secondsToString(waitTime)})`; endDateStr += ` (${LoadingScreen.secondsToString(waitTime)})`;
let $waitTimeBox = LoadingScreen.#$waitTimeBox; let $waitTimeBox = LoadingScreen.$waitTimeBox;
if (!$waitTimeBox) { if (!$waitTimeBox) {
$waitTimeBox = CE('div', {'class': 'bx-wait-time-box'}, $waitTimeBox = CE('div', {'class': 'bx-wait-time-box'},
CE('label', {}, t('server')), CE('label', {}, t('server')),
@ -118,7 +118,7 @@ export class LoadingScreen {
); );
document.documentElement.appendChild($waitTimeBox); document.documentElement.appendChild($waitTimeBox);
LoadingScreen.#$waitTimeBox = $waitTimeBox; LoadingScreen.$waitTimeBox = $waitTimeBox;
} else { } else {
$waitTimeBox.classList.remove('bx-gone'); $waitTimeBox.classList.remove('bx-gone');
$estimated = $waitTimeBox.querySelector('.bx-wait-time-estimated')!; $estimated = $waitTimeBox.querySelector('.bx-wait-time-estimated')!;
@ -126,36 +126,36 @@ export class LoadingScreen {
} }
$estimated.textContent = endDateStr; $estimated.textContent = endDateStr;
$countDown.textContent = LoadingScreen.#secondsToString(secondsLeft); $countDown.textContent = LoadingScreen.secondsToString(secondsLeft);
document.title = `[${$countDown.textContent}] ${LoadingScreen.#orgWebTitle}`; document.title = `[${$countDown.textContent}] ${LoadingScreen.orgWebTitle}`;
LoadingScreen.#waitTimeInterval = window.setInterval(() => { LoadingScreen.waitTimeInterval = window.setInterval(() => {
secondsLeft--; secondsLeft--;
$countDown.textContent = LoadingScreen.#secondsToString(secondsLeft); $countDown.textContent = LoadingScreen.secondsToString(secondsLeft);
document.title = `[${$countDown.textContent}] ${LoadingScreen.#orgWebTitle}`; document.title = `[${$countDown.textContent}] ${LoadingScreen.orgWebTitle}`;
if (secondsLeft <= 0) { if (secondsLeft <= 0) {
LoadingScreen.#waitTimeInterval && clearInterval(LoadingScreen.#waitTimeInterval); LoadingScreen.waitTimeInterval && clearInterval(LoadingScreen.waitTimeInterval);
LoadingScreen.#waitTimeInterval = null; LoadingScreen.waitTimeInterval = null;
} }
}, 1000); }, 1000);
} }
static hide() { static hide() {
LoadingScreen.#orgWebTitle && (document.title = LoadingScreen.#orgWebTitle); LoadingScreen.orgWebTitle && (document.title = LoadingScreen.orgWebTitle);
LoadingScreen.#$waitTimeBox && LoadingScreen.#$waitTimeBox.classList.add('bx-gone'); LoadingScreen.$waitTimeBox && LoadingScreen.$waitTimeBox.classList.add('bx-gone');
if (getPref(PrefKey.UI_LOADING_SCREEN_GAME_ART) && LoadingScreen.#$bgStyle) { if (getPref(PrefKey.UI_LOADING_SCREEN_GAME_ART) && LoadingScreen.$bgStyle) {
const $rocketBg = document.querySelector('#game-stream rect[width="800"]'); const $rocketBg = document.querySelector('#game-stream rect[width="800"]');
$rocketBg && $rocketBg.addEventListener('transitionend', e => { $rocketBg && $rocketBg.addEventListener('transitionend', e => {
LoadingScreen.#$bgStyle.textContent += compressCss(` LoadingScreen.$bgStyle.textContent += compressCss(`
#game-stream { #game-stream {
background: #000 !important; background: #000 !important;
} }
`); `);
}); });
LoadingScreen.#$bgStyle.textContent += compressCss(` LoadingScreen.$bgStyle.textContent += compressCss(`
#game-stream rect[width="800"] { #game-stream rect[width="800"] {
opacity: 1 !important; opacity: 1 !important;
} }
@ -166,10 +166,10 @@ export class LoadingScreen {
} }
static reset() { static reset() {
LoadingScreen.#$bgStyle && (LoadingScreen.#$bgStyle.textContent = ''); LoadingScreen.$bgStyle && (LoadingScreen.$bgStyle.textContent = '');
LoadingScreen.#$waitTimeBox && LoadingScreen.#$waitTimeBox.classList.add('bx-gone'); LoadingScreen.$waitTimeBox && LoadingScreen.$waitTimeBox.classList.add('bx-gone');
LoadingScreen.#waitTimeInterval && clearInterval(LoadingScreen.#waitTimeInterval); LoadingScreen.waitTimeInterval && clearInterval(LoadingScreen.waitTimeInterval);
LoadingScreen.#waitTimeInterval = null; LoadingScreen.waitTimeInterval = null;
} }
} }

View File

@ -23,37 +23,37 @@ export class PointerClient {
return PointerClient.instance; return PointerClient.instance;
} }
#socket: WebSocket | undefined | null; private socket: WebSocket | undefined | null;
#mkbHandler: MkbHandler | undefined; private mkbHandler: MkbHandler | undefined;
start(port: number, mkbHandler: MkbHandler) { start(port: number, mkbHandler: MkbHandler) {
if (!port) { if (!port) {
throw new Error('PointerServer port is 0'); throw new Error('PointerServer port is 0');
} }
this.#mkbHandler = mkbHandler; this.mkbHandler = mkbHandler;
// Create WebSocket connection. // Create WebSocket connection.
this.#socket = new WebSocket(`ws://localhost:${port}`); this.socket = new WebSocket(`ws://localhost:${port}`);
this.#socket.binaryType = 'arraybuffer'; this.socket.binaryType = 'arraybuffer';
// Connection opened // Connection opened
this.#socket.addEventListener('open', (event) => { this.socket.addEventListener('open', (event) => {
BxLogger.info(LOG_TAG, 'connected') BxLogger.info(LOG_TAG, 'connected')
}); });
// Error // Error
this.#socket.addEventListener('error', (event) => { this.socket.addEventListener('error', (event) => {
BxLogger.error(LOG_TAG, event); BxLogger.error(LOG_TAG, event);
Toast.show('Cannot setup mouse: ' + event); Toast.show('Cannot setup mouse: ' + event);
}); });
this.#socket.addEventListener('close', (event) => { this.socket.addEventListener('close', (event) => {
this.#socket = null; this.socket = null;
}); });
// Listen for messages // Listen for messages
this.#socket.addEventListener('message', (event) => { this.socket.addEventListener('message', (event) => {
const dataView = new DataView(event.data); const dataView = new DataView(event.data);
let messageType = dataView.getInt8(0); let messageType = dataView.getInt8(0);
@ -84,7 +84,7 @@ export class PointerClient {
offset += Int16Array.BYTES_PER_ELEMENT; offset += Int16Array.BYTES_PER_ELEMENT;
const y = dataView.getInt16(offset); const y = dataView.getInt16(offset);
this.#mkbHandler?.handleMouseMove({ this.mkbHandler?.handleMouseMove({
movementX: x, movementX: x,
movementY: y, movementY: y,
}); });
@ -94,7 +94,7 @@ export class PointerClient {
onPress(messageType: PointerAction, dataView: DataView, offset: number) { onPress(messageType: PointerAction, dataView: DataView, offset: number) {
const button = dataView.getUint8(offset); const button = dataView.getUint8(offset);
this.#mkbHandler?.handleMouseClick({ this.mkbHandler?.handleMouseClick({
pointerButton: button, pointerButton: button,
pressed: messageType === PointerAction.BUTTON_PRESS, pressed: messageType === PointerAction.BUTTON_PRESS,
}); });
@ -108,7 +108,7 @@ export class PointerClient {
offset += Int16Array.BYTES_PER_ELEMENT; offset += Int16Array.BYTES_PER_ELEMENT;
const hScroll = dataView.getInt16(offset); const hScroll = dataView.getInt16(offset);
this.#mkbHandler?.handleMouseWheel({ this.mkbHandler?.handleMouseWheel({
vertical: vScroll, vertical: vScroll,
horizontal: hScroll, horizontal: hScroll,
}); });
@ -118,13 +118,13 @@ export class PointerClient {
onPointerCaptureChanged(dataView: DataView, offset: number) { onPointerCaptureChanged(dataView: DataView, offset: number) {
const hasCapture = dataView.getInt8(offset) === 1; const hasCapture = dataView.getInt8(offset) === 1;
!hasCapture && this.#mkbHandler?.stop(); !hasCapture && this.mkbHandler?.stop();
} }
stop() { stop() {
try { try {
this.#socket?.close(); this.socket?.close();
} catch (e) {} } catch (e) {}
this.#socket = null; this.socket = null;
} }
} }

View File

@ -6,14 +6,14 @@ type ToastOptions = {
} }
export class Toast { export class Toast {
static #$wrapper: HTMLElement; private static $wrapper: HTMLElement;
static #$msg: HTMLElement; private static $msg: HTMLElement;
static #$status: HTMLElement; private static $status: HTMLElement;
static #stack: Array<[string, string, ToastOptions]> = []; private static stack: Array<[string, string, ToastOptions]> = [];
static #isShowing = false; private static isShowing = false;
static #timeout?: number | null; private static timeout?: number | null;
static #DURATION = 3000; private static DURATION = 3000;
static show(msg: string, status?: string, options: Partial<ToastOptions> = {}) { static show(msg: string, status?: string, options: Partial<ToastOptions> = {}) {
options = options || {}; options = options || {};
@ -21,69 +21,70 @@ export class Toast {
const args = Array.from(arguments) as [string, string, ToastOptions]; const args = Array.from(arguments) as [string, string, ToastOptions];
if (options.instant) { if (options.instant) {
// Clear stack // Clear stack
Toast.#stack = [args]; Toast.stack = [args];
Toast.#showNext(); Toast.showNext();
} else { } else {
Toast.#stack.push(args); Toast.stack.push(args);
!Toast.#isShowing && Toast.#showNext(); !Toast.isShowing && Toast.showNext();
} }
} }
static #showNext() { private static showNext() {
if (!Toast.#stack.length) { if (!Toast.stack.length) {
Toast.#isShowing = false; Toast.isShowing = false;
return; return;
} }
Toast.#isShowing = true; Toast.isShowing = true;
Toast.#timeout && clearTimeout(Toast.#timeout); Toast.timeout && clearTimeout(Toast.timeout);
Toast.#timeout = window.setTimeout(Toast.#hide, Toast.#DURATION); Toast.timeout = window.setTimeout(Toast.hide, Toast.DURATION);
// Get values from item // Get values from item
const [msg, status, options] = Toast.#stack.shift()!; const [msg, status, options] = Toast.stack.shift()!;
if (options && options.html) { if (options && options.html) {
Toast.#$msg.innerHTML = msg; Toast.$msg.innerHTML = msg;
} else { } else {
Toast.#$msg.textContent = msg; Toast.$msg.textContent = msg;
} }
if (status) { if (status) {
Toast.#$status.classList.remove('bx-gone'); Toast.$status.classList.remove('bx-gone');
Toast.#$status.textContent = status; Toast.$status.textContent = status;
} else { } else {
Toast.#$status.classList.add('bx-gone'); Toast.$status.classList.add('bx-gone');
} }
const classList = Toast.#$wrapper.classList; const classList = Toast.$wrapper.classList;
classList.remove('bx-offscreen', 'bx-hide'); classList.remove('bx-offscreen', 'bx-hide');
classList.add('bx-show'); classList.add('bx-show');
} }
static #hide() { private static hide() {
Toast.#timeout = null; Toast.timeout = null;
const classList = Toast.#$wrapper.classList; const classList = Toast.$wrapper.classList;
classList.remove('bx-show'); classList.remove('bx-show');
classList.add('bx-hide'); classList.add('bx-hide');
} }
static setup() { static setup() {
Toast.#$wrapper = CE('div', {'class': 'bx-toast bx-offscreen'}, Toast.$wrapper = CE('div', {'class': 'bx-toast bx-offscreen'},
Toast.#$msg = CE('span', {'class': 'bx-toast-msg'}), Toast.$msg = CE('span', {'class': 'bx-toast-msg'}),
Toast.#$status = CE('span', {'class': 'bx-toast-status'})); Toast.$status = CE('span', {'class': 'bx-toast-status'}),
);
Toast.#$wrapper.addEventListener('transitionend', e => { Toast.$wrapper.addEventListener('transitionend', e => {
const classList = Toast.#$wrapper.classList; const classList = Toast.$wrapper.classList;
if (classList.contains('bx-hide')) { if (classList.contains('bx-hide')) {
classList.remove('bx-offscreen', 'bx-hide'); classList.remove('bx-offscreen', 'bx-hide');
classList.add('bx-offscreen'); classList.add('bx-offscreen');
Toast.#showNext(); Toast.showNext();
} }
}); });
document.documentElement.appendChild(Toast.#$wrapper); document.documentElement.appendChild(Toast.$wrapper);
} }
} }

View File

@ -3,7 +3,6 @@ import { STATES } from "./global";
export class XcloudApi { export class XcloudApi {
private static instance: XcloudApi; private static instance: XcloudApi;
public static getInstance(): XcloudApi { public static getInstance(): XcloudApi {
if (!XcloudApi.instance) { if (!XcloudApi.instance) {
XcloudApi.instance = new XcloudApi(); XcloudApi.instance = new XcloudApi();
@ -12,12 +11,12 @@ export class XcloudApi {
return XcloudApi.instance; return XcloudApi.instance;
} }
#CACHE_TITLES: {[key: string]: XcloudTitleInfo} = {}; private CACHE_TITLES: {[key: string]: XcloudTitleInfo} = {};
#CACHE_WAIT_TIME: {[key: string]: XcloudWaitTimeInfo} = {}; private CACHE_WAIT_TIME: {[key: string]: XcloudWaitTimeInfo} = {};
async getTitleInfo(id: string): Promise<XcloudTitleInfo | null> { async getTitleInfo(id: string): Promise<XcloudTitleInfo | null> {
if (id in this.#CACHE_TITLES) { if (id in this.CACHE_TITLES) {
return this.#CACHE_TITLES[id]; return this.CACHE_TITLES[id];
} }
const baseUri = STATES.selectedRegion.baseUri; const baseUri = STATES.selectedRegion.baseUri;
@ -45,13 +44,13 @@ export class XcloudApi {
} catch (e) { } catch (e) {
json = {} json = {}
} }
this.#CACHE_TITLES[id] = json; this.CACHE_TITLES[id] = json;
return json; return json;
} }
async getWaitTime(id: string): Promise<XcloudWaitTimeInfo | null> { async getWaitTime(id: string): Promise<XcloudWaitTimeInfo | null> {
if (id in this.#CACHE_WAIT_TIME) { if (id in this.CACHE_WAIT_TIME) {
return this.#CACHE_WAIT_TIME[id]; return this.CACHE_WAIT_TIME[id];
} }
const baseUri = STATES.selectedRegion.baseUri; const baseUri = STATES.selectedRegion.baseUri;
@ -73,7 +72,7 @@ export class XcloudApi {
json = {}; json = {};
} }
this.#CACHE_WAIT_TIME[id] = json; this.CACHE_WAIT_TIME[id] = json;
return json; return json;
} }
} }