logo

pleroma-fe

My custom branche(s) on git.pleroma.social/pleroma/pleroma-fe git clone https://anongit.hacktivis.me/git/pleroma-fe.git/

notifications_fetcher.service.js (3632B)


  1. import apiService from '../api/api.service.js'
  2. import { promiseInterval } from '../promise_interval/promise_interval.js'
  3. // For using include_types when fetching notifications.
  4. // Note: chat_mention excluded as pleroma-fe polls them separately
  5. const mastoApiNotificationTypes = [
  6. 'mention',
  7. 'status',
  8. 'favourite',
  9. 'reblog',
  10. 'follow',
  11. 'follow_request',
  12. 'move',
  13. 'poll',
  14. 'pleroma:emoji_reaction',
  15. 'pleroma:chat_mention',
  16. 'pleroma:report'
  17. ]
  18. const update = ({ store, notifications, older }) => {
  19. store.dispatch('addNewNotifications', { notifications, older })
  20. }
  21. const fetchAndUpdate = ({ store, credentials, older = false, since }) => {
  22. const args = { credentials }
  23. const { getters } = store
  24. const rootState = store.rootState || store.state
  25. const timelineData = rootState.notifications
  26. const hideMutedPosts = getters.mergedConfig.hideMutedPosts
  27. args.includeTypes = mastoApiNotificationTypes
  28. args.withMuted = !hideMutedPosts
  29. args.timeline = 'notifications'
  30. if (older) {
  31. if (timelineData.minId !== Number.POSITIVE_INFINITY) {
  32. args.until = timelineData.minId
  33. }
  34. return fetchNotifications({ store, args, older })
  35. } else {
  36. // fetch new notifications
  37. if (since === undefined && timelineData.maxId !== Number.POSITIVE_INFINITY) {
  38. args.since = timelineData.maxId
  39. } else if (since !== null) {
  40. args.since = since
  41. }
  42. const result = fetchNotifications({ store, args, older })
  43. // If there's any unread notifications, try fetch notifications since
  44. // the newest read notification to check if any of the unread notifs
  45. // have changed their 'seen' state (marked as read in another session), so
  46. // we can update the state in this session to mark them as read as well.
  47. // The normal maxId-check does not tell if older notifications have changed
  48. const notifications = timelineData.data
  49. const readNotifsIds = notifications.filter(n => n.seen).map(n => n.id)
  50. const unreadNotifsIds = notifications.filter(n => !n.seen).map(n => n.id)
  51. if (readNotifsIds.length > 0 && readNotifsIds.length > 0) {
  52. const minId = Math.min(...unreadNotifsIds) // Oldest known unread notification
  53. if (minId !== Infinity) {
  54. args.since = false // Don't use since_id since it sorta conflicts with min_id
  55. args.minId = minId - 1 // go beyond
  56. fetchNotifications({ store, args, older })
  57. }
  58. }
  59. return result
  60. }
  61. }
  62. const fetchNotifications = ({ store, args, older }) => {
  63. return apiService.fetchTimeline(args)
  64. .then((response) => {
  65. if (response.errors) {
  66. throw new Error(`${response.status} ${response.statusText}`)
  67. }
  68. const notifications = response.data
  69. update({ store, notifications, older })
  70. return notifications
  71. })
  72. .catch((error) => {
  73. store.dispatch('pushGlobalNotice', {
  74. level: 'error',
  75. messageKey: 'notifications.error',
  76. messageArgs: [error.message],
  77. timeout: 5000
  78. })
  79. console.error(error)
  80. })
  81. }
  82. const startFetching = ({ credentials, store }) => {
  83. // Initially there's set flag to silence all desktop notifications so
  84. // that there won't spam of them when user just opened up the FE we
  85. // reset that flag after a while to show new notifications once again.
  86. setTimeout(() => store.dispatch('setNotificationsSilence', false), 10000)
  87. const boundFetchAndUpdate = () => fetchAndUpdate({ credentials, store })
  88. boundFetchAndUpdate()
  89. return promiseInterval(boundFetchAndUpdate, 10000)
  90. }
  91. const notificationsFetcher = {
  92. fetchAndUpdate,
  93. startFetching
  94. }
  95. export default notificationsFetcher