diff --git a/dashboard-ui/bower_components/emby-webcomponents/listview/listview.js b/dashboard-ui/bower_components/emby-webcomponents/listview/listview.js
index 0e4fc98d1..ee90a5e35 100644
--- a/dashboard-ui/bower_components/emby-webcomponents/listview/listview.js
+++ b/dashboard-ui/bower_components/emby-webcomponents/listview/listview.js
@@ -142,6 +142,20 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan
return html;
}
+ function getRightButtonsHtml(options) {
+
+ var html = '';
+
+ for (var i = 0, length = options.rightButtons.length; i < length; i++) {
+
+ var button = options.rightButtons[i];
+
+ html += '';
+ }
+
+ return html;
+ }
+
function getListViewHtml(options) {
var items = options.items;
@@ -406,9 +420,8 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan
html += '';
}
- if (options.recordButton) {
-
- html += '';
+ if (options.rightButtons) {
+ html += getRightButtonsHtml(options);
}
if (options.enableUserDataButtons !== false) {
diff --git a/dashboard-ui/bower_components/emby-webcomponents/playback/playbackmanager.js b/dashboard-ui/bower_components/emby-webcomponents/playback/playbackmanager.js
index 7e2390429..ec6f7240a 100644
--- a/dashboard-ui/bower_components/emby-webcomponents/playback/playbackmanager.js
+++ b/dashboard-ui/bower_components/emby-webcomponents/playback/playbackmanager.js
@@ -2215,7 +2215,12 @@ define(['events', 'datetime', 'appSettings', 'pluginManager', 'userSettings', 'g
}
}
- self.setCurrentPlaylistIndex = function (i) {
+ self.setCurrentPlaylistIndex = function (i, player) {
+
+ player = player || currentPlayer;
+ if (player && !enableLocalPlaylistManagement(player)) {
+ return player.setCurrentPlaylistIndex(i);
+ }
var newItem = playlist[i];
@@ -2228,7 +2233,43 @@ define(['events', 'datetime', 'appSettings', 'pluginManager', 'userSettings', 'g
});
};
- self.getCurrentPlaylistIndex = function (i) {
+ self.removeFromPlaylist = function (index, player) {
+
+ if (index < 0) {
+ throw new Error('Invalid playlist index');
+ }
+
+ player = player || currentPlayer;
+ if (player && !enableLocalPlaylistManagement(player)) {
+ return player.removeFromPlaylist(i);
+ }
+
+ if (playlist.length <= 1) {
+ return self.stop();
+ }
+
+ var isCurrentIndex = self.getCurrentPlaylistIndex(player) === index;
+
+ playlist.splice(index, 1);
+
+ events.trigger(player, 'playlistitemremove', [
+ {
+ index: index
+ }]);
+
+ if (isCurrentIndex) {
+ return self.setCurrentPlaylistIndex(Math.min(index, playlist.length - 1), player);
+ }
+
+ return Promise.resolve();
+ };
+
+ self.getCurrentPlaylistIndex = function (i, player) {
+
+ player = player || currentPlayer;
+ if (player && !enableLocalPlaylistManagement(player)) {
+ return player.getCurrentPlaylistIndex();
+ }
return currentPlaylistIndex;
};
@@ -2241,7 +2282,7 @@ define(['events', 'datetime', 'appSettings', 'pluginManager', 'userSettings', 'g
}
repeatMode = value;
- events.trigger(self, 'repeatmodechange');
+ events.trigger(player, 'repeatmodechange');
};
self.getRepeatMode = function (player) {
diff --git a/dashboard-ui/bower_components/emby-webcomponents/shortcuts.js b/dashboard-ui/bower_components/emby-webcomponents/shortcuts.js
index 70d0bf10d..29dacc278 100644
--- a/dashboard-ui/bower_components/emby-webcomponents/shortcuts.js
+++ b/dashboard-ui/bower_components/emby-webcomponents/shortcuts.js
@@ -330,6 +330,20 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'embyRouter', 'g
else if (action === 'addtoplaylist') {
getItem(target).then(addToPlaylist);
}
+
+ else if (action === 'custom') {
+
+ var customAction = target.getAttribute('data-customaction');
+
+ card.dispatchEvent(new CustomEvent('action-' + customAction, {
+ detail: {
+ item: getItem(target),
+ index: parseInt(card.getAttribute('data-index') || '-1')
+ },
+ cancelable: false,
+ bubbles: true
+ }));
+ }
}
function addToPlaylist(item) {
diff --git a/dashboard-ui/components/remotecontrol.js b/dashboard-ui/components/remotecontrol.js
index 0c0294be9..cb47d3750 100644
--- a/dashboard-ui/components/remotecontrol.js
+++ b/dashboard-ui/components/remotecontrol.js
@@ -262,13 +262,11 @@
var self = this;
var playlistNeedsRefresh = true;
- var isEnabled;
function toggleRepeat(player) {
-
- if (player && lastPlayerState) {
- var state = lastPlayerState;
- switch ((state.PlayState || {}).RepeatMode) {
+
+ if (player) {
+ switch (playbackManager.getRepeatMode(player)) {
case 'RepeatNone':
playbackManager.setRepeatMode('RepeatAll', player);
break;
@@ -329,21 +327,26 @@
context.classList.add('hideVideoButtons');
}
+ updateRepeatModeDisplay(playState.RepeatMode);
+ updateNowPlayingInfo(context, state);
+ }
+
+ function updateRepeatModeDisplay(repeatMode) {
+
+ var context = dlg;
var toggleRepeatButton = context.querySelector('.repeatToggleButton');
- if (playState.RepeatMode == 'RepeatAll') {
+ if (repeatMode == 'RepeatAll') {
toggleRepeatButton.innerHTML = "repeat";
toggleRepeatButton.classList.add('nowPlayingPageRepeatActive');
}
- else if (playState.RepeatMode == 'RepeatOne') {
+ else if (repeatMode == 'RepeatOne') {
toggleRepeatButton.innerHTML = "repeat_one";
toggleRepeatButton.classList.add('nowPlayingPageRepeatActive');
} else {
toggleRepeatButton.innerHTML = "repeat";
toggleRepeatButton.classList.remove('nowPlayingPageRepeatActive');
}
-
- updateNowPlayingInfo(context, state);
}
function updatePlayerVolumeState(context, isMuted, volumeLevel) {
@@ -471,14 +474,20 @@
function loadPlaylist(context, player) {
getPlaylistItems(player).then(function (items) {
-
+
var html = '';
html += listView.getListViewHtml({
items: items,
smallIcon: true,
action: 'setplaylistindex',
- enableUserDataButtons: false
+ enableUserDataButtons: false,
+ rightButtons: [
+ {
+ icon: '',
+ title: globalize.translate('ButtonRemove'),
+ id: 'remove'
+ }]
});
playlistNeedsRefresh = false;
@@ -514,6 +523,23 @@
loadPlaylist(dlg, player);
}
+ function onRepeatModeChange(e) {
+
+ var player = this;
+
+ updateRepeatModeDisplay(playbackManager.getRepeatMode(player));
+ }
+
+ function onPlaylistUpdate(e) {
+
+ var player = this;
+
+ playbackManager.getPlayerState(player).then(function (state) {
+
+ onStateChanged.call(player, { type: 'init' }, state);
+ });
+ }
+
function onPlaybackStopped(e, state) {
console.log('remotecontrol event: ' + e.type);
@@ -568,7 +594,8 @@
events.off(player, 'playbackstart', onPlaybackStart);
events.off(player, 'statechange', onPlaybackStart);
- events.off(player, 'repeatmodechange', onPlaybackStart);
+ events.off(player, 'repeatmodechange', onRepeatModeChange);
+ events.off(player, 'playlistitemremove', onPlaylistUpdate);
events.off(player, 'playbackstop', onPlaybackStopped);
events.off(player, 'volumechange', onVolumeChanged);
events.off(player, 'pause', onPlayPauseStateChanged);
@@ -596,9 +623,8 @@
events.on(player, 'playbackstart', onPlaybackStart);
events.on(player, 'statechange', onPlaybackStart);
- // TODO: Replace this with smaller changes on repeatmodechange.
- // For now go cheap and just refresh the entire component
- events.on(player, 'repeatmodechange', onPlaybackStart);
+ events.on(player, 'repeatmodechange', onRepeatModeChange);
+ events.on(player, 'playlistitemremove', onPlaylistUpdate);
events.on(player, 'playbackstop', onPlaybackStopped);
events.on(player, 'volumechange', onVolumeChanged);
events.on(player, 'pause', onPlayPauseStateChanged);
@@ -740,6 +766,10 @@
playbackManager.toggleMute(currentPlayer);
});
+ context.querySelector('.playlist').addEventListener('action-remove', function (e) {
+
+ playbackManager.removeFromPlaylist(e.detail.index, currentPlayer);
+ });
}
function onPlayerChange() {
diff --git a/dashboard-ui/scripts/nowplayingbar.js b/dashboard-ui/scripts/nowplayingbar.js
index 09edcf170..0edbe2bf5 100644
--- a/dashboard-ui/scripts/nowplayingbar.js
+++ b/dashboard-ui/scripts/nowplayingbar.js
@@ -188,9 +188,8 @@
toggleRepeatButton.addEventListener('click', function () {
if (currentPlayer) {
- var state = lastPlayerState || {};
- switch ((state.PlayState || {}).RepeatMode) {
+ switch (playbackManager.getRepeatMode(currentPlayer)) {
case 'RepeatAll':
playbackManager.setRepeatMode('RepeatOne', currentPlayer);
break;
@@ -344,17 +343,7 @@
toggleRepeatButton.classList.remove('hide');
}
- if (playState.RepeatMode == 'RepeatAll') {
- toggleRepeatButtonIcon.innerHTML = "repeat";
- toggleRepeatButton.classList.add('repeatActive');
- }
- else if (playState.RepeatMode == 'RepeatOne') {
- toggleRepeatButtonIcon.innerHTML = "repeat_one";
- toggleRepeatButton.classList.add('repeatActive');
- } else {
- toggleRepeatButtonIcon.innerHTML = "repeat";
- toggleRepeatButton.classList.remove('repeatActive');
- }
+ updateRepeatModeDisplay(playState.RepeatMode);
updatePlayerVolumeState(playState.IsMuted, playState.VolumeLevel);
@@ -368,6 +357,21 @@
updateNowPlayingInfo(state);
}
+ function updateRepeatModeDisplay(repeatMode) {
+
+ if (repeatMode == 'RepeatAll') {
+ toggleRepeatButtonIcon.innerHTML = "repeat";
+ toggleRepeatButton.classList.add('repeatActive');
+ }
+ else if (repeatMode == 'RepeatOne') {
+ toggleRepeatButtonIcon.innerHTML = "repeat_one";
+ toggleRepeatButton.classList.add('repeatActive');
+ } else {
+ toggleRepeatButtonIcon.innerHTML = "repeat";
+ toggleRepeatButton.classList.remove('repeatActive');
+ }
+ }
+
function updateTimeDisplay(positionTicks, runtimeTicks) {
// See bindEvents for why this is necessary
@@ -576,6 +580,13 @@
onStateChanged.call(player, e, state);
}
+ function onRepeatModeChange(e) {
+
+ var player = this;
+
+ updateRepeatModeDisplay(playbackManager.getRepeatMode(player));
+ }
+
function showNowPlayingBar() {
getNowPlayingBar().then(slideUp);
@@ -681,7 +692,7 @@
if (player) {
events.off(player, 'playbackstart', onPlaybackStart);
events.off(player, 'statechange', onPlaybackStart);
- events.off(player, 'repeatmodechange', onPlaybackStart);
+ events.off(player, 'repeatmodechange', onRepeatModeChange);
events.off(player, 'playbackstop', onPlaybackStopped);
events.off(player, 'volumechange', onVolumeChanged);
events.off(player, 'pause', onPlayPauseStateChanged);
@@ -725,9 +736,7 @@
events.on(player, 'playbackstart', onPlaybackStart);
events.on(player, 'statechange', onPlaybackStart);
- // TODO: Replace this with smaller changes on repeatmodechange.
- // For now go cheap and just refresh the entire component
- events.on(player, 'repeatmodechange', onPlaybackStart);
+ events.on(player, 'repeatmodechange', onRepeatModeChange);
events.on(player, 'playbackstop', onPlaybackStopped);
events.on(player, 'volumechange', onVolumeChanged);
events.on(player, 'pause', onPlayPauseStateChanged);