diff options
| author | Shpuld Shpludson <shp@cock.li> | 2020-01-15 16:35:13 +0000 |
|---|---|---|
| committer | Shpuld Shpludson <shp@cock.li> | 2020-01-15 16:35:13 +0000 |
| commit | 3ab128e73924ce34d190ff609cb9b081cdffe402 (patch) | |
| tree | bba013a7d61688b90c1f59a8f9fa6c3323b72a05 /src/modules/api.js | |
| parent | 7c26435e66fd7e142ea4b88fbe51eede32eeb5ce (diff) | |
| parent | 7397636914a9d3e7fd30373034c25175273ab808 (diff) | |
Merge branch 'develop' into 'master'
`master` refresh with `develop`
See merge request pleroma/pleroma-fe!1028
Diffstat (limited to 'src/modules/api.js')
| -rw-r--r-- | src/modules/api.js | 165 |
1 files changed, 139 insertions, 26 deletions
diff --git a/src/modules/api.js b/src/modules/api.js index 31cb55c6..9c296275 100644 --- a/src/modules/api.js +++ b/src/modules/api.js @@ -6,18 +6,19 @@ const api = { backendInteractor: backendInteractorService(), fetchers: {}, socket: null, - chatDisabled: false, + mastoUserSocket: null, followRequests: [] }, mutations: { setBackendInteractor (state, backendInteractor) { state.backendInteractor = backendInteractor }, - addFetcher (state, {timeline, fetcher}) { - state.fetchers[timeline] = fetcher + addFetcher (state, { fetcherName, fetcher }) { + state.fetchers[fetcherName] = fetcher }, - removeFetcher (state, {timeline}) { - delete state.fetchers[timeline] + removeFetcher (state, { fetcherName, fetcher }) { + window.clearInterval(fetcher) + delete state.fetchers[fetcherName] }, setWsToken (state, token) { state.wsToken = token @@ -25,44 +26,156 @@ const api = { setSocket (state, socket) { state.socket = socket }, - setChatDisabled (state, value) { - state.chatDisabled = value - }, setFollowRequests (state, value) { state.followRequests = value } }, actions: { - startFetching (store, {timeline = 'friends', tag = false, userId = false}) { - // Don't start fetching if we already are. + // Global MastoAPI socket control, in future should disable ALL sockets/(re)start relevant sockets + enableMastoSockets (store) { + const { state, dispatch } = store + if (state.mastoUserSocket) return + return dispatch('startMastoUserSocket') + }, + disableMastoSockets (store) { + const { state, dispatch } = store + if (!state.mastoUserSocket) return + return dispatch('stopMastoUserSocket') + }, + + // MastoAPI 'User' sockets + startMastoUserSocket (store) { + return new Promise((resolve, reject) => { + try { + const { state, dispatch, rootState } = store + const timelineData = rootState.statuses.timelines.friends + state.mastoUserSocket = state.backendInteractor.startUserSocket({ store }) + state.mastoUserSocket.addEventListener( + 'message', + ({ detail: message }) => { + if (!message) return // pings + if (message.event === 'notification') { + dispatch('addNewNotifications', { + notifications: [message.notification], + older: false + }) + } else if (message.event === 'update') { + dispatch('addNewStatuses', { + statuses: [message.status], + userId: false, + showImmediately: timelineData.visibleStatuses.length === 0, + timeline: 'friends' + }) + } + } + ) + state.mastoUserSocket.addEventListener('error', ({ detail: error }) => { + console.error('Error in MastoAPI websocket:', error) + }) + state.mastoUserSocket.addEventListener('close', ({ detail: closeEvent }) => { + const ignoreCodes = new Set([ + 1000, // Normal (intended) closure + 1001 // Going away + ]) + const { code } = closeEvent + if (ignoreCodes.has(code)) { + console.debug(`Not restarting socket becasue of closure code ${code} is in ignore list`) + } else { + console.warn(`MastoAPI websocket disconnected, restarting. CloseEvent code: ${code}`) + dispatch('startFetchingTimeline', { timeline: 'friends' }) + dispatch('startFetchingNotifications') + dispatch('restartMastoUserSocket') + } + }) + resolve() + } catch (e) { + reject(e) + } + }) + }, + restartMastoUserSocket ({ dispatch }) { + // This basically starts MastoAPI user socket and stops conventional + // fetchers when connection reestablished + return dispatch('startMastoUserSocket').then(() => { + dispatch('stopFetchingTimeline', { timeline: 'friends' }) + dispatch('stopFetchingNotifications') + }) + }, + stopMastoUserSocket ({ state, dispatch }) { + dispatch('startFetchingTimeline', { timeline: 'friends' }) + dispatch('startFetchingNotifications') + console.log(state.mastoUserSocket) + state.mastoUserSocket.close() + }, + + // Timelines + startFetchingTimeline (store, { + timeline = 'friends', + tag = false, + userId = false + }) { if (store.state.fetchers[timeline]) return - const fetcher = store.state.backendInteractor.startFetching({ timeline, store, userId, tag }) - store.commit('addFetcher', { timeline, fetcher }) + const fetcher = store.state.backendInteractor.startFetchingTimeline({ + timeline, store, userId, tag + }) + store.commit('addFetcher', { fetcherName: timeline, fetcher }) }, - stopFetching (store, timeline) { + stopFetchingTimeline (store, timeline) { const fetcher = store.state.fetchers[timeline] - window.clearInterval(fetcher) - store.commit('removeFetcher', {timeline}) + if (!fetcher) return + store.commit('removeFetcher', { fetcherName: timeline, fetcher }) + }, + + // Notifications + startFetchingNotifications (store) { + if (store.state.fetchers.notifications) return + const fetcher = store.state.backendInteractor.startFetchingNotifications({ store }) + store.commit('addFetcher', { fetcherName: 'notifications', fetcher }) + }, + stopFetchingNotifications (store) { + const fetcher = store.state.fetchers.notifications + if (!fetcher) return + store.commit('removeFetcher', { fetcherName: 'notifications', fetcher }) + }, + fetchAndUpdateNotifications (store) { + store.state.backendInteractor.fetchAndUpdateNotifications({ store }) }, + + // Follow requests + startFetchingFollowRequests (store) { + if (store.state.fetchers['followRequests']) return + const fetcher = store.state.backendInteractor.startFetchingFollowRequests({ store }) + store.commit('addFetcher', { fetcherName: 'followRequests', fetcher }) + }, + stopFetchingFollowRequests (store) { + const fetcher = store.state.fetchers.followRequests + if (!fetcher) return + store.commit('removeFetcher', { fetcherName: 'followRequests', fetcher }) + }, + removeFollowRequest (store, request) { + let requests = store.state.followRequests.filter((it) => it !== request) + store.commit('setFollowRequests', requests) + }, + + // Pleroma websocket setWsToken (store, token) { store.commit('setWsToken', token) }, - initializeSocket (store) { + initializeSocket ({ dispatch, commit, state, rootState }) { // Set up websocket connection - if (!store.state.chatDisabled) { - const token = store.state.wsToken - const socket = new Socket('/socket', {params: {token}}) + const token = state.wsToken + if (rootState.instance.chatAvailable && typeof token !== 'undefined' && state.socket === null) { + const socket = new Socket('/socket', { params: { token } }) socket.connect() - store.dispatch('initializeChat', socket) + + commit('setSocket', socket) + dispatch('initializeChat', socket) } }, - disableChat (store) { - store.commit('setChatDisabled', true) - }, - removeFollowRequest (store, request) { - let requests = store.state.followRequests.filter((it) => it !== request) - store.commit('setFollowRequests', requests) + disconnectFromSocket ({ commit, state }) { + state.socket && state.socket.disconnect() + commit('setSocket', null) } } } |
