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

update playlist management

This commit is contained in:
Luke Pulverenti 2017-01-14 03:03:46 -05:00
parent 893b492cbb
commit 7a6ac9c251
24 changed files with 121 additions and 79 deletions

View file

@ -231,9 +231,6 @@
.channelTimeslotHeader, .timeslotHeader { .channelTimeslotHeader, .timeslotHeader {
background: transparent; background: transparent;
}
.timeslotHeader, .channelTimeslotHeader {
height: 2.2em; height: 2.2em;
} }
@ -259,6 +256,9 @@
/* Needed for Firefox */ /* Needed for Firefox */
text-align: left; text-align: left;
contain: strict; contain: strict;
flex-grow: 1;
margin: 0 !important;
padding: 0 !important;
} }
.programAccent { .programAccent {

View file

@ -33,6 +33,22 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'embyRouter',
}); });
} }
if (playbackManager.canQueue(item)) {
if (options.queue !== false) {
commands.push({
name: globalize.translate('sharedcomponents#AddToPlayQueue'),
id: 'queue'
});
}
//if (options.queueAllFromHere) {
// commands.push({
// name: globalize.translate('sharedcomponents#QueueAllFromHere'),
// id: 'queueallfromhere'
// });
//}
}
if ((item.Type === 'Timer') && user.Policy.EnableLiveTvManagement && options.cancelTimer !== false) { if ((item.Type === 'Timer') && user.Policy.EnableLiveTvManagement && options.cancelTimer !== false) {
commands.push({ commands.push({
name: globalize.translate('sharedcomponents#CancelRecording'), name: globalize.translate('sharedcomponents#CancelRecording'),
@ -152,22 +168,6 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'embyRouter',
id: 'playallfromhere' id: 'playallfromhere'
}); });
} }
if (playbackManager.canQueue(item)) {
if (options.queue !== false) {
commands.push({
name: globalize.translate('sharedcomponents#Queue'),
id: 'queue'
});
}
if (options.queueAllFromHere) {
commands.push({
name: globalize.translate('sharedcomponents#QueueAllFromHere'),
id: 'queueallfromhere'
});
}
}
} }
if (item.Type === 'Program' && options.record !== false) { if (item.Type === 'Program' && options.record !== false) {

View file

@ -398,8 +398,8 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan
if (!clickEntireItem) { if (!clickEntireItem) {
if (options.queueButton) { if (options.addToListButton) {
html += '<button is="paper-icon-button-light" class="listItemButton itemAction autoSize" data-action="queue"><i class="md-icon">&#xE03B;</i></button>'; html += '<button is="paper-icon-button-light" class="listItemButton itemAction autoSize" data-action="addtoplaylist"><i class="md-icon">&#xE03B;</i></button>';
} }
if (options.moreButton !== false) { if (options.moreButton !== false) {

View file

@ -12,8 +12,8 @@ define(['playbackManager'], function (playbackManager) {
self.intercept = function (options) { self.intercept = function (options) {
// Don't care about video backdrops or any kind of non-fullscreen playback // Don't care about video backdrops, or theme music or any kind of non-fullscreen playback
if (!options.fullscreen && options.mediaType === 'Video') { if (!options.fullscreen) {
return Promise.resolve(); return Promise.resolve();
} }

View file

@ -1,4 +1,4 @@
define(['shell', 'dialogHelper', 'loading', 'layoutManager', 'connectionManager', 'userSettings', 'embyRouter', 'globalize', 'emby-input', 'paper-icon-button-light', 'emby-select', 'material-icons', 'css!./../formdialog', 'emby-button'], function (shell, dialogHelper, loading, layoutManager, connectionManager, userSettings, embyRouter, globalize) { define(['shell', 'dialogHelper', 'loading', 'layoutManager', 'playbackManager', 'connectionManager', 'userSettings', 'embyRouter', 'globalize', 'emby-input', 'paper-icon-button-light', 'emby-select', 'material-icons', 'css!./../formdialog', 'emby-button'], function (shell, dialogHelper, loading, layoutManager, playbackManager, connectionManager, userSettings, embyRouter, globalize) {
'use strict'; 'use strict';
var currentServerId; var currentServerId;
@ -18,8 +18,6 @@
function onSubmit(e) { function onSubmit(e) {
loading.show();
var panel = parentWithClass(this, 'dialog'); var panel = parentWithClass(this, 'dialog');
var playlistId = panel.querySelector('#selectPlaylistToAddTo').value; var playlistId = panel.querySelector('#selectPlaylistToAddTo').value;
@ -38,6 +36,8 @@
function createPlaylist(apiClient, dlg) { function createPlaylist(apiClient, dlg) {
loading.show();
var url = apiClient.getUrl("Playlists", { var url = apiClient.getUrl("Playlists", {
Name: dlg.querySelector('#txtNewPlaylistName').value, Name: dlg.querySelector('#txtNewPlaylistName').value,
@ -72,9 +72,24 @@
function addToPlaylist(apiClient, dlg, id) { function addToPlaylist(apiClient, dlg, id) {
var itemIds = dlg.querySelector('.fldSelectedItemIds').value || '';
if (id === 'queue') {
playbackManager.queue({
serverId: apiClient.serverId(),
ids: itemIds.split(',')
});
dialogHelper.close(dlg);
showToast();
return;
}
loading.show();
var url = apiClient.getUrl("Playlists/" + id + "/Items", { var url = apiClient.getUrl("Playlists/" + id + "/Items", {
Ids: dlg.querySelector('.fldSelectedItemIds').value || '', Ids: itemIds,
userId: apiClient.getCurrentUserId() userId: apiClient.getCurrentUserId()
}); });
@ -87,11 +102,14 @@
loading.hide(); loading.hide();
dialogHelper.close(dlg); dialogHelper.close(dlg);
showToast();
});
}
function showToast() {
require(['toast'], function (toast) { require(['toast'], function (toast) {
toast(globalize.translate('sharedcomponents#MessageItemsAdded')); toast(globalize.translate('sharedcomponents#MessageItemsAdded'));
}); });
});
} }
function triggerChange(select) { function triggerChange(select) {
@ -118,6 +136,7 @@
var html = ''; var html = '';
html += '<option value="queue">' + globalize.translate('sharedcomponents#AddToPlayQueue') + '</option>';
html += '<option value="">' + globalize.translate('sharedcomponents#OptionNew') + '</option>'; html += '<option value="">' + globalize.translate('sharedcomponents#OptionNew') + '</option>';
html += result.Items.map(function (i) { html += result.Items.map(function (i) {
@ -161,7 +180,7 @@
html += '</div>'; html += '</div>';
html += '<div class="formDialogFooter">'; html += '<div class="formDialogFooter">';
html += '<button is="emby-button" type="submit" class="raised btnSubmit block formDialogFooterItem button-submit">' + globalize.translate('sharedcomponents#ButtonOk') + '</button>'; html += '<button is="emby-button" type="submit" class="raised btnSubmit block formDialogFooterItem button-submit">' + globalize.translate('sharedcomponents#Add') + '</button>';
html += '</div>'; html += '</div>';
html += '<input type="hidden" class="fldSelectedItemIds" />'; html += '<input type="hidden" class="fldSelectedItemIds" />';

View file

@ -36,7 +36,7 @@
require(['listViewStyle', 'emby-button', 'formDialogStyle'], function () { require(['listViewStyle', 'emby-button', 'formDialogStyle'], function () {
var dlg = dialogHelper.createDialog({ var dlg = dialogHelper.createDialog({
size: 'fullscreen-border', size: layoutManager.tv ? 'fullscreen' : 'fullscreen-border',
removeOnClose: true, removeOnClose: true,
scrollY: false scrollY: false
}); });
@ -290,7 +290,7 @@
} }
var dlg = dialogHelper.createDialog({ var dlg = dialogHelper.createDialog({
size: 'fullscreen-border', size: layoutManager.tv ? 'fullscreen' : 'fullscreen-border',
removeOnClose: true, removeOnClose: true,
scrollY: false scrollY: false
}); });
@ -524,7 +524,7 @@
function restorePurchase(unlockableProductInfo) { function restorePurchase(unlockableProductInfo) {
var dlg = dialogHelper.createDialog({ var dlg = dialogHelper.createDialog({
size: 'fullscreen-border', size: layoutManager.tv ? 'fullscreen' : 'fullscreen-border',
removeOnClose: true, removeOnClose: true,
scrollY: false scrollY: false
}); });

View file

@ -326,6 +326,21 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'embyRouter', 'g
else if (action === 'playtrailer') { else if (action === 'playtrailer') {
getItem(target).then(playTrailer); getItem(target).then(playTrailer);
} }
else if (action === 'addtoplaylist') {
getItem(target).then(addToPlaylist);
}
}
function addToPlaylist(item) {
require(['playlistEditor'], function (playlistEditor) {
new playlistEditor().show({
items: [item.Id],
serverId: item.ServerId
});
});
} }
function playTrailer(item) { function playTrailer(item) {

View file

@ -2,7 +2,7 @@
'use strict'; 'use strict';
function enableScrollX() { function enableScrollX() {
return browserInfo.mobile && AppInfo.enableAppLayouts; return browserInfo.mobile;
} }
function getThumbShape() { function getThumbShape() {

View file

@ -73,14 +73,13 @@
<span>${OptionPlayNextEpisodeAutomatically}</span> <span>${OptionPlayNextEpisodeAutomatically}</span>
</label> </label>
<div class="checkboxContainer fldExternalPlayer checkboxContainer-withDescription"> <div class="checkboxContainer fldExternalPlayer checkboxContainer-withDescription hide">
<label> <label>
<input type="checkbox" is="emby-checkbox" class="chkExternalVideoPlayer" /> <input type="checkbox" is="emby-checkbox" class="chkExternalVideoPlayer" />
<span>${OptionEnableExternalVideoPlayers}</span> <span>${OptionEnableExternalVideoPlayers}</span>
</label> </label>
<div class="fieldDescription checkboxFieldDescription"> <div class="fieldDescription checkboxFieldDescription">
<div class="labelGenericExternalPlayers hide">${LabelExternalPlayersHelp}</div> <div class="labelNativeExternalPlayers">${LabelNativeExternalPlayersHelp}</div>
<div class="labelNativeExternalPlayers hide">${LabelNativeExternalPlayersHelp}</div>
</div> </div>
</div> </div>
</div> </div>

View file

@ -1,12 +1,14 @@
<div id="playlistsPage" data-dom-cache="true" data-role="page" class="page libraryPage noSecondaryNavPage" data-title="${HeaderPlaylists}"> <div id="playlistsPage" data-dom-cache="true" data-role="page" class="page libraryPage noSecondaryNavPage" data-title="${HeaderPlaylists}">
<div data-role="content"> <div data-role="content">
<div class="viewSettings">
<div style="text-align: center; display: flex; flex-wrap: wrap; align-items: center; justify-content: center; padding: 0 .5em 1em;">
<div class="listTopPaging"> <div class="listTopPaging">
&nbsp; &nbsp;
</div> </div>
<button type="button" is="paper-icon-button-light" class="btnNewPlaylist autoSize"><i class="md-icon">add</i></button>
</div> </div>
<div is="emby-itemscontainer" id="items" class="itemsContainer paddedItemsContainer centered"></div> <div is="emby-itemscontainer" id="items" class="itemsContainer paddedItemsContainer centered"></div>
<div class="noItemsMessage hide" style="text-align: center;"> <div class="noItemsMessage hide" style="text-align: center;">
<p>${MessageNoPlaylistsAvailable}</p> <p>${MessageNoPlaylistsAvailable}</p>

View file

@ -38,7 +38,7 @@
} }
function enableScrollX() { function enableScrollX() {
return browserInfo.mobile && AppInfo.enableAppLayouts; return browserInfo.mobile;
} }
function getThumbShape() { function getThumbShape() {

View file

@ -275,7 +275,7 @@
action: 'playallfromhere', action: 'playallfromhere',
smallIcon: true, smallIcon: true,
artist: true, artist: true,
queueButton: true addToListButton: true
}); });
break; break;

View file

@ -73,7 +73,6 @@
item: item, item: item,
open: false, open: false,
play: false, play: false,
queue: false,
playAllFromHere: false, playAllFromHere: false,
queueAllFromHere: false, queueAllFromHere: false,
positionTo: button, positionTo: button,
@ -1261,7 +1260,7 @@
image: false, image: false,
artist: 'auto', artist: 'auto',
containerAlbumArtist: item.AlbumArtist, containerAlbumArtist: item.AlbumArtist,
queueButton: true addToListButton: true
}); });
isList = true; isList = true;
} }
@ -1549,6 +1548,9 @@
case 'games': case 'games':
type = 'Game'; type = 'Game';
break; break;
case 'music':
type = 'MusicAlbum';
break;
default: default:
type = 'Movie'; type = 'Movie';
break; break;

View file

@ -2,7 +2,7 @@
'use strict'; 'use strict';
function enableScrollX() { function enableScrollX() {
return browserInfo.mobile && AppInfo.enableAppLayouts; return browserInfo.mobile;
} }
function getBackdropShape() { function getBackdropShape() {

View file

@ -2,7 +2,7 @@
'use strict'; 'use strict';
function enableScrollX() { function enableScrollX() {
return browserInfo.mobile && AppInfo.enableAppLayouts; return browserInfo.mobile;
} }
function renderRecordings(elem, recordings, cardOptions) { function renderRecordings(elem, recordings, cardOptions) {

View file

@ -47,7 +47,7 @@
} }
function enableScrollX() { function enableScrollX() {
return browserInfo.mobile && AppInfo.enableAppLayouts; return browserInfo.mobile;
} }
function getThumbShape() { function getThumbShape() {

View file

@ -99,7 +99,7 @@
items: result.Items, items: result.Items,
context: 'music', context: 'music',
sortBy: query.SortBy, sortBy: query.SortBy,
queueButton: true addToListButton: true
}); });
} }
else if (viewStyle == "PosterCard") { else if (viewStyle == "PosterCard") {

View file

@ -186,14 +186,6 @@
view.querySelector('.fldExternalPlayer').classList.add('hide'); view.querySelector('.fldExternalPlayer').classList.add('hide');
} }
if (AppInfo.supportsExternalPlayerMenu) {
view.querySelector('.labelNativeExternalPlayers').classList.remove('hide');
view.querySelector('.labelGenericExternalPlayers').classList.add('hide');
} else {
view.querySelector('.labelGenericExternalPlayers').classList.remove('hide');
view.querySelector('.labelNativeExternalPlayers').classList.add('hide');
}
loadPage(view); loadPage(view);
}); });

View file

@ -552,26 +552,24 @@
height: imgHeight height: imgHeight
})) : null; })) : null;
if (url === currentImgUrl) { if (url !== currentImgUrl) {
return;
}
currentImgUrl = url; currentImgUrl = url;
imageLoader.lazyImage(nowPlayingImageElement, url); imageLoader.lazyImage(nowPlayingImageElement, url);
}
userdataButtons.destroy({
element: nowPlayingUserData
});
if (nowPlayingItem.Id) { if (nowPlayingItem.Id) {
ApiClient.getItem(Dashboard.getCurrentUserId(), nowPlayingItem.Id).then(function (item) { ApiClient.getItem(Dashboard.getCurrentUserId(), nowPlayingItem.Id).then(function(item) {
userdataButtons.fill({ userdataButtons.fill({
item: item, item: item,
includePlayed: false, includePlayed: false,
element: nowPlayingUserData element: nowPlayingUserData
}); });
}); });
} else {
userdataButtons.destroy({
element: nowPlayingUserData
});
} }
} }

View file

@ -207,6 +207,18 @@
reloadItems(); reloadItems();
}); });
view.querySelector('.btnNewPlaylist').addEventListener('click', function () {
require(['playlistEditor'], function (playlistEditor) {
var serverId = ApiClient.serverInfo().Id;
new playlistEditor().show({
items: [],
serverId: serverId
});
});
});
onViewStyleChange(); onViewStyleChange();
}; };

