diff options
| author | Shpuld Shpludson <shp@cock.li> | 2021-03-15 09:45:38 +0000 |
|---|---|---|
| committer | Shpuld Shpludson <shp@cock.li> | 2021-03-15 09:45:38 +0000 |
| commit | a00212a3bbc029439a27ba01895e01adf37a2db6 (patch) | |
| tree | 7848bf740d0e081501ccb194031329ce5980d337 /src/modules/api.js | |
| parent | 184364c7e06a982b48bbe6d913f02a73dd428aef (diff) | |
| parent | a8967d85bd7ae1541f1d4e41e95fc8fa111f2360 (diff) | |
Merge branch 'websocket-fixes' into 'develop'
Various websocket fixes
See merge request pleroma/pleroma-fe!1326
Diffstat (limited to 'src/modules/api.js')
| -rw-r--r-- | src/modules/api.js | 102 |
1 files changed, 82 insertions, 20 deletions
diff --git a/src/modules/api.js b/src/modules/api.js index 08485a30..8654b90a 100644 --- a/src/modules/api.js +++ b/src/modules/api.js @@ -3,8 +3,11 @@ import { WSConnectionStatus } from '../services/api/api.service.js' import { maybeShowChatNotification } from '../services/chat_utils/chat_utils.js' import { Socket } from 'phoenix' +const retryTimeout = (multiplier) => 1000 * multiplier + const api = { state: { + retryMultiplier: 1, backendInteractor: backendInteractorService(), fetchers: {}, socket: null, @@ -34,18 +37,43 @@ const api = { }, setMastoUserSocketStatus (state, value) { state.mastoUserSocketStatus = value + }, + incrementRetryMultiplier (state) { + state.retryMultiplier = Math.max(++state.retryMultiplier, 3) + }, + resetRetryMultiplier (state) { + state.retryMultiplier = 1 } }, actions: { - // Global MastoAPI socket control, in future should disable ALL sockets/(re)start relevant sockets - enableMastoSockets (store) { - const { state, dispatch } = store - if (state.mastoUserSocket) return + /** + * Global MastoAPI socket control, in future should disable ALL sockets/(re)start relevant sockets + * + * @param {Boolean} [initial] - whether this enabling happened at boot time or not + */ + enableMastoSockets (store, initial) { + const { state, dispatch, commit } = store + // Do not initialize unless nonexistent or closed + if ( + state.mastoUserSocket && + ![ + WebSocket.CLOSED, + WebSocket.CLOSING + ].includes(state.mastoUserSocket.getState()) + ) { + return + } + if (initial) { + commit('setMastoUserSocketStatus', WSConnectionStatus.STARTING_INITIAL) + } else { + commit('setMastoUserSocketStatus', WSConnectionStatus.STARTING) + } return dispatch('startMastoUserSocket') }, disableMastoSockets (store) { - const { state, dispatch } = store + const { state, dispatch, commit } = store if (!state.mastoUserSocket) return + commit('setMastoUserSocketStatus', WSConnectionStatus.DISABLED) return dispatch('stopMastoUserSocket') }, @@ -91,11 +119,29 @@ const api = { } ) state.mastoUserSocket.addEventListener('open', () => { + // Do not show notification when we just opened up the page + if (state.mastoUserSocketStatus !== WSConnectionStatus.STARTING_INITIAL) { + dispatch('pushGlobalNotice', { + level: 'success', + messageKey: 'timeline.socket_reconnected', + timeout: 5000 + }) + } + // Stop polling if we were errored or disabled + if (new Set([ + WSConnectionStatus.ERROR, + WSConnectionStatus.DISABLED + ]).has(state.mastoUserSocketStatus)) { + dispatch('stopFetchingTimeline', { timeline: 'friends' }) + dispatch('stopFetchingNotifications') + dispatch('stopFetchingChats') + } + commit('resetRetryMultiplier') commit('setMastoUserSocketStatus', WSConnectionStatus.JOINED) }) state.mastoUserSocket.addEventListener('error', ({ detail: error }) => { console.error('Error in MastoAPI websocket:', error) - commit('setMastoUserSocketStatus', WSConnectionStatus.ERROR) + // TODO is this needed? dispatch('clearOpenedChats') }) state.mastoUserSocket.addEventListener('close', ({ detail: closeEvent }) => { @@ -106,14 +152,26 @@ const api = { const { code } = closeEvent if (ignoreCodes.has(code)) { console.debug(`Not restarting socket becasue of closure code ${code} is in ignore list`) + commit('setMastoUserSocketStatus', WSConnectionStatus.CLOSED) } else { console.warn(`MastoAPI websocket disconnected, restarting. CloseEvent code: ${code}`) - dispatch('startFetchingTimeline', { timeline: 'friends' }) - dispatch('startFetchingNotifications') - dispatch('startFetchingChats') - dispatch('restartMastoUserSocket') + setTimeout(() => { + dispatch('startMastoUserSocket') + }, retryTimeout(state.retryMultiplier)) + commit('incrementRetryMultiplier') + if (state.mastoUserSocketStatus !== WSConnectionStatus.ERROR) { + dispatch('startFetchingTimeline', { timeline: 'friends' }) + dispatch('startFetchingNotifications') + dispatch('startFetchingChats') + dispatch('pushGlobalNotice', { + level: 'error', + messageKey: 'timeline.socket_broke', + messageArgs: [code], + timeout: 5000 + }) + } + commit('setMastoUserSocketStatus', WSConnectionStatus.ERROR) } - commit('setMastoUserSocketStatus', WSConnectionStatus.CLOSED) dispatch('clearOpenedChats') }) resolve() @@ -122,15 +180,6 @@ const api = { } }) }, - 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') - dispatch('stopFetchingChats') - }) - }, stopMastoUserSocket ({ state, dispatch }) { dispatch('startFetchingTimeline', { timeline: 'friends' }) dispatch('startFetchingNotifications') @@ -156,6 +205,13 @@ const api = { if (!fetcher) return store.commit('removeFetcher', { fetcherName: timeline, fetcher }) }, + fetchTimeline (store, timeline, { ...rest }) { + store.state.backendInteractor.fetchTimeline({ + store, + timeline, + ...rest + }) + }, // Notifications startFetchingNotifications (store) { @@ -168,6 +224,12 @@ const api = { if (!fetcher) return store.commit('removeFetcher', { fetcherName: 'notifications', fetcher }) }, + fetchNotifications (store, { ...rest }) { + store.state.backendInteractor.fetchNotifications({ + store, + ...rest + }) + }, // Follow requests startFetchingFollowRequests (store) { |
