summaryrefslogtreecommitdiffstats
path: root/web_src
diff options
context:
space:
mode:
authorzeripath <art27@cantab.net>2020-04-24 04:57:38 +0100
committerGitHub <noreply@github.com>2020-04-24 00:57:38 -0300
commitb10c416f9e72da39fb5f7398c7c67faaab008a5e (patch)
treedd5579c788f0a29326f979c9a984cd899b2f1737 /web_src
parente74c4e1be988f2815146338cbce8210e515a937e (diff)
downloadgitea-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.js110
-rw-r--r--web_src/js/index.js8
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) {