pleroma-fe/src/modules/notifications.js

190 lines
5.9 KiB
JavaScript
Raw Normal View History

2026-01-06 16:23:17 +02:00
import { useReportsStore } from 'src/stores/reports.js'
import { useServerSideStorageStore } from 'src/stores/serverSideStorage'
2026-01-06 16:23:17 +02:00
import apiService from '../services/api/api.service.js'
2026-01-06 16:23:17 +02:00
import {
closeAllDesktopNotifications,
closeDesktopNotification,
} from '../services/desktop_notification_utils/desktop_notification_utils.js'
import {
isStatusNotification,
isValidNotification,
2026-01-06 16:22:52 +02:00
maybeShowNotification,
} from '../services/notification_utils/notification_utils.js'
const emptyNotifications = () => ({
desktopNotificationSilence: true,
maxId: 0,
minId: Number.POSITIVE_INFINITY,
data: [],
idStore: {},
2026-01-06 16:22:52 +02:00
loading: false,
})
export const defaultState = () => ({
2026-01-06 16:22:52 +02:00
...emptyNotifications(),
})
export const notifications = {
state: defaultState(),
mutations: {
2026-01-06 16:22:52 +02:00
addNewNotifications(state, { notifications }) {
notifications.forEach((notification) => {
state.data.push(notification)
state.idStore[notification.id] = notification
})
},
2026-01-06 16:22:52 +02:00
clearNotifications(state) {
2025-02-04 15:23:21 +02:00
const blankState = defaultState()
2026-01-06 16:22:52 +02:00
Object.keys(state).forEach((k) => {
2025-02-04 15:23:21 +02:00
state[k] = blankState[k]
})
},
2026-01-06 16:22:52 +02:00
updateNotificationsMinMaxId(state, id) {
state.maxId = id > state.maxId ? id : state.maxId
state.minId = id < state.minId ? id : state.minId
},
2026-01-06 16:22:52 +02:00
setNotificationsLoading(state, { value }) {
state.loading = value
},
2026-01-06 16:22:52 +02:00
setNotificationsSilence(state, { value }) {
state.desktopNotificationSilence = value
},
2026-01-06 16:22:52 +02:00
markNotificationsAsSeen(state) {
state.data.forEach((notification) => {
notification.seen = true
})
},
2026-01-06 16:22:52 +02:00
markSingleNotificationAsSeen(state, { id }) {
const notification = state.idStore[id]
if (notification) notification.seen = true
},
2026-01-06 16:22:52 +02:00
dismissNotification(state, { id }) {
state.data = state.data.filter((n) => n.id !== id)
2023-11-16 20:09:16 +02:00
delete state.idStore[id]
},
2026-01-06 16:22:52 +02:00
updateNotification(state, { id, updater }) {
const notification = state.idStore[id]
notification && updater(notification)
2026-01-06 16:22:52 +02:00
},
},
actions: {
2026-01-06 16:22:52 +02:00
addNewNotifications(store, { notifications }) {
const { commit, dispatch, state, rootState } = store
const validNotifications = notifications.filter((notification) => {
// If invalid notification, update ids but don't add it to store
if (!isValidNotification(notification)) {
console.error('Invalid notification:', notification)
commit('updateNotificationsMinMaxId', notification.id)
return false
}
return true
})
2026-01-06 16:22:52 +02:00
const statusNotifications = validNotifications.filter(
(notification) =>
isStatusNotification(notification.type) && notification.status,
)
// Synchronous commit to add all the statuses
2026-01-06 16:22:52 +02:00
commit('addNewStatuses', {
statuses: statusNotifications.map(
(notification) => notification.status,
),
})
// Update references to statuses in notifications to ones in the store
2026-01-06 16:22:52 +02:00
statusNotifications.forEach((notification) => {
const id = notification.status.id
const referenceStatus = rootState.statuses.allStatusesObject[id]
if (referenceStatus) {
notification.status = referenceStatus
}
})
2026-01-06 16:22:52 +02:00
validNotifications.forEach((notification) => {
if (notification.type === 'pleroma:report') {
2025-01-30 21:56:07 +02:00
useReportsStore().addReport(notification.report)
}
if (notification.type === 'pleroma:emoji_reaction') {
dispatch('fetchEmojiReactionsBy', notification.status.id)
}
// Only add a new notification if we don't have one for the same action
// eslint-disable-next-line no-prototype-builtins
2026-01-06 16:20:14 +02:00
if (!Object.hasOwn(state.idStore, notification.id)) {
commit('updateNotificationsMinMaxId', notification.id)
2023-11-16 20:09:16 +02:00
commit('addNewNotifications', { notifications: [notification] })
maybeShowNotification(
store,
2026-01-06 16:22:52 +02:00
Object.values(
useServerSideStorageStore().prefsStorage.simple.muteFilters,
),
notification,
)
} else if (notification.seen) {
state.idStore[notification.id].seen = true
}
})
},
2026-01-06 16:22:52 +02:00
notificationClicked({ state, dispatch }, { id }) {
2023-11-16 20:41:41 +02:00
const notification = state.idStore[id]
const { type, seen } = notification
if (!seen) {
switch (type) {
case 'mention':
case 'pleroma:report':
case 'follow_request':
break
default:
dispatch('markSingleNotificationAsSeen', { id })
2023-11-16 20:41:41 +02:00
}
}
},
2026-01-06 16:22:52 +02:00
setNotificationsLoading({ commit }, { value }) {
commit('setNotificationsLoading', { value })
},
2026-01-06 16:22:52 +02:00
setNotificationsSilence({ commit }, { value }) {
commit('setNotificationsSilence', { value })
},
2026-01-06 16:22:52 +02:00
markNotificationsAsSeen({ rootState, state, commit }) {
commit('markNotificationsAsSeen')
2026-01-06 16:22:52 +02:00
apiService
.markNotificationsAsSeen({
id: state.maxId,
credentials: rootState.users.currentUser.credentials,
})
.then(() => {
closeAllDesktopNotifications(rootState)
})
},
markSingleNotificationAsSeen({ rootState, commit }, { id }) {
commit('markSingleNotificationAsSeen', { id })
2026-01-06 16:22:52 +02:00
apiService
.markNotificationsAsSeen({
single: true,
id,
credentials: rootState.users.currentUser.credentials,
})
.then(() => {
closeDesktopNotification(rootState, { id })
})
},
dismissNotificationLocal({ commit }, { id }) {
commit('dismissNotification', { id })
},
2026-01-06 16:22:52 +02:00
dismissNotification({ rootState, commit }, { id }) {
commit('dismissNotification', { id })
rootState.api.backendInteractor.dismissNotification({ id })
},
2026-01-06 16:22:52 +02:00
updateNotification({ commit }, { id, updater }) {
commit('updateNotification', { id, updater })
2026-01-06 16:22:52 +02:00
},
},
}
export default notifications