diff --git a/changelog.d/avatar_mentions.change b/changelog.d/avatar_mentions.change deleted file mode 100644 index f75f02ea4..000000000 --- a/changelog.d/avatar_mentions.change +++ /dev/null @@ -1 +0,0 @@ -If user avatars next to mentions are enabled it will show empty placeholder avatar next to label while user is being fetched, to avoid jumps diff --git a/src/boot/after_store.js b/src/boot/after_store.js index f411235f3..3f2033ecc 100644 --- a/src/boot/after_store.js +++ b/src/boot/after_store.js @@ -29,6 +29,7 @@ import { import routes from './routes' import { useAuthFlowStore } from 'src/stores/auth_flow' +import { useChatsStore } from 'src/stores/chats.js' import { useEmojiStore } from 'src/stores/emoji.js' import { useI18nStore } from 'src/stores/i18n' import { useInstanceStore } from 'src/stores/instance.js' @@ -593,6 +594,7 @@ const afterStoreSetup = async ({ pinia, store, storageError, i18n }) => { useI18nStore().setI18n(i18n) // Global WS handlers + useChatsStore().attachSocket() useInterfaceStore().attachSocket() useStatusesStore().attachSocket() diff --git a/src/components/chat_view/chat_view.js b/src/components/chat_view/chat_view.js index ab655cc39..29b6c51a3 100644 --- a/src/components/chat_view/chat_view.js +++ b/src/components/chat_view/chat_view.js @@ -89,14 +89,15 @@ const Chat = { fetcher: null, socket: null, streaming: false, + fetching: true, errorLoadingChat: false, messageRetriers: {}, idempotencyKeyIndex: {}, } }, - created() { + async created() { if (this.testMode) return - this.activate() + await this.activate() this.attachSocket() }, mounted() { @@ -243,10 +244,11 @@ const Chat = { accountId: this.chatUserId, credentials: useOAuthStore().token, }) - useUsersStore().addNewUsers(result) const { data } = result + useUsersStore().addNewUsers({ ...result, data: data.account }) data.account = useUsersStore().findUser(data.account.id) this.chat = data + this.maxId = this.chat.lastMessage?.id } catch (e) { console.error('Error creating or getting a chat', e) this.errorLoadingChat = true @@ -254,33 +256,38 @@ const Chat = { } if (this.isConversation || this.chat) { + this.startFetching('Chat activated', true) this.$nextTick(() => { this.scrollDown({ forceRead: true }) }) - this.startFetching('Chat activated', true) } }, deactivate() { this.clear() - if (!this.streaming) { - this.stopFetching() + if (this.fetching) { + this.stopFetching('Chat deactivated') } }, attachSocket() { const et = new EventTarget() - const socket = { et } + const socket = { + name: 'chatview', + et, + } et.addEventListener('update', this.onStreamMessage) + et.addEventListener('pleroma:chat_update', this.onChatUpdate) et.addEventListener('open', this.onStreamConnect) et.addEventListener('close', this.onStreamDisconnect) - useStreamingStore().addSubscriber(socket) this.socket = socket + useStreamingStore().addSubscriber(this.socket) }, detachSocket() { const { et } = this.socket et.removeEventListener('update', this.onStreamMessage) + et.removeEventListener('pleroma:chat_update', this.onChatUpdate) et.removeEventListener('open', this.onStreamConnect) et.removeEventListener('close', this.onStreamDisconnect) @@ -303,11 +310,13 @@ const Chat = { 5000, ) this.fetchChat({ isFirstFetch }) + this.fetching = true }, stopFetching(reason) { console.debug('[Chat View] Stopped fetching', 'Reason:', reason) this.fetcher.stop() this.fetcher = null + this.fetching = false }, // Actions @@ -437,6 +446,10 @@ const Chat = { ) this.addMessages({ messages }) }, + onChatUpdate({ data: { chatUpdate } }) { + const messages = [chatUpdate.lastMessage] + this.addMessages({ messages }) + }, addMessages({ messages: newMessages }) { for (let i = 0; i < newMessages.length; i++) { const message = newMessages[i] diff --git a/src/components/conversation/conversation.js b/src/components/conversation/conversation.js index 3202a79c9..8fd39aa1d 100644 --- a/src/components/conversation/conversation.js +++ b/src/components/conversation/conversation.js @@ -155,9 +155,9 @@ const conversation = { return this.otherRepliesButtonPosition === 'inside' }, suspendable() { - return this.unsuspendibleIds.size > 0 + return this.unsuspendibleIds.size === 0 }, - hideStatus() { + hide() { return this.virtualHidden && this.suspendable }, originalStatusId() { @@ -365,7 +365,6 @@ const conversation = { return !!(this.expanded || this.isPage) }, hiddenStyle() { - if (this.isExpanded || !this.virtualHidden) return {} return { height: this.virtualHeight + 'px' } }, threadDisplayStatus() { @@ -621,6 +620,7 @@ const conversation = { } }, updateVirtualHeight() { + if (this.hide) return // no updates when not rendering this.$nextTick(() => { this.virtualHeight = this.$refs.body.getBoundingClientRect().height this.$emit('update:virtualHeight', { diff --git a/src/components/conversation/conversation.vue b/src/components/conversation/conversation.vue index cc1376978..94c4db188 100644 --- a/src/components/conversation/conversation.vue +++ b/src/components/conversation/conversation.vue @@ -1,7 +1,6 @@ diff --git a/src/components/timeline/timeline.js b/src/components/timeline/timeline.js index 029693651..3c7e33060 100644 --- a/src/components/timeline/timeline.js +++ b/src/components/timeline/timeline.js @@ -239,7 +239,7 @@ const Timeline = { const bodyBRect = document.body.getBoundingClientRect() const height = Math.max(bodyBRect.height, -bodyBRect.y) if ( - !this.timeline.fetcher.loadingOlder.value && + !this.timeline.fetcher.loadingOlder && window.innerHeight + window.pageYOffset >= height - 750 ) { this.fetchOlderStatuses() diff --git a/src/components/user_avatar/user_avatar.js b/src/components/user_avatar/user_avatar.js index c8701fe66..b80aa8fb8 100644 --- a/src/components/user_avatar/user_avatar.js +++ b/src/components/user_avatar/user_avatar.js @@ -12,7 +12,7 @@ const UserAvatar = { props: { // UserID of a user to show avatar of userId: { - required: false, // You can pass null to just render a placeholder + required: true, type: String, }, // Use less space and use alternative roundness diff --git a/src/components/user_avatar/user_avatar.vue b/src/components/user_avatar/user_avatar.vue index 613d224a0..d9e96d52d 100644 --- a/src/components/user_avatar/user_avatar.vue +++ b/src/components/user_avatar/user_avatar.vue @@ -70,7 +70,6 @@ &.-placeholder { background-color: var(--background); - border: 1px solid var(--border) } } diff --git a/src/components/who_to_follow_panel/who_to_follow_panel.js b/src/components/who_to_follow_panel/who_to_follow_panel.js index b87004e44..0f7f93556 100644 --- a/src/components/who_to_follow_panel/who_to_follow_panel.js +++ b/src/components/who_to_follow_panel/who_to_follow_panel.js @@ -30,8 +30,8 @@ function showWhoToFollow(panel, reply) { }) } -function getWhoToFollow(panel) { - const credentials = panel.$useUsersStore().currentUser.credentials +function getWhoToFollow() { + const credentials = useOAuthStore().token if (credentials) { panel.usersToFollow.forEach((toFollow) => { toFollow.name = 'Loading...' @@ -66,7 +66,7 @@ const WhoToFollowPanel = { watch: { user: function () { if (this.suggestionsEnabled) { - getWhoToFollow(this) + getWhoToFollow() } }, }, @@ -77,7 +77,7 @@ const WhoToFollowPanel = { id: 0, })) if (this.suggestionsEnabled) { - getWhoToFollow(this) + getWhoToFollow() } }, } diff --git a/src/services/chat_utils/chat_utils.js b/src/services/chat_utils/chat_utils.js index d99c17ed8..a5c0d67cd 100644 --- a/src/services/chat_utils/chat_utils.js +++ b/src/services/chat_utils/chat_utils.js @@ -11,13 +11,14 @@ export const maybeShowChatNotification = (chat) => { title: chat.account.name, icon: chat.account.profile_image_url, body: chat.lastMessage.content, + type: 'chatMention', } if (chat.lastMessage.attachment?.type === 'image') { opts.image = chat.lastMessage.attachment.preview_url } - showDesktopNotification(window.vuex.state, opts) + showDesktopNotification(opts) } export const buildFakeMessage = ({ diff --git a/src/services/status_poster/status_poster.service.js b/src/services/status_poster/status_poster.service.js index 00b8699ac..41038573d 100644 --- a/src/services/status_poster/status_poster.service.js +++ b/src/services/status_poster/status_poster.service.js @@ -2,7 +2,7 @@ import { map } from 'lodash' import { useStatusesStore } from 'src/stores/statuses.js' import { useTimelinesStore } from 'src/stores/timelines.js' -import { useUsersStore } from 'src/stores/users.js' +import { useOAuthStore } from 'src/stores/oauth.js' import { editStatus as apiEditStatus, @@ -28,7 +28,7 @@ const postStatus = ({ const mediaIds = map(media, 'id') return apiPostStatus({ - credentials: useUsersStore().currentUser.credentials, + credentials: useOAuthStore().token, status, spoilerText, visibility, @@ -71,7 +71,7 @@ const editStatus = ({ return apiEditStatus({ id: statusId, - credentials: useUsersStore().currentUser.credentials, + credentials: useOAuthStore().token, status, spoilerText, sensitive, @@ -101,12 +101,12 @@ const editStatus = ({ } const uploadMedia = ({ store, formData }) => { - const credentials = useUsersStore().currentUser.credentials + const credentials = useOAuthStore().token return apiUploadMedia({ credentials, formData }).then(({ data }) => data) } const setMediaDescription = ({ store, id, description }) => { - const credentials = useUsersStore().currentUser.credentials + const credentials = useOAuthStore().token return apiSetMediaDescription({ credentials, id, description }).then( ({ data }) => data, ) diff --git a/src/stores/chats.js b/src/stores/chats.js index 9da01c76b..82bb638dd 100644 --- a/src/stores/chats.js +++ b/src/stores/chats.js @@ -37,7 +37,10 @@ export const useChatsStore = defineStore('chats', { actions: { attachSocket() { const et = new EventTarget() - const socket = { et } + const socket = { + name: 'chats', + et, + } et.addEventListener('pleroma:chat_update', this.updateChat) @@ -83,9 +86,6 @@ export const useChatsStore = defineStore('chats', { chat.lastMessage = updatedChat.lastMessage chat.unread = updatedChat.unread chat.updated_at = updatedChat.updated_at - if (isNewMessage && chat.unread) { - maybeShowChatNotification(chat) - } } else { this.chatList.data.push(updatedChat) this.chatList.idStore[updatedChat.id] = updatedChat @@ -98,16 +98,16 @@ export const useChatsStore = defineStore('chats', { chat.unread = 0 } }, - updateChat({ chat: updatedChat }) { + updateChat({ data: { chatUpdate: updatedChat } }) { const chat = getChatById(this, updatedChat.id) if (chat) { chat.lastMessage = updatedChat.lastMessage chat.unread = updatedChat.unread chat.updated_at = updatedChat.updated_at - } - if (!chat) { + } else { this.chatList.data.unshift(updatedChat) } + maybeShowChatNotification(chat) this.chatList.idStore[updatedChat.id] = updatedChat }, deleteChat(id) { diff --git a/src/stores/instance.js b/src/stores/instance.js index 123f0b819..12480e8c1 100644 --- a/src/stores/instance.js +++ b/src/stores/instance.js @@ -14,6 +14,7 @@ import { import { useInterfaceStore } from 'src/stores/interface.js' import { useUsersStore } from 'src/stores/users.js' +import { useOAuthStore } from 'src/stores/oauth.js' import { fetchKnownDomains } from 'src/api/public.js' @@ -213,7 +214,7 @@ export const useInstanceStore = defineStore('instance', { async getKnownDomains() { try { const { data } = await fetchKnownDomains({ - credentials: useUsersStore().currentUser.credentials, + credentials: useOAuthStore().token }) this.knownDomains = data } catch (e) { diff --git a/src/stores/interface.js b/src/stores/interface.js index 0eba6f158..e87a0ecd9 100644 --- a/src/stores/interface.js +++ b/src/stores/interface.js @@ -96,7 +96,10 @@ export const useInterfaceStore = defineStore('interface', { actions: { attachSocket() { const et = new EventTarget() - const socket = { et } + const socket = { + name: 'interface', + et, + } et.addEventListener('open', this.onStreamConnect) et.addEventListener('close', this.onStreamDisconnect) @@ -854,7 +857,7 @@ export const useInterfaceStore = defineStore('interface', { }, unregisterPushNotifications() { - const token = this.currentUser.credentials + const token = useOAuthStore().token unregisterPushNotifications(token) }, diff --git a/src/stores/notifications.js b/src/stores/notifications.js index a12ce8133..3405fb352 100644 --- a/src/stores/notifications.js +++ b/src/stores/notifications.js @@ -31,7 +31,9 @@ export const defaultState = () => ({ statusIdStore: new Set(), socket: null, streaming: false, + fetching: true, fetcher: null, + paused: false, }) export const useNotificationsStore = defineStore('notifications', { @@ -40,14 +42,29 @@ export const useNotificationsStore = defineStore('notifications', { // Init attachSocket() { const et = new EventTarget() - const socket = { et } + const socket = { + name: 'notifications', + et, + } et.addEventListener('notification', this.addNewNotifications) et.addEventListener('open', this.onStreamConnect) et.addEventListener('close', this.onStreamDisconnect) - useStreamingStore().addSubscriber(socket) this.socket = socket + useStreamingStore().addSubscriber(this.socket) + }, + pause() { + this.paused = true + if (this.fetcher && this.fetching) { + this.stopFetching('Notifications paused') + } + }, + resume() { + this.paused = false + if (this.fetcher && this.fetching) { + this.startFetching('Notifications resumed') + } }, activate() { this.attachSocket() @@ -62,7 +79,7 @@ export const useNotificationsStore = defineStore('notifications', { this.startFetching('Notifications activated') }, deactivate() { - if (!this.streaming) { + if (this.fetching) { this.stopFetching('Notifications deactivated') } @@ -77,6 +94,7 @@ export const useNotificationsStore = defineStore('notifications', { Object.keys(blankState).forEach((k) => { this[k] = blankState[k] }) + console.log('[Notifications] Deactivated', this.fetcher) }, // Poll & Push @@ -91,20 +109,30 @@ export const useNotificationsStore = defineStore('notifications', { this.startFetching('Socket disconnected') }, startFetching(reason) { + if (this.paused) { + console.debug( + '[Notificatiosn] NOT Starting notifications fetcher because it is paused', + 'Original Reason:', + reason, + ) + return + } console.debug( - '[Notifications] Starting fetching notifications', + '[Notifications] Starting notifications fetcher', 'Reason:', reason, ) this.fetcher.startFetching() + this.fetching = true }, stopFetching(reason) { + this.fetcher.stopFetching() + this.fetching = false console.debug( - '[Notifications] Stopped fetching notifications', + '[Notifications] Stopped notifications fetcher', 'Reason:', reason, ) - this.fetcher.stopFetching() }, // Updates @@ -223,7 +251,7 @@ export const useNotificationsStore = defineStore('notifications', { case 'follow_request': break default: - this.markSingleNotificationAsSeen({ id }) + this.markSingleNotificationAsSeen(id) } } }, diff --git a/src/stores/search.js b/src/stores/search.js index ad85712c4..cd7862d23 100644 --- a/src/stores/search.js +++ b/src/stores/search.js @@ -19,7 +19,7 @@ export const useSearchStore = defineStore('search', { credentials: useOAuthStore().token, }) - const { accounts, statuses } = data + const { accounts, statuses, hashtags } = data useUsersStore().addNewUsers({ ...rest, @@ -36,6 +36,7 @@ export const useSearchStore = defineStore('search', { useStatusesStore().allStatuses.get(s.id), ) output.accounts = accounts.map((s) => useUsersStore().findUser(s.id)) + output.hashtags = hashtags ?? [] return output }, diff --git a/src/stores/statuses.js b/src/stores/statuses.js index 8836a0a77..337cb399d 100644 --- a/src/stores/statuses.js +++ b/src/stores/statuses.js @@ -49,6 +49,7 @@ export const useStatusesStore = defineStore('statuses', { data.forEach((id) => this.setDeleted(id)) const socket = { + name: 'statuses', et, handlers: { handleUpdate, @@ -64,15 +65,9 @@ export const useStatusesStore = defineStore('statuses', { this.socket = socket }, resetStatuses() { - this.socket.et.removeEventListener('update', this.socket.handleUpdate) - this.socket.et.removeEventListener( - 'status.update', - this.socket.handleUpdate, - ) - this.socket.et.removeEventListener('delete', this.socket.handleDelete) - const emptyState = defaultState() Object.entries(emptyState).forEach(([key, value]) => { + if (key === 'socket') return this[key] = value }) }, @@ -154,7 +149,7 @@ export const useStatusesStore = defineStore('statuses', { const newStatus = { ...old, - ...neu, + ...Object.fromEntries(Object.entries(neu).filter(([, v]) => v !== undefined)), user, } diff --git a/src/stores/streaming.js b/src/stores/streaming.js index 5129a571d..1b4d07292 100644 --- a/src/stores/streaming.js +++ b/src/stores/streaming.js @@ -131,6 +131,7 @@ export const useStreamingStore = defineStore('streaming', { }, getSubArgs(stream) { + if (stream === undefined) return undefined const argumentKey = ARGUMENT_MAP[stream.name] const args = argumentKey ? { diff --git a/src/stores/timelines.js b/src/stores/timelines.js index fe098587a..190396f48 100644 --- a/src/stores/timelines.js +++ b/src/stores/timelines.js @@ -16,9 +16,11 @@ const emptyTl = (name, argument = null) => { maxId: '', minId: '', streaming: false, + fetching: false, reloadNeeded: false, fetcher: null, socket: null, + paused: false, } const property = ARGUMENT_MAP[name] @@ -105,16 +107,16 @@ export const useTimelinesStore = defineStore('timelines', { const openHandler = () => this.onStreamConnect(timelineName, argument) const closeHandler = () => this.onStreamDisconnect(timelineName, argument) - const messageHandler = - () => - ({ detail: message }) => - this.onStreamMessage(timelineName, argument, message) + const messageHandler = (message) => { + this.onStreamMessage(timelineName, argument, message) + } et.addEventListener('open', openHandler) et.addEventListener('close', closeHandler) et.addEventListener('update', messageHandler) timeline.socket = { + name: 'timelines', stream: { name: streamName, argument, @@ -133,7 +135,7 @@ export const useTimelinesStore = defineStore('timelines', { deactivate(timelineName, persistent) { const timeline = this[timelineName] if (timeline.persistent && !persistent) return - if (!timeline.streaming) { + if (timeline.fetching) { this.stopFetchingTimeline(timelineName, 'Timeline deactivation') } @@ -177,6 +179,48 @@ export const useTimelinesStore = defineStore('timelines', { }) }, + // Pause + pause(name) { + const timeline = this[name] + timeline.paused = true + console.debug( + '[Timelines] Pausing timeline', + name, + ) + if (timeline.fetcher && timeline.fetching) { + timeline.fetcher.stopFetching() + } + }, + resume(name) { + const timeline = this[name] + timeline.paused = false + console.debug( + '[Timelines] Resuming timeline', + name, + ) + if (timeline.fetcher && timeline.fetching) { + timeline.fetcher.startFetching() + } + }, + pauseAll() { + TIMELINES.forEach((name) => { + try { + this.pause(name) + } catch (e) { + console.error(`[Timelines] Failed to pause timeline ${name}:`, e) + } + }) + }, + resumeAll() { + TIMELINES.forEach((name) => { + try { + this.resume(name) + } catch (e) { + console.error(`[Timelines] Failed to pause timeline ${name}:`, e) + } + }) + }, + // Update stuff addStatusesToTimeline( timelineName, @@ -231,7 +275,7 @@ export const useTimelinesStore = defineStore('timelines', { }, onStreamMessage(timeline, argument, event) { this.addStatusesToTimeline(timeline, argument, { - statuses: [event.data.status.id], + statuses: event.data.map(({ id }) => id), }) }, @@ -247,15 +291,28 @@ export const useTimelinesStore = defineStore('timelines', { this.startFetchingTimeline(timeline, argument, 'Socket disconnected') }, startFetchingTimeline(timelineName, argument, reason) { + const timeline = this[timelineName] + console.log('[Timelines]', toValue(timeline)) + if (timeline.paused) { + console.debug( + '[Timelines] NOT Starting timeline fetcher because it is paused', + timelineName, + argument, + 'Original Reason:', + reason, + ) + return + } + console.debug( - '[Timelines] Starting fetching timeline', + '[Timelines] Starting timeline fetcher', timelineName, argument, 'Reason:', reason, ) - const timeline = this[timelineName] timeline.fetcher.startFetching() + timeline.fetching = true }, stopFetchingTimeline(timelineName, reason) { const timeline = this[timelineName] @@ -275,6 +332,7 @@ export const useTimelinesStore = defineStore('timelines', { 'Reason:', reason, ) + timeline.fetching = false } }, diff --git a/src/stores/users.js b/src/stores/users.js index 10d9222c9..9b824bf04 100644 --- a/src/stores/users.js +++ b/src/stores/users.js @@ -2,6 +2,8 @@ import Cookies from 'js-cookie' import { last } from 'lodash' import { defineStore } from 'pinia' +import { WSConnectionStatus } from 'src/api/websocket.js' + import { useAnnouncementsStore } from 'src/stores/announcements.js' import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders.js' import { useChatsStore } from 'src/stores/chats.js' @@ -615,12 +617,15 @@ export const useUsersStore = defineStore('users', { user.domainMutes = new Set() this.lastLoginName = user.screen_name - this.currentUser = user + useTimelinesStore().deactivateAll() + useStatusesStore().resetStatuses() this.users = new Map() this.usersByName = new Map() this.usersByURL = new Map() this.relationships = new Map() + this.currentUser = user + this.addNewUsers({ data: user, ...rest }) useInterfaceStore().onLogin() useSyncConfigStore() @@ -634,7 +639,6 @@ export const useUsersStore = defineStore('users', { }) useUserHighlightStore().initUserHighlight(user) - this.addNewUsers({ data: user, ...rest }) useEmojiStore().fetchEmoji() @@ -660,8 +664,8 @@ export const useUsersStore = defineStore('users', { } // DMs and Home - useNotificationsStore().activate() useTimelinesStore().activatePersistents() + useNotificationsStore().activate() if (useInstanceCapabilitiesStore().pleromaChatMessagesAvailable) { // Start fetching chats @@ -708,6 +712,16 @@ export const useUsersStore = defineStore('users', { const store = window.vuex const oauth = useOAuthStore() + // Pause fetching + useNotificationsStore().pause() + useTimelinesStore().pauseAll() + + // Pause-less stores + useAnnouncementsStore().stopFetching() + useListsStore().stopFetching() + useBookmarkFoldersStore().stopFetching() + store?.dispatch('stopFetchingFollowRequests') + // NOTE: No need to verify the app still exists, because if it doesn't, // the token will be invalid too return oauth @@ -722,28 +736,53 @@ export const useUsersStore = defineStore('users', { return revokeToken(params) }) .then(() => { + oauth.clearToken() + this.currentUser = null this.lastLoginName = null + useNotificationsStore().deactivate() + + // Full reset on logout success + useTimelinesStore().deactivateAll() + useStatusesStore().resetStatuses() + useChatsStore().resetChats() + this.users = new Map() this.usersByName = new Map() this.usersByURL = new Map() this.relationships = new Map() - useNotificationsStore().deactivate() - useAnnouncementsStore().stopFetching() - useListsStore().stopFetching() - useBookmarkFoldersStore().stopFetching() - store?.dispatch('stopFetchingFollowRequests') - useTimelinesStore().deactivateAll() - useStatusesStore().resetStatuses() - if (useMergedConfigStore().mergedConfig.useStreamingApi) { + + // Socket is most likely already closed by server + if ( + useMergedConfigStore().mergedConfig.useStreamingApi + && useStreamingStore().state !== WSConnectionStatus.CLOSED + ) { useStreamingStore().stopSocket() } - useChatsStore().resetChats() - oauth.clearToken() + Cookies.remove('__Host-pleroma_key', { path: '/' }) useInterfaceStore().onLogout() }) + .catch((e) => { + useInterfaceStore().pushGlobalNotice({ + messageKey: 'user.logout_failure', + messageArgs: { + error: e, + }, + level: 'error', + }) + console.error('Logout error!', e) + + useAnnouncementsStore().startFetching() + useListsStore().startFetching() + useBookmarkFoldersStore().startFetching() + store?.dispatch('startFetchingFollowRequests') + }) + .finally(() => { + useNotificationsStore().resume() + useTimelinesStore().resumeAll() + }) }, }, persist: { diff --git a/test/unit/specs/components/rich_content.spec.js b/test/unit/specs/components/rich_content.spec.js index 81ce72e87..19bfdc035 100644 --- a/test/unit/specs/components/rich_content.spec.js +++ b/test/unit/specs/components/rich_content.spec.js @@ -354,13 +354,11 @@ describe('RichContent', () => { '', '', '', - '', 'https://', '', 'lol.tld/', '', '', - '', '', '', '', @@ -420,25 +418,21 @@ describe('RichContent', () => { '', '', '', - '', 'https://', '', 'lol.tld/', '', '', - '', '', '', '', '', '', - '', 'https://', '', 'lol.tld/', '', '', - '', '', '', '',