1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00
jellyfin-web/src/components/upnextdialog/upnextdialog.js

243 lines
6.8 KiB
JavaScript
Raw Normal View History

2020-08-14 08:46:34 +02:00
import dom from '../../scripts/dom';
2020-08-16 20:24:45 +02:00
import { playbackManager } from '../playback/playbackmanager';
2020-09-08 02:05:02 -04:00
import { Events } from 'jellyfin-apiclient';
2020-08-14 08:46:34 +02:00
import mediaInfo from '../mediainfo/mediainfo';
import layoutManager from '../layoutManager';
import focusManager from '../focusManager';
import globalize from '../../scripts/globalize';
import itemHelper from '../itemHelper';
import './upnextdialog.css';
import '../../elements/emby-button/emby-button';
import '../../assets/css/flexstyles.scss';
/* eslint-disable indent */
2020-07-27 10:30:24 +01:00
const transitionEndEventName = dom.whichTransitionEvent();
2018-10-23 01:05:09 +03:00
function getHtml() {
2020-07-27 10:30:24 +01:00
let html = '';
html += '<div class="flex flex-direction-column flex-grow">';
html += '<h2 class="upNextDialog-nextVideoText" style="margin:.25em 0;">&nbsp;</h2>';
html += '<h3 class="upNextDialog-title" style="margin:.25em 0 .5em;"></h3>';
html += '<div class="flex flex-direction-row upNextDialog-mediainfo">';
html += '</div>';
html += '<div class="flex flex-direction-row upNextDialog-buttons" style="margin-top:1em;">';
html += '<button type="button" is="emby-button" class="raised raised-mini btnStartNow upNextDialog-button">';
html += globalize.translate('HeaderStartNow');
html += '</button>';
html += '<button type="button" is="emby-button" class="raised raised-mini btnHide upNextDialog-button">';
html += globalize.translate('Hide');
html += '</button>';
// buttons
html += '</div>';
// main
html += '</div>';
return html;
2018-10-23 01:05:09 +03:00
}
function setNextVideoText() {
2020-07-27 10:30:24 +01:00
const instance = this;
2020-07-27 10:30:24 +01:00
const elem = instance.options.parent;
2020-07-27 10:30:24 +01:00
const secondsRemaining = Math.max(Math.round(getTimeRemainingMs(instance) / 1000), 0);
2020-02-16 03:44:43 +01:00
console.debug('up next seconds remaining: ' + secondsRemaining);
2020-07-27 10:30:24 +01:00
const timeText = '<span class="upNextDialog-countdownText">' + globalize.translate('HeaderSecondsValue', secondsRemaining) + '</span>';
2020-07-27 10:30:24 +01:00
const nextVideoText = instance.itemType === 'Episode' ?
globalize.translate('HeaderNextEpisodePlayingInValue', timeText) :
globalize.translate('HeaderNextVideoPlayingInValue', timeText);
elem.querySelector('.upNextDialog-nextVideoText').innerHTML = nextVideoText;
2018-10-23 01:05:09 +03:00
}
function fillItem(item) {
2020-07-27 10:30:24 +01:00
const instance = this;
2020-07-27 10:30:24 +01:00
const elem = instance.options.parent;
elem.querySelector('.upNextDialog-mediainfo').innerHTML = mediaInfo.getPrimaryMediaInfoHtml(item, {
2020-08-20 20:39:33 +02:00
criticRating: false,
originalAirDate: false,
starRating: false,
subtitles: false
});
2020-07-27 10:30:24 +01:00
let title = itemHelper.getDisplayName(item);
if (item.SeriesName) {
title = item.SeriesName + ' - ' + title;
}
elem.querySelector('.upNextDialog-title').innerHTML = title || '';
instance.itemType = item.Type;
instance.show();
2018-10-23 01:05:09 +03:00
}
function clearCountdownTextTimeout(instance) {
if (instance._countdownTextTimeout) {
clearInterval(instance._countdownTextTimeout);
instance._countdownTextTimeout = null;
}
2018-10-23 01:05:09 +03:00
}
function onStartNowClick() {
2020-07-27 10:30:24 +01:00
const options = this.options;
2018-10-23 01:05:09 +03:00
if (options) {
2020-07-27 10:30:24 +01:00
const player = options.player;
this.hide();
playbackManager.nextTrack(player);
2018-10-23 01:05:09 +03:00
}
}
function init(instance, options) {
options.parent.innerHTML = getHtml();
options.parent.classList.add('hide');
options.parent.classList.add('upNextDialog');
options.parent.classList.add('upNextDialog-hidden');
fillItem.call(instance, options.nextItem);
options.parent.querySelector('.btnHide').addEventListener('click', instance.hide.bind(instance));
options.parent.querySelector('.btnStartNow').addEventListener('click', onStartNowClick.bind(instance));
2018-10-23 01:05:09 +03:00
}
function clearHideAnimationEventListeners(instance, elem) {
2020-07-27 10:30:24 +01:00
const fn = instance._onHideAnimationComplete;
if (fn) {
dom.removeEventListener(elem, transitionEndEventName, fn, {
once: true
});
}
2018-10-23 01:05:09 +03:00
}
function onHideAnimationComplete(e) {
2020-07-27 10:30:24 +01:00
const instance = this;
const elem = e.target;
elem.classList.add('hide');
clearHideAnimationEventListeners(instance, elem);
2020-09-08 02:05:02 -04:00
Events.trigger(instance, 'hide');
2018-10-23 01:05:09 +03:00
}
function hideComingUpNext() {
2020-07-27 10:30:24 +01:00
const instance = this;
clearCountdownTextTimeout(this);
if (!instance.options) {
return;
}
2020-07-27 10:30:24 +01:00
const elem = instance.options.parent;
if (!elem) {
return;
}
clearHideAnimationEventListeners(this, elem);
if (elem.classList.contains('upNextDialog-hidden')) {
return;
2018-10-23 01:05:09 +03:00
}
// trigger a reflow to force it to animate again
void elem.offsetWidth;
elem.classList.add('upNextDialog-hidden');
2020-07-27 10:30:24 +01:00
const fn = onHideAnimationComplete.bind(instance);
instance._onHideAnimationComplete = fn;
dom.addEventListener(elem, transitionEndEventName, fn, {
once: true
});
2018-10-23 01:05:09 +03:00
}
function getTimeRemainingMs(instance) {
2020-07-27 10:30:24 +01:00
const options = instance.options;
2018-10-23 01:05:09 +03:00
if (options) {
2020-07-27 10:30:24 +01:00
const runtimeTicks = playbackManager.duration(options.player);
2018-10-23 01:05:09 +03:00
if (runtimeTicks) {
const timeRemainingTicks = runtimeTicks - playbackManager.currentTime(options.player) * 10000;
return Math.round(timeRemainingTicks / 10000);
2018-10-23 01:05:09 +03:00
}
}
return 0;
2018-10-23 01:05:09 +03:00
}
function startComingUpNextHideTimer(instance) {
2020-07-27 10:30:24 +01:00
const timeRemainingMs = getTimeRemainingMs(instance);
if (timeRemainingMs <= 0) {
return;
}
setNextVideoText.call(instance);
clearCountdownTextTimeout(instance);
instance._countdownTextTimeout = setInterval(setNextVideoText.bind(instance), 400);
2018-10-23 01:05:09 +03:00
}
class UpNextDialog {
constructor(options) {
this.options = options;
init(this, options);
2018-10-23 01:05:09 +03:00
}
show() {
2020-07-27 10:30:24 +01:00
const elem = this.options.parent;
clearHideAnimationEventListeners(this, elem);
elem.classList.remove('hide');
// trigger a reflow to force it to animate again
void elem.offsetWidth;
elem.classList.remove('upNextDialog-hidden');
if (layoutManager.tv) {
setTimeout(function () {
focusManager.focus(elem.querySelector('.btnStartNow'));
}, 50);
}
startComingUpNextHideTimer(this);
}
hide() {
hideComingUpNext.call(this);
}
destroy() {
hideComingUpNext.call(this);
this.options = null;
this.itemType = null;
}
}
export default UpNextDialog;
/* eslint-enable indent */