From cfb3392c356cf4a85d5145189defa1c1cad6dde8 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 6 Jul 2013 17:23:32 -0400 Subject: [PATCH] added a notifications service --- ApiClient.js | 57 +++++- .../css/images/notifications/error.png | Bin 4262 -> 2164 bytes .../css/images/notifications/info.png | Bin 6290 -> 2996 bytes dashboard-ui/css/notifications.css | 160 +++++++++++++++ dashboard-ui/css/search.css | 1 - dashboard-ui/scripts/notifications.js | 191 ++++++++++++++++++ dashboard-ui/scripts/site.js | 4 +- packages.config | 2 +- 8 files changed, 411 insertions(+), 4 deletions(-) create mode 100644 dashboard-ui/css/notifications.css create mode 100644 dashboard-ui/scripts/notifications.js diff --git a/ApiClient.js b/ApiClient.js index ebea5b9860..a90d2dcf8b 100644 --- a/ApiClient.js +++ b/ApiClient.js @@ -243,6 +243,61 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) { }); }; + self.getNotificationSummary = function (userId) { + + if (!userId) { + throw new Error("null userId"); + } + + var url = self.getUrl("Notifications/" + userId + "/Summary"); + + return self.ajax({ + type: "GET", + url: url, + dataType: "json" + }); + }; + + self.getNotifications = function (userId, options) { + + if (!userId) { + throw new Error("null userId"); + } + + var url = self.getUrl("Notifications/" + userId, options || {}); + + return self.ajax({ + type: "GET", + url: url, + dataType: "json" + }); + }; + + self.markNotificationsRead = function (userId, idList, isRead) { + + if (!userId) { + throw new Error("null userId"); + } + + if (!idList || !idList.length) { + throw new Error("null idList"); + } + + var suffix = isRead ? "Read" : "Unread"; + + var params = { + UserId: userId, + Ids: idList.join(',') + }; + + var url = self.getUrl("Notifications/" + userId + "/" + suffix, params); + + return self.ajax({ + type: "POST", + url: url + }); + }; + /** * Gets the current server status */ @@ -1937,7 +1992,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) { if (!item) { throw new Error("null item"); } - + var url = self.getUrl("Artists/" + self.encodeName(item.Name)); return self.ajax({ diff --git a/dashboard-ui/css/images/notifications/error.png b/dashboard-ui/css/images/notifications/error.png index c6b5693c4e969b318cd3e9a9c1e178e87121b1d9..ec55035e9cf596c1746acf8e47c947f486d1ab2d 100644 GIT binary patch delta 2137 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 literal 6290 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 diff --git a/dashboard-ui/css/notifications.css b/dashboard-ui/css/notifications.css new file mode 100644 index 0000000000..5a361994bf --- /dev/null +++ b/dashboard-ui/css/notifications.css @@ -0,0 +1,160 @@ +.btnNotifications { + text-decoration: none; + vertical-align: middle; + -moz-border-radius: 2px; + -webkit-border-radius: 2px; + border-radius: 2px; + padding: 8px 12px; + text-align: center; + text-decoration: none !important; + -moz-user-select: none; + -webkit-user-select: none; + background-color: #f5f5f5; + background-image: -webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#f1f1f1)); + background-image: -webkit-linear-gradient(top,#f5f5f5,#f1f1f1); + background-image: -moz-linear-gradient(top,#f5f5f5,#f1f1f1); + background-image: -ms-linear-gradient(top,#f5f5f5,#f1f1f1); + background-image: -o-linear-gradient(top,#f5f5f5,#f1f1f1); + background-image: linear-gradient(top,#f5f5f5,#f1f1f1); + border: 1px solid #dcdcdc; + color: #666; +} + +.levelNormal { + background-color: #4d90fe; + background-image: -webkit-gradient(linear,left top,left bottom,from(#4d90fe),to(#4787ed)); + background-image: -webkit-linear-gradient(top,#4d90fe,#4787ed); + background-image: -moz-linear-gradient(top,#4d90fe,#4787ed); + background-image: -ms-linear-gradient(top,#4d90fe,#4787ed); + background-image: -o-linear-gradient(top,#4d90fe,#4787ed); + background-image: linear-gradient(top,#4d90fe,#4787ed); + border-color: #3079ed; + color: #fff!important; +} + +.levelWarning { + background-color: #FF7537; + background-image: none; + border-color: #FF7537; + color: #fff!important; +} + +.levelError { + background-color: #d14836; + background-image: -webkit-gradient(linear,left top,left bottom,from(#dd4b39),to(#d14836)); + background-image: -webkit-linear-gradient(top,#dd4b39,#d14836); + background-image: -moz-linear-gradient(top,#dd4b39,#d14836); + background-image: -ms-linear-gradient(top,#dd4b39,#d14836); + background-image: -o-linear-gradient(top,#dd4b39,#d14836); + background-image: linear-gradient(top,#dd4b39,#d14836); + border-color: #c6322a; + color: #fff!important; +} + +.flyoutNotification { + border-top: 1px solid #ccc; + background: #f8f8f8; + color: #555; +} + + .flyoutNotification p { + margin: .7em 0; + } + +.notificationsFlyout { + width: 300px; +} + +.notificationName { + font-weight: bold; + color: #555; +} + +.notificationImage { + display: none; +} + +.unreadFlyoutNotification { + background-color: #ECEEF4; +} + +.btnMarkReadContainer { + padding: .5em; +} + +.imgNotification, .imgNotificationInner { + width: 60px; + height: 60px; +} + +.imgNotificationInner { + background-repeat: no-repeat; + background-size: contain; + background-position: center center; +} + +.imgNotificationIcon { + background-size: 50% auto; +} + + +.imgNotificationNormal { + background-color: #4d90fe; + background-image: -webkit-gradient(linear,left top,left bottom,from(#4d90fe),to(#4787ed)); + background-image: -webkit-linear-gradient(top,#4d90fe,#4787ed); + background-image: -moz-linear-gradient(top,#4d90fe,#4787ed); + background-image: -ms-linear-gradient(top,#4d90fe,#4787ed); + background-image: -o-linear-gradient(top,#4d90fe,#4787ed); + background-image: linear-gradient(top,#4d90fe,#4787ed); +} + +.imgNotificationNormal .imgNotificationInner { + background-image: url(images/notifications/info.png); +} + +.imgNotificationError { + background-color: #d14836; + background-image: -webkit-gradient(linear,left top,left bottom,from(#dd4b39),to(#d14836)); + background-image: -webkit-linear-gradient(top,#dd4b39,#d14836); + background-image: -moz-linear-gradient(top,#dd4b39,#d14836); + background-image: -ms-linear-gradient(top,#dd4b39,#d14836); + background-image: -o-linear-gradient(top,#dd4b39,#d14836); + background-image: linear-gradient(top,#dd4b39,#d14836); +} + +.imgNotificationError .imgNotificationInner { + background-image: url(images/notifications/error.png); +} + +.imgNotificationWarning { + background-color: #FF7537; +} + +.imgNotificationWarning .imgNotificationInner { + background-image: url(images/notifications/error.png); +} + +@media all and (min-width: 500px) { + .notificationsFlyout { + width: 400px; + } +} + +@media all and (min-width: 600px) { + .notificationsFlyout { + width: 500px; + } + + + .notificationImage { + display: inline-block; + vertical-align: top; + margin: 0 1em; + padding: .7em 0; + } + + .notificationContent { + display: inline-block; + vertical-align: top; + } +} diff --git a/dashboard-ui/css/search.css b/dashboard-ui/css/search.css index fb7676186d..5043637f04 100644 --- a/dashboard-ui/css/search.css +++ b/dashboard-ui/css/search.css @@ -35,7 +35,6 @@ text-decoration: none !important; -moz-user-select: none; -webkit-user-select: none; - text-align: center; } .txtSearch, .btnSearch { diff --git a/dashboard-ui/scripts/notifications.js b/dashboard-ui/scripts/notifications.js new file mode 100644 index 0000000000..31ccb80240 --- /dev/null +++ b/dashboard-ui/scripts/notifications.js @@ -0,0 +1,191 @@ +(function ($, document, Dashboard) { + + var userId; + var getNotificationsSummaryPromise; + + function getNotificationsSummary() { + + getNotificationsSummaryPromise = getNotificationsSummaryPromise || ApiClient.getNotificationSummary(userId); + + return getNotificationsSummaryPromise; + } + + function updateNotificationCount() { + + getNotificationsSummary().done(function (summary) { + + var elem = $('.btnNotifications').removeClass('levelNormal').removeClass('levelWarning').removeClass('levelError').html(summary.UnreadCount); + + if (summary.UnreadCount) { + elem.addClass('level' + summary.MaxUnreadNotificationLevel); + } + }); + } + + function showNotificationsFlyout() { + + var context = this; + + var html = '
'; + + html += 'Close'; + + html += '
'; + html += '

Notifications

'; + html += '
'; + + html += '
'; + + html += '

Loading...'; + + html += '

'; + + html += ''; + html += '
'; + + html += '
'; + + $(document.body).append(html); + + $('.notificationsFlyout').popup({ positionTo: context }).trigger('create').popup("open").on("popupafterclose", function () { + + $(this).off("popupafterclose").remove(); + + }).on('click', '.btnMarkRead', function () { + + + var ids = $('.unreadFlyoutNotification').map(function () { + + return this.getAttribute('data-notificationid'); + + }).get(); + + ApiClient.markNotificationsRead(Dashboard.getCurrentUserId(), ids, true).done(function () { + + $('.notificationsFlyout').popup("close"); + + }); + + }); + + refreshFlyoutContents(); + } + + function refreshFlyoutContents() { + + var limit = 5; + var startIndex = 0; + + ApiClient.getNotifications(Dashboard.getCurrentUserId(), { StartIndex: startIndex, Limit: limit }).done(function (result) { + + listUnreadNotifications(result.Notifications, result.TotalRecordCount, startIndex, limit); + + }); + } + + function listUnreadNotifications(notifications, totalRecordCount, startIndex, limit) { + + var elem = $('.notificationsFlyoutlist'); + + if (!totalRecordCount) { + elem.html('

No unread notifications.

'); + $('.btnMarkReadContainer').hide(); + return; + } + + if (notifications.filter(function(n) { + + return !n.IsRead; + + }).length) { + $('.btnMarkReadContainer').show(); + } else { + $('.btnMarkReadContainer').hide(); + } + + + var html = ''; + + for (var i = 0, length = notifications.length; i < length; i++) { + + var notification = notifications[i]; + + html += getNotificationHtml(notification); + + } + + elem.html(html); + } + + function getNotificationHtml(notification) { + + var html = ''; + + var cssClass = notification.IsRead ? "flyoutNotification" : "flyoutNotification unreadFlyoutNotification"; + + html += '
'; + + html += '
'; + html += getImageHtml(notification); + html += '
'; + + html += '
'; + + html += '

' + notification.Name + '

'; + + html += '

' + humane_date(notification.Date) + '

'; + + if (notification.Description) { + html += '

' + notification.Description + '

'; + } + + html += '
'; + html += '
'; + + return html; + } + + function getImageHtml(notification) { + + if (notification.Level == "Error") { + + return '
'; + + } + if (notification.Level == "Warning") { + + return '
'; + + } + + return '
'; + + } + + $(Dashboard).on('interiorheaderrendered', function (e, header, user) { + + if (!user || $('.notificationsButton', header).length) { + return; + } + + userId = user.Id; + + $('0').insertAfter($('.btnCurrentUser', header)).on('click', showNotificationsFlyout); + + updateNotificationCount(); + }); + + $(ApiClient).on("websocketmessage", function (e, msg) { + + + if (msg.MessageType === "NotificationUpdated" || msg.MessageType === "NotificationAdded" || msg.MessageType === "NotificationsMarkedRead") { + + getNotificationsSummaryPromise = null; + + updateNotificationCount(); + } + + }); + + +})(jQuery, document, Dashboard); \ No newline at end of file diff --git a/dashboard-ui/scripts/site.js b/dashboard-ui/scripts/site.js index 4b1ae74e94..67397a1e83 100644 --- a/dashboard-ui/scripts/site.js +++ b/dashboard-ui/scripts/site.js @@ -445,7 +445,7 @@ var Dashboard = { html += 'Close'; html += '
'; - html += '

' + user.Name + '

'; + html += '

' + user.Name + '

'; html += '
'; html += '
'; @@ -594,6 +594,8 @@ var Dashboard = { } }); } + + $(Dashboard).trigger('interiorheaderrendered', [header, user]); }, ensureToolsMenu: function (page) { diff --git a/packages.config b/packages.config index ef87d534e7..439f8cb979 100644 --- a/packages.config +++ b/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file