You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

notification.js 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. const {AppSubUrl, csrf, NotificationSettings} = window.config;
  2. export function initNotificationsTable() {
  3. $('#notification_table .button').on('click', async function () {
  4. const data = await updateNotification(
  5. $(this).data('url'),
  6. $(this).data('status'),
  7. $(this).data('page'),
  8. $(this).data('q'),
  9. $(this).data('notification-id'),
  10. );
  11. $('#notification_div').replaceWith(data);
  12. initNotificationsTable();
  13. await updateNotificationCount();
  14. return false;
  15. });
  16. }
  17. async function receiveUpdateCount(event) {
  18. try {
  19. const data = JSON.parse(event.data);
  20. const notificationCount = document.querySelector('.notification_count');
  21. if (data.Count > 0) {
  22. notificationCount.classList.remove('hidden');
  23. } else {
  24. notificationCount.classList.add('hidden');
  25. }
  26. notificationCount.text(`${data.Count}`);
  27. await updateNotificationTable();
  28. } catch (error) {
  29. console.error(error, event);
  30. }
  31. }
  32. export async function initNotificationCount() {
  33. const notificationCount = $('.notification_count');
  34. if (!notificationCount.length) {
  35. return;
  36. }
  37. if (NotificationSettings.EventSourceUpdateTime > 0 && !!window.EventSource) {
  38. // Try to connect to the event source via the shared worker first
  39. if (window.SharedWorker) {
  40. const worker = new SharedWorker(`${__webpack_public_path__}js/eventsource.sharedworker.js`, 'notification-worker');
  41. worker.addEventListener('error', (event) => {
  42. console.error(event);
  43. });
  44. worker.port.onmessageerror = () => {
  45. console.error('Unable to deserialize message');
  46. };
  47. worker.port.postMessage({
  48. type: 'start',
  49. url: `${window.location.origin}${AppSubUrl}/user/events`,
  50. });
  51. worker.port.addEventListener('message', (event) => {
  52. if (!event.data || !event.data.type) {
  53. console.error(event);
  54. return;
  55. }
  56. if (event.data.type === 'notification-count') {
  57. receiveUpdateCount(event.data);
  58. } else if (event.data.type === 'error') {
  59. console.error(event.data);
  60. } else if (event.data.type === 'logout') {
  61. if (event.data !== 'here') {
  62. return;
  63. }
  64. worker.port.postMessage({
  65. type: 'close',
  66. });
  67. worker.port.close();
  68. window.location.href = AppSubUrl;
  69. }
  70. });
  71. worker.port.addEventListener('error', (e) => {
  72. console.error(e);
  73. });
  74. worker.port.start();
  75. window.addEventListener('beforeunload', () => {
  76. worker.port.postMessage({
  77. type: 'close',
  78. });
  79. worker.port.close();
  80. });
  81. return;
  82. }
  83. }
  84. if (NotificationSettings.MinTimeout <= 0) {
  85. return;
  86. }
  87. const fn = (timeout, lastCount) => {
  88. setTimeout(async () => {
  89. await updateNotificationCountWithCallback(fn, timeout, lastCount);
  90. }, timeout);
  91. };
  92. fn(NotificationSettings.MinTimeout, notificationCount.text());
  93. }
  94. async function updateNotificationCountWithCallback(callback, timeout, lastCount) {
  95. const currentCount = $('.notification_count').text();
  96. if (lastCount !== currentCount) {
  97. callback(NotificationSettings.MinTimeout, currentCount);
  98. return;
  99. }
  100. const newCount = await updateNotificationCount();
  101. let needsUpdate = false;
  102. if (lastCount !== newCount) {
  103. needsUpdate = true;
  104. timeout = NotificationSettings.MinTimeout;
  105. } else if (timeout < NotificationSettings.MaxTimeout) {
  106. timeout += NotificationSettings.TimeoutStep;
  107. }
  108. callback(timeout, newCount);
  109. if (needsUpdate) {
  110. await updateNotificationTable();
  111. }
  112. }
  113. async function updateNotificationTable() {
  114. const notificationDiv = $('#notification_div');
  115. if (notificationDiv.length > 0) {
  116. const data = await $.ajax({
  117. type: 'GET',
  118. url: `${AppSubUrl}/notifications?${notificationDiv.data('params')}`,
  119. data: {
  120. 'div-only': true,
  121. }
  122. });
  123. notificationDiv.replaceWith(data);
  124. initNotificationsTable();
  125. }
  126. }
  127. async function updateNotificationCount() {
  128. const data = await $.ajax({
  129. type: 'GET',
  130. url: `${AppSubUrl}/api/v1/notifications/new`,
  131. headers: {
  132. 'X-Csrf-Token': csrf,
  133. },
  134. });
  135. const notificationCount = $('.notification_count');
  136. if (data.new === 0) {
  137. notificationCount.addClass('hidden');
  138. } else {
  139. notificationCount.removeClass('hidden');
  140. }
  141. notificationCount.text(`${data.new}`);
  142. return `${data.new}`;
  143. }
  144. async function updateNotification(url, status, page, q, notificationID) {
  145. if (status !== 'pinned') {
  146. $(`#notification_${notificationID}`).remove();
  147. }
  148. return $.ajax({
  149. type: 'POST',
  150. url,
  151. data: {
  152. _csrf: csrf,
  153. notification_id: notificationID,
  154. status,
  155. page,
  156. q,
  157. noredirect: true,
  158. },
  159. });
  160. }