This commit is contained in:
redphx
2024-12-07 16:48:58 +07:00
parent 557a38214d
commit 4011eb402a
55 changed files with 181 additions and 139 deletions

View File

@@ -3,8 +3,8 @@ import { ShortcutHandler } from "@/utils/shortcut-handler";
export class ControllerShortcut {
private static buttonsCache: {[key: string]: boolean[]} = {};
private static buttonsStatus: {[key: string]: boolean[]} = {};
private static buttonsCache: { [key: string]: boolean[] } = {};
private static buttonsStatus: { [key: string]: boolean[] } = {};
static reset(index: number) {
ControllerShortcut.buttonsCache[index] = [];

View File

@@ -47,8 +47,8 @@ export class GameBar {
const position = getPref<GameBarPosition>(PrefKey.GAME_BAR_POSITION);
const $gameBar = CE('div', {id: 'bx-game-bar', class: 'bx-gone', 'data-position': position},
$container = CE('div', {class: 'bx-game-bar-container bx-offscreen'}),
const $gameBar = CE('div', { id: 'bx-game-bar', class: 'bx-gone', 'data-position': position },
$container = CE('div', { class: 'bx-game-bar-container bx-offscreen' }),
createSvgIcon(position === 'bottom-left' ? BxIcon.CARET_RIGHT : BxIcon.CARET_LEFT),
);

View File

@@ -4,7 +4,7 @@ import { t } from "@utils/translation";
import { STATES } from "@utils/global";
import { PrefKey } from "@/enums/pref-keys";
import { getPref } from "@/utils/settings-storages/global-settings-storage";
import { compressCss } from "@macros/build" with {type: "macro"};
import { compressCss } from "@macros/build" with { type: "macro" };
import { LoadingScreenRocket } from "@/enums/pref-values";
export class LoadingScreen {

View File

@@ -95,7 +95,7 @@ export class KeyHelper {
const tmp = str.split(':');
const code = tmp[0] as KeyEventInfo['code'];
const modifiers = parseInt(tmp[1]);
const modifiers = parseInt(tmp[1] as string);
return {
code,

View File

@@ -1,4 +1,4 @@
import { isFullVersion } from "@macros/build" with {type: "macro"};
import { isFullVersion } from "@macros/build" with { type: "macro" };
import { MkbPresetKey, MouseConstant, MouseMapTo, WheelCode } from "@/enums/mkb";
import { BxEvent } from "@utils/bx-event";
@@ -16,6 +16,8 @@ import { getPref } from "@/utils/settings-storages/global-settings-storage";
import { GamepadKey, GamepadStick } from "@/enums/gamepad";
import { MkbPopup } from "./mkb-popup";
import type { MkbConvertedPresetData } from "@/types/presets";
import { StreamSettings } from "@/utils/stream-settings";
import { ShortcutAction } from "@/enums/shortcut-actions";
const PointerToMouseButton = {
1: 0,
@@ -168,7 +170,7 @@ export class EmulatedMkbHandler extends MkbHandler {
private popup: MkbPopup;
private STICK_MAP: {[key in GamepadKey]?: [GamepadKey[], number, number]} = {
private STICK_MAP: { [key in GamepadKey]?: [GamepadKey[], number, number] } = {
[GamepadKey.LS_LEFT]: [this.LEFT_STICK_X, 0, -1],
[GamepadKey.LS_RIGHT]: [this.LEFT_STICK_X, 0, 1],
[GamepadKey.LS_UP]: [this.LEFT_STICK_Y, 1, -1],
@@ -529,7 +531,12 @@ export class EmulatedMkbHandler extends MkbHandler {
MkbPopup.getInstance().reset();
if (AppInterface) {
Toast.show(t('press-key-to-toggle-mkb', {key: `<b>F8</b>`}), t('virtual-controller'), {html: true});
const shortcutKey = StreamSettings.findKeyboardShortcut(ShortcutAction.MKB_TOGGLE);
if (shortcutKey) {
const msg = t('press-key-to-toggle-mkb', { key: `<b>${KeyHelper.codeToKeyName(shortcutKey)}</b>` });
Toast.show(msg, t('native-mkb'), { html: true });
}
this.waitForMouseData(false);
} else {
this.waitForMouseData(true);
@@ -627,7 +634,7 @@ export class EmulatedMkbHandler extends MkbHandler {
this.waitForMouseData(true);
this.mouseDataProvider?.stop();
// Toast.show(t('virtual-controller'), t('disabled'), {instant: true});
// Toast.show(t('virtual-controller'), t('disabled'), { instant: true });
}
static setupEvents() {

View File

@@ -182,7 +182,7 @@ export class NativeMkbHandler extends MkbHandler {
window.BX_EXPOSED.stopTakRendering = true;
this.waitForMouseData(false);
Toast.show(t('native-mkb'), t('enabled'), {instant: true});
Toast.show(t('native-mkb'), t('enabled'), { instant: true });
}
stop() {

View File

@@ -480,6 +480,10 @@ BxEvent.dispatch(window, BxEvent.XCLOUD_POLLING_MODE_CHANGED);
// Get param name
const params = str.substring(index, backetIndex).match(/\(([^)]+)\)/)![1];
if (!params) {
return false;
}
const titleInfoVar = params.split(',')[0];
const newCode = `
@@ -502,6 +506,10 @@ BxLogger.info('patchXcloudTitleInfo', ${titleInfoVar});
// Get param name
const params = str.substring(index, backetIndex).match(/\(([^)]+)\)/)![1];
if (!params) {
return false;
}
const configsVar = params.split(',')[1];
const newCode = `

View File

@@ -1 +1 @@
e && BxEvent.dispatch(window, BxEvent.NAVIGATION_FOCUS_CHANGED, {element: e});
e && BxEvent.dispatch(window, BxEvent.NAVIGATION_FOCUS_CHANGED, { element: e });

View File

@@ -204,7 +204,7 @@ export class RemotePlayManager {
}
if (this.consoles.length === 0) {
Toast.show(t('no-consoles-found'), '', {instant: true});
Toast.show(t('no-consoles-found'), '', { instant: true });
return;
}

View File

@@ -21,7 +21,7 @@ export class MicrophoneShortcut {
try {
window.BX_EXPOSED.streamSession.tryEnableChatAsync(enableMic);
showToast && Toast.show(t('microphone'), t(enableMic ? 'unmuted': 'muted'), {instant: true});
showToast && Toast.show(t('microphone'), t(enableMic ? 'unmuted': 'muted'), { instant: true });
return enableMic;
} catch (e) {

View File

@@ -37,7 +37,7 @@ export class SoundShortcut {
SoundShortcut.setGainNodeVolume(newValue);
// Show toast
Toast.show(`${t('stream')} ${t('volume')}`, newValue + '%', {instant: true});
Toast.show(`${t('stream')} ${t('volume')}`, newValue + '%', { instant: true });
return newValue;
}
@@ -69,7 +69,7 @@ export class SoundShortcut {
}
SoundShortcut.setGainNodeVolume(targetValue);
Toast.show(`${t('stream')} ${t('volume')}`, status, {instant: true});
Toast.show(`${t('stream')} ${t('volume')}`, status, { instant: true });
BxEvent.dispatch(window, BxEvent.SPEAKER_STATE_CHANGED, {
speakerState: targetValue === 0 ? SpeakerState.MUTED : SpeakerState.ENABLED,
@@ -82,7 +82,7 @@ export class SoundShortcut {
$media.muted = !$media.muted;
const status = $media.muted ? t('muted') : t('unmuted');
Toast.show(`${t('stream')} ${t('volume')}`, status, {instant: true});
Toast.show(`${t('stream')} ${t('volume')}`, status, { instant: true });
BxEvent.dispatch(window, BxEvent.SPEAKER_STATE_CHANGED, {
speakerState: $media.muted ? SpeakerState.MUTED : SpeakerState.ENABLED,

View File

@@ -1,4 +1,4 @@
import { isFullVersion } from "@macros/build" with {type: "macro"};
import { isFullVersion } from "@macros/build" with { type: "macro" };
import { CE } from "@/utils/html";
import { WebGL2Player } from "./player/webgl2-player";
@@ -52,7 +52,7 @@ export class StreamPlayer {
id: 'bx-video-filters',
xmlns: 'http://www.w3.org/2000/svg',
class: 'bx-gone',
}, CE('defs', {xmlns: 'http://www.w3.org/2000/svg'},
}, CE('defs', { xmlns: 'http://www.w3.org/2000/svg' },
CE('filter', {
id: 'bx-filter-usm',
xmlns: 'http://www.w3.org/2000/svg',

View File

@@ -1,4 +1,4 @@
import { isLiteVersion } from "@macros/build" with {type: "macro"};
import { isLiteVersion } from "@macros/build" with { type: "macro" };
import { t } from "@utils/translation";
import { BxEvent } from "@utils/bx-event";
@@ -118,9 +118,9 @@ export class StreamBadges {
return $badge;
}
$badge = CE('div', {class: 'bx-badge', title: badgeInfo.name},
CE('span', {class: 'bx-badge-name'}, createSvgIcon(badgeInfo.icon)),
CE('span', {class: 'bx-badge-value', style: `background-color: ${badgeInfo.color}`}, value),
$badge = CE('div', { class: 'bx-badge', title: badgeInfo.name },
CE('span', { class: 'bx-badge-name' }, createSvgIcon(badgeInfo.icon)),
CE('span', { class: 'bx-badge-value', style: `background-color: ${badgeInfo.color}` }, value),
);
if (name === StreamBadge.BATTERY) {
@@ -219,7 +219,7 @@ export class StreamBadges {
this.serverInfo.audio ? this.badges.audio.$element : [StreamBadge.AUDIO, '?'],
];
const $container = CE('div', {class: 'bx-badges'});
const $container = CE('div', { class: 'bx-badges' });
for (const item of BADGES) {
if (!item) {

View File

@@ -209,7 +209,7 @@ export class StreamStats {
}
private async render() {
this.$container = CE('div', {class: 'bx-stats-bar bx-gone'});
this.$container = CE('div', { class: 'bx-stats-bar bx-gone' });
let statKey: keyof typeof this.stats;
for (statKey in this.stats) {

View File

@@ -267,7 +267,7 @@ export class StreamUiHandler {
};
});
observer.observe($screen, {subtree: true, childList: true});
observer.observe($screen, { subtree: true, childList: true });
StreamUiHandler.observer = observer;
}
}

View File

@@ -233,13 +233,13 @@ export class TouchController {
let html = false;
if (layout.author) {
const author = `<b>${escapeHtml(layout.author)}</b>`;
msg = t('touch-control-layout-by', {name: author});
msg = t('touch-control-layout-by', { name: author });
html = true;
} else {
msg = t('touch-control-layout');
}
layoutChanged && Toast.show(msg, layout.name, {html: html});
layoutChanged && Toast.show(msg, layout.name, { html });
window.setTimeout(() => {
// Show gyroscope control in the "More options" dialog if this layout has gyroscope

View File

@@ -154,7 +154,7 @@ export class NavigationDialogManager {
private constructor() {
BxLogger.info(this.LOG_TAG, 'constructor()');
this.$overlay = CE('div', {class: 'bx-navigation-dialog-overlay bx-gone'});
this.$overlay = CE('div', { class: 'bx-navigation-dialog-overlay bx-gone' });
this.$overlay.addEventListener('click', e => {
e.preventDefault();
e.stopPropagation();
@@ -164,7 +164,7 @@ export class NavigationDialogManager {
document.documentElement.appendChild(this.$overlay);
this.$container = CE('div', {class: 'bx-navigation-dialog bx-gone'});
this.$container = CE('div', { class: 'bx-navigation-dialog bx-gone' });
document.documentElement.appendChild(this.$container);
// Hide dialog when the Guide menu is shown
@@ -186,7 +186,7 @@ export class NavigationDialogManager {
// Find un-calculated <select> elements
this.calculateSelectBoxes($dialog);
});
observer.observe(this.$container, {childList: true});
observer.observe(this.$container, { childList: true });
}
}
@@ -260,7 +260,7 @@ export class NavigationDialogManager {
} else if (keyCode === 'Enter' || keyCode === 'NumpadEnter' || keyCode === 'Space') {
if (!($target instanceof HTMLInputElement && $target.type === 'text')) {
handled = true;
$target.dispatchEvent(new MouseEvent('click', {bubbles: true}));
$target.dispatchEvent(new MouseEvent('click', { bubbles: true }));
}
} else if (keyCode === 'Escape') {
handled = true;
@@ -393,7 +393,7 @@ export class NavigationDialogManager {
}
if (releasedButton === GamepadKey.A) {
document.activeElement && document.activeElement.dispatchEvent(new MouseEvent('click', {bubbles: true}));
document.activeElement?.dispatchEvent(new MouseEvent('click', { bubbles: true }));
return;
} else if (releasedButton === GamepadKey.B) {
this.hide();

View File

@@ -95,8 +95,8 @@ export class ControllerShortcutsManagerDialog extends BaseProfileManagerDialog<C
};
const fragment = document.createDocumentFragment();
fragment.appendChild(CE('p', {class: 'bx-shortcut-note'},
CE('span', {class: 'bx-prompt'}, PrompFont.HOME),
fragment.appendChild(CE('p', { class: 'bx-shortcut-note' },
CE('span', { class: 'bx-prompt' }, PrompFont.HOME),
': ' + t('controller-shortcuts-xbox-note'),
));
@@ -109,8 +109,8 @@ export class ControllerShortcutsManagerDialog extends BaseProfileManagerDialog<C
orientation: 'horizontal',
},
});
const $label = CE('label', {class: 'bx-prompt'}, `${PrompFont.HOME}${prompt}`);
const $div = CE('div', {class: 'bx-shortcut-actions'});
const $label = CE('label', { class: 'bx-prompt' }, `${PrompFont.HOME}${prompt}`);
const $div = CE('div', { class: 'bx-shortcut-actions' });
let $fakeSelect: HTMLSelectElement | null = null;
if (!PREF_CONTROLLER_FRIENDLY_UI) {

View File

@@ -32,7 +32,7 @@ export class RemotePlayDialog extends NavigationDialog {
}
private setupDialog() {
const $fragment = CE('div', {'class': 'bx-remote-play-container'});
const $fragment = CE('div', { class: 'bx-remote-play-container' });
const $settingNote = CE('p', {});
@@ -69,13 +69,13 @@ export class RemotePlayDialog extends NavigationDialog {
const consoles = manager.getConsoles();
for (let con of consoles) {
const $child = CE('div', {class: 'bx-remote-play-device-wrapper'},
CE('div', {class: 'bx-remote-play-device-info'},
const $child = CE('div', { class: 'bx-remote-play-device-wrapper' },
CE('div', { class: 'bx-remote-play-device-info' },
CE('div', {},
CE('span', {class: 'bx-remote-play-device-name'}, con.deviceName),
CE('span', {class: 'bx-remote-play-console-type'}, con.consoleType.replace('Xbox', ''))
CE('span', { class: 'bx-remote-play-device-name' }, con.deviceName),
CE('span', { class: 'bx-remote-play-console-type' }, con.consoleType.replace('Xbox', ''))
),
CE('div', {class: 'bx-remote-play-power-state'}, this.STATE_LABELS[con.powerState]),
CE('div', { class: 'bx-remote-play-power-state' }, this.STATE_LABELS[con.powerState]),
),
// Connect button

View File

@@ -1,4 +1,4 @@
import { isFullVersion } from "@macros/build" with {type: "macro"};
import { isFullVersion } from "@macros/build" with { type: "macro" };
import { limitVideoPlayerFps, onChangeVideoPlayerType, updateVideoPlayer } from "@/modules/stream/stream-settings-utils";
import { ButtonStyle, CE, createButton, createSettingRow, createSvgIcon, escapeCssSelector, type BxButtonOptions } from "@/utils/html";
@@ -39,7 +39,7 @@ type SettingTabSectionItem = Partial<{
note: string | (() => HTMLElement);
experimental: string;
content: HTMLElement | (() => HTMLElement);
options: {[key: string]: string};
options: { [key: string]: string };
unsupported: boolean;
unsupportedNote: string;
onChange: (e: any, value: number) => void;
@@ -112,7 +112,7 @@ export class SettingsDialog extends NavigationDialog {
if (!SCRIPT_VERSION.includes('beta') && PREF_LATEST_VERSION && PREF_LATEST_VERSION != SCRIPT_VERSION) {
// Show new version button
const opts = {
label: '🌟 ' + t('new-version-available', {version: PREF_LATEST_VERSION}),
label: '🌟 ' + t('new-version-available', { version: PREF_LATEST_VERSION }),
style: ButtonStyle.PRIMARY | ButtonStyle.FOCUSABLE | ButtonStyle.FULL_WIDTH,
} as BxButtonOptions;
@@ -549,7 +549,7 @@ export class SettingsDialog extends NavigationDialog {
// If there is no custom layouts -> show only Default option
if (!customLayouts) {
$elm.appendChild(CE('option', {value: ''}, t('default')));
$elm.appendChild(CE('option', { value: '' }, t('default')));
$elm.value = '';
$elm.dispatchEvent(new Event('input'));
return;
@@ -567,7 +567,7 @@ export class SettingsDialog extends NavigationDialog {
name = layout.name;
}
const $option = CE('option', {value: key}, name);
const $option = CE('option', { value: key }, name);
$fragment.appendChild($option);
}
@@ -859,7 +859,7 @@ export class SettingsDialog extends NavigationDialog {
setting.options[value] = label;
const $option = CE<HTMLOptionElement>('option', {value: value}, label);
const $option = CE<HTMLOptionElement>('option', { value }, label);
const continent = continents[region.contintent];
if (!continent.children) {
continent.children = [];
@@ -1002,9 +1002,9 @@ export class SettingsDialog extends NavigationDialog {
let $note;
if (unsupportedNote) {
$note = CE('div', {class: 'bx-settings-dialog-note'}, unsupportedNote);
$note = CE('div', { class: 'bx-settings-dialog-note' }, unsupportedNote);
} else if (note) {
$note = CE('div', {class: 'bx-settings-dialog-note'}, note);
$note = CE('div', { class: 'bx-settings-dialog-note' }, note);
}
const $row = createSettingRow(label, !prefDefinition?.unsupported && $control, {
@@ -1083,7 +1083,7 @@ export class SettingsDialog extends NavigationDialog {
// Add note
if (section.unsupportedNote) {
const $note = CE('b', {class: 'bx-note-unsupported'}, section.unsupportedNote);
const $note = CE('b', { class: 'bx-note-unsupported' }, section.unsupportedNote);
$tabContent.appendChild($note);
}

View File

@@ -65,7 +65,7 @@ export class ControllerExtraSettings extends HTMLElement {
CE('div', { class: 'bx-controller-extra-wrapper' },
$selectControllers,
CE('div', {class: 'bx-sub-content-box'},
CE('div', { class: 'bx-sub-content-box' },
createSettingRow(
t('controller-shortcuts-in-game'),
CE('div', {

View File

@@ -91,12 +91,12 @@ export class SuggestionsSetting {
SuggestionsSetting.generateDefaultSuggestedSettings.call(this);
// Start rendering
const $suggestedSettings = CE('div', {class: 'bx-suggest-wrapper'});
const $suggestedSettings = CE('div', { class: 'bx-suggest-wrapper' });
const $select = CE<HTMLSelectElement>('select', {},
hasRecommendedSettings && CE('option', {value: 'recommended'}, t('recommended')),
!hasRecommendedSettings && CE('option', {value: 'highest'}, t('highest-quality')),
CE('option', {value: 'default'}, t('default')),
CE('option', {value: 'lowest'}, t('lowest-quality')),
hasRecommendedSettings && CE('option', { value: 'recommended' }, t('recommended')),
!hasRecommendedSettings && CE('option', { value: 'highest' }, t('highest-quality')),
CE('option', { value: 'default' }, t('default')),
CE('option', { value: 'lowest' }, t('lowest-quality')),
);
$select.addEventListener('input', e => {
const profile = $select.value as SuggestedSettingProfile;
@@ -107,13 +107,13 @@ export class SuggestionsSetting {
let note: HTMLElement | string | undefined;
if (profile === 'recommended') {
note = t('recommended-settings-for-device', {device: recommendedDevice});
note = t('recommended-settings-for-device', { device: recommendedDevice });
} else if (profile === 'highest') {
// Add note for "Highest quality" profile
note = '⚠️ ' + t('highest-quality-note');
}
note && fragment.appendChild(CE('div', {class: 'bx-suggest-note'}, note));
note && fragment.appendChild(CE('div', { class: 'bx-suggest-note' }, note));
const settings = this.suggestedSettings[profile];
let prefKey: PrefKey;
@@ -265,7 +265,7 @@ export class SuggestionsSetting {
// Get recommended settings from GitHub
try {
let {brand, board, model} = androidInfo!;
let { brand, board, model } = androidInfo!;
brand = normalize(brand);
board = normalize(board);
model = normalize(model);

View File

@@ -28,7 +28,7 @@ export class GameTile {
}
if (typeof totalWaitTime === 'number' && isElementVisible($elm)) {
const $div = CE('div', {'class': 'bx-game-tile-wait-time'},
const $div = CE('div', { class: 'bx-game-tile-wait-time' },
createSvgIcon(BxIcon.PLAYTIME),
CE('span', {}, secondsToHms(totalWaitTime)),
);

View File

@@ -1,4 +1,4 @@
import { isFullVersion } from "@macros/build" with {type: "macro"};
import { isFullVersion } from "@macros/build" with { type: "macro" };
import { BxEvent } from "@/utils/bx-event";
import { AppInterface, STATES } from "@/utils/global";
@@ -42,7 +42,7 @@ export class GuideMenu {
// Wait until the Guide dialog is closed
window.addEventListener(BxEvent.XCLOUD_DIALOG_DISMISSED, e => {
setTimeout(() => SettingsDialog.getInstance().show(), 50);
}, {once: true});
}, { once: true });
// Close all xCloud's dialogs
this.closeGuideMenu();
@@ -218,7 +218,7 @@ export class GuideMenu {
for (index = 0; ($elm = $elm?.previousElementSibling); index++);
if (index === 0) {
BxEvent.dispatch(window, BxEvent.XCLOUD_GUIDE_MENU_SHOWN, {where: GuideMenuTab.HOME});
BxEvent.dispatch(window, BxEvent.XCLOUD_GUIDE_MENU_SHOWN, { where: GuideMenuTab.HOME });
}
}
}

View File

@@ -92,7 +92,7 @@ export class HeaderSection {
this.timeoutId && clearTimeout(this.timeoutId);
this.timeoutId = window.setTimeout(this.checkHeader, 2000);
});
this.observer.observe($root, {subtree: true, childList: true});
this.observer.observe($root, { subtree: true, childList: true });
this.checkHeader();
}