mirror of
https://github.com/redphx/better-xcloud.git
synced 2025-08-08 22:27:44 +02:00
EventBus (#590)
* Replace BxEvent.TITLE_INFO_READY with Event Bus * Migrate more events * Migrate stream events to event bus * Migrate preset events * Migrate more * Fix dispatching "input" event twice in Number Stepper
This commit is contained in:
27
src/index.ts
27
src/index.ts
@@ -44,6 +44,7 @@ import { StreamSettings } from "./utils/stream-settings";
|
||||
import { KeyboardShortcutHandler } from "./modules/mkb/keyboard-shortcut-handler";
|
||||
import { GhPagesUtils } from "./utils/gh-pages";
|
||||
import { DeviceVibrationManager } from "./modules/device-vibration-manager";
|
||||
import { EventBus } from "./utils/event-bus";
|
||||
|
||||
// Handle login page
|
||||
if (window.location.pathname.includes('/auth/msa')) {
|
||||
@@ -190,7 +191,9 @@ window.addEventListener('popstate', onHistoryChanged);
|
||||
window.history.pushState = patchHistoryMethod('pushState');
|
||||
window.history.replaceState = patchHistoryMethod('replaceState');
|
||||
|
||||
window.addEventListener(BxEvent.XCLOUD_SERVERS_UNAVAILABLE, e => {
|
||||
EventBus.Script.on('xcloudServerUnavailable', () => {
|
||||
EventBus.Script.off('xcloudServerUnavailable', null);
|
||||
|
||||
STATES.supportedRegion = false;
|
||||
window.setTimeout(HeaderSection.watchHeader, 2000);
|
||||
|
||||
@@ -199,14 +202,14 @@ window.addEventListener(BxEvent.XCLOUD_SERVERS_UNAVAILABLE, e => {
|
||||
if ($unsupportedPage) {
|
||||
SettingsDialog.getInstance().show();
|
||||
}
|
||||
}, { once: true });
|
||||
});
|
||||
|
||||
window.addEventListener(BxEvent.XCLOUD_SERVERS_READY, e => {
|
||||
EventBus.Script.on('xcloudServerReady', () => {
|
||||
STATES.isSignedIn = true;
|
||||
window.setTimeout(HeaderSection.watchHeader, 2000);
|
||||
});
|
||||
|
||||
window.addEventListener(BxEvent.STREAM_LOADING, e => {
|
||||
EventBus.Stream.on('stateLoading', () => {
|
||||
// Get title ID for screenshot's name
|
||||
if (window.location.pathname.includes('/launch/') && STATES.currentStream.titleInfo) {
|
||||
STATES.currentStream.titleSlug = productTitleToSlug(STATES.currentStream.titleInfo.product.title);
|
||||
@@ -216,9 +219,9 @@ window.addEventListener(BxEvent.STREAM_LOADING, e => {
|
||||
});
|
||||
|
||||
// Setup loading screen
|
||||
getPref(PrefKey.LOADING_SCREEN_GAME_ART) && window.addEventListener(BxEvent.TITLE_INFO_READY, LoadingScreen.setup);
|
||||
getPref(PrefKey.LOADING_SCREEN_GAME_ART) && EventBus.Script.on('titleInfoReady', LoadingScreen.setup);
|
||||
|
||||
window.addEventListener(BxEvent.STREAM_STARTING, e => {
|
||||
EventBus.Stream.on('stateStarting', () => {
|
||||
// Hide loading screen
|
||||
LoadingScreen.hide();
|
||||
|
||||
@@ -232,7 +235,7 @@ window.addEventListener(BxEvent.STREAM_STARTING, e => {
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener(BxEvent.STREAM_PLAYING, e => {
|
||||
EventBus.Stream.on('statePlaying', payload => {
|
||||
window.BX_STREAM_SETTINGS = StreamSettings.settings;
|
||||
StreamSettings.refreshAllSettings();
|
||||
|
||||
@@ -251,7 +254,7 @@ window.addEventListener(BxEvent.STREAM_PLAYING, e => {
|
||||
KeyboardShortcutHandler.getInstance().start();
|
||||
|
||||
// Setup screenshot
|
||||
const $video = (e as any).$video as HTMLVideoElement;
|
||||
const $video = payload.$video as HTMLVideoElement;
|
||||
ScreenshotManager.getInstance().updateCanvasSize($video.videoWidth, $video.videoHeight);
|
||||
|
||||
// Setup local co-op
|
||||
@@ -262,8 +265,8 @@ window.addEventListener(BxEvent.STREAM_PLAYING, e => {
|
||||
updateVideoPlayer();
|
||||
});
|
||||
|
||||
window.addEventListener(BxEvent.STREAM_ERROR_PAGE, e => {
|
||||
BxEvent.dispatch(window, BxEvent.STREAM_STOPPED);
|
||||
EventBus.Stream.on('stateError', () => {
|
||||
EventBus.Stream.emit('stateStopped', {});
|
||||
});
|
||||
|
||||
isFullVersion() && window.addEventListener(BxEvent.XCLOUD_RENDERING_COMPONENT, e => {
|
||||
@@ -340,9 +343,9 @@ function unload() {
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener(BxEvent.STREAM_STOPPED, unload);
|
||||
EventBus.Stream.on('stateStopped', unload);
|
||||
window.addEventListener('pagehide', e => {
|
||||
BxEvent.dispatch(window, BxEvent.STREAM_STOPPED);
|
||||
EventBus.Stream.emit('stateStopped', {});
|
||||
});
|
||||
|
||||
isFullVersion() && window.addEventListener(BxEvent.CAPTURE_SCREENSHOT, e => {
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import { AppInterface, STATES } from "@utils/global";
|
||||
import { BxEvent } from "@utils/bx-event";
|
||||
import { StreamSettings } from "@/utils/stream-settings";
|
||||
import { EventBus } from "@/utils/event-bus";
|
||||
|
||||
const VIBRATION_DATA_MAP = {
|
||||
gamepadIndex: 8,
|
||||
@@ -47,9 +48,7 @@ export class DeviceVibrationManager {
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener(BxEvent.DEVICE_VIBRATION_CHANGED, e => {
|
||||
this.setupDataChannel();
|
||||
});
|
||||
EventBus.Script.on('deviceVibrationUpdated', () => this.setupDataChannel());
|
||||
}
|
||||
|
||||
private setupDataChannel() {
|
||||
|
@@ -18,6 +18,7 @@ import { MkbPopup } from "./mkb-popup";
|
||||
import type { MkbConvertedPresetData } from "@/types/presets";
|
||||
import { StreamSettings } from "@/utils/stream-settings";
|
||||
import { ShortcutAction } from "@/enums/shortcut-actions";
|
||||
import { EventBus } from "@/utils/event-bus";
|
||||
|
||||
const PointerToMouseButton = {
|
||||
1: 0,
|
||||
@@ -639,7 +640,7 @@ export class EmulatedMkbHandler extends MkbHandler {
|
||||
|
||||
static setupEvents() {
|
||||
if (isFullVersion()) {
|
||||
window.addEventListener(BxEvent.STREAM_PLAYING, () => {
|
||||
EventBus.Stream.on('statePlaying', () => {
|
||||
if (STATES.currentStream.titleInfo?.details.hasMkbSupport) {
|
||||
// Enable native MKB in Android app
|
||||
NativeMkbHandler.getInstance()?.init();
|
||||
@@ -649,7 +650,7 @@ export class EmulatedMkbHandler extends MkbHandler {
|
||||
});
|
||||
|
||||
if (EmulatedMkbHandler.isAllowed()) {
|
||||
window.addEventListener(BxEvent.MKB_UPDATED, () => {
|
||||
EventBus.Script.on('mkbSettingUpdated', () => {
|
||||
EmulatedMkbHandler.getInstance()?.refreshPresetData();
|
||||
});
|
||||
}
|
||||
|
@@ -1,12 +1,12 @@
|
||||
import { CE, createButton, ButtonStyle, type BxButtonOptions } from "@/utils/html";
|
||||
import { t } from "@/utils/translation";
|
||||
import { BxEvent } from "@/utils/bx-event";
|
||||
import { ShortcutAction } from "@/enums/shortcut-actions";
|
||||
import { SettingsDialog } from "../ui/dialog/settings-dialog";
|
||||
import type { MkbHandler } from "./base-mkb-handler";
|
||||
import { NativeMkbHandler } from "./native-mkb-handler";
|
||||
import { StreamSettings } from "@/utils/stream-settings";
|
||||
import { KeyHelper } from "./key-helper";
|
||||
import { EventBus } from "@/utils/event-bus";
|
||||
|
||||
type MkbPopupType = 'virtual' | 'native';
|
||||
|
||||
@@ -24,7 +24,7 @@ export class MkbPopup {
|
||||
constructor() {
|
||||
this.render();
|
||||
|
||||
window.addEventListener(BxEvent.KEYBOARD_SHORTCUTS_UPDATED, e => {
|
||||
EventBus.Script.on('keyboardShortcutsUpdated', () => {
|
||||
const $newButton = this.createActivateButton();
|
||||
this.$btnActivate.replaceWith($newButton);
|
||||
this.$btnActivate = $newButton;
|
||||
|
@@ -1,4 +1,3 @@
|
||||
import { BxEvent } from "@utils/bx-event"
|
||||
import { CE } from "@utils/html"
|
||||
import { t } from "@utils/translation"
|
||||
import { STATES } from "@utils/global"
|
||||
@@ -7,6 +6,7 @@ import { getPref } from "@/utils/settings-storages/global-settings-storage"
|
||||
import { StreamStatsCollector, type StreamStatGrade } from "@/utils/stream-stats-collector"
|
||||
import { BxLogger } from "@/utils/bx-logger"
|
||||
import { StreamStat } from "@/enums/pref-values"
|
||||
import { EventBus } from "@/utils/event-bus"
|
||||
|
||||
|
||||
export class StreamStats {
|
||||
@@ -230,7 +230,7 @@ export class StreamStats {
|
||||
}
|
||||
|
||||
static setupEvents() {
|
||||
window.addEventListener(BxEvent.STREAM_PLAYING, e => {
|
||||
EventBus.Stream.on('statePlaying', () => {
|
||||
const PREF_STATS_QUICK_GLANCE = getPref(PrefKey.STATS_QUICK_GLANCE_ENABLED);
|
||||
const PREF_STATS_SHOW_WHEN_PLAYING = getPref(PrefKey.STATS_SHOW_WHEN_PLAYING);
|
||||
|
||||
|
@@ -1,11 +1,11 @@
|
||||
import { STATES } from "@utils/global.ts";
|
||||
import { createSvgIcon } from "@utils/html.ts";
|
||||
import { BxIcon } from "@utils/bx-icon";
|
||||
import { BxEvent } from "@utils/bx-event.ts";
|
||||
import { t } from "@utils/translation.ts";
|
||||
import { StreamBadges } from "./stream-badges.ts";
|
||||
import { StreamStats } from "./stream-stats.ts";
|
||||
import { SettingsDialog } from "../ui/dialog/settings-dialog.ts";
|
||||
import { EventBus } from "@/utils/event-bus.ts";
|
||||
|
||||
|
||||
export class StreamUiHandler {
|
||||
@@ -243,7 +243,7 @@ export class StreamUiHandler {
|
||||
|
||||
// Error Page: .PureErrorPage.ErrorScreen
|
||||
if (className.includes('PureErrorPage')) {
|
||||
BxEvent.dispatch(window, BxEvent.STREAM_ERROR_PAGE);
|
||||
EventBus.Stream.emit('stateError', {});
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -30,6 +30,7 @@ import { SuggestionsSetting } from "./settings/suggestions";
|
||||
import { StreamSettings } from "@/utils/stream-settings";
|
||||
import { MkbExtraSettings } from "./settings/mkb-extra";
|
||||
import { BxExposed } from "@/utils/bx-exposed";
|
||||
import { EventBus } from "@/utils/event-bus";
|
||||
|
||||
|
||||
type SettingTabSectionItem = Partial<{
|
||||
@@ -434,16 +435,13 @@ export class SettingsDialog extends NavigationDialog {
|
||||
},
|
||||
onCreated: (setting: SettingTabSectionItem, $elm: HTMLElement) => {
|
||||
const $range = $elm.querySelector<HTMLInputElement>('input[type=range')!;
|
||||
window.addEventListener(BxEvent.SETTINGS_CHANGED, e => {
|
||||
const { storageKey, settingKey, settingValue } = e as any;
|
||||
if (storageKey !== StorageKey.GLOBAL || settingKey !== PrefKey.AUDIO_VOLUME) {
|
||||
return;
|
||||
}
|
||||
|
||||
$range.value = settingValue;
|
||||
BxEvent.dispatch($range, 'input', {
|
||||
ignoreOnChange: true,
|
||||
});
|
||||
EventBus.Script.on('settingChanged', payload => {
|
||||
const { storageKey, settingKey, settingValue } = payload;
|
||||
if (storageKey === StorageKey.GLOBAL && settingKey === PrefKey.AUDIO_VOLUME) {
|
||||
$range.value = settingValue;
|
||||
BxEvent.dispatch($range, 'input', { ignoreOnChange: true });
|
||||
}
|
||||
});
|
||||
},
|
||||
}],
|
||||
|
@@ -7,23 +7,6 @@ export namespace BxEvent {
|
||||
export const JUMP_BACK_IN_READY = 'bx-jump-back-in-ready';
|
||||
export const POPSTATE = 'bx-popstate';
|
||||
|
||||
export const TITLE_INFO_READY = 'bx-title-info-ready';
|
||||
|
||||
export const SETTINGS_CHANGED = 'bx-settings-changed';
|
||||
|
||||
export const STREAM_LOADING = 'bx-stream-loading';
|
||||
export const STREAM_STARTING = 'bx-stream-starting';
|
||||
export const STREAM_STARTED = 'bx-stream-started';
|
||||
export const STREAM_PLAYING = 'bx-stream-playing';
|
||||
export const STREAM_STOPPED = 'bx-stream-stopped';
|
||||
export const STREAM_ERROR_PAGE = 'bx-stream-error-page';
|
||||
|
||||
export const STREAM_WEBRTC_CONNECTED = 'bx-stream-webrtc-connected';
|
||||
export const STREAM_WEBRTC_DISCONNECTED = 'bx-stream-webrtc-disconnected';
|
||||
|
||||
export const MKB_UPDATED = 'bx-mkb-updated';
|
||||
export const KEYBOARD_SHORTCUTS_UPDATED = 'bx-keyboard-shortcuts-updated';
|
||||
|
||||
// export const STREAM_EVENT_TARGET_READY = 'bx-stream-event-target-ready';
|
||||
export const STREAM_SESSION_READY = 'bx-stream-session-ready';
|
||||
|
||||
@@ -33,11 +16,7 @@ export namespace BxEvent {
|
||||
export const REMOTE_PLAY_READY = 'bx-remote-play-ready';
|
||||
export const REMOTE_PLAY_FAILED = 'bx-remote-play-failed';
|
||||
|
||||
export const XCLOUD_SERVERS_READY = 'bx-servers-ready';
|
||||
export const XCLOUD_SERVERS_UNAVAILABLE = 'bx-servers-unavailable';
|
||||
|
||||
export const DATA_CHANNEL_CREATED = 'bx-data-channel-created';
|
||||
export const DEVICE_VIBRATION_CHANGED = 'bx-device-vibration-changed';
|
||||
|
||||
export const GAME_BAR_ACTION_ACTIVATED = 'bx-game-bar-action-activated';
|
||||
export const MICROPHONE_STATE_CHANGED = 'bx-microphone-state-changed';
|
||||
@@ -51,8 +30,6 @@ export namespace BxEvent {
|
||||
|
||||
export const NAVIGATION_FOCUS_CHANGED = 'bx-nav-focus-changed';
|
||||
|
||||
export const GH_PAGES_FORCE_NATIVE_MKB_UPDATED = 'bx-gh-pages-force-native-mkb-updated';
|
||||
|
||||
// xCloud Dialog events
|
||||
export const XCLOUD_DIALOG_SHOWN = 'bx-xcloud-dialog-shown';
|
||||
export const XCLOUD_DIALOG_DISMISSED = 'bx-xcloud-dialog-dismissed';
|
||||
@@ -86,7 +63,7 @@ export namespace BxEvent {
|
||||
target.dispatchEvent(event);
|
||||
AppInterface && AppInterface.onEvent(eventName);
|
||||
|
||||
BX_FLAGS.Debug && BxLogger.warning('BxEvent', 'dispatch', eventName, data)
|
||||
BX_FLAGS.Debug && BxLogger.warning('BxEvent', 'dispatch', eventName, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,7 +1,6 @@
|
||||
import { isFullVersion } from "@macros/build" with { type: "macro" };
|
||||
|
||||
import { ControllerShortcut } from "@/modules/controller-shortcut";
|
||||
import { BxEvent } from "@utils/bx-event";
|
||||
import { deepClone, STATES } from "@utils/global";
|
||||
import { BxLogger } from "./bx-logger";
|
||||
import { BX_FLAGS } from "./bx-flags";
|
||||
@@ -12,6 +11,7 @@ import { GamePassCloudGallery } from "@/enums/game-pass-gallery";
|
||||
import { TouchController } from "@/modules/touch-controller";
|
||||
import { NativeMkbMode, TouchControllerMode } from "@/enums/pref-values";
|
||||
import { Patcher, type PatchPage } from "@/modules/patcher/patcher";
|
||||
import { EventBus } from "./event-bus";
|
||||
|
||||
export enum SupportedInputType {
|
||||
CONTROLLER = 'Controller',
|
||||
@@ -139,7 +139,7 @@ export const BxExposed = {
|
||||
|
||||
// Save this info in STATES
|
||||
STATES.currentStream.titleInfo = titleInfo;
|
||||
BxEvent.dispatch(window, BxEvent.TITLE_INFO_READY);
|
||||
EventBus.Script.emit('titleInfoReady', {});
|
||||
|
||||
return titleInfo;
|
||||
},
|
||||
|
81
src/utils/event-bus.ts
Normal file
81
src/utils/event-bus.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
import type { PrefKey, StorageKey } from "@/enums/pref-keys";
|
||||
import { BX_FLAGS } from "./bx-flags";
|
||||
import { BxLogger } from "./bx-logger";
|
||||
|
||||
type EventCallback<T = any> = (payload: T) => void;
|
||||
|
||||
type ScriptEvents = {
|
||||
xcloudServerReady: {};
|
||||
xcloudServerUnavailable: {};
|
||||
|
||||
titleInfoReady: {};
|
||||
settingChanged: {
|
||||
storageKey: StorageKey;
|
||||
settingKey: PrefKey;
|
||||
settingValue: any;
|
||||
};
|
||||
|
||||
mkbSettingUpdated: {};
|
||||
keyboardShortcutsUpdated: {};
|
||||
deviceVibrationUpdated: {};
|
||||
|
||||
// GH pages
|
||||
listForcedNativeMkbUpdated: {};
|
||||
};
|
||||
|
||||
type StreamEvents = {
|
||||
stateLoading: {};
|
||||
stateStarting: {};
|
||||
statePlaying: { $video?: HTMLVideoElement };
|
||||
stateStopped: {};
|
||||
stateError: {};
|
||||
};
|
||||
|
||||
export class EventBus<TEvents extends Record<string, any>> {
|
||||
private listeners: Map<keyof TEvents, Set<EventCallback<any>>> = new Map();
|
||||
|
||||
static readonly Script = new EventBus<ScriptEvents>();
|
||||
static readonly Stream = new EventBus<StreamEvents>();
|
||||
|
||||
on<K extends keyof TEvents>(event: K, callback: EventCallback<TEvents[K]>): void {
|
||||
if (!this.listeners.has(event)) {
|
||||
this.listeners.set(event, new Set());
|
||||
}
|
||||
this.listeners.get(event)!.add(callback);
|
||||
|
||||
BX_FLAGS.Debug && BxLogger.warning('EventBus', 'on', event, callback);
|
||||
}
|
||||
|
||||
off<K extends keyof TEvents>(event: K, callback: EventCallback<TEvents[K]> | null): void {
|
||||
BX_FLAGS.Debug && BxLogger.warning('EventBus', 'off', event, callback);
|
||||
|
||||
if (!callback) {
|
||||
// Remove all listener callbacks
|
||||
this.listeners.delete(event);
|
||||
return;
|
||||
}
|
||||
|
||||
const callbacks = this.listeners.get(event);
|
||||
if (!callbacks) {
|
||||
return;
|
||||
}
|
||||
|
||||
callbacks.delete(callback);
|
||||
if (callbacks.size === 0) {
|
||||
this.listeners.delete(event);
|
||||
}
|
||||
}
|
||||
|
||||
offAll(): void {
|
||||
this.listeners.clear();
|
||||
}
|
||||
|
||||
emit<K extends keyof TEvents>(event: K, payload: TEvents[K]): void {
|
||||
BX_FLAGS.Debug && BxLogger.warning('EventBus', 'emit', event, payload);
|
||||
|
||||
const callbacks = this.listeners.get(event) || [];
|
||||
for (const callback of callbacks) {
|
||||
callback(payload);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,7 +1,7 @@
|
||||
import { StorageKey } from "@/enums/pref-keys";
|
||||
import { NATIVE_FETCH } from "./bx-flags";
|
||||
import { BxLogger } from "./bx-logger";
|
||||
import { BxEvent } from "./bx-event";
|
||||
import { EventBus } from "./event-bus";
|
||||
|
||||
|
||||
export type ForceNativeMkbResponse = {
|
||||
@@ -53,7 +53,7 @@ export class GhPagesUtils {
|
||||
if (json.$schemaVersion === supportedSchema) {
|
||||
// Save to storage
|
||||
window.localStorage.setItem(key, JSON.stringify(json));
|
||||
BxEvent.dispatch(window, BxEvent.GH_PAGES_FORCE_NATIVE_MKB_UPDATED);
|
||||
EventBus.Script.emit('listForcedNativeMkbUpdated', {});
|
||||
}
|
||||
});
|
||||
|
||||
|
@@ -3,14 +3,15 @@ import { LoadingScreen } from "@modules/loading-screen";
|
||||
import { RemotePlayManager } from "@/modules/remote-play-manager";
|
||||
import { HeaderSection } from "@/modules/ui/header";
|
||||
import { NavigationDialogManager } from "@/modules/ui/dialog/navigation-dialog";
|
||||
import { EventBus } from "./event-bus";
|
||||
|
||||
export function patchHistoryMethod(type: 'pushState' | 'replaceState') {
|
||||
const orig = window.history[type];
|
||||
|
||||
return function(...args: any[]) {
|
||||
BxEvent.dispatch(window, BxEvent.POPSTATE, {
|
||||
arguments: args,
|
||||
});
|
||||
arguments: args,
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
return orig.apply(this, arguments);
|
||||
@@ -38,5 +39,5 @@ export function onHistoryChanged(e: PopStateEvent) {
|
||||
LoadingScreen.reset();
|
||||
window.setTimeout(HeaderSection.watchHeader, 2000);
|
||||
|
||||
BxEvent.dispatch(window, BxEvent.STREAM_STOPPED);
|
||||
EventBus.Stream.emit('stateStopped', {});
|
||||
}
|
||||
|
@@ -7,6 +7,7 @@ import { PrefKey } from "@/enums/pref-keys";
|
||||
import { getPref, getPrefDefinition } from "./settings-storages/global-settings-storage";
|
||||
import { CodecProfile } from "@/enums/pref-values";
|
||||
import type { SettingDefinition } from "@/types/setting-definition";
|
||||
import { EventBus } from "./event-bus";
|
||||
|
||||
export function patchVideoApi() {
|
||||
const PREF_SKIP_SPLASH_VIDEO = getPref(PrefKey.UI_SKIP_SPLASH_VIDEO);
|
||||
@@ -27,9 +28,9 @@ export function patchVideoApi() {
|
||||
} satisfies StreamPlayerOptions;
|
||||
STATES.currentStream.streamPlayer = new StreamPlayer(this, getPref(PrefKey.VIDEO_PLAYER_TYPE), playerOptions);
|
||||
|
||||
BxEvent.dispatch(window, BxEvent.STREAM_PLAYING, {
|
||||
$video: this,
|
||||
});
|
||||
EventBus.Stream.emit('statePlaying', {
|
||||
$video: this,
|
||||
})
|
||||
}
|
||||
|
||||
const nativePlay = HTMLMediaElement.prototype.play;
|
||||
|
@@ -1,16 +1,16 @@
|
||||
import type { PrefKey } from "@/enums/pref-keys";
|
||||
import type { PrefKey, StorageKey } from "@/enums/pref-keys";
|
||||
import type { NumberStepperParams, SettingAction, SettingDefinitions } from "@/types/setting-definition";
|
||||
import { BxEvent } from "../bx-event";
|
||||
import { t } from "../translation";
|
||||
import { SCRIPT_VARIANT } from "../global";
|
||||
import { EventBus } from "../event-bus";
|
||||
|
||||
export class BaseSettingsStore {
|
||||
private storage: Storage;
|
||||
private storageKey: string;
|
||||
private storageKey: StorageKey;
|
||||
private _settings: object | null;
|
||||
private definitions: SettingDefinitions;
|
||||
|
||||
constructor(storageKey: string, definitions: SettingDefinitions) {
|
||||
constructor(storageKey: StorageKey, definitions: SettingDefinitions) {
|
||||
this.storage = window.localStorage;
|
||||
this.storageKey = storageKey;
|
||||
|
||||
@@ -93,7 +93,7 @@ export class BaseSettingsStore {
|
||||
this.settings[key] = this.validateValue('get', key, value);
|
||||
this.saveSettings();
|
||||
|
||||
emitEvent && BxEvent.dispatch(window, BxEvent.SETTINGS_CHANGED, {
|
||||
emitEvent && EventBus.Script.emit('settingChanged', {
|
||||
storageKey: this.storageKey,
|
||||
settingKey: key,
|
||||
settingValue: value,
|
||||
|
@@ -12,7 +12,7 @@ import { CodecProfile, StreamResolution, TouchControllerMode, TouchControllerSty
|
||||
import { MkbMappingDefaultPresetId } from "../local-db/mkb-mapping-presets-table";
|
||||
import { KeyboardShortcutDefaultId } from "../local-db/keyboard-shortcuts-table";
|
||||
import { GhPagesUtils } from "../gh-pages";
|
||||
import { BxEvent } from "../bx-event";
|
||||
import { EventBus } from "../event-bus";
|
||||
|
||||
|
||||
function getSupportedCodecProfiles() {
|
||||
@@ -432,7 +432,7 @@ export class GlobalSettingsStorage extends BaseSettingsStorage {
|
||||
if (!setting.unsupported) {
|
||||
(setting as any).multipleOptions = GhPagesUtils.getNativeMkbCustomList(true);
|
||||
|
||||
window.addEventListener(BxEvent.GH_PAGES_FORCE_NATIVE_MKB_UPDATED, e => {
|
||||
EventBus.Script.on('listForcedNativeMkbUpdated', () => {
|
||||
(setting as any).multipleOptions = GhPagesUtils.getNativeMkbCustomList();
|
||||
});
|
||||
}
|
||||
|
@@ -10,10 +10,10 @@ import { hasGamepad } from "./gamepad";
|
||||
import { MkbMappingPresetsTable } from "./local-db/mkb-mapping-presets-table";
|
||||
import type { GamepadKey } from "@/enums/gamepad";
|
||||
import { MkbPresetKey, MouseConstant } from "@/enums/mkb";
|
||||
import { BxEvent } from "./bx-event";
|
||||
import { KeyboardShortcutDefaultId, KeyboardShortcutsTable } from "./local-db/keyboard-shortcuts-table";
|
||||
import { ShortcutAction } from "@/enums/shortcut-actions";
|
||||
import { KeyHelper } from "@/modules/mkb/key-helper";
|
||||
import { EventBus } from "./event-bus";
|
||||
|
||||
|
||||
export type StreamSettingsData = {
|
||||
@@ -110,7 +110,7 @@ export class StreamSettings {
|
||||
}
|
||||
|
||||
StreamSettings.settings.deviceVibrationIntensity = intensity;
|
||||
BxEvent.dispatch(window, BxEvent.DEVICE_VIBRATION_CHANGED);
|
||||
EventBus.Script.emit('deviceVibrationUpdated', {});
|
||||
}
|
||||
|
||||
static async refreshMkbSettings() {
|
||||
@@ -148,7 +148,7 @@ export class StreamSettings {
|
||||
settings.mkbPreset = converted;
|
||||
|
||||
setPref(PrefKey.MKB_P1_MAPPING_PRESET_ID, orgPreset.id);
|
||||
BxEvent.dispatch(window, BxEvent.MKB_UPDATED);
|
||||
EventBus.Script.emit('mkbSettingUpdated', {});
|
||||
}
|
||||
|
||||
static async refreshKeyboardShortcuts() {
|
||||
@@ -159,7 +159,7 @@ export class StreamSettings {
|
||||
settings.keyboardShortcuts = null;
|
||||
|
||||
setPref(PrefKey.KEYBOARD_SHORTCUTS_IN_GAME_PRESET_ID, presetId);
|
||||
BxEvent.dispatch(window, BxEvent.KEYBOARD_SHORTCUTS_UPDATED);
|
||||
EventBus.Script.emit('keyboardShortcutsUpdated', {});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ export class StreamSettings {
|
||||
settings.keyboardShortcuts = converted;
|
||||
|
||||
setPref(PrefKey.KEYBOARD_SHORTCUTS_IN_GAME_PRESET_ID, orgPreset.id);
|
||||
BxEvent.dispatch(window, BxEvent.KEYBOARD_SHORTCUTS_UPDATED);
|
||||
EventBus.Script.emit('keyboardShortcutsUpdated', {});
|
||||
}
|
||||
|
||||
static async refreshAllSettings() {
|
||||
|
@@ -1,10 +1,10 @@
|
||||
import { PrefKey } from "@/enums/pref-keys";
|
||||
import { BxEvent } from "./bx-event";
|
||||
import { STATES } from "./global";
|
||||
import { humanFileSize, secondsToHm } from "./html";
|
||||
import { getPref } from "./settings-storages/global-settings-storage";
|
||||
import { BxLogger } from "./bx-logger";
|
||||
import { StreamStat } from "@/enums/pref-values";
|
||||
import { EventBus } from "./event-bus";
|
||||
|
||||
export type StreamStatGrade = '' | 'bad' | 'ok' | 'good';
|
||||
|
||||
@@ -310,9 +310,8 @@ export class StreamStatsCollector {
|
||||
}
|
||||
|
||||
static setupEvents() {
|
||||
window.addEventListener(BxEvent.STREAM_PLAYING, e => {
|
||||
const statsCollector = StreamStatsCollector.getInstance();
|
||||
statsCollector.reset();
|
||||
EventBus.Stream.on('statePlaying', () => {
|
||||
StreamStatsCollector.getInstance().reset();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@@ -4,7 +4,6 @@ import { LoadingScreen } from "@modules/loading-screen";
|
||||
import { RemotePlayManager } from "@/modules/remote-play-manager";
|
||||
import { StreamBadges } from "@modules/stream/stream-badges";
|
||||
import { TouchController } from "@modules/touch-controller";
|
||||
import { BxEvent } from "./bx-event";
|
||||
import { NATIVE_FETCH, BX_FLAGS } from "./bx-flags";
|
||||
import { STATES } from "./global";
|
||||
import { generateMsDeviceInfo, getOsNameFromResolution, patchIceCandidates } from "./network";
|
||||
@@ -13,6 +12,7 @@ import { BypassServerIps } from "@/enums/bypass-servers";
|
||||
import { PrefKey } from "@/enums/pref-keys";
|
||||
import { getPref } from "./settings-storages/global-settings-storage";
|
||||
import { NativeMkbMode, StreamResolution, TouchControllerMode } from "@/enums/pref-values";
|
||||
import { EventBus } from "./event-bus";
|
||||
|
||||
export class XcloudInterceptor {
|
||||
private static readonly SERVER_EXTRA_INFO: Record<string, [string, ServerContinent]> = {
|
||||
@@ -52,7 +52,7 @@ export class XcloudInterceptor {
|
||||
const response = await NATIVE_FETCH(request, init);
|
||||
if (response.status !== 200) {
|
||||
// Unsupported region
|
||||
BxEvent.dispatch(window, BxEvent.XCLOUD_SERVERS_UNAVAILABLE);
|
||||
EventBus.Script.emit('xcloudServerUnavailable', {});
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ export class XcloudInterceptor {
|
||||
STATES.serverRegions[region.name] = Object.assign({}, region);
|
||||
}
|
||||
|
||||
BxEvent.dispatch(window, BxEvent.XCLOUD_SERVERS_READY);
|
||||
EventBus.Script.emit('xcloudServerReady', {});
|
||||
|
||||
const preferredRegion = getPreferredServerRegion();
|
||||
if (preferredRegion && preferredRegion in STATES.serverRegions) {
|
||||
@@ -107,7 +107,7 @@ export class XcloudInterceptor {
|
||||
}
|
||||
|
||||
private static async handlePlay(request: RequestInfo | URL, init?: RequestInit) {
|
||||
BxEvent.dispatch(window, BxEvent.STREAM_LOADING);
|
||||
EventBus.Stream.emit('stateLoading', {});
|
||||
|
||||
const PREF_STREAM_TARGET_RESOLUTION = getPref<StreamResolution>(PrefKey.STREAM_RESOLUTION);
|
||||
const PREF_STREAM_PREFERRED_LOCALE = getPref<StreamPreferredLocale>(PrefKey.STREAM_PREFERRED_LOCALE);
|
||||
@@ -189,7 +189,7 @@ export class XcloudInterceptor {
|
||||
return response;
|
||||
}
|
||||
|
||||
BxEvent.dispatch(window, BxEvent.STREAM_STARTING);
|
||||
EventBus.Stream.emit('stateStarting', {});
|
||||
|
||||
const obj = JSON.parse(text);
|
||||
let overrides = JSON.parse(obj.clientStreamingConfigOverrides || '{}') || {};
|
||||
|
@@ -9,6 +9,7 @@ import { getPref } from "./settings-storages/global-settings-storage";
|
||||
import type { RemotePlayConsoleAddresses } from "@/types/network";
|
||||
import { RemotePlayManager } from "@/modules/remote-play-manager";
|
||||
import { StreamResolution, TouchControllerMode } from "@/enums/pref-values";
|
||||
import { EventBus } from "./event-bus";
|
||||
|
||||
export class XhomeInterceptor {
|
||||
private static consoleAddrs: RemotePlayConsoleAddresses = {};
|
||||
@@ -35,7 +36,7 @@ export class XhomeInterceptor {
|
||||
}
|
||||
|
||||
private static async handleConfiguration(request: Request | URL) {
|
||||
BxEvent.dispatch(window, BxEvent.STREAM_STARTING);
|
||||
EventBus.Stream.emit('stateStarting', {});
|
||||
|
||||
const response = await NATIVE_FETCH(request);
|
||||
const obj = await response.clone().json();
|
||||
@@ -124,7 +125,7 @@ export class XhomeInterceptor {
|
||||
}
|
||||
|
||||
private static async handlePlay(request: RequestInfo | URL) {
|
||||
BxEvent.dispatch(window, BxEvent.STREAM_LOADING);
|
||||
EventBus.Stream.emit('stateLoading', {});
|
||||
|
||||
const clone = (request as Request).clone();
|
||||
const body = await clone.json();
|
||||
|
@@ -1,5 +1,4 @@
|
||||
import type { NumberStepperParams } from "@/types/setting-definition";
|
||||
import { BxEvent } from "@/utils/bx-event";
|
||||
import { CE, escapeCssSelector } from "@/utils/html";
|
||||
import { setNearby } from "@/utils/navigation-utils";
|
||||
import type { BxHtmlSettingElement } from "@/utils/setting-element";
|
||||
@@ -26,7 +25,6 @@ export class BxNumberStepper extends HTMLInputElement implements BxHtmlSettingEl
|
||||
private $btnDec!: HTMLButtonElement;
|
||||
private $range!: HTMLInputElement | null;
|
||||
|
||||
onInput!: typeof BxNumberStepper['onInput'];
|
||||
onRangeInput!: typeof BxNumberStepper['onRangeInput'];
|
||||
onClick!: typeof BxNumberStepper['onClick'];
|
||||
onPointerUp!: typeof BxNumberStepper['onPointerUp'];
|
||||
@@ -77,7 +75,6 @@ export class BxNumberStepper extends HTMLInputElement implements BxHtmlSettingEl
|
||||
self.$btnDec = $btnDec;
|
||||
self.onChange = onChange;
|
||||
|
||||
self.onInput = BxNumberStepper.onInput.bind(self);
|
||||
self.onRangeInput = BxNumberStepper.onRangeInput.bind(self);
|
||||
self.onClick = BxNumberStepper.onClick.bind(self);
|
||||
self.onPointerUp = BxNumberStepper.onPointerUp.bind(self);
|
||||
@@ -117,8 +114,7 @@ export class BxNumberStepper extends HTMLInputElement implements BxHtmlSettingEl
|
||||
self.$range = $range;
|
||||
options.hideSlider && $range.classList.add('bx-gone');
|
||||
|
||||
$range.addEventListener('input', self.onRangeInput);
|
||||
self.addEventListener('input', self.onInput);
|
||||
self.addEventListener('input', self.onRangeInput);
|
||||
self.appendChild($range);
|
||||
|
||||
if (options.ticks || options.exactTicks) {
|
||||
@@ -183,10 +179,6 @@ export class BxNumberStepper extends HTMLInputElement implements BxHtmlSettingEl
|
||||
return value;
|
||||
}
|
||||
|
||||
private static onInput(this: BxNumberStepper, e: Event) {
|
||||
BxEvent.dispatch(this.$range, 'input');
|
||||
}
|
||||
|
||||
private static onRangeInput(this: BxNumberStepper, e: Event) {
|
||||
let value = parseInt((e.target as HTMLInputElement).value);
|
||||
if (this.options.reverse) {
|
||||
|
Reference in New Issue
Block a user