View file

@ -717,7 +717,7 @@ var AppInfo = {};
AppInfo.enableHomeTabs = false; AppInfo.enableHomeTabs = false;
if (isAndroid) { if (isAndroid) {
AppInfo.supportsExternalPlayerMenu = true; AppInfo.supportsExternalPlayers = true;
} }
} }
else { else {
@ -1003,12 +1003,6 @@ var AppInfo = {};
paths.hlsjs = bowerPath + "/hlsjs/dist/hls.min"; paths.hlsjs = bowerPath + "/hlsjs/dist/hls.min";
if ((window.chrome && window.chrome.sockets) || Dashboard.isRunningInCordova()) {
paths.serverdiscovery = apiClientBowerPath + "/serverdiscovery-chrome";
} else {
paths.serverdiscovery = apiClientBowerPath + "/serverdiscovery";
}
define("webActionSheet", [embyWebComponentsBowerPath + "/actionsheet/actionsheet"], returnFirstDependency); define("webActionSheet", [embyWebComponentsBowerPath + "/actionsheet/actionsheet"], returnFirstDependency);
if (Dashboard.isRunningInCordova()) { if (Dashboard.isRunningInCordova()) {
@ -1367,7 +1361,7 @@ var AppInfo = {};
appSettings.set('externalplayers', val.toString()); appSettings.set('externalplayers', val.toString());
} }
return appSettings.get('externalplayers') == 'true'; return appSettings.get('externalplayers') === 'true';
}; };
return appSettings; return appSettings;
@ -1403,6 +1397,16 @@ var AppInfo = {};
define("registerElement", []); define("registerElement", []);
} }
if ((window.chrome && window.chrome.sockets)) {
define("serverdiscovery", [apiClientBowerPath + "/serverdiscovery-chrome"], returnFirstDependency);
} else if (Dashboard.isRunningInCordova() && browser.android) {
define("serverdiscovery", ["cordova/serverdiscovery"], returnFirstDependency);
} else if (Dashboard.isRunningInCordova() && browser.safari) {
define("serverdiscovery", [apiClientBowerPath + "/serverdiscovery-chrome"], returnFirstDependency);
} else {
define("serverdiscovery", [apiClientBowerPath + "/serverdiscovery"], returnFirstDependency);
}
if (Dashboard.isRunningInCordova() && browser.safari) { if (Dashboard.isRunningInCordova() && browser.safari) {
define("imageFetcher", ['cordova/imagestore'], returnFirstDependency); define("imageFetcher", ['cordova/imagestore'], returnFirstDependency);
} else { } else {

View file

@ -74,7 +74,7 @@
action: 'playallfromhere', action: 'playallfromhere',
smallIcon: true, smallIcon: true,
artist: true, artist: true,
queueButton: true addToListButton: true
}); });
var i, length; var i, length;

