Compare commits

...

13 Commits

2 changed files with 248 additions and 80 deletions

View File

@ -1,5 +1,5 @@
// ==UserScript== // ==UserScript==
// @name Better xCloud // @name Better xCloud
// @namespace https://github.com/redphx // @namespace https://github.com/redphx
// @version 3.3.0 // @version 3.4.0
// ==/UserScript== // ==/UserScript==

View File

@ -1,7 +1,7 @@
// ==UserScript== // ==UserScript==
// @name Better xCloud // @name Better xCloud
// @namespace https://github.com/redphx // @namespace https://github.com/redphx
// @version 3.3.0 // @version 3.4.0
// @description Improve Xbox Cloud Gaming (xCloud) experience // @description Improve Xbox Cloud Gaming (xCloud) experience
// @author redphx // @author redphx
// @license MIT // @license MIT
@ -16,11 +16,12 @@
/* ADDITIONAL CODE */ /* ADDITIONAL CODE */
const SCRIPT_VERSION = '3.3.0'; const SCRIPT_VERSION = '3.4.0';
const SCRIPT_HOME = 'https://github.com/redphx/better-xcloud'; const SCRIPT_HOME = 'https://github.com/redphx/better-xcloud';
// Setup flags // Setup flags
const DEFAULT_FLAGS = { const DEFAULT_FLAGS = {
PreloadRemotePlay: true,
PreloadUi: false, PreloadUi: false,
EnableXcloudLogging: false, EnableXcloudLogging: false,
@ -188,6 +189,7 @@ const createButton = options => {
options.icon && $btn.appendChild(createSvgIcon(options.icon, 4)); options.icon && $btn.appendChild(createSvgIcon(options.icon, 4));
options.label && $btn.appendChild(CE('span', {}, options.label)); options.label && $btn.appendChild(CE('span', {}, options.label));
options.title && $btn.setAttribute('title', options.title); options.title && $btn.setAttribute('title', options.title);
options.disabled && ($btn.disabled = true);
options.onClick && $btn.addEventListener('click', options.onClick); options.onClick && $btn.addEventListener('click', options.onClick);
if (options.url) { if (options.url) {
@ -607,7 +609,7 @@ const Translations = {
"明瞭度(クラリティ)", "明瞭度(クラリティ)",
"선명도", "선명도",
"Ostrość", "Ostrość",
"Clareza", "Nitidez",
"Чёткость", "Чёткость",
"Netlik", "Netlik",
"Чіткість", "Чіткість",
@ -687,7 +689,7 @@ const Translations = {
"Apakah anda yakin ingin menghapus preset ini?", "Apakah anda yakin ingin menghapus preset ini?",
"Do you want to delete this preset?", "Do you want to delete this preset?",
"¿Desea eliminar este preajuste?", "¿Desea eliminar este preajuste?",
, "Voulez-vous supprimer ce préréglage?",
, ,
"このプリセットを削除しますか?", "このプリセットを削除しますか?",
"이 프리셋을 삭제하시겠습니까?", "이 프리셋을 삭제하시겠습니까?",
@ -772,7 +774,7 @@ const Translations = {
"Kontroler", "Kontroler",
"Controller", "Controller",
"Joystick", "Joystick",
, "Contrôle",
"Controller", "Controller",
"コントローラー", "コントローラー",
"컨트롤러", "컨트롤러",
@ -1078,7 +1080,7 @@ const Translations = {
"Nyalakan pintas kontroler", "Nyalakan pintas kontroler",
"Enable controller shortcuts", "Enable controller shortcuts",
"Habilitar accesos directos del Joystick", "Habilitar accesos directos del Joystick",
, "Activer les raccourcis du contrôle",
"Consenti scorciatoie da controller", "Consenti scorciatoie da controller",
"コントローラーショートカットを有効化", "コントローラーショートカットを有効化",
"컨트롤러 숏컷 활성화", "컨트롤러 숏컷 활성화",
@ -1345,6 +1347,23 @@ const Translations = {
"Ẩn con trỏ chuột khi không di chuyển", "Ẩn con trỏ chuột khi không di chuyển",
"空闲时隐藏鼠标", "空闲时隐藏鼠标",
], ],
"hide-scrollbar": [
,
,
"Hide web page's scrollbar",
,
,
,
,
,
,
,
,
,
,
"Ẩn thanh cuộn của trang web",
,
],
"hide-system-menu-icon": [ "hide-system-menu-icon": [
"Symbol des System-Menüs ausblenden", "Symbol des System-Menüs ausblenden",
"Sembunyikan ikon menu sistem", "Sembunyikan ikon menu sistem",
@ -1398,7 +1417,7 @@ const Translations = {
], ],
"install-android": [ "install-android": [
"\"Better xCloud\" App für Android installieren", "\"Better xCloud\" App für Android installieren",
, "Pasang aplikasi Better xCloud untuk Android",
"Install Better xCloud app for Android", "Install Better xCloud app for Android",
, ,
, ,
@ -1440,7 +1459,7 @@ const Translations = {
"言語", "言語",
"언어", "언어",
"Język", "Język",
"Linguagem", "Idioma",
"Язык", "Язык",
"Dil", "Dil",
"Мова", "Мова",
@ -1457,7 +1476,7 @@ const Translations = {
"大", "大",
"크게", "크게",
"Duży", "Duży",
"Largo", "Grande",
"Большой", "Большой",
"Büyük", "Büyük",
"Великий", "Великий",
@ -1605,7 +1624,7 @@ const Translations = {
"Mikrofon", "Mikrofon",
"Microphone", "Microphone",
"Micrófono", "Micrófono",
, "Microphone",
"Microfono", "Microfono",
"マイク", "マイク",
"마이크", "마이크",
@ -2281,8 +2300,8 @@ const Translations = {
"保存", "保存",
], ],
"screenshot-apply-filters": [ "screenshot-apply-filters": [
, "Videofilter auf Screenshots anwenden",
, "Terapkan filter video pada screenshot",
"Applies video filters to screenshots", "Applies video filters to screenshots",
, ,
, ,
@ -2290,9 +2309,9 @@ const Translations = {
"スクリーンショットにビデオフィルターを適用", "スクリーンショットにビデオフィルターを適用",
, ,
, ,
, "Aplicar filtros às capturas de tela",
"Применяет фильтры видео к скриншотам", "Применяет фильтры видео к скриншотам",
, "Görsel filtreleri ekran görüntülerine de uygular",
"Застосовує відеофільтри до знімків екрана", "Застосовує відеофільтри до знімків екрана",
"Áp dụng hiệu ứng video vào ảnh chụp màn hình", "Áp dụng hiệu ứng video vào ảnh chụp màn hình",
, ,
@ -2375,7 +2394,7 @@ const Translations = {
"ページを更新をして設定変更を適用", "ページを更新をして設定変更を適用",
"적용 및 페이지 새로고침", "적용 및 페이지 새로고침",
"Odśwież stronę, aby zastosować zmiany", "Odśwież stronę, aby zastosować zmiany",
"Recarregue a página para refletir as alterações", "Recarregue a página para aplicar as alterações",
"Перезагрузить страницу, чтобы применить изменения", "Перезагрузить страницу, чтобы применить изменения",
"Kaydetmek için sayfayı yenile", "Kaydetmek için sayfayı yenile",
"Перезавантажте сторінку, щоб застосувати зміни", "Перезавантажте сторінку, щоб застосувати зміни",
@ -2460,7 +2479,7 @@ const Translations = {
"推定待機時間を表示", "推定待機時間を表示",
"예상 대기 시간 표시", "예상 대기 시간 표시",
"Pokaż szacowany czas oczekiwania", "Pokaż szacowany czas oczekiwania",
"Mostrar o tempo estimado de espera", "Mostrar o tempo de espera estimado",
"Показать предполагаемое время до запуска", "Показать предполагаемое время до запуска",
"Tahminî bekleme süresini göster", "Tahminî bekleme süresini göster",
"Показувати орієнтовний час очікування", "Показувати орієнтовний час очікування",
@ -2783,7 +2802,7 @@ const Translations = {
"Better xCloudをサポート", "Better xCloudをサポート",
, ,
"Wesprzyj Better xCloud", "Wesprzyj Better xCloud",
"Suporte ao Melhor xCloud", "Suporte ao Better xCloud",
"Поддержать Better xCloud", "Поддержать Better xCloud",
"Better xCloud'a destek ver", "Better xCloud'a destek ver",
"Підтримати Better xCloud", "Підтримати Better xCloud",
@ -2817,7 +2836,7 @@ const Translations = {
"ターゲット解像度", "ターゲット解像度",
"목표 해상도", "목표 해상도",
"Rozdzielczość docelowa", "Rozdzielczość docelowa",
"Resolução alvo", "Resolução padrão",
"Целевое разрешение", "Целевое разрешение",
"Tercih edilen çözünürlük", "Tercih edilen çözünürlük",
"Цільова роздільна здатність", "Цільова роздільна здатність",
@ -3198,6 +3217,23 @@ const Translations = {
"Cường độ rung", "Cường độ rung",
"振动强度", "振动强度",
], ],
"vibration-status": [
"Vibration",
,
"Vibration",
,
,
,
"振動",
,
,
,
"Вибрация",
"Titreşim",
"Вібрація",
"Rung",
"手柄震动",
],
"video": [ "video": [
"Video", "Video",
"Video", "Video",
@ -3327,7 +3363,7 @@ const Translations = {
"推定完了時間", "推定完了時間",
"예상 완료 시간", "예상 완료 시간",
"Szacowany czas zakończenia", "Szacowany czas zakończenia",
"Tempo estimado de conclusão", "Tempo estimado para a conclusão",
"Примерное время запуска", "Примерное время запуска",
"Tahminî bitiş süresi", "Tahminî bitiş süresi",
"Орієнтовний час завершення", "Орієнтовний час завершення",
@ -3562,7 +3598,6 @@ class RemotePlay {
}; };
} }
static #dialog;
static #$content; static #$content;
static #$consoles; static #$consoles;
@ -3572,22 +3607,19 @@ class RemotePlay {
} }
RemotePlay.#$content = CE('div', {}, t('getting-consoles-list')); RemotePlay.#$content = CE('div', {}, t('getting-consoles-list'));
RemotePlay.#dialog = new Dialog({
title: t('remote-play'),
content: RemotePlay.#$content,
helpUrl: 'https://better-xcloud.github.io/remote-play/',
});
RemotePlay.#getXhomeToken(() => { RemotePlay.#getXhomeToken(() => {
RemotePlay.#getConsolesList(() => { RemotePlay.#getConsolesList(() => {
console.log(RemotePlay.#CONSOLES); console.log(RemotePlay.#CONSOLES);
RemotePlay.#renderConsoles(); RemotePlay.#renderConsoles();
const $btn = document.querySelector('.bx-remote-play-button');
$btn && ($btn.disabled = false);
}); });
}); });
} }
static #renderConsoles() { static #renderConsoles() {
const $fragment = document.createDocumentFragment(); const $fragment = CE('div', {'class': 'bx-remote-play-container'});
if (!RemotePlay.#CONSOLES || RemotePlay.#CONSOLES.length === 0) { if (!RemotePlay.#CONSOLES || RemotePlay.#CONSOLES.length === 0) {
$fragment.appendChild(CE('span', {}, t('no-consoles-found'))); $fragment.appendChild(CE('span', {}, t('no-consoles-found')));
@ -3640,27 +3672,9 @@ class RemotePlay {
createButton({ createButton({
classes: ['bx-remote-play-connect-button'], classes: ['bx-remote-play-connect-button'],
label: t('console-connect'), label: t('console-connect'),
style: ButtonStyle.PRIMARY, style: ButtonStyle.PRIMARY | ButtonStyle.FOCUSABLE,
onClick: e => { onClick: e => {
REMOTE_PLAY_CONFIG = { RemotePlay.play(con.serverId);
serverId: con.serverId,
};
window.BX_REMOTE_PLAY_CONFIG = REMOTE_PLAY_CONFIG;
const url = window.location.href.substring(0, 31) + '/launch/fortnite/BT5P2X999VH2#remote-play';
const $pageContent = document.getElementById('PageContent');
const $anchor = CE('a', { href: url, class: 'bx-hidden bx-offscreen' }, '');
$anchor.addEventListener('click', e => {
setTimeout(() => {
$pageContent.removeChild($anchor);
}, 1000);
});
$pageContent.appendChild($anchor);
$anchor.click();
RemotePlay.#dialog.hide();
}, },
}), }),
); );
@ -3668,22 +3682,7 @@ class RemotePlay {
$fragment.appendChild($child); $fragment.appendChild($child);
} }
RemotePlay.#$content.parentElement.replaceChild($fragment, RemotePlay.#$content); RemotePlay.#$content = CE('div', {}, $fragment);
}
static detect() {
if (!getPref(Preferences.REMOTE_PLAY_ENABLED)) {
return;
}
IS_REMOTE_PLAYING = window.location.pathname.includes('/launch/') && window.location.hash.startsWith('#remote-play');
if (IS_REMOTE_PLAYING) {
window.BX_REMOTE_PLAY_CONFIG = REMOTE_PLAY_CONFIG;
// Remove /launch/... from URL
window.history.replaceState({origin: 'better-xcloud'}, '', 'https://www.xbox.com/' + location.pathname.substring(1, 6) + '/play');
} else {
window.BX_REMOTE_PLAY_CONFIG = null;
}
} }
static #getXhomeToken(callback) { static #getXhomeToken(callback) {
@ -3765,8 +3764,11 @@ class RemotePlay {
REMOTE_PLAY_SERVER = server; REMOTE_PLAY_SERVER = server;
callback(); callback();
break;
} catch (e) {} } catch (e) {}
if (RemotePlay.#CONSOLES) {
break;
}
} }
// None of the servers worked // None of the servers worked
@ -3775,9 +3777,91 @@ class RemotePlay {
} }
} }
static showDialog() { static play(serverId, resolution) {
if (resolution) {
setPref(Preferences.REMOTE_PLAY_RESOLUTION, resolution);
}
REMOTE_PLAY_CONFIG = {
serverId: serverId,
};
window.BX_REMOTE_PLAY_CONFIG = REMOTE_PLAY_CONFIG;
const url = window.location.href.substring(0, 31) + '/launch/fortnite/BT5P2X999VH2#remote-play';
const $pageContent = document.getElementById('PageContent');
const $anchor = CE('a', { href: url, class: 'bx-hidden bx-offscreen' }, '');
$anchor.addEventListener('click', e => {
setTimeout(() => {
$pageContent.removeChild($anchor);
}, 1000);
});
$pageContent.appendChild($anchor);
$anchor.click();
RemotePlay.detachPopup();
}
static preload() {
RemotePlay.#initialize(); RemotePlay.#initialize();
RemotePlay.#dialog.show(); }
static detachPopup() {
// Detach popup from body
const $popup = document.querySelector('.bx-remote-play-popup');
$popup && $popup.remove();
}
static togglePopup(force = null) {
if (!getPref(Preferences.REMOTE_PLAY_ENABLED) || !RemotePlay.isReady()) {
return;
}
RemotePlay.#initialize();
if (AppInterface && AppInterface.showRemotePlayDialog) {
AppInterface.showRemotePlayDialog(JSON.stringify(RemotePlay.#CONSOLES));
document.activeElement.blur();
return;
}
if (document.querySelector('.bx-remote-play-popup')) {
if (force === false) {
RemotePlay.#$content.classList.add('bx-gone');
} else {
RemotePlay.#$content.classList.toggle('bx-gone');
}
return;
}
const $header = document.querySelector('#gamepass-root header');
const group = $header.firstElementChild.getAttribute('data-group');
RemotePlay.#$content.setAttribute('data-group', group);
RemotePlay.#$content.classList.add('bx-remote-play-popup');
RemotePlay.#$content.classList.remove('bx-gone');
$header.insertAdjacentElement('afterend', RemotePlay.#$content);
}
static detect() {
if (!getPref(Preferences.REMOTE_PLAY_ENABLED)) {
return;
}
IS_REMOTE_PLAYING = window.location.pathname.includes('/launch/') && window.location.hash.startsWith('#remote-play');
if (IS_REMOTE_PLAYING) {
window.BX_REMOTE_PLAY_CONFIG = REMOTE_PLAY_CONFIG;
// Remove /launch/... from URL
window.history.replaceState({origin: 'better-xcloud'}, '', 'https://www.xbox.com/' + location.pathname.substring(1, 6) + '/play');
} else {
window.BX_REMOTE_PLAY_CONFIG = null;
}
}
static isReady() {
return RemotePlay.#CONSOLES !== null && RemotePlay.#CONSOLES.length > 0;
} }
} }
@ -4628,6 +4712,11 @@ class SettingElement {
const $control = method(...Array.from(arguments).slice(1)); const $control = method(...Array.from(arguments).slice(1));
$control.id = `bx_setting_${key}`; $control.id = `bx_setting_${key}`;
// Add "name" property to "select" elements
if (type === SettingElement.TYPE_OPTIONS || type === SettingElement.TYPE_MULTIPLE_OPTIONS) {
$control.name = $control.id;
}
return $control; return $control;
} }
} }
@ -7061,6 +7150,7 @@ class Preferences {
static get UI_LOADING_SCREEN_ROCKET() { return 'ui_loading_screen_rocket'; } static get UI_LOADING_SCREEN_ROCKET() { return 'ui_loading_screen_rocket'; }
static get UI_LAYOUT() { return 'ui_layout'; } static get UI_LAYOUT() { return 'ui_layout'; }
static get UI_SCROLLBAR_HIDE() { return 'ui_scrollbar_hide'; }
static get VIDEO_CLARITY() { return 'video_clarity'; } static get VIDEO_CLARITY() { return 'video_clarity'; }
static get VIDEO_RATIO() { return 'video_ratio' } static get VIDEO_RATIO() { return 'video_ratio' }
@ -7408,6 +7498,10 @@ class Preferences {
}, },
}, },
[Preferences.UI_SCROLLBAR_HIDE]: {
'default': false,
},
[Preferences.BLOCK_SOCIAL_FEATURES]: { [Preferences.BLOCK_SOCIAL_FEATURES]: {
'default': false, 'default': false,
}, },
@ -8101,10 +8195,8 @@ if (gamepadFound) {
'disableTrackEvent', 'disableTrackEvent',
], ],
getPref(Preferences.REMOTE_PLAY_ENABLED) && [ getPref(Preferences.REMOTE_PLAY_ENABLED) && ['remotePlayKeepAlive'],
'remotePlayDirectConnectUrl', getPref(Preferences.REMOTE_PLAY_ENABLED) && ['remotePlayDirectConnectUrl'],
'remotePlayKeepAlive',
],
[ [
'overrideSettings', 'overrideSettings',
@ -8372,6 +8464,7 @@ function addCss() {
--bx-reload-button-z-index: 9200; --bx-reload-button-z-index: 9200;
--bx-dialog-z-index: 9101; --bx-dialog-z-index: 9101;
--bx-dialog-overlay-z-index: 9100; --bx-dialog-overlay-z-index: 9100;
--bx-remote-play-popup-z-index: 9090;
--bx-stats-bar-z-index: 9001; --bx-stats-bar-z-index: 9001;
--bx-stream-settings-z-index: 9000; --bx-stream-settings-z-index: 9000;
--bx-mkb-pointer-lock-msg-z-index: 8999; --bx-mkb-pointer-lock-msg-z-index: 8999;
@ -8494,6 +8587,10 @@ a.bx-button.bx-full-width {
height: 46px; height: 46px;
} }
.bx-remote-play-button[disabled] {
opacity: 0.5;
}
.bx-settings-button { .bx-settings-button {
line-height: 30px; line-height: 30px;
font-size: 14px; font-size: 14px;
@ -8504,16 +8601,16 @@ a.bx-button.bx-full-width {
content: ' 🌟'; content: ' 🌟';
} }
.bx-remote-play-button, .bx-settings-button { .bx-button.bx-focusable, .bx-settings-button {
position: relative; position: relative;
} }
.bx-remote-play-button::after, .bx-settings-button::after { .bx-button.bx-focusable::after {
border: 2px solid transparent; border: 2px solid transparent;
border-radius: 4px; border-radius: 4px;
} }
.bx-remote-play-button:focus::after, .bx-settings-button:focus::after { .bx-button.bx-focusable:focus::after {
content: ''; content: '';
border-color: white; border-color: white;
position: absolute; position: absolute;
@ -8778,8 +8875,8 @@ div[class*=StreamMenu-module__menuContainer] > div[class*=Menu-module] {
bottom: 0; bottom: 0;
box-sizing: border-box; box-sizing: border-box;
width: 60px; width: 60px;
height: 60px; height: 90px;
padding: 16px; padding: 16px 16px 46px 16px;
background-size: cover; background-size: cover;
background-repeat: no-repeat; background-repeat: no-repeat;
background-origin: content-box; background-origin: content-box;
@ -8796,7 +8893,7 @@ div[class*=StreamMenu-module__menuContainer] > div[class*=Menu-module] {
} }
.bx-screenshot-button[data-capturing=true] { .bx-screenshot-button[data-capturing=true] {
padding: 8px; padding: 8px 8px 38px 8px;
} }
.bx-screenshot-canvas { .bx-screenshot-canvas {
@ -9474,6 +9571,45 @@ div[class*=StreamMenu-module__menuContainer] > div[class*=Menu-module] {
margin-top: 14px; margin-top: 14px;
} }
.bx-remote-play-popup {
width: 100%;
max-width: 1920px;
margin: auto;
position: relative;
height: 0.1px;
overflow: visible;
z-index: var(--bx-remote-play-popup-z-index);
}
.bx-remote-play-container {
position: absolute;
right: 10px;
top: 0;
background: #1a1b1e;
border-radius: 10px;
width: 420px;
max-width: calc(100vw - 20px);
margin: 0 0 0 auto;
padding: 20px;
box-shadow: #00000080 0px 0px 12px 0px;
}
@media (min-width:480px) and (min-height:calc(480px + 1px)) {
.bx-remote-play-container {
right: calc(env(safe-area-inset-right, 0px) + 32px)
}
}
@media (min-width:768px) and (min-height:calc(480px + 1px)) {
.bx-remote-play-container {
right: calc(env(safe-area-inset-right, 0px) + 48px)
}
}
@media (min-width:1920px) and (min-height:calc(480px + 1px)) {
.bx-remote-play-container {
right: calc(env(safe-area-inset-right, 0px) + 80px)
}
}
.bx-remote-play-settings { .bx-remote-play-settings {
margin-bottom: 12px; margin-bottom: 12px;
padding-bottom: 12px; padding-bottom: 12px;
@ -9678,6 +9814,15 @@ body:not([data-media-type=tv]) div[class*=MenuItem-module__label] {
`; `;
} }
// Hide scrollbar
if (getPref(Preferences.UI_SCROLLBAR_HIDE)) {
css += `
body::-webkit-scrollbar {
display: none;
}
`;
}
const $style = createElement('style', {}, css); const $style = createElement('style', {}, css);
document.documentElement.appendChild($style); document.documentElement.appendChild($style);
} }
@ -10237,9 +10382,10 @@ function injectSettingsButton($parent) {
classes: ['bx-remote-play-button'], classes: ['bx-remote-play-button'],
icon: Icon.REMOTE_PLAY, icon: Icon.REMOTE_PLAY,
title: t('remote-play'), title: t('remote-play'),
disabled: !RemotePlay.isReady(),
style: ButtonStyle.GHOST | ButtonStyle.FOCUSABLE, style: ButtonStyle.GHOST | ButtonStyle.FOCUSABLE,
onClick: e => { onClick: e => {
RemotePlay.showDialog(); RemotePlay.togglePopup();
}, },
}); });
$headerFragment.appendChild($remotePlayBtn); $headerFragment.appendChild($remotePlayBtn);
@ -10375,6 +10521,7 @@ function injectSettingsButton($parent) {
}, },
[t('ui')]: { [t('ui')]: {
[Preferences.UI_LAYOUT]: t('layout'), [Preferences.UI_LAYOUT]: t('layout'),
[Preferences.UI_SCROLLBAR_HIDE]: t('hide-scrollbar'),
[Preferences.STREAM_SIMPLIFY_MENU]: t('simplify-stream-menu'), [Preferences.STREAM_SIMPLIFY_MENU]: t('simplify-stream-menu'),
[Preferences.SKIP_SPLASH_VIDEO]: t('skip-splash-video'), [Preferences.SKIP_SPLASH_VIDEO]: t('skip-splash-video'),
[Preferences.HIDE_DOTS_ICON]: t('hide-system-menu-icon'), [Preferences.HIDE_DOTS_ICON]: t('hide-system-menu-icon'),
@ -10463,6 +10610,8 @@ function injectSettingsButton($parent) {
let selectedValue; let selectedValue;
$control = CE('select', {id: `bx_setting_${settingId}`}); $control = CE('select', {id: `bx_setting_${settingId}`});
$control.name = $control.id;
$control.addEventListener('change', e => { $control.addEventListener('change', e => {
setPref(settingId, e.target.value); setPref(settingId, e.target.value);
onChange(e); onChange(e);
@ -11380,6 +11529,10 @@ function takeScreenshot(callback) {
if (AppInterface) { if (AppInterface) {
const data = $SCREENSHOT_CANVAS.toDataURL('image/png').split(';base64,')[1]; const data = $SCREENSHOT_CANVAS.toDataURL('image/png').split(';base64,')[1];
AppInterface.saveScreenshot(GAME_TITLE_ID, data); AppInterface.saveScreenshot(GAME_TITLE_ID, data);
// Free screenshot from memory
$canvasContext.clearRect(0, 0, $SCREENSHOT_CANVAS.width, $SCREENSHOT_CANVAS.height);
callback && callback(); callback && callback();
return; return;
} }
@ -11479,6 +11632,9 @@ function onHistoryChanged(e) {
$settings.classList.add('bx-gone'); $settings.classList.add('bx-gone');
} }
// Hide Remote Play popup
RemotePlay.detachPopup();
LoadingScreen.reset(); LoadingScreen.reset();
setTimeout(checkHeader, 2000); setTimeout(checkHeader, 2000);
@ -11708,7 +11864,11 @@ if (getPref(Preferences.CONTROLLER_ENABLE_SHORTCUTS)) {
Patcher.initialize(); Patcher.initialize();
// Preload Remote Play
if (getPref(Preferences.REMOTE_PLAY_ENABLED)) {
BX_FLAGS.PreloadRemotePlay && RemotePlay.preload();
RemotePlay.detect(); RemotePlay.detect();
}
StreamBadges.setupEvents(); StreamBadges.setupEvents();
StreamStats.setupEvents(); StreamStats.setupEvents();
@ -11716,6 +11876,7 @@ MkbHandler.setupEvents();
// Show a toast when connecting/disconecting controller // Show a toast when connecting/disconecting controller
function showGamepadToast(gamepad) { function showGamepadToast(gamepad) {
console.log(gamepad);
let text = '🎮'; let text = '🎮';
if (getPref(Preferences.LOCAL_CO_OP_ENABLED)) { if (getPref(Preferences.LOCAL_CO_OP_ENABLED)) {
@ -11725,7 +11886,14 @@ function showGamepadToast(gamepad) {
// Remove "(STANDARD GAMEPAD Vendor: xxx Product: xxx)" from ID // Remove "(STANDARD GAMEPAD Vendor: xxx Product: xxx)" from ID
const gamepadId = gamepad.id.replace(/ \(.*?Vendor: \w+ Product: \w+\)$/, ''); const gamepadId = gamepad.id.replace(/ \(.*?Vendor: \w+ Product: \w+\)$/, '');
text += ` - ${gamepadId}`; text += ` - ${gamepadId}`;
const status = gamepad.connected ? t('connected') : t('disconnected');
let status;
if (gamepad.connected) {
const supportVibration = !!gamepad.vibrationActuator;
status = (supportVibration ? '✅' : '❌') + ' ' + t('vibration-status');
} else {
status = t('disconnected');
}
Toast.show(text, status, {instant: false}); Toast.show(text, status, {instant: false});
} }