mirror of
https://github.com/redphx/better-xcloud.git
synced 2025-08-06 21:28:27 +02:00
Add option to show wait time in game card
This commit is contained in:
85
src/modules/ui/game-tile.ts
Normal file
85
src/modules/ui/game-tile.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
import { BxEvent } from "@/utils/bx-event";
|
||||
import { BxIcon } from "@/utils/bx-icon";
|
||||
import { CE, createSvgIcon, getReactProps } from "@/utils/html";
|
||||
import { XcloudApi } from "@/utils/xcloud-api";
|
||||
|
||||
export class GameTile {
|
||||
static #timeout: number | null;
|
||||
|
||||
static #secondsToHms(seconds: number) {
|
||||
let h = Math.floor(seconds / 3600);
|
||||
seconds %= 3600;
|
||||
let m = Math.floor(seconds / 60);
|
||||
let s = seconds % 60;
|
||||
|
||||
const output = [];
|
||||
h > 0 && output.push(`${h}h`);
|
||||
m > 0 && output.push(`${m}m`);
|
||||
output.push(`${s}s`);
|
||||
|
||||
return output.join(' ');
|
||||
}
|
||||
|
||||
static async #showWaitTime($elm: HTMLElement, productId: string) {
|
||||
let totalWaitTime;
|
||||
|
||||
const api = XcloudApi.getInstance();
|
||||
const info = await api.getTitleInfo(productId);
|
||||
if (info) {
|
||||
const waitTime = await api.getWaitTime(info.titleId);
|
||||
if (waitTime) {
|
||||
totalWaitTime = waitTime.estimatedTotalWaitTimeInSeconds || 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (totalWaitTime && totalWaitTime == 10 && $elm.isConnected) {
|
||||
const $div = CE('div', {'class': 'bx-game-tile-wait-time'},
|
||||
createSvgIcon(BxIcon.PLAYTIME),
|
||||
CE('span', {}, GameTile.#secondsToHms(totalWaitTime)),
|
||||
);
|
||||
$elm.insertAdjacentElement('afterbegin', $div);
|
||||
}
|
||||
}
|
||||
|
||||
static requestWaitTime($elm: HTMLElement, productId: string) {
|
||||
GameTile.#timeout && clearTimeout(GameTile.#timeout);
|
||||
GameTile.#timeout = window.setTimeout(async () => {
|
||||
if (!($elm as any).hasWaitTime) {
|
||||
($elm as any).hasWaitTime = true;
|
||||
GameTile.#showWaitTime($elm, productId);
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
static setup() {
|
||||
window.addEventListener(BxEvent.NAVIGATION_FOCUS_CHANGED, e => {
|
||||
let productId;
|
||||
const $elm = (e as any).element;
|
||||
try {
|
||||
if (($elm.tagName === 'BUTTON' && $elm.className.includes('MruGameCard')) || (($elm.tagName === 'A' && $elm.className.includes('GameCard')))) {
|
||||
let props = getReactProps($elm.parentElement);
|
||||
|
||||
// When context menu is enabled
|
||||
if (Array.isArray(props.children)) {
|
||||
productId = props.children[0].props.productId;
|
||||
} else {
|
||||
productId = props.children.props.productId;
|
||||
}
|
||||
} else if ($elm.tagName === 'A' && $elm.className.includes('GameItem')) {
|
||||
let props = getReactProps($elm.parentElement);
|
||||
props = props.children.props;
|
||||
if (props.location !== 'NonStreamableGameItem') {
|
||||
if ('productId' in props) {
|
||||
productId = props.productId;
|
||||
} else {
|
||||
// Search page
|
||||
productId = props.children.props.productId;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
productId && GameTile.requestWaitTime($elm, productId);
|
||||
});
|
||||
}
|
||||
}
|
@@ -90,6 +90,7 @@ const SETTINGS_UI = {
|
||||
items: [
|
||||
PrefKey.UI_LAYOUT,
|
||||
PrefKey.UI_HOME_CONTEXT_MENU_DISABLED,
|
||||
PrefKey.UI_GAME_CARD_SHOW_WAIT_TIME,
|
||||
PrefKey.CONTROLLER_SHOW_CONNECTION_STATUS,
|
||||
PrefKey.STREAM_SIMPLIFY_MENU,
|
||||
PrefKey.SKIP_SPLASH_VIDEO,
|
||||
|
Reference in New Issue
Block a user