diff options
author | zeripath <art27@cantab.net> | 2020-04-24 04:57:38 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-24 00:57:38 -0300 |
commit | b10c416f9e72da39fb5f7398c7c67faaab008a5e (patch) | |
tree | dd5579c788f0a29326f979c9a984cd899b2f1737 /web_src | |
parent | e74c4e1be988f2815146338cbce8210e515a937e (diff) | |
download | gitea-b10c416f9e72da39fb5f7398c7c67faaab008a5e.tar.gz gitea-b10c416f9e72da39fb5f7398c7c67faaab008a5e.zip |
Use AJAX for notifications table (#10961)
* Use AJAX for notifications table
Signed-off-by: Andrew Thornton <art27@cantab.net>
* move to separate js
Signed-off-by: Andrew Thornton <art27@cantab.net>
* placate golangci-lint
Signed-off-by: Andrew Thornton <art27@cantab.net>
* Add autoupdating notification count
Signed-off-by: Andrew Thornton <art27@cantab.net>
* Fix wipeall
Signed-off-by: Andrew Thornton <art27@cantab.net>
* placate tests
Signed-off-by: Andrew Thornton <art27@cantab.net>
* Try hidden
Signed-off-by: Andrew Thornton <art27@cantab.net>
* Try hide and hidden
Signed-off-by: Andrew Thornton <art27@cantab.net>
* More auto-update improvements
Only run checker on pages that have a count
Change starting checker to 10s with a back-off to 60s if there is no change
Signed-off-by: Andrew Thornton <art27@cantab.net>
* string comparison!
Signed-off-by: Andrew Thornton <art27@cantab.net>
* as per @silverwind
Signed-off-by: Andrew Thornton <art27@cantab.net>
* add configurability as per @6543
Signed-off-by: Andrew Thornton <art27@cantab.net>
* Add documentation as per @6543
Signed-off-by: Andrew Thornton <art27@cantab.net>
* Use CSRF header not query
Signed-off-by: Andrew Thornton <art27@cantab.net>
* Further JS improvements
Fix @etzelia update notification table request
Fix @silverwind comments
Co-Authored-By: silverwind <me@silverwind.io>
Signed-off-by: Andrew Thornton <art27@cantab.net>
* Simplify the notification count fns
Signed-off-by: Andrew Thornton <art27@cantab.net>
Co-authored-by: silverwind <me@silverwind.io>
Diffstat (limited to 'web_src')
-rw-r--r-- | web_src/js/features/notification.js | 110 | ||||
-rw-r--r-- | web_src/js/index.js | 8 |
2 files changed, 118 insertions, 0 deletions
diff --git a/web_src/js/features/notification.js b/web_src/js/features/notification.js new file mode 100644 index 0000000000..3f2af4de91 --- /dev/null +++ b/web_src/js/features/notification.js @@ -0,0 +1,110 @@ +const {AppSubUrl, csrf, NotificationSettings} = window.config; + +export function initNotificationsTable() { + $('#notification_table .button').on('click', async function () { + const data = await updateNotification( + $(this).data('url'), + $(this).data('status'), + $(this).data('page'), + $(this).data('q'), + $(this).data('notification-id'), + ); + + $('#notification_div').replaceWith(data); + initNotificationsTable(); + await updateNotificationCount(); + + return false; + }); +} + +export function initNotificationCount() { + if (NotificationSettings.MinTimeout <= 0) { + return; + } + + const notificationCount = $('.notification_count'); + + if (notificationCount.length > 0) { + const fn = (timeout, lastCount) => { + setTimeout(async () => { + await updateNotificationCountWithCallback(fn, timeout, lastCount); + }, timeout); + }; + + fn(NotificationSettings.MinTimeout, notificationCount.text()); + } +} + +async function updateNotificationCountWithCallback(callback, timeout, lastCount) { + const currentCount = $('.notification_count').text(); + if (lastCount !== currentCount) { + callback(NotificationSettings.MinTimeout, currentCount); + return; + } + + const newCount = await updateNotificationCount(); + let needsUpdate = false; + + if (lastCount !== newCount) { + needsUpdate = true; + timeout = NotificationSettings.MinTimeout; + } else if (timeout < NotificationSettings.MaxTimeout) { + timeout += NotificationSettings.TimeoutStep; + } + + callback(timeout, newCount); + + const notificationDiv = $('#notification_div'); + if (notificationDiv.length > 0 && needsUpdate) { + const data = await $.ajax({ + type: 'GET', + url: `${AppSubUrl}/notifications?${notificationDiv.data('params')}`, + data: { + 'div-only': true, + } + }); + notificationDiv.replaceWith(data); + initNotificationsTable(); + } +} + +async function updateNotificationCount() { + const data = await $.ajax({ + type: 'GET', + url: `${AppSubUrl}/api/v1/notifications/new`, + headers: { + 'X-Csrf-Token': csrf, + }, + }); + + const notificationCount = $('.notification_count'); + if (data.new === 0) { + notificationCount.addClass('hidden'); + } else { + notificationCount.removeClass('hidden'); + } + + notificationCount.text(`${data.new}`); + + return `${data.new}`; +} + +async function updateNotification(url, status, page, q, notificationID) { + if (status !== 'pinned') { + $(`#notification_${notificationID}`).remove(); + } + + return $.ajax({ + type: 'POST', + url, + data: { + _csrf: csrf, + notification_id: notificationID, + status, + page, + q, + noredirect: true, + }, + }); +} diff --git a/web_src/js/index.js b/web_src/js/index.js index ed747765a0..9e699c1a2e 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, initNotificationCount} from './features/notification.js'; const {AppSubUrl, StaticUrlPrefix, csrf} = window.config; @@ -2431,6 +2432,11 @@ $(document).ready(async () => { window.location = $(this).data('href'); }); + // make table <td> 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 +2612,8 @@ $(document).ready(async () => { initRepoStatusChecker(); initTemplateSearch(); initContextPopups(); + initNotificationsTable(); + initNotificationCount(); // Repo clone url. if ($('#repo-clone-url').length > 0) { |