From 2d23ad7ded6899703c50096b1a56a482790051d5 Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Tue, 21 Apr 2020 18:10:58 +0100 Subject: [PATCH 01/16] Use AJAX for notifications table Signed-off-by: Andrew Thornton --- routers/user/notification.go | 29 +++-- templates/user/notification/notification.tmpl | 90 +--------------- .../user/notification/notification_div.tmpl | 102 ++++++++++++++++++ web_src/js/index.js | 46 ++++++++ 4 files changed, 172 insertions(+), 95 deletions(-) create mode 100644 templates/user/notification/notification_div.tmpl diff --git a/routers/user/notification.go b/routers/user/notification.go index 74803f149e95..3d0deb199841 100644 --- a/routers/user/notification.go +++ b/routers/user/notification.go @@ -7,6 +7,7 @@ package user import ( "errors" "fmt" + "net/http" "strconv" "strings" @@ -17,7 +18,8 @@ import ( ) const ( - tplNotification base.TplName = "user/notification/notification" + tplNotification base.TplName = "user/notification/notification" + tplNotificationDiv = "user/notification/notification_div" ) // GetNotificationCount is the middleware that sets the notification count in the context @@ -41,6 +43,14 @@ func GetNotificationCount(c *context.Context) { // Notifications is the notifications page func Notifications(c *context.Context) { + getNotifications(c) + if c.Written() { + return + } + c.HTML(http.StatusOK, tplNotification) +} + +func getNotifications(c *context.Context) { var ( keyword = strings.Trim(c.Query("q"), " ") status models.NotificationStatus @@ -126,8 +136,6 @@ func Notifications(c *context.Context) { pager.SetDefaultParams(c) c.Data["Page"] = pager - - c.HTML(200, tplNotification) } // NotificationStatusPost is a route for changing the status of a notification @@ -155,8 +163,17 @@ func NotificationStatusPost(c *context.Context) { return } - url := fmt.Sprintf("%s/notifications?page=%s", setting.AppSubURL, c.Query("page")) - c.Redirect(url, 303) + if !c.QueryBool("noredirect") { + url := fmt.Sprintf("%s/notifications?page=%s", setting.AppSubURL, c.Query("page")) + c.Redirect(url, http.StatusSeeOther) + } + + getNotifications(c) + if c.Written() { + return + } + + c.HTML(http.StatusOK, tplNotificationDiv) } // NotificationPurgePost is a route for 'purging' the list of notifications - marking all unread as read @@ -168,5 +185,5 @@ func NotificationPurgePost(c *context.Context) { } url := fmt.Sprintf("%s/notifications", setting.AppSubURL) - c.Redirect(url, 303) + c.Redirect(url, http.StatusSeeOther) } diff --git a/templates/user/notification/notification.tmpl b/templates/user/notification/notification.tmpl index c4f744a29173..7bc120688861 100644 --- a/templates/user/notification/notification.tmpl +++ b/templates/user/notification/notification.tmpl @@ -23,95 +23,7 @@ {{end}} -
- {{if eq (len .Notifications) 0}} - {{if eq .Status 1}} - {{.i18n.Tr "notification.no_unread"}} - {{else}} - {{.i18n.Tr "notification.no_read"}} - {{end}} - {{else}} - - - {{range $notification := .Notifications}} - {{$issue := $notification.Issue}} - {{$repo := $notification.Repository}} - {{$repoOwner := $repo.MustOwner}} - - - - - - - - - {{end}} - -
- {{if eq $notification.Status 3}} - {{svg "octicon-pin" 16}} - {{else if $issue.IsPull}} - {{if $issue.IsClosed}} - {{if $issue.GetPullRequest.HasMerged}} - {{svg "octicon-git-merge" 16}} - {{else}} - {{svg "octicon-git-pull-request" 16}} - {{end}} - {{else}} - {{svg "octicon-git-pull-request" 16}} - {{end}} - {{else}} - {{if $issue.IsClosed}} - {{svg "octicon-issue-closed" 16}} - {{else}} - {{svg "octicon-issue-opened" 16}} - {{end}} - {{end}} - - - #{{$issue.Index}} - {{$issue.Title}} - - - - {{$repoOwner.Name}}/{{$repo.Name}} - - - {{if ne $notification.Status 3}} -
- {{$.CsrfTokenHtml}} - - - -
- {{end}} -
- {{if or (eq $notification.Status 1) (eq $notification.Status 3)}} -
- {{$.CsrfTokenHtml}} - - - - -
- {{else if eq $notification.Status 2}} -
- {{$.CsrfTokenHtml}} - - - - -
- {{end}} -
- {{end}} -
- + {{template "user/notification/notification_div" .}} {{template "base/paginate" .}} diff --git a/templates/user/notification/notification_div.tmpl b/templates/user/notification/notification_div.tmpl new file mode 100644 index 000000000000..b8bd5ef296d8 --- /dev/null +++ b/templates/user/notification/notification_div.tmpl @@ -0,0 +1,102 @@ +
+ {{if eq (len .Notifications) 0}} + {{if eq .Status 1}} + {{.i18n.Tr "notification.no_unread"}} + {{else}} + {{.i18n.Tr "notification.no_read"}} + {{end}} + {{else}} + + + {{range $notification := .Notifications}} + {{$issue := .Issue}} + {{$repo := .Repository}} + {{$repoOwner := $repo.MustOwner}} + + + + + + + + {{end}} + +
+ {{if eq .Status 3}} + {{svg "octicon-pin" 16}} + {{else if $issue.IsPull}} + {{if $issue.IsClosed}} + {{if $issue.GetPullRequest.HasMerged}} + {{svg "octicon-git-merge" 16}} + {{else}} + {{svg "octicon-git-pull-request" 16}} + {{end}} + {{else}} + {{svg "octicon-git-pull-request" 16}} + {{end}} + {{else}} + {{if $issue.IsClosed}} + {{svg "octicon-issue-closed" 16}} + {{else}} + {{svg "octicon-issue-opened" 16}} + {{end}} + {{end}} + + + #{{$issue.Index}} - {{$issue.Title}} + + + + {{$repoOwner.Name}}/{{$repo.Name}} + + + {{if ne .Status 3}} +
+ {{$.CsrfTokenHtml}} + + + +
+ {{end}} +
+ {{if or (eq .Status 1) (eq .Status 3)}} +
+ {{$.CsrfTokenHtml}} + + + + +
+ {{else if eq .Status 2}} +
+ {{$.CsrfTokenHtml}} + + + + +
+ {{end}} +
+ {{end}} +
\ No newline at end of file diff --git a/web_src/js/index.js b/web_src/js/index.js index ed747765a00f..050870201a50 100644 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -180,6 +180,46 @@ function updateIssuesMeta(url, action, issueIds, elementId, isAdd) { })); } +function initNotificationsTable() { + const $notificationTable = $('#notification_table'); + if ($notificationTable) { + $notificationTable.find('.button').click(function () { + updateNotification( + $(this).data('url'), + $(this).data('status'), + $(this).data('page'), + $(this).data('q'), + $(this).data('notification-id') + ).then((data) => { + $('#notification_div').replaceWith(data); + initNotificationsTable(); + }); + return false; + }); + } +} + +function updateNotification(url, status, page, q, notificationID) { + return new Promise(((resolve) => { + if (status != "pinned") { + $(`#notification_${notificationID}`).remove(); + } + $.ajax({ + type: 'POST', + url, + data: { + _csrf: csrf, + notification_id: notificationID, + status, + page, + q, + noredirect: true, + }, + success: resolve + }); + })); +} + function initRepoStatusChecker() { const migrating = $('#repo_migrating'); $('#repo_migrating_failed').hide(); @@ -2431,6 +2471,11 @@ $(document).ready(async () => { window.location = $(this).data('href'); }); + // make table element clickable like a link + $('td[data-href]').click(function () { + window.location = $(this).data('href'); + }); + // Dropzone const $dropzone = $('#dropzone'); if ($dropzone.length > 0) { @@ -2606,6 +2651,7 @@ $(document).ready(async () => { initRepoStatusChecker(); initTemplateSearch(); initContextPopups(); + initNotificationsTable(); // Repo clone url. if ($('#repo-clone-url').length > 0) { From 345b6e89d063d78eabc72adf85fef868be918b44 Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Tue, 21 Apr 2020 18:23:53 +0100 Subject: [PATCH 02/16] move to separate js Signed-off-by: Andrew Thornton --- web_src/js/features/notification.js | 38 ++++++++++++++++++++++++++ web_src/js/index.js | 41 +---------------------------- 2 files changed, 39 insertions(+), 40 deletions(-) create mode 100644 web_src/js/features/notification.js diff --git a/web_src/js/features/notification.js b/web_src/js/features/notification.js new file mode 100644 index 000000000000..244a289bdf93 --- /dev/null +++ b/web_src/js/features/notification.js @@ -0,0 +1,38 @@ +const {csrf} = window.config; + +export default async function initNotificationsTable() { + $('#notification_table .button').click(function () { + updateNotification( + $(this).data('url'), + $(this).data('status'), + $(this).data('page'), + $(this).data('q'), + $(this).data('notification-id') + ).then((data) => { + $('#notification_div').replaceWith(data); + initNotificationsTable(); + }); + return false; + }); +} + +function updateNotification(url, status, page, q, notificationID) { + return new Promise(((resolve) => { + if (status !== 'pinned') { + $(`#notification_${notificationID}`).remove(); + } + $.ajax({ + type: 'POST', + url, + data: { + _csrf: csrf, + notification_id: notificationID, + status, + page, + q, + noredirect: true, + }, + success: resolve + }); + })); +} diff --git a/web_src/js/index.js b/web_src/js/index.js index 050870201a50..95d626090c1c 100644 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -18,6 +18,7 @@ import initDateTimePicker from './features/datetimepicker.js'; import createDropzone from './features/dropzone.js'; import highlight from './features/highlight.js'; import ActivityTopAuthors from './components/ActivityTopAuthors.vue'; +import initNotificationsTable from './features/notification.js'; const {AppSubUrl, StaticUrlPrefix, csrf} = window.config; @@ -180,46 +181,6 @@ function updateIssuesMeta(url, action, issueIds, elementId, isAdd) { })); } -function initNotificationsTable() { - const $notificationTable = $('#notification_table'); - if ($notificationTable) { - $notificationTable.find('.button').click(function () { - updateNotification( - $(this).data('url'), - $(this).data('status'), - $(this).data('page'), - $(this).data('q'), - $(this).data('notification-id') - ).then((data) => { - $('#notification_div').replaceWith(data); - initNotificationsTable(); - }); - return false; - }); - } -} - -function updateNotification(url, status, page, q, notificationID) { - return new Promise(((resolve) => { - if (status != "pinned") { - $(`#notification_${notificationID}`).remove(); - } - $.ajax({ - type: 'POST', - url, - data: { - _csrf: csrf, - notification_id: notificationID, - status, - page, - q, - noredirect: true, - }, - success: resolve - }); - })); -} - function initRepoStatusChecker() { const migrating = $('#repo_migrating'); $('#repo_migrating_failed').hide(); From 7d5fca4e618bb58d27394c0b1a289598b484ea53 Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Tue, 21 Apr 2020 19:44:49 +0100 Subject: [PATCH 03/16] placate golangci-lint Signed-off-by: Andrew Thornton --- routers/user/notification.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routers/user/notification.go b/routers/user/notification.go index 3d0deb199841..d03eaab0411f 100644 --- a/routers/user/notification.go +++ b/routers/user/notification.go @@ -19,7 +19,7 @@ import ( const ( tplNotification base.TplName = "user/notification/notification" - tplNotificationDiv = "user/notification/notification_div" + tplNotificationDiv base.TplName = "user/notification/notification_div" ) // GetNotificationCount is the middleware that sets the notification count in the context From 0e6236e99a30608ceb97582b12d7ea93e311b82e Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Tue, 21 Apr 2020 20:54:51 +0100 Subject: [PATCH 04/16] Add autoupdating notification count Signed-off-by: Andrew Thornton --- routers/user/notification.go | 6 +--- templates/base/head_navbar.tmpl | 9 ++---- templates/user/notification/notification.tmpl | 4 +-- web_src/js/features/notification.js | 32 +++++++++++++++++-- web_src/js/index.js | 3 +- 5 files changed, 37 insertions(+), 17 deletions(-) diff --git a/routers/user/notification.go b/routers/user/notification.go index d03eaab0411f..7e78ed5a5706 100644 --- a/routers/user/notification.go +++ b/routers/user/notification.go @@ -125,11 +125,7 @@ func getNotifications(c *context.Context) { c.Flash.Error(fmt.Sprintf("ERROR: %d notifications were removed due to missing parts - check the logs", failCount)) } - title := c.Tr("notifications") - if status == models.NotificationStatusUnread && total > 0 { - title = fmt.Sprintf("(%d) %s", total, title) - } - c.Data["Title"] = title + c.Data["Title"] = c.Tr("notifications") c.Data["Keyword"] = keyword c.Data["Status"] = status c.Data["Notifications"] = notifications diff --git a/templates/base/head_navbar.tmpl b/templates/base/head_navbar.tmpl index de02bca1f7c5..e06e26357a30 100644 --- a/templates/base/head_navbar.tmpl +++ b/templates/base/head_navbar.tmpl @@ -46,12 +46,9 @@ {{svg "octicon-bell" 16}} {{.i18n.Tr "notifications"}} - - {{if .NotificationUnreadCount}} - - {{.NotificationUnreadCount}} - - {{end}} + + {{.NotificationUnreadCount}} + diff --git a/templates/user/notification/notification.tmpl b/templates/user/notification/notification.tmpl index 7bc120688861..b9b17dbc3d10 100644 --- a/templates/user/notification/notification.tmpl +++ b/templates/user/notification/notification.tmpl @@ -7,9 +7,7 @@