diff --git a/src/components/quick_filter_settings/quick_filter_settings.js b/src/components/quick_filter_settings/quick_filter_settings.js index a629266f8..db4b81af8 100644 --- a/src/components/quick_filter_settings/quick_filter_settings.js +++ b/src/components/quick_filter_settings/quick_filter_settings.js @@ -5,9 +5,9 @@ import Popover from 'src/components/popover/popover.vue' import { useInterfaceStore } from 'src/stores/interface.js' import { useLocalConfigStore } from 'src/stores/local_config.js' import { useMergedConfigStore } from 'src/stores/merged_config.js' -import { useStatusesStore } from 'src/stores/statuses.js' import { useSyncConfigStore } from 'src/stores/sync_config.js' import { useUsersStore } from 'src/stores/users.js' +import { useTimelinesStore } from 'src/stores/timelines.js' import { library } from '@fortawesome/fontawesome-svg-core' import { faFilter, faFont, faWrench } from '@fortawesome/free-solid-svg-icons' @@ -28,7 +28,7 @@ const QuickFilterSettings = { path: 'replyVisibility', value: visibility, }) - useStatusesStore().requireReloadAll() + useTimelinesStore().requireReloadAll() }, openTab(tab) { useInterfaceStore().openSettingsModalTab(tab) diff --git a/src/components/settings_modal/tabs/clutter_tab.js b/src/components/settings_modal/tabs/clutter_tab.js index 18300231c..1b3a41285 100644 --- a/src/components/settings_modal/tabs/clutter_tab.js +++ b/src/components/settings_modal/tabs/clutter_tab.js @@ -11,7 +11,7 @@ import UnitSetting from '../helpers/unit_setting.vue' import { useInstanceStore } from 'src/stores/instance.js' import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js' -import { useStatusesStore } from 'src/stores/statuses.js' +import { useTimelinesStore } from 'src/stores/timelines.js' const ClutterTab = { components: { @@ -36,7 +36,7 @@ const ClutterTab = { // Updating nested properties watch: { replyVisibility() { - useStatusesStore().requireReloadAll() + useTimelinesStore().requireReloadAll() }, }, } diff --git a/src/components/settings_modal/tabs/filtering_tab.js b/src/components/settings_modal/tabs/filtering_tab.js index fbc7b8902..1152aa697 100644 --- a/src/components/settings_modal/tabs/filtering_tab.js +++ b/src/components/settings_modal/tabs/filtering_tab.js @@ -14,7 +14,7 @@ import UnitSetting from '../helpers/unit_setting.vue' import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js' import { useInterfaceStore } from 'src/stores/interface' import { useMergedConfigStore } from 'src/stores/merged_config.js' -import { useStatusesStore } from 'src/stores/statuses.js' +import { useTimelinesStore } from 'src/stores/timelines.js' import { useSyncConfigStore } from 'src/stores/sync_config.js' import { @@ -266,7 +266,7 @@ const FilteringTab = { // Updating nested properties watch: { replyVisibility() { - useStatusesStore().requireReloadAll() + useTimelinesStore().requireReloadAll() }, muteFiltersObject() { this.muteFiltersDraftObject = cloneDeep( diff --git a/src/components/timeline/timeline.js b/src/components/timeline/timeline.js index 85f3172dd..97558bc01 100644 --- a/src/components/timeline/timeline.js +++ b/src/components/timeline/timeline.js @@ -102,7 +102,12 @@ const Timeline = { } }, statusesToDisplay() { - if (!this.virtualScrollingEnabled) return this.visibleStatusIds + if (!this.virtualScrollingEnabled) { + return new Set( + this.filteredVisibleStatuses.map(({ id }) => id), + ) + } + const amount = this.timeline.visibleStatusIds.size const statusesPerSide = Math.ceil(Math.max(3, window.innerHeight / 80)) const min = Math.max(0, this.virtualScrollIndex - statusesPerSide) diff --git a/src/i18n/en.json b/src/i18n/en.json index 8c7379742..0e861fe77 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -1634,7 +1634,6 @@ "no_statuses": "No statuses", "socket_reconnected": "Realtime connection established", "socket_disconnected": "Realtime connection unavaialable", - "socket_closed": "Realtime connection closed", "socket_broke": "Realtime connection lost: CloseEvent code {0}", "quick_view_settings": "Quick view settings", "quick_filter_settings": "Quick filter settings", diff --git a/src/stores/fetchers/notifications_fetcher.js b/src/stores/fetchers/notifications_fetcher.js index a31877072..cde444d91 100644 --- a/src/stores/fetchers/notifications_fetcher.js +++ b/src/stores/fetchers/notifications_fetcher.js @@ -36,7 +36,7 @@ const notificationsFetcher = (credentials) => { const notifications = response.data if (older && notifications.length === 0) bottomedOut.value = true - useNotificationsStore().addNewNotifications(response) + useNotificationsStore().addNewNotifications(response, older) } catch (error) { if ( error.statusCode === 400 && @@ -78,7 +78,7 @@ const notificationsFetcher = (credentials) => { args.timeline = 'notifications' if (older) { - if (timelineData.minId !== Number.POSITIVE_INFINITY) { + if (timelineData.minId !== '') { args.maxId = timelineData.minId } return await fetchNotifications({ args, older }) @@ -86,7 +86,7 @@ const notificationsFetcher = (credentials) => { // fetch new notifications if ( sinceId === undefined && - timelineData.maxId !== Number.POSITIVE_INFINITY + timelineData.maxId !== '' ) { args.sinceId = timelineData.maxId } else if (sinceId !== null) { diff --git a/src/stores/interface.js b/src/stores/interface.js index e87a0ecd9..f2b2d86c7 100644 --- a/src/stores/interface.js +++ b/src/stores/interface.js @@ -134,14 +134,7 @@ export const useInterfaceStore = defineStore('interface', { 1001, // Going away ]) const { code } = closeEvent.original - if (intendedCodes.has(code)) { - this.pushGlobalNotice({ - level: 'success', - messageKey: 'timeline.socket_closed', - messageArgs: [code], - timeout: 5000, - }) - } else { + if (!intendedCodes.has(code)) { this.pushGlobalNotice({ level: 'error', messageKey: 'timeline.socket_broke', diff --git a/src/stores/streaming.js b/src/stores/streaming.js index 5fec7a788..dae047f46 100644 --- a/src/stores/streaming.js +++ b/src/stores/streaming.js @@ -131,6 +131,7 @@ export const useStreamingStore = defineStore('streaming', { }, stopSocket() { this.socket.close() + this.socket = null this.state = WSConnectionStatus.CLOSED this.retrying = false this.retryMultiplier = 1 diff --git a/src/stores/timelines.js b/src/stores/timelines.js index 8d69139bc..801773874 100644 --- a/src/stores/timelines.js +++ b/src/stores/timelines.js @@ -81,6 +81,7 @@ export const ARGUMENT_MAP = { user: 'userId', userPinned: 'userId', media: 'userId', + favorites: 'userId', } const TIMELINES = new Set([ @@ -180,7 +181,7 @@ export const useTimelinesStore = defineStore('timelines', { timeline.socket.handlers timeline.socket.et.removeEventListener('open', openHandler) timeline.socket.et.removeEventListener('close', closeHandler) - timeline.socket.et.removeEventListener('message', messageHandler) + timeline.socket.et.removeEventListener('update', messageHandler) } this[timelineName] = emptyTl(timelineName) @@ -267,8 +268,6 @@ export const useTimelinesStore = defineStore('timelines', { if (statuses.length === 0) return const timeline = this[timelineName] - this.populateRepeats(timeline, repeats) - // This makes sure that user timeline won't get data meant for other // user. I.e. opening different user profiles makes request which could // return data late after user already viewing different user profile @@ -279,6 +278,8 @@ export const useTimelinesStore = defineStore('timelines', { return } + this.populateRepeats(timeline, repeats) + const filtered = statuses.filter((id) => !timeline.statusIds.has(id)) if (older) { timeline.order.push(...filtered) diff --git a/src/stores/users.js b/src/stores/users.js index 90c87c0f3..d3c8ad6cf 100644 --- a/src/stores/users.js +++ b/src/stores/users.js @@ -276,15 +276,21 @@ export const useUsersStore = defineStore('users', { const result = await promise - if (result) { - const { id, screen_name } = result + try { + if (result) { + const { id, screen_name } = result - // Save promise for future use - this.fetchesIds.set(id, promise) - this.fetchesNames.set(screen_name, promise) - return this.users.get(id) - } else { - return null + // Save promise for future use + this.fetchesIds.set(id, promise) + this.fetchesNames.set(screen_name, promise) + return this.users.get(id) + } else { + return null + } + } catch (e) { + console.error(`Failed fetching user ${identifier}`, e) + map.delete(identifier) + throw e } }, async fetchUser(id) { @@ -518,7 +524,7 @@ export const useUsersStore = defineStore('users', { /// Mute muteUser(id, expiresIn = 0) { - const predictedRelationship = this.relationships[id] || { id } + const predictedRelationship = this.relationships.get(id) || { id } predictedRelationship.muting = true this.updateUserRelationships({ optimism: true, @@ -537,7 +543,7 @@ export const useUsersStore = defineStore('users', { return Promise.all(data.map((d) => this.muteUser(d))) }, unmuteUser(id) { - const predictedRelationship = this.relationships[id] || { id } + const predictedRelationship = this.relationships.get(id) || { id } predictedRelationship.muting = false this.updateUserRelationships({ optimism: true, @@ -554,7 +560,7 @@ export const useUsersStore = defineStore('users', { /// Block blockUser(id, expiresIn = 0) { - const predictedRelationship = this.relationships[id] || { id } + const predictedRelationship = this.relationships.get(id) || { id } this.updateUserRelationships({ optimism: true, data: [predictedRelationship],