mirror of
https://github.com/redphx/better-xcloud.git
synced 2025-07-06 22:31:44 +02:00
Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
5a27caad23 | |||
e7d7ccf165 | |||
782c0a6967 | |||
5f696ff0b8 | |||
c796152bdd | |||
2ae8452c90 | |||
bf7d6453ea | |||
130a7ffbd7 | |||
1d590103ce | |||
a268e49280 | |||
7db004ede3 |
2
dist/better-xcloud.meta.js
vendored
2
dist/better-xcloud.meta.js
vendored
@ -1,5 +1,5 @@
|
|||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name Better xCloud
|
// @name Better xCloud
|
||||||
// @namespace https://github.com/redphx
|
// @namespace https://github.com/redphx
|
||||||
// @version 5.4.1
|
// @version 5.4.2
|
||||||
// ==/UserScript==
|
// ==/UserScript==
|
||||||
|
54
dist/better-xcloud.user.js
vendored
54
dist/better-xcloud.user.js
vendored
File diff suppressed because one or more lines are too long
@ -67,10 +67,6 @@
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 16px;
|
width: 16px;
|
||||||
height: var(--bx-button-height);
|
height: var(--bx-button-height);
|
||||||
|
|
||||||
&:not(:only-child) {
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
span {
|
span {
|
||||||
@ -82,6 +78,10 @@
|
|||||||
color: #fff;
|
color: #fff;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|
||||||
|
&:not(:only-child) {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,5 +119,12 @@ button.bx-inactive {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.bx-button-shortcut {
|
.bx-button-shortcut {
|
||||||
margin-top: 10px;
|
max-width: max-content;
|
||||||
|
margin: 10px 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 568px) and (max-height: 480px) {
|
||||||
|
.bx-button-shortcut {
|
||||||
|
margin: 8px 0 0 10px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,6 +98,7 @@
|
|||||||
|
|
||||||
.bx-settings-row {
|
.bx-settings-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
padding: 6px 12px;
|
padding: 6px 12px;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
@ -115,6 +115,7 @@
|
|||||||
|
|
||||||
.bx-stream-settings-row {
|
.bx-stream-settings-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
border-bottom: 1px solid #40404080;
|
border-bottom: 1px solid #40404080;
|
||||||
padding: 16px 8px;
|
padding: 16px 8px;
|
||||||
border-left: 2px solid transparent;
|
border-left: 2px solid transparent;
|
||||||
|
@ -85,6 +85,7 @@
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-family: var(--bx-monospaced-font);
|
font-family: var(--bx-monospaced-font);
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
span {
|
span {
|
||||||
line-height: unset;
|
line-height: unset;
|
||||||
|
@ -207,6 +207,7 @@ export class ControllerShortcut {
|
|||||||
|
|
||||||
BxEvent.dispatch($select, 'input', {
|
BxEvent.dispatch($select, 'input', {
|
||||||
ignoreOnChange: true,
|
ignoreOnChange: true,
|
||||||
|
manualTrigger: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -529,14 +529,18 @@ export class StreamSettings {
|
|||||||
const $childSetting = $sibling.querySelector('[tabindex="0"]:last-of-type') as HTMLElement;
|
const $childSetting = $sibling.querySelector('[tabindex="0"]:last-of-type') as HTMLElement;
|
||||||
if ($childSetting) {
|
if ($childSetting) {
|
||||||
$childSetting.focus();
|
$childSetting.focus();
|
||||||
return;
|
|
||||||
|
// Only stop when it was focused successfully
|
||||||
|
if (document.activeElement === $childSetting) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If it's the first/last item -> loop around
|
// If it's the first/last item -> loop around
|
||||||
// TODO: bugged if pseudo is "first-of-type" and the first setting is disabled
|
// TODO: bugged if pseudo is "first-of-type" and the first setting is disabled
|
||||||
const pseudo = direction === NavigationDirection.UP ? ':last-of-type' : '';
|
const pseudo = direction === NavigationDirection.UP ? ':last-of-type' : '';
|
||||||
const $target = this.$settings!.querySelector(`div[data-tab-group]:not(.bx-gone) div[data-focus-container]${pseudo} [tabindex="0"]:not(:disabled):last-of-type`);
|
const $target = this.$settings!.querySelector(`div[data-tab-group]:not(.bx-gone) div[data-focus-container]:not(.bx-gone)${pseudo} [tabindex="0"]:not(:disabled):last-of-type`);
|
||||||
$target && ($target as HTMLElement).focus();
|
$target && ($target as HTMLElement).focus();
|
||||||
} else if (direction === NavigationDirection.LEFT || direction === NavigationDirection.RIGHT) {
|
} else if (direction === NavigationDirection.LEFT || direction === NavigationDirection.RIGHT) {
|
||||||
// Find all child elements with tabindex
|
// Find all child elements with tabindex
|
||||||
|
@ -177,7 +177,7 @@ export function setupSettingsUi() {
|
|||||||
if (AppInterface) {
|
if (AppInterface) {
|
||||||
// Show Android app settings button
|
// Show Android app settings button
|
||||||
topButtons.push(createButton({
|
topButtons.push(createButton({
|
||||||
label: t('android-app-settings'),
|
label: t('app-settings'),
|
||||||
icon: BxIcon.STREAM_SETTINGS,
|
icon: BxIcon.STREAM_SETTINGS,
|
||||||
style: ButtonStyle.FULL_WIDTH | ButtonStyle.FOCUSABLE,
|
style: ButtonStyle.FULL_WIDTH | ButtonStyle.FOCUSABLE,
|
||||||
onClick: e => {
|
onClick: e => {
|
||||||
@ -465,6 +465,7 @@ export function setupSettingsUi() {
|
|||||||
|
|
||||||
PrefKey.VIDEO_PLAYER_TYPE,
|
PrefKey.VIDEO_PLAYER_TYPE,
|
||||||
PrefKey.VIDEO_PROCESSING,
|
PrefKey.VIDEO_PROCESSING,
|
||||||
|
PrefKey.VIDEO_POWER_PREFERENCE,
|
||||||
PrefKey.VIDEO_SHARPNESS,
|
PrefKey.VIDEO_SHARPNESS,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ export class GuideMenu {
|
|||||||
}),
|
}),
|
||||||
|
|
||||||
appSettings: createButton({
|
appSettings: createButton({
|
||||||
label: t('android-app-settings'),
|
label: t('app-settings'),
|
||||||
style: ButtonStyle.FULL_WIDTH | ButtonStyle.FOCUSABLE,
|
style: ButtonStyle.FULL_WIDTH | ButtonStyle.FOCUSABLE,
|
||||||
onClick: e => {
|
onClick: e => {
|
||||||
// Close all xCloud's dialogs
|
// Close all xCloud's dialogs
|
||||||
|
@ -28,7 +28,6 @@ export class ProductDetailsPage {
|
|||||||
// Find action buttons container
|
// Find action buttons container
|
||||||
const $container = document.querySelector('div[class*=ActionButtons-module__container]');
|
const $container = document.querySelector('div[class*=ActionButtons-module__container]');
|
||||||
if ($container) {
|
if ($container) {
|
||||||
this.$btnShortcut.style.width = $container.getBoundingClientRect().width + 'px';
|
|
||||||
$container.parentElement?.appendChild(ProductDetailsPage.$btnShortcut);
|
$container.parentElement?.appendChild(ProductDetailsPage.$btnShortcut);
|
||||||
}
|
}
|
||||||
}, 500);
|
}, 500);
|
||||||
|
@ -50,7 +50,7 @@ function createElement<T=HTMLElement>(elmName: string, props: {[index: string]:
|
|||||||
|
|
||||||
if (arg instanceof Node) {
|
if (arg instanceof Node) {
|
||||||
$elm.appendChild(arg);
|
$elm.appendChild(arg);
|
||||||
} else if (arg !== null && typeof arg !== 'undefined') {
|
} else if (arg !== null && arg !== false && typeof arg !== 'undefined') {
|
||||||
$elm.appendChild(document.createTextNode(arg));
|
$elm.appendChild(document.createTextNode(arg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -644,8 +644,8 @@ export class Preferences {
|
|||||||
default: 'default',
|
default: 'default',
|
||||||
options: {
|
options: {
|
||||||
'default': t('default'),
|
'default': t('default'),
|
||||||
'high-performance': t('high-performance'),
|
|
||||||
'low-power': t('low-power'),
|
'low-power': t('low-power'),
|
||||||
|
'high-performance': t('high-performance'),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
[PrefKey.VIDEO_SHARPNESS]: {
|
[PrefKey.VIDEO_SHARPNESS]: {
|
||||||
|
@ -31,7 +31,7 @@ const Texts = {
|
|||||||
"always-off": "Always off",
|
"always-off": "Always off",
|
||||||
"always-on": "Always on",
|
"always-on": "Always on",
|
||||||
"amd-fidelity-cas": "AMD FidelityFX CAS",
|
"amd-fidelity-cas": "AMD FidelityFX CAS",
|
||||||
"android-app-settings": "Android app settings",
|
"app-settings": "App settings",
|
||||||
"apply": "Apply",
|
"apply": "Apply",
|
||||||
"aspect-ratio": "Aspect ratio",
|
"aspect-ratio": "Aspect ratio",
|
||||||
"aspect-ratio-note": "Don't use with native touch games",
|
"aspect-ratio-note": "Don't use with native touch games",
|
||||||
|
@ -24,6 +24,7 @@ export class BxSelectElement {
|
|||||||
const isMultiple = $select.multiple;
|
const isMultiple = $select.multiple;
|
||||||
let $checkBox: HTMLInputElement;
|
let $checkBox: HTMLInputElement;
|
||||||
let $label: HTMLElement;
|
let $label: HTMLElement;
|
||||||
|
let visibleIndex = $select.selectedIndex;
|
||||||
|
|
||||||
let $content;
|
let $content;
|
||||||
|
|
||||||
@ -41,7 +42,7 @@ export class BxSelectElement {
|
|||||||
});
|
});
|
||||||
|
|
||||||
$checkBox.addEventListener('input', e => {
|
$checkBox.addEventListener('input', e => {
|
||||||
const $option = getOptionAtIndex($select.selectedIndex);
|
const $option = getOptionAtIndex(visibleIndex);
|
||||||
$option && ($option.selected = (e.target as HTMLInputElement).checked);
|
$option && ($option.selected = (e.target as HTMLInputElement).checked);
|
||||||
|
|
||||||
$select.dispatchEvent(new Event('input'));
|
$select.dispatchEvent(new Event('input'));
|
||||||
@ -57,11 +58,13 @@ export class BxSelectElement {
|
|||||||
return options[index];
|
return options[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
const render = () => {
|
const render = (e?: Event) => {
|
||||||
// console.log('options', this.options, 'selectedIndices', this.selectedIndices, 'selectedOptions', this.selectedOptions);
|
// console.log('options', this.options, 'selectedIndices', this.selectedIndices, 'selectedOptions', this.selectedOptions);
|
||||||
|
if (e && (e as any).manualTrigger) {
|
||||||
|
visibleIndex = $select.selectedIndex;
|
||||||
|
}
|
||||||
|
|
||||||
const visibleIndex = normalizeIndex($select.selectedIndex);
|
visibleIndex = normalizeIndex(visibleIndex);
|
||||||
|
|
||||||
const $option = getOptionAtIndex(visibleIndex);
|
const $option = getOptionAtIndex(visibleIndex);
|
||||||
let content = '';
|
let content = '';
|
||||||
if ($option) {
|
if ($option) {
|
||||||
@ -94,10 +97,11 @@ export class BxSelectElement {
|
|||||||
const disableNext = visibleIndex === $select.querySelectorAll('option').length - 1;
|
const disableNext = visibleIndex === $select.querySelectorAll('option').length - 1;
|
||||||
|
|
||||||
$btnPrev.classList.toggle('bx-inactive', disablePrev);
|
$btnPrev.classList.toggle('bx-inactive', disablePrev);
|
||||||
// disablePrev && document.activeElement === $btnPrev && $btnNext.focus();
|
|
||||||
|
|
||||||
$btnNext.classList.toggle('bx-inactive', disableNext);
|
$btnNext.classList.toggle('bx-inactive', disableNext);
|
||||||
// disableNext && document.activeElement === $btnNext &&$btnPrev.focus();
|
|
||||||
|
// Focus the other button when reaching the beginning/end
|
||||||
|
disablePrev && !disableNext && document.activeElement === $btnPrev && $btnNext.focus();
|
||||||
|
disableNext && !disablePrev && document.activeElement === $btnNext && $btnPrev.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
const normalizeIndex = (index: number): number => {
|
const normalizeIndex = (index: number): number => {
|
||||||
@ -107,18 +111,23 @@ export class BxSelectElement {
|
|||||||
const onPrevNext = (e: Event) => {
|
const onPrevNext = (e: Event) => {
|
||||||
const goNext = e.target === $btnNext;
|
const goNext = e.target === $btnNext;
|
||||||
|
|
||||||
const currentIndex = $select.selectedIndex;
|
const currentIndex = visibleIndex;
|
||||||
let newIndex = goNext ? currentIndex + 1 : currentIndex - 1;
|
let newIndex = goNext ? currentIndex + 1 : currentIndex - 1;
|
||||||
newIndex = normalizeIndex(newIndex);
|
newIndex = normalizeIndex(newIndex);
|
||||||
|
|
||||||
|
visibleIndex = newIndex;
|
||||||
if (!isMultiple && newIndex !== currentIndex) {
|
if (!isMultiple && newIndex !== currentIndex) {
|
||||||
$select.selectedIndex = newIndex;
|
$select.selectedIndex = newIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
$select.dispatchEvent(new Event('input'));
|
if (isMultiple) {
|
||||||
|
render();
|
||||||
|
} else {
|
||||||
|
$select.dispatchEvent(new Event('input'));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$select.addEventListener('input', e => render());
|
$select.addEventListener('input', render);
|
||||||
$btnPrev.addEventListener('click', onPrevNext);
|
$btnPrev.addEventListener('click', onPrevNext);
|
||||||
$btnNext.addEventListener('click', onPrevNext);
|
$btnNext.addEventListener('click', onPrevNext);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user