Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F85831436
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Authored By
Unknown
Size
8 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/stores/notifications.js b/src/stores/notifications.js
index a12ce81338..eb92576026 100644
--- a/src/stores/notifications.js
+++ b/src/stores/notifications.js
@@ -1,290 +1,290 @@
import { defineStore } from 'pinia'
import notificationsFetcher from 'src/stores/fetchers/notifications_fetcher.js'
import { useI18nStore } from 'src/stores/i18n.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { useOAuthStore } from 'src/stores/oauth.js'
import { useReportsStore } from 'src/stores/reports.js'
import { useStatusesStore } from 'src/stores/statuses.js'
import { useStreamingStore } from 'src/stores/streaming.js'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
import { useUsersStore } from 'src/stores/users.js'
import { dismissNotification, markNotificationsAsSeen } from 'src/api/user.js'
import {
closeAllDesktopNotifications,
closeDesktopNotification,
} from 'src/services/desktop_notification_utils/desktop_notification_utils.js'
import {
isValidNotification,
maybeShowNotification,
} from 'src/services/notification_utils/notification_utils.js'
import { isStatusNotification } from 'src/services/notification_utils/notification_utils_sw.js'
export const defaultState = () => ({
desktopNotificationSilence: true,
maxId: '',
minId: '',
data: [],
statusNotificationRelations: new WeakMap(),
idStore: new Map(),
statusIdStore: new Set(),
socket: null,
streaming: false,
fetcher: null,
})
export const useNotificationsStore = defineStore('notifications', {
state: defaultState,
actions: {
// Init
attachSocket() {
const et = new EventTarget()
const socket = { et }
et.addEventListener('notification', this.addNewNotifications)
et.addEventListener('open', this.onStreamConnect)
et.addEventListener('close', this.onStreamDisconnect)
useStreamingStore().addSubscriber(socket)
this.socket = socket
},
activate() {
this.attachSocket()
// Initially there's set flag to silence all desktop notifications so
// that there won't spam of them when user just opened up the FE we
// reset that flag after a while to show new notifications once again.
setTimeout(() => (this.desktopNotificationSilence = false), 10000)
if (this.fetcher) throw new Error('Fetcher already exists!')
this.fetcher = notificationsFetcher(useOAuthStore().token)
this.startFetching('Notifications activated')
},
deactivate() {
if (!this.streaming) {
this.stopFetching('Notifications deactivated')
}
useStreamingStore().removeSubscriber(this.socket)
const { et } = this.socket
et.removeEventListener('notification', this.addNewNotifications)
et.removeEventListener('open', this.onStreamConnect)
et.removeEventListener('close', this.onStreamDisconnect)
const blankState = defaultState()
Object.keys(blankState).forEach((k) => {
this[k] = blankState[k]
})
},
// Poll & Push
onStreamConnect() {
console.debug('[Notifications] Notifications stream connected')
this.streaming = true
this.stopFetching('Socket connected')
},
onStreamDisconnect() {
console.debug('[Notifications] Notifications stream disconnected')
this.streaming = false
this.startFetching('Socket disconnected')
},
startFetching(reason) {
console.debug(
'[Notifications] Starting fetching notifications',
'Reason:',
reason,
)
this.fetcher.startFetching()
},
stopFetching(reason) {
console.debug(
'[Notifications] Stopped fetching notifications',
'Reason:',
reason,
)
this.fetcher.stopFetching()
},
// Updates
updateExtremes(id) {
if (this.maxId === '' || id > this.maxId) {
this.maxId = id
}
if (this.minId === '' || id < this.minId) {
this.minId = id
}
},
addNewNotifications(result, older) {
const { timestamp, data } = result
const notifications = older ? data : [...data].reverse()
useUsersStore().addNewUsers({
timestamp,
data: notifications.map((n) => n.from_profile),
})
notifications.forEach((n) => {
n.from_profile = useUsersStore().findUser(n.from_profile.id)
})
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)
this.updateExtremes(notification.id)
return false
}
return true
})
useUsersStore().addNewUsers({
timestamp,
data: validNotifications.map(
(notification) => notification.from_profile,
),
})
const statusNotifications = validNotifications.filter(
(notification) =>
isStatusNotification(notification.type) && notification.status,
)
// Synchronous commit to add all the statuses
useStatusesStore().addNewStatuses({
timestamp,
statuses: statusNotifications.map(
(notification) => notification.status,
),
})
// Update references to statuses in notifications to ones in the store
statusNotifications.forEach((notification) => {
const id = notification.status.id
const referenceStatus = useStatusesStore().allStatuses.get(id)
if (referenceStatus) {
notification.status = referenceStatus
}
})
validNotifications.forEach((notification) => {
if (notification.type === 'pleroma:report') {
useReportsStore().addReport(notification.report)
}
if (notification.type === 'pleroma:emoji_reaction') {
useStatusesStore().fetchEmojiReactions(notification.status.id)
}
// Only add a new notification if we don't have one for the same action
if (!this.idStore.has(notification.id)) {
this.updateExtremes(notification.id)
if (older) {
this.data.push(notification)
} else {
this.data.unshift(notification)
}
this.idStore.set(notification.id, notification)
if (notification.status) {
this.statusNotificationRelations.set(
notification.status,
this.idStore.get(notification.id),
)
}
maybeShowNotification(
useMergedConfigStore().mergedConfig.notificationVisibility,
Object.values(
useSyncConfigStore().prefsStorage.simple.muteFilters ?? {},
),
notification,
useI18nStore().i18n,
)
} else if (notification.seen) {
this.idStore.get(notification.id).seen = true
}
})
},
// Seen / Dismiss
notificationClicked(id) {
const notification = this.idStore.get(id)
const { type, seen } = notification
if (!seen) {
switch (type) {
case 'mention':
case 'pleroma:report':
case 'follow_request':
break
default:
- this.markSingleNotificationAsSeen({ id })
+ this.markSingleNotificationAsSeen(id)
}
}
},
markNotificationsAsSeen() {
this.data.forEach((notification) => {
notification.seen = true
})
markNotificationsAsSeen({
id: this.maxId,
credentials: useOAuthStore().token,
}).then(() => {
closeAllDesktopNotifications()
})
},
markSingleNotificationAsSeen(id) {
const notification = this.idStore.get(id)
if (notification) notification.seen = true
markNotificationsAsSeen({
single: true,
id,
credentials: useOAuthStore().token,
}).then(() => {
closeDesktopNotification(id)
})
},
dismissNotificationLocal(id) {
this.idStore.delete(id)
this.syncOrder()
},
dismissNotification(id) {
this.dismissNotificationLocal(id)
dismissNotification({
id,
credentials: useOAuthStore().token,
})
},
syncOrder() {
this.minId = ''
this.maxId = ''
this.data = this.data.filter(({ id }) => {
const present = this.idStore.has(id)
if (present) {
this.updateExtremes(id) // Side-effect
}
return present
})
},
wipeStatuses(ids) {
const set = new Set(ids)
this.data.forEach((notification) => {
const status =
isStatusNotification(notification.type) && notification.status
if (status && set.has(status.id)) {
this.idStore.delete(notification.id)
}
})
this.syncOrder()
},
},
})
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sun, Nov 1, 3:16 PM (11 h, 6 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1803132
Default Alt Text
(8 KB)
Attached To
Mode
rPUFE pleroma-fe-upstream
Attached
Detach File
Event Timeline