diff --git a/src/lib/push_notifications_plugin.js b/src/lib/push_notifications_plugin.js index ad546922d..b3f6885d7 100644 --- a/src/lib/push_notifications_plugin.js +++ b/src/lib/push_notifications_plugin.js @@ -37,7 +37,9 @@ export const piniaPushNotificationsPlugin = ({ store }) => { if (store.$id === 'interface') { if (actionName === 'setNotificationPermission') { permissionGranted = args[0] === 'granted' - } else if (actionName !== 'onLogin' && actionName !== 'onLogout') { + } else if (actionName === 'setLoginStatus') { + user = args[0] + } else { return } } else if (store.$id === 'sync_config') { diff --git a/src/services/chat_utils/chat_utils.js b/src/services/chat_utils/chat_utils.js index bbe74ce09..e99958110 100644 --- a/src/services/chat_utils/chat_utils.js +++ b/src/services/chat_utils/chat_utils.js @@ -3,11 +3,8 @@ import { showDesktopNotification } from '../desktop_notification_utils/desktop_n import { useUsersStore } from 'src/stores/users.js' export const maybeShowChatNotification = (chat) => { - // No messages if (!chat.lastMessage) return - // No unreads to display if (chat.unread === 0) return - // Don't notify on outgoing message (shouldn't happen with condition above) if (useUsersStore().currentUser.id === chat.lastMessage.account_id) return const opts = { diff --git a/src/stores/admin_settings.js b/src/stores/admin_settings.js index 1e47cce2e..f3b845f61 100644 --- a/src/stores/admin_settings.js +++ b/src/stores/admin_settings.js @@ -430,7 +430,7 @@ export const useAdminSettingsStore = defineStore('adminSettings', { }) resultUserIds.data.forEach((userId) => { - useStatusesStore().wipeUserStatuses(userId) + useStatusesStore().wipeUserStatuses(status.user.id) // Users are technically never deleted, just deactivated // so there's no real need to delete them from store. }) diff --git a/src/stores/chats.js b/src/stores/chats.js index 6fcfbcd1e..86ea310ce 100644 --- a/src/stores/chats.js +++ b/src/stores/chats.js @@ -40,8 +40,8 @@ export const useChatsStore = defineStore('chats', { useStreamingStore().addSubscriber(socket) }, startFetching() { - this.fetcher = promiseInterval(() => this.fetchChats(), 5000) - this.fetchChats() + this.fetcher = () => promiseInterval(() => this.fetchChats(), 5000) + this.fetcher() }, stopFetching() { this.fetcher?.stop() @@ -56,6 +56,8 @@ export const useChatsStore = defineStore('chats', { }, resetChats() { this.data = new Map() + this.stopFetching() + this.startFetching() }, addNewChats(result) { useUsersStore().addNewUsers({ @@ -77,15 +79,13 @@ export const useChatsStore = defineStore('chats', { updateChat(updatedChat) { const chat = this.data.get(updatedChat.id) if (chat) { - const isNewMessage = chat.lastMessage !== updatedChat.lastMessage chat.lastMessage = updatedChat.lastMessage chat.unread = updatedChat.unread chat.updated_at = updatedChat.updated_at - if (isNewMessage) maybeShowChatNotification(chat) } else { this.data.set(updatedChat.id, updatedChat) - maybeShowChatNotification(updatedChat) } + maybeShowChatNotification(chat ?? updatedChat) }, deleteChat(id) { this.data.delete(id) diff --git a/src/stores/fetchers/timeline_fetcher.js b/src/stores/fetchers/timeline_fetcher.js index 5737befef..54250318f 100644 --- a/src/stores/fetchers/timeline_fetcher.js +++ b/src/stores/fetchers/timeline_fetcher.js @@ -46,7 +46,7 @@ const timelineFetcher = (timeline, argument, credentials) => { } args.withMuted = !hideMutedPosts - if (loggedIn && REPLY_VISIBILITY_TIMELINES.has(timeline.name)) { + if (loggedIn && REPLY_VISIBILITY_TIMELINES.has(timeline)) { args.replyVisibility = replyVisibility } diff --git a/src/stores/notifications.js b/src/stores/notifications.js index c69e9c164..4f18ccc21 100644 --- a/src/stores/notifications.js +++ b/src/stores/notifications.js @@ -22,41 +22,17 @@ import { import { isStatusNotification } from 'src/services/notification_utils/notification_utils_sw.js' export const defaultState = () => ({ - // Prevents desktop notification spam on startup desktopNotificationSilence: true, - - // Pagination maxId: '', minId: '', - - // Order data: [], - - // TODO: Implement! - // Useful for making notification as seen - // when interacting with status statusNotificationRelations: new WeakMap(), - - // ID to Object notification idStore: new Map(), - - // Reference to WS subscriber + statusIdStore: new Set(), socket: null, - - // Indicates whether notifications receive push updates streaming: false, - - // Indicates whether notifications are SUPPOSED to be fetching - // this is partiualrly useful for when pausing/resuming. I.e. - // whether we need to start fetching again if timeline was resumed. fetching: true, - - // Reference to fetcher, used for polling for new notifications - // and manually fetching old notifications fetcher: null, - - // Whether notifications fetcher has been paused - it stops fetching - // (but still receives pushes!) paused: false, }) diff --git a/src/stores/reports.js b/src/stores/reports.js index 0b0e25380..2d9819442 100644 --- a/src/stores/reports.js +++ b/src/stores/reports.js @@ -19,10 +19,8 @@ export const useReportsStore = defineStore('reports', { actions: { openUserReportingModal({ userId, statusIds = [] }) { const preTickedIds = new Set(statusIds) - // There could be a case (i.e. user is only ever mentioned in someone else's post -> user popover) - // where user has no known posts - const userAllStatusesIds = - useStatusesStore().statusesPerUser.get(userId) ?? new Set() + // There shouldn't be a case where this is undefined + const userAllStatusesIds = useStatusesStore().statusesPerUser.get(userId) // Set constructor should take care of duplicated IDs and order, // later duplicated IDs will be dropped in favor of earlier const sortedIds = new Set([...preTickedIds, ...userAllStatusesIds]) diff --git a/src/stores/statuses.js b/src/stores/statuses.js index ceb51ceb6..8a5938211 100644 --- a/src/stores/statuses.js +++ b/src/stores/statuses.js @@ -534,7 +534,7 @@ export const useStatusesStore = defineStore('statuses', { // For when blocking a user wipeUserStatuses(userId) { - const removed = this.statusesPerUser.get(userId) ?? new Set() + const removed = this.statusesPerUser.get(userId) removed.forEach((statusId) => { const status = this.allStatuses.get(statusId) this.allStatuses.delete(statusId) diff --git a/src/stores/timelines.js b/src/stores/timelines.js index bdd49d05c..562bec21d 100644 --- a/src/stores/timelines.js +++ b/src/stores/timelines.js @@ -8,49 +8,18 @@ import { TIMELINE_STREAM_MAP, useStreamingStore } from 'src/stores/streaming.js' const emptyTl = (name, argument = null) => { const result = { - // Name of the timeline. Useful for debugging and logging name, - - // Order of statuses, important for timelines that - // have different ordering, i.e. bookmarks and favorites order: [], - - // All statuses belonging to the timeline statusIds: new Set(), - - // Statuses shown to user visibleStatusIds: new Set(), - - // Number of statuses not shown yet newStatusCount: 0, - - // Pagination maxId: '', minId: '', - - // Indicates whether timeline receives push updates streaming: false, - - // Indicates whether timeline is SUPPOSED to be fetching - // this is partiualrly useful for when pausing/resuming - // timeline. I.e. whether we need to start fetching again - // if timeline was resumed. fetching: false, - - // Indicates that in recent poll update we've hit more than or - // equal to 20 statuses and most likely missed some statuses - // between polls reloadNeeded: false, - - // Reference to fetcher, used for polling for new statuses and - // manually fetching old statuses fetcher: null, - - // Reference to WS subscriber socket: null, - - // Whether the timeline has been paused - it stops fetching - // (but still receives pushes!) paused: false, } @@ -347,14 +316,6 @@ export const useTimelinesStore = defineStore('timelines', { reason, ) return - } else if (timeline.paused) { - console.debug( - '[Timelines] Deactivating paused timeline', - timelineName, - 'Reason:', - reason, - ) - timeline.fetching = false } else { timeline.fetcher.stopFetching() console.debug( diff --git a/src/stores/users.js b/src/stores/users.js index 1c32ab679..f41f75aa2 100644 --- a/src/stores/users.js +++ b/src/stores/users.js @@ -50,6 +50,7 @@ import { promiseInterval } from 'src/services/promise_interval/promise_interval. export const useUsersStore = defineStore('users', { state: () => ({ loggingIn: false, + lastLoginName: null, currentUser: null, users: new Map(), usersByName: new Map(), @@ -615,6 +616,7 @@ export const useUsersStore = defineStore('users', { user.muteIds = new Set() user.domainMutes = new Set() + this.lastLoginName = user.screen_name useTimelinesStore().deactivateAll() useStatusesStore().resetStatuses() @@ -737,13 +739,13 @@ export const useUsersStore = defineStore('users', { oauth.clearToken() this.currentUser = null + this.lastLoginName = null useNotificationsStore().deactivate() // Full reset on logout success useTimelinesStore().deactivateAll() useStatusesStore().resetStatuses() - useChatsStore().stopFetching() useChatsStore().resetChats() this.users = new Map() @@ -775,7 +777,6 @@ export const useUsersStore = defineStore('users', { useAnnouncementsStore().startFetching() useListsStore().startFetching() useBookmarkFoldersStore().startFetching() - useChatsStore().startFetching() store?.dispatch('startFetchingFollowRequests') }) .finally(() => { @@ -784,4 +785,7 @@ export const useUsersStore = defineStore('users', { }) }, }, + persist: { + paths: ['lastLoginName'], + }, }) diff --git a/test/unit/specs/stores/users.spec.js b/test/unit/specs/stores/users.spec.js index 2709d680a..285359c62 100644 --- a/test/unit/specs/stores/users.spec.js +++ b/test/unit/specs/stores/users.spec.js @@ -679,6 +679,7 @@ describe('Users store', () => { expect(store.usersByName).to.have.length(1) expect(store.usersByURL).to.have.length(1) expect(store.relationships).to.have.length(0) + expect(store.lastLoginName).to.eql(userScreenName) spies.forEach((spy, index) => { expect(spy, `Spy ${index} has failed`).to.have.been.called }) @@ -782,6 +783,7 @@ describe('Users store', () => { expect(store.loggedIn).to.eql(true) await store.logout() expect(store.loggedIn).to.eql(false) + expect(store.lastLoginName).to.eql(null) expect(revokeApi).to.have.been.called expect(store.users).to.have.length(0) expect(store.usersByName).to.have.length(0)