mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Enable TV Support for 'Ask to Skip' (#6295)
This commit is contained in:
parent
92e8821003
commit
26df03b64c
3 changed files with 46 additions and 33 deletions
|
@ -27,7 +27,6 @@ import { MediaError } from 'types/mediaError';
|
||||||
import { getMediaError } from 'utils/mediaError';
|
import { getMediaError } from 'utils/mediaError';
|
||||||
import { toApi } from 'utils/jellyfin-apiclient/compat';
|
import { toApi } from 'utils/jellyfin-apiclient/compat';
|
||||||
import { BaseItemKind } from '@jellyfin/sdk/lib/generated-client/models/base-item-kind.js';
|
import { BaseItemKind } from '@jellyfin/sdk/lib/generated-client/models/base-item-kind.js';
|
||||||
import browser from 'scripts/browser.js';
|
|
||||||
import { bindSkipSegment } from './skipsegment.ts';
|
import { bindSkipSegment } from './skipsegment.ts';
|
||||||
|
|
||||||
const UNLIMITED_ITEMS = -1;
|
const UNLIMITED_ITEMS = -1;
|
||||||
|
@ -3687,10 +3686,8 @@ export class PlaybackManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
bindMediaSegmentManager(self);
|
bindMediaSegmentManager(self);
|
||||||
if (!browser.tv && !browser.xboxOne && !browser.ps4) {
|
|
||||||
this._skipSegment = bindSkipSegment(self);
|
this._skipSegment = bindSkipSegment(self);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
getCurrentPlayer() {
|
getCurrentPlayer() {
|
||||||
return this._currentPlayer;
|
return this._currentPlayer;
|
||||||
|
|
|
@ -9,37 +9,44 @@ import './skipbutton.scss';
|
||||||
import dom from 'scripts/dom';
|
import dom from 'scripts/dom';
|
||||||
import globalize from 'lib/globalize';
|
import globalize from 'lib/globalize';
|
||||||
import * as userSettings from 'scripts/settings/userSettings';
|
import * as userSettings from 'scripts/settings/userSettings';
|
||||||
|
import focusManager from 'components/focusManager';
|
||||||
|
import layoutManager from 'components/layoutManager';
|
||||||
|
|
||||||
interface ShowOptions {
|
interface ShowOptions {
|
||||||
animate?: boolean;
|
animate?: boolean;
|
||||||
keep?: boolean;
|
keep?: boolean;
|
||||||
|
focus?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onHideComplete(this: HTMLButtonElement) {
|
||||||
|
if (this) {
|
||||||
|
this.classList.add('hide');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SkipSegment extends PlaybackSubscriber {
|
class SkipSegment extends PlaybackSubscriber {
|
||||||
private skipElement: HTMLButtonElement | undefined;
|
private skipElement: HTMLButtonElement | null;
|
||||||
private currentSegment: MediaSegmentDto | null | undefined;
|
private currentSegment: MediaSegmentDto | null | undefined;
|
||||||
private hideTimeout: ReturnType<typeof setTimeout> | null | undefined;
|
private hideTimeout: ReturnType<typeof setTimeout> | null | undefined;
|
||||||
|
|
||||||
constructor(playbackManager: PlaybackManager) {
|
constructor(playbackManager: PlaybackManager) {
|
||||||
super(playbackManager);
|
super(playbackManager);
|
||||||
|
|
||||||
|
this.skipElement = null;
|
||||||
this.onOsdChanged = this.onOsdChanged.bind(this);
|
this.onOsdChanged = this.onOsdChanged.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
onHideComplete() {
|
|
||||||
if (this.skipElement) {
|
|
||||||
this.skipElement.classList.add('hide');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
createSkipElement() {
|
createSkipElement() {
|
||||||
if (!this.skipElement && this.currentSegment) {
|
if (!this.skipElement && this.currentSegment) {
|
||||||
const elem = document.createElement('button');
|
let buttonHtml = '';
|
||||||
elem.classList.add('skip-button');
|
|
||||||
elem.classList.add('hide');
|
|
||||||
elem.classList.add('skip-button-hidden');
|
|
||||||
|
|
||||||
elem.addEventListener('click', () => {
|
buttonHtml += '<button is="emby-button" class="skip-button hide skip-button-hidden"></button>';
|
||||||
|
|
||||||
|
document.body.insertAdjacentHTML('beforeend', buttonHtml);
|
||||||
|
|
||||||
|
this.skipElement = document.body.querySelector('.skip-button');
|
||||||
|
if (this.skipElement) {
|
||||||
|
this.skipElement.addEventListener('click', () => {
|
||||||
const time = this.playbackManager.currentTime() * TICKS_PER_MILLISECOND;
|
const time = this.playbackManager.currentTime() * TICKS_PER_MILLISECOND;
|
||||||
if (this.currentSegment?.EndTicks) {
|
if (this.currentSegment?.EndTicks) {
|
||||||
if (time < this.currentSegment.EndTicks - TICKS_PER_SECOND) {
|
if (time < this.currentSegment.EndTicks - TICKS_PER_SECOND) {
|
||||||
|
@ -49,9 +56,7 @@ class SkipSegment extends PlaybackSubscriber {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
document.body.appendChild(elem);
|
|
||||||
this.skipElement = elem;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +71,7 @@ class SkipSegment extends PlaybackSubscriber {
|
||||||
const elem = this.skipElement;
|
const elem = this.skipElement;
|
||||||
if (elem) {
|
if (elem) {
|
||||||
this.clearHideTimeout();
|
this.clearHideTimeout();
|
||||||
dom.removeEventListener(elem, dom.whichTransitionEvent(), this.onHideComplete, {
|
dom.removeEventListener(elem, dom.whichTransitionEvent(), onHideComplete, {
|
||||||
once: true
|
once: true
|
||||||
});
|
});
|
||||||
elem.classList.remove('hide');
|
elem.classList.remove('hide');
|
||||||
|
@ -78,6 +83,11 @@ class SkipSegment extends PlaybackSubscriber {
|
||||||
|
|
||||||
void elem.offsetWidth;
|
void elem.offsetWidth;
|
||||||
|
|
||||||
|
const hasFocus = document.activeElement && focusManager.isCurrentlyFocusable(document.activeElement);
|
||||||
|
if (options.focus && !hasFocus) {
|
||||||
|
focusManager.focus(elem);
|
||||||
|
}
|
||||||
|
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
elem.classList.remove('skip-button-hidden');
|
elem.classList.remove('skip-button-hidden');
|
||||||
|
|
||||||
|
@ -97,7 +107,7 @@ class SkipSegment extends PlaybackSubscriber {
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
elem.classList.add('skip-button-hidden');
|
elem.classList.add('skip-button-hidden');
|
||||||
|
|
||||||
dom.addEventListener(elem, dom.whichTransitionEvent(), this.onHideComplete, {
|
dom.addEventListener(elem, dom.whichTransitionEvent(), onHideComplete, {
|
||||||
once: true
|
once: true
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -116,7 +126,8 @@ class SkipSegment extends PlaybackSubscriber {
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
this.showSkipButton({
|
this.showSkipButton({
|
||||||
animate: false,
|
animate: false,
|
||||||
keep: true
|
keep: true,
|
||||||
|
focus: false
|
||||||
});
|
});
|
||||||
} else if (!this.hideTimeout) {
|
} else if (!this.hideTimeout) {
|
||||||
this.hideSkipButton();
|
this.hideSkipButton();
|
||||||
|
@ -140,7 +151,10 @@ class SkipSegment extends PlaybackSubscriber {
|
||||||
|
|
||||||
this.setButtonText();
|
this.setButtonText();
|
||||||
|
|
||||||
this.showSkipButton({ animate: true });
|
this.showSkipButton({
|
||||||
|
animate: true,
|
||||||
|
focus: layoutManager.tv
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1237,8 +1237,10 @@ export default function (view) {
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case 'Enter':
|
case 'Enter':
|
||||||
|
if (e.target.tagName !== 'BUTTON') {
|
||||||
playbackManager.playPause(currentPlayer);
|
playbackManager.playPause(currentPlayer);
|
||||||
showOsd(btnPlayPause);
|
showOsd(btnPlayPause);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue