announcements.js (3663B)
- import { defineStore } from 'pinia'
- const FETCH_ANNOUNCEMENT_INTERVAL_MS = 1000 * 60 * 5
- export const useAnnouncementsStore = defineStore('announcements', {
- state: () => ({
- announcements: [],
- supportsAnnouncements: true,
- fetchAnnouncementsTimer: undefined
- }),
- getters: {
- unreadAnnouncementCount () {
- if (!window.vuex.state.users.currentUser) {
- return 0
- }
- const unread = this.announcements.filter(announcement => !(announcement.inactive || announcement.read))
- return unread.length
- }
- },
- actions: {
- fetchAnnouncements () {
- if (!this.supportsAnnouncements) {
- return Promise.resolve()
- }
- const currentUser = window.vuex.state.users.currentUser
- const isAdmin = currentUser && currentUser.privileges.includes('announcements_manage_announcements')
- const getAnnouncements = async () => {
- if (!isAdmin) {
- return window.vuex.state.api.backendInteractor.fetchAnnouncements()
- }
- const all = await window.vuex.state.api.backendInteractor.adminFetchAnnouncements()
- const visible = await window.vuex.state.api.backendInteractor.fetchAnnouncements()
- const visibleObject = visible.reduce((a, c) => {
- a[c.id] = c
- return a
- }, {})
- const getWithinVisible = announcement => visibleObject[announcement.id]
- all.forEach(announcement => {
- const visibleAnnouncement = getWithinVisible(announcement)
- if (!visibleAnnouncement) {
- announcement.inactive = true
- } else {
- announcement.read = visibleAnnouncement.read
- }
- })
- return all
- }
- return getAnnouncements()
- .then(announcements => {
- this.announcements = announcements
- })
- .catch(error => {
- // If and only if backend does not support announcements, it would return 404.
- // In this case, silently ignores it.
- if (error && error.statusCode === 404) {
- this.supportsAnnouncements = false
- } else {
- throw error
- }
- })
- },
- markAnnouncementAsRead (id) {
- return window.vuex.state.api.backendInteractor.dismissAnnouncement({ id })
- .then(() => {
- const index = this.announcements.findIndex(a => a.id === id)
- if (index < 0) {
- return
- }
- this.announcements[index].read = true
- })
- },
- startFetchingAnnouncements () {
- if (this.fetchAnnouncementsTimer) {
- return
- }
- const interval = setInterval(() => this.fetchAnnouncements(), FETCH_ANNOUNCEMENT_INTERVAL_MS)
- this.fetchAnnouncementsTimer = interval
- return this.fetchAnnouncements()
- },
- stopFetchingAnnouncements () {
- const interval = this.fetchAnnouncementsTimer
- this.fetchAnnouncementsTimer = undefined
- clearInterval(interval)
- },
- postAnnouncement ({ content, startsAt, endsAt, allDay }) {
- return window.vuex.state.api.backendInteractor.postAnnouncement({ content, startsAt, endsAt, allDay })
- .then(() => {
- return this.fetchAnnouncements()
- })
- },
- editAnnouncement ({ id, content, startsAt, endsAt, allDay }) {
- return window.vuex.state.api.backendInteractor.editAnnouncement({ id, content, startsAt, endsAt, allDay })
- .then(() => {
- return this.fetchAnnouncements()
- })
- },
- deleteAnnouncement (id) {
- return window.vuex.state.api.backendInteractor.deleteAnnouncement({ id })
- .then(() => {
- return this.fetchAnnouncements()
- })
- }
- }
- })