mirror of
https://github.com/redphx/better-xcloud.git
synced 2025-07-12 09:11:43 +02:00
Compare commits
17 Commits
Author | SHA1 | Date | |
---|---|---|---|
0c45a7705d | |||
5655c5f3b6 | |||
2a6713a038 | |||
ecd2d4af1d | |||
c0a14d59a1 | |||
73b1142c1e | |||
1b7fe7f7d0 | |||
41da54a27c | |||
649bb0452d | |||
9c0949930f | |||
2ecb40e6ee | |||
3490ce47bb | |||
bb912ae1b4 | |||
b3e10ce721 | |||
7e6800b3ef | |||
32422e5a62 | |||
75d4e6f65c |
3
LICENSE
3
LICENSE
@ -1,6 +1,7 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2023 redphx
|
Copyright (c) 2023 redphx
|
||||||
|
Copyright (c) 2020 Phosphor Icons
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -19,3 +20,5 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
|
|
||||||
|
---
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name Better xCloud
|
// @name Better xCloud
|
||||||
// @namespace https://github.com/redphx
|
// @namespace https://github.com/redphx
|
||||||
// @version 3.0.1
|
// @version 3.0.2.1
|
||||||
// ==/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.0.1
|
// @version 3.0.2.1
|
||||||
// @description Improve Xbox Cloud Gaming (xCloud) experience
|
// @description Improve Xbox Cloud Gaming (xCloud) experience
|
||||||
// @author redphx
|
// @author redphx
|
||||||
// @license MIT
|
// @license MIT
|
||||||
@ -13,7 +13,7 @@
|
|||||||
// ==/UserScript==
|
// ==/UserScript==
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const SCRIPT_VERSION = '3.0.1';
|
const SCRIPT_VERSION = '3.0.2.1';
|
||||||
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;
|
||||||
@ -39,6 +39,14 @@ window.NATIVE_MKB_TITLES = [
|
|||||||
|
|
||||||
console.log(`[Better xCloud] readyState: ${document.readyState}`);
|
console.log(`[Better xCloud] readyState: ${document.readyState}`);
|
||||||
|
|
||||||
|
const BxEvent = {
|
||||||
|
JUMP_BACK_IN_READY: 'bx-jump-back-in-ready',
|
||||||
|
POPSTATE: 'bx-popstate',
|
||||||
|
|
||||||
|
STREAM_STARTING: 'bx-stream-starting',
|
||||||
|
STREAM_STARTED: 'bx-stream-started',
|
||||||
|
STREAM_STOPPED: 'bx-stream-stopped',
|
||||||
|
};
|
||||||
|
|
||||||
// Quickly create a tree of elements without having to use innerHTML
|
// Quickly create a tree of elements without having to use innerHTML
|
||||||
function createElement(elmName, props = {}) {
|
function createElement(elmName, props = {}) {
|
||||||
@ -82,6 +90,7 @@ function createElement(elmName, props = {}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const CE = createElement;
|
const CE = createElement;
|
||||||
|
window.BX_CE = CE;
|
||||||
const CTN = document.createTextNode.bind(document);
|
const CTN = document.createTextNode.bind(document);
|
||||||
|
|
||||||
|
|
||||||
@ -103,7 +112,7 @@ const createSvgIcon = (icon, strokeWidth=2) => {
|
|||||||
|
|
||||||
|
|
||||||
const createButton = options => {
|
const createButton = options => {
|
||||||
const $btn = CE('button', {'class': 'bx-button'});
|
const $btn = CE(options.url ? 'a' : 'button', {'class': 'bx-button'});
|
||||||
|
|
||||||
options.isPrimary && $btn.classList.add('bx-primary');
|
options.isPrimary && $btn.classList.add('bx-primary');
|
||||||
options.isDanger && $btn.classList.add('bx-danger');
|
options.isDanger && $btn.classList.add('bx-danger');
|
||||||
@ -113,6 +122,11 @@ const createButton = options => {
|
|||||||
options.title && $btn.setAttribute('title', options.title);
|
options.title && $btn.setAttribute('title', options.title);
|
||||||
options.onClick && $btn.addEventListener('click', options.onClick);
|
options.onClick && $btn.addEventListener('click', options.onClick);
|
||||||
|
|
||||||
|
if (options.url) {
|
||||||
|
$btn.href = options.url;
|
||||||
|
$btn.target = '_blank';
|
||||||
|
}
|
||||||
|
|
||||||
return $btn;
|
return $btn;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -677,7 +691,7 @@ const Translations = {
|
|||||||
"es-ES": "Contrapeso de la zona muerta",
|
"es-ES": "Contrapeso de la zona muerta",
|
||||||
"ja-JP": "デッドゾーンのカウンターウエイト",
|
"ja-JP": "デッドゾーンのカウンターウエイト",
|
||||||
"pt-BR": "Contador da Zona Morta",
|
"pt-BR": "Contador da Zona Morta",
|
||||||
"ru-RU": "Противовес мертвой зоны",
|
"ru-RU": "Противодействие мертвой зоне игры",
|
||||||
"tr-TR": "Ölü alan denge ağırlığı",
|
"tr-TR": "Ölü alan denge ağırlığı",
|
||||||
"uk-UA": "Противага Deadzone",
|
"uk-UA": "Противага Deadzone",
|
||||||
"vi-VN": "Đối trọng vùng chết",
|
"vi-VN": "Đối trọng vùng chết",
|
||||||
@ -999,6 +1013,14 @@ const Translations = {
|
|||||||
"vi-VN": "Đang lấy danh sách các console...",
|
"vi-VN": "Đang lấy danh sách các console...",
|
||||||
"zh-CN": "正在获取控制台列表...",
|
"zh-CN": "正在获取控制台列表...",
|
||||||
},
|
},
|
||||||
|
"help": {
|
||||||
|
"de-DE": "Hilfe",
|
||||||
|
"en-US": "Help",
|
||||||
|
"ja-JP": "ヘルプ",
|
||||||
|
"pt-BR": "Ajuda",
|
||||||
|
"ru-RU": "Справка",
|
||||||
|
"vi-VN": "Trợ giúp",
|
||||||
|
},
|
||||||
"hide-idle-cursor": {
|
"hide-idle-cursor": {
|
||||||
"de-DE": "Mauszeiger bei Inaktivität ausblenden",
|
"de-DE": "Mauszeiger bei Inaktivität ausblenden",
|
||||||
"en-US": "Hide mouse cursor on idle",
|
"en-US": "Hide mouse cursor on idle",
|
||||||
@ -1145,21 +1167,6 @@ const Translations = {
|
|||||||
"uk-UA": "Прив'язати мишу до",
|
"uk-UA": "Прив'язати мишу до",
|
||||||
"vi-VN": "Gán chuột với",
|
"vi-VN": "Gán chuột với",
|
||||||
},
|
},
|
||||||
"max-bitrate": {
|
|
||||||
"de-DE": "Max. Bitrate",
|
|
||||||
"en-US": "Max bitrate",
|
|
||||||
"es-ES": "Tasa de bits máxima",
|
|
||||||
"it-IT": "Bitrate massimo",
|
|
||||||
"ja-JP": "最大ビットレート",
|
|
||||||
"ko-KR": "최대 비트레이트",
|
|
||||||
"pl-PL": "Maksymalny bitrate",
|
|
||||||
"pt-BR": "Taxa máxima dos bits",
|
|
||||||
"ru-RU": "Максимальный битрейт",
|
|
||||||
"tr-TR": "Maksimum bithızı",
|
|
||||||
"uk-UA": "Максимальний бітрейт",
|
|
||||||
"vi-VN": "Bitrate tối đa",
|
|
||||||
"zh-CN": "最大比特率",
|
|
||||||
},
|
|
||||||
"may-not-work-properly": {
|
"may-not-work-properly": {
|
||||||
"de-DE": "Funktioniert evtl. nicht fehlerfrei!",
|
"de-DE": "Funktioniert evtl. nicht fehlerfrei!",
|
||||||
"en-US": "May not work properly!",
|
"en-US": "May not work properly!",
|
||||||
@ -2119,6 +2126,7 @@ const Translations = {
|
|||||||
"en-US": "Stick decay minimum",
|
"en-US": "Stick decay minimum",
|
||||||
"ja-JP": "スティックの減衰の最小値",
|
"ja-JP": "スティックの減衰の最小値",
|
||||||
"pt-BR": "Mínimo decaimento do analógico",
|
"pt-BR": "Mínimo decaimento do analógico",
|
||||||
|
"ru-RU": "Минимальная перезарядка стика",
|
||||||
"tr-TR": "Çubuğun ortalanma süresi minimumu",
|
"tr-TR": "Çubuğun ortalanma süresi minimumu",
|
||||||
"vi-VN": "Độ suy giảm tối thiểu của cần điều khiển",
|
"vi-VN": "Độ suy giảm tối thiểu của cần điều khiển",
|
||||||
},
|
},
|
||||||
@ -2127,6 +2135,7 @@ const Translations = {
|
|||||||
"en-US": "Stick decay strength",
|
"en-US": "Stick decay strength",
|
||||||
"ja-JP": "スティックの減衰の強さ",
|
"ja-JP": "スティックの減衰の強さ",
|
||||||
"pt-BR": "Força de decaimento do analógico",
|
"pt-BR": "Força de decaimento do analógico",
|
||||||
|
"ru-RU": "Скорость перезарядки стика",
|
||||||
"tr-TR": "Çubuğun ortalanma gücü",
|
"tr-TR": "Çubuğun ortalanma gücü",
|
||||||
"vi-VN": "Sức mạnh độ suy giảm của cần điều khiển",
|
"vi-VN": "Sức mạnh độ suy giảm của cần điều khiển",
|
||||||
},
|
},
|
||||||
@ -2717,7 +2726,9 @@ const Icon = {
|
|||||||
COPY: '<path d="M1.498 6.772h23.73v23.73H1.498zm5.274-5.274h23.73v23.73"/>',
|
COPY: '<path d="M1.498 6.772h23.73v23.73H1.498zm5.274-5.274h23.73v23.73"/>',
|
||||||
TRASH: '<path d="M29.5 6.182h-27m9.818 7.363v9.818m7.364-9.818v9.818"/><path d="M27.045 6.182V29.5c0 .673-.554 1.227-1.227 1.227H6.182c-.673 0-1.227-.554-1.227-1.227V6.182m17.181 0V3.727a2.47 2.47 0 0 0-2.455-2.455h-7.364a2.47 2.47 0 0 0-2.455 2.455v2.455"/>',
|
TRASH: '<path d="M29.5 6.182h-27m9.818 7.363v9.818m7.364-9.818v9.818"/><path d="M27.045 6.182V29.5c0 .673-.554 1.227-1.227 1.227H6.182c-.673 0-1.227-.554-1.227-1.227V6.182m17.181 0V3.727a2.47 2.47 0 0 0-2.455-2.455h-7.364a2.47 2.47 0 0 0-2.455 2.455v2.455"/>',
|
||||||
CURSOR_TEXT: '<path d="M16 7.3a5.83 5.83 0 0 1 5.8-5.8h2.9m0 29h-2.9a5.83 5.83 0 0 1-5.8-5.8"/><path d="M7.3 30.5h2.9a5.83 5.83 0 0 0 5.8-5.8V7.3a5.83 5.83 0 0 0-5.8-5.8H7.3"/><path d="M11.65 16h8.7"/>',
|
CURSOR_TEXT: '<path d="M16 7.3a5.83 5.83 0 0 1 5.8-5.8h2.9m0 29h-2.9a5.83 5.83 0 0 1-5.8-5.8"/><path d="M7.3 30.5h2.9a5.83 5.83 0 0 0 5.8-5.8V7.3a5.83 5.83 0 0 0-5.8-5.8H7.3"/><path d="M11.65 16h8.7"/>',
|
||||||
INFO: '<g transform="matrix(.153399 0 0 .153398 -3.63501 -3.635009)"><g fill="none" stroke="#fff" stroke-width="16"><circle cx="128" cy="128" r="96"/><path d="M120 120c4.389 0 8 3.611 8 8v40c0 4.389 3.611 8 8 8"/></g><circle cx="124" cy="84" r="12" stroke-width="6"/></g>',
|
QUESTION: '<g transform="matrix(.256867 0 0 .256867 -16.878964 -18.049342)"><circle cx="128" cy="180" r="12" fill="#fff"/><path d="M128 144v-8c17.67 0 32-12.54 32-28s-14.33-28-32-28-32 12.54-32 28v4" fill="none" stroke="#fff" stroke-width="16"/></g>',
|
||||||
|
|
||||||
|
REMOTE_PLAY: '<g transform="matrix(.492308 0 0 .581818 -14.7692 -11.6364)"><clipPath id="A"><path d="M30 20h65v55H30z"/></clipPath><g clip-path="url(#A)"><g transform="matrix(.395211 0 0 .334409 11.913 7.01124)"><g transform="matrix(.555556 0 0 .555556 57.8889 -20.2417)" fill="none" stroke="#fff" stroke-width="13.88"><path d="M200 140.564c-42.045-33.285-101.955-33.285-144 0M168 165c-23.783-17.3-56.217-17.3-80 0"/></g><g transform="matrix(-.555556 0 0 -.555556 200.111 262.393)"><g transform="matrix(1 0 0 1 0 11.5642)"><path d="M200 129c-17.342-13.728-37.723-21.795-58.636-24.198C111.574 101.378 80.703 109.444 56 129" fill="none" stroke="#fff" stroke-width="13.88"/></g><path d="M168 165c-23.783-17.3-56.217-17.3-80 0" fill="none" stroke="#fff" stroke-width="13.88"/></g><g transform="matrix(.75 0 0 .75 32 32)"><path d="M24 72h208v93.881H24z" fill="none" stroke="#fff" stroke-linejoin="miter" stroke-width="9.485"/><circle cx="188" cy="128" r="12" stroke-width="10" transform="matrix(.708333 0 0 .708333 71.8333 12.8333)"/><path d="M24.358 103.5h110" fill="none" stroke="#fff" stroke-linecap="butt" stroke-width="10.282"/></g></g></g></g>',
|
||||||
|
|
||||||
SCREENSHOT_B64: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDMyIDMyIiBmaWxsPSIjZmZmIj48cGF0aCBkPSJNMjguMzA4IDUuMDM4aC00LjI2NWwtMi4wOTctMy4xNDVhMS4yMyAxLjIzIDAgMCAwLTEuMDIzLS41NDhoLTkuODQ2YTEuMjMgMS4yMyAwIDAgMC0xLjAyMy41NDhMNy45NTYgNS4wMzhIMy42OTJBMy43MSAzLjcxIDAgMCAwIDAgOC43MzF2MTcuMjMxYTMuNzEgMy43MSAwIDAgMCAzLjY5MiAzLjY5MmgyNC42MTVBMy43MSAzLjcxIDAgMCAwIDMyIDI1Ljk2MlY4LjczMWEzLjcxIDMuNzEgMCAwIDAtMy42OTItMy42OTJ6bS02Ljc2OSAxMS42OTJjMCAzLjAzOS0yLjUgNS41MzgtNS41MzggNS41MzhzLTUuNTM4LTIuNS01LjUzOC01LjUzOCAyLjUtNS41MzggNS41MzgtNS41MzggNS41MzggMi41IDUuNTM4IDUuNTM4eiIvPjwvc3ZnPgo=',
|
SCREENSHOT_B64: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDMyIDMyIiBmaWxsPSIjZmZmIj48cGF0aCBkPSJNMjguMzA4IDUuMDM4aC00LjI2NWwtMi4wOTctMy4xNDVhMS4yMyAxLjIzIDAgMCAwLTEuMDIzLS41NDhoLTkuODQ2YTEuMjMgMS4yMyAwIDAgMC0xLjAyMy41NDhMNy45NTYgNS4wMzhIMy42OTJBMy43MSAzLjcxIDAgMCAwIDAgOC43MzF2MTcuMjMxYTMuNzEgMy43MSAwIDAgMCAzLjY5MiAzLjY5MmgyNC42MTVBMy43MSAzLjcxIDAgMCAwIDMyIDI1Ljk2MlY4LjczMWEzLjcxIDMuNzEgMCAwIDAtMy42OTItMy42OTJ6bS02Ljc2OSAxMS42OTJjMCAzLjAzOS0yLjUgNS41MzgtNS41MzggNS41MzhzLTUuNTM4LTIuNS01LjUzOC01LjUzOCAyLjUtNS41MzggNS41MzgtNS41MzggNS41MzggMi41IDUuNTM4IDUuNTM4eiIvPjwvc3ZnPgo=',
|
||||||
};
|
};
|
||||||
@ -2731,6 +2742,7 @@ class Dialog {
|
|||||||
content,
|
content,
|
||||||
hideCloseButton,
|
hideCloseButton,
|
||||||
onClose,
|
onClose,
|
||||||
|
helpUrl,
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
// Create dialog overlay
|
// Create dialog overlay
|
||||||
@ -2747,7 +2759,9 @@ class Dialog {
|
|||||||
let $close;
|
let $close;
|
||||||
this.onClose = onClose;
|
this.onClose = onClose;
|
||||||
this.$dialog = CE('div', {'class': `bx-dialog ${className || ''} bx-gone`},
|
this.$dialog = CE('div', {'class': `bx-dialog ${className || ''} bx-gone`},
|
||||||
this.$title = CE('b', {}, title),
|
this.$title = CE('h2', {}, CE('b', {}, title),
|
||||||
|
helpUrl && createButton({icon: Icon.QUESTION, isGhost: true, title: __('help'), url: helpUrl}),
|
||||||
|
),
|
||||||
this.$content = CE('div', {'class': 'bx-dialog-content'}, content),
|
this.$content = CE('div', {'class': 'bx-dialog-content'}, content),
|
||||||
!hideCloseButton && ($close = CE('button', {}, __('close'))),
|
!hideCloseButton && ($close = CE('button', {}, __('close'))),
|
||||||
);
|
);
|
||||||
@ -2767,7 +2781,7 @@ class Dialog {
|
|||||||
|
|
||||||
show(newOptions) {
|
show(newOptions) {
|
||||||
if (newOptions && newOptions.title) {
|
if (newOptions && newOptions.title) {
|
||||||
this.$title.textContent = newOptions.title;
|
this.$title.querySelector('b').textContent = newOptions.title;
|
||||||
this.$title.classList.remove('bx-gone');
|
this.$title.classList.remove('bx-gone');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2859,6 +2873,7 @@ class RemotePlay {
|
|||||||
RemotePlay.#dialog = new Dialog({
|
RemotePlay.#dialog = new Dialog({
|
||||||
title: __('remote-play'),
|
title: __('remote-play'),
|
||||||
content: RemotePlay.#$content,
|
content: RemotePlay.#$content,
|
||||||
|
helpUrl: 'https://better-xcloud.github.io/remote-play/',
|
||||||
});
|
});
|
||||||
|
|
||||||
RemotePlay.#getXhomeToken(() => {
|
RemotePlay.#getXhomeToken(() => {
|
||||||
@ -3181,10 +3196,12 @@ class LoadingScreen {
|
|||||||
let $waitTimeBox = LoadingScreen.#$waitTimeBox;
|
let $waitTimeBox = LoadingScreen.#$waitTimeBox;
|
||||||
if (!$waitTimeBox) {
|
if (!$waitTimeBox) {
|
||||||
$waitTimeBox = CE('div', {'class': 'bx-wait-time-box'},
|
$waitTimeBox = CE('div', {'class': 'bx-wait-time-box'},
|
||||||
|
CE('label', {}, __('server')),
|
||||||
|
CE('span', {}, getPreferredServerRegion()),
|
||||||
CE('label', {}, __('wait-time-estimated')),
|
CE('label', {}, __('wait-time-estimated')),
|
||||||
$estimated = CE('span', {'class': 'bx-wait-time-estimated'}),
|
$estimated = CE('span', {}),
|
||||||
CE('label', {}, __('wait-time-countdown')),
|
CE('label', {}, __('wait-time-countdown')),
|
||||||
$countDown = CE('span', {'class': 'bx-wait-time-countdown'}),
|
$countDown = CE('span', {}),
|
||||||
);
|
);
|
||||||
|
|
||||||
document.documentElement.appendChild($waitTimeBox);
|
document.documentElement.appendChild($waitTimeBox);
|
||||||
@ -4766,7 +4783,7 @@ class MkbRemapper {
|
|||||||
// Update state of Activate button
|
// Update state of Activate button
|
||||||
const activated = PREFS.get(Preferences.MKB_DEFAULT_PRESET_ID) === this.#STATE.currentPresetId;
|
const activated = PREFS.get(Preferences.MKB_DEFAULT_PRESET_ID) === this.#STATE.currentPresetId;
|
||||||
this.#$.activateButton.disabled = activated;
|
this.#$.activateButton.disabled = activated;
|
||||||
this.#$.activateButton.textContent = activated ? __('activated') : __('activate');
|
this.#$.activateButton.querySelector('span').textContent = activated ? __('activated') : __('activate');
|
||||||
}
|
}
|
||||||
|
|
||||||
#refresh() {
|
#refresh() {
|
||||||
@ -4811,7 +4828,7 @@ class MkbRemapper {
|
|||||||
// Update state of Activate button
|
// Update state of Activate button
|
||||||
const activated = defaultPresetId === this.#STATE.currentPresetId;
|
const activated = defaultPresetId === this.#STATE.currentPresetId;
|
||||||
this.#$.activateButton.disabled = activated;
|
this.#$.activateButton.disabled = activated;
|
||||||
this.#$.activateButton.textContent = activated ? __('activated') : __('activate');
|
this.#$.activateButton.querySelector('span').textContent = activated ? __('activated') : __('activate');
|
||||||
|
|
||||||
!this.#STATE.isEditing && this.#switchPreset(this.#STATE.currentPresetId);
|
!this.#STATE.isEditing && this.#switchPreset(this.#STATE.currentPresetId);
|
||||||
});
|
});
|
||||||
@ -6203,7 +6220,7 @@ class Preferences {
|
|||||||
'default': true,
|
'default': true,
|
||||||
},
|
},
|
||||||
[Preferences.UI_LOADING_SCREEN_WAIT_TIME]: {
|
[Preferences.UI_LOADING_SCREEN_WAIT_TIME]: {
|
||||||
'default': false,
|
'default': true,
|
||||||
},
|
},
|
||||||
[Preferences.UI_LOADING_SCREEN_ROCKET]: {
|
[Preferences.UI_LOADING_SCREEN_ROCKET]: {
|
||||||
'default': 'show',
|
'default': 'show',
|
||||||
@ -6772,13 +6789,13 @@ if (window.BX_VIBRATION_INTENSITY && window.BX_VIBRATION_INTENSITY < 1) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static #PATCH_ORDERS = [
|
static #PATCH_ORDERS = [
|
||||||
['disableStreamGate'],
|
|
||||||
|
|
||||||
[
|
[
|
||||||
'disableAiTrack',
|
'disableAiTrack',
|
||||||
'disableTelemetry',
|
'disableTelemetry',
|
||||||
],
|
],
|
||||||
|
|
||||||
|
['disableStreamGate'],
|
||||||
|
|
||||||
['tvLayout'],
|
['tvLayout'],
|
||||||
|
|
||||||
['enableXcloudLogger'],
|
['enableXcloudLogger'],
|
||||||
@ -7035,7 +7052,6 @@ function addCss() {
|
|||||||
--bx-danger-button-hover-color: #e61d1d;
|
--bx-danger-button-hover-color: #e61d1d;
|
||||||
--bx-danger-button-disabled-color: #a26c6c;
|
--bx-danger-button-disabled-color: #a26c6c;
|
||||||
|
|
||||||
|
|
||||||
--bx-toast-z-index: 9999;
|
--bx-toast-z-index: 9999;
|
||||||
--bx-dialog-z-index: 9101;
|
--bx-dialog-z-index: 9101;
|
||||||
--bx-dialog-overlay-z-index: 9100;
|
--bx-dialog-overlay-z-index: 9100;
|
||||||
@ -7061,6 +7077,10 @@ div[class^=HUDButton-module__hiddenContainer] ~ div:not([class^=HUDButton-module
|
|||||||
left: -9999px;
|
left: -9999px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a.bx-button {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
.bx-button {
|
.bx-button {
|
||||||
background-color: var(--bx-default-button-color);
|
background-color: var(--bx-default-button-color);
|
||||||
user-select: none;
|
user-select: none;
|
||||||
@ -7130,9 +7150,20 @@ div[class^=HUDButton-module__hiddenContainer] ~ div:not([class^=HUDButton-module
|
|||||||
|
|
||||||
.bx-button span {
|
.bx-button span {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
height: 32px;
|
height: 30px;
|
||||||
line-height: 32px;
|
line-height: 32px;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bx-remote-play-button {
|
||||||
|
height: auto;
|
||||||
|
margin-right: 8px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bx-remote-play-button svg {
|
||||||
|
width: 32px;
|
||||||
|
height: 46px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bx-settings-button {
|
.bx-settings-button {
|
||||||
@ -7143,6 +7174,7 @@ div[class^=HUDButton-module__hiddenContainer] ~ div:not([class^=HUDButton-module
|
|||||||
line-height: 30px;
|
line-height: 30px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bx-settings-button:hover, .bx-settings-button:focus {
|
.bx-settings-button:hover, .bx-settings-button:focus {
|
||||||
@ -7561,17 +7593,22 @@ div[class*=StreamMenu-module__menuContainer] > div[class*=Menu-module] {
|
|||||||
outline: none !important;
|
outline: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bx-dialog > b {
|
.bx-dialog h2 {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bx-dialog h2 b {
|
||||||
|
flex: 1;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
display: block;
|
display: block;
|
||||||
font-family: var(--bx-title-font);
|
font-family: var(--bx-title-font);
|
||||||
font-size: 26px;
|
font-size: 26px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
line-height: 32px;
|
line-height: 32px;
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.bx-dialog.bx-binding-dialog > b {
|
.bx-dialog.bx-binding-dialog h2 b {
|
||||||
font-family: var(--bx-promptfont-font) !important;
|
font-family: var(--bx-promptfont-font) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7582,7 +7619,7 @@ div[class*=StreamMenu-module__menuContainer] > div[class*=Menu-module] {
|
|||||||
|
|
||||||
.bx-dialog > button {
|
.bx-dialog > button {
|
||||||
padding: 8px 32px;
|
padding: 8px 32px;
|
||||||
margin: 20px auto 0;
|
margin: 10px auto 0;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
display: block;
|
display: block;
|
||||||
@ -7722,20 +7759,23 @@ div[class*=StreamMenu-module__menuContainer] > div[class*=Menu-module] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.bx-quick-settings-tab-contents h2 {
|
.bx-quick-settings-tab-contents h2 {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
display: flex;
|
||||||
|
align-item: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bx-quick-settings-tab-contents h2 span {
|
||||||
|
display: inline-block;
|
||||||
font-size: 28px;
|
font-size: 28px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
margin-bottom: 8px;
|
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
display: flex;
|
flex: 1;
|
||||||
|
height: 32px;
|
||||||
|
line-height: 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bx-quick-settings-tab-contents h2 a {
|
.bx-quick-settings-tab-contents h2 a {
|
||||||
display: flex;
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
margin-left: 8px;
|
|
||||||
align-selft: flex-start;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.bx-quick-settings-tab-contents input[type="range"] {
|
.bx-quick-settings-tab-contents input[type="range"] {
|
||||||
@ -8034,15 +8074,16 @@ div[class*=StreamMenu-module__menuContainer] > div[class*=Menu-module] {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bx-wait-time-estimated, .bx-wait-time-countdown {
|
.bx-wait-time-box span {
|
||||||
display: block;
|
display: block;
|
||||||
font-family: var(--bx-monospaced-font);
|
font-family: var(--bx-monospaced-font);
|
||||||
text-align: right;
|
text-align: right;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bx-wait-time-estimated {
|
.bx-wait-time-box span:last-of-type {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* REMOTE PLAY */
|
/* REMOTE PLAY */
|
||||||
@ -8092,11 +8133,11 @@ div[class*=StreamMenu-module__menuContainer] > div[class*=Menu-module] {
|
|||||||
|
|
||||||
.bx-remote-play-device-wrapper {
|
.bx-remote-play-device-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bx-remote-play-device-wrapper:not(:last-child) {
|
.bx-remote-play-device-wrapper:last-child {
|
||||||
margin-bottom: 14px;
|
margin-bottom: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bx-remote-play-device-info {
|
.bx-remote-play-device-info {
|
||||||
@ -8348,12 +8389,14 @@ function clearDbLogs(dbName, table) {
|
|||||||
request.onsuccess = e => {
|
request.onsuccess = e => {
|
||||||
const db = e.target.result;
|
const db = e.target.result;
|
||||||
|
|
||||||
const objectStore = db.transaction(table, 'readwrite').objectStore(table);
|
try {
|
||||||
const objectStoreRequest = objectStore.clear();
|
const objectStore = db.transaction(table, 'readwrite').objectStore(table);
|
||||||
|
const objectStoreRequest = objectStore.clear();
|
||||||
|
|
||||||
objectStoreRequest.onsuccess = function(event) {
|
objectStoreRequest.onsuccess = function(event) {
|
||||||
console.log(`[Better xCloud] Cleared ${dbName}.${table}`);
|
console.log(`[Better xCloud] Cleared ${dbName}.${table}`);
|
||||||
};
|
};
|
||||||
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8786,7 +8829,23 @@ function injectSettingsButton($parent) {
|
|||||||
|
|
||||||
const PREF_PREFERRED_REGION = getPreferredServerRegion();
|
const PREF_PREFERRED_REGION = getPreferredServerRegion();
|
||||||
const PREF_LATEST_VERSION = PREFS.get(Preferences.LATEST_VERSION);
|
const PREF_LATEST_VERSION = PREFS.get(Preferences.LATEST_VERSION);
|
||||||
const PREF_REMOTE_PLAY_ENABLED = PREFS.get(Preferences.REMOTE_PLAY_ENABLED);
|
|
||||||
|
// Remote Play button
|
||||||
|
if (PREFS.get(Preferences.REMOTE_PLAY_ENABLED)) {
|
||||||
|
const $remotePlayBtn = createButton({
|
||||||
|
icon: Icon.REMOTE_PLAY,
|
||||||
|
title: __('remote-play'),
|
||||||
|
isGhost: true,
|
||||||
|
isRound: true,
|
||||||
|
onClick: e => {
|
||||||
|
RemotePlay.showDialog();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
$remotePlayBtn.classList.add('bx-remote-play-button', 'bx-focusable');
|
||||||
|
|
||||||
|
$parent.appendChild($remotePlayBtn);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Setup Settings button
|
// Setup Settings button
|
||||||
const $button = CE('button', {'class': 'bx-settings-button'}, PREF_PREFERRED_REGION);
|
const $button = CE('button', {'class': 'bx-settings-button'}, PREF_PREFERRED_REGION);
|
||||||
@ -8810,7 +8869,7 @@ function injectSettingsButton($parent) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let $updateAvailable;
|
let $updateAvailable;
|
||||||
let $remotePlayBtn;
|
|
||||||
const $wrapper = CE('div', {'class': 'bx-settings-wrapper'},
|
const $wrapper = CE('div', {'class': 'bx-settings-wrapper'},
|
||||||
CE('div', {'class': 'bx-settings-title-wrapper'},
|
CE('div', {'class': 'bx-settings-title-wrapper'},
|
||||||
CE('a', {
|
CE('a', {
|
||||||
@ -8818,7 +8877,7 @@ function injectSettingsButton($parent) {
|
|||||||
'href': SCRIPT_HOME,
|
'href': SCRIPT_HOME,
|
||||||
'target': '_blank',
|
'target': '_blank',
|
||||||
}, 'Better xCloud ' + SCRIPT_VERSION),
|
}, 'Better xCloud ' + SCRIPT_VERSION),
|
||||||
$remotePlayBtn = CE('button', {'class': 'bx-primary-button bx-no-margin'}, __('remote-play')),
|
createButton({icon: Icon.QUESTION, label: __('help'), url: 'https://better-xcloud.github.io/features/'}),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$updateAvailable = CE('a', {
|
$updateAvailable = CE('a', {
|
||||||
@ -8827,17 +8886,6 @@ function injectSettingsButton($parent) {
|
|||||||
'target': '_blank',
|
'target': '_blank',
|
||||||
});
|
});
|
||||||
|
|
||||||
if (PREF_REMOTE_PLAY_ENABLED) {
|
|
||||||
$remotePlayBtn.addEventListener('click', e => {
|
|
||||||
RemotePlay.showDialog();
|
|
||||||
|
|
||||||
// Hide Settings
|
|
||||||
$container.classList.add('bx-gone');
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
$remotePlayBtn.classList.add('bx-gone');
|
|
||||||
}
|
|
||||||
|
|
||||||
$wrapper.appendChild($updateAvailable);
|
$wrapper.appendChild($updateAvailable);
|
||||||
|
|
||||||
// Show new version indicator
|
// Show new version indicator
|
||||||
@ -9682,8 +9730,8 @@ function setupQuickSettingsBar() {
|
|||||||
|
|
||||||
for (const settingGroup of settingTab.items) {
|
for (const settingGroup of settingTab.items) {
|
||||||
$group.appendChild(CE('h2', {},
|
$group.appendChild(CE('h2', {},
|
||||||
settingGroup.label,
|
CE('span', {}, settingGroup.label),
|
||||||
settingGroup.help_url && CE('a', {href: settingGroup.help_url, target: '_blank'}, createSvgIcon(Icon.INFO, 4)),
|
settingGroup.help_url && createButton({icon: Icon.QUESTION, isGhost: true, url: settingGroup.help_url, title: __('help')}),
|
||||||
));
|
));
|
||||||
if (settingGroup.note) {
|
if (settingGroup.note) {
|
||||||
if (typeof settingGroup.note === 'string') {
|
if (typeof settingGroup.note === 'string') {
|
||||||
@ -9806,9 +9854,10 @@ function setupScreenshotButton() {
|
|||||||
|
|
||||||
|
|
||||||
function patchHistoryMethod(type) {
|
function patchHistoryMethod(type) {
|
||||||
var orig = window.history[type];
|
const orig = window.history[type];
|
||||||
|
|
||||||
return function(...args) {
|
return function(...args) {
|
||||||
const event = new Event('xcloud_popstate');
|
const event = new Event(BxEvent.POPSTATE);
|
||||||
event.arguments = args;
|
event.arguments = args;
|
||||||
window.dispatchEvent(event);
|
window.dispatchEvent(event);
|
||||||
|
|
||||||
@ -10025,9 +10074,10 @@ function setupBxUi() {
|
|||||||
|
|
||||||
|
|
||||||
// Hide Settings UI when navigate to another page
|
// Hide Settings UI when navigate to another page
|
||||||
window.addEventListener('xcloud_popstate', onHistoryChanged);
|
window.addEventListener(BxEvent.POPSTATE, onHistoryChanged);
|
||||||
window.addEventListener('popstate', onHistoryChanged);
|
window.addEventListener('popstate', onHistoryChanged);
|
||||||
// Make pushState/replaceState methods dispatch "xcloud_popstate" event
|
|
||||||
|
// Make pushState/replaceState methods dispatch BxEvent.POPSTATE event
|
||||||
window.history.pushState = patchHistoryMethod('pushState');
|
window.history.pushState = patchHistoryMethod('pushState');
|
||||||
window.history.replaceState = patchHistoryMethod('replaceState');
|
window.history.replaceState = patchHistoryMethod('replaceState');
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user