mirror of
https://github.com/redphx/better-xcloud.git
synced 2025-06-06 15:47:18 +02:00
Show local co-op icon in details page
This commit is contained in:
parent
68b29ecb50
commit
6448a00271
@ -106,7 +106,6 @@
|
|||||||
&.bx-frosted {
|
&.bx-frosted {
|
||||||
--button-alpha: 0.2;
|
--button-alpha: 0.2;
|
||||||
background-color: unquote('rgba(var(--button-rgb), var(--button-alpha))');
|
background-color: unquote('rgba(var(--button-rgb), var(--button-alpha))');
|
||||||
backdrop-filter: blur(4px) brightness(1.5);
|
|
||||||
|
|
||||||
&:not([disabled]):not(:active) {
|
&:not([disabled]):not(:active) {
|
||||||
&:hover, &.bx-focusable:focus {
|
&:hover, &.bx-focusable:focus {
|
||||||
|
@ -1,3 +1,12 @@
|
|||||||
|
.bx-product-details-icons {
|
||||||
|
padding: 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.bx-product-details-buttons {
|
.bx-product-details-buttons {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
|
@ -149,6 +149,10 @@ div[class^=HUDButton-module__hiddenContainer] ~ div:not([class^=HUDButton-module
|
|||||||
font-family: var(--bx-normal-font) !important;
|
font-family: var(--bx-normal-font) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bx-frosted {
|
||||||
|
backdrop-filter: blur(4px) brightness(1.5);
|
||||||
|
}
|
||||||
|
|
||||||
select[multiple], select[multiple]:focus {
|
select[multiple], select[multiple]:focus {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
border: none;
|
border: none;
|
||||||
|
@ -1054,6 +1054,33 @@ ${subsVar} = subs;
|
|||||||
str = PatcherUtils.insertAt(str, returnIndex, newCode);
|
str = PatcherUtils.insertAt(str, returnIndex, newCode);
|
||||||
return str;
|
return str;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
// 27.0.6-hotfix.1, 28444.js
|
||||||
|
gameCardPassTitle(str: string) {
|
||||||
|
// Pass gameTitle info to gameCardCustomIcons()
|
||||||
|
let index = str.indexOf('=["productId","showInputBadges","ownershipBadgeType"');
|
||||||
|
index > -1 && (index = PatcherUtils.indexOf(str, ',gameTitle:', index, 500, true));
|
||||||
|
if (index < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const gameTitleVar = PatcherUtils.getVariableNameAfter(str, index);
|
||||||
|
if (!gameTitleVar) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
index = PatcherUtils.indexOf(str, 'return', index);
|
||||||
|
index = PatcherUtils.indexOf(str, 'productId:', index);
|
||||||
|
if (index < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const newCode = `gameTitle: ${gameTitleVar},`;
|
||||||
|
str = PatcherUtils.insertAt(str, index, newCode);
|
||||||
|
return str;
|
||||||
|
},
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
let PATCH_ORDERS = PatcherUtils.filterPatches([
|
let PATCH_ORDERS = PatcherUtils.filterPatches([
|
||||||
@ -1065,6 +1092,7 @@ let PATCH_ORDERS = PatcherUtils.filterPatches([
|
|||||||
|
|
||||||
'exposeReactCreateComponent',
|
'exposeReactCreateComponent',
|
||||||
'gameCardCustomIcons',
|
'gameCardCustomIcons',
|
||||||
|
// 'gameCardPassTitle',
|
||||||
|
|
||||||
'modifyPreloadedState',
|
'modifyPreloadedState',
|
||||||
|
|
||||||
@ -1185,7 +1213,7 @@ let STREAM_PAGE_PATCH_ORDERS = PatcherUtils.filterPatches([
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
let PRODUCT_DETAIL_PAGE_PATCH_ORDERS = PatcherUtils.filterPatches([
|
let PRODUCT_DETAIL_PAGE_PATCH_ORDERS = PatcherUtils.filterPatches([
|
||||||
AppInterface && 'detectProductDetailPage',
|
'detectProductDetailPage',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const ALL_PATCHES = [...PATCH_ORDERS, ...HOME_PAGE_PATCH_ORDERS, ...STREAM_PAGE_PATCH_ORDERS, ...PRODUCT_DETAIL_PAGE_PATCH_ORDERS];
|
const ALL_PATCHES = [...PATCH_ORDERS, ...HOME_PAGE_PATCH_ORDERS, ...STREAM_PAGE_PATCH_ORDERS, ...PRODUCT_DETAIL_PAGE_PATCH_ORDERS];
|
||||||
|
@ -5,5 +5,5 @@ const supportedInputIcons = $supportedInputIcons$;
|
|||||||
const { productId } = $param$;
|
const { productId } = $param$;
|
||||||
|
|
||||||
if (window.BX_EXPOSED.localCoOpManager.isSupported(productId)) {
|
if (window.BX_EXPOSED.localCoOpManager.isSupported(productId)) {
|
||||||
supportedInputIcons.push(() => window.BX_EXPOSED.createReactLocalCoOpIcon());
|
supportedInputIcons.push(window.BX_EXPOSED.createReactLocalCoOpIcon);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import { BX_FLAGS } from "@/utils/bx-flags";
|
import { BX_FLAGS } from "@/utils/bx-flags";
|
||||||
import { BxIcon } from "@/utils/bx-icon";
|
import { BxIcon } from "@/utils/bx-icon";
|
||||||
import { AppInterface } from "@/utils/global";
|
import { AppInterface } from "@/utils/global";
|
||||||
import { ButtonStyle, CE, createButton } from "@/utils/html";
|
import { ButtonStyle, CE, createButton, createSvgIcon } from "@/utils/html";
|
||||||
|
import { LocalCoOpManager } from "@/utils/local-co-op-manager";
|
||||||
import { t } from "@/utils/translation";
|
import { t } from "@/utils/translation";
|
||||||
import { parseDetailsPath } from "@/utils/utils";
|
import { parseDetailsPath } from "@/utils/utils";
|
||||||
|
|
||||||
@ -28,12 +29,23 @@ export class ProductDetailsPage {
|
|||||||
private static injectTimeoutId: number | null = null;
|
private static injectTimeoutId: number | null = null;
|
||||||
|
|
||||||
static injectButtons() {
|
static injectButtons() {
|
||||||
if (!AppInterface) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ProductDetailsPage.injectTimeoutId && clearTimeout(ProductDetailsPage.injectTimeoutId);
|
ProductDetailsPage.injectTimeoutId && clearTimeout(ProductDetailsPage.injectTimeoutId);
|
||||||
ProductDetailsPage.injectTimeoutId = window.setTimeout(() => {
|
ProductDetailsPage.injectTimeoutId = window.setTimeout(() => {
|
||||||
|
// Inputs
|
||||||
|
const $inputsContainer = document.querySelector<HTMLElement>('div[class*="Header-module__gamePassAndInputsContainer"]');
|
||||||
|
if ($inputsContainer && !$inputsContainer.dataset.bxInjected) {
|
||||||
|
$inputsContainer.dataset.bxInjected = 'true';
|
||||||
|
|
||||||
|
const { productId } = parseDetailsPath(window.location.pathname);
|
||||||
|
if (LocalCoOpManager.getInstance().isSupported(productId || '')) {
|
||||||
|
$inputsContainer.insertAdjacentElement('afterend', CE('div', {
|
||||||
|
class: 'bx-product-details-icons bx-frosted',
|
||||||
|
}, createSvgIcon(BxIcon.LOCAL_CO_OP), t('local-co-op')));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inject buttons for Android app
|
||||||
|
if (AppInterface) {
|
||||||
// Find action buttons container
|
// Find action buttons container
|
||||||
const $container = document.querySelector('div[class*=ActionButtons-module__container]');
|
const $container = document.querySelector('div[class*=ActionButtons-module__container]');
|
||||||
if ($container && $container.parentElement) {
|
if ($container && $container.parentElement) {
|
||||||
@ -44,6 +56,7 @@ export class ProductDetailsPage {
|
|||||||
ProductDetailsPage.$btnWallpaper,
|
ProductDetailsPage.$btnWallpaper,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import iconDisplay from "@assets/svg/display.svg" with { type: "text" };
|
|||||||
import iconEye from "@assets/svg/eye.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 iconEyeSlash from "@assets/svg/eye-slash.svg" with { type: "text" };
|
||||||
import iconHome from "@assets/svg/home.svg" with { type: "text" };
|
import iconHome from "@assets/svg/home.svg" with { type: "text" };
|
||||||
|
import iconLocalCoOp from "@assets/svg/local-co-op.svg" with { type: "text" };
|
||||||
import iconNativeMkb from "@assets/svg/native-mkb.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" };
|
import iconNew from "@assets/svg/new.svg" with { type: "text" };
|
||||||
import iconPencil from "@assets/svg/pencil-simple-line.svg" with { type: "text" };
|
import iconPencil from "@assets/svg/pencil-simple-line.svg" with { type: "text" };
|
||||||
@ -52,6 +53,7 @@ export const BxIcon = {
|
|||||||
EYE: iconEye,
|
EYE: iconEye,
|
||||||
EYE_SLASH: iconEyeSlash,
|
EYE_SLASH: iconEyeSlash,
|
||||||
HOME: iconHome,
|
HOME: iconHome,
|
||||||
|
LOCAL_CO_OP: iconLocalCoOp,
|
||||||
NATIVE_MKB: iconNativeMkb,
|
NATIVE_MKB: iconNativeMkb,
|
||||||
NEW: iconNew,
|
NEW: iconNew,
|
||||||
MANAGE: iconPencil,
|
MANAGE: iconPencil,
|
||||||
|
@ -123,7 +123,7 @@ export function productTitleToSlug(title: string): string {
|
|||||||
export function parseDetailsPath(path: string) {
|
export function parseDetailsPath(path: string) {
|
||||||
const matches = /\/games\/(?<titleSlug>[^\/]+)\/(?<productId>\w+)/.exec(path);
|
const matches = /\/games\/(?<titleSlug>[^\/]+)\/(?<productId>\w+)/.exec(path);
|
||||||
if (!matches?.groups) {
|
if (!matches?.groups) {
|
||||||
return;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const titleSlug = matches.groups.titleSlug!.replaceAll('\%' + '7C', '-');
|
const titleSlug = matches.groups.titleSlug!.replaceAll('\%' + '7C', '-');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user