logo

pleroma-fe

My custom branche(s) on git.pleroma.social/pleroma/pleroma-fe
commit: 6bd38c7d6f3b0bf7cd1bdb6f6dcb49492491c562
parent 68c2a5b18f887f3db2f5685953bc5175aaaabbd3
Author: Shpuld Shpludson <shp@cock.li>
Date:   Thu,  1 Oct 2020 13:20:14 +0000

Merge branch 'fix/wait-for-request-before-starting-interval' into 'develop'

Fix/wait for request before starting interval - fix #937

Closes #937

See merge request pleroma/pleroma-fe!1222

Diffstat:

MCHANGELOG.md1+
Msrc/components/chat/chat.js5+++--
Msrc/modules/api.js2+-
Msrc/modules/chats.js11+++++------
Msrc/services/follow_request_fetcher/follow_request_fetcher.service.js5+++--
Msrc/services/notifications_fetcher/notifications_fetcher.service.js8+++++---
Asrc/services/promise_interval/promise_interval.js27+++++++++++++++++++++++++++
Msrc/services/timeline_fetcher/timeline_fetcher.service.js6++++--
8 files changed, 49 insertions(+), 16 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md @@ -21,6 +21,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Polls will be hidden with status content if "Collapse posts with subjects" is enabled and the post is collapsed. ### Fixed +- Network fetches don't pile up anymore but wait for previous ones to finish to reduce throttling. - Autocomplete won't stop at the second @, so it'll still work with "@lain@l" and not start over. - Fixed weird autocomplete behavior when you write ":custom_emoji: ?" diff --git a/src/components/chat/chat.js b/src/components/chat/chat.js @@ -5,6 +5,7 @@ import ChatMessage from '../chat_message/chat_message.vue' import PostStatusForm from '../post_status_form/post_status_form.vue' import ChatTitle from '../chat_title/chat_title.vue' import chatService from '../../services/chat_service/chat_service.js' +import { promiseInterval } from '../../services/promise_interval/promise_interval.js' import { getScrollPosition, getNewTopPosition, isBottomedOut, scrollableContainerHeight } from './chat_layout_utils.js' const BOTTOMED_OUT_OFFSET = 10 @@ -246,7 +247,7 @@ const Chat = { const fetchOlderMessages = !!maxId const sinceId = fetchLatest && chatMessageService.maxId - this.backendInteractor.chatMessages({ id: chatId, maxId, sinceId }) + return this.backendInteractor.chatMessages({ id: chatId, maxId, sinceId }) .then((messages) => { // Clear the current chat in case we're recovering from a ws connection loss. if (isFirstFetch) { @@ -287,7 +288,7 @@ const Chat = { }, doStartFetching () { this.$store.dispatch('startFetchingCurrentChat', { - fetcher: () => setInterval(() => this.fetchChat({ fetchLatest: true }), 5000) + fetcher: () => promiseInterval(() => this.fetchChat({ fetchLatest: true }), 5000) }) this.fetchChat({ isFirstFetch: true }) }, diff --git a/src/modules/api.js b/src/modules/api.js @@ -20,7 +20,7 @@ const api = { state.fetchers[fetcherName] = fetcher }, removeFetcher (state, { fetcherName, fetcher }) { - window.clearInterval(fetcher) + state.fetchers[fetcherName].stop() delete state.fetchers[fetcherName] }, setWsToken (state, token) { diff --git a/src/modules/chats.js b/src/modules/chats.js @@ -3,6 +3,7 @@ import { find, omitBy, orderBy, sumBy } from 'lodash' import chatService from '../services/chat_service/chat_service.js' import { parseChat, parseChatMessage } from '../services/entity_normalizer/entity_normalizer.service.js' import { maybeShowChatNotification } from '../services/chat_utils/chat_utils.js' +import { promiseInterval } from '../services/promise_interval/promise_interval.js' const emptyChatList = () => ({ data: [], @@ -42,12 +43,10 @@ const chats = { actions: { // Chat list startFetchingChats ({ dispatch, commit }) { - const fetcher = () => { - dispatch('fetchChats', { latest: true }) - } + const fetcher = () => dispatch('fetchChats', { latest: true }) fetcher() commit('setChatListFetcher', { - fetcher: () => setInterval(() => { fetcher() }, 5000) + fetcher: () => promiseInterval(fetcher, 5000) }) }, stopFetchingChats ({ commit }) { @@ -113,14 +112,14 @@ const chats = { setChatListFetcher (state, { commit, fetcher }) { const prevFetcher = state.chatListFetcher if (prevFetcher) { - clearInterval(prevFetcher) + prevFetcher.stop() } state.chatListFetcher = fetcher && fetcher() }, setCurrentChatFetcher (state, { fetcher }) { const prevFetcher = state.fetcher if (prevFetcher) { - clearInterval(prevFetcher) + prevFetcher.stop() } state.fetcher = fetcher && fetcher() }, diff --git a/src/services/follow_request_fetcher/follow_request_fetcher.service.js b/src/services/follow_request_fetcher/follow_request_fetcher.service.js @@ -1,4 +1,5 @@ import apiService from '../api/api.service.js' +import { promiseInterval } from '../promise_interval/promise_interval.js' const fetchAndUpdate = ({ store, credentials }) => { return apiService.fetchFollowRequests({ credentials }) @@ -10,9 +11,9 @@ const fetchAndUpdate = ({ store, credentials }) => { } const startFetching = ({ credentials, store }) => { - fetchAndUpdate({ credentials, store }) const boundFetchAndUpdate = () => fetchAndUpdate({ credentials, store }) - return setInterval(boundFetchAndUpdate, 10000) + boundFetchAndUpdate() + return promiseInterval(boundFetchAndUpdate, 10000) } const followRequestFetcher = { diff --git a/src/services/notifications_fetcher/notifications_fetcher.service.js b/src/services/notifications_fetcher/notifications_fetcher.service.js @@ -1,4 +1,5 @@ import apiService from '../api/api.service.js' +import { promiseInterval } from '../promise_interval/promise_interval.js' const update = ({ store, notifications, older }) => { store.dispatch('setNotificationsError', { value: false }) @@ -39,6 +40,7 @@ const fetchAndUpdate = ({ store, credentials, older = false }) => { args['since'] = Math.max(...readNotifsIds) fetchNotifications({ store, args, older }) } + return result } } @@ -53,13 +55,13 @@ const fetchNotifications = ({ store, args, older }) => { } const startFetching = ({ credentials, store }) => { - fetchAndUpdate({ credentials, store }) - const boundFetchAndUpdate = () => fetchAndUpdate({ credentials, store }) // Initially there's set flag to silence all desktop notifications so // that there won't spam of them when user just opened up the FE we // reset that flag after a while to show new notifications once again. setTimeout(() => store.dispatch('setNotificationsSilence', false), 10000) - return setInterval(boundFetchAndUpdate, 10000) + const boundFetchAndUpdate = () => fetchAndUpdate({ credentials, store }) + boundFetchAndUpdate() + return promiseInterval(boundFetchAndUpdate, 10000) } const notificationsFetcher = { diff --git a/src/services/promise_interval/promise_interval.js b/src/services/promise_interval/promise_interval.js @@ -0,0 +1,27 @@ + +// promiseInterval - replacement for setInterval for promises, starts counting +// the interval only after a promise is done instead of immediately. +// - promiseCall is a function that returns a promise, it's called the first +// time after the first interval. +// - interval is the interval delay in ms. + +export const promiseInterval = (promiseCall, interval) => { + let stopped = false + let timeout = null + + const func = () => { + promiseCall().finally(() => { + if (stopped) return + timeout = window.setTimeout(func, interval) + }) + } + + const stopFetcher = () => { + stopped = true + window.clearTimeout(timeout) + } + + timeout = window.setTimeout(func, interval) + + return { stop: stopFetcher } +} diff --git a/src/services/timeline_fetcher/timeline_fetcher.service.js b/src/services/timeline_fetcher/timeline_fetcher.service.js @@ -1,6 +1,7 @@ import { camelCase } from 'lodash' import apiService from '../api/api.service.js' +import { promiseInterval } from '../promise_interval/promise_interval.js' const update = ({ store, statuses, timeline, showImmediately, userId, pagination }) => { const ccTimeline = camelCase(timeline) @@ -71,8 +72,9 @@ const startFetching = ({ timeline = 'friends', credentials, store, userId = fals const showImmediately = timelineData.visibleStatuses.length === 0 timelineData.userId = userId fetchAndUpdate({ timeline, credentials, store, showImmediately, userId, tag }) - const boundFetchAndUpdate = () => fetchAndUpdate({ timeline, credentials, store, userId, tag }) - return setInterval(boundFetchAndUpdate, 10000) + const boundFetchAndUpdate = () => + fetchAndUpdate({ timeline, credentials, store, userId, tag }) + return promiseInterval(boundFetchAndUpdate, 10000) } const timelineFetcher = { fetchAndUpdate,