mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Merge remote-tracking branch 'upstream/master' into es6
With conflicts
This commit is contained in:
commit
3713091382
165 changed files with 4194 additions and 2714 deletions
|
@ -1,3 +1,4 @@
|
|||
<<<<<<< HEAD
|
||||
import appHost from 'apphost';
|
||||
import appSettings from 'appSettings';
|
||||
import dom from 'dom';
|
||||
|
@ -8,6 +9,10 @@ import browser from 'browser';
|
|||
import globalize from 'globalize';
|
||||
import 'cardStyle';
|
||||
import 'emby-checkbox';
|
||||
=======
|
||||
define(['apphost', 'appSettings', 'dom', 'connectionManager', 'loading', 'layoutManager', 'libraryMenu', 'browser', 'globalize', 'cardStyle', 'emby-checkbox'], function (appHost, appSettings, dom, connectionManager, loading, layoutManager, libraryMenu, browser, globalize) {
|
||||
'use strict';
|
||||
>>>>>>> upstream/master
|
||||
|
||||
/* eslint-disable indent */
|
||||
|
||||
|
@ -16,6 +21,7 @@ import 'emby-checkbox';
|
|||
function authenticateUserByName(page, apiClient, username, password) {
|
||||
loading.show();
|
||||
apiClient.authenticateUserByName(username, password).then(function (result) {
|
||||
<<<<<<< HEAD
|
||||
const user = result.User;
|
||||
const serverId = getParameterByName('serverid');
|
||||
let newUrl;
|
||||
|
@ -26,9 +32,13 @@ import 'emby-checkbox';
|
|||
newUrl = 'home.html';
|
||||
}
|
||||
|
||||
=======
|
||||
var user = result.User;
|
||||
>>>>>>> upstream/master
|
||||
loading.hide();
|
||||
|
||||
Dashboard.onServerChanged(user.Id, result.AccessToken, apiClient);
|
||||
Dashboard.navigate(newUrl);
|
||||
Dashboard.navigate('home.html');
|
||||
}, function (response) {
|
||||
page.querySelector('#txtManualName').value = '';
|
||||
page.querySelector('#txtManualPassword').value = '';
|
||||
|
@ -204,6 +214,7 @@ import 'emby-checkbox';
|
|||
});
|
||||
view.addEventListener('viewshow', function (e) {
|
||||
loading.show();
|
||||
libraryMenu.setTransparentMenu(true);
|
||||
|
||||
if (!appHost.supports('multiserver')) {
|
||||
view.querySelector('.btnSelectServer').classList.add('hide');
|
||||
|
@ -225,6 +236,14 @@ import 'emby-checkbox';
|
|||
view.querySelector('.disclaimer').textContent = options.LoginDisclaimer || '';
|
||||
});
|
||||
});
|
||||
<<<<<<< HEAD
|
||||
}
|
||||
|
||||
/* eslint-enable indent */
|
||||
=======
|
||||
view.addEventListener('viewhide', function (e) {
|
||||
libraryMenu.setTransparentMenu(false);
|
||||
});
|
||||
};
|
||||
});
|
||||
>>>>>>> upstream/master
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
<<<<<<< HEAD
|
||||
import loading from 'loading';
|
||||
import appRouter from 'appRouter';
|
||||
import layoutManager from 'layoutManager';
|
||||
|
@ -19,6 +20,12 @@ import 'emby-button';
|
|||
/* eslint-disable indent */
|
||||
|
||||
const enableFocusTransform = !browser.slow && !browser.edge;
|
||||
=======
|
||||
define(['loading', 'appRouter', 'layoutManager', 'libraryMenu', 'appSettings', 'apphost', 'focusManager', 'connectionManager', 'globalize', 'actionsheet', 'dom', 'browser', 'material-icons', 'flexStyles', 'emby-scroller', 'emby-itemscontainer', 'cardStyle', 'emby-button'], function (loading, appRouter, layoutManager, libraryMenu, appSettings, appHost, focusManager, connectionManager, globalize, actionSheet, dom, browser) {
|
||||
'use strict';
|
||||
|
||||
var enableFocusTransform = !browser.slow && !browser.edge;
|
||||
>>>>>>> upstream/master
|
||||
|
||||
function renderSelectServerItems(view, servers) {
|
||||
const items = servers.map(function (server) {
|
||||
|
@ -200,6 +207,7 @@ import 'emby-button';
|
|||
view.addEventListener('viewshow', function (e) {
|
||||
const isRestored = e.detail.isRestored;
|
||||
appRouter.setTitle(null);
|
||||
libraryMenu.setTransparentMenu(true);
|
||||
|
||||
if (!isRestored) {
|
||||
loadServers();
|
||||
|
|
|
@ -189,6 +189,7 @@ import 'emby-itemscontainer';
|
|||
function reloadSystemInfo(view, apiClient) {
|
||||
apiClient.getSystemInfo().then(function (systemInfo) {
|
||||
view.querySelector('#serverName').innerHTML = globalize.translate('DashboardServerName', systemInfo.ServerName);
|
||||
<<<<<<< HEAD
|
||||
let localizedVersion = globalize.translate('DashboardVersionNumber', systemInfo.Version);
|
||||
|
||||
if (systemInfo.SystemUpdateLevel !== 'Release') {
|
||||
|
@ -196,6 +197,9 @@ import 'emby-itemscontainer';
|
|||
}
|
||||
|
||||
view.querySelector('#versionNumber').innerHTML = localizedVersion;
|
||||
=======
|
||||
view.querySelector('#versionNumber').innerHTML = globalize.translate('DashboardVersionNumber', systemInfo.Version);
|
||||
>>>>>>> upstream/master
|
||||
view.querySelector('#operatingSystem').innerHTML = globalize.translate('DashboardOperatingSystem', systemInfo.OperatingSystem);
|
||||
view.querySelector('#architecture').innerHTML = globalize.translate('DashboardArchitecture', systemInfo.SystemArchitecture);
|
||||
|
||||
|
|
|
@ -170,7 +170,7 @@ import 'emby-itemrefreshindicator';
|
|||
showType: false,
|
||||
showLocations: false,
|
||||
showMenu: false,
|
||||
showNameWithIcon: true
|
||||
showNameWithIcon: false
|
||||
});
|
||||
|
||||
for (let i = 0; i < virtualFolders.length; i++) {
|
||||
|
@ -185,7 +185,7 @@ import 'emby-itemrefreshindicator';
|
|||
$('.btnCardMenu', divVirtualFolders).on('click', function () {
|
||||
showCardMenu(page, this, virtualFolders);
|
||||
});
|
||||
divVirtualFolders.querySelector('.addLibrary').addEventListener('click', function () {
|
||||
divVirtualFolders.querySelector('#addLibrary').addEventListener('click', function () {
|
||||
addVirtualFolder(page);
|
||||
});
|
||||
$('.editLibrary', divVirtualFolders).on('click', function () {
|
||||
|
@ -256,7 +256,12 @@ import 'emby-itemrefreshindicator';
|
|||
style += 'min-width:33.3%;';
|
||||
}
|
||||
|
||||
html += '<div class="card backdropCard scalableCard backdropCard-scalable" style="' + style + '" data-index="' + index + '" data-id="' + virtualFolder.ItemId + '">';
|
||||
if (virtualFolder.Locations.length == 0) {
|
||||
html += '<div id="addLibrary" class="card backdropCard scalableCard backdropCard-scalable" style="' + style + '" data-index="' + index + '" data-id="' + virtualFolder.ItemId + '">';
|
||||
} else {
|
||||
html += '<div class="card backdropCard scalableCard backdropCard-scalable" style="' + style + '" data-index="' + index + '" data-id="' + virtualFolder.ItemId + '">';
|
||||
}
|
||||
|
||||
html += '<div class="cardBox visualCardBox">';
|
||||
html += '<div class="cardScalable visualCardBox-cardScalable">';
|
||||
html += '<div class="cardPadder cardPadder-backdrop"></div>';
|
||||
|
|
|
@ -105,7 +105,9 @@ import globalize from 'globalize';
|
|||
$('#chkEnableSharing', page).prop('checked', user.Policy.EnablePublicSharing);
|
||||
$('#txtRemoteClientBitrateLimit', page).val(user.Policy.RemoteClientBitrateLimit / 1e6 || '');
|
||||
$('#txtLoginAttemptsBeforeLockout', page).val(user.Policy.LoginAttemptsBeforeLockout || '0');
|
||||
$('#selectSyncPlayAccess').val(user.Policy.SyncPlayAccess);
|
||||
if (ApiClient.isMinServerVersion('10.6.0')) {
|
||||
$('#selectSyncPlayAccess').val(user.Policy.SyncPlayAccess);
|
||||
}
|
||||
loading.hide();
|
||||
}
|
||||
|
||||
|
@ -147,7 +149,9 @@ import globalize from 'globalize';
|
|||
}).map(function (c) {
|
||||
return c.getAttribute('data-id');
|
||||
});
|
||||
user.Policy.SyncPlayAccess = page.querySelector('#selectSyncPlayAccess').value;
|
||||
if (ApiClient.isMinServerVersion('10.6.0')) {
|
||||
user.Policy.SyncPlayAccess = page.querySelector('#selectSyncPlayAccess').value;
|
||||
}
|
||||
ApiClient.updateUser(user).then(function () {
|
||||
ApiClient.updateUserPolicy(user.Id, user.Policy).then(function () {
|
||||
onSaveComplete(page, user);
|
||||
|
|
231
src/controllers/itemDetails/index.html
Normal file
231
src/controllers/itemDetails/index.html
Normal file
|
@ -0,0 +1,231 @@
|
|||
<div id="itemDetailPage" data-role="page" class="page libraryPage itemDetailPage noSecondaryNavPage selfBackdropPage" data-backbutton="true">
|
||||
<div id="itemBackdrop" class="itemBackdrop">
|
||||
</div>
|
||||
|
||||
<div class="detailLogo"></div>
|
||||
<div class="detailPageWrapperContainer">
|
||||
<div class="detailPagePrimaryContainer padded-left padded-right">
|
||||
<div class="infoWrapper infoText">
|
||||
<div class="nameContainer"></div>
|
||||
<div class="itemMiscInfo itemMiscInfo-primary" style="margin-bottom: 0.6em"></div>
|
||||
<div class="itemMiscInfo itemMiscInfo-secondary" style="margin-bottom: 0.6em"></div>
|
||||
</div>
|
||||
|
||||
<div class="mainDetailButtons">
|
||||
<button is="emby-button" type="button" class="button-flat btnResume hide detailButton" title="${ButtonResume}" data-mode="resume">
|
||||
<div class="detailButton-content">
|
||||
<span class="material-icons detailButton-icon play_arrow"></span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<button is="emby-button" type="button" class="button-flat btnPlay hide detailButton" title="${ButtonPlay}" data-mode="play">
|
||||
<div class="detailButton-content">
|
||||
<span class="material-icons detailButton-icon play_arrow"></span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<button is="emby-button" type="button" class="button-flat btnDownload hide detailButton" title="${ButtonDownload}">
|
||||
<div class="detailButton-content">
|
||||
<span class="material-icons detailButton-icon get_app"></span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<button is="emby-button" type="button" class="button-flat btnPlayTrailer hide detailButton" title="${ButtonTrailer}">
|
||||
<div class="detailButton-content">
|
||||
<span class="material-icons detailButton-icon theaters"></span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<button is="emby-button" type="button" class="button-flat btnInstantMix hide detailButton" title="${HeaderInstantMix}">
|
||||
<div class="detailButton-content">
|
||||
<span class="material-icons detailButton-icon explore"></span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<button is="emby-button" type="button" class="button-flat btnShuffle hide detailButton" title="${ButtonShuffle}">
|
||||
<div class="detailButton-content">
|
||||
<span class="material-icons detailButton-icon shuffle"></span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<button is="emby-button" type="button" class="button-flat btnCancelSeriesTimer hide detailButton" title="${CancelSeries}">
|
||||
<div class="detailButton-content">
|
||||
<span class="material-icons detailButton-icon delete"></span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<button is="emby-button" type="button" class="button-flat btnCancelTimer hide detailButton" title="${StopRecording}">
|
||||
<div class="detailButton-content">
|
||||
<span class="material-icons detailButton-icon stop"></span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<button is="emby-playstatebutton" type="button" class="button-flat btnPlaystate hide detailButton" title="">
|
||||
<div class="detailButton-content">
|
||||
<span class="material-icons detailButton-icon check"></span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<button is="emby-ratingbutton" type="button" class="button-flat btnUserRating hide detailButton" title="${Rate}">
|
||||
<div class="detailButton-content">
|
||||
<span class="material-icons detailButton-icon favorite"></span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<button is="emby-button" type="button" class="button-flat btnSplitVersions hide detailButton" title="${ButtonSplit}">
|
||||
<div class="detailButton-content">
|
||||
<span class="material-icons detailButton-icon call_split"></span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<button is="emby-button" type="button" class="button-flat btnMoreCommands hide detailButton" title="${ButtonMore}">
|
||||
<div class="detailButton-content">
|
||||
<span class="material-icons detailButton-icon more_vert"></span>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detailPageSecondaryContainer">
|
||||
<div class="detailImageContainer padded-left"></div>
|
||||
<div class="detailPageContent">
|
||||
<div class="detailPagePrimaryContent padded-right">
|
||||
<div class="detailSection">
|
||||
<div class="itemMiscInfo nativeName hide"></div>
|
||||
|
||||
<div class="itemDetailsGroup">
|
||||
<div class="detailsGroupItem genresGroup hide">
|
||||
<div class="genresLabel label"></div>
|
||||
<div class="genres content"></div>
|
||||
</div>
|
||||
|
||||
<div class="detailsGroupItem directorsGroup hide">
|
||||
<div class="directorsLabel label"></div>
|
||||
<div class="directors content"></div>
|
||||
</div>
|
||||
|
||||
<div class="detailsGroupItem writersGroup hide">
|
||||
<div class="writersLabel label"></div>
|
||||
<div class="writers content"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form class="trackSelections hide focuscontainer-x">
|
||||
<div class="selectContainer selectSourceContainer hide trackSelectionFieldContainer flex-shrink-zero">
|
||||
<select is="emby-select" class="selectSource detailTrackSelect" label=""></select>
|
||||
</div>
|
||||
<div class="selectContainer selectVideoContainer hide trackSelectionFieldContainer flex-shrink-zero">
|
||||
<select is="emby-select" class="selectVideo detailTrackSelect" label=""></select>
|
||||
</div>
|
||||
<div class="selectContainer selectAudioContainer hide trackSelectionFieldContainer flex-shrink-zero">
|
||||
<select is="emby-select" class="selectAudio detailTrackSelect" label=""></select>
|
||||
</div>
|
||||
<div class="selectContainer selectSubtitlesContainer hide trackSelectionFieldContainer flex-shrink-zero">
|
||||
<select is="emby-select" class="selectSubtitles detailTrackSelect" label=""></select>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="recordingFields hide" style="margin: .5em 0 1.5em;"></div>
|
||||
<div class="detailSectionContent">
|
||||
<div class="itemLastPlayed hide"></div>
|
||||
|
||||
<p class="itemGenres"></p>
|
||||
<h3 class="tagline"></h3>
|
||||
<p class="overview"></p>
|
||||
<div class="overview-controls">
|
||||
<a class="overview-expand hide" is="emby-linkbutton" href="#">${ShowMore}</a>
|
||||
</div>
|
||||
<p id="itemBirthday"></p>
|
||||
<p id="itemBirthLocation"></p>
|
||||
<p id="itemDeathDate"></p>
|
||||
<p id="seriesAirTime"></p>
|
||||
|
||||
<div class="itemTags hide" style="margin: .7em 0;font-size:92%;"></div>
|
||||
<div class="itemExternalLinks hide" style="margin: .7em 0;font-size:92%;"></div>
|
||||
<div class="seriesRecordingEditor"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="seriesTimerScheduleSection verticalSection detailVerticalSection hide" style="margin-top:-3em;">
|
||||
<h2 class="sectionTitle">${HeaderSchedule}</h2>
|
||||
<div class="seriesTimerSchedule padded-right"></div>
|
||||
</div>
|
||||
|
||||
<div class="collectionItems hide"></div>
|
||||
|
||||
<div class="nextUpSection verticalSection detailVerticalSection hide">
|
||||
<h2 class="sectionTitle sectionTitle-cards">${HeaderNextUp}</h2>
|
||||
<div is="emby-itemscontainer" class="nextUpItems vertical-wrap padded-right"></div>
|
||||
</div>
|
||||
|
||||
<div class="programGuideSection hide verticalSection detailVerticalSection">
|
||||
<div class="programGuide"></div>
|
||||
</div>
|
||||
|
||||
<div id="childrenCollapsible" class="hide verticalSection detailVerticalSection">
|
||||
<h2 class="childrenSectionHeader sectionTitle sectionTitle-cards hide">
|
||||
<span id="childrenTitle"></span>
|
||||
</h2>
|
||||
<div id="childrenContent">
|
||||
<div is="emby-itemscontainer" class="childrenItemsContainer itemsContainer padded-right" style="text-align: left;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="additionalPartsCollapsible" class="verticalSection detailVerticalSection hide">
|
||||
<h2 class="sectionTitle sectionTitle-cards padded-right">${HeaderAdditionalParts}</h2>
|
||||
<div id="additionalPartsContent" is="emby-itemscontainer" class="itemsContainer vertical-wrap padded-right"></div>
|
||||
</div>
|
||||
|
||||
<div class="verticalSection detailVerticalSection moreFromSeasonSection hide">
|
||||
<h2 class="sectionTitle sectionTitle-cards padded-right"></h2>
|
||||
<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true">
|
||||
<div is="emby-itemscontainer" class="scrollSlider focuscontainer-x itemsContainer"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="verticalSection detailVerticalSection moreFromArtistSection hide">
|
||||
<h2 class="sectionTitle sectionTitle-cards padded-right"></h2>
|
||||
<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true">
|
||||
<div is="emby-itemscontainer" class="scrollSlider focuscontainer-x itemsContainer"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="castCollapsible" class="verticalSection detailVerticalSection hide">
|
||||
<h2 id="peopleHeader" class="sectionTitle sectionTitle-cards padded-right">${HeaderCastCrew}</h2>
|
||||
<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true">
|
||||
<div id="castContent" is="emby-itemscontainer" class="scrollSlider focuscontainer-x itemsContainer"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="seriesScheduleSection" class="verticalSection detailVerticalSection hide">
|
||||
<h2 class="sectionTitle padded-right">${HeaderUpcomingOnTV}</h2>
|
||||
<div id="seriesScheduleList" is="emby-itemscontainer" class="itemsContainer vertical-list padded-right"></div>
|
||||
</div>
|
||||
|
||||
<div id="specialsCollapsible" class="verticalSection detailVerticalSection hide">
|
||||
<h2 class="sectionTitle sectionTitle-cards padded-right">${HeaderSpecialFeatures}</h2>
|
||||
<div id="specialsContent" is="emby-itemscontainer" class="itemsContainer vertical-wrap padded-right"></div>
|
||||
</div>
|
||||
|
||||
<div id="musicVideosCollapsible" class="verticalSection detailVerticalSection hide">
|
||||
<h2 class="sectionTitle sectionTitle-cards padded-right">${HeaderMusicVideos}</h2>
|
||||
<div id="musicVideosContent" is="emby-itemscontainer" class="itemsContainer vertical-wrap padded-right"></div>
|
||||
</div>
|
||||
|
||||
<div id="scenesCollapsible" class="verticalSection detailVerticalSection verticalSection-extrabottompadding hide">
|
||||
<h2 class="sectionTitle sectionTitle-cards padded-right">${HeaderScenes}</h2>
|
||||
<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true">
|
||||
<div id="scenesContent" is="emby-itemscontainer" class="scrollSlider focuscontainer-x itemsContainer"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="similarCollapsible" class="verticalSection detailVerticalSection verticalSection-extrabottompadding hide">
|
||||
<h2 class="sectionTitle sectionTitle-cards padded-right">${HeaderMoreLikeThis}</h2>
|
||||
<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true">
|
||||
<div is="emby-itemscontainer" class="scrollSlider focuscontainer-x itemsContainer similarContent"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -28,15 +28,11 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
}
|
||||
|
||||
function hideAll(page, className, show) {
|
||||
var i;
|
||||
var length;
|
||||
var elems = page.querySelectorAll('.' + className);
|
||||
|
||||
for (i = 0, length = elems.length; i < length; i++) {
|
||||
for (const elem of page.querySelectorAll('.' + className)) {
|
||||
if (show) {
|
||||
elems[i].classList.remove('hide');
|
||||
elem.classList.remove('hide');
|
||||
} else {
|
||||
elems[i].classList.add('hide');
|
||||
elem.classList.add('hide');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -51,17 +47,19 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
positionTo: button,
|
||||
cancelTimer: false,
|
||||
record: false,
|
||||
deleteItem: true === item.IsFolder,
|
||||
deleteItem: item.CanDelete === true,
|
||||
shuffle: false,
|
||||
instantMix: false,
|
||||
user: user,
|
||||
share: true
|
||||
};
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
function getProgramScheduleHtml(items) {
|
||||
var html = '';
|
||||
|
||||
html += '<div is="emby-itemscontainer" class="itemsContainer vertical-list" data-contextmenu="false">';
|
||||
html += listView.getListViewHtml({
|
||||
items: items,
|
||||
|
@ -75,7 +73,10 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
moreButton: false,
|
||||
recordButton: false
|
||||
});
|
||||
return html += '</div>';
|
||||
|
||||
html += '</div>';
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
function renderSeriesTimerSchedule(page, apiClient, seriesTimerId) {
|
||||
|
@ -143,9 +144,12 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
|
||||
var mediaSources = item.MediaSources;
|
||||
instance._currentPlaybackMediaSources = mediaSources;
|
||||
|
||||
page.querySelector('.trackSelections').classList.remove('hide');
|
||||
select.setLabel(globalize.translate('LabelVersion'));
|
||||
|
||||
var currentValue = select.value;
|
||||
|
||||
var selectedId = mediaSources[0].Id;
|
||||
select.innerHTML = mediaSources.map(function (v) {
|
||||
var selected = v.Id === selectedId ? ' selected' : '';
|
||||
|
@ -163,7 +167,6 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
renderAudioSelections(page, mediaSources);
|
||||
renderSubtitleSelections(page, mediaSources);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function renderVideoSelections(page, mediaSources) {
|
||||
|
@ -171,9 +174,11 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
var mediaSource = mediaSources.filter(function (m) {
|
||||
return m.Id === mediaSourceId;
|
||||
})[0];
|
||||
|
||||
var tracks = mediaSource.MediaStreams.filter(function (m) {
|
||||
return 'Video' === m.Type;
|
||||
return m.Type === 'Video';
|
||||
});
|
||||
|
||||
var select = page.querySelector('.selectVideo');
|
||||
select.setLabel(globalize.translate('LabelVideo'));
|
||||
var selectedId = tracks.length ? tracks[0].Index : -1;
|
||||
|
@ -242,12 +247,24 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
select.setLabel(globalize.translate('LabelSubtitles'));
|
||||
var selectedId = null == mediaSource.DefaultSubtitleStreamIndex ? -1 : mediaSource.DefaultSubtitleStreamIndex;
|
||||
|
||||
if (tracks.length) {
|
||||
var videoTracks = mediaSource.MediaStreams.filter(function (m) {
|
||||
return 'Video' === m.Type;
|
||||
});
|
||||
|
||||
// This only makes sense on Video items
|
||||
if (videoTracks.length) {
|
||||
var selected = -1 === selectedId ? ' selected' : '';
|
||||
select.innerHTML = '<option value="-1">' + globalize.translate('Off') + '</option>' + tracks.map(function (v) {
|
||||
selected = v.Index === selectedId ? ' selected' : '';
|
||||
return '<option value="' + v.Index + '" ' + selected + '>' + v.DisplayTitle + '</option>';
|
||||
}).join('');
|
||||
|
||||
if (tracks.length > 0) {
|
||||
select.removeAttribute('disabled');
|
||||
} else {
|
||||
select.setAttribute('disabled', 'disabled');
|
||||
}
|
||||
|
||||
page.querySelector('.selectSubtitlesContainer').classList.remove('hide');
|
||||
} else {
|
||||
select.innerHTML = '';
|
||||
|
@ -278,7 +295,15 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
var enableShuffle = item.IsFolder || -1 !== ['MusicAlbum', 'MusicGenre', 'MusicArtist'].indexOf(item.Type);
|
||||
hideAll(page, 'btnShuffle', enableShuffle);
|
||||
canPlay = true;
|
||||
hideAll(page, 'btnResume', item.UserData && item.UserData.PlaybackPositionTicks > 0);
|
||||
|
||||
const isResumable = item.UserData && item.UserData.PlaybackPositionTicks > 0;
|
||||
hideAll(page, 'btnResume', isResumable);
|
||||
|
||||
if (isResumable) {
|
||||
for (const elem of page.querySelectorAll('.btnPlay')) {
|
||||
elem.querySelector('.detailButton-icon').classList.replace('play_arrow', 'replay');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
hideAll(page, 'btnPlay');
|
||||
hideAll(page, 'btnResume');
|
||||
|
@ -324,8 +349,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
function getArtistLinksHtml(artists, serverId, context) {
|
||||
var html = [];
|
||||
|
||||
for (var i = 0, length = artists.length; i < length; i++) {
|
||||
var artist = artists[i];
|
||||
for (const artist of artists) {
|
||||
var href = appRouter.getRouteUrl(artist, {
|
||||
context: context,
|
||||
itemType: 'MusicArtist',
|
||||
|
@ -333,10 +357,18 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
});
|
||||
html.push('<a style="color:inherit;" class="button-link" is="emby-linkbutton" href="' + href + '">' + artist.Name + '</a>');
|
||||
}
|
||||
html = html.join(' / ');
|
||||
|
||||
return html = html.join(' / ');
|
||||
return html;
|
||||
}
|
||||
function renderName(item, container, isStatic, context) {
|
||||
|
||||
/**
|
||||
* Renders the item's name block
|
||||
* @param {Object} item - Item used to render the name.
|
||||
* @param {HTMLDivElement} container - Container to render the information into.
|
||||
* @param {Object} context - Application context.
|
||||
*/
|
||||
function renderName(item, container, context) {
|
||||
var parentRoute;
|
||||
var parentNameHtml = [];
|
||||
var parentNameLast = false;
|
||||
|
@ -410,16 +442,12 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
if (parentNameLast) {
|
||||
// Music
|
||||
if (layoutManager.mobile) {
|
||||
html = '<h3 class="parentName" style="margin: .25em 0;">' + parentNameHtml.join('</br>') + '</h3>';
|
||||
html = '<h3 class="parentName musicParentName">' + parentNameHtml.join('</br>') + '</h3>';
|
||||
} else {
|
||||
html = '<h3 class="parentName" style="margin: .25em 0;">' + parentNameHtml.join(' - ') + '</h3>';
|
||||
html = '<h3 class="parentName musicParentName">' + parentNameHtml.join(' - ') + '</h3>';
|
||||
}
|
||||
} else {
|
||||
if (layoutManager.mobile) {
|
||||
html = '<h1 class="parentName" style="margin: 0.2em 0 0">' + parentNameHtml.join('</br>') + '</h1>';
|
||||
} else {
|
||||
html = '<h1 class="parentName" style="margin: 0.2em 0 0">' + tvShowHtml + '</h1>';
|
||||
}
|
||||
html = '<h1 class="parentName">' + tvShowHtml + '</h1>';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -428,17 +456,19 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
});
|
||||
|
||||
if (html && !parentNameLast) {
|
||||
if (!layoutManager.mobile && tvSeasonHtml) {
|
||||
html += '<h3 class="itemName infoText" style="margin: 0.2em 0 0">' + tvSeasonHtml + ' - ' + name + '</h3>';
|
||||
if (tvSeasonHtml) {
|
||||
html += '<h3 class="itemName infoText subtitle">' + tvSeasonHtml + ' - ' + name + '</h3>';
|
||||
} else {
|
||||
html += '<h3 class="itemName infoText" style="margin: 0.2em 0 0">' + name + '</h3>';
|
||||
html += '<h3 class="itemName infoText subtitle">' + name + '</h3>';
|
||||
}
|
||||
} else if (item.OriginalTitle && item.OriginalTitle != item.Name) {
|
||||
html = '<h1 class="itemName infoText parentNameLast withOriginalTitle">' + name + '</h1>' + html;
|
||||
} else {
|
||||
html = '<h1 class="itemName infoText" style="margin: 0.4em 0 0">' + name + '</h1>' + html;
|
||||
html = '<h1 class="itemName infoText parentNameLast">' + name + '</h1>' + html;
|
||||
}
|
||||
|
||||
if (item.OriginalTitle && item.OriginalTitle != item.Name) {
|
||||
html += '<h4 class="itemName infoText" style="margin: 0 0 0;">' + item.OriginalTitle + '</h4>';
|
||||
html += '<h4 class="itemName infoText originalTitle">' + item.OriginalTitle + '</h4>';
|
||||
}
|
||||
|
||||
container.innerHTML = html;
|
||||
|
@ -470,43 +500,18 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
var imgUrl;
|
||||
var hasbackdrop = false;
|
||||
var itemBackdropElement = page.querySelector('#itemBackdrop');
|
||||
var usePrimaryImage = item.MediaType === 'Video' && item.Type !== 'Movie' && item.Type !== 'Trailer' ||
|
||||
item.MediaType && item.MediaType !== 'Video' ||
|
||||
item.Type === 'MusicAlbum' ||
|
||||
item.Type === 'Person';
|
||||
|
||||
if (!layoutManager.mobile && !userSettings.detailsBanner()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ('Program' === item.Type && item.ImageTags && item.ImageTags.Thumb) {
|
||||
imgUrl = apiClient.getScaledImageUrl(item.Id, {
|
||||
type: 'Thumb',
|
||||
maxWidth: dom.getScreenWidth(),
|
||||
index: 0,
|
||||
tag: item.ImageTags.Thumb
|
||||
});
|
||||
page.classList.remove('noBackdrop');
|
||||
imageLoader.lazyImage(itemBackdropElement, imgUrl);
|
||||
hasbackdrop = true;
|
||||
} else if (usePrimaryImage && item.ImageTags && item.ImageTags.Primary) {
|
||||
imgUrl = apiClient.getScaledImageUrl(item.Id, {
|
||||
type: 'Primary',
|
||||
maxWidth: dom.getScreenWidth(),
|
||||
index: 0,
|
||||
tag: item.ImageTags.Primary
|
||||
});
|
||||
page.classList.remove('noBackdrop');
|
||||
imageLoader.lazyImage(itemBackdropElement, imgUrl);
|
||||
hasbackdrop = true;
|
||||
} else if (item.BackdropImageTags && item.BackdropImageTags.length) {
|
||||
if (item.BackdropImageTags && item.BackdropImageTags.length) {
|
||||
imgUrl = apiClient.getScaledImageUrl(item.Id, {
|
||||
type: 'Backdrop',
|
||||
maxWidth: dom.getScreenWidth(),
|
||||
index: 0,
|
||||
tag: item.BackdropImageTags[0]
|
||||
});
|
||||
page.classList.remove('noBackdrop');
|
||||
imageLoader.lazyImage(itemBackdropElement, imgUrl);
|
||||
hasbackdrop = true;
|
||||
} else if (item.ParentBackdropItemId && item.ParentBackdropImageTags && item.ParentBackdropImageTags.length) {
|
||||
|
@ -516,50 +521,35 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
index: 0,
|
||||
tag: item.ParentBackdropImageTags[0]
|
||||
});
|
||||
page.classList.remove('noBackdrop');
|
||||
imageLoader.lazyImage(itemBackdropElement, imgUrl);
|
||||
hasbackdrop = true;
|
||||
} else if (item.ImageTags && item.ImageTags.Thumb) {
|
||||
imgUrl = apiClient.getScaledImageUrl(item.Id, {
|
||||
type: 'Thumb',
|
||||
maxWidth: dom.getScreenWidth(),
|
||||
index: 0,
|
||||
tag: item.ImageTags.Thumb
|
||||
});
|
||||
page.classList.remove('noBackdrop');
|
||||
imageLoader.lazyImage(itemBackdropElement, imgUrl);
|
||||
hasbackdrop = true;
|
||||
} else {
|
||||
itemBackdropElement.style.backgroundImage = '';
|
||||
}
|
||||
|
||||
if ('Person' === item.Type) {
|
||||
// FIXME: This hides the backdrop on all persons to fix a margin issue. Ideally, a proper fix should be made.
|
||||
page.classList.add('noBackdrop');
|
||||
itemBackdropElement.classList.add('personBackdrop');
|
||||
} else {
|
||||
itemBackdropElement.classList.remove('personBackdrop');
|
||||
}
|
||||
|
||||
return hasbackdrop;
|
||||
}
|
||||
|
||||
function reloadFromItem(instance, page, params, item, user) {
|
||||
var context = params.context;
|
||||
page.querySelector('.detailPagePrimaryContainer').classList.add('detailSticky');
|
||||
const apiClient = connectionManager.getApiClient(item.ServerId);
|
||||
|
||||
renderName(item, page.querySelector('.nameContainer'), false, context);
|
||||
var apiClient = connectionManager.getApiClient(item.ServerId);
|
||||
renderSeriesTimerEditor(page, item, apiClient, user);
|
||||
renderTimerEditor(page, item, apiClient, user);
|
||||
renderImage(page, item, apiClient, user);
|
||||
renderLogo(page, item, apiClient);
|
||||
Emby.Page.setTitle('');
|
||||
setInitialCollapsibleState(page, item, apiClient, context, user);
|
||||
renderDetails(page, item, apiClient, context);
|
||||
renderTrackSelections(page, instance, item);
|
||||
|
||||
// Start rendering the artwork first
|
||||
renderImage(page, item);
|
||||
renderLogo(page, item, apiClient);
|
||||
renderBackdrop(item);
|
||||
renderDetailPageBackdrop(page, item, apiClient);
|
||||
|
||||
// Render the main information for the item
|
||||
page.querySelector('.detailPagePrimaryContainer').classList.add('detailRibbon');
|
||||
renderName(item, page.querySelector('.nameContainer'), params.context);
|
||||
renderDetails(page, item, apiClient, params.context);
|
||||
renderTrackSelections(page, instance, item);
|
||||
|
||||
renderSeriesTimerEditor(page, item, apiClient, user);
|
||||
renderTimerEditor(page, item, apiClient, user);
|
||||
setInitialCollapsibleState(page, item, apiClient, params.context, user);
|
||||
var canPlay = reloadPlayButtons(page, item);
|
||||
|
||||
if ((item.LocalTrailerCount || item.RemoteTrailers && item.RemoteTrailers.length) && -1 !== playbackManager.getSupportedCommands().indexOf('PlayTrailers')) {
|
||||
|
@ -570,12 +560,6 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
|
||||
setTrailerButtonVisibility(page, item);
|
||||
|
||||
if (item.CanDelete && !item.IsFolder) {
|
||||
hideAll(page, 'btnDeleteItem', true);
|
||||
} else {
|
||||
hideAll(page, 'btnDeleteItem');
|
||||
}
|
||||
|
||||
if ('Program' !== item.Type || canPlay) {
|
||||
hideAll(page, 'mainDetailButtons', true);
|
||||
} else {
|
||||
|
@ -667,18 +651,15 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
}
|
||||
|
||||
function renderLogo(page, item, apiClient) {
|
||||
var url = logoImageUrl(item, apiClient, {
|
||||
maxWidth: 400
|
||||
});
|
||||
var detailLogo = page.querySelector('.detailLogo');
|
||||
|
||||
var url = logoImageUrl(item, apiClient, {});
|
||||
|
||||
if (!layoutManager.mobile && !userSettings.enableBackdrops()) {
|
||||
detailLogo.classList.add('hide');
|
||||
} else if (url) {
|
||||
detailLogo.classList.remove('hide');
|
||||
detailLogo.classList.add('lazy');
|
||||
detailLogo.setAttribute('data-src', url);
|
||||
imageLoader.lazyImage(detailLogo);
|
||||
imageLoader.setLazyImage(detailLogo, url);
|
||||
} else {
|
||||
detailLogo.classList.add('hide');
|
||||
}
|
||||
|
@ -704,172 +685,59 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
}
|
||||
}
|
||||
|
||||
function renderLinks(linksElem, item) {
|
||||
var html = [];
|
||||
function renderLinks(page, item) {
|
||||
var externalLinksElem = page.querySelector('.itemExternalLinks');
|
||||
|
||||
var links = [];
|
||||
|
||||
if (!layoutManager.tv && item.HomePageUrl) {
|
||||
links.push('<a style="color:inherit;" is="emby-linkbutton" class="button-link" href="' + item.HomePageUrl + '" target="_blank">' + globalize.translate('ButtonWebsite') + '</a>');
|
||||
links.push(`<a is="emby-linkbutton" class="button-link" href="${item.HomePageUrl}" target="_blank">${globalize.translate('ButtonWebsite')}</a>`);
|
||||
}
|
||||
|
||||
if (item.ExternalUrls) {
|
||||
for (var i = 0, length = item.ExternalUrls.length; i < length; i++) {
|
||||
var url = item.ExternalUrls[i];
|
||||
links.push('<a style="color:inherit;" is="emby-linkbutton" class="button-link" href="' + url.Url + '" target="_blank">' + url.Name + '</a>');
|
||||
for (const url of item.ExternalUrls) {
|
||||
links.push(`<a is="emby-linkbutton" class="button-link" href="${url.Url}" target="_blank">${url.Name}</a>`);
|
||||
}
|
||||
}
|
||||
|
||||
var html = [];
|
||||
if (links.length) {
|
||||
html.push(links.join(', '));
|
||||
}
|
||||
|
||||
linksElem.innerHTML = html.join(', ');
|
||||
externalLinksElem.innerHTML = html.join(', ');
|
||||
|
||||
if (html.length) {
|
||||
linksElem.classList.remove('hide');
|
||||
externalLinksElem.classList.remove('hide');
|
||||
} else {
|
||||
linksElem.classList.add('hide');
|
||||
externalLinksElem.classList.add('hide');
|
||||
}
|
||||
}
|
||||
|
||||
function renderDetailImage(page, elem, item, apiClient, editable, imageLoader, indicators) {
|
||||
if ('SeriesTimer' === item.Type || 'Program' === item.Type) {
|
||||
editable = false;
|
||||
}
|
||||
function renderDetailImage(elem, item, imageLoader) {
|
||||
const itemArray = [];
|
||||
itemArray.push(item);
|
||||
const cardHtml = cardBuilder.getCardsHtml(itemArray, {
|
||||
shape: 'auto',
|
||||
showTitle: false,
|
||||
centerText: true,
|
||||
overlayText: false,
|
||||
transition: false,
|
||||
disableIndicators: true,
|
||||
disableHoverMenu: true,
|
||||
overlayPlayButton: true,
|
||||
width: dom.getWindowSize().innerWidth * 0.5
|
||||
});
|
||||
|
||||
elem.classList.add('detailimg-hidemobile');
|
||||
|
||||
var imageTags = item.ImageTags || {};
|
||||
|
||||
if (item.PrimaryImageTag) {
|
||||
imageTags.Primary = item.PrimaryImageTag;
|
||||
}
|
||||
|
||||
var url;
|
||||
var html = '';
|
||||
var shape = 'portrait';
|
||||
var detectRatio = false;
|
||||
|
||||
/* In the following section, getScreenWidth() is multiplied by 0.5 as the posters
|
||||
are 25vw and we need double the resolution to counter Skia's scaling. */
|
||||
// TODO: Find a reliable way to get the poster width
|
||||
if (imageTags.Primary) {
|
||||
url = apiClient.getScaledImageUrl(item.Id, {
|
||||
type: 'Primary',
|
||||
maxWidth: Math.round(dom.getScreenWidth() * 0.5),
|
||||
tag: item.ImageTags.Primary
|
||||
});
|
||||
detectRatio = true;
|
||||
} else if (item.BackdropImageTags && item.BackdropImageTags.length) {
|
||||
url = apiClient.getScaledImageUrl(item.Id, {
|
||||
type: 'Backdrop',
|
||||
maxWidth: Math.round(dom.getScreenWidth() * 0.5),
|
||||
tag: item.BackdropImageTags[0]
|
||||
});
|
||||
shape = 'thumb';
|
||||
} else if (imageTags.Thumb) {
|
||||
url = apiClient.getScaledImageUrl(item.Id, {
|
||||
type: 'Thumb',
|
||||
maxWidth: Math.round(dom.getScreenWidth() * 0.5),
|
||||
tag: item.ImageTags.Thumb
|
||||
});
|
||||
shape = 'thumb';
|
||||
} else if (imageTags.Disc) {
|
||||
url = apiClient.getScaledImageUrl(item.Id, {
|
||||
type: 'Disc',
|
||||
maxWidth: Math.round(dom.getScreenWidth() * 0.5),
|
||||
tag: item.ImageTags.Disc
|
||||
});
|
||||
shape = 'square';
|
||||
} else if (item.AlbumId && item.AlbumPrimaryImageTag) {
|
||||
url = apiClient.getScaledImageUrl(item.AlbumId, {
|
||||
type: 'Primary',
|
||||
maxWidth: Math.round(dom.getScreenWidth() * 0.5),
|
||||
tag: item.AlbumPrimaryImageTag
|
||||
});
|
||||
shape = 'square';
|
||||
} else if (item.SeriesId && item.SeriesPrimaryImageTag) {
|
||||
url = apiClient.getScaledImageUrl(item.SeriesId, {
|
||||
type: 'Primary',
|
||||
maxWidth: Math.round(dom.getScreenWidth() * 0.5),
|
||||
tag: item.SeriesPrimaryImageTag
|
||||
});
|
||||
} else if (item.ParentPrimaryImageItemId && item.ParentPrimaryImageTag) {
|
||||
url = apiClient.getScaledImageUrl(item.ParentPrimaryImageItemId, {
|
||||
type: 'Primary',
|
||||
maxWidth: Math.round(dom.getScreenWidth() * 0.5),
|
||||
tag: item.ParentPrimaryImageTag
|
||||
});
|
||||
}
|
||||
|
||||
if (editable && url === undefined) {
|
||||
html += "<a class='itemDetailGalleryLink itemDetailImage defaultCardBackground defaultCardBackground" + cardBuilder.getDefaultBackgroundClass(item.Name) + "' is='emby-linkbutton' style='display:block;margin:0;padding:0;' href='#'>";
|
||||
} else if (!editable && url === undefined) {
|
||||
html += "<div class='itemDetailGalleryLink itemDetailImage defaultCardBackground defaultCardBackground" + cardBuilder.getDefaultBackgroundClass(item.Name) + "' is='emby-linkbutton' style='display:block;margin:0;padding:0;' href='#'>";
|
||||
} else if (editable) {
|
||||
html += "<a class='itemDetailGalleryLink' is='emby-linkbutton' style='display:block;margin:0;padding:0;' href='#'>";
|
||||
}
|
||||
|
||||
if (url) {
|
||||
html += "<img class='itemDetailImage lazy' src='data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=' />";
|
||||
}
|
||||
|
||||
if (url === undefined) {
|
||||
html += cardBuilder.getDefaultText(item);
|
||||
}
|
||||
|
||||
if (editable) {
|
||||
html += '</a>';
|
||||
} else if (!editable && url === undefined) {
|
||||
html += '</div>';
|
||||
}
|
||||
|
||||
var progressHtml = item.IsFolder || !item.UserData ? '' : indicators.getProgressBarHtml(item);
|
||||
html += '<div class="detailImageProgressContainer">';
|
||||
|
||||
if (progressHtml) {
|
||||
html += progressHtml;
|
||||
}
|
||||
|
||||
html += '</div>';
|
||||
elem.innerHTML = html;
|
||||
|
||||
if (detectRatio && item.PrimaryImageAspectRatio) {
|
||||
if (item.PrimaryImageAspectRatio >= 1.48) {
|
||||
shape = 'thumb';
|
||||
} else if (item.PrimaryImageAspectRatio >= 0.85 && item.PrimaryImageAspectRatio <= 1.34) {
|
||||
shape = 'square';
|
||||
}
|
||||
}
|
||||
|
||||
if ('thumb' == shape) {
|
||||
elem.classList.add('thumbDetailImageContainer');
|
||||
elem.classList.remove('portraitDetailImageContainer');
|
||||
elem.classList.remove('squareDetailImageContainer');
|
||||
} else if ('square' == shape) {
|
||||
elem.classList.remove('thumbDetailImageContainer');
|
||||
elem.classList.remove('portraitDetailImageContainer');
|
||||
elem.classList.add('squareDetailImageContainer');
|
||||
} else {
|
||||
elem.classList.remove('thumbDetailImageContainer');
|
||||
elem.classList.add('portraitDetailImageContainer');
|
||||
elem.classList.remove('squareDetailImageContainer');
|
||||
}
|
||||
|
||||
if (url) {
|
||||
imageLoader.lazyImage(elem.querySelector('img'), url);
|
||||
}
|
||||
elem.innerHTML = cardHtml;
|
||||
imageLoader.lazyChildren(elem);
|
||||
}
|
||||
|
||||
function renderImage(page, item, apiClient, user) {
|
||||
function renderImage(page, item) {
|
||||
renderDetailImage(
|
||||
page,
|
||||
page.querySelector('.detailImageContainer'),
|
||||
item,
|
||||
apiClient,
|
||||
user.Policy.IsAdministrator && 'Photo' != item.MediaType,
|
||||
imageLoader,
|
||||
indicators
|
||||
imageLoader
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -985,54 +853,41 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
}
|
||||
}
|
||||
|
||||
function renderOverview(elems, item) {
|
||||
for (var i = 0, length = elems.length; i < length; i++) {
|
||||
var elem = elems[i];
|
||||
function renderOverview(page, item) {
|
||||
for (const overviewElemnt of page.querySelectorAll('.overview')) {
|
||||
var overview = item.Overview || '';
|
||||
|
||||
if (overview) {
|
||||
elem.innerHTML = overview;
|
||||
elem.classList.remove('hide');
|
||||
elem.classList.add('detail-clamp-text');
|
||||
overviewElemnt.innerHTML = overview;
|
||||
overviewElemnt.classList.remove('hide');
|
||||
overviewElemnt.classList.add('detail-clamp-text');
|
||||
|
||||
// Grab the sibling element to control the expand state
|
||||
var expandButton = elem.parentElement.querySelector('.overview-expand');
|
||||
var expandButton = overviewElemnt.parentElement.querySelector('.overview-expand');
|
||||
|
||||
// Detect if we have overflow of text. Based on this StackOverflow answer
|
||||
// https://stackoverflow.com/a/35157976
|
||||
if (Math.abs(elem.scrollHeight - elem.offsetHeight) > 2) {
|
||||
if (Math.abs(overviewElemnt.scrollHeight - overviewElemnt.offsetHeight) > 2) {
|
||||
expandButton.classList.remove('hide');
|
||||
} else {
|
||||
expandButton.classList.add('hide');
|
||||
}
|
||||
|
||||
expandButton.addEventListener('click', toggleLineClamp.bind(null, elem));
|
||||
expandButton.addEventListener('click', toggleLineClamp.bind(null, overviewElemnt));
|
||||
|
||||
var anchors = elem.querySelectorAll('a');
|
||||
|
||||
for (var j = 0, length2 = anchors.length; j < length2; j++) {
|
||||
anchors[j].setAttribute('target', '_blank');
|
||||
for (const anchor of overviewElemnt.querySelectorAll('a')) {
|
||||
anchor.setAttribute('target', '_blank');
|
||||
}
|
||||
} else {
|
||||
elem.innerHTML = '';
|
||||
elem.classList.add('hide');
|
||||
overviewElemnt.innerHTML = '';
|
||||
overviewElemnt.classList.add('hide');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function renderGenres(page, item, context) {
|
||||
context = context || inferContext(item);
|
||||
var type;
|
||||
function renderGenres(page, item, context = inferContext(item)) {
|
||||
var genres = item.GenreItems || [];
|
||||
|
||||
switch (context) {
|
||||
case 'music':
|
||||
type = 'MusicGenre';
|
||||
break;
|
||||
|
||||
default:
|
||||
type = 'Genre';
|
||||
}
|
||||
var type = context === 'music' ? 'MusicGenre' : 'Genre';
|
||||
|
||||
var html = genres.map(function (p) {
|
||||
return '<a style="color:inherit;" class="button-link" is="emby-linkbutton" href="' + appRouter.getRouteUrl({
|
||||
|
@ -1058,19 +913,49 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
}
|
||||
}
|
||||
|
||||
function renderDirector(page, item, context) {
|
||||
var directors = (item.People || []).filter(function (p) {
|
||||
return 'Director' === p.Type;
|
||||
function renderWriter(page, item, context) {
|
||||
var writers = (item.People || []).filter(function (person) {
|
||||
return person.Type === 'Writer';
|
||||
});
|
||||
var html = directors.map(function (p) {
|
||||
|
||||
var html = writers.map(function (person) {
|
||||
return '<a style="color:inherit;" class="button-link" is="emby-linkbutton" href="' + appRouter.getRouteUrl({
|
||||
Name: p.Name,
|
||||
Name: person.Name,
|
||||
Type: 'Person',
|
||||
ServerId: item.ServerId,
|
||||
Id: p.Id
|
||||
Id: person.Id
|
||||
}, {
|
||||
context: context
|
||||
}) + '">' + p.Name + '</a>';
|
||||
}) + '">' + person.Name + '</a>';
|
||||
}).join(', ');
|
||||
|
||||
var writersLabel = page.querySelector('.writersLabel');
|
||||
writersLabel.innerHTML = globalize.translate(writers.length > 1 ? 'Writers' : 'Writer');
|
||||
var writersValue = page.querySelector('.writers');
|
||||
writersValue.innerHTML = html;
|
||||
|
||||
var writersGroup = page.querySelector('.writersGroup');
|
||||
if (writers.length) {
|
||||
writersGroup.classList.remove('hide');
|
||||
} else {
|
||||
writersGroup.classList.add('hide');
|
||||
}
|
||||
}
|
||||
|
||||
function renderDirector(page, item, context) {
|
||||
var directors = (item.People || []).filter(function (person) {
|
||||
return person.Type === 'Director';
|
||||
});
|
||||
|
||||
var html = directors.map(function (person) {
|
||||
return '<a style="color:inherit;" class="button-link" is="emby-linkbutton" href="' + appRouter.getRouteUrl({
|
||||
Name: person.Name,
|
||||
Type: 'Person',
|
||||
ServerId: item.ServerId,
|
||||
Id: person.Id
|
||||
}, {
|
||||
context: context
|
||||
}) + '">' + person.Name + '</a>';
|
||||
}).join(', ');
|
||||
|
||||
var directorsLabel = page.querySelector('.directorsLabel');
|
||||
|
@ -1086,13 +971,39 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
}
|
||||
}
|
||||
|
||||
function renderDetails(page, item, apiClient, context, isStatic) {
|
||||
renderSimilarItems(page, item, context);
|
||||
renderMoreFromSeason(page, item, apiClient);
|
||||
renderMoreFromArtist(page, item, apiClient);
|
||||
renderDirector(page, item, context);
|
||||
renderGenres(page, item, context);
|
||||
renderChannelGuide(page, apiClient, item);
|
||||
function renderMiscInfo(page, item) {
|
||||
const primaryItemMiscInfo = page.querySelectorAll('.itemMiscInfo-primary');
|
||||
|
||||
for (const miscInfo of primaryItemMiscInfo) {
|
||||
mediaInfo.fillPrimaryMediaInfo(miscInfo, item, {
|
||||
interactive: true,
|
||||
episodeTitle: false,
|
||||
subtitles: false
|
||||
});
|
||||
|
||||
if (miscInfo.innerHTML && 'SeriesTimer' !== item.Type) {
|
||||
miscInfo.classList.remove('hide');
|
||||
} else {
|
||||
miscInfo.classList.add('hide');
|
||||
}
|
||||
}
|
||||
|
||||
const secondaryItemMiscInfo = page.querySelectorAll('.itemMiscInfo-secondary');
|
||||
|
||||
for (const miscInfo of secondaryItemMiscInfo) {
|
||||
mediaInfo.fillSecondaryMediaInfo(miscInfo, item, {
|
||||
interactive: true
|
||||
});
|
||||
|
||||
if (miscInfo.innerHTML && 'SeriesTimer' !== item.Type) {
|
||||
miscInfo.classList.remove('hide');
|
||||
} else {
|
||||
miscInfo.classList.add('hide');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function renderTagline(page, item) {
|
||||
var taglineElement = page.querySelector('.tagline');
|
||||
|
||||
if (item.Taglines && item.Taglines.length) {
|
||||
|
@ -1101,44 +1012,21 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
} else {
|
||||
taglineElement.classList.add('hide');
|
||||
}
|
||||
}
|
||||
|
||||
var overview = page.querySelector('.overview');
|
||||
var externalLinksElem = page.querySelector('.itemExternalLinks');
|
||||
|
||||
renderOverview([overview], item);
|
||||
|
||||
var i;
|
||||
var itemMiscInfo;
|
||||
itemMiscInfo = page.querySelectorAll('.itemMiscInfo-primary');
|
||||
for (i = 0; i < itemMiscInfo.length; i++) {
|
||||
mediaInfo.fillPrimaryMediaInfo(itemMiscInfo[i], item, {
|
||||
interactive: true,
|
||||
episodeTitle: false,
|
||||
subtitles: false
|
||||
});
|
||||
|
||||
if (itemMiscInfo[i].innerHTML && 'SeriesTimer' !== item.Type) {
|
||||
itemMiscInfo[i].classList.remove('hide');
|
||||
} else {
|
||||
itemMiscInfo[i].classList.add('hide');
|
||||
}
|
||||
}
|
||||
|
||||
itemMiscInfo = page.querySelectorAll('.itemMiscInfo-secondary');
|
||||
for (i = 0; i < itemMiscInfo.length; i++) {
|
||||
mediaInfo.fillSecondaryMediaInfo(itemMiscInfo[i], item, {
|
||||
interactive: true
|
||||
});
|
||||
|
||||
if (itemMiscInfo[i].innerHTML && 'SeriesTimer' !== item.Type) {
|
||||
itemMiscInfo[i].classList.remove('hide');
|
||||
} else {
|
||||
itemMiscInfo[i].classList.add('hide');
|
||||
}
|
||||
}
|
||||
|
||||
function renderDetails(page, item, apiClient, context, isStatic) {
|
||||
renderSimilarItems(page, item, context);
|
||||
renderMoreFromSeason(page, item, apiClient);
|
||||
renderMoreFromArtist(page, item, apiClient);
|
||||
renderDirector(page, item, context);
|
||||
renderWriter(page, item, context);
|
||||
renderGenres(page, item, context);
|
||||
renderChannelGuide(page, apiClient, item);
|
||||
renderTagline(page, item);
|
||||
renderOverview(page, item);
|
||||
renderMiscInfo(page, item);
|
||||
reloadUserDataButtons(page, item);
|
||||
renderLinks(externalLinksElem, item);
|
||||
renderLinks(page, item);
|
||||
renderTags(page, item);
|
||||
renderSeriesAirTime(page, item, isStatic);
|
||||
}
|
||||
|
@ -1426,8 +1314,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
action: 'playallfromhere',
|
||||
image: false,
|
||||
artist: 'auto',
|
||||
containerAlbumArtists: item.AlbumArtists,
|
||||
addToListButton: true
|
||||
containerAlbumArtists: item.AlbumArtists
|
||||
});
|
||||
isList = true;
|
||||
} else if ('Series' == item.Type) {
|
||||
|
@ -1469,11 +1356,12 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
items: result.Items,
|
||||
showIndexNumber: false,
|
||||
enableOverview: true,
|
||||
enablePlayedButton: layoutManager.mobile ? false : true,
|
||||
infoButton: layoutManager.mobile ? false : true,
|
||||
imageSize: 'large',
|
||||
enableSideMediaInfo: false,
|
||||
highlight: false,
|
||||
action: layoutManager.tv ? 'resume' : 'none',
|
||||
infoButton: true,
|
||||
action: !layoutManager.desktop ? 'link' : 'none',
|
||||
imagePlayButton: true,
|
||||
includeParentInfoInTitle: false
|
||||
});
|
||||
|
@ -1500,6 +1388,9 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
childrenItemsContainer.classList.remove('vertical-list');
|
||||
}
|
||||
}
|
||||
if (layoutManager.mobile) {
|
||||
childrenItemsContainer.classList.remove('padded-right');
|
||||
}
|
||||
childrenItemsContainer.innerHTML = html;
|
||||
imageLoader.lazyChildren(childrenItemsContainer);
|
||||
if ('BoxSet' == item.Type) {
|
||||
|
@ -1701,12 +1592,10 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
}
|
||||
|
||||
function renderCollectionItems(page, parentItem, types, items) {
|
||||
page.querySelector('.collectionItems').classList.remove('hide');
|
||||
page.querySelector('.collectionItems').innerHTML = '';
|
||||
var i;
|
||||
var length;
|
||||
|
||||
for (i = 0, length = types.length; i < length; i++) {
|
||||
var type = types[i];
|
||||
for (const type of types) {
|
||||
var typeItems = filterItemsByCollectionItemType(items, type);
|
||||
|
||||
if (typeItems.length) {
|
||||
|
@ -1739,8 +1628,8 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
renderChildren(page, parentItem);
|
||||
};
|
||||
|
||||
for (i = 0, length = containers.length; i < length; i++) {
|
||||
containers[i].notifyRefreshNeeded = notifyRefreshNeeded;
|
||||
for (const container of containers) {
|
||||
container.notifyRefreshNeeded = notifyRefreshNeeded;
|
||||
}
|
||||
|
||||
// if nothing in the collection can be played hide play and shuffle buttons
|
||||
|
@ -1876,7 +1765,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
|
||||
function renderCast(page, item) {
|
||||
var people = (item.People || []).filter(function (p) {
|
||||
return 'Director' !== p.Type;
|
||||
return p.Type === 'Actor';
|
||||
});
|
||||
|
||||
if (!people.length) {
|
||||
|
@ -1905,12 +1794,10 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
}
|
||||
|
||||
function bindAll(view, selector, eventName, fn) {
|
||||
var i;
|
||||
var length;
|
||||
var elems = view.querySelectorAll(selector);
|
||||
|
||||
for (i = 0, length = elems.length; i < length; i++) {
|
||||
elems[i].addEventListener(eventName, fn);
|
||||
for (const elem of elems) {
|
||||
elem.addEventListener(eventName, fn);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1923,13 +1810,14 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
return function (view, params) {
|
||||
function reload(instance, page, params) {
|
||||
loading.show();
|
||||
|
||||
var apiClient = params.serverId ? connectionManager.getApiClient(params.serverId) : ApiClient;
|
||||
var promises = [getPromise(apiClient, params), apiClient.getCurrentUser()];
|
||||
Promise.all(promises).then(function (responses) {
|
||||
var item = responses[0];
|
||||
var user = responses[1];
|
||||
|
||||
Promise.all([getPromise(apiClient, params), apiClient.getCurrentUser()]).then(([item, user]) => {
|
||||
currentItem = item;
|
||||
reloadFromItem(instance, page, params, item, user);
|
||||
}).catch((error) => {
|
||||
console.error('failed to get item or current user: ', error);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1980,7 +1868,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
});
|
||||
}
|
||||
|
||||
playItem(item, item.UserData && 'resume' === mode ? item.UserData.PlaybackPositionTicks : 0);
|
||||
playItem(item, item.UserData && mode === 'resume' ? item.UserData.PlaybackPositionTicks : 0);
|
||||
}
|
||||
|
||||
function onPlayClick() {
|
||||
|
@ -1995,15 +1883,6 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
playbackManager.shuffle(currentItem);
|
||||
}
|
||||
|
||||
function onDeleteClick() {
|
||||
require(['deleteHelper'], function (deleteHelper) {
|
||||
deleteHelper.deleteItem({
|
||||
item: currentItem,
|
||||
navigate: true
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function onCancelSeriesTimerClick() {
|
||||
require(['recordingHelper'], function (recordingHelper) {
|
||||
recordingHelper.cancelSeriesTimerWithConfirmation(currentItem.Id, currentItem.ServerId).then(function () {
|
||||
|
@ -2092,7 +1971,6 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
bindAll(view, '.btnPlayTrailer', 'click', onPlayTrailerClick);
|
||||
bindAll(view, '.btnCancelSeriesTimer', 'click', onCancelSeriesTimerClick);
|
||||
bindAll(view, '.btnCancelTimer', 'click', onCancelTimerClick);
|
||||
bindAll(view, '.btnDeleteItem', 'click', onDeleteClick);
|
||||
bindAll(view, '.btnDownload', 'click', onDownloadClick);
|
||||
view.querySelector('.trackSelections').addEventListener('submit', onTrackSelectionsSubmit);
|
||||
view.querySelector('.btnSplitVersions').addEventListener('click', function () {
|
||||
|
@ -2125,9 +2003,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
|||
view.addEventListener('viewshow', function (e) {
|
||||
var page = this;
|
||||
|
||||
if (layoutManager.mobile) {
|
||||
libraryMenu.setTransparentMenu(true);
|
||||
}
|
||||
libraryMenu.setTransparentMenu(true);
|
||||
|
||||
if (e.detail.isRestored) {
|
||||
if (currentItem) {
|
|
@ -1,22 +1,22 @@
|
|||
define(['components/remotecontrol/remotecontrol', 'libraryMenu', 'emby-button'], function (remotecontrolFactory, libraryMenu) {
|
||||
'use strict';
|
||||
import remotecontrolFactory from 'components/remotecontrol/remotecontrol';
|
||||
import libraryMenu from 'libraryMenu';
|
||||
import 'emby-button';
|
||||
|
||||
return function (view, params) {
|
||||
var remoteControl = new remotecontrolFactory();
|
||||
remoteControl.init(view, view.querySelector('.remoteControlContent'));
|
||||
view.addEventListener('viewshow', function (e) {
|
||||
libraryMenu.setTransparentMenu(true);
|
||||
export default function (view, params) {
|
||||
const remoteControl = new remotecontrolFactory();
|
||||
remoteControl.init(view, view.querySelector('.remoteControlContent'));
|
||||
view.addEventListener('viewshow', function (e) {
|
||||
libraryMenu.setTransparentMenu(true);
|
||||
|
||||
if (remoteControl) {
|
||||
remoteControl.onShow();
|
||||
}
|
||||
});
|
||||
view.addEventListener('viewbeforehide', function (e) {
|
||||
libraryMenu.setTransparentMenu(false);
|
||||
if (remoteControl) {
|
||||
remoteControl.onShow();
|
||||
}
|
||||
});
|
||||
view.addEventListener('viewbeforehide', function (e) {
|
||||
libraryMenu.setTransparentMenu(false);
|
||||
|
||||
if (remoteControl) {
|
||||
remoteControl.destroy();
|
||||
}
|
||||
});
|
||||
};
|
||||
});
|
||||
if (remoteControl) {
|
||||
remoteControl.destroy();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,5 +1,26 @@
|
|||
define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'mediaInfo', 'focusManager', 'imageLoader', 'scrollHelper', 'events', 'connectionManager', 'browser', 'globalize', 'apphost', 'layoutManager', 'userSettings', 'keyboardnavigation', 'scrollStyles', 'emby-slider', 'paper-icon-button-light', 'css!assets/css/videoosd'], function (playbackManager, dom, inputManager, datetime, itemHelper, mediaInfo, focusManager, imageLoader, scrollHelper, events, connectionManager, browser, globalize, appHost, layoutManager, userSettings, keyboardnavigation) {
|
||||
'use strict';
|
||||
import playbackManager from 'playbackManager';
|
||||
import dom from 'dom';
|
||||
import inputManager from 'inputManager';
|
||||
import datetime from 'datetime';
|
||||
import itemHelper from 'itemHelper';
|
||||
import mediaInfo from 'mediaInfo';
|
||||
import focusManager from 'focusManager';
|
||||
import imageLoader from 'imageLoader';
|
||||
import scrollHelper from 'scrollHelper';
|
||||
import events from 'events';
|
||||
import connectionManager from 'connectionManager';
|
||||
import browser from 'browser';
|
||||
import globalize from 'globalize';
|
||||
import appHost from 'apphost';
|
||||
import layoutManager from 'layoutManager';
|
||||
import * as userSettings from 'userSettings';
|
||||
import keyboardnavigation from 'keyboardnavigation';
|
||||
import 'scrollStyles';
|
||||
import 'emby-slider';
|
||||
import 'paper-icon-button-light';
|
||||
import 'css!assets/css/videoosd';
|
||||
|
||||
/* eslint-disable indent */
|
||||
|
||||
function seriesImageUrl(item, options) {
|
||||
if ('Episode' !== item.Type) {
|
||||
|
@ -45,13 +66,13 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
return null;
|
||||
}
|
||||
|
||||
return function (view, params) {
|
||||
export default function (view, params) {
|
||||
function onVerticalSwipe(e, elem, data) {
|
||||
var player = currentPlayer;
|
||||
const player = currentPlayer;
|
||||
|
||||
if (player) {
|
||||
var deltaY = data.currentDeltaY;
|
||||
var windowSize = dom.getWindowSize();
|
||||
const deltaY = data.currentDeltaY;
|
||||
const windowSize = dom.getWindowSize();
|
||||
|
||||
if (supportsBrightnessChange && data.clientX < windowSize.innerWidth / 2) {
|
||||
return void doBrightnessTouch(deltaY, player, windowSize.innerHeight);
|
||||
|
@ -62,23 +83,23 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
}
|
||||
|
||||
function doBrightnessTouch(deltaY, player, viewHeight) {
|
||||
var delta = -deltaY / viewHeight * 100;
|
||||
var newValue = playbackManager.getBrightness(player) + delta;
|
||||
const delta = -deltaY / viewHeight * 100;
|
||||
let newValue = playbackManager.getBrightness(player) + delta;
|
||||
newValue = Math.min(newValue, 100);
|
||||
newValue = Math.max(newValue, 0);
|
||||
playbackManager.setBrightness(newValue, player);
|
||||
}
|
||||
|
||||
function doVolumeTouch(deltaY, player, viewHeight) {
|
||||
var delta = -deltaY / viewHeight * 100;
|
||||
var newValue = playbackManager.getVolume(player) + delta;
|
||||
const delta = -deltaY / viewHeight * 100;
|
||||
let newValue = playbackManager.getVolume(player) + delta;
|
||||
newValue = Math.min(newValue, 100);
|
||||
newValue = Math.max(newValue, 0);
|
||||
playbackManager.setVolume(newValue, player);
|
||||
}
|
||||
|
||||
function onDoubleClick(e) {
|
||||
var clientX = e.clientX;
|
||||
const clientX = e.clientX;
|
||||
|
||||
if (null != clientX) {
|
||||
if (clientX < dom.getWindowSize().innerWidth / 2) {
|
||||
|
@ -94,7 +115,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
|
||||
function getDisplayItem(item) {
|
||||
if ('TvChannel' === item.Type) {
|
||||
var apiClient = connectionManager.getApiClient(item.ServerId);
|
||||
const apiClient = connectionManager.getApiClient(item.ServerId);
|
||||
return apiClient.getItem(apiClient.getCurrentUserId(), item.Id).then(function (refreshedItem) {
|
||||
return {
|
||||
originalItem: refreshedItem,
|
||||
|
@ -120,7 +141,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
|
||||
connectionManager.getApiClient(item.ServerId).getCurrentUser().then(function (user) {
|
||||
if (user.Policy.EnableLiveTvManagement) {
|
||||
require(['recordingButton'], function (RecordingButton) {
|
||||
import('recordingButton').then(({default: RecordingButton}) => {
|
||||
if (recordingButtonManager) {
|
||||
return void recordingButtonManager.refreshItem(item);
|
||||
}
|
||||
|
@ -136,22 +157,22 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
}
|
||||
|
||||
function updateDisplayItem(itemInfo) {
|
||||
var item = itemInfo.originalItem;
|
||||
const item = itemInfo.originalItem;
|
||||
currentItem = item;
|
||||
var displayItem = itemInfo.displayItem || item;
|
||||
const displayItem = itemInfo.displayItem || item;
|
||||
updateRecordingButton(displayItem);
|
||||
setPoster(displayItem, item);
|
||||
var parentName = displayItem.SeriesName || displayItem.Album;
|
||||
let parentName = displayItem.SeriesName || displayItem.Album;
|
||||
|
||||
if (displayItem.EpisodeTitle || displayItem.IsSeries) {
|
||||
parentName = displayItem.Name;
|
||||
}
|
||||
|
||||
setTitle(displayItem, parentName);
|
||||
var titleElement;
|
||||
var osdTitle = view.querySelector('.osdTitle');
|
||||
let titleElement;
|
||||
const osdTitle = view.querySelector('.osdTitle');
|
||||
titleElement = osdTitle;
|
||||
var displayName = itemHelper.getDisplayName(displayItem, {
|
||||
let displayName = itemHelper.getDisplayName(displayItem, {
|
||||
includeParentInfo: 'Program' !== displayItem.Type,
|
||||
includeIndexNumber: 'Program' !== displayItem.Type
|
||||
});
|
||||
|
@ -168,7 +189,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
titleElement.classList.add('hide');
|
||||
}
|
||||
|
||||
var mediaInfoHtml = mediaInfo.getPrimaryMediaInfoHtml(displayItem, {
|
||||
const mediaInfoHtml = mediaInfo.getPrimaryMediaInfoHtml(displayItem, {
|
||||
runtime: false,
|
||||
subtitles: false,
|
||||
tomatoes: false,
|
||||
|
@ -178,7 +199,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
episodeTitleIndexNumber: 'Program' !== displayItem.Type,
|
||||
programIndicator: false
|
||||
});
|
||||
var osdMediaInfo = view.querySelector('.osdMediaInfo');
|
||||
const osdMediaInfo = view.querySelector('.osdMediaInfo');
|
||||
osdMediaInfo.innerHTML = mediaInfoHtml;
|
||||
|
||||
if (mediaInfoHtml) {
|
||||
|
@ -187,8 +208,8 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
osdMediaInfo.classList.add('hide');
|
||||
}
|
||||
|
||||
var secondaryMediaInfo = view.querySelector('.osdSecondaryMediaInfo');
|
||||
var secondaryMediaInfoHtml = mediaInfo.getSecondaryMediaInfoHtml(displayItem, {
|
||||
const secondaryMediaInfo = view.querySelector('.osdSecondaryMediaInfo');
|
||||
const secondaryMediaInfoHtml = mediaInfo.getSecondaryMediaInfoHtml(displayItem, {
|
||||
startDate: false,
|
||||
programTime: false
|
||||
});
|
||||
|
@ -236,7 +257,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
}
|
||||
|
||||
function setDisplayTime(elem, date) {
|
||||
var html;
|
||||
let html;
|
||||
|
||||
if (date) {
|
||||
date = datetime.parseISO8601Date(date);
|
||||
|
@ -251,7 +272,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
}
|
||||
|
||||
function updateNowPlayingInfo(player, state) {
|
||||
var item = state.NowPlayingItem;
|
||||
const item = state.NowPlayingItem;
|
||||
|
||||
currentItem = item;
|
||||
if (!item) {
|
||||
|
@ -294,7 +315,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
function setTitle(item, parentName) {
|
||||
Emby.Page.setTitle(parentName || '');
|
||||
|
||||
var documentTitle = parentName || (item ? item.Name : null);
|
||||
const documentTitle = parentName || (item ? item.Name : null);
|
||||
|
||||
if (documentTitle) {
|
||||
document.title = documentTitle;
|
||||
|
@ -302,10 +323,10 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
}
|
||||
|
||||
function setPoster(item, secondaryItem) {
|
||||
var osdPoster = view.querySelector('.osdPoster');
|
||||
const osdPoster = view.querySelector('.osdPoster');
|
||||
|
||||
if (item) {
|
||||
var imgUrl = seriesImageUrl(item, {
|
||||
let imgUrl = seriesImageUrl(item, {
|
||||
maxWidth: osdPoster.clientWidth * 2,
|
||||
type: 'Primary'
|
||||
}) || seriesImageUrl(item, {
|
||||
|
@ -333,13 +354,21 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
osdPoster.innerHTML = '';
|
||||
}
|
||||
|
||||
let osdLockCount = 0;
|
||||
|
||||
function showOsd() {
|
||||
slideDownToShow(headerElement);
|
||||
showMainOsdControls();
|
||||
startOsdHideTimer();
|
||||
if (!osdLockCount) {
|
||||
startOsdHideTimer();
|
||||
}
|
||||
}
|
||||
|
||||
function hideOsd() {
|
||||
if (osdLockCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
slideUpToHide(headerElement);
|
||||
hideMainOsdControls();
|
||||
}
|
||||
|
@ -352,6 +381,19 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
}
|
||||
}
|
||||
|
||||
function lockOsd() {
|
||||
osdLockCount++;
|
||||
stopOsdHideTimer();
|
||||
}
|
||||
|
||||
function unlockOsd() {
|
||||
osdLockCount--;
|
||||
// Restart hide timer if OSD is currently visible
|
||||
if (currentVisibleMenu && !osdLockCount) {
|
||||
startOsdHideTimer();
|
||||
}
|
||||
}
|
||||
|
||||
function startOsdHideTimer() {
|
||||
stopOsdHideTimer();
|
||||
osdHideTimeout = setTimeout(hideOsd, 3e3);
|
||||
|
@ -379,7 +421,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
}
|
||||
|
||||
function onHideAnimationComplete(e) {
|
||||
var elem = e.target;
|
||||
const elem = e.target;
|
||||
if (elem != osdBottomElement)
|
||||
return;
|
||||
elem.classList.add('hide');
|
||||
|
@ -390,7 +432,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
|
||||
function showMainOsdControls() {
|
||||
if (!currentVisibleMenu) {
|
||||
var elem = osdBottomElement;
|
||||
const elem = osdBottomElement;
|
||||
currentVisibleMenu = 'osd';
|
||||
clearHideAnimationEventListeners(elem);
|
||||
elem.classList.remove('hide');
|
||||
|
@ -407,7 +449,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
|
||||
function hideMainOsdControls() {
|
||||
if ('osd' === currentVisibleMenu) {
|
||||
var elem = osdBottomElement;
|
||||
const elem = osdBottomElement;
|
||||
clearHideAnimationEventListeners(elem);
|
||||
elem.classList.add('videoOsdBottom-hidden');
|
||||
dom.addEventListener(elem, transitionEndEventName, onHideAnimationComplete, {
|
||||
|
@ -425,9 +467,9 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
|
||||
function onPointerMove(e) {
|
||||
if ('mouse' === (e.pointerType || (layoutManager.mobile ? 'touch' : 'mouse'))) {
|
||||
var eventX = e.screenX || 0;
|
||||
var eventY = e.screenY || 0;
|
||||
var obj = lastPointerMoveData;
|
||||
const eventX = e.screenX || 0;
|
||||
const eventY = e.screenY || 0;
|
||||
const obj = lastPointerMoveData;
|
||||
|
||||
if (!obj) {
|
||||
lastPointerMoveData = {
|
||||
|
@ -448,7 +490,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
}
|
||||
|
||||
function onInputCommand(e) {
|
||||
var player = currentPlayer;
|
||||
const player = currentPlayer;
|
||||
|
||||
switch (e.detail.command) {
|
||||
case 'left':
|
||||
|
@ -507,7 +549,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
}
|
||||
|
||||
function onRecordingCommand() {
|
||||
var btnRecord = view.querySelector('.btnRecord');
|
||||
const btnRecord = view.querySelector('.btnRecord');
|
||||
|
||||
if (!btnRecord.classList.contains('hide')) {
|
||||
btnRecord.click();
|
||||
|
@ -534,7 +576,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
}
|
||||
|
||||
function onStateChanged(event, state) {
|
||||
var player = this;
|
||||
const player = this;
|
||||
|
||||
if (state.NowPlayingItem) {
|
||||
isEnabled = true;
|
||||
|
@ -552,21 +594,21 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
|
||||
function onVolumeChanged(e) {
|
||||
if (isEnabled) {
|
||||
var player = this;
|
||||
const player = this;
|
||||
updatePlayerVolumeState(player, player.isMuted(), player.getVolume());
|
||||
}
|
||||
}
|
||||
|
||||
function onPlaybackStart(e, state) {
|
||||
console.debug('nowplaying event: ' + e.type);
|
||||
var player = this;
|
||||
const player = this;
|
||||
onStateChanged.call(player, e, state);
|
||||
resetUpNextDialog();
|
||||
}
|
||||
|
||||
function resetUpNextDialog() {
|
||||
comingUpNextDisplayed = false;
|
||||
var dlg = currentUpNextDialog;
|
||||
const dlg = currentUpNextDialog;
|
||||
|
||||
if (dlg) {
|
||||
dlg.destroy();
|
||||
|
@ -586,8 +628,8 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
}
|
||||
|
||||
function onMediaStreamsChanged(e) {
|
||||
var player = this;
|
||||
var state = playbackManager.getPlayerState(player);
|
||||
const player = this;
|
||||
const state = playbackManager.getPlayerState(player);
|
||||
onStateChanged.call(player, {
|
||||
type: 'init'
|
||||
}, state);
|
||||
|
@ -607,7 +649,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
currentPlayer = player;
|
||||
if (!player) return;
|
||||
}
|
||||
var state = playbackManager.getPlayerState(player);
|
||||
const state = playbackManager.getPlayerState(player);
|
||||
onStateChanged.call(player, {
|
||||
type: 'init'
|
||||
}, state);
|
||||
|
@ -632,7 +674,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
destroyStats();
|
||||
destroySubtitleSync();
|
||||
resetUpNextDialog();
|
||||
var player = currentPlayer;
|
||||
const player = currentPlayer;
|
||||
|
||||
if (player) {
|
||||
events.off(player, 'playbackstart', onPlaybackStart);
|
||||
|
@ -650,15 +692,15 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
function onTimeUpdate(e) {
|
||||
// Test for 'currentItem' is required for Firefox since its player spams 'timeupdate' events even being at breakpoint
|
||||
if (isEnabled && currentItem) {
|
||||
var now = new Date().getTime();
|
||||
const now = new Date().getTime();
|
||||
|
||||
if (!(now - lastUpdateTime < 700)) {
|
||||
lastUpdateTime = now;
|
||||
var player = this;
|
||||
const player = this;
|
||||
currentRuntimeTicks = playbackManager.duration(player);
|
||||
var currentTime = playbackManager.currentTime(player);
|
||||
const currentTime = playbackManager.currentTime(player);
|
||||
updateTimeDisplay(currentTime, currentRuntimeTicks, playbackManager.playbackStartTime(player), playbackManager.getBufferedRanges(player));
|
||||
var item = currentItem;
|
||||
const item = currentItem;
|
||||
refreshProgramInfoIfNeeded(player, item);
|
||||
showComingUpNextIfNeeded(player, item, currentTime, currentRuntimeTicks);
|
||||
}
|
||||
|
@ -667,9 +709,9 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
|
||||
function showComingUpNextIfNeeded(player, currentItem, currentTimeTicks, runtimeTicks) {
|
||||
if (runtimeTicks && currentTimeTicks && !comingUpNextDisplayed && !currentVisibleMenu && 'Episode' === currentItem.Type && userSettings.enableNextVideoInfoOverlay()) {
|
||||
var showAtSecondsLeft = runtimeTicks >= 3e10 ? 40 : runtimeTicks >= 24e9 ? 35 : 30;
|
||||
var showAtTicks = runtimeTicks - 1e3 * showAtSecondsLeft * 1e4;
|
||||
var timeRemainingTicks = runtimeTicks - currentTimeTicks;
|
||||
const showAtSecondsLeft = runtimeTicks >= 3e10 ? 40 : runtimeTicks >= 24e9 ? 35 : 30;
|
||||
const showAtTicks = runtimeTicks - 1e3 * showAtSecondsLeft * 1e4;
|
||||
const timeRemainingTicks = runtimeTicks - currentTimeTicks;
|
||||
|
||||
if (currentTimeTicks >= showAtTicks && runtimeTicks >= 6e9 && timeRemainingTicks >= 2e8) {
|
||||
showComingUpNext(player);
|
||||
|
@ -684,7 +726,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
}
|
||||
|
||||
function showComingUpNext(player) {
|
||||
require(['upNextDialog'], function (UpNextDialog) {
|
||||
import('upNextDialog').then(({default: UpNextDialog}) => {
|
||||
if (!(currentVisibleMenu || currentUpNextDialog)) {
|
||||
currentVisibleMenu = 'upnext';
|
||||
comingUpNextDisplayed = true;
|
||||
|
@ -702,15 +744,15 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
|
||||
function refreshProgramInfoIfNeeded(player, item) {
|
||||
if ('TvChannel' === item.Type) {
|
||||
var program = item.CurrentProgram;
|
||||
const program = item.CurrentProgram;
|
||||
|
||||
if (program && program.EndDate) {
|
||||
try {
|
||||
var endDate = datetime.parseISO8601Date(program.EndDate);
|
||||
const endDate = datetime.parseISO8601Date(program.EndDate);
|
||||
|
||||
if (new Date().getTime() >= endDate.getTime()) {
|
||||
console.debug('program info needs to be refreshed');
|
||||
var state = playbackManager.getPlayerState(player);
|
||||
const state = playbackManager.getPlayerState(player);
|
||||
onStateChanged.call(player, {
|
||||
type: 'init'
|
||||
}, state);
|
||||
|
@ -738,9 +780,9 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
}
|
||||
|
||||
function updatePlayerStateInternal(event, player, state) {
|
||||
var playState = state.PlayState || {};
|
||||
const playState = state.PlayState || {};
|
||||
updatePlayPauseState(playState.IsPaused);
|
||||
var supportedCommands = playbackManager.getSupportedCommands(player);
|
||||
const supportedCommands = playbackManager.getSupportedCommands(player);
|
||||
currentPlayerSupportedCommands = supportedCommands;
|
||||
supportsBrightnessChange = -1 !== supportedCommands.indexOf('SetBrightness');
|
||||
updatePlayerVolumeState(player, playState.IsMuted, playState.VolumeLevel);
|
||||
|
@ -751,7 +793,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
|
||||
btnFastForward.disabled = !playState.CanSeek;
|
||||
btnRewind.disabled = !playState.CanSeek;
|
||||
var nowPlayingItem = state.NowPlayingItem || {};
|
||||
const nowPlayingItem = state.NowPlayingItem || {};
|
||||
playbackStartTimeTicks = playState.PlaybackStartTimeTicks;
|
||||
updateTimeDisplay(playState.PositionTicks, nowPlayingItem.RunTimeTicks, playState.PlaybackStartTimeTicks, playState.BufferedRanges || []);
|
||||
updateNowPlayingInfo(player, state);
|
||||
|
@ -762,7 +804,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
view.querySelector('.btnVideoOsdSettings').classList.add('hide');
|
||||
}
|
||||
|
||||
var isProgressClear = state.MediaSource && null == state.MediaSource.RunTimeTicks;
|
||||
const isProgressClear = state.MediaSource && null == state.MediaSource.RunTimeTicks;
|
||||
nowPlayingPositionSlider.setIsClear(isProgressClear);
|
||||
|
||||
if (nowPlayingItem.RunTimeTicks) {
|
||||
|
@ -799,12 +841,12 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
if (enableProgressByTimeOfDay) {
|
||||
if (nowPlayingPositionSlider && !nowPlayingPositionSlider.dragging) {
|
||||
if (programStartDateMs && programEndDateMs) {
|
||||
var currentTimeMs = (playbackStartTimeTicks + (positionTicks || 0)) / 1e4;
|
||||
var programRuntimeMs = programEndDateMs - programStartDateMs;
|
||||
const currentTimeMs = (playbackStartTimeTicks + (positionTicks || 0)) / 1e4;
|
||||
const programRuntimeMs = programEndDateMs - programStartDateMs;
|
||||
|
||||
if (nowPlayingPositionSlider.value = getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, currentTimeMs), bufferedRanges.length) {
|
||||
var rangeStart = getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, (playbackStartTimeTicks + (bufferedRanges[0].start || 0)) / 1e4);
|
||||
var rangeEnd = getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, (playbackStartTimeTicks + (bufferedRanges[0].end || 0)) / 1e4);
|
||||
const rangeStart = getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, (playbackStartTimeTicks + (bufferedRanges[0].start || 0)) / 1e4);
|
||||
const rangeEnd = getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, (playbackStartTimeTicks + (bufferedRanges[0].end || 0)) / 1e4);
|
||||
nowPlayingPositionSlider.setBufferedRanges([{
|
||||
start: rangeStart,
|
||||
end: rangeEnd
|
||||
|
@ -823,7 +865,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
} else {
|
||||
if (nowPlayingPositionSlider && !nowPlayingPositionSlider.dragging) {
|
||||
if (runtimeTicks) {
|
||||
var pct = positionTicks / runtimeTicks;
|
||||
let pct = positionTicks / runtimeTicks;
|
||||
pct *= 100;
|
||||
nowPlayingPositionSlider.value = pct;
|
||||
} else {
|
||||
|
@ -847,9 +889,9 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
}
|
||||
|
||||
function updatePlayerVolumeState(player, isMuted, volumeLevel) {
|
||||
var supportedCommands = currentPlayerSupportedCommands;
|
||||
var showMuteButton = true;
|
||||
var showVolumeSlider = true;
|
||||
const supportedCommands = currentPlayerSupportedCommands;
|
||||
let showMuteButton = true;
|
||||
let showVolumeSlider = true;
|
||||
|
||||
if (-1 === supportedCommands.indexOf('Mute')) {
|
||||
showMuteButton = false;
|
||||
|
@ -897,8 +939,8 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
}
|
||||
|
||||
function updatePlaylist(player) {
|
||||
var btnPreviousTrack = view.querySelector('.btnPreviousTrack');
|
||||
var btnNextTrack = view.querySelector('.btnNextTrack');
|
||||
const btnPreviousTrack = view.querySelector('.btnPreviousTrack');
|
||||
const btnNextTrack = view.querySelector('.btnNextTrack');
|
||||
btnPreviousTrack.classList.remove('hide');
|
||||
btnNextTrack.classList.remove('hide');
|
||||
btnNextTrack.disabled = false;
|
||||
|
@ -911,7 +953,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
return;
|
||||
}
|
||||
|
||||
var html = datetime.getDisplayRunningTime(ticks);
|
||||
let html = datetime.getDisplayRunningTime(ticks);
|
||||
|
||||
if (divider) {
|
||||
html = ' / ' + html;
|
||||
|
@ -921,15 +963,15 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
}
|
||||
|
||||
function onSettingsButtonClick(e) {
|
||||
var btn = this;
|
||||
const btn = this;
|
||||
|
||||
require(['playerSettingsMenu'], function (playerSettingsMenu) {
|
||||
var player = currentPlayer;
|
||||
import('playerSettingsMenu').then(({default: playerSettingsMenu}) => {
|
||||
const player = currentPlayer;
|
||||
|
||||
if (player) {
|
||||
|
||||
// show subtitle offset feature only if player and media support it
|
||||
var showSubOffset = playbackManager.supportSubtitleOffset(player) &&
|
||||
const showSubOffset = playbackManager.supportSubtitleOffset(player) &&
|
||||
playbackManager.canHandleOffsetOnCurrentSubtitle(player);
|
||||
|
||||
playerSettingsMenu.show({
|
||||
|
@ -948,7 +990,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
if ('stats' === selectedOption) {
|
||||
toggleStats();
|
||||
} else if ('suboffset' === selectedOption) {
|
||||
var player = currentPlayer;
|
||||
const player = currentPlayer;
|
||||
if (player) {
|
||||
playbackManager.enableShowingSubtitleOffset(player);
|
||||
toggleSubtitleSync();
|
||||
|
@ -957,8 +999,8 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
}
|
||||
|
||||
function toggleStats() {
|
||||
require(['playerStats'], function (PlayerStats) {
|
||||
var player = currentPlayer;
|
||||
import('playerStats').then(({default: PlayerStats}) => {
|
||||
const player = currentPlayer;
|
||||
|
||||
if (player) {
|
||||
if (statsOverlay) {
|
||||
|
@ -980,11 +1022,11 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
}
|
||||
|
||||
function showAudioTrackSelection() {
|
||||
var player = currentPlayer;
|
||||
var audioTracks = playbackManager.audioTracks(player);
|
||||
var currentIndex = playbackManager.getAudioStreamIndex(player);
|
||||
var menuItems = audioTracks.map(function (stream) {
|
||||
var opt = {
|
||||
const player = currentPlayer;
|
||||
const audioTracks = playbackManager.audioTracks(player);
|
||||
const currentIndex = playbackManager.getAudioStreamIndex(player);
|
||||
const menuItems = audioTracks.map(function (stream) {
|
||||
const opt = {
|
||||
name: stream.DisplayTitle,
|
||||
id: stream.Index
|
||||
};
|
||||
|
@ -995,15 +1037,15 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
|
||||
return opt;
|
||||
});
|
||||
var positionTo = this;
|
||||
const positionTo = this;
|
||||
|
||||
require(['actionsheet'], function (actionsheet) {
|
||||
import('actionsheet').then(({default: actionsheet}) => {
|
||||
actionsheet.show({
|
||||
items: menuItems,
|
||||
title: globalize.translate('Audio'),
|
||||
positionTo: positionTo
|
||||
}).then(function (id) {
|
||||
var index = parseInt(id);
|
||||
const index = parseInt(id);
|
||||
|
||||
if (index !== currentIndex) {
|
||||
playbackManager.setAudioStreamIndex(index, player);
|
||||
|
@ -1013,9 +1055,9 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
}
|
||||
|
||||
function showSubtitleTrackSelection() {
|
||||
var player = currentPlayer;
|
||||
var streams = playbackManager.subtitleTracks(player);
|
||||
var currentIndex = playbackManager.getSubtitleStreamIndex(player);
|
||||
const player = currentPlayer;
|
||||
const streams = playbackManager.subtitleTracks(player);
|
||||
let currentIndex = playbackManager.getSubtitleStreamIndex(player);
|
||||
|
||||
if (null == currentIndex) {
|
||||
currentIndex = -1;
|
||||
|
@ -1025,8 +1067,8 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
Index: -1,
|
||||
DisplayTitle: globalize.translate('Off')
|
||||
});
|
||||
var menuItems = streams.map(function (stream) {
|
||||
var opt = {
|
||||
const menuItems = streams.map(function (stream) {
|
||||
const opt = {
|
||||
name: stream.DisplayTitle,
|
||||
id: stream.Index
|
||||
};
|
||||
|
@ -1037,15 +1079,15 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
|
||||
return opt;
|
||||
});
|
||||
var positionTo = this;
|
||||
const positionTo = this;
|
||||
|
||||
require(['actionsheet'], function (actionsheet) {
|
||||
import('actionsheet').then(({default: actionsheet}) => {
|
||||
actionsheet.show({
|
||||
title: globalize.translate('Subtitles'),
|
||||
items: menuItems,
|
||||
positionTo: positionTo
|
||||
}).then(function (id) {
|
||||
var index = parseInt(id);
|
||||
const index = parseInt(id);
|
||||
|
||||
if (index !== currentIndex) {
|
||||
playbackManager.setSubtitleStreamIndex(index, player);
|
||||
|
@ -1057,8 +1099,8 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
}
|
||||
|
||||
function toggleSubtitleSync(action) {
|
||||
require(['subtitleSync'], function (SubtitleSync) {
|
||||
var player = currentPlayer;
|
||||
import('subtitleSync').then(({default: SubtitleSync}) => {
|
||||
const player = currentPlayer;
|
||||
if (subtitleSyncOverlay) {
|
||||
subtitleSyncOverlay.toggle(action);
|
||||
} else if (player) {
|
||||
|
@ -1078,12 +1120,12 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
* Clicked element.
|
||||
* To skip 'click' handling on Firefox/Edge.
|
||||
*/
|
||||
var clickedElement;
|
||||
let clickedElement;
|
||||
|
||||
function onWindowKeyDown(e) {
|
||||
function onKeyDown(e) {
|
||||
clickedElement = e.srcElement;
|
||||
|
||||
var key = keyboardnavigation.getKeyName(e);
|
||||
const key = keyboardnavigation.getKeyName(e);
|
||||
|
||||
if (!currentVisibleMenu && 32 === e.keyCode) {
|
||||
playbackManager.playPause(currentPlayer);
|
||||
|
@ -1187,19 +1229,37 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
var percent = parseInt(key, 10) * 10;
|
||||
case '9': {
|
||||
const percent = parseInt(key, 10) * 10;
|
||||
playbackManager.seekPercent(percent, currentPlayer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onKeyDownCapture() {
|
||||
// Restart hide timer if OSD is currently visible
|
||||
if (currentVisibleMenu) {
|
||||
showOsd();
|
||||
}
|
||||
}
|
||||
|
||||
function onWindowMouseDown(e) {
|
||||
clickedElement = e.srcElement;
|
||||
lockOsd();
|
||||
}
|
||||
|
||||
function onWindowMouseUp() {
|
||||
unlockOsd();
|
||||
}
|
||||
|
||||
function onWindowTouchStart(e) {
|
||||
clickedElement = e.srcElement;
|
||||
lockOsd();
|
||||
}
|
||||
|
||||
function onWindowTouchEnd() {
|
||||
unlockOsd();
|
||||
}
|
||||
|
||||
function getImgUrl(item, chapter, index, maxWidth, apiClient) {
|
||||
|
@ -1216,11 +1276,11 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
}
|
||||
|
||||
function getChapterBubbleHtml(apiClient, item, chapters, positionTicks) {
|
||||
var chapter;
|
||||
var index = -1;
|
||||
let chapter;
|
||||
let index = -1;
|
||||
|
||||
for (var i = 0, length = chapters.length; i < length; i++) {
|
||||
var currentChapter = chapters[i];
|
||||
for (let i = 0, length = chapters.length; i < length; i++) {
|
||||
const currentChapter = chapters[i];
|
||||
|
||||
if (positionTicks >= currentChapter.StartPositionTicks) {
|
||||
chapter = currentChapter;
|
||||
|
@ -1232,10 +1292,10 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
return null;
|
||||
}
|
||||
|
||||
var src = getImgUrl(item, chapter, index, 400, apiClient);
|
||||
const src = getImgUrl(item, chapter, index, 400, apiClient);
|
||||
|
||||
if (src) {
|
||||
var html = '<div class="chapterThumbContainer">';
|
||||
let html = '<div class="chapterThumbContainer">';
|
||||
html += '<img class="chapterThumb" src="' + src + '" />';
|
||||
html += '<div class="chapterThumbTextContainer">';
|
||||
html += '<div class="chapterThumbText chapterThumbText-dim">';
|
||||
|
@ -1251,15 +1311,15 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
return null;
|
||||
}
|
||||
|
||||
var playPauseClickTimeout;
|
||||
let playPauseClickTimeout;
|
||||
function onViewHideStopPlayback() {
|
||||
if (playbackManager.isPlayingVideo()) {
|
||||
require(['shell'], function (shell) {
|
||||
import('shell').then(({default: shell}) => {
|
||||
shell.disableFullscreen();
|
||||
});
|
||||
|
||||
clearTimeout(playPauseClickTimeout);
|
||||
var player = currentPlayer;
|
||||
const player = currentPlayer;
|
||||
view.removeEventListener('viewbeforehide', onViewHideStopPlayback);
|
||||
releaseCurrentPlayer();
|
||||
playbackManager.stop(player);
|
||||
|
@ -1274,47 +1334,49 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
}
|
||||
}
|
||||
|
||||
require(['shell'], function (shell) {
|
||||
import('shell').then(({default: shell}) => {
|
||||
shell.enableFullscreen();
|
||||
});
|
||||
|
||||
var currentPlayer;
|
||||
var comingUpNextDisplayed;
|
||||
var currentUpNextDialog;
|
||||
var isEnabled;
|
||||
var currentItem;
|
||||
var recordingButtonManager;
|
||||
var enableProgressByTimeOfDay;
|
||||
var supportsBrightnessChange;
|
||||
var currentVisibleMenu;
|
||||
var statsOverlay;
|
||||
var osdHideTimeout;
|
||||
var lastPointerMoveData;
|
||||
var self = this;
|
||||
var currentPlayerSupportedCommands = [];
|
||||
var currentRuntimeTicks = 0;
|
||||
var lastUpdateTime = 0;
|
||||
var programStartDateMs = 0;
|
||||
var programEndDateMs = 0;
|
||||
var playbackStartTimeTicks = 0;
|
||||
var subtitleSyncOverlay;
|
||||
var nowPlayingVolumeSlider = view.querySelector('.osdVolumeSlider');
|
||||
var nowPlayingVolumeSliderContainer = view.querySelector('.osdVolumeSliderContainer');
|
||||
var nowPlayingPositionSlider = view.querySelector('.osdPositionSlider');
|
||||
var nowPlayingPositionText = view.querySelector('.osdPositionText');
|
||||
var nowPlayingDurationText = view.querySelector('.osdDurationText');
|
||||
var startTimeText = view.querySelector('.startTimeText');
|
||||
var endTimeText = view.querySelector('.endTimeText');
|
||||
var endsAtText = view.querySelector('.endsAtText');
|
||||
var btnRewind = view.querySelector('.btnRewind');
|
||||
var btnFastForward = view.querySelector('.btnFastForward');
|
||||
var transitionEndEventName = dom.whichTransitionEvent();
|
||||
var headerElement = document.querySelector('.skinHeader');
|
||||
var osdBottomElement = document.querySelector('.videoOsdBottom-maincontrols');
|
||||
let currentPlayer;
|
||||
let comingUpNextDisplayed;
|
||||
let currentUpNextDialog;
|
||||
let isEnabled;
|
||||
let currentItem;
|
||||
let recordingButtonManager;
|
||||
let enableProgressByTimeOfDay;
|
||||
let supportsBrightnessChange;
|
||||
let currentVisibleMenu;
|
||||
let statsOverlay;
|
||||
let osdHideTimeout;
|
||||
let lastPointerMoveData;
|
||||
const self = this;
|
||||
let currentPlayerSupportedCommands = [];
|
||||
let currentRuntimeTicks = 0;
|
||||
let lastUpdateTime = 0;
|
||||
let programStartDateMs = 0;
|
||||
let programEndDateMs = 0;
|
||||
let playbackStartTimeTicks = 0;
|
||||
let subtitleSyncOverlay;
|
||||
const nowPlayingVolumeSlider = view.querySelector('.osdVolumeSlider');
|
||||
const nowPlayingVolumeSliderContainer = view.querySelector('.osdVolumeSliderContainer');
|
||||
const nowPlayingPositionSlider = view.querySelector('.osdPositionSlider');
|
||||
const nowPlayingPositionText = view.querySelector('.osdPositionText');
|
||||
const nowPlayingDurationText = view.querySelector('.osdDurationText');
|
||||
const startTimeText = view.querySelector('.startTimeText');
|
||||
const endTimeText = view.querySelector('.endTimeText');
|
||||
const endsAtText = view.querySelector('.endsAtText');
|
||||
const btnRewind = view.querySelector('.btnRewind');
|
||||
const btnFastForward = view.querySelector('.btnFastForward');
|
||||
const transitionEndEventName = dom.whichTransitionEvent();
|
||||
const headerElement = document.querySelector('.skinHeader');
|
||||
const osdBottomElement = document.querySelector('.videoOsdBottom-maincontrols');
|
||||
|
||||
nowPlayingPositionSlider.enableKeyboardDragging();
|
||||
nowPlayingVolumeSlider.enableKeyboardDragging();
|
||||
|
||||
if (layoutManager.tv) {
|
||||
nowPlayingPositionSlider.classList.add('focusable');
|
||||
nowPlayingPositionSlider.enableKeyboardDragging();
|
||||
}
|
||||
|
||||
view.addEventListener('viewbeforeshow', function (e) {
|
||||
|
@ -1325,23 +1387,35 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
try {
|
||||
events.on(playbackManager, 'playerchange', onPlayerChange);
|
||||
bindToPlayer(playbackManager.getCurrentPlayer());
|
||||
/* eslint-disable-next-line compat/compat */
|
||||
dom.addEventListener(document, window.PointerEvent ? 'pointermove' : 'mousemove', onPointerMove, {
|
||||
passive: true
|
||||
});
|
||||
showOsd();
|
||||
inputManager.on(window, onInputCommand);
|
||||
dom.addEventListener(window, 'keydown', onWindowKeyDown, {
|
||||
document.addEventListener('keydown', onKeyDown);
|
||||
dom.addEventListener(document, 'keydown', onKeyDownCapture, {
|
||||
capture: true
|
||||
});
|
||||
/* eslint-disable-next-line compat/compat */
|
||||
dom.addEventListener(window, window.PointerEvent ? 'pointerdown' : 'mousedown', onWindowMouseDown, {
|
||||
passive: true
|
||||
});
|
||||
/* eslint-disable-next-line compat/compat */
|
||||
dom.addEventListener(window, window.PointerEvent ? 'pointerup' : 'mouseup', onWindowMouseUp, {
|
||||
passive: true
|
||||
});
|
||||
dom.addEventListener(window, 'touchstart', onWindowTouchStart, {
|
||||
passive: true
|
||||
});
|
||||
['touchend', 'touchcancel'].forEach((event) => {
|
||||
dom.addEventListener(window, event, onWindowTouchEnd, {
|
||||
passive: true
|
||||
});
|
||||
});
|
||||
} catch (e) {
|
||||
require(['appRouter'], function(appRouter) {
|
||||
appRouter.showDirect('/');
|
||||
import('appRouter').then(({default: appRouter}) => {
|
||||
appRouter.goHome();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -1350,18 +1424,30 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
statsOverlay.enabled(false);
|
||||
}
|
||||
|
||||
dom.removeEventListener(window, 'keydown', onWindowKeyDown, {
|
||||
document.removeEventListener('keydown', onKeyDown);
|
||||
dom.removeEventListener(document, 'keydown', onKeyDownCapture, {
|
||||
capture: true
|
||||
});
|
||||
/* eslint-disable-next-line compat/compat */
|
||||
dom.removeEventListener(window, window.PointerEvent ? 'pointerdown' : 'mousedown', onWindowMouseDown, {
|
||||
passive: true
|
||||
});
|
||||
/* eslint-disable-next-line compat/compat */
|
||||
dom.removeEventListener(window, window.PointerEvent ? 'pointerup' : 'mouseup', onWindowMouseUp, {
|
||||
passive: true
|
||||
});
|
||||
dom.removeEventListener(window, 'touchstart', onWindowTouchStart, {
|
||||
passive: true
|
||||
});
|
||||
['touchend', 'touchcancel'].forEach((event) => {
|
||||
dom.removeEventListener(window, event, onWindowTouchEnd, {
|
||||
passive: true
|
||||
});
|
||||
});
|
||||
stopOsdHideTimer();
|
||||
headerElement.classList.remove('osdHeader');
|
||||
headerElement.classList.remove('osdHeader-hidden');
|
||||
/* eslint-disable-next-line compat/compat */
|
||||
dom.removeEventListener(document, window.PointerEvent ? 'pointermove' : 'mousemove', onPointerMove, {
|
||||
passive: true
|
||||
});
|
||||
|
@ -1396,14 +1482,15 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
destroyStats();
|
||||
destroySubtitleSync();
|
||||
});
|
||||
var lastPointerDown = 0;
|
||||
let lastPointerDown = 0;
|
||||
/* eslint-disable-next-line compat/compat */
|
||||
dom.addEventListener(view, window.PointerEvent ? 'pointerdown' : 'click', function (e) {
|
||||
if (dom.parentWithClass(e.target, ['videoOsdBottom', 'upNextContainer'])) {
|
||||
return void showOsd();
|
||||
}
|
||||
|
||||
var pointerType = e.pointerType || (layoutManager.mobile ? 'touch' : 'mouse');
|
||||
var now = new Date().getTime();
|
||||
const pointerType = e.pointerType || (layoutManager.mobile ? 'touch' : 'mouse');
|
||||
const now = new Date().getTime();
|
||||
|
||||
switch (pointerType) {
|
||||
case 'touch':
|
||||
|
@ -1441,31 +1528,28 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
if (browser.touch) {
|
||||
dom.addEventListener(view, 'dblclick', onDoubleClick, {});
|
||||
} else {
|
||||
var options = { passive: true };
|
||||
const options = { passive: true };
|
||||
dom.addEventListener(view, 'dblclick', function () {
|
||||
playbackManager.toggleFullscreen(currentPlayer);
|
||||
}, options);
|
||||
}
|
||||
|
||||
function setVolume() {
|
||||
playbackManager.setVolume(this.value, currentPlayer);
|
||||
}
|
||||
|
||||
view.querySelector('.buttonMute').addEventListener('click', function () {
|
||||
playbackManager.toggleMute(currentPlayer);
|
||||
});
|
||||
nowPlayingVolumeSlider.addEventListener('change', setVolume);
|
||||
nowPlayingVolumeSlider.addEventListener('mousemove', setVolume);
|
||||
nowPlayingVolumeSlider.addEventListener('touchmove', setVolume);
|
||||
|
||||
nowPlayingVolumeSlider.addEventListener('input', (e) => {
|
||||
playbackManager.setVolume(e.target.value, currentPlayer);
|
||||
});
|
||||
|
||||
nowPlayingPositionSlider.addEventListener('change', function () {
|
||||
var player = currentPlayer;
|
||||
const player = currentPlayer;
|
||||
|
||||
if (player) {
|
||||
var newPercent = parseFloat(this.value);
|
||||
const newPercent = parseFloat(this.value);
|
||||
|
||||
if (enableProgressByTimeOfDay) {
|
||||
var seekAirTimeTicks = newPercent / 100 * (programEndDateMs - programStartDateMs) * 1e4;
|
||||
let seekAirTimeTicks = newPercent / 100 * (programEndDateMs - programStartDateMs) * 1e4;
|
||||
seekAirTimeTicks += 1e4 * programStartDateMs;
|
||||
seekAirTimeTicks -= playbackStartTimeTicks;
|
||||
playbackManager.seek(seekAirTimeTicks, player);
|
||||
|
@ -1479,7 +1563,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
showOsd();
|
||||
if (enableProgressByTimeOfDay) {
|
||||
if (programStartDateMs && programEndDateMs) {
|
||||
var ms = programEndDateMs - programStartDateMs;
|
||||
let ms = programEndDateMs - programStartDateMs;
|
||||
ms /= 100;
|
||||
ms *= value;
|
||||
ms += programStartDateMs;
|
||||
|
@ -1493,13 +1577,13 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
return '--:--';
|
||||
}
|
||||
|
||||
var ticks = currentRuntimeTicks;
|
||||
let ticks = currentRuntimeTicks;
|
||||
ticks /= 100;
|
||||
ticks *= value;
|
||||
var item = currentItem;
|
||||
const item = currentItem;
|
||||
|
||||
if (item && item.Chapters && item.Chapters.length && item.Chapters[0].ImageTag) {
|
||||
var html = getChapterBubbleHtml(connectionManager.getApiClient(item.ServerId), item, item.Chapters, ticks);
|
||||
let html = getChapterBubbleHtml(connectionManager.getApiClient(item.ServerId), item, item.Chapters, ticks);
|
||||
|
||||
if (html) {
|
||||
return html;
|
||||
|
@ -1532,8 +1616,13 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
|
||||
if (browser.touch) {
|
||||
(function () {
|
||||
<<<<<<< HEAD
|
||||
require(['touchHelper'], function (TouchHelper) {
|
||||
self.touchHelper = new TouchHelper.default(view, {
|
||||
=======
|
||||
import('touchHelper').then(({default: TouchHelper}) => {
|
||||
self.touchHelper = new TouchHelper(view, {
|
||||
>>>>>>> upstream/master
|
||||
swipeYThreshold: 30,
|
||||
triggerOnMove: true,
|
||||
preventDefaultOnMove: true,
|
||||
|
@ -1544,5 +1633,6 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
|||
});
|
||||
})();
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/* eslint-enable indent */
|
||||
|
|
|
@ -1,20 +1,23 @@
|
|||
define(['displaySettings', 'userSettings', 'autoFocuser'], function (DisplaySettings, userSettings, autoFocuser) {
|
||||
'use strict';
|
||||
import DisplaySettings from 'displaySettings';
|
||||
import * as userSettings from 'userSettings';
|
||||
import autoFocuser from 'autoFocuser';
|
||||
|
||||
/* eslint-disable indent */
|
||||
|
||||
// Shortcuts
|
||||
const UserSettings = userSettings.UserSettings;
|
||||
|
||||
return function (view, params) {
|
||||
export default function (view, params) {
|
||||
function onBeforeUnload(e) {
|
||||
if (hasChanges) {
|
||||
e.returnValue = 'You currently have unsaved changes. Are you sure you wish to leave?';
|
||||
}
|
||||
}
|
||||
|
||||
var settingsInstance;
|
||||
var hasChanges;
|
||||
var userId = params.userId || ApiClient.getCurrentUserId();
|
||||
var currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings();
|
||||
let settingsInstance;
|
||||
let hasChanges;
|
||||
const userId = params.userId || ApiClient.getCurrentUserId();
|
||||
const currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings();
|
||||
view.addEventListener('viewshow', function () {
|
||||
window.addEventListener('beforeunload', onBeforeUnload);
|
||||
|
||||
|
@ -26,28 +29,23 @@ define(['displaySettings', 'userSettings', 'autoFocuser'], function (DisplaySett
|
|||
userId: userId,
|
||||
element: view.querySelector('.settingsContainer'),
|
||||
userSettings: currentSettings,
|
||||
enableSaveButton: false,
|
||||
enableSaveConfirmation: false,
|
||||
enableSaveButton: true,
|
||||
enableSaveConfirmation: true,
|
||||
autoFocus: autoFocuser.isEnabled()
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
view.addEventListener('change', function () {
|
||||
hasChanges = true;
|
||||
});
|
||||
view.addEventListener('viewbeforehide', function () {
|
||||
window.removeEventListener('beforeunload', onBeforeUnload);
|
||||
hasChanges = false;
|
||||
|
||||
if (settingsInstance) {
|
||||
settingsInstance.submit();
|
||||
}
|
||||
});
|
||||
view.addEventListener('viewdestroy', function () {
|
||||
if (settingsInstance) {
|
||||
settingsInstance.destroy();
|
||||
settingsInstance = null;
|
||||
}
|
||||
});
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/* eslint-enable indent */
|
||||
|
|
|
@ -1,20 +1,27 @@
|
|||
define(['homescreenSettings', 'dom', 'globalize', 'loading', 'userSettings', 'autoFocuser', 'listViewStyle'], function (HomescreenSettings, dom, globalize, loading, userSettings, autoFocuser) {
|
||||
'use strict';
|
||||
import HomescreenSettings from 'homescreenSettings';
|
||||
import dom from 'dom';
|
||||
import globalize from 'globalize';
|
||||
import loading from 'loading';
|
||||
import * as userSettings from 'userSettings';
|
||||
import autoFocuser from 'autoFocuser';
|
||||
import 'listViewStyle';
|
||||
|
||||
/* eslint-disable indent */
|
||||
|
||||
// Shortcuts
|
||||
const UserSettings = userSettings.UserSettings;
|
||||
|
||||
return function (view, params) {
|
||||
export default function (view, params) {
|
||||
function onBeforeUnload(e) {
|
||||
if (hasChanges) {
|
||||
e.returnValue = 'You currently have unsaved changes. Are you sure you wish to leave?';
|
||||
}
|
||||
}
|
||||
|
||||
var homescreenSettingsInstance;
|
||||
var hasChanges;
|
||||
var userId = params.userId || ApiClient.getCurrentUserId();
|
||||
var currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings();
|
||||
let homescreenSettingsInstance;
|
||||
let hasChanges;
|
||||
const userId = params.userId || ApiClient.getCurrentUserId();
|
||||
const currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings();
|
||||
view.addEventListener('viewshow', function () {
|
||||
window.addEventListener('beforeunload', onBeforeUnload);
|
||||
|
||||
|
@ -26,27 +33,23 @@ define(['homescreenSettings', 'dom', 'globalize', 'loading', 'userSettings', 'au
|
|||
userId: userId,
|
||||
element: view.querySelector('.homeScreenSettingsContainer'),
|
||||
userSettings: currentSettings,
|
||||
enableSaveButton: false,
|
||||
enableSaveConfirmation: false,
|
||||
enableSaveButton: true,
|
||||
enableSaveConfirmation: true,
|
||||
autoFocus: autoFocuser.isEnabled()
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
view.addEventListener('change', function () {
|
||||
hasChanges = true;
|
||||
});
|
||||
view.addEventListener('viewbeforehide', function () {
|
||||
hasChanges = false;
|
||||
|
||||
if (homescreenSettingsInstance) {
|
||||
homescreenSettingsInstance.submit();
|
||||
}
|
||||
});
|
||||
view.addEventListener('viewdestroy', function () {
|
||||
if (homescreenSettingsInstance) {
|
||||
homescreenSettingsInstance.destroy();
|
||||
homescreenSettingsInstance = null;
|
||||
}
|
||||
});
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/* eslint-enable indent */
|
||||
|
|
|
@ -1,20 +1,27 @@
|
|||
define(['playbackSettings', 'dom', 'globalize', 'loading', 'userSettings', 'autoFocuser', 'listViewStyle'], function (PlaybackSettings, dom, globalize, loading, userSettings, autoFocuser) {
|
||||
'use strict';
|
||||
import PlaybackSettings from 'playbackSettings';
|
||||
import dom from 'dom';
|
||||
import globalize from 'globalize';
|
||||
import loading from 'loading';
|
||||
import * as userSettings from 'userSettings';
|
||||
import autoFocuser from 'autoFocuser';
|
||||
import 'listViewStyle';
|
||||
|
||||
/* eslint-disable indent */
|
||||
|
||||
// Shortcuts
|
||||
const UserSettings = userSettings.UserSettings;
|
||||
|
||||
return function (view, params) {
|
||||
export default function (view, params) {
|
||||
function onBeforeUnload(e) {
|
||||
if (hasChanges) {
|
||||
e.returnValue = 'You currently have unsaved changes. Are you sure you wish to leave?';
|
||||
}
|
||||
}
|
||||
|
||||
var settingsInstance;
|
||||
var hasChanges;
|
||||
var userId = params.userId || ApiClient.getCurrentUserId();
|
||||
var currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings();
|
||||
let settingsInstance;
|
||||
let hasChanges;
|
||||
const userId = params.userId || ApiClient.getCurrentUserId();
|
||||
const currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings();
|
||||
view.addEventListener('viewshow', function () {
|
||||
window.addEventListener('beforeunload', onBeforeUnload);
|
||||
|
||||
|
@ -26,27 +33,23 @@ define(['playbackSettings', 'dom', 'globalize', 'loading', 'userSettings', 'auto
|
|||
userId: userId,
|
||||
element: view.querySelector('.settingsContainer'),
|
||||
userSettings: currentSettings,
|
||||
enableSaveButton: false,
|
||||
enableSaveConfirmation: false,
|
||||
enableSaveButton: true,
|
||||
enableSaveConfirmation: true,
|
||||
autoFocus: autoFocuser.isEnabled()
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
view.addEventListener('change', function () {
|
||||
hasChanges = true;
|
||||
});
|
||||
view.addEventListener('viewbeforehide', function () {
|
||||
hasChanges = false;
|
||||
|
||||
if (settingsInstance) {
|
||||
settingsInstance.submit();
|
||||
}
|
||||
});
|
||||
view.addEventListener('viewdestroy', function () {
|
||||
if (settingsInstance) {
|
||||
settingsInstance.destroy();
|
||||
settingsInstance = null;
|
||||
}
|
||||
});
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/* eslint-enable indent */
|
||||
|
|
|
@ -1,6 +1,14 @@
|
|||
<<<<<<< HEAD
|
||||
import subtitleSettings from 'subtitleSettings';
|
||||
import {UserSettings, currentSettings as userSettings} from 'userSettings';
|
||||
import autoFocuser from 'autoFocuser';
|
||||
=======
|
||||
import SubtitleSettings from 'subtitleSettings';
|
||||
import * as userSettings from 'userSettings';
|
||||
import autoFocuser from 'autoFocuser';
|
||||
|
||||
/* eslint-disable indent */
|
||||
>>>>>>> upstream/master
|
||||
|
||||
export class SubtitleController {
|
||||
constructor(view, params) {
|
||||
|
@ -10,6 +18,7 @@ export class SubtitleController {
|
|||
this.subtitleSettingsInstance = null;
|
||||
this.view = view;
|
||||
|
||||
<<<<<<< HEAD
|
||||
view.addEventListener('viewshow', this.viewShow.bind(this));
|
||||
view.addEventListener('change', this.change.bind(this));
|
||||
view.addEventListener('viewbeforehide', this.viewBeforeHide.bind(this));
|
||||
|
@ -56,8 +65,53 @@ export class SubtitleController {
|
|||
beforeUnload(e) {
|
||||
if (this.hasChanges) {
|
||||
e.returnValue = 'You currently have unsaved changes. Are you sure you wish to leave?';
|
||||
=======
|
||||
export default function (view, params) {
|
||||
function onBeforeUnload(e) {
|
||||
if (hasChanges) {
|
||||
e.returnValue = 'You currently have unsaved changes. Are you sure you wish to leave?';
|
||||
}
|
||||
>>>>>>> upstream/master
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
export default SubtitleController;
|
||||
=======
|
||||
let subtitleSettingsInstance;
|
||||
let hasChanges;
|
||||
const userId = params.userId || ApiClient.getCurrentUserId();
|
||||
const currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings();
|
||||
view.addEventListener('viewshow', function () {
|
||||
window.addEventListener('beforeunload', onBeforeUnload);
|
||||
|
||||
if (subtitleSettingsInstance) {
|
||||
subtitleSettingsInstance.loadData();
|
||||
} else {
|
||||
subtitleSettingsInstance = new SubtitleSettings({
|
||||
serverId: ApiClient.serverId(),
|
||||
userId: userId,
|
||||
element: view.querySelector('.settingsContainer'),
|
||||
userSettings: currentSettings,
|
||||
enableSaveButton: true,
|
||||
enableSaveConfirmation: true,
|
||||
autoFocus: autoFocuser.isEnabled()
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
view.addEventListener('change', function () {
|
||||
hasChanges = true;
|
||||
});
|
||||
|
||||
view.addEventListener('viewdestroy', function () {
|
||||
if (subtitleSettingsInstance) {
|
||||
subtitleSettingsInstance.destroy();
|
||||
subtitleSettingsInstance = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* eslint-enable indent */
|
||||
>>>>>>> upstream/master
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue