diff --git a/src/renderer/store/TimelineSpace/Contents.ts b/src/renderer/store/TimelineSpace/Contents.ts index d2312ad6..a30206bb 100644 --- a/src/renderer/store/TimelineSpace/Contents.ts +++ b/src/renderer/store/TimelineSpace/Contents.ts @@ -1,6 +1,6 @@ import SideBar, { SideBarModuleState } from './Contents/SideBar' import Home, { HomeState } from './Contents/Home' -import Notifications from './Contents/Notifications' +import Notifications, { NotificationsState } from './Contents/Notifications' import Favourites from './Contents/Favourites' import Local, { LocalState } from './Contents/Local' import Public, { PublicState } from './Contents/Public' @@ -17,6 +17,7 @@ export interface ContentsState {} export interface ContentsModuleState extends ContentsState { SideBar: SideBarModuleState, Home: HomeState, + Notifications: NotificationsState, Local: LocalState, Public: PublicState } diff --git a/src/renderer/store/TimelineSpace/Contents/Notifications.js b/src/renderer/store/TimelineSpace/Contents/Notifications.js deleted file mode 100644 index ae1ba0e7..00000000 --- a/src/renderer/store/TimelineSpace/Contents/Notifications.js +++ /dev/null @@ -1,102 +0,0 @@ -import { ipcRenderer } from 'electron' -import Mastodon from 'megalodon' - -const Notifications = { - namespaced: true, - state: { - lazyLoading: false, - heading: true, - notifications: [], - unreadNotifications: [], - filter: '' - }, - mutations: { - changeLazyLoading (state, value) { - state.lazyLoading = value - }, - changeHeading (state, value) { - state.heading = value - }, - appendNotifications (state, notification) { - if (state.heading) { - state.notifications = [notification].concat(state.notifications) - } else { - state.unreadNotifications = [notification].concat(state.unreadNotifications) - } - }, - updateNotifications (state, notifications) { - state.notifications = notifications - }, - mergeNotifications (state) { - state.notifications = state.unreadNotifications.slice(0, 80).concat(state.notifications) - state.unreadNotifications = [] - }, - insertNotifications (state, notifications) { - state.notifications = state.notifications.concat(notifications) - }, - updateToot (state, message) { - state.notifications = state.notifications.map((notification) => { - // I want to update toot only mention. - // Because Toot component don't use status information when other patterns. - if (notification.type === 'mention' && notification.status.id === message.id) { - const status = { - status: message - } - return Object.assign(notification, status) - } else { - return notification - } - }) - }, - clearNotifications (state) { - state.notifications = [] - }, - archiveNotifications (state) { - state.notifications = state.notifications.slice(0, 30) - }, - changeFilter (state, filter) { - state.filter = filter - } - }, - actions: { - fetchNotifications ({ commit, rootState }) { - const client = new Mastodon( - rootState.TimelineSpace.account.accessToken, - rootState.TimelineSpace.account.baseURL + '/api/v1' - ) - return client.get('/notifications', { limit: 30 }) - .then(res => { - commit('updateNotifications', res.data) - return res.data - }) - }, - lazyFetchNotifications ({ state, commit, rootState }, last) { - if (last === undefined || last === null) { - return Promise.resolve(null) - } - if (state.lazyLoading) { - return Promise.resolve(null) - } - commit('changeLazyLoading', true) - const client = new Mastodon( - rootState.TimelineSpace.account.accessToken, - rootState.TimelineSpace.account.baseURL + '/api/v1' - ) - return client.get('/notifications', { max_id: last.id, limit: 30 }) - .then(res => { - commit('changeLazyLoading', false) - commit('insertNotifications', res.data) - return res.data - }) - .catch(err => { - commit('changeLazyLoading', false) - throw err - }) - }, - resetBadge () { - ipcRenderer.send('reset-badge') - } - } -} - -export default Notifications diff --git a/src/renderer/store/TimelineSpace/Contents/Notifications.ts b/src/renderer/store/TimelineSpace/Contents/Notifications.ts new file mode 100644 index 00000000..53847c2c --- /dev/null +++ b/src/renderer/store/TimelineSpace/Contents/Notifications.ts @@ -0,0 +1,125 @@ +import { ipcRenderer } from 'electron' +import Mastodon, { Notification, Status, Response } from 'megalodon' +import { Module, MutationTree, ActionTree } from 'vuex' +import { RootState } from '@/store' + +export interface NotificationsState { + lazyLoading: boolean, + heading: boolean, + notifications: Array, + unreadNotifications: Array, + filter: string +} + +const state = (): NotificationsState => ({ + lazyLoading: false, + heading: true, + notifications: [], + unreadNotifications: [], + filter: '' +}) + +export const MUTATION_TYPES = { + CHANGE_LAZY_LOADING: 'changeLazyLoading', + CHANGE_HEADING: 'changeHeading', + APPEND_NOTIFICATIONS: 'appendNotifications', + UPDATE_NOTIFICATIONS: 'updateNotifications', + MERGE_NOTIFICATIONS: 'mergeNotifications', + INSERT_NOTIFICATIONS: 'insertNotifications', + UPDATE_TOOT: 'updateToot', + CLEAR_NOTIFICATIONS: 'clearNotifications', + ARCHIVE_NOTIFICATIONS: 'archiveNotifications', + CHANGE_FILTER: 'changeFilter' +} + +const mutations: MutationTree = { + [MUTATION_TYPES.CHANGE_LAZY_LOADING]: (state, value: boolean) => { + state.lazyLoading = value + }, + [MUTATION_TYPES.CHANGE_HEADING]: (state, value: boolean) => { + state.heading = value + }, + [MUTATION_TYPES.APPEND_NOTIFICATIONS]: (state, notification: Notification) => { + if (state.heading) { + state.notifications = [notification].concat(state.notifications) + } else { + state.unreadNotifications = [notification].concat(state.unreadNotifications) + } + }, + [MUTATION_TYPES.UPDATE_NOTIFICATIONS]: (state, notifications: Array) => { + state.notifications = notifications + }, + [MUTATION_TYPES.MERGE_NOTIFICATIONS]: (state) => { + state.notifications = state.unreadNotifications.slice(0, 80).concat(state.notifications) + state.unreadNotifications = [] + }, + [MUTATION_TYPES.INSERT_NOTIFICATIONS]: (state, notifications: Array) => { + state.notifications = state.notifications.concat(notifications) + }, + [MUTATION_TYPES.UPDATE_TOOT]: (state, message: Status) => { + state.notifications = state.notifications.map((notification) => { + // I want to update toot only mention. + // Because Toot component don't use status information when other patterns. + if (notification.status !== null && notification.status.id === message.id) { + const status = { + status: message + } + return Object.assign(notification, status) + } else { + return notification + } + }) + }, + [MUTATION_TYPES.CLEAR_NOTIFICATIONS]: (state) => { + state.notifications = [] + }, + [MUTATION_TYPES.ARCHIVE_NOTIFICATIONS]: (state) => { + state.notifications = state.notifications.slice(0, 30) + }, + [MUTATION_TYPES.CHANGE_FILTER]: (state, filter: string) => { + state.filter = filter + } +} + +const actions: ActionTree = { + fetchNotifications: async ({ commit, rootState }): Promise> => { + const client = new Mastodon( + rootState.TimelineSpace.account.accessToken!, + rootState.TimelineSpace.account.baseURL + '/api/v1' + ) + const res: Response> = await client.get>('/notifications', { limit: 30 }) + + commit(MUTATION_TYPES.UPDATE_NOTIFICATIONS, res.data) + return res.data + }, + lazyFetchNotifications: ({ state, commit, rootState }, lastNotification: Notification): Promise | null> => { + if (state.lazyLoading) { + return Promise.resolve(null) + } + commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, true) + const client = new Mastodon( + rootState.TimelineSpace.account.accessToken!, + rootState.TimelineSpace.account.baseURL + '/api/v1' + ) + return client.get>('/notifications', { max_id: lastNotification.id, limit: 30 }) + .then(res => { + commit(MUTATION_TYPES.INSERT_NOTIFICATIONS, res.data) + return res.data + }) + .finally(() => { + commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, false) + }) + }, + resetBadge: () => { + ipcRenderer.send('reset-badge') + } +} + +const Notifications: Module = { + namespaced: true, + state: state, + mutations: mutations, + actions: actions +} + +export default Notifications