From a095370ab84025433a8eaaa2f21e581197986c3d Mon Sep 17 00:00:00 2001 From: redphx <96280+redphx@users.noreply.github.com> Date: Fri, 30 Aug 2024 20:04:40 +0700 Subject: [PATCH] Show the wait time of every games in the "Jump back in" section all at once --- src/assets/css/root.styl | 10 ++--- src/modules/ui/game-tile.ts | 85 +++++++++++++++++++++++-------------- src/utils/bx-event.ts | 2 +- 3 files changed, 57 insertions(+), 40 deletions(-) diff --git a/src/assets/css/root.styl b/src/assets/css/root.styl index 033d7a6..b974bd4 100644 --- a/src/assets/css/root.styl +++ b/src/assets/css/root.styl @@ -168,16 +168,11 @@ div[class*=SupportedInputsBadge] { left: 0; z-index: 1; background: #0000008c; - display: none; - border-radius: 0 0 4px 0; + display: flex; + border-radius: 4px 0 4px 0; align-items: center; padding: 4px 8px; - a[class^=BaseItem-module__container]:focus &, - button[class^=BaseItem-module__container]:focus & { - display: flex; - } - svg { width: 14px; height: 16px; @@ -190,6 +185,7 @@ div[class*=SupportedInputsBadge] { line-height: 16px; font-size: 12px; font-weight: bold; + margin-left: 2px; } } diff --git a/src/modules/ui/game-tile.ts b/src/modules/ui/game-tile.ts index 02825a8..1fd5858 100644 --- a/src/modules/ui/game-tile.ts +++ b/src/modules/ui/game-tile.ts @@ -1,6 +1,6 @@ import { BxEvent } from "@/utils/bx-event"; import { BxIcon } from "@/utils/bx-icon"; -import { CE, createSvgIcon, getReactProps } from "@/utils/html"; +import { CE, createSvgIcon, getReactProps, isElementVisible } from "@/utils/html"; import { XcloudApi } from "@/utils/xcloud-api"; export class GameTile { @@ -23,6 +23,11 @@ export class GameTile { } static async #showWaitTime($elm: HTMLElement, productId: string) { + if (($elm as any).hasWaitTime) { + return; + } + ($elm as any).hasWaitTime = true; + let totalWaitTime; const api = XcloudApi.getInstance(); @@ -34,7 +39,7 @@ export class GameTile { } } - if (typeof totalWaitTime === 'number' && $elm.isConnected) { + if (typeof totalWaitTime === 'number' && isElementVisible($elm)) { const $div = CE('div', {'class': 'bx-game-tile-wait-time'}, createSvgIcon(BxIcon.PLAYTIME), CE('span', {}, GameTile.#secondsToHms(totalWaitTime)), @@ -43,45 +48,61 @@ export class GameTile { } } - static requestWaitTime($elm: HTMLElement, productId: string) { + 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); + GameTile.#showWaitTime($elm, productId); + }, 500); + } + + static #findProductId($elm: HTMLElement): string | null { + let productId = null; + + 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; + } + } } - }, 1000); + } catch (e) {} + + return productId; } 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; - } - } + const className = $elm.className || ''; + if (className.includes('MruGameCard')) { + // Show the wait time of every games in the "Jump back in" section all at once + const $ol = $elm.closest('ol'); + if ($ol && !($ol as any).hasWaitTime) { + ($ol as any).hasWaitTime = true; + $ol.querySelectorAll('button[class*=MruGameCard]').forEach(($elm: HTMLElement) => { + const productId = GameTile.#findProductId($elm); + productId && GameTile.#showWaitTime($elm, productId); + }); } - } catch (e) {} - - productId && GameTile.requestWaitTime($elm, productId); + } else { + const productId = GameTile.#findProductId($elm); + productId && GameTile.#requestWaitTime($elm, productId); + } }); } } diff --git a/src/utils/bx-event.ts b/src/utils/bx-event.ts index e4ae521..736339f 100644 --- a/src/utils/bx-event.ts +++ b/src/utils/bx-event.ts @@ -51,7 +51,7 @@ export namespace BxEvent { export const XCLOUD_POLLING_MODE_CHANGED = 'bx-xcloud-polling-mode-changed'; - export const XCLOUD_RENDERING_COMPONENT = 'bx-xcloud-rendering-page'; + export const XCLOUD_RENDERING_COMPONENT = 'bx-xcloud-rendering-component'; export const XCLOUD_ROUTER_HISTORY_READY = 'bx-xcloud-router-history-ready';