mirror of
https://github.com/redphx/better-xcloud.git
synced 2025-06-28 18:31:44 +02:00
Compare commits
14 Commits
Author | SHA1 | Date | |
---|---|---|---|
ecd2d4af1d | |||
c0a14d59a1 | |||
73b1142c1e | |||
1b7fe7f7d0 | |||
41da54a27c | |||
649bb0452d | |||
9c0949930f | |||
2ecb40e6ee | |||
3490ce47bb | |||
bb912ae1b4 | |||
b3e10ce721 | |||
7e6800b3ef | |||
32422e5a62 | |||
75d4e6f65c |
3
LICENSE
3
LICENSE
@ -1,6 +1,7 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 redphx
|
||||
Copyright (c) 2020 Phosphor Icons
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
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,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
---
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ==UserScript==
|
||||
// @name Better xCloud
|
||||
// @namespace https://github.com/redphx
|
||||
// @version 3.0.1
|
||||
// @version 3.0.2
|
||||
// ==/UserScript==
|
||||
|
@ -1,7 +1,7 @@
|
||||
// ==UserScript==
|
||||
// @name Better xCloud
|
||||
// @namespace https://github.com/redphx
|
||||
// @version 3.0.1
|
||||
// @version 3.0.2
|
||||
// @description Improve Xbox Cloud Gaming (xCloud) experience
|
||||
// @author redphx
|
||||
// @license MIT
|
||||
@ -13,7 +13,7 @@
|
||||
// ==/UserScript==
|
||||
'use strict';
|
||||
|
||||
const SCRIPT_VERSION = '3.0.1';
|
||||
const SCRIPT_VERSION = '3.0.2';
|
||||
const SCRIPT_HOME = 'https://github.com/redphx/better-xcloud';
|
||||
|
||||
const ENABLE_XCLOUD_LOGGER = false;
|
||||
@ -39,6 +39,14 @@ window.NATIVE_MKB_TITLES = [
|
||||
|
||||
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
|
||||
function createElement(elmName, props = {}) {
|
||||
@ -82,6 +90,7 @@ function createElement(elmName, props = {}) {
|
||||
}
|
||||
|
||||
const CE = createElement;
|
||||
window.BX_CE = CE;
|
||||
const CTN = document.createTextNode.bind(document);
|
||||
|
||||
|
||||
@ -103,7 +112,7 @@ const createSvgIcon = (icon, strokeWidth=2) => {
|
||||
|
||||
|
||||
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.isDanger && $btn.classList.add('bx-danger');
|
||||
@ -113,6 +122,11 @@ const createButton = options => {
|
||||
options.title && $btn.setAttribute('title', options.title);
|
||||
options.onClick && $btn.addEventListener('click', options.onClick);
|
||||
|
||||
if (options.url) {
|
||||
$btn.href = options.url;
|
||||
$btn.target = '_blank';
|
||||
}
|
||||
|
||||
return $btn;
|
||||
}
|
||||
|
||||
@ -677,7 +691,7 @@ const Translations = {
|
||||
"es-ES": "Contrapeso de la zona muerta",
|
||||
"ja-JP": "デッドゾーンのカウンターウエイト",
|
||||
"pt-BR": "Contador da Zona Morta",
|
||||
"ru-RU": "Противовес мертвой зоны",
|
||||
"ru-RU": "Противодействие мертвой зоне игры",
|
||||
"tr-TR": "Ölü alan denge ağırlığı",
|
||||
"uk-UA": "Противага Deadzone",
|
||||
"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...",
|
||||
"zh-CN": "正在获取控制台列表...",
|
||||
},
|
||||
"help": {
|
||||
"de-DE": "Hilfe",
|
||||
"en-US": "Help",
|
||||
"ja-JP": "ヘルプ",
|
||||
"pt-BR": "Ajuda",
|
||||
"ru-RU": "Справка",
|
||||
"vi-VN": "Trợ giúp",
|
||||
},
|
||||
"hide-idle-cursor": {
|
||||
"de-DE": "Mauszeiger bei Inaktivität ausblenden",
|
||||
"en-US": "Hide mouse cursor on idle",
|
||||
@ -1145,21 +1167,6 @@ const Translations = {
|
||||
"uk-UA": "Прив'язати мишу до",
|
||||
"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": {
|
||||
"de-DE": "Funktioniert evtl. nicht fehlerfrei!",
|
||||
"en-US": "May not work properly!",
|
||||
@ -2119,6 +2126,7 @@ const Translations = {
|
||||
"en-US": "Stick decay minimum",
|
||||
"ja-JP": "スティックの減衰の最小値",
|
||||
"pt-BR": "Mínimo decaimento do analógico",
|
||||
"ru-RU": "Минимальная перезарядка стика",
|
||||
"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",
|
||||
},
|
||||
@ -2127,6 +2135,7 @@ const Translations = {
|
||||
"en-US": "Stick decay strength",
|
||||
"ja-JP": "スティックの減衰の強さ",
|
||||
"pt-BR": "Força de decaimento do analógico",
|
||||
"ru-RU": "Скорость перезарядки стика",
|
||||
"tr-TR": "Çubuğun ortalanma gücü",
|
||||
"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"/>',
|
||||
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"/>',
|
||||
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=',
|
||||
};
|
||||
@ -2731,6 +2742,7 @@ class Dialog {
|
||||
content,
|
||||
hideCloseButton,
|
||||
onClose,
|
||||
helpUrl,
|
||||
} = options;
|
||||
|
||||
// Create dialog overlay
|
||||
@ -2747,7 +2759,9 @@ class Dialog {
|
||||
let $close;
|
||||
this.onClose = onClose;
|
||||
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),
|
||||
!hideCloseButton && ($close = CE('button', {}, __('close'))),
|
||||
);
|
||||
@ -2767,7 +2781,7 @@ class Dialog {
|
||||
|
||||
show(newOptions) {
|
||||
if (newOptions && newOptions.title) {
|
||||
this.$title.textContent = newOptions.title;
|
||||
this.$title.querySelector('b').textContent = newOptions.title;
|
||||
this.$title.classList.remove('bx-gone');
|
||||
}
|
||||
|
||||
@ -2859,6 +2873,7 @@ class RemotePlay {
|
||||
RemotePlay.#dialog = new Dialog({
|
||||
title: __('remote-play'),
|
||||
content: RemotePlay.#$content,
|
||||
helpUrl: 'https://better-xcloud.github.io/remote-play/',
|
||||
});
|
||||
|
||||
RemotePlay.#getXhomeToken(() => {
|
||||
@ -3181,10 +3196,12 @@ class LoadingScreen {
|
||||
let $waitTimeBox = LoadingScreen.#$waitTimeBox;
|
||||
if (!$waitTimeBox) {
|
||||
$waitTimeBox = CE('div', {'class': 'bx-wait-time-box'},
|
||||
CE('label', {}, __('server')),
|
||||
CE('span', {}, getPreferredServerRegion()),
|
||||
CE('label', {}, __('wait-time-estimated')),
|
||||
$estimated = CE('span', {'class': 'bx-wait-time-estimated'}),
|
||||
$estimated = CE('span', {}),
|
||||
CE('label', {}, __('wait-time-countdown')),
|
||||
$countDown = CE('span', {'class': 'bx-wait-time-countdown'}),
|
||||
$countDown = CE('span', {}),
|
||||
);
|
||||
|
||||
document.documentElement.appendChild($waitTimeBox);
|
||||
@ -4766,7 +4783,7 @@ class MkbRemapper {
|
||||
// Update state of Activate button
|
||||
const activated = PREFS.get(Preferences.MKB_DEFAULT_PRESET_ID) === this.#STATE.currentPresetId;
|
||||
this.#$.activateButton.disabled = activated;
|
||||
this.#$.activateButton.textContent = activated ? __('activated') : __('activate');
|
||||
this.#$.activateButton.querySelector('span').textContent = activated ? __('activated') : __('activate');
|
||||
}
|
||||
|
||||
#refresh() {
|
||||
@ -4811,7 +4828,7 @@ class MkbRemapper {
|
||||
// Update state of Activate button
|
||||
const activated = defaultPresetId === this.#STATE.currentPresetId;
|
||||
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);
|
||||
});
|
||||
@ -6203,7 +6220,7 @@ class Preferences {
|
||||
'default': true,
|
||||
},
|
||||
[Preferences.UI_LOADING_SCREEN_WAIT_TIME]: {
|
||||
'default': false,
|
||||
'default': true,
|
||||
},
|
||||
[Preferences.UI_LOADING_SCREEN_ROCKET]: {
|
||||
'default': 'show',
|
||||
@ -6609,6 +6626,57 @@ class Patcher {
|
||||
return funcStr.replace(text, `connectMode:window.BX_REMOTE_PLAY_CONFIG?"xhome-connect":"cloud-connect",remotePlayServerId:(window.BX_REMOTE_PLAY_CONFIG&&window.BX_REMOTE_PLAY_CONFIG.serverId)||''`);
|
||||
},
|
||||
|
||||
// Add a "Remote Play" button to the "Jump back in" list
|
||||
remotePlayPatchHomeJumpBackIn: PREFS.get(Preferences.REMOTE_PLAY_ENABLED) && function(funcStr) {
|
||||
const index = funcStr.indexOf('MruTitlesGamesRow-module__childContainer');
|
||||
if (index === -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const startIndex = funcStr.indexOf('return(', index);
|
||||
const newCode = `
|
||||
setTimeout(() => { window.dispatchEvent(new Event('${BxEvent.JUMP_BACK_IN_READY}')); }, 1000);
|
||||
`;
|
||||
|
||||
// Add event listener
|
||||
window.addEventListener(BxEvent.JUMP_BACK_IN_READY, e => {
|
||||
const $list = document.querySelector('ol[class^=ItemRow-module__list]');
|
||||
if (!$list) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($list.querySelector('.bx-jump-in-li')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const $li = $list.firstElementChild.cloneNode(true);
|
||||
$li.classList.add('bx-jump-in-li');
|
||||
|
||||
$li.addEventListener('click', e => {
|
||||
RemotePlay.showDialog();
|
||||
});
|
||||
|
||||
const $button = $li.querySelector('button');
|
||||
$button.removeAttribute('id');
|
||||
$button.removeAttribute('aria-labelledby');
|
||||
$button.setAttribute('aria-label', __('remote-play'));
|
||||
|
||||
// Remove card's info
|
||||
const $cardInfo = $button.querySelector('div[class^=BaseItem]');
|
||||
$cardInfo.parentElement.removeChild($cardInfo);
|
||||
|
||||
const $images = $button.querySelector('div[class^=WrappedResponsiveImage]');
|
||||
$images.classList.add('bx-remote-play-icon-wrapper');
|
||||
$images.innerHTML = '';
|
||||
$images.appendChild(createSvgIcon(Icon.REMOTE_PLAY), 2);
|
||||
|
||||
$list.insertBefore($li, $list.firstElementChild);
|
||||
});
|
||||
|
||||
funcStr = funcStr.substring(0, startIndex) + newCode + funcStr.substring(startIndex);
|
||||
return funcStr;
|
||||
},
|
||||
|
||||
// Disable trackEvent() function
|
||||
disableTrackEvent: PREFS.get(Preferences.BLOCK_TRACKING) && function(funcStr) {
|
||||
const text = 'this.trackEvent=';
|
||||
@ -6772,13 +6840,15 @@ if (window.BX_VIBRATION_INTENSITY && window.BX_VIBRATION_INTENSITY < 1) {
|
||||
};
|
||||
|
||||
static #PATCH_ORDERS = [
|
||||
['disableStreamGate'],
|
||||
|
||||
[
|
||||
'disableAiTrack',
|
||||
'disableTelemetry',
|
||||
],
|
||||
|
||||
['disableStreamGate'],
|
||||
|
||||
['remotePlayPatchHomeJumpBackIn'],
|
||||
|
||||
['tvLayout'],
|
||||
|
||||
['enableXcloudLogger'],
|
||||
@ -7035,7 +7105,6 @@ function addCss() {
|
||||
--bx-danger-button-hover-color: #e61d1d;
|
||||
--bx-danger-button-disabled-color: #a26c6c;
|
||||
|
||||
|
||||
--bx-toast-z-index: 9999;
|
||||
--bx-dialog-z-index: 9101;
|
||||
--bx-dialog-overlay-z-index: 9100;
|
||||
@ -7061,6 +7130,39 @@ div[class^=HUDButton-module__hiddenContainer] ~ div:not([class^=HUDButton-module
|
||||
left: -9999px;
|
||||
}
|
||||
|
||||
.bx-jump-in-li {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.bx-jump-in-li button {
|
||||
width: 60px;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.bx-jump-in-li button:not(:focus) .bx-remote-play-icon-wrapper {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
|
||||
.bx-remote-play-icon-wrapper, .bx-jump-in-li button:hover .bx-remote-play-icon-wrapper {
|
||||
background: #7b7b7b1a;
|
||||
}
|
||||
|
||||
.bx-remote-play-icon-wrapper svg {
|
||||
padding: 10px;
|
||||
height: 100%;
|
||||
filter: drop-shadow(0px 1px 1px rgba(0, 0, 0, 0.5));
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.bx-jump-in-li button:hover .bx-remote-play-icon-wrapper svg, .bx-jump-in-li button:focus .bx-remote-play-icon-wrapper svg {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
a.bx-button {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.bx-button {
|
||||
background-color: var(--bx-default-button-color);
|
||||
user-select: none;
|
||||
@ -7130,9 +7232,10 @@ div[class^=HUDButton-module__hiddenContainer] ~ div:not([class^=HUDButton-module
|
||||
|
||||
.bx-button span {
|
||||
display: inline-block;
|
||||
height: 32px;
|
||||
height: 30px;
|
||||
line-height: 32px;
|
||||
vertical-align: middle;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.bx-settings-button {
|
||||
@ -7561,17 +7664,22 @@ div[class*=StreamMenu-module__menuContainer] > div[class*=Menu-module] {
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
.bx-dialog > b {
|
||||
.bx-dialog h2 {
|
||||
display: flex;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.bx-dialog h2 b {
|
||||
flex: 1;
|
||||
color: #fff;
|
||||
display: block;
|
||||
font-family: var(--bx-title-font);
|
||||
font-size: 26px;
|
||||
font-weight: 400;
|
||||
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;
|
||||
}
|
||||
|
||||
@ -7722,20 +7830,23 @@ div[class*=StreamMenu-module__menuContainer] > div[class*=Menu-module] {
|
||||
}
|
||||
|
||||
.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-weight: bold;
|
||||
margin-bottom: 8px;
|
||||
text-transform: uppercase;
|
||||
text-align: left;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
.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"] {
|
||||
@ -8034,15 +8145,16 @@ div[class*=StreamMenu-module__menuContainer] > div[class*=Menu-module] {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.bx-wait-time-estimated, .bx-wait-time-countdown {
|
||||
.bx-wait-time-box span {
|
||||
display: block;
|
||||
font-family: var(--bx-monospaced-font);
|
||||
text-align: right;
|
||||
font-size: 16px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.bx-wait-time-estimated {
|
||||
margin-bottom: 10px;
|
||||
.bx-wait-time-box span:last-of-type {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* REMOTE PLAY */
|
||||
@ -8348,12 +8460,14 @@ function clearDbLogs(dbName, table) {
|
||||
request.onsuccess = e => {
|
||||
const db = e.target.result;
|
||||
|
||||
const objectStore = db.transaction(table, 'readwrite').objectStore(table);
|
||||
const objectStoreRequest = objectStore.clear();
|
||||
try {
|
||||
const objectStore = db.transaction(table, 'readwrite').objectStore(table);
|
||||
const objectStoreRequest = objectStore.clear();
|
||||
|
||||
objectStoreRequest.onsuccess = function(event) {
|
||||
console.log(`[Better xCloud] Cleared ${dbName}.${table}`);
|
||||
};
|
||||
objectStoreRequest.onsuccess = function(event) {
|
||||
console.log(`[Better xCloud] Cleared ${dbName}.${table}`);
|
||||
};
|
||||
} catch (e) {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -8786,7 +8900,6 @@ function injectSettingsButton($parent) {
|
||||
|
||||
const PREF_PREFERRED_REGION = getPreferredServerRegion();
|
||||
const PREF_LATEST_VERSION = PREFS.get(Preferences.LATEST_VERSION);
|
||||
const PREF_REMOTE_PLAY_ENABLED = PREFS.get(Preferences.REMOTE_PLAY_ENABLED);
|
||||
|
||||
// Setup Settings button
|
||||
const $button = CE('button', {'class': 'bx-settings-button'}, PREF_PREFERRED_REGION);
|
||||
@ -8810,7 +8923,7 @@ function injectSettingsButton($parent) {
|
||||
});
|
||||
|
||||
let $updateAvailable;
|
||||
let $remotePlayBtn;
|
||||
|
||||
const $wrapper = CE('div', {'class': 'bx-settings-wrapper'},
|
||||
CE('div', {'class': 'bx-settings-title-wrapper'},
|
||||
CE('a', {
|
||||
@ -8818,7 +8931,7 @@ function injectSettingsButton($parent) {
|
||||
'href': SCRIPT_HOME,
|
||||
'target': '_blank',
|
||||
}, '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', {
|
||||
@ -8827,17 +8940,6 @@ function injectSettingsButton($parent) {
|
||||
'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);
|
||||
|
||||
// Show new version indicator
|
||||
@ -9682,8 +9784,8 @@ function setupQuickSettingsBar() {
|
||||
|
||||
for (const settingGroup of settingTab.items) {
|
||||
$group.appendChild(CE('h2', {},
|
||||
settingGroup.label,
|
||||
settingGroup.help_url && CE('a', {href: settingGroup.help_url, target: '_blank'}, createSvgIcon(Icon.INFO, 4)),
|
||||
CE('span', {}, settingGroup.label),
|
||||
settingGroup.help_url && createButton({icon: Icon.QUESTION, isGhost: true, url: settingGroup.help_url, title: __('help')}),
|
||||
));
|
||||
if (settingGroup.note) {
|
||||
if (typeof settingGroup.note === 'string') {
|
||||
@ -9806,9 +9908,10 @@ function setupScreenshotButton() {
|
||||
|
||||
|
||||
function patchHistoryMethod(type) {
|
||||
var orig = window.history[type];
|
||||
const orig = window.history[type];
|
||||
|
||||
return function(...args) {
|
||||
const event = new Event('xcloud_popstate');
|
||||
const event = new Event(BxEvent.POPSTATE);
|
||||
event.arguments = args;
|
||||
window.dispatchEvent(event);
|
||||
|
||||
@ -10025,9 +10128,10 @@ function setupBxUi() {
|
||||
|
||||
|
||||
// Hide Settings UI when navigate to another page
|
||||
window.addEventListener('xcloud_popstate', onHistoryChanged);
|
||||
window.addEventListener(BxEvent.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.replaceState = patchHistoryMethod('replaceState');
|
||||
|
||||
|
Reference in New Issue
Block a user