aboutsummaryrefslogtreecommitdiff
path: root/src/modules
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules')
-rw-r--r--src/modules/announcements.js135
-rw-r--r--src/modules/api.js2
-rw-r--r--src/modules/users.js10
3 files changed, 145 insertions, 2 deletions
diff --git a/src/modules/announcements.js b/src/modules/announcements.js
new file mode 100644
index 00000000..e4d2d2b0
--- /dev/null
+++ b/src/modules/announcements.js
@@ -0,0 +1,135 @@
+const FETCH_ANNOUNCEMENT_INTERVAL_MS = 1000 * 60 * 5
+
+export const defaultState = {
+ announcements: [],
+ supportsAnnouncements: true,
+ 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
+ },
+ setSupportsAnnouncements (state, supportsAnnouncements) {
+ state.supportsAnnouncements = supportsAnnouncements
+ }
+}
+
+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) {
+ if (!store.state.supportsAnnouncements) {
+ return Promise.resolve()
+ }
+
+ 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
+ }, {})
+ 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 => {
+ store.commit('setAnnouncements', 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) {
+ store.commit('setSupportsAnnouncements', false)
+ } else {
+ throw error
+ }
+ })
+ },
+ 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
diff --git a/src/modules/api.js b/src/modules/api.js
index 0acc03f1..fee584e8 100644
--- a/src/modules/api.js
+++ b/src/modules/api.js
@@ -216,7 +216,7 @@ const api = {
if (!fetcher) return
store.commit('removeFetcher', { fetcherName: timeline, fetcher })
},
- fetchTimeline (store, timeline, { ...rest }) {
+ fetchTimeline (store, { timeline, ...rest }) {
store.state.backendInteractor.fetchTimeline({
store,
timeline,
diff --git a/src/modules/users.js b/src/modules/users.js
index eef87c2c..053e44b6 100644
--- a/src/modules/users.js
+++ b/src/modules/users.js
@@ -56,6 +56,11 @@ const removeUserFromFollowers = (store, id) => {
.then((relationship) => store.commit('updateUserRelationship', [relationship]))
}
+const editUserNote = (store, { id, comment }) => {
+ return store.rootState.api.backendInteractor.editUserNote({ id, comment })
+ .then((relationship) => store.commit('updateUserRelationship', [relationship]))
+}
+
const muteUser = (store, id) => {
const predictedRelationship = store.state.relationships[id] || { id }
predictedRelationship.muting = true
@@ -335,6 +340,9 @@ const users = {
unblockUsers (store, ids = []) {
return Promise.all(ids.map(id => unblockUser(store, id)))
},
+ editUserNote (store, args) {
+ return editUserNote(store, args)
+ },
fetchMutes (store) {
return store.rootState.api.backendInteractor.fetchMutes()
.then((mutes) => {
@@ -588,7 +596,7 @@ const users = {
}
if (store.getters.mergedConfig.useStreamingApi) {
- store.dispatch('fetchTimeline', 'friends', { since: null })
+ store.dispatch('fetchTimeline', { timeline: 'friends', since: null })
store.dispatch('fetchNotifications', { since: null })
store.dispatch('enableMastoSockets', true).catch((error) => {
console.error('Failed initializing MastoAPI Streaming socket', error)