diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index 5692ad4de6..8c09613947 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -28,7 +28,6 @@ import { MediaError } from 'types/mediaError'; import { getMediaError } from 'utils/mediaError'; import { toApi } from 'utils/jellyfin-apiclient/compat'; import { BaseItemKind } from '@jellyfin/sdk/lib/generated-client/models/base-item-kind.js'; -import browser from 'scripts/browser.js'; import { bindSkipSegment } from './skipsegment.ts'; const UNLIMITED_ITEMS = -1; @@ -3664,9 +3663,8 @@ export class PlaybackManager { }); } - if (!browser.tv && !browser.xboxOne && !browser.ps4) { - this._skipSegment = bindSkipSegment(self); - } + bindMediaSegmentManager(self); + this._skipSegment = bindSkipSegment(self); } getCurrentPlayer() { diff --git a/src/components/playback/skipsegment.ts b/src/components/playback/skipsegment.ts index e77c00d094..523a16c49e 100644 --- a/src/components/playback/skipsegment.ts +++ b/src/components/playback/skipsegment.ts @@ -9,49 +9,54 @@ import './skipbutton.scss'; import dom from 'scripts/dom'; import globalize from 'lib/globalize'; import * as userSettings from 'scripts/settings/userSettings'; +import focusManager from 'components/focusManager'; +import layoutManager from 'components/layoutManager'; interface ShowOptions { animate?: boolean; keep?: boolean; + focus?: boolean; +} + +function onHideComplete(this: HTMLButtonElement) { + if (this) { + this.classList.add('hide'); + } } class SkipSegment extends PlaybackSubscriber { - private skipElement: HTMLButtonElement | undefined; + private skipElement: HTMLButtonElement | null; private currentSegment: MediaSegmentDto | null | undefined; private hideTimeout: ReturnType | null | undefined; constructor(playbackManager: PlaybackManager) { super(playbackManager); + this.skipElement = null; this.onOsdChanged = this.onOsdChanged.bind(this); } - onHideComplete() { - if (this.skipElement) { - this.skipElement.classList.add('hide'); - } - } - createSkipElement() { if (!this.skipElement && this.currentSegment) { - const elem = document.createElement('button'); - elem.classList.add('skip-button'); - elem.classList.add('hide'); - elem.classList.add('skip-button-hidden'); + let buttonHtml = ''; - elem.addEventListener('click', () => { - const time = this.playbackManager.currentTime() * TICKS_PER_MILLISECOND; - if (this.currentSegment?.EndTicks) { - if (time < this.currentSegment.EndTicks - TICKS_PER_SECOND) { - this.playbackManager.seek(this.currentSegment.EndTicks); - } else { - this.hideSkipButton(); + buttonHtml += ''; + + 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; + if (this.currentSegment?.EndTicks) { + if (time < this.currentSegment.EndTicks - TICKS_PER_SECOND) { + this.playbackManager.seek(this.currentSegment.EndTicks); + } else { + this.hideSkipButton(); + } } - } - }); - - document.body.appendChild(elem); - this.skipElement = elem; + }); + } } } @@ -66,7 +71,7 @@ class SkipSegment extends PlaybackSubscriber { const elem = this.skipElement; if (elem) { this.clearHideTimeout(); - dom.removeEventListener(elem, dom.whichTransitionEvent(), this.onHideComplete, { + dom.removeEventListener(elem, dom.whichTransitionEvent(), onHideComplete, { once: true }); elem.classList.remove('hide'); @@ -78,6 +83,11 @@ class SkipSegment extends PlaybackSubscriber { void elem.offsetWidth; + const hasFocus = document.activeElement && focusManager.isCurrentlyFocusable(document.activeElement); + if (options.focus && !hasFocus) { + focusManager.focus(elem); + } + requestAnimationFrame(() => { elem.classList.remove('skip-button-hidden'); @@ -97,7 +107,7 @@ class SkipSegment extends PlaybackSubscriber { requestAnimationFrame(() => { elem.classList.add('skip-button-hidden'); - dom.addEventListener(elem, dom.whichTransitionEvent(), this.onHideComplete, { + dom.addEventListener(elem, dom.whichTransitionEvent(), onHideComplete, { once: true }); }); @@ -116,7 +126,8 @@ class SkipSegment extends PlaybackSubscriber { if (isOpen) { this.showSkipButton({ animate: false, - keep: true + keep: true, + focus: false }); } else if (!this.hideTimeout) { this.hideSkipButton(); @@ -140,7 +151,10 @@ class SkipSegment extends PlaybackSubscriber { this.setButtonText(); - this.showSkipButton({ animate: true }); + this.showSkipButton({ + animate: true, + focus: layoutManager.tv + }); } } diff --git a/src/controllers/playback/video/index.js b/src/controllers/playback/video/index.js index e56f8a8048..6dbf106ff5 100644 --- a/src/controllers/playback/video/index.js +++ b/src/controllers/playback/video/index.js @@ -1237,8 +1237,10 @@ export default function (view) { } return; case 'Enter': - playbackManager.playPause(currentPlayer); - showOsd(btnPlayPause); + if (e.target.tagName !== 'BUTTON') { + playbackManager.playPause(currentPlayer); + showOsd(btnPlayPause); + } return; } }