mirror of
https://github.com/redphx/better-xcloud.git
synced 2025-07-07 14:51:42 +02:00
Compare commits
22 Commits
Author | SHA1 | Date | |
---|---|---|---|
adf689d61d | |||
086385fbfb | |||
705446ffb9 | |||
e366cb73e4 | |||
d148fc708e | |||
f75e22b5f6 | |||
0f7ac4c372 | |||
a4874c76db | |||
397b3baa9b | |||
0330d0d811 | |||
f8e035d98f | |||
1e7bc366ca | |||
c207025df9 | |||
83b35dfc61 | |||
e6ec664087 | |||
06790c8098 | |||
7310a009df | |||
5392414abd | |||
d78e55586e | |||
77abc44f3d | |||
788ac3d527 | |||
47ef5a9cd2 |
@ -1,5 +1,5 @@
|
|||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name Better xCloud
|
// @name Better xCloud
|
||||||
// @namespace https://github.com/redphx
|
// @namespace https://github.com/redphx
|
||||||
// @version 3.2.1
|
// @version 3.2.3
|
||||||
// ==/UserScript==
|
// ==/UserScript==
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name Better xCloud
|
// @name Better xCloud
|
||||||
// @namespace https://github.com/redphx
|
// @namespace https://github.com/redphx
|
||||||
// @version 3.2.1
|
// @version 3.2.3
|
||||||
// @description Improve Xbox Cloud Gaming (xCloud) experience
|
// @description Improve Xbox Cloud Gaming (xCloud) experience
|
||||||
// @author redphx
|
// @author redphx
|
||||||
// @license MIT
|
// @license MIT
|
||||||
@ -14,7 +14,7 @@
|
|||||||
// ==/UserScript==
|
// ==/UserScript==
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const SCRIPT_VERSION = '3.2.1';
|
const SCRIPT_VERSION = '3.2.3';
|
||||||
const SCRIPT_HOME = 'https://github.com/redphx/better-xcloud';
|
const SCRIPT_HOME = 'https://github.com/redphx/better-xcloud';
|
||||||
|
|
||||||
const ENABLE_XCLOUD_LOGGER = false;
|
const ENABLE_XCLOUD_LOGGER = false;
|
||||||
@ -675,6 +675,22 @@ const Translations = {
|
|||||||
"Bạn có muốn kết nối lại stream không?",
|
"Bạn có muốn kết nối lại stream không?",
|
||||||
"您想要刷新吗?",
|
"您想要刷新吗?",
|
||||||
],
|
],
|
||||||
|
"connected": [
|
||||||
|
,
|
||||||
|
"Connected",
|
||||||
|
"Conectado",
|
||||||
|
,
|
||||||
|
,
|
||||||
|
"接続済み",
|
||||||
|
,
|
||||||
|
"Połączony",
|
||||||
|
,
|
||||||
|
"Подключен",
|
||||||
|
"Bağlı",
|
||||||
|
"Під’єднано",
|
||||||
|
"Đã kết nối",
|
||||||
|
"已连接",
|
||||||
|
],
|
||||||
"console-connect": [
|
"console-connect": [
|
||||||
"Verbinden",
|
"Verbinden",
|
||||||
"Connect",
|
"Connect",
|
||||||
@ -963,6 +979,22 @@ const Translations = {
|
|||||||
"Đã tắt",
|
"Đã tắt",
|
||||||
"禁用",
|
"禁用",
|
||||||
],
|
],
|
||||||
|
"disconnected": [
|
||||||
|
,
|
||||||
|
"Disconnected",
|
||||||
|
"Desconectado",
|
||||||
|
,
|
||||||
|
,
|
||||||
|
"切断",
|
||||||
|
,
|
||||||
|
"Rozłączony",
|
||||||
|
,
|
||||||
|
"Отключен",
|
||||||
|
"Bağlı değil",
|
||||||
|
"Роз’єднано",
|
||||||
|
"Đã ngắt kết nối",
|
||||||
|
"已断开连接",
|
||||||
|
],
|
||||||
"edit": [
|
"edit": [
|
||||||
"Bearbeiten",
|
"Bearbeiten",
|
||||||
"Edit",
|
"Edit",
|
||||||
@ -996,7 +1028,7 @@ const Translations = {
|
|||||||
"启用手柄快捷方式",
|
"启用手柄快捷方式",
|
||||||
],
|
],
|
||||||
"enable-local-co-op-support": [
|
"enable-local-co-op-support": [
|
||||||
"Lokale Coop-Unterstützung aktivieren",
|
"Lokale Koop-Unterstützung aktivieren",
|
||||||
"Enable local co-op support",
|
"Enable local co-op support",
|
||||||
"Habilitar soporte co-op local",
|
"Habilitar soporte co-op local",
|
||||||
,
|
,
|
||||||
@ -1009,7 +1041,7 @@ const Translations = {
|
|||||||
"Yerel çok oyuncu desteğini aktive et",
|
"Yerel çok oyuncu desteğini aktive et",
|
||||||
"Увімкнути локальну co-op підтримку",
|
"Увімкнути локальну co-op підтримку",
|
||||||
"Kích hoạt tính năng chơi chung cục bộ",
|
"Kích hoạt tính năng chơi chung cục bộ",
|
||||||
,
|
"启用本地多人联机",
|
||||||
],
|
],
|
||||||
"enable-local-co-op-support-note": [
|
"enable-local-co-op-support-note": [
|
||||||
"Funktioniert nur, wenn das Spiel kein anderes Profil benötigt",
|
"Funktioniert nur, wenn das Spiel kein anderes Profil benötigt",
|
||||||
@ -1025,7 +1057,7 @@ const Translations = {
|
|||||||
"Bu seçenek ancak oyun ayrı profillere giriş yapılmasını istemiyorsa etki eder",
|
"Bu seçenek ancak oyun ayrı profillere giriş yapılmasını istemiyorsa etki eder",
|
||||||
"Працює, лише якщо для гри не потрібен інший профіль",
|
"Працює, лише якщо для гри не потрібен інший профіль",
|
||||||
"Chỉ hoạt động nếu game không yêu cầu thêm tài khoản khác",
|
"Chỉ hoạt động nếu game không yêu cầu thêm tài khoản khác",
|
||||||
,
|
"仅在当前游戏不要求切换账户时才能使用",
|
||||||
],
|
],
|
||||||
"enable-mic-on-startup": [
|
"enable-mic-on-startup": [
|
||||||
"Mikrofon bei Spielstart aktivieren",
|
"Mikrofon bei Spielstart aktivieren",
|
||||||
@ -1045,18 +1077,18 @@ const Translations = {
|
|||||||
],
|
],
|
||||||
"enable-mkb": [
|
"enable-mkb": [
|
||||||
"Maus- und Tastaturunterstützung aktivieren",
|
"Maus- und Tastaturunterstützung aktivieren",
|
||||||
"Enable Mouse & Keyboard support",
|
"Emulate controller with Mouse & Keyboard",
|
||||||
"Habilitar soporte para ratón y teclado",
|
"Emular mandos con teclado y ratón",
|
||||||
,
|
,
|
||||||
"Abilitare il supporto di mouse e tastiera",
|
"Abilitare il supporto di mouse e tastiera",
|
||||||
"マウス&キーボードのサポートを有効化",
|
"マウス&キーボード操作をコントローラー化",
|
||||||
"마우스 & 키보드 활성화",
|
"마우스 & 키보드 활성화",
|
||||||
"Włącz obsługę myszy i klawiatury",
|
"Włącz obsługę myszy i klawiatury",
|
||||||
"Habilitar suporte ao Mouse & Teclado",
|
"Habilitar suporte ao Mouse & Teclado",
|
||||||
"Включить поддержку мыши и клавиатуры",
|
"Эмулировать контроллер с помощью мыши и клавиатуры",
|
||||||
"Klavye ve fare desteğini aktive et",
|
"Klavye ve fare desteğini aktive et",
|
||||||
"Увімкнути підтримку миші та клавіатури",
|
"Емуляція контролера за допомогою миші та клавіатури",
|
||||||
"Kích hoạt hỗ trợ Chuột & Bàn phím",
|
"Giả lập tay cầm bằng Chuột và Bàn phím",
|
||||||
"启用鼠标和键盘支持",
|
"启用鼠标和键盘支持",
|
||||||
],
|
],
|
||||||
"enable-quick-glance-mode": [
|
"enable-quick-glance-mode": [
|
||||||
@ -1169,7 +1201,7 @@ const Translations = {
|
|||||||
"Mobil cihazda Fortnite: Dünyayı Kurtar modunu etkinleştir",
|
"Mobil cihazda Fortnite: Dünyayı Kurtar modunu etkinleştir",
|
||||||
"Дозволити відтворення режиму STW на мобільному пристрої",
|
"Дозволити відтворення режиму STW на мобільному пристрої",
|
||||||
"Cho phép chơi chế độ STW trên điện thoại",
|
"Cho phép chơi chế độ STW trên điện thoại",
|
||||||
,
|
"允许游玩Save the World模式",
|
||||||
],
|
],
|
||||||
"fortnite-force-console-version": [
|
"fortnite-force-console-version": [
|
||||||
"Fortnite: Erzwinge Konsolenversion",
|
"Fortnite: Erzwinge Konsolenversion",
|
||||||
@ -1185,7 +1217,7 @@ const Translations = {
|
|||||||
"Fortnite'ın konsol sürümünü aç",
|
"Fortnite'ın konsol sürümünü aç",
|
||||||
"Fortnite: примусова консольна версія",
|
"Fortnite: примусова консольна версія",
|
||||||
"Fortnite: bắt buộc phiên bản console",
|
"Fortnite: bắt buộc phiên bản console",
|
||||||
,
|
"Fortnite: 强制使用主机版客户端",
|
||||||
],
|
],
|
||||||
"getting-consoles-list": [
|
"getting-consoles-list": [
|
||||||
"Rufe Liste der Konsolen ab...",
|
"Rufe Liste der Konsolen ab...",
|
||||||
@ -1380,20 +1412,20 @@ const Translations = {
|
|||||||
"载入画面",
|
"载入画面",
|
||||||
],
|
],
|
||||||
"local-co-op": [
|
"local-co-op": [
|
||||||
,
|
"Lokales Koop",
|
||||||
"Local co-op",
|
"Local co-op",
|
||||||
"Co-op local",
|
"Co-op local",
|
||||||
,
|
,
|
||||||
,
|
,
|
||||||
"ローカルマルチプレイ",
|
"ローカルマルチプレイ",
|
||||||
,
|
,
|
||||||
,
|
"Lokalna kooperacja",
|
||||||
"Co-op local",
|
"Co-op local",
|
||||||
,
|
"Локальная кооперативная игра",
|
||||||
,
|
"Yerel çoklu oyunculu",
|
||||||
"Локальний co-op",
|
"Локальний co-op",
|
||||||
"Chơi chung cục bộ",
|
"Chơi chung cục bộ",
|
||||||
,
|
"本地多人联机",
|
||||||
],
|
],
|
||||||
"map-mouse-to": [
|
"map-mouse-to": [
|
||||||
"Maus binden an",
|
"Maus binden an",
|
||||||
@ -2123,13 +2155,13 @@ const Translations = {
|
|||||||
,
|
,
|
||||||
"タッチコントローラーとコントローラー#1を分ける",
|
"タッチコントローラーとコントローラー#1を分ける",
|
||||||
,
|
,
|
||||||
,
|
"Oddziel Kontroler dotykowy i Kontroler #1",
|
||||||
"Separar o Controle por Toque e o Controle #1",
|
"Separar o Controle por Toque e o Controle #1",
|
||||||
"Раздельный сенсорный контроллер и контроллер #1",
|
"Раздельный сенсорный контроллер и контроллер #1",
|
||||||
,
|
"Dokunmatik kumandayı ve birincil kumandayı ayrı tut",
|
||||||
"Окремо Сенсорний контролер та Контролер #1",
|
"Окремо Сенсорний контролер та Контролер #1",
|
||||||
"Tách biệt Bộ điều khiển cảm ứng và Tay cầm #1",
|
"Tách biệt Bộ điều khiển cảm ứng và Tay cầm #1",
|
||||||
,
|
"虚拟摇杆和手柄分别控制不同角色",
|
||||||
],
|
],
|
||||||
"separate-touch-controller-note": [
|
"separate-touch-controller-note": [
|
||||||
"Touch-Controller ist Spieler 1, Controller #1 ist Spieler 2",
|
"Touch-Controller ist Spieler 1, Controller #1 ist Spieler 2",
|
||||||
@ -2139,13 +2171,13 @@ const Translations = {
|
|||||||
,
|
,
|
||||||
"タッチコントローラーがプレイヤー1、コントローラー#1がプレイヤー2に割り当てられます",
|
"タッチコントローラーがプレイヤー1、コントローラー#1がプレイヤー2に割り当てられます",
|
||||||
,
|
,
|
||||||
,
|
"Kontroler dotykowy to Gracz 1, Kontroler #1 to Gracz 2",
|
||||||
"O Controle por Toque é o Jogador 1, o Controle #1 é o Jogador 2",
|
"O Controle por Toque é o Jogador 1, o Controle #1 é o Jogador 2",
|
||||||
"Сенсорный контроллер — игрок 1, контроллер #1 — игрок 2",
|
"Сенсорный контроллер — игрок 1, контроллер #1 — игрок 2",
|
||||||
,
|
"Dokunmaktik kumanda birinci oyuncu, birincil kumanda ikinci oyuncu",
|
||||||
"Сенсорний контролер це Гравець 1, Контролер #1 це Гравець 2",
|
"Сенсорний контролер це Гравець 1, Контролер #1 це Гравець 2",
|
||||||
"Bộ điều khiển cảm ứng là Người chơi 1, Tay cầm #1 là Người chơi 2",
|
"Bộ điều khiển cảm ứng là Người chơi 1, Tay cầm #1 là Người chơi 2",
|
||||||
,
|
"虚拟摇杆为玩家1,手柄#1为玩家2",
|
||||||
],
|
],
|
||||||
"server": [
|
"server": [
|
||||||
"Server",
|
"Server",
|
||||||
@ -2627,6 +2659,22 @@ const Translations = {
|
|||||||
"Trắng hoàn toàn",
|
"Trắng hoàn toàn",
|
||||||
"白色",
|
"白色",
|
||||||
],
|
],
|
||||||
|
"tc-auto-off": [
|
||||||
|
"Aus, wenn Controller gefunden",
|
||||||
|
"Off when controller found",
|
||||||
|
"Desactivar cuando se encuentra el controlador",
|
||||||
|
,
|
||||||
|
,
|
||||||
|
"コントローラー接続時に無効化",
|
||||||
|
,
|
||||||
|
"Wyłącz, gdy kontroler zostanie znaleziony",
|
||||||
|
"Desligar toque quando o controle estiver conectado",
|
||||||
|
"Выключить, когда контроллер найден",
|
||||||
|
"Başka bir kumanda bağlandığında kapat",
|
||||||
|
"Вимкнено, коли контролер знайдено",
|
||||||
|
"Tắt khi sử dụng tay cầm",
|
||||||
|
"手柄连接时隐藏虚拟摇杆",
|
||||||
|
],
|
||||||
"tc-availability": [
|
"tc-availability": [
|
||||||
"Verfügbarkeit",
|
"Verfügbarkeit",
|
||||||
"Availability",
|
"Availability",
|
||||||
@ -3061,7 +3109,7 @@ const Translations = {
|
|||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
const LOCALE = Translations.getLocale();
|
let LOCALE = Translations.getLocale();
|
||||||
const t = Translations.get;
|
const t = Translations.get;
|
||||||
|
|
||||||
|
|
||||||
@ -4047,14 +4095,39 @@ class Toast {
|
|||||||
static #$wrapper;
|
static #$wrapper;
|
||||||
static #$msg;
|
static #$msg;
|
||||||
static #$status;
|
static #$status;
|
||||||
|
static #stack = [];
|
||||||
|
static #isShowing = false;
|
||||||
|
|
||||||
static #timeout;
|
static #timeout;
|
||||||
static #DURATION = 3000;
|
static #DURATION = 3000;
|
||||||
|
|
||||||
static show(msg, status) {
|
static show(msg, status, options) {
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
if (options.instant) {
|
||||||
|
// Clear stack
|
||||||
|
Toast.#stack = [arguments];
|
||||||
|
Toast.#showNext();
|
||||||
|
} else {
|
||||||
|
Toast.#stack.push(arguments);
|
||||||
|
!Toast.#isShowing && Toast.#showNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static #showNext() {
|
||||||
|
if (!Toast.#stack.length) {
|
||||||
|
Toast.#isShowing = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Toast.#isShowing = true;
|
||||||
|
|
||||||
Toast.#timeout && clearTimeout(Toast.#timeout);
|
Toast.#timeout && clearTimeout(Toast.#timeout);
|
||||||
Toast.#timeout = setTimeout(Toast.#hide, Toast.#DURATION);
|
Toast.#timeout = setTimeout(Toast.#hide, Toast.#DURATION);
|
||||||
|
|
||||||
|
// Get values from item
|
||||||
|
const [msg, status, options] = Toast.#stack.shift();
|
||||||
|
|
||||||
Toast.#$msg.textContent = msg;
|
Toast.#$msg.textContent = msg;
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
@ -4087,6 +4160,8 @@ class Toast {
|
|||||||
if (classList.contains('bx-hide')) {
|
if (classList.contains('bx-hide')) {
|
||||||
classList.remove('bx-offscreen', 'bx-hide');
|
classList.remove('bx-offscreen', 'bx-hide');
|
||||||
classList.add('bx-offscreen');
|
classList.add('bx-offscreen');
|
||||||
|
|
||||||
|
Toast.#showNext();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -4831,7 +4906,7 @@ class MkbHandler {
|
|||||||
static get MAXIMUM_STICK_RANGE() { return 1.1; }
|
static get MAXIMUM_STICK_RANGE() { return 1.1; }
|
||||||
|
|
||||||
#VIRTUAL_GAMEPAD = {
|
#VIRTUAL_GAMEPAD = {
|
||||||
id: 'Xbox 360 Controller (XInput STANDARD GAMEPAD)',
|
id: 'Xbox 360 Controller',
|
||||||
index: 3,
|
index: 3,
|
||||||
connected: false,
|
connected: false,
|
||||||
hapticActuators: null,
|
hapticActuators: null,
|
||||||
@ -6712,6 +6787,7 @@ class Preferences {
|
|||||||
static get STREAM_SIMPLIFY_MENU() { return 'stream_simplify_menu'; }
|
static get STREAM_SIMPLIFY_MENU() { return 'stream_simplify_menu'; }
|
||||||
|
|
||||||
static get STREAM_TOUCH_CONTROLLER() { return 'stream_touch_controller'; }
|
static get STREAM_TOUCH_CONTROLLER() { return 'stream_touch_controller'; }
|
||||||
|
static get STREAM_TOUCH_CONTROLLER_AUTO_OFF() { return 'stream_touch_controller_auto_off'; }
|
||||||
static get STREAM_TOUCH_CONTROLLER_STYLE_STANDARD() { return 'stream_touch_controller_style_standard'; }
|
static get STREAM_TOUCH_CONTROLLER_STYLE_STANDARD() { return 'stream_touch_controller_style_standard'; }
|
||||||
static get STREAM_TOUCH_CONTROLLER_STYLE_CUSTOM() { return 'stream_touch_controller_style_custom'; }
|
static get STREAM_TOUCH_CONTROLLER_STYLE_CUSTOM() { return 'stream_touch_controller_style_custom'; }
|
||||||
|
|
||||||
@ -6785,18 +6861,18 @@ class Preferences {
|
|||||||
'options': {
|
'options': {
|
||||||
'de-DE': 'Deutsch',
|
'de-DE': 'Deutsch',
|
||||||
'en-US': 'English (United States)',
|
'en-US': 'English (United States)',
|
||||||
'es-ES': 'espa\xf1ol (Espa\xf1a)',
|
'es-ES': 'español (España)',
|
||||||
'fr-FR': 'fran\xe7ais',
|
'fr-FR': 'français',
|
||||||
'it-IT': 'italiano',
|
'it-IT': 'italiano',
|
||||||
'ja-JP': '\u65e5\u672c\u8a9e',
|
'ja-JP': '日本語',
|
||||||
'ko-KR': '\ud55c\uad6d\uc5b4',
|
'ko-KR': '한국어',
|
||||||
'pl-PL': 'polski',
|
'pl-PL': 'polski',
|
||||||
'pt-BR': 'portugu\xeas (Brasil)',
|
'pt-BR': 'português (Brasil)',
|
||||||
'ru-RU': '\u0440\u0443\u0441\u0441\u043a\u0438\u0439',
|
'ru-RU': 'русский',
|
||||||
'tr-TR': 'T\xfcrk\xe7e',
|
'tr-TR': 'Türkçe',
|
||||||
'uk-UA': 'українська',
|
'uk-UA': 'українська',
|
||||||
'vi-VN': 'Tiếng Việt',
|
'vi-VN': 'Tiếng Việt',
|
||||||
'zh-CN': '\u4e2d\u6587(\u7b80\u4f53)',
|
'zh-CN': '中文(简体)',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
[Preferences.SERVER_REGION]: {
|
[Preferences.SERVER_REGION]: {
|
||||||
@ -6806,37 +6882,37 @@ class Preferences {
|
|||||||
'default': 'default',
|
'default': 'default',
|
||||||
'options': {
|
'options': {
|
||||||
'default': t('default'),
|
'default': t('default'),
|
||||||
'ar-SA': '\u0627\u0644\u0639\u0631\u0628\u064a\u0629',
|
'ar-SA': 'العربية',
|
||||||
'cs-CZ': '\u010de\u0161tina',
|
'cs-CZ': 'čeština',
|
||||||
'da-DK': 'dansk',
|
'da-DK': 'dansk',
|
||||||
'de-DE': 'Deutsch',
|
'de-DE': 'Deutsch',
|
||||||
'el-GR': '\u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac',
|
'el-GR': 'Ελληνικά',
|
||||||
'en-GB': 'English (United Kingdom)',
|
'en-GB': 'English (United Kingdom)',
|
||||||
'en-US': 'English (United States)',
|
'en-US': 'English (United States)',
|
||||||
'es-ES': 'espa\xf1ol (Espa\xf1a)',
|
'es-ES': 'español (España)',
|
||||||
'es-MX': 'espa\xf1ol (Latinoam\xe9rica)',
|
'es-MX': 'español (Latinoamérica)',
|
||||||
'fi-FI': 'suomi',
|
'fi-FI': 'suomi',
|
||||||
'fr-FR': 'fran\xe7ais',
|
'fr-FR': 'français',
|
||||||
'he-IL': '\u05e2\u05d1\u05e8\u05d9\u05ea',
|
'he-IL': 'עברית',
|
||||||
'hu-HU': 'magyar',
|
'hu-HU': 'magyar',
|
||||||
'it-IT': 'italiano',
|
'it-IT': 'italiano',
|
||||||
'ja-JP': '\u65e5\u672c\u8a9e',
|
'ja-JP': '日本語',
|
||||||
'ko-KR': '\ud55c\uad6d\uc5b4',
|
'ko-KR': '한국어',
|
||||||
'nb-NO': 'norsk bokm\xe5l',
|
'nb-NO': 'norsk bokmål',
|
||||||
'nl-NL': 'Nederlands',
|
'nl-NL': 'Nederlands',
|
||||||
'pl-PL': 'polski',
|
'pl-PL': 'polski',
|
||||||
'pt-BR': 'portugu\xeas (Brasil)',
|
'pt-BR': 'português (Brasil)',
|
||||||
'pt-PT': 'portugu\xeas (Portugal)',
|
'pt-PT': 'português (Portugal)',
|
||||||
'ru-RU': '\u0440\u0443\u0441\u0441\u043a\u0438\u0439',
|
'ru-RU': 'русский',
|
||||||
'sk-SK': 'sloven\u010dina',
|
'sk-SK': 'slovenčina',
|
||||||
'sv-SE': 'svenska',
|
'sv-SE': 'svenska',
|
||||||
'tr-TR': 'T\xfcrk\xe7e',
|
'tr-TR': 'Türkçe',
|
||||||
'zh-CN': '\u4e2d\u6587(\u7b80\u4f53)',
|
'zh-CN': '中文(简体)',
|
||||||
'zh-TW': '\u4e2d\u6587 (\u7e41\u9ad4)',
|
'zh-TW': '中文 (繁體)',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
[Preferences.STREAM_TARGET_RESOLUTION]: {
|
[Preferences.STREAM_TARGET_RESOLUTION]: {
|
||||||
'default': '1080p',
|
'default': 'auto',
|
||||||
'options': {
|
'options': {
|
||||||
'auto': t('default'),
|
'auto': t('default'),
|
||||||
'1080p': '1080p',
|
'1080p': '1080p',
|
||||||
@ -6929,21 +7005,25 @@ class Preferences {
|
|||||||
[Preferences.HIDE_DOTS_ICON]: {
|
[Preferences.HIDE_DOTS_ICON]: {
|
||||||
'default': false,
|
'default': false,
|
||||||
},
|
},
|
||||||
|
|
||||||
[Preferences.STREAM_TOUCH_CONTROLLER]: {
|
[Preferences.STREAM_TOUCH_CONTROLLER]: {
|
||||||
'default': 'all',
|
'default': 'all',
|
||||||
'options': {
|
'options': {
|
||||||
'default': t('default'),
|
'default': t('default'),
|
||||||
'all': t('tc-all-games'),
|
'all': t('tc-all-games'),
|
||||||
'off': t('off'),
|
|
||||||
},
|
},
|
||||||
'unsupported': !HAS_TOUCH_SUPPORT,
|
'unsupported': !HAS_TOUCH_SUPPORT,
|
||||||
'ready': () => {
|
'ready': () => {
|
||||||
const setting = Preferences.SETTINGS[Preferences.STREAM_TOUCH_CONTROLLER];
|
const setting = Preferences.SETTINGS[Preferences.STREAM_TOUCH_CONTROLLER];
|
||||||
if (setting.unsupported) {
|
if (setting.unsupported) {
|
||||||
setting.default = 'off';
|
setting.default = 'default';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
[Preferences.STREAM_TOUCH_CONTROLLER_AUTO_OFF]: {
|
||||||
|
'default': false,
|
||||||
|
'unsupported': !HAS_TOUCH_SUPPORT,
|
||||||
|
},
|
||||||
[Preferences.STREAM_TOUCH_CONTROLLER_STYLE_STANDARD]: {
|
[Preferences.STREAM_TOUCH_CONTROLLER_STYLE_STANDARD]: {
|
||||||
'default': 'default',
|
'default': 'default',
|
||||||
'options': {
|
'options': {
|
||||||
@ -6961,6 +7041,7 @@ class Preferences {
|
|||||||
},
|
},
|
||||||
'unsupported': !HAS_TOUCH_SUPPORT,
|
'unsupported': !HAS_TOUCH_SUPPORT,
|
||||||
},
|
},
|
||||||
|
|
||||||
[Preferences.STREAM_SIMPLIFY_MENU]: {
|
[Preferences.STREAM_SIMPLIFY_MENU]: {
|
||||||
'default': false,
|
'default': false,
|
||||||
},
|
},
|
||||||
@ -7482,12 +7563,23 @@ class Patcher {
|
|||||||
|
|
||||||
// Block WebRTC stats collector
|
// Block WebRTC stats collector
|
||||||
blockWebRtcStatsCollector: function(funcStr) {
|
blockWebRtcStatsCollector: function(funcStr) {
|
||||||
const text = 'this.intervalMs=0,';
|
const text = 'this.shouldCollectStats=!0';
|
||||||
if (!funcStr.includes(text)) {
|
if (!funcStr.includes(text)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return funcStr.replace(text, 'false,' + text);
|
return funcStr.replace(text, 'this.shouldCollectStats=!1');
|
||||||
|
},
|
||||||
|
|
||||||
|
blockGamepadStatsCollector: function(funcStr) {
|
||||||
|
const text = 'this.inputPollingIntervalStats.addValue';
|
||||||
|
if (!funcStr.includes(text)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
funcStr = funcStr.replace('this.inputPollingIntervalStats.addValue', '');
|
||||||
|
funcStr = funcStr.replace('this.inputPollingDurationStats.addValue', '');
|
||||||
|
return funcStr;
|
||||||
},
|
},
|
||||||
|
|
||||||
enableXcloudLogger: function(funcStr) {
|
enableXcloudLogger: function(funcStr) {
|
||||||
@ -7690,6 +7782,32 @@ if (window.BX_VIBRATION_INTENSITY && window.BX_VIBRATION_INTENSITY < 1) {
|
|||||||
funcStr = funcStr.replace(text, text + newCode);
|
funcStr = funcStr.replace(text, text + newCode);
|
||||||
return funcStr;
|
return funcStr;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
disableTakRenderer: function(funcStr) {
|
||||||
|
const text = 'const{TakRenderer:';
|
||||||
|
if (!funcStr.includes(text)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const newCode = `
|
||||||
|
const gamepads = window.navigator.getGamepads();
|
||||||
|
let gamepadFound = false;
|
||||||
|
|
||||||
|
for (let gamepad of gamepads) {
|
||||||
|
if (gamepad && gamepad.connected) {
|
||||||
|
gamepadFound = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gamepadFound) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
funcStr = funcStr.replace(text, newCode + text);
|
||||||
|
return funcStr;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static #PATCH_ORDERS = [
|
static #PATCH_ORDERS = [
|
||||||
@ -7733,10 +7851,13 @@ if (window.BX_VIBRATION_INTENSITY && window.BX_VIBRATION_INTENSITY < 1) {
|
|||||||
getPref(Preferences.REMOTE_PLAY_ENABLED) && ['remotePlayConnectMode'],
|
getPref(Preferences.REMOTE_PLAY_ENABLED) && ['remotePlayConnectMode'],
|
||||||
|
|
||||||
['playVibration'],
|
['playVibration'],
|
||||||
getPref(Preferences.STREAM_TOUCH_CONTROLLER) === 'all' && ['exposeTouchLayoutManager'],
|
HAS_TOUCH_SUPPORT && getPref(Preferences.STREAM_TOUCH_CONTROLLER) === 'all' && ['exposeTouchLayoutManager'],
|
||||||
|
HAS_TOUCH_SUPPORT && getPref(Preferences.STREAM_TOUCH_CONTROLLER_AUTO_OFF) && ['disableTakRenderer'],
|
||||||
|
|
||||||
ENABLE_XCLOUD_LOGGER && ['enableConsoleLogging'],
|
ENABLE_XCLOUD_LOGGER && ['enableConsoleLogging'],
|
||||||
|
|
||||||
|
getPref(Preferences.BLOCK_TRACKING) && ['blockGamepadStatsCollector'],
|
||||||
|
|
||||||
[
|
[
|
||||||
'disableGamepadDisconnectedScreen',
|
'disableGamepadDisconnectedScreen',
|
||||||
ENABLE_NATIVE_MKB_BETA && 'mkbMouseAndKeyboardEnabled',
|
ENABLE_NATIVE_MKB_BETA && 'mkbMouseAndKeyboardEnabled',
|
||||||
@ -7979,6 +8100,7 @@ function addCss() {
|
|||||||
--bx-danger-button-disabled-color: #a26c6c;
|
--bx-danger-button-disabled-color: #a26c6c;
|
||||||
|
|
||||||
--bx-toast-z-index: 9999;
|
--bx-toast-z-index: 9999;
|
||||||
|
--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-stats-bar-z-index: 9001;
|
--bx-stats-bar-z-index: 9001;
|
||||||
@ -8128,7 +8250,23 @@ a.bx-button {
|
|||||||
bottom: 0;
|
bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.better_xcloud_settings {
|
.bx-settings-reload-button-wrapper {
|
||||||
|
z-index: var(--bx-reload-button-z-index);
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
text-align: center;
|
||||||
|
background: #000000cf;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bx-settings-reload-button-wrapper button {
|
||||||
|
max-width: 450px;
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bx-settings-container {
|
||||||
background-color: #151515;
|
background-color: #151515;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
@ -8271,6 +8409,15 @@ a.bx-button {
|
|||||||
|
|
||||||
.bx-settings-row input {
|
.bx-settings-row input {
|
||||||
align-self: center;
|
align-self: center;
|
||||||
|
accent-color: var(--bx-primary-button-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bx-settings-row select:disabled {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
background: transparent;
|
||||||
|
text-align-last: right;
|
||||||
|
border: none;
|
||||||
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bx-settings-wrapper .bx-button.bx-primary {
|
.bx-settings-wrapper .bx-button.bx-primary {
|
||||||
@ -8423,9 +8570,15 @@ div[class*=StreamMenu-module__menuContainer] > div[class*=Menu-module] {
|
|||||||
border-right: none;
|
border-right: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bx-stats-bar[data-display=glancing]::before {
|
.bx-stats-bar::before {
|
||||||
content: '👀 ';
|
display: none;
|
||||||
|
content: '👀';
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bx-stats-bar[data-display=glancing]::before {
|
||||||
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bx-stats-bar[data-position=top-left] {
|
.bx-stats-bar[data-position=top-left] {
|
||||||
@ -8687,6 +8840,10 @@ div[class*=StreamMenu-module__menuContainer] > div[class*=Menu-module] {
|
|||||||
margin-bottom: 0 !important;
|
margin-bottom: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bx-quick-settings-row input {
|
||||||
|
accent-color: var(--bx-primary-button-color);
|
||||||
|
}
|
||||||
|
|
||||||
.bx-quick-settings-tab-contents h2 {
|
.bx-quick-settings-tab-contents h2 {
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -8818,13 +8975,19 @@ div[class*=StreamMenu-module__menuContainer] > div[class*=Menu-module] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.bx-mkb-settings select:disabled {
|
.bx-mkb-settings select:disabled {
|
||||||
|
-webkit-appearance: none;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
|
text-align-last: right;
|
||||||
|
text-align: right;
|
||||||
border: none;
|
border: none;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bx-quick-settings-row select:disabled {
|
.bx-quick-settings-row select:disabled {
|
||||||
text-align: right;
|
-webkit-appearance: none;
|
||||||
|
background: transparent;
|
||||||
|
text-align-last: right;
|
||||||
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bx-mkb-pointer-lock-msg {
|
.bx-mkb-pointer-lock-msg {
|
||||||
@ -9058,11 +9221,6 @@ div[class*=StreamMenu-module__menuContainer] > div[class*=Menu-module] {
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bx-remote-play-settings input {
|
|
||||||
display: block;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bx-remote-play-settings span {
|
.bx-remote-play-settings span {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
@ -9181,15 +9339,6 @@ div[class*=StreamHUD-module__buttonsContainer] {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide touch controller
|
|
||||||
if (getPref(Preferences.STREAM_TOUCH_CONTROLLER) === 'off') {
|
|
||||||
css += `
|
|
||||||
#MultiTouchSurface, #BabylonCanvasContainer-main {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Simplify Stream's menu
|
// Simplify Stream's menu
|
||||||
css += `
|
css += `
|
||||||
div[class*=StreamMenu-module__menu] {
|
div[class*=StreamMenu-module__menu] {
|
||||||
@ -9806,6 +9955,7 @@ function injectSettingsButton($parent) {
|
|||||||
const PREF_LATEST_VERSION = getPref(Preferences.LATEST_VERSION);
|
const PREF_LATEST_VERSION = getPref(Preferences.LATEST_VERSION);
|
||||||
|
|
||||||
const $headerFragment = document.createDocumentFragment();
|
const $headerFragment = document.createDocumentFragment();
|
||||||
|
let $reloadBtnWrapper;
|
||||||
|
|
||||||
// Remote Play button
|
// Remote Play button
|
||||||
if (getPref(Preferences.REMOTE_PLAY_ENABLED)) {
|
if (getPref(Preferences.REMOTE_PLAY_ENABLED)) {
|
||||||
@ -9828,7 +9978,7 @@ function injectSettingsButton($parent) {
|
|||||||
label: PREF_PREFERRED_REGION,
|
label: PREF_PREFERRED_REGION,
|
||||||
style: ButtonStyle.GHOST | ButtonStyle.FOCUSABLE | ButtonStyle.FULL_HEIGHT,
|
style: ButtonStyle.GHOST | ButtonStyle.FOCUSABLE | ButtonStyle.FULL_HEIGHT,
|
||||||
onClick: e => {
|
onClick: e => {
|
||||||
const $settings = document.querySelector('.better_xcloud_settings');
|
const $settings = document.querySelector('.bx-settings-container');
|
||||||
$settings.classList.toggle('bx-gone');
|
$settings.classList.toggle('bx-gone');
|
||||||
$settings.scrollIntoView();
|
$settings.scrollIntoView();
|
||||||
document.activeElement && document.activeElement.blur();
|
document.activeElement && document.activeElement.blur();
|
||||||
@ -9842,12 +9992,16 @@ function injectSettingsButton($parent) {
|
|||||||
|
|
||||||
// Add the Settings button to the web page
|
// Add the Settings button to the web page
|
||||||
$headerFragment.appendChild($settingsBtn);
|
$headerFragment.appendChild($settingsBtn);
|
||||||
|
|
||||||
$parent.appendChild($headerFragment);
|
$parent.appendChild($headerFragment);
|
||||||
|
|
||||||
|
// Avoid rendering the Settings multiple times
|
||||||
|
if (document.querySelector('.bx-settings-container')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Setup Settings UI
|
// Setup Settings UI
|
||||||
const $container = CE('div', {
|
const $container = CE('div', {
|
||||||
'class': 'better_xcloud_settings bx-gone',
|
'class': 'bx-settings-container bx-gone',
|
||||||
});
|
});
|
||||||
|
|
||||||
let $updateAvailable;
|
let $updateAvailable;
|
||||||
@ -9919,6 +10073,7 @@ function injectSettingsButton($parent) {
|
|||||||
[t('touch-controller')]: {
|
[t('touch-controller')]: {
|
||||||
_note: !HAS_TOUCH_SUPPORT ? '⚠️ ' + t('device-unsupported-touch') : null,
|
_note: !HAS_TOUCH_SUPPORT ? '⚠️ ' + t('device-unsupported-touch') : null,
|
||||||
[Preferences.STREAM_TOUCH_CONTROLLER]: t('tc-availability'),
|
[Preferences.STREAM_TOUCH_CONTROLLER]: t('tc-availability'),
|
||||||
|
[Preferences.STREAM_TOUCH_CONTROLLER_AUTO_OFF]: t('tc-auto-off'),
|
||||||
[Preferences.STREAM_TOUCH_CONTROLLER_STYLE_STANDARD]: t('tc-standard-layout-style'),
|
[Preferences.STREAM_TOUCH_CONTROLLER_STYLE_STANDARD]: t('tc-standard-layout-style'),
|
||||||
[Preferences.STREAM_TOUCH_CONTROLLER_STYLE_CUSTOM]: t('tc-custom-layout-style'),
|
[Preferences.STREAM_TOUCH_CONTROLLER_STYLE_CUSTOM]: t('tc-custom-layout-style'),
|
||||||
},
|
},
|
||||||
@ -9956,6 +10111,23 @@ function injectSettingsButton($parent) {
|
|||||||
|
|
||||||
$wrapper.appendChild($group);
|
$wrapper.appendChild($group);
|
||||||
|
|
||||||
|
let onChange = e => {
|
||||||
|
if (!$reloadBtnWrapper) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$reloadBtnWrapper.classList.remove('bx-gone');
|
||||||
|
|
||||||
|
if (e.target.id === 'bx_setting_' + Preferences.BETTER_XCLOUD_LOCALE) {
|
||||||
|
// Update locale
|
||||||
|
LOCALE = Translations.getLocale();
|
||||||
|
|
||||||
|
const $btn = $reloadBtnWrapper.firstElementChild;
|
||||||
|
$btn.textContent = t('settings-reloading');
|
||||||
|
$btn.click();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
for (let settingId in SETTINGS_UI[groupLabel]) {
|
for (let settingId in SETTINGS_UI[groupLabel]) {
|
||||||
if (settingId.startsWith('_')) {
|
if (settingId.startsWith('_')) {
|
||||||
continue;
|
continue;
|
||||||
@ -9978,6 +10150,7 @@ function injectSettingsButton($parent) {
|
|||||||
});
|
});
|
||||||
$inpCustomUserAgent.addEventListener('change', e => {
|
$inpCustomUserAgent.addEventListener('change', e => {
|
||||||
setPref(Preferences.USER_AGENT_CUSTOM, e.target.value.trim());
|
setPref(Preferences.USER_AGENT_CUSTOM, e.target.value.trim());
|
||||||
|
onChange(e);
|
||||||
});
|
});
|
||||||
|
|
||||||
$control = PREFS.toElement(Preferences.USER_AGENT_PROFILE, e => {
|
$control = PREFS.toElement(Preferences.USER_AGENT_PROFILE, e => {
|
||||||
@ -9988,6 +10161,8 @@ function injectSettingsButton($parent) {
|
|||||||
$inpCustomUserAgent.value = userAgent;
|
$inpCustomUserAgent.value = userAgent;
|
||||||
$inpCustomUserAgent.readOnly = !isCustom;
|
$inpCustomUserAgent.readOnly = !isCustom;
|
||||||
$inpCustomUserAgent.disabled = !isCustom;
|
$inpCustomUserAgent.disabled = !isCustom;
|
||||||
|
|
||||||
|
onChange(e);
|
||||||
});
|
});
|
||||||
} else if (settingId === Preferences.SERVER_REGION) {
|
} else if (settingId === Preferences.SERVER_REGION) {
|
||||||
let selectedValue;
|
let selectedValue;
|
||||||
@ -9995,6 +10170,7 @@ function injectSettingsButton($parent) {
|
|||||||
$control = CE('select', {id: `bx_setting_${settingId}`});
|
$control = CE('select', {id: `bx_setting_${settingId}`});
|
||||||
$control.addEventListener('change', e => {
|
$control.addEventListener('change', e => {
|
||||||
setPref(settingId, e.target.value);
|
setPref(settingId, e.target.value);
|
||||||
|
onChange(e);
|
||||||
});
|
});
|
||||||
|
|
||||||
selectedValue = PREF_PREFERRED_REGION;
|
selectedValue = PREF_PREFERRED_REGION;
|
||||||
@ -10020,15 +10196,14 @@ function injectSettingsButton($parent) {
|
|||||||
$control.appendChild($option);
|
$control.appendChild($option);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let onChange = null;
|
|
||||||
if (settingId === Preferences.BETTER_XCLOUD_LOCALE) {
|
if (settingId === Preferences.BETTER_XCLOUD_LOCALE) {
|
||||||
onChange = e => {
|
$control = PREFS.toElement(settingId, e => {
|
||||||
localStorage.setItem('better_xcloud_locale', e.target.value);
|
localStorage.setItem('better_xcloud_locale', e.target.value);
|
||||||
window.location.reload();
|
onChange(e);
|
||||||
}
|
});
|
||||||
|
} else {
|
||||||
|
$control = PREFS.toElement(settingId, onChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
$control = PREFS.toElement(settingId, onChange);
|
|
||||||
labelAttrs = {'for': $control.id, 'tabindex': 0};
|
labelAttrs = {'for': $control.id, 'tabindex': 0};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10059,9 +10234,8 @@ function injectSettingsButton($parent) {
|
|||||||
|
|
||||||
// Setup Reload button
|
// Setup Reload button
|
||||||
const $reloadBtn = createButton({
|
const $reloadBtn = createButton({
|
||||||
classes: ['bx-settings-reload-button'],
|
|
||||||
label: t('settings-reload'),
|
label: t('settings-reload'),
|
||||||
style: ButtonStyle.PRIMARY | ButtonStyle.FOCUSABLE | ButtonStyle.FULL_WIDTH,
|
style: ButtonStyle.DANGER | ButtonStyle.FOCUSABLE | ButtonStyle.FULL_WIDTH,
|
||||||
onClick: e => {
|
onClick: e => {
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
$reloadBtn.disabled = true;
|
$reloadBtn.disabled = true;
|
||||||
@ -10069,7 +10243,9 @@ function injectSettingsButton($parent) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
$reloadBtn.setAttribute('tabindex', 0);
|
$reloadBtn.setAttribute('tabindex', 0);
|
||||||
$wrapper.appendChild($reloadBtn);
|
|
||||||
|
$reloadBtnWrapper = CE('div', {'class': 'bx-settings-reload-button-wrapper bx-gone'}, $reloadBtn);
|
||||||
|
$wrapper.appendChild($reloadBtnWrapper);
|
||||||
|
|
||||||
// Donation link
|
// Donation link
|
||||||
const $donationLink = CE('a', {'class': 'bx-donation-link', href: 'https://ko-fi.com/redphx', target: '_blank'}, `❤️ ${t('support-better-xcloud')}`);
|
const $donationLink = CE('a', {'class': 'bx-donation-link', href: 'https://ko-fi.com/redphx', target: '_blank'}, `❤️ ${t('support-better-xcloud')}`);
|
||||||
@ -10667,14 +10843,8 @@ function setupQuickSettingsBar() {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
HAS_TOUCH_SUPPORT && {
|
HAS_TOUCH_SUPPORT && {
|
||||||
icon: Icon.HAND_TAP,
|
|
||||||
group: 'touch-controller',
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
group: 'touch-controller',
|
group: 'touch-controller',
|
||||||
label: t('touch-controller'),
|
label: t('touch-controller'),
|
||||||
items: [
|
items: [
|
||||||
@ -10833,6 +11003,10 @@ function setupQuickSettingsBar() {
|
|||||||
const $group = CE('div', {'data-group': settingTab.group, 'class': 'bx-gone'});
|
const $group = CE('div', {'data-group': settingTab.group, 'class': 'bx-gone'});
|
||||||
|
|
||||||
for (const settingGroup of settingTab.items) {
|
for (const settingGroup of settingTab.items) {
|
||||||
|
if (!settingGroup) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$group.appendChild(CE('h2', {},
|
$group.appendChild(CE('h2', {},
|
||||||
CE('span', {}, settingGroup.label),
|
CE('span', {}, settingGroup.label),
|
||||||
settingGroup.help_url && createButton({
|
settingGroup.help_url && createButton({
|
||||||
@ -10990,7 +11164,7 @@ function onHistoryChanged(e) {
|
|||||||
|
|
||||||
setTimeout(RemotePlay.detect, 10);
|
setTimeout(RemotePlay.detect, 10);
|
||||||
|
|
||||||
const $settings = document.querySelector('.better_xcloud_settings');
|
const $settings = document.querySelector('.bx-settings-container');
|
||||||
if ($settings) {
|
if ($settings) {
|
||||||
$settings.classList.add('bx-gone');
|
$settings.classList.add('bx-gone');
|
||||||
}
|
}
|
||||||
@ -11105,7 +11279,7 @@ window.addEventListener(BxEvent.STREAM_STOPPED, e => {
|
|||||||
IS_PLAYING = false;
|
IS_PLAYING = false;
|
||||||
|
|
||||||
// Stop MKB listeners
|
// Stop MKB listeners
|
||||||
MkbHandler.INSTANCE.destroy();
|
getPref(Preferences.MKB_ENABLED) && MkbHandler.INSTANCE.destroy();
|
||||||
|
|
||||||
const $quickBar = document.querySelector('.bx-quick-settings-bar');
|
const $quickBar = document.querySelector('.bx-quick-settings-bar');
|
||||||
if ($quickBar) {
|
if ($quickBar) {
|
||||||
@ -11231,3 +11405,22 @@ RemotePlay.detect();
|
|||||||
StreamBadges.setupEvents();
|
StreamBadges.setupEvents();
|
||||||
StreamStats.setupEvents();
|
StreamStats.setupEvents();
|
||||||
MkbHandler.setupEvents();
|
MkbHandler.setupEvents();
|
||||||
|
|
||||||
|
// Show a toast when connecting/disconecting controller
|
||||||
|
function showGamepadToast(gamepad) {
|
||||||
|
let text = '🎮';
|
||||||
|
|
||||||
|
if (getPref(Preferences.LOCAL_CO_OP_ENABLED)) {
|
||||||
|
text += ` #${gamepad.index + 1}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove "(STANDARD GAMEPAD Vendor: xxx Product: xxx)" from ID
|
||||||
|
const gamepadId = gamepad.id.replace(/ \(.* Vendor: \w+ Product: \w+\)$/, '');
|
||||||
|
text += ` - ${gamepadId}`;
|
||||||
|
const status = gamepad.connected ? t('connected') : t('disconnected');
|
||||||
|
|
||||||
|
Toast.show(text, status, {instant: false});
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('gamepadconnected', e => showGamepadToast(e.gamepad));
|
||||||
|
window.addEventListener('gamepaddisconnected', e => showGamepadToast(e.gamepad));
|
||||||
|
Reference in New Issue
Block a user