aboutsummaryrefslogtreecommitdiff
path: root/src/modules/announcements.js
blob: ab16626c02bdb065672a488f5e6f2243afc8ca2e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
const FETCH_ANNOUNCEMENT_INTERVAL_MS = 1000 * 60 * 5

export const defaultState = {
  announcements: [],
  fetchAnnouncementsTimer: undefined
}

export const mutations = {
  setAnnouncements (state, announcements) {
    state.announcements = announcements
  },
  setAnnouncementRead (state, { id, read }) {
    const index = state.announcements.findIndex(a => a.id === id)

    if (index < 0) {
      return
    }

    state.announcements[index].read = read
  },
  setFetchAnnouncementsTimer (state, timer) {
    state.fetchAnnouncementsTimer = timer
  }
}

export const getters = {
  unreadAnnouncementCount (state, _getters, rootState) {
    if (!rootState.users.currentUser) {
      return 0
    }

    const unread = state.announcements.filter(announcement => !(announcement.inactive || announcement.read))
    return unread.length
  }
}

const announcements = {
  state: defaultState,
  mutations,
  getters,
  actions: {
    fetchAnnouncements (store) {
      const currentUser = store.rootState.users.currentUser
      const isAdmin = currentUser && currentUser.role === 'admin'

      const getAnnouncements = async () => {
        if (!isAdmin) {
          return store.rootState.api.backendInteractor.fetchAnnouncements()
        }

        const all = await store.rootState.api.backendInteractor.adminFetchAnnouncements()
        const visible = await store.rootState.api.backendInteractor.fetchAnnouncements()
        const visibleObject = visible.reduce((a, c) => {
          a[c.id] = c
          return a
        }, {})

        all.forEach(announcement => {
          if (!visibleObject[announcement.id]) {
            announcement.inactive = true
          } else {
            announcement.read = visibleObject[announcement.id].read
          }
        })

        return all
      }

      return getAnnouncements()
        .then(announcements => {
          store.commit('setAnnouncements', announcements)
        })
    },
    markAnnouncementAsRead (store, id) {
      return store.rootState.api.backendInteractor.dismissAnnouncement({ id })
        .then(() => {
          store.commit('setAnnouncementRead', { id, read: true })
        })
    },
    startFetchingAnnouncements (store) {
      if (store.state.fetchAnnouncementsTimer) {
        return
      }

      const interval = setInterval(() => store.dispatch('fetchAnnouncements'), FETCH_ANNOUNCEMENT_INTERVAL_MS)
      store.commit('setFetchAnnouncementsTimer', interval)

      return store.dispatch('fetchAnnouncements')
    },
    stopFetchingAnnouncements (store) {
      const interval = store.state.fetchAnnouncementsTimer
      store.commit('setFetchAnnouncementsTimer', undefined)
      clearInterval(interval)
    },
    postAnnouncement (store, { content, startsAt, endsAt, allDay }) {
      return store.rootState.api.backendInteractor.postAnnouncement({ content, startsAt, endsAt, allDay })
        .then(() => {
          return store.dispatch('fetchAnnouncements')
        })
    },
    editAnnouncement (store, { id, content, startsAt, endsAt, allDay }) {
      return store.rootState.api.backendInteractor.editAnnouncement({ id, content, startsAt, endsAt, allDay })
        .then(() => {
          return store.dispatch('fetchAnnouncements')
        })
    },
    deleteAnnouncement (store, id) {
      return store.rootState.api.backendInteractor.deleteAnnouncement({ id })
        .then(() => {
          return store.dispatch('fetchAnnouncements')
        })
    }
  }
}

export default announcements