This repository has been archived on 2024-02-08. You can view files and clone it, but cannot push or open issues or pull requests.
frontend/src/stores/notifications.ts

74 lines
2.0 KiB
TypeScript

import {acceptHMRUpdate, defineStore} from 'pinia'
import {computed, ref} from 'vue'
import {tryOnUnmounted} from '@vueuse/core'
import type {INotification} from '@/modelTypes/INotification'
import NotificationService from '@/services/notification'
import {findIndexById} from '@/helpers/utils'
const NOTIFICATIONS_PULL_INTERVAL = 10000
export const useNotificationStore = defineStore('notification', () => {
const allNotifications = ref<INotification[]>([])
const notifications = computed(() => {
return allNotifications.value ? allNotifications.value.filter(n => n.name !== '') : []
})
const unreadNotifications = computed(() => {
return notifications.value.filter(n => n.readAt === null).length
})
const hasUnreadNotifications = computed(() => unreadNotifications.value > 0)
let timeout: ReturnType<typeof setTimeout>
const notificationService = new NotificationService()
async function loadNotifications() {
allNotifications.value = await notificationService.getAll() as INotification[]
}
async function pullNotifications() {
await loadNotifications()
timeout = setTimeout(pullNotifications, NOTIFICATIONS_PULL_INTERVAL)
}
function startNotificationPulling() {
pullNotifications()
return stopNotificationPulling
}
function stopNotificationPulling() {
clearTimeout(timeout)
}
async function markNotificationAsRead(notificationItem: INotification): Promise<INotification | undefined> {
const index = findIndexById(allNotifications.value, notificationItem.id)
if (index === -1) {
return
}
allNotifications.value[index] = {
...notificationItem,
read: true,
}
await notificationService.update(allNotifications.value[index])
}
tryOnUnmounted(stopNotificationPulling)
return {
notifications,
unreadNotifications,
hasUnreadNotifications,
startNotificationPulling,
stopNotificationPulling,
markNotificationAsRead,
}
})
// support hot reloading
if (import.meta.hot) {
import.meta.hot.accept(acceptHMRUpdate(useNotificationStore, import.meta.hot))
}