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.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  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', (e) => {
  52. if (!e.data || !e.data.type) {
  53. console.error(e);
  54. return;
  55. }
  56. if (event.data.type === 'notification-count') {
  57. receiveUpdateCount(e.data);
  58. return;
  59. } else if (event.data.type === 'error') {
  60. console.error(e.data);
  61. return;
  62. } else if (event.data.type === 'logout') {
  63. if (e.data !== 'here') {
  64. return;
  65. }
  66. worker.port.postMessage({
  67. type: 'close',
  68. });
  69. worker.port.close();
  70. window.location.href = AppSubUrl;
  71. return;
  72. } else {
  73. return;
  74. }
  75. });
  76. worker.port.addEventListener('error', (e) => {
  77. console.error(e);
  78. });
  79. worker.port.start();
  80. window.addEventListener('beforeunload', () => {
  81. worker.port.postMessage({
  82. type: 'close',
  83. });
  84. worker.port.close();
  85. });
  86. return;
  87. }
  88. }
  89. if (NotificationSettings.MinTimeout <= 0) {
  90. return;
  91. }
  92. const fn = (timeout, lastCount) => {
  93. setTimeout(async () => {
  94. await updateNotificationCountWithCallback(fn, timeout, lastCount);
  95. }, timeout);
  96. };
  97. fn(NotificationSettings.MinTimeout, notificationCount.text());
  98. }
  99. async function updateNotificationCountWithCallback(callback, timeout, lastCount) {
  100. const currentCount = $('.notification_count').text();
  101. if (lastCount !== currentCount) {
  102. callback(NotificationSettings.MinTimeout, currentCount);
  103. return;
  104. }
  105. const newCount = await updateNotificationCount();
  106. let needsUpdate = false;
  107. if (lastCount !== newCount) {
  108. needsUpdate = true;
  109. timeout = NotificationSettings.MinTimeout;
  110. } else if (timeout < NotificationSettings.MaxTimeout) {
  111. timeout += NotificationSettings.TimeoutStep;
  112. }
  113. callback(timeout, newCount);
  114. if (needsUpdate) {
  115. await updateNotificationTable();
  116. }
  117. }
  118. async function updateNotificationTable() {
  119. const notificationDiv = $('#notification_div');
  120. if (notificationDiv.length > 0) {
  121. const data = await $.ajax({
  122. type: 'GET',
  123. url: `${AppSubUrl}/notifications?${notificationDiv.data('params')}`,
  124. data: {
  125. 'div-only': true,
  126. }
  127. });
  128. notificationDiv.replaceWith(data);
  129. initNotificationsTable();
  130. }
  131. }
  132. async function updateNotificationCount() {
  133. const data = await $.ajax({
  134. type: 'GET',
  135. url: `${AppSubUrl}/api/v1/notifications/new`,
  136. headers: {
  137. 'X-Csrf-Token': csrf,
  138. },
  139. });
  140. const notificationCount = $('.notification_count');
  141. if (data.new === 0) {
  142. notificationCount.addClass('hidden');
  143. } else {
  144. notificationCount.removeClass('hidden');
  145. }
  146. notificationCount.text(`${data.new}`);
  147. return `${data.new}`;
  148. }
  149. async function updateNotification(url, status, page, q, notificationID) {
  150. if (status !== 'pinned') {
  151. $(`#notification_${notificationID}`).remove();
  152. }
  153. return $.ajax({
  154. type: 'POST',
  155. url,
  156. data: {
  157. _csrf: csrf,
  158. notification_id: notificationID,
  159. status,
  160. page,
  161. q,
  162. noredirect: true,
  163. },
  164. });
  165. }