mirror of
https://github.com/redphx/better-xcloud.git
synced 2025-08-05 20:58:27 +02:00
Prepare for webOS & Tizen support
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { ControllerShortcut } from "@/modules/controller-shortcut";
|
||||
import { BxEvent } from "@utils/bx-event";
|
||||
import { STATES } from "@utils/global";
|
||||
import { deepClone, STATES } from "@utils/global";
|
||||
import { getPref, PrefKey } from "@utils/preferences";
|
||||
import { BxLogger } from "./bx-logger";
|
||||
import { BX_FLAGS } from "./bx-flags";
|
||||
@@ -19,7 +19,7 @@ export const BxExposed = {
|
||||
|
||||
modifyTitleInfo: (titleInfo: XcloudTitleInfo): XcloudTitleInfo => {
|
||||
// Clone the object since the original is read-only
|
||||
titleInfo = structuredClone(titleInfo);
|
||||
titleInfo = deepClone(titleInfo);
|
||||
|
||||
let supportedInputTypes = titleInfo.details.supportedInputTypes;
|
||||
|
||||
|
@@ -9,6 +9,8 @@ type BxFlags = Partial<{
|
||||
|
||||
ForceNativeMkbTitles: string[];
|
||||
FeatureGates: {[key: string]: boolean} | null,
|
||||
|
||||
ScriptUi: 'default' | 'tv',
|
||||
}>
|
||||
|
||||
// Setup flags
|
||||
@@ -23,6 +25,8 @@ const DEFAULT_FLAGS: BxFlags = {
|
||||
|
||||
ForceNativeMkbTitles: [],
|
||||
FeatureGates: null,
|
||||
|
||||
ScriptUi: 'default',
|
||||
}
|
||||
|
||||
export const BX_FLAGS: BxFlags = Object.assign(DEFAULT_FLAGS, window.BX_FLAGS || {});
|
||||
|
@@ -140,3 +140,16 @@ body::-webkit-scrollbar {
|
||||
const $style = CE('style', {}, css);
|
||||
document.documentElement.appendChild($style);
|
||||
}
|
||||
|
||||
|
||||
export function preloadFonts() {
|
||||
const $link = CE<HTMLLinkElement>('link', {
|
||||
rel: 'preload',
|
||||
href: 'https://redphx.github.io/better-xcloud/fonts/promptfont.otf',
|
||||
as: 'font',
|
||||
type: 'font/otf',
|
||||
crossorigin: '',
|
||||
});
|
||||
|
||||
document.querySelector('head')?.appendChild($link);
|
||||
}
|
||||
|
@@ -24,3 +24,15 @@ export const STATES: BxStates = {
|
||||
|
||||
pointerServerPort: 9269,
|
||||
};
|
||||
|
||||
export function deepClone(obj: any): any {
|
||||
if ('structuredClone' in window) {
|
||||
return structuredClone(obj);
|
||||
}
|
||||
|
||||
if (!obj) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
return JSON.parse(JSON.stringify(obj));
|
||||
}
|
||||
|
@@ -9,6 +9,7 @@ type BxButton = {
|
||||
title?: string;
|
||||
disabled?: boolean;
|
||||
onClick?: EventListener;
|
||||
attributes?: {[key: string]: any},
|
||||
}
|
||||
|
||||
type ButtonStyle = {[index: string]: number} & {[index: number]: string};
|
||||
@@ -94,6 +95,12 @@ export const createButton = <T=HTMLButtonElement>(options: BxButton): T => {
|
||||
options.disabled && (($btn as HTMLButtonElement).disabled = true);
|
||||
options.onClick && $btn.addEventListener('click', options.onClick);
|
||||
|
||||
for (const key in options.attributes) {
|
||||
if (!$btn.hasOwnProperty(key)) {
|
||||
$btn.setAttribute(key, options.attributes[key]);
|
||||
}
|
||||
}
|
||||
|
||||
return $btn as T;
|
||||
}
|
||||
|
||||
|
@@ -576,8 +576,10 @@ export function interceptHttpRequests() {
|
||||
const response = await NATIVE_FETCH(request, init);
|
||||
const json = await response.json();
|
||||
|
||||
for (const key in FeatureGates) {
|
||||
json.exp.treatments[key] = FeatureGates[key]
|
||||
if (json && json.exp && json.treatments) {
|
||||
for (const key in FeatureGates) {
|
||||
json.exp.treatments[key] = FeatureGates[key]
|
||||
}
|
||||
}
|
||||
|
||||
response.json = () => Promise.resolve(json);
|
||||
|
@@ -570,7 +570,7 @@ export class Preferences {
|
||||
[UserAgentProfile.SMARTTV_GENERIC]: 'Smart TV',
|
||||
[UserAgentProfile.SMARTTV_TIZEN]: 'Samsung Smart TV',
|
||||
[UserAgentProfile.VR_OCULUS]: 'Meta Quest VR',
|
||||
[UserAgentProfile.ANDROID_KIWI_V123]: 'Kiwi Browser v123',
|
||||
[UserAgentProfile.ANDROID_KIWI_V123]: 'Kiwi Browser v124 Fix',
|
||||
[UserAgentProfile.CUSTOM]: t('custom'),
|
||||
},
|
||||
},
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { STATES } from "@utils/global";
|
||||
import { deepClone, STATES } from "@utils/global";
|
||||
import { BxLogger } from "./bx-logger";
|
||||
import { TouchController } from "@modules/touch-controller";
|
||||
import { GamePassCloudGallery } from "../enums/game-pass-gallery";
|
||||
@@ -59,7 +59,7 @@ export function overridePreloadState() {
|
||||
|
||||
// @ts-ignore
|
||||
_state = state;
|
||||
STATES.appContext = structuredClone(state.appContext);
|
||||
STATES.appContext = deepClone(state.appContext);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@@ -38,7 +38,7 @@ export class SettingElement {
|
||||
}
|
||||
|
||||
$control.value = currentValue;
|
||||
onChange && $control.addEventListener('change', e => {
|
||||
onChange && $control.addEventListener('input', e => {
|
||||
const target = e.target as HTMLSelectElement;
|
||||
const value = (setting.type && setting.type === 'number') ? parseInt(target.value) : target.value;
|
||||
onChange(e, value);
|
||||
@@ -76,7 +76,7 @@ export class SettingElement {
|
||||
|
||||
const $parent = target.parentElement!;
|
||||
$parent.focus();
|
||||
$parent.dispatchEvent(new Event('change'));
|
||||
$parent.dispatchEvent(new Event('input'));
|
||||
});
|
||||
|
||||
$control.appendChild($option);
|
||||
@@ -90,7 +90,7 @@ export class SettingElement {
|
||||
|
||||
$control.addEventListener('mousemove', e => e.preventDefault());
|
||||
|
||||
onChange && $control.addEventListener('change', (e: Event) => {
|
||||
onChange && $control.addEventListener('input', (e: Event) => {
|
||||
const target = e.target as HTMLSelectElement
|
||||
const values = Array.from(target.selectedOptions).map(i => i.value);
|
||||
onChange(e, values);
|
||||
|
@@ -377,8 +377,12 @@ export class Translations {
|
||||
const resp = await NATIVE_FETCH(`https://raw.githubusercontent.com/redphx/better-xcloud/gh-pages/translations/${locale}.json`);
|
||||
const translations = await resp.json();
|
||||
|
||||
window.localStorage.setItem(Translations.#KEY_TRANSLATIONS, JSON.stringify(translations));
|
||||
Translations.#foreignTranslations = translations;
|
||||
// Prevent saving incorrect translations
|
||||
let currentLocale = localStorage.getItem(Translations.#KEY_LOCALE);
|
||||
if (currentLocale === locale) {
|
||||
window.localStorage.setItem(Translations.#KEY_TRANSLATIONS, JSON.stringify(translations));
|
||||
Translations.#foreignTranslations = translations;
|
||||
}
|
||||
return true;
|
||||
} catch (e) {
|
||||
debugger;
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import { UserAgentProfile } from "@enums/user-agent";
|
||||
import { deepClone } from "./global";
|
||||
|
||||
type UserAgentConfig = {
|
||||
profile: UserAgentProfile,
|
||||
@@ -45,7 +46,7 @@ export class UserAgent {
|
||||
}
|
||||
|
||||
static updateStorage(profile: UserAgentProfile, custom?: string) {
|
||||
const clonedConfig = structuredClone(UserAgent.#config);
|
||||
const clonedConfig = deepClone(UserAgent.#config);
|
||||
clonedConfig.profile = profile;
|
||||
|
||||
if (typeof custom !== 'undefined') {
|
||||
|
Reference in New Issue
Block a user