Add "Create shortcut" button to Product Details page

This commit is contained in:
redphx 2024-07-19 16:48:31 +07:00
parent 66123bc4ef
commit dbbdc48aab
9 changed files with 79 additions and 5 deletions

View File

@ -69,7 +69,7 @@
height: var(--bx-button-height);
&:not(:only-child) {
margin-right: 4px;
margin-right: 10px;
}
}
@ -117,3 +117,7 @@ button.bx-inactive {
opacity: 0.2;
background: transparent !important;
}
.bx-button-shortcut {
margin-top: 10px;
}

View File

@ -5,7 +5,7 @@
--bx-monospaced-font: Consolas, "Courier New", Courier, monospace;
--bx-promptfont-font: promptfont;
--bx-button-height: 36px;
--bx-button-height: 40px;
--bx-default-button-color: #2d3036;
--bx-default-button-hover-color: #515863;

View File

@ -0,0 +1,4 @@
<svg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='#fff' fill-rule='evenodd' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 32 32'>
<path d="M13.253 3.639c0-.758-.615-1.373-1.373-1.373H3.639c-.758 0-1.373.615-1.373 1.373v8.241c0 .758.615 1.373 1.373 1.373h8.241c.758 0 1.373-.615 1.373-1.373V3.639zm0 16.481c0-.758-.615-1.373-1.373-1.373H3.639c-.758 0-1.373.615-1.373 1.373v8.241c0 .758.615 1.373 1.373 1.373h8.241c.758 0 1.373-.615 1.373-1.373V20.12zm16.481 0c0-.758-.615-1.373-1.373-1.373H20.12c-.758 0-1.373.615-1.373 1.373v8.241c0 .758.615 1.373 1.373 1.373h8.241c.758 0 1.373-.615 1.373-1.373V20.12zM19.262 7.76h9.957"/>
<path d="M24.24 2.781v9.957"/>
</svg>

After

Width:  |  Height:  |  Size: 711 B

View File

