';
var imgClass = 'cardImage cardImage-img lazy';
if (coveredImage) {
@@ -1318,7 +1323,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'mediaInfo
}
if (!imgUrl) {
- var defaultName = item.Type === 'Program' ? item.Name : itemHelper.getDisplayName(item);
+ var defaultName = item.Type === 'Program' || item.Type == 'Timer' || item.EpisodeTitle ? item.Name : itemHelper.getDisplayName(item);
cardImageContainerOpen += '
' + defaultName + '
';
}
diff --git a/dashboard-ui/bower_components/emby-webcomponents/dialog/dialog.template.html b/dashboard-ui/bower_components/emby-webcomponents/dialog/dialog.template.html
index 96fc5ae5ed..7fa18c17ad 100644
--- a/dashboard-ui/bower_components/emby-webcomponents/dialog/dialog.template.html
+++ b/dashboard-ui/bower_components/emby-webcomponents/dialog/dialog.template.html
@@ -1,5 +1,5 @@
diff --git a/dashboard-ui/bower_components/emby-webcomponents/guide/guide.js b/dashboard-ui/bower_components/emby-webcomponents/guide/guide.js
index a0c4187564..26cc3237f6 100644
--- a/dashboard-ui/bower_components/emby-webcomponents/guide/guide.js
+++ b/dashboard-ui/bower_components/emby-webcomponents/guide/guide.js
@@ -374,7 +374,7 @@
return '';
}
- return '';
+ return '';
}
function getChannelProgramsHtml(context, date, channel, programs, options) {
diff --git a/dashboard-ui/bower_components/emby-webcomponents/images/imagehelper.js b/dashboard-ui/bower_components/emby-webcomponents/images/imagehelper.js
index 14972c29ff..accdea5740 100644
--- a/dashboard-ui/bower_components/emby-webcomponents/images/imagehelper.js
+++ b/dashboard-ui/bower_components/emby-webcomponents/images/imagehelper.js
@@ -52,9 +52,9 @@ define(['visibleinviewport', 'imageFetcher', 'layoutManager', 'events', 'browser
imageFetcher.loadImage(elem, source).then(function () {
- fillVibrant(elem, source);
+ var fillingVibrant = fillVibrant(elem, source);
- if (enableFade && !layoutManager.tv && enableEffects !== false) {
+ if (enableFade && !layoutManager.tv && enableEffects !== false && !fillingVibrant) {
fadeIn(elem);
}
@@ -66,30 +66,27 @@ define(['visibleinviewport', 'imageFetcher', 'layoutManager', 'events', 'browser
function fillVibrant(img, url) {
if (img.tagName != 'IMG') {
- return;
+ return false;
}
var vibrantElement = img.getAttribute('data-vibrant');
if (!vibrantElement) {
- return;
+ return false;
}
if (window.Vibrant) {
fillVibrantOnLoaded(img, url, vibrantElement);
- return;
+ return true;
}
require(['vibrant'], function () {
fillVibrantOnLoaded(img, url, vibrantElement);
});
+ return true;
}
function fillVibrantOnLoaded(img, url, vibrantElement) {
- if (img.tagName != 'IMG') {
- return;
- }
-
vibrantElement = document.getElementById(vibrantElement);
if (!vibrantElement) {
return;
@@ -121,8 +118,7 @@ define(['visibleinviewport', 'imageFetcher', 'layoutManager', 'events', 'browser
url = url.split('?')[0];
- console.log(url);
- return 'vibrant3-' + url;
+ return 'vibrant5-' + url;
}
function getCachedVibrantInfo(url) {
diff --git a/dashboard-ui/bower_components/emby-webcomponents/itemcontextmenu.js b/dashboard-ui/bower_components/emby-webcomponents/itemcontextmenu.js
index 624b7ecffd..44e31c339e 100644
--- a/dashboard-ui/bower_components/emby-webcomponents/itemcontextmenu.js
+++ b/dashboard-ui/bower_components/emby-webcomponents/itemcontextmenu.js
@@ -29,13 +29,20 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'embyRouter',
});
}
- if ((item.Type == 'Timer') && user.Policy.EnableLiveTvManagement) {
+ if ((item.Type == 'Timer') && user.Policy.EnableLiveTvManagement && options.cancelTimer !== false) {
commands.push({
name: globalize.translate('sharedcomponents#ButtonCancel'),
id: 'canceltimer'
});
}
+ if ((item.Type == 'SeriesTimer') && user.Policy.EnableLiveTvManagement && options.cancelTimer !== false) {
+ commands.push({
+ name: globalize.translate('sharedcomponents#CancelSeries'),
+ id: 'cancelseriestimer'
+ });
+ }
+
if (item.CanDelete) {
if (item.Type == 'Playlist' || item.Type == 'BoxSet') {
@@ -479,6 +486,9 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'embyRouter',
case 'canceltimer':
deleteTimer(apiClient, item, resolve, id);
break;
+ case 'cancelseriestimer':
+ deleteSeriesTimer(apiClient, item, resolve, id);
+ break;
default:
reject();
break;
@@ -488,25 +498,20 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'embyRouter',
function deleteTimer(apiClient, item, resolve, command) {
- require(['confirm'], function (confirm) {
+ require(['recordingHelper'], function (recordingHelper) {
- confirm(globalize.translate('sharedcomponents#MessageConfirmRecordingCancellation'), globalize.translate('sharedcomponents#HeaderConfirmRecordingCancellation')).then(function () {
+ recordingHelper.cancelTimerWithConfirmation(item.Id, item.ServerId).then(function() {
+ getResolveFunction(resolve, command, true)();
+ });
+ });
+ }
- loading.show();
+ function deleteSeriesTimer(apiClient, item, resolve, command) {
- var promise = item.Type == 'SeriesTimer' ?
- apiClient.cancelLiveTvSeriesTimer(item.Id) :
- apiClient.cancelLiveTvTimer(item.Id);
+ require(['recordingHelper'], function (recordingHelper) {
- promise.then(function () {
-
- require(['toast'], function (toast) {
- toast(globalize.translate('sharedcomponents#RecordingCancelled'));
- });
-
- loading.hide();
- getResolveFunction(resolve, command, true)();
- });
+ recordingHelper.cancelSeriesTimerWithConfirmation(item.Id, item.ServerId).then(function () {
+ getResolveFunction(resolve, command, true)();
});
});
}
diff --git a/dashboard-ui/bower_components/emby-webcomponents/listview/listview.js b/dashboard-ui/bower_components/emby-webcomponents/listview/listview.js
index a5db2d695c..ec5a8aa768 100644
--- a/dashboard-ui/bower_components/emby-webcomponents/listview/listview.js
+++ b/dashboard-ui/bower_components/emby-webcomponents/listview/listview.js
@@ -267,7 +267,7 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan
textlines.push(datetime.getDisplayTime(datetime.parseISO8601Date(item.StartDate)));
}
- var parentTitle;
+ var parentTitle = null;
if (options.showParentTitle) {
if (item.Type == 'Episode') {
@@ -287,8 +287,12 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan
if (options.showParentTitle && options.parentTitleWithTitle) {
- if (parentTitle && displayName) {
- parentTitle += ' - ' + displayName;
+ if (displayName) {
+
+ if (parentTitle) {
+ parentTitle += ' - ';
+ }
+ parentTitle = (parentTitle || '') + displayName;
}
textlines.push(parentTitle || '');
diff --git a/dashboard-ui/bower_components/emby-webcomponents/recordingcreator/recordingeditor.js b/dashboard-ui/bower_components/emby-webcomponents/recordingcreator/recordingeditor.js
index a9e9b8fadc..7cf9fb0710 100644
--- a/dashboard-ui/bower_components/emby-webcomponents/recordingcreator/recordingeditor.js
+++ b/dashboard-ui/bower_components/emby-webcomponents/recordingcreator/recordingeditor.js
@@ -10,30 +10,9 @@
return new Promise(function (resolve, reject) {
- require(['confirm'], function (confirm) {
+ require(['recordingHelper'], function (recordingHelper) {
- confirm({
-
- title: globalize.translate('sharedcomponents#HeaderConfirmRecordingCancellation'),
- text: globalize.translate('sharedcomponents#MessageConfirmRecordingCancellation'),
- confirmText: globalize.translate('sharedcomponents#HeaderCancelRecording'),
- cancelText: globalize.translate('sharedcomponents#HeaderKeepRecording'),
- primary: 'cancel'
-
- }).then(function () {
-
- loading.show();
-
- apiClient.cancelLiveTvTimer(timerId).then(function () {
-
- require(['toast'], function (toast) {
- toast(globalize.translate('sharedcomponents#RecordingCancelled'));
- });
-
- loading.hide();
- resolve();
- });
- });
+ recordingHelper.cancelTimerWithConfirmation(timerId, apiClient.serverId()).then(resolve, reject);
});
});
}
diff --git a/dashboard-ui/bower_components/emby-webcomponents/recordingcreator/recordinghelper.js b/dashboard-ui/bower_components/emby-webcomponents/recordingcreator/recordinghelper.js
index 687118076b..60d17a95f0 100644
--- a/dashboard-ui/bower_components/emby-webcomponents/recordingcreator/recordinghelper.js
+++ b/dashboard-ui/bower_components/emby-webcomponents/recordingcreator/recordinghelper.js
@@ -25,6 +25,72 @@
});
}
+ function cancelTimerWithConfirmation(timerId, serverId) {
+
+ return new Promise(function (resolve, reject) {
+
+ require(['confirm'], function (confirm) {
+
+ confirm({
+
+ text: globalize.translate('sharedcomponents#MessageConfirmRecordingCancellation'),
+ primary: 'cancel',
+ confirmText: globalize.translate('sharedcomponents#HeaderCancelRecording'),
+ cancelText: globalize.translate('sharedcomponents#HeaderKeepRecording')
+
+ }).then(function () {
+
+ loading.show();
+
+ var apiClient = connectionManager.getApiClient(serverId);
+ apiClient.cancelLiveTvTimer(timerId).then(function () {
+
+ require(['toast'], function (toast) {
+ toast(globalize.translate('sharedcomponents#RecordingCancelled'));
+ });
+
+ loading.hide();
+ resolve();
+ }, reject);
+
+ }, reject);
+ });
+ });
+ }
+
+ function cancelSeriesTimerWithConfirmation(timerId, serverId) {
+
+ return new Promise(function (resolve, reject) {
+
+ require(['confirm'], function (confirm) {
+
+ confirm({
+
+ text: globalize.translate('sharedcomponents#MessageConfirmRecordingCancellation'),
+ primary: 'cancel',
+ confirmText: globalize.translate('sharedcomponents#HeaderCancelSeries'),
+ cancelText: globalize.translate('sharedcomponents#HeaderKeepSeries')
+
+ }).then(function () {
+
+ loading.show();
+
+ var apiClient = connectionManager.getApiClient(serverId);
+ apiClient.cancelLiveTvSeriesTimer(timerId).then(function () {
+
+ require(['toast'], function (toast) {
+ toast(globalize.translate('sharedcomponents#SeriesCancelled'));
+ });
+
+ loading.hide();
+ resolve();
+ }, reject);
+
+ }, reject);
+ });
+ });
+ }
+
function cancelTimer(apiClient, timerId, hideLoading) {
loading.show();
return apiClient.cancelLiveTvTimer(timerId).then(function () {
@@ -88,6 +154,8 @@
cancelTimer: cancelTimer,
createRecording: createRecording,
changeRecordingToSeries: changeRecordingToSeries,
- toggleRecording: toggleRecording
+ toggleRecording: toggleRecording,
+ cancelTimerWithConfirmation: cancelTimerWithConfirmation,
+ cancelSeriesTimerWithConfirmation: cancelSeriesTimerWithConfirmation
};
});
\ No newline at end of file
diff --git a/dashboard-ui/bower_components/emby-webcomponents/recordingcreator/seriesrecordingeditor.js b/dashboard-ui/bower_components/emby-webcomponents/recordingcreator/seriesrecordingeditor.js
index a91d31a8c3..15e7fe6450 100644
--- a/dashboard-ui/bower_components/emby-webcomponents/recordingcreator/seriesrecordingeditor.js
+++ b/dashboard-ui/bower_components/emby-webcomponents/recordingcreator/seriesrecordingeditor.js
@@ -10,30 +10,9 @@
return new Promise(function (resolve, reject) {
- require(['confirm'], function (confirm) {
+ require(['recordingHelper'], function (recordingHelper) {
- confirm({
-
- title: globalize.translate('sharedcomponents#HeaderConfirmRecordingCancellation'),
- text: globalize.translate('sharedcomponents#MessageConfirmRecordingCancellation'),
- confirmText: globalize.translate('sharedcomponents#HeaderCancelRecording'),
- cancelText: globalize.translate('sharedcomponents#HeaderKeepRecording'),
- primary: 'cancel'
-
- }).then(function () {
-
- loading.show();
-
- apiClient.cancelLiveSeriesTvTimer(timerId).then(function () {
-
- require(['toast'], function (toast) {
- toast(globalize.translate('sharedcomponents#RecordingCancelled'));
- });
-
- loading.hide();
- resolve();
- });
- });
+ recordingHelper.cancelSeriesTimerWithConfirmation(timerId, apiClient.serverId()).then(resolve, reject);
});
});
}
diff --git a/dashboard-ui/css/nowplayingbar.css b/dashboard-ui/css/nowplayingbar.css
index cd3069903d..b7055e0512 100644
--- a/dashboard-ui/css/nowplayingbar.css
+++ b/dashboard-ui/css/nowplayingbar.css
@@ -49,7 +49,6 @@
.nowPlayingBar {
/* Above everything, except for the video player and popup overlays */
color: #fff;
- background: #222326;
text-align: center;
/*box-shadow: 0 -2px 2px 0 rgba(0,0,0,.14),-1px 5px 1px rgba(0,0,0,.12);*/
will-change: transform;
diff --git a/dashboard-ui/scripts/htmlmediarenderer.js b/dashboard-ui/scripts/htmlmediarenderer.js
index 01961b710f..68ece16c01 100644
--- a/dashboard-ui/scripts/htmlmediarenderer.js
+++ b/dashboard-ui/scripts/htmlmediarenderer.js
@@ -424,6 +424,27 @@
hls.on(Hls.Events.MANIFEST_PARSED, function () {
elem.play();
});
+
+ hls.on(Hls.Events.ERROR, function (event, data) {
+ if (data.fatal) {
+ switch (data.type) {
+ case Hls.ErrorTypes.NETWORK_ERROR:
+ // try to recover network error
+ console.log("fatal network error encountered, try to recover");
+ hls.startLoad();
+ break;
+ case Hls.ErrorTypes.MEDIA_ERROR:
+ console.log("fatal media error encountered, try to recover");
+ hls.recoverMediaError();
+ break;
+ default:
+ // cannot recover
+ hls.destroy();
+ break;
+ }
+ }
+ });
+
hlsPlayer = hls;
});
diff --git a/dashboard-ui/scripts/livetvitems.js b/dashboard-ui/scripts/livetvitems.js
index 79bef3bf34..06c2249ea1 100644
--- a/dashboard-ui/scripts/livetvitems.js
+++ b/dashboard-ui/scripts/livetvitems.js
@@ -1,4 +1,4 @@
-define(['cardBuilder', 'emby-itemscontainer'], function (cardBuilder) {
+define(['cardBuilder', 'apphost', 'emby-itemscontainer'], function (cardBuilder, appHost) {
return function (view, params) {
@@ -56,6 +56,8 @@
page.querySelector('.listTopPaging').innerHTML = pagingHtml;
+ var supportsImageAnalysis = appHost.supports('imageanalysis') && (params.type == 'Recordings' || params.type == 'RecordingSeries');
+
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: query.IsMovie || params.type == 'RecordingSeries' ? 'portrait' : "backdrop",
@@ -71,9 +73,11 @@
showAirTime: params.type != 'Recordings' && params.type != 'RecordingSeries',
showAirDateTime: params.type != 'Recordings' && params.type != 'RecordingSeries',
showChannelName: params.type != 'Recordings' && params.type != 'RecordingSeries',
- overlayMoreButton: true,
+ overlayMoreButton: !supportsImageAnalysis,
showYear: query.IsMovie && params.type == 'Recordings',
- coverImage: true
+ coverImage: true,
+ cardLayout: supportsImageAnalysis,
+ vibrant: supportsImageAnalysis
});
var elem = page.querySelector('.itemsContainer');
diff --git a/dashboard-ui/scripts/livetvseriestimers.js b/dashboard-ui/scripts/livetvseriestimers.js
index cea15b472d..7e75d11584 100644
--- a/dashboard-ui/scripts/livetvseriestimers.js
+++ b/dashboard-ui/scripts/livetvseriestimers.js
@@ -36,7 +36,6 @@
showTitle: true,
cardLayout: true,
vibrant: true,
- cardFooterAside: 'none',
preferThumb: true,
coverImage: true,
overlayText: false,
diff --git a/dashboard-ui/scripts/notificationsetting.js b/dashboard-ui/scripts/notificationsetting.js
index 745e359baa..e45601bc84 100644
--- a/dashboard-ui/scripts/notificationsetting.js
+++ b/dashboard-ui/scripts/notificationsetting.js
@@ -1,4 +1,4 @@
-define(['jQuery', 'emby-checkbox'], function ($) {
+define(['jQuery', 'emby-checkbox', 'fnchecked'], function ($) {
var notificationsConfigurationKey = "notifications";
@@ -153,6 +153,7 @@
ApiClient.updateNamedConfiguration(notificationsConfigurationKey, notificationOptions).then(function (r) {
+ Dashboard.processServerConfigurationUpdateResult();
Dashboard.navigate('notificationsettings.html');
});
diff --git a/dashboard-ui/scripts/tvstudios.js b/dashboard-ui/scripts/tvstudios.js
index 8282c2b4ee..6c4a193d23 100644
--- a/dashboard-ui/scripts/tvstudios.js
+++ b/dashboard-ui/scripts/tvstudios.js
@@ -1,4 +1,4 @@
-define(['libraryBrowser', 'cardBuilder'], function (libraryBrowser, cardBuilder) {
+define(['libraryBrowser', 'cardBuilder', 'apphost'], function (libraryBrowser, cardBuilder, appHost) {
// The base query options
var data = {};
@@ -43,15 +43,20 @@
promise.then(function (result) {
var elem = context.querySelector('#items');
+
+ var supportsImageAnalysis = appHost.supports('imageanalysis');
+
cardBuilder.buildCards(result.Items, {
itemsContainer: elem,
shape: "backdrop",
preferThumb: true,
- showTitle: false,
+ showTitle: supportsImageAnalysis,
scalable: true,
showItemCounts: true,
- centerText: true,
- overlayMoreButton: true
+ centerText: !supportsImageAnalysis,
+ overlayMoreButton: !supportsImageAnalysis,
+ cardLayout: supportsImageAnalysis,
+ vibrant: supportsImageAnalysis
});
Dashboard.hideLoadingMsg();
diff --git a/dashboard-ui/strings/en-US.json b/dashboard-ui/strings/en-US.json
index f27609da2e..b0aad1c3fa 100644
--- a/dashboard-ui/strings/en-US.json
+++ b/dashboard-ui/strings/en-US.json
@@ -618,7 +618,6 @@
"NotificationOptionTaskFailed": "Scheduled task failure",
"NotificationOptionInstallationFailed": "Installation failure",
"NotificationOptionNewLibraryContent": "New content added",
- "NotificationOptionNewLibraryContentMultiple": "New content added (multiple)",
"NotificationOptionCameraImageUploaded": "Camera image uploaded",
"NotificationOptionUserLockedOut": "User locked out",
"HeaderSendNotificationHelp": "Notifications are delivered to your Emby inbox. Additional options can be installed from the Services tab.",