View file

@ -47,7 +47,7 @@
} }
function enableScrollX() { function enableScrollX() {
return browserInfo.mobile && AppInfo.enableAppLayouts; return browserInfo.mobile;
} }
function getThumbShape() { function getThumbShape() {

View file

@ -981,8 +981,7 @@
"LabelConnectUserNameHelp": "Connect this local user to an online Emby account to enable easy sign-in access from any Emby app without having to know the server ip address.", "LabelConnectUserNameHelp": "Connect this local user to an online Emby account to enable easy sign-in access from any Emby app without having to know the server ip address.",
"ButtonLearnMoreAboutEmbyConnect": "Learn more about Emby Connect", "ButtonLearnMoreAboutEmbyConnect": "Learn more about Emby Connect",
"LabelExternalPlayers": "External players:", "LabelExternalPlayers": "External players:",
"LabelExternalPlayersHelp": "Display buttons to play content in external players. This is only available on devices that support url schemes, generally Android and iOS. With external players there is generally no support for remote control or resuming.", "LabelNativeExternalPlayersHelp": "Play videos using external players.",
"LabelNativeExternalPlayersHelp": "Display buttons to play content in external players.",
"HeaderSubtitleProfile": "Subtitle Profile", "HeaderSubtitleProfile": "Subtitle Profile",
"HeaderSubtitleProfiles": "Subtitle Profiles", "HeaderSubtitleProfiles": "Subtitle Profiles",
"HeaderSubtitleProfilesHelp": "Subtitle profiles describe the subtitle formats supported by the device.", "HeaderSubtitleProfilesHelp": "Subtitle profiles describe the subtitle formats supported by the device.",