diff --git a/dashboard-ui/bower_components/emby-webcomponents/.bower.json b/dashboard-ui/bower_components/emby-webcomponents/.bower.json index db8c3716c5..7875ebd827 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/.bower.json +++ b/dashboard-ui/bower_components/emby-webcomponents/.bower.json @@ -14,12 +14,12 @@ }, "devDependencies": {}, "ignore": [], - "version": "1.4.474", - "_release": "1.4.474", + "version": "1.4.475", + "_release": "1.4.475", "_resolution": { "type": "version", - "tag": "1.4.474", - "commit": "6e74a88452ec9dee906696b042c969dcc1aee842" + "tag": "1.4.475", + "commit": "ee9afc32bf7c7da8a40158d556cb217bd2c80ef5" }, "_source": "https://github.com/MediaBrowser/emby-webcomponents.git", "_target": "^1.2.1", diff --git a/dashboard-ui/bower_components/emby-webcomponents/chromecastplayer.js b/dashboard-ui/bower_components/emby-webcomponents/chromecastplayer.js index b2de9c336f..cf1b1e1b2b 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/chromecastplayer.js +++ b/dashboard-ui/bower_components/emby-webcomponents/chromecastplayer.js @@ -971,15 +971,19 @@ }); }; + self.getPlaylist = function () { + return Promise.resolve([]); + }; + self.getCurrentPlaylistIndex = function () { return 0; }; - self.setCurrentPlaylistIndex = function (index) { + self.setCurrentPlaylistItem = function (playlistItemId) { return Promise.resolve(); }; - self.removeFromPlaylist = function (index) { + self.removeFromPlaylist = function (playlistItemIds) { return Promise.resolve(); }; diff --git a/dashboard-ui/bower_components/emby-webcomponents/emby-itemscontainer/emby-itemscontainer.js b/dashboard-ui/bower_components/emby-webcomponents/emby-itemscontainer/emby-itemscontainer.js index 313d93fb7f..706646ca5b 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/emby-itemscontainer/emby-itemscontainer.js +++ b/dashboard-ui/bower_components/emby-webcomponents/emby-itemscontainer/emby-itemscontainer.js @@ -107,20 +107,35 @@ function onDrop(evt, itemsContainer) { - - loading.show(); - var el = evt.item; var newIndex = evt.newIndex; var itemId = el.getAttribute('data-playlistitemid'); var playlistId = el.getAttribute('data-playlistid'); + if (!playlistId) { + + var oldIndex = evt.oldIndex; + + el.dispatchEvent(new CustomEvent('itemdrop', { + detail: { + oldIndex: oldIndex, + newIndex: newIndex, + playlistItemId: itemId + }, + bubbles: true, + cancelable: false + })); + return; + } + var serverId = el.getAttribute('data-serverid'); var apiClient = connectionManager.getApiClient(serverId); newIndex = Math.max(0, newIndex - 1); + loading.show(); + apiClient.ajax({ url: apiClient.getUrl('Playlists/' + playlistId + '/Items/' + itemId + '/Move/' + newIndex), @@ -129,7 +144,6 @@ }).then(function () { - el.setAttribute('data-index', newIndex); loading.hide(); }, function () { @@ -171,7 +185,7 @@ // dragging ended onEnd: function (/**Event*/evt) { - onDrop(evt, self); + return onDrop(evt, self); } }); }); diff --git a/dashboard-ui/bower_components/emby-webcomponents/listview/listview.css b/dashboard-ui/bower_components/emby-webcomponents/listview/listview.css index b958e08eb2..d54df523d8 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/listview/listview.css +++ b/dashboard-ui/bower_components/emby-webcomponents/listview/listview.css @@ -42,6 +42,7 @@ .listViewDragHandle { margin-left: -.25em !important; + touch-action: none; } .listItemBody { diff --git a/dashboard-ui/bower_components/emby-webcomponents/listview/listview.js b/dashboard-ui/bower_components/emby-webcomponents/listview/listview.js index ee90a5e359..431fd6bea7 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/listview/listview.js +++ b/dashboard-ui/bower_components/emby-webcomponents/listview/listview.js @@ -235,7 +235,7 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan var collectionTypeData = item.CollectionType ? (' data-collectiontype="' + item.CollectionType + '"') : ''; var channelIdData = item.ChannelId ? (' data-channelid="' + item.ChannelId + '"') : ''; - html += '<' + outerTagName + ' class="' + cssClass + '" data-index="' + i + '"' + playlistItemId + ' data-action="' + action + '" data-isfolder="' + item.IsFolder + '" data-id="' + item.Id + '" data-serverid="' + item.ServerId + '" data-type="' + item.Type + '"' + mediaTypeData + collectionTypeData + channelIdData + positionTicksData + collectionIdData + playlistIdData + '>'; + html += '<' + outerTagName + ' class="' + cssClass + '"' + playlistItemId + ' data-action="' + action + '" data-isfolder="' + item.IsFolder + '" data-id="' + item.Id + '" data-serverid="' + item.ServerId + '" data-type="' + item.Type + '"' + mediaTypeData + collectionTypeData + channelIdData + positionTicksData + collectionIdData + playlistIdData + '>'; if (!clickEntireItem && options.dragHandle) { //html += ''; diff --git a/dashboard-ui/bower_components/emby-webcomponents/playback/playbackmanager.js b/dashboard-ui/bower_components/emby-webcomponents/playback/playbackmanager.js index ec6f7240af..d1838157f3 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/playback/playbackmanager.js +++ b/dashboard-ui/bower_components/emby-webcomponents/playback/playbackmanager.js @@ -30,6 +30,7 @@ define(['events', 'datetime', 'appSettings', 'pluginManager', 'userSettings', 'g var repeatMode = 'RepeatNone'; var playlist = []; var currentPlaylistIndex; + var currentPlaylistItemId; var currentPlayOptions; var playNextAfterEnded = true; var playerStates = {}; @@ -454,8 +455,14 @@ define(['events', 'datetime', 'appSettings', 'pluginManager', 'userSettings', 'g }); }; - self.playlist = function () { - return playlist.slice(0); + self.getPlaylist = function (player) { + + player = player || currentPlayer; + if (player && !enableLocalPlaylistManagement(player)) { + return player.getPlaylist(); + } + + return Promise.resolve(playlist.slice(0)); }; self.getCurrentPlayer = function () { @@ -916,9 +923,9 @@ define(['events', 'datetime', 'appSettings', 'pluginManager', 'userSettings', 'g changeStream(player, ticks); }; - self.nextChapter = function () { + self.nextChapter = function (player) { - var player = currentPlayer; + player = player || currentPlayer; var item = self.currentItem(player); var ticks = getCurrentTicks(player); @@ -930,15 +937,15 @@ define(['events', 'datetime', 'appSettings', 'pluginManager', 'userSettings', 'g })[0]; if (nextChapter) { - self.seek(nextChapter.StartPositionTicks); + self.seek(nextChapter.StartPositionTicks, player); } else { - self.nextTrack(); + self.nextTrack(player); } }; - self.previousChapter = function () { + self.previousChapter = function (player) { - var player = currentPlayer; + player = player || currentPlayer; var item = self.currentItem(player); var ticks = getCurrentTicks(player); @@ -946,21 +953,26 @@ define(['events', 'datetime', 'appSettings', 'pluginManager', 'userSettings', 'g // Go back 10 seconds ticks -= 100000000; + // If there's no previous track, then at least rewind to beginning + if (self.getCurrentPlaylistIndex(player) === 0) { + ticks = Math.max(ticks, 0); + } + var previousChapters = (item.Chapters || []).filter(function (i) { return i.StartPositionTicks <= ticks; }); if (previousChapters.length) { - self.seek(previousChapters[previousChapters.length - 1].StartPositionTicks); + self.seek(previousChapters[previousChapters.length - 1].StartPositionTicks, player); } else { - self.previousTrack(); + self.previousTrack(player); } }; - self.fastForward = function () { + self.fastForward = function (player) { - var player = currentPlayer; + player = player || currentPlayer; if (player.fastForward != null) { player.fastForward(userSettings.skipForwardLength()); @@ -979,9 +991,9 @@ define(['events', 'datetime', 'appSettings', 'pluginManager', 'userSettings', 'g } }; - self.rewind = function () { + self.rewind = function (player) { - var player = currentPlayer; + player = player || currentPlayer; if (player.rewind != null) { player.rewind(userSettings.skipBackLength()); @@ -1492,7 +1504,15 @@ define(['events', 'datetime', 'appSettings', 'pluginManager', 'userSettings', 'g } var afterPlayInternal = function () { - setPlaylistState(0, items); + + for (var i = 0, length = items.length; i < length; i++) { + addUniquePlaylistItemId(items[i]); + } + playlist = items.slice(0); + + var playIndex = 0; + + setPlaylistState(items[playIndex].PlaylistItemId, playIndex); loading.hide(); }; @@ -1519,13 +1539,22 @@ define(['events', 'datetime', 'appSettings', 'pluginManager', 'userSettings', 'g return true; } - // Set currentPlaylistIndex and playlist. Using a method allows for overloading in derived player implementations - function setPlaylistState(i, items) { - if (!isNaN(i)) { - currentPlaylistIndex = i; + var currentId = 0; + function addUniquePlaylistItemId(item) { + + if (!item.PlaylistItemId) { + + item.PlaylistItemId = "playlistItem" + currentId; + currentId++; } - if (items) { - playlist = items.slice(0); + } + + // Set playlist state. Using a method allows for overloading in derived player implementations + function setPlaylistState(playlistItemId, index) { + + if (!isNaN(index)) { + currentPlaylistIndex = index; + currentPlaylistItemId = playlistItemId; } } @@ -2215,55 +2244,114 @@ define(['events', 'datetime', 'appSettings', 'pluginManager', 'userSettings', 'g } } - self.setCurrentPlaylistIndex = function (i, player) { + function findPlaylistIndex(playlistItemId, list) { + + for (var i = 0, length = playlist.length; i < length; i++) { + if (list[i].PlaylistItemId === playlistItemId) { + return i; + } + } + + return -1; + } + + self.setCurrentPlaylistItem = function (playlistItemId, player) { player = player || currentPlayer; if (player && !enableLocalPlaylistManagement(player)) { - return player.setCurrentPlaylistIndex(i); + return player.setCurrentPlaylistItem(playlistItemId); } - var newItem = playlist[i]; + var newItem; + var newItemIndex; + for (var i = 0, length = playlist.length; i < length; i++) { + if (playlist[i].PlaylistItemId === playlistItemId) { + newItem = playlist[i]; + newItemIndex = i; + break; + } + } - var playOptions = Object.assign({}, currentPlayOptions, { - startPositionTicks: 0 - }); + if (newItem) { + var playOptions = Object.assign({}, currentPlayOptions, { + startPositionTicks: 0 + }); - playInternal(newItem, playOptions, function () { - currentPlaylistIndex = i; - }); + playInternal(newItem, playOptions, function () { + setPlaylistState(newItem.PlaylistItemId, newItemIndex); + }); + } }; - self.removeFromPlaylist = function (index, player) { + self.removeFromPlaylist = function (playlistItemIds, player) { - if (index < 0) { - throw new Error('Invalid playlist index'); + if (!playlistItemIds) { + throw new Error('Invalid playlistItemIds'); } player = player || currentPlayer; if (player && !enableLocalPlaylistManagement(player)) { - return player.removeFromPlaylist(i); + return player.removeFromPlaylist(playlistItemIds); } - if (playlist.length <= 1) { + if (playlist.length <= playlistItemIds.length) { return self.stop(); } - var isCurrentIndex = self.getCurrentPlaylistIndex(player) === index; - - playlist.splice(index, 1); + var currentPlaylistItemId = self.currentItem(player).PlaylistItemId; + var isCurrentIndex = playlistItemIds.indexOf(currentPlaylistItemId) !== -1; + playlist = playlist.filter(function (item) { + return playlistItemIds.indexOf(item.PlaylistItemId) === -1; + }); events.trigger(player, 'playlistitemremove', [ { - index: index + playlistItemIds: playlistItemIds }]); if (isCurrentIndex) { - return self.setCurrentPlaylistIndex(Math.min(index, playlist.length - 1), player); + return self.setCurrentPlaylistItem(0, player); } return Promise.resolve(); }; + function moveInArray(array, from, to) { + array.splice(to, 0, array.splice(from, 1)[0]); + } + + self.movePlaylistItem = function (playlistItemId, newIndex, player) { + + player = player || currentPlayer; + if (player && !enableLocalPlaylistManagement(player)) { + return player.movePlaylistItem(playlistItemId, newIndex); + } + + var oldIndex; + for (var i = 0, length = playlist.length; i < length; i++) { + if (playlist[i].PlaylistItemId === playlistItemId) { + oldIndex = i; + break; + } + } + + if (oldIndex === -1 || oldIndex === newIndex) { + return; + } + + if (newIndex >= playlist.length) { + throw new Error('newIndex out of bounds'); + } + + moveInArray(playlist, oldIndex, newIndex); + + events.trigger(player, 'playlistitemmove', [ + { + playlistItemId: playlistItemId, + newIndex: newIndex + }]); + }; + self.getCurrentPlaylistIndex = function (i, player) { player = player || currentPlayer; @@ -2271,7 +2359,17 @@ define(['events', 'datetime', 'appSettings', 'pluginManager', 'userSettings', 'g return player.getCurrentPlaylistIndex(); } - return currentPlaylistIndex; + return findPlaylistIndex(currentPlaylistItemId, playlist); + }; + + self.getCurrentPlaylistItemId = function (i, player) { + + player = player || currentPlayer; + if (player && !enableLocalPlaylistManagement(player)) { + return player.getCurrentPlaylistItemId(); + } + + return currentPlaylistItemId; }; self.setRepeatMode = function (value, player) { @@ -2295,7 +2393,7 @@ define(['events', 'datetime', 'appSettings', 'pluginManager', 'userSettings', 'g return repeatMode; }; - function getNextItemInfo() { + function getNextItemInfo(player) { var newIndex; var playlistLength = playlist.length; @@ -2303,16 +2401,16 @@ define(['events', 'datetime', 'appSettings', 'pluginManager', 'userSettings', 'g switch (self.getRepeatMode()) { case 'RepeatOne': - newIndex = currentPlaylistIndex; + newIndex = self.getCurrentPlaylistIndex(player); break; case 'RepeatAll': - newIndex = currentPlaylistIndex + 1; + newIndex = self.getCurrentPlaylistIndex(player) + 1; if (newIndex >= playlistLength) { newIndex = 0; } break; default: - newIndex = currentPlaylistIndex + 1; + newIndex = self.getCurrentPlaylistIndex(player) + 1; break; } @@ -2339,7 +2437,7 @@ define(['events', 'datetime', 'appSettings', 'pluginManager', 'userSettings', 'g return player.nextTrack(); } - var newItemInfo = getNextItemInfo(); + var newItemInfo = getNextItemInfo(player); if (newItemInfo) { @@ -2350,7 +2448,7 @@ define(['events', 'datetime', 'appSettings', 'pluginManager', 'userSettings', 'g }); playInternal(newItemInfo.item, playOptions, function () { - setPlaylistState(newItemInfo.index); + setPlaylistState(newItemInfo.item.PlaylistItemId, newItemInfo.index); }); } }; @@ -2362,7 +2460,7 @@ define(['events', 'datetime', 'appSettings', 'pluginManager', 'userSettings', 'g return player.previousTrack(); } - var newIndex = currentPlaylistIndex - 1; + var newIndex = self.getCurrentPlaylistIndex(player) - 1; if (newIndex >= 0) { var newItem = playlist[newIndex]; @@ -2373,7 +2471,7 @@ define(['events', 'datetime', 'appSettings', 'pluginManager', 'userSettings', 'g }); playInternal(newItem, playOptions, function () { - setPlaylistState(newIndex); + setPlaylistState(newItem.PlaylistItemId, newIndex); }); } } @@ -2431,6 +2529,8 @@ define(['events', 'datetime', 'appSettings', 'pluginManager', 'userSettings', 'g function queueAll(items, mode) { for (var i = 0, length = items.length; i < length; i++) { + + addUniquePlaylistItemId(items[i]); playlist.push(items[i]); } } @@ -2531,7 +2631,7 @@ define(['events', 'datetime', 'appSettings', 'pluginManager', 'userSettings', 'g clearProgressInterval(player); - var nextItem = playNextAfterEnded ? getNextItemInfo() : null; + var nextItem = playNextAfterEnded ? getNextItemInfo(player) : null; var nextMediaType = (nextItem ? nextItem.item.MediaType : null); @@ -2548,6 +2648,7 @@ define(['events', 'datetime', 'appSettings', 'pluginManager', 'userSettings', 'g if (!nextItem) { playlist = []; currentPlaylistIndex = -1; + currentPlaylistItemId = null; } events.trigger(player, 'playbackstop', [state]); diff --git a/dashboard-ui/bower_components/emby-webcomponents/playmenu.js b/dashboard-ui/bower_components/emby-webcomponents/playmenu.js index 7bcd216bbc..ec969fd309 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/playmenu.js +++ b/dashboard-ui/bower_components/emby-webcomponents/playmenu.js @@ -44,13 +44,6 @@ define(['actionsheet', 'datetime', 'playbackManager', 'globalize', 'appSettings' }); } - if (playbackManager.canQueue(item)) { - menuItems.push({ - name: globalize.translate('sharedcomponents#Queue'), - id: 'queue' - }); - } - if (itemType === "Audio" || itemType === "MusicAlbum" || itemType === "MusicArtist" || itemType === "MusicGenre") { menuItems.push({ name: globalize.translate('sharedcomponents#InstantMix'), diff --git a/dashboard-ui/bower_components/emby-webcomponents/router.js b/dashboard-ui/bower_components/emby-webcomponents/router.js index d5405e377f..827048ae1b 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/router.js +++ b/dashboard-ui/bower_components/emby-webcomponents/router.js @@ -178,6 +178,7 @@ define(['loading', 'viewManager', 'skinManager', 'pluginManager', 'backdrop', 'b isBack: isBackNav, state: ctx.state, type: route.type, + fullscreen: route.fullscreen, controllerFactory: controllerFactory, options: { supportsThemeMedia: route.supportsThemeMedia || false diff --git a/dashboard-ui/bower_components/emby-webcomponents/sessionplayer.js b/dashboard-ui/bower_components/emby-webcomponents/sessionplayer.js index be037961ee..7378e8f0a1 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/sessionplayer.js +++ b/dashboard-ui/bower_components/emby-webcomponents/sessionplayer.js @@ -283,15 +283,19 @@ return state.MediaType === 'Audio'; }; + self.getPlaylist = function () { + return Promise.resolve([]); + }; + self.getCurrentPlaylistIndex = function () { return 0; }; - self.setCurrentPlaylistIndex = function (index) { + self.setCurrentPlaylistItem = function (playlistItemId) { return Promise.resolve(); }; - self.removeFromPlaylist = function (index) { + self.removeFromPlaylist = function (playlistItemIds) { return Promise.resolve(); }; diff --git a/dashboard-ui/bower_components/emby-webcomponents/shortcuts.js b/dashboard-ui/bower_components/emby-webcomponents/shortcuts.js index 29dacc2782..465e805a51 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/shortcuts.js +++ b/dashboard-ui/bower_components/emby-webcomponents/shortcuts.js @@ -288,7 +288,7 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'embyRouter', 'g } else if (action === 'setplaylistindex') { - playbackManager.setCurrentPlaylistIndex(parseInt(card.getAttribute('data-index'))); + playbackManager.setCurrentPlaylistItem(card.getAttribute('data-playlistitemid')); } else if (action === 'record') { @@ -337,8 +337,7 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'embyRouter', 'g card.dispatchEvent(new CustomEvent('action-' + customAction, { detail: { - item: getItem(target), - index: parseInt(card.getAttribute('data-index') || '-1') + playlistItemId: card.getAttribute('data-playlistitemid') }, cancelable: false, bubbles: true diff --git a/dashboard-ui/bower_components/emby-webcomponents/viewmanager/viewcontainer-lite.js b/dashboard-ui/bower_components/emby-webcomponents/viewmanager/viewcontainer-lite.js index 570fae8be4..ba26716362 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/viewmanager/viewcontainer-lite.js +++ b/dashboard-ui/bower_components/emby-webcomponents/viewmanager/viewcontainer-lite.js @@ -43,6 +43,16 @@ define(['browser', 'dom', 'css!./viewcontainer-lite'], function (browser, dom) { if (options.type) { view.setAttribute('data-type', options.type); } + + var properties = []; + if (options.fullscreen) { + properties.push('fullscreen'); + } + + if (properties.length) { + view.setAttribute('data-properties', properties.join(',')); + } + view.innerHTML = options.view; var currentPage = allPages[pageIndex]; diff --git a/dashboard-ui/bower_components/emby-webcomponents/viewmanager/viewmanager.js b/dashboard-ui/bower_components/emby-webcomponents/viewmanager/viewmanager.js index c22a6ca9b0..3c464f46ce 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/viewmanager/viewmanager.js +++ b/dashboard-ui/bower_components/emby-webcomponents/viewmanager/viewmanager.js @@ -65,23 +65,33 @@ define(['viewcontainer', 'focusManager', 'queryString', 'layoutManager'], functi } } + function getProperties(view) { + var props = view.getAttribute('data-properties'); + + if (props) { + return props.split(','); + } + + return []; + } + function dispatchViewEvent(view, eventName, isRestored, isCancellable) { + var eventDetail = { + type: view.getAttribute('data-type'), + isRestored: isRestored, + properties: getProperties(view) + }; + var eventResult = view.dispatchEvent(new CustomEvent(eventName, { - detail: { - type: view.getAttribute('data-type'), - isRestored: isRestored - }, + detail: eventDetail, bubbles: true, cancelable: isCancellable || false })); if (dispatchPageEvents) { view.dispatchEvent(new CustomEvent(eventName.replace('view', 'page'), { - detail: { - type: view.getAttribute('data-type'), - isRestored: isRestored - }, + detail: eventDetail, bubbles: true, cancelable: false })); @@ -93,13 +103,13 @@ define(['viewcontainer', 'focusManager', 'queryString', 'layoutManager'], functi function getViewEventDetail(view, options, isRestore) { var url = options.url; - var state = options.state; var index = url.indexOf('?'); var params = index === -1 ? {} : queryString.parse(url.substring(index + 1)); return { detail: { type: view.getAttribute('data-type'), + properties: getProperties(view), params: params, isRestored: isRestore, state: options.state, diff --git a/dashboard-ui/components/dockedtabs/dockedtabs.js b/dashboard-ui/components/dockedtabs/dockedtabs.js index b016d6d136..d6bedc6711 100644 --- a/dashboard-ui/components/dockedtabs/dockedtabs.js +++ b/dashboard-ui/components/dockedtabs/dockedtabs.js @@ -326,7 +326,7 @@ var instance; function onViewShow(e) { - if (e.detail.type === 'video-osd' || !Dashboard.getCurrentUserId()) { + if (e.detail.properties.indexOf('fullscreen') !== -1 || !Dashboard.getCurrentUserId()) { instance.hide(); } else { instance.show(); diff --git a/dashboard-ui/components/remotecontrol.js b/dashboard-ui/components/remotecontrol.js index 34dd86d310..df82fbf0cd 100644 --- a/dashboard-ui/components/remotecontrol.js +++ b/dashboard-ui/components/remotecontrol.js @@ -451,7 +451,7 @@ function getPlaylistItems(player) { - return Promise.resolve(playbackManager.playlist(player)); + return playbackManager.getPlaylist(player); return ApiClient.getItems(Dashboard.getCurrentUserId(), { @@ -487,7 +487,8 @@ icon: '', title: globalize.translate('ButtonRemove'), id: 'remove' - }] + }], + dragHandle: true }); playlistNeedsRefresh = false; @@ -496,13 +497,12 @@ itemsContainer.innerHTML = html; - var index = playbackManager.getCurrentPlaylistIndex(player); + var playlistItemId = playbackManager.getCurrentPlaylistItemId(player); - if (index != -1) { + if (playlistItemId) { - var item = itemsContainer.querySelectorAll('.listItem')[index]; - if (item) { - var img = item.querySelector('.listItemImage'); + var img = itemsContainer.querySelector('.listItem[data-playlistItemId="' + playlistItemId + '"] .listItemImage'); + if (img) { img.classList.remove('lazy'); img.classList.add('playlistIndexIndicatorImage'); @@ -531,7 +531,7 @@ } function onPlaylistUpdate(e) { - + var player = this; playbackManager.getPlayerState(player).then(function (state) { @@ -598,6 +598,7 @@ events.off(player, 'statechange', onPlaybackStart); events.off(player, 'repeatmodechange', onRepeatModeChange); events.off(player, 'playlistitemremove', onPlaylistUpdate); + events.off(player, 'playlistitemmove', onPlaylistUpdate); events.off(player, 'playbackstop', onPlaybackStopped); events.off(player, 'volumechange', onVolumeChanged); events.off(player, 'pause', onPlayPauseStateChanged); @@ -627,6 +628,7 @@ events.on(player, 'statechange', onPlaybackStart); events.on(player, 'repeatmodechange', onRepeatModeChange); events.on(player, 'playlistitemremove', onPlaylistUpdate); + events.on(player, 'playlistitemmove', onPlaylistUpdate); events.on(player, 'playbackstop', onPlaybackStopped); events.on(player, 'volumechange', onVolumeChanged); events.on(player, 'pause', onPlayPauseStateChanged); @@ -768,10 +770,22 @@ playbackManager.toggleMute(currentPlayer); }); - context.querySelector('.playlist').addEventListener('action-remove', function (e) { - playbackManager.removeFromPlaylist(e.detail.index, currentPlayer); + var playlistContainer = context.querySelector('.playlist'); + + playlistContainer.addEventListener('action-remove', function (e) { + + playbackManager.removeFromPlaylist([e.detail.playlistItemId], currentPlayer); }); + playlistContainer.addEventListener('itemdrop', function (e) { + + var newIndex = e.detail.newIndex; + var playlistItemId = e.detail.playlistItemId; + + playbackManager.movePlaylistItem(playlistItemId, newIndex, currentPlayer); + }); + + playlistContainer.enableDragReordering(true); } function onPlayerChange() { diff --git a/dashboard-ui/components/viewcontainer-lite.js b/dashboard-ui/components/viewcontainer-lite.js index bd8b593a41..6300519722 100644 --- a/dashboard-ui/components/viewcontainer-lite.js +++ b/dashboard-ui/components/viewcontainer-lite.js @@ -102,6 +102,15 @@ define(['browser'], function (browser) { view.setAttribute('data-type', options.type); } + var properties = []; + if (options.fullscreen) { + properties.push('fullscreen'); + } + + if (properties.length) { + view.setAttribute('data-properties', properties.join(',')); + } + var animatable = view; allPages[pageIndex] = view; diff --git a/dashboard-ui/css/librarybrowser.css b/dashboard-ui/css/librarybrowser.css index 253f6d248f..837ca4c4f6 100644 --- a/dashboard-ui/css/librarybrowser.css +++ b/dashboard-ui/css/librarybrowser.css @@ -286,7 +286,6 @@ span.itemCommunityRating:not(:empty) + .userDataIcons { } .detailUserDataIcons { - margin-left: .5em; white-space: nowrap; } diff --git a/dashboard-ui/css/nowplaying.css b/dashboard-ui/css/nowplaying.css index b881004ee8..ed9a32cdd5 100644 --- a/dashboard-ui/css/nowplaying.css +++ b/dashboard-ui/css/nowplaying.css @@ -101,7 +101,7 @@ .nowPlayingPageImage { width: auto; - height: 40vh; + height: 36vh; } } diff --git a/dashboard-ui/itemdetails.html b/dashboard-ui/itemdetails.html index ca296da6d1..911cc79f01 100644 --- a/dashboard-ui/itemdetails.html +++ b/dashboard-ui/itemdetails.html @@ -17,7 +17,7 @@ -
+
@@ -55,8 +55,8 @@ more_vert   +
-
diff --git a/dashboard-ui/scripts/site.js b/dashboard-ui/scripts/site.js index 07dd0981ca..c20458ba5f 100644 --- a/dashboard-ui/scripts/site.js +++ b/dashboard-ui/scripts/site.js @@ -2095,7 +2095,8 @@ var AppInfo = {}; dependencies: ['paper-icon-button-light', 'emby-slider', 'emby-button', 'emby-input', 'emby-itemscontainer'], controller: 'scripts/nowplayingpage', autoFocus: false, - transition: 'fade' + transition: 'fade', + fullscreen: true }); defineRoute({ @@ -2346,7 +2347,8 @@ var AppInfo = {}; controller: 'scripts/videoosd', autoFocus: false, type: 'video-osd', - supportsThemeMedia: true + supportsThemeMedia: true, + fullscreen: true }); defineRoute({ diff --git a/dashboard-ui/scripts/videoosd.js b/dashboard-ui/scripts/videoosd.js index 6b6b6e331e..f1762344c4 100644 --- a/dashboard-ui/scripts/videoosd.js +++ b/dashboard-ui/scripts/videoosd.js @@ -734,29 +734,14 @@ function updatePlaylist(player) { - var items = playbackManager.playlist(player); - - var index = playbackManager.getCurrentPlaylistIndex(player); - - var previousEnabled = index > 0; - var nextEnabled = (index < items.length - 1); - var btnPreviousTrack = view.querySelector('.btnPreviousTrack'); var btnNextTrack = view.querySelector('.btnNextTrack'); - if (!nextEnabled && !previousEnabled) { + btnPreviousTrack.classList.remove('hide'); + btnNextTrack.classList.remove('hide'); - btnPreviousTrack.classList.add('hide'); - btnNextTrack.classList.add('hide'); - - } else { - - btnPreviousTrack.classList.remove('hide'); - btnNextTrack.classList.remove('hide'); - - btnNextTrack.disabled = !nextEnabled; - btnPreviousTrack.disabled = !previousEnabled; - } + btnNextTrack.disabled = false; + btnPreviousTrack.disabled = false; } function updateTimeText(elem, ticks, divider) {