fix(web): update unread total immediately upon archiving (#982)

This commit is contained in:
Pujit Mehrotra
2024-12-13 12:28:56 -05:00
committed by GitHub
parent ef82ec5af5
commit 29d9371cc3

View File

@@ -1,5 +1,8 @@
import { InMemoryCache, type InMemoryCacheConfig } from '@apollo/client/core/index.js';
import { getNotifications } from '~/components/Notifications/graphql/notification.query';
import {
getNotifications,
notificationsOverview,
} from '~/components/Notifications/graphql/notification.query';
import { NotificationType, type NotificationOverview } from '~/composables/gql/graphql';
import { NotificationType as NotificationCacheType } from '~/composables/gql/typename';
import { mergeAndDedup } from './merge';
@@ -109,6 +112,7 @@ const defaultCacheConfig: InMemoryCacheConfig = {
},
archiveNotification: {
/**
* Optimistically decrements unread total from overview &
* Ensures newly archived notifications appear in the archive list without a page reload.
*
* When a notification is archived, we need to evict the cached archive list to force a refetch.
@@ -119,11 +123,13 @@ const defaultCacheConfig: InMemoryCacheConfig = {
* Note: This may cause temporary jitter with infinite scroll.
*
* This function:
* 1. Checks if the cache has an archive list. If not, this function is a no-op.
* 2. If the list has items, evicts just the archive list
* 3. If it is empty, evicts the entire notifications cache
* 4. Runs garbage collection to clean up orphaned references
* 5. Returns the original mutation result
*
* 1. Optimistically updates notification overview
* 2. Checks if the cache has an archive list. If not, this function is a no-op.
* 3. If the list has items, evicts just the archive list
* 4. If it is empty, evicts the entire notifications cache
* 5. Runs garbage collection to clean up orphaned references
* 6. Returns the original mutation result
*
* @param _ - Existing cache value (unused)
* @param incoming - Result (i.e. the archived notification) from the server after archiving
@@ -131,6 +137,13 @@ const defaultCacheConfig: InMemoryCacheConfig = {
* @returns The incoming result to be cached
*/
merge(_, incoming, { cache }) {
cache.updateQuery({ query: notificationsOverview }, (data) => {
if (!data) return;
const update = structuredClone(data);
update.notifications.overview.unread.total--;
return update;
});
const archiveQuery = cache.readQuery({
query: getNotifications,
// @ts-expect-error the cache only uses the filter type; the limit & offset are superfluous.
@@ -147,7 +160,6 @@ const defaultCacheConfig: InMemoryCacheConfig = {
args: { filter: { type: NotificationType.Archive } },
});
}
cache.gc();
return incoming;
},