Bluesky app fork with some witchin' additions 💫

Reduce `listConvos` requests (#6378)

* Reduce page size for request

* Remove refetch interval entirely

* Add comment

* Optimistically mark as read

* Drop default active poll interval to 60s from 5min

* Only optimistically update unread count if success

authored by

Eric Bailey and committed by
GitHub
db39f3e9 18aaa19b

+46 -11
+1 -1
src/state/messages/events/const.ts
··· 1 - export const DEFAULT_POLL_INTERVAL = 60e3 * 5 1 + export const DEFAULT_POLL_INTERVAL = 60e3 2 2 export const BACKGROUND_POLL_INTERVAL = 60e3 * 5
+36 -3
src/state/queries/messages/conversation.ts
··· 5 5 import {DM_SERVICE_HEADERS} from '#/state/queries/messages/const' 6 6 import {useOnMarkAsRead} from '#/state/queries/messages/list-converations' 7 7 import {useAgent} from '#/state/session' 8 - import {RQKEY as LIST_CONVOS_KEY} from './list-converations' 8 + import { 9 + ConvoListQueryData, 10 + getConvoFromQueryData, 11 + RQKEY as LIST_CONVOS_KEY, 12 + } from './list-converations' 9 13 10 14 const RQKEY_ROOT = 'convo' 11 15 export const RQKEY = (convoId: string) => [RQKEY_ROOT, convoId] ··· 57 61 if (!convoId) throw new Error('No convoId provided') 58 62 optimisticUpdate(convoId) 59 63 }, 60 - onSettled() { 61 - queryClient.invalidateQueries({queryKey: LIST_CONVOS_KEY}) 64 + onSuccess(_, {convoId}) { 65 + if (!convoId) return 66 + 67 + queryClient.setQueryData(LIST_CONVOS_KEY, (old: ConvoListQueryData) => { 68 + if (!old) return old 69 + 70 + const existingConvo = getConvoFromQueryData(convoId, old) 71 + 72 + if (existingConvo) { 73 + return { 74 + ...old, 75 + pages: old.pages.map(page => { 76 + return { 77 + ...page, 78 + convos: page.convos.map(convo => { 79 + if (convo.id === convoId) { 80 + return { 81 + ...convo, 82 + unreadCount: 0, 83 + } 84 + } 85 + return convo 86 + }), 87 + } 88 + }), 89 + } 90 + } else { 91 + // If we somehow marked a convo as read that doesn't exist in the 92 + // list, then we don't need to do anything. 93 + } 94 + }) 62 95 }, 63 96 }) 64 97 }
+9 -7
src/state/queries/messages/list-converations.tsx
··· 39 39 queryKey: RQKEY, 40 40 queryFn: async ({pageParam}) => { 41 41 const {data} = await agent.api.chat.bsky.convo.listConvos( 42 - {cursor: pageParam}, 42 + {cursor: pageParam, limit: 20}, 43 43 {headers: DM_SERVICE_HEADERS}, 44 44 ) 45 45 ··· 47 47 }, 48 48 initialPageParam: undefined as RQPageParam, 49 49 getNextPageParam: lastPage => lastPage.cursor, 50 - // refetch every 60 seconds since we can't get *all* info from the logs 51 - // i.e. reading chats on another device won't update the unread count 52 - refetchInterval: 60_000, 53 50 }) 54 51 } 55 52 ··· 180 177 }), 181 178 } 182 179 } else { 180 + /** 181 + * We received a message from an conversation old enough that 182 + * it doesn't exist in the query cache, meaning we need to 183 + * refetch and bump the old convo to the top. 184 + */ 183 185 debouncedRefetch() 184 186 } 185 187 }) ··· 245 247 return useMemo(() => { 246 248 return { 247 249 count, 248 - numUnread: count > 0 ? (count > 30 ? '30+' : String(count)) : undefined, 250 + numUnread: count > 0 ? (count > 10 ? '10+' : String(count)) : undefined, 249 251 } 250 252 }, [count]) 251 253 } 252 254 253 - type ConvoListQueryData = { 255 + export type ConvoListQueryData = { 254 256 pageParams: Array<string | undefined> 255 257 pages: Array<ChatBskyConvoListConvos.OutputSchema> 256 258 } ··· 301 303 } 302 304 } 303 305 304 - function getConvoFromQueryData(chatId: string, old: ConvoListQueryData) { 306 + export function getConvoFromQueryData(chatId: string, old: ConvoListQueryData) { 305 307 for (const page of old.pages) { 306 308 for (const convo of page.convos) { 307 309 if (convo.id === chatId) {