@ -35,6 +35,7 @@ import { updateVideoPlayer } from "./modules/stream/stream-settings-utils";
import { UiSection } from "./enums/ui-sections";
import { HeaderSection } from "./modules/ui/header";
import { GameTile } from "./modules/ui/game-tile";
import { ProductDetailsPage } from "./modules/ui/product-details";
// Handle login page
@ -198,6 +199,13 @@ window.addEventListener(BxEvent.STREAM_ERROR_PAGE, e => {
BxEvent.dispatch(window, BxEvent.STREAM_STOPPED);
});
window.addEventListener(BxEvent.XCLOUD_RENDERING_COMPONENT, e => {
const component = (e as any).component;
if (component === 'product-details') {
ProductDetailsPage.injectShortcutButton();
}
});
function unload() {
if (!STATES.isPlaying) {
return;

View File

@ -1,4 +1,4 @@
import { SCRIPT_VERSION, STATES } from "@utils/global";
import { AppInterface, SCRIPT_VERSION, STATES } from "@utils/global";
import { BX_FLAGS } from "@utils/bx-flags";
import { getPref, PrefKey } from "@utils/preferences";
import { VibrationManager } from "@modules/vibration-manager";
@ -799,6 +799,22 @@ if (this.baseStorageKey in window.BX_EXPOSED.overrideSettings) {
str = str.substring(0, index) + codeSetCurrentlyFocusedInteractable + str.substring(index);
return str;
},
// product-details-page.js#2388, 24.17.20
detectProductDetailsPage(str: string) {
let index = str.indexOf('{location:"ProductDetailPage",');
if (index === -1) {
return false;
}
index = str.indexOf('return', index - 40);
if (index === -1) {
return false;
}
str = str.substring(0, index) + 'BxEvent.dispatch(window, BxEvent.XCLOUD_RENDERING_COMPONENT, {component: "product-details"});' + str.substring(index);
return str;
},
};
let PATCH_ORDERS: PatchArray = [
@ -820,6 +836,7 @@ let PATCH_ORDERS: PatchArray = [
'exposeDialogRoutes',
'enableTvRoutes',
AppInterface && 'detectProductDetailsPage',
'overrideStorageGetSettings',
getPref(PrefKey.UI_GAME_CARD_SHOW_WAIT_TIME) && 'patchSetCurrentlyFocusedInteractable',

View File

@ -0,0 +1,36 @@
import { BX_FLAGS } from "@/utils/bx-flags";
import { BxIcon } from "@/utils/bx-icon";
import { AppInterface } from "@/utils/global";
import { ButtonStyle, createButton } from "@/utils/html";
import { t } from "@/utils/translation";
export class ProductDetailsPage {
private static $btnShortcut = createButton({
classes: ['bx-button-shortcut'],
icon: BxIcon.CREATE_SHORTCUT,
label: t('create-shortcut'),
style: ButtonStyle.FOCUSABLE,
tabIndex: 0,
onClick: e => {
AppInterface && AppInterface.createShortcut(window.location.pathname.substring(6));
},
});
private static shortcutTimeoutId: number | null = null;
static injectShortcutButton() {
if (!AppInterface || BX_FLAGS.DeviceInfo?.deviceType !== 'android') {
return;
}
ProductDetailsPage.shortcutTimeoutId && clearTimeout(ProductDetailsPage.shortcutTimeoutId);
ProductDetailsPage.shortcutTimeoutId = window.setTimeout(() => {
// Find action buttons container
const $container = document.querySelector('div[class*=ActionButtons-module__container]');
if ($container) {
this.$btnShortcut.style.width = $container.getBoundingClientRect().width + 'px';
$container.parentElement?.appendChild(ProductDetailsPage.$btnShortcut);
}
}, 500);
}
}

View File

@ -48,6 +48,8 @@ export enum BxEvent {
XCLOUD_GUIDE_MENU_SHOWN = 'bx-xcloud-guide-menu-shown',
XCLOUD_POLLING_MODE_CHANGED = 'bx-xcloud-polling-mode-changed',
XCLOUD_RENDERING_COMPONENT = 'bx-xcloud-rendering-page',
}
export enum XcloudEvent {

View File

@ -1,6 +1,7 @@
import iconCommand from "@assets/svg/command.svg" with { type: "text" };
import iconController from "@assets/svg/controller.svg" with { type: "text" };
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 iconHome from "@assets/svg/home.svg" with { type: "text" };
@ -11,9 +12,9 @@ import iconRefresh from "@assets/svg/refresh.svg" with { type: "text" };
import iconRemotePlay from "@assets/svg/remote-play.svg" with { type: "text" };
import iconStreamSettings from "@assets/svg/stream-settings.svg" with { type: "text" };
import iconStreamStats from "@assets/svg/stream-stats.svg" with { type: "text" };
import iconTrash from "@assets/svg/trash.svg" with { type: "text" };
import iconTouchControlEnable from "@assets/svg/touch-control-enable.svg" with { type: "text" };
import iconTouchControlDisable from "@assets/svg/touch-control-disable.svg" with { type: "text" };
import iconTouchControlEnable from "@assets/svg/touch-control-enable.svg" with { type: "text" };
import iconTrash from "@assets/svg/trash.svg" with { type: "text" };
import iconVirtualController from "@assets/svg/virtual-controller.svg" with { type: "text" };
// Game Bar
@ -37,6 +38,7 @@ export const BxIcon = {
STREAM_STATS: iconStreamStats,
COMMAND: iconCommand,
CONTROLLER: iconController,
CREATE_SHORTCUT: iconCreateShortcut,
DISPLAY: iconDisplay,
HOME: iconHome,
NATIVE_MKB: iconNativeMkb,

View File

@ -76,6 +76,7 @@ const Texts = {
"controller-shortcuts-xbox-note": "Button to open the Guide menu",
"controller-vibration": "Controller vibration",
"copy": "Copy",
"create-shortcut": "Create shortcut",
"custom": "Custom",
"deadzone-counterweight": "Deadzone counterweight",
"decrease": "Decrease",