Fix convo header loading state (#7603)

* get initial convo state from cache

* undo useConvoQuery changes

* fix shadowing situation with new hook
This commit is contained in:
Samuel Newman
2025-02-03 14:37:24 -08:00
committed by GitHub
parent fa8607b861
commit 32b28d6662
11 changed files with 174 additions and 84 deletions
+25 -7
View File
@@ -81,7 +81,7 @@ export class Convo {
convoId: string
convo: ChatBskyConvoDefs.ConvoView | undefined
sender: AppBskyActorDefs.ProfileViewBasic | undefined
recipients: AppBskyActorDefs.ProfileViewBasic[] | undefined = undefined
recipients: AppBskyActorDefs.ProfileViewBasic[] | undefined
snapshot: ConvoState | undefined
constructor(params: ConvoParams) {
@@ -91,6 +91,10 @@ export class Convo {
this.events = params.events
this.senderUserDid = params.agent.session?.did!
if (params.placeholderData) {
this.setupPlaceholderData(params.placeholderData)
}
this.subscribe = this.subscribe.bind(this)
this.getSnapshot = this.getSnapshot.bind(this)
this.sendMessage = this.sendMessage.bind(this)
@@ -131,10 +135,10 @@ export class Convo {
return {
status: ConvoStatus.Initializing,
items: [],
convo: undefined,
convo: this.convo,
error: undefined,
sender: undefined,
recipients: undefined,
sender: this.sender,
recipients: this.recipients,
isFetchingHistory: this.isFetchingHistory,
deleteMessage: undefined,
sendMessage: undefined,
@@ -176,10 +180,10 @@ export class Convo {
return {
status: ConvoStatus.Uninitialized,
items: [],
convo: undefined,
convo: this.convo,
error: undefined,
sender: undefined,
recipients: undefined,
sender: this.sender,
recipients: this.recipients,
isFetchingHistory: false,
deleteMessage: undefined,
sendMessage: undefined,
@@ -424,6 +428,20 @@ export class Convo {
}
}
/**
* Initialises the convo with placeholder data, if provided. We still refetch it before rendering the convo,
* but this allows us to render the convo header immediately.
*/
private setupPlaceholderData(
data: NonNullable<ConvoParams['placeholderData']>,
) {
this.convo = data.convo
this.sender = data.convo.members.find(m => m.did === this.senderUserDid)
this.recipients = data.convo.members.filter(
m => m.did !== this.senderUserDid,
)
}
private async setup() {
try {
const {convo, sender, recipients} = await this.fetchConvo()
+16 -9
View File
@@ -1,4 +1,5 @@
import React, {useContext, useState, useSyncExternalStore} from 'react'
import {ChatBskyConvoDefs} from '@atproto/api'
import {useFocusEffect} from '@react-navigation/native'
import {useQueryClient} from '@tanstack/react-query'
@@ -14,7 +15,10 @@ import {
} from '#/state/messages/convo/types'
import {isConvoActive} from '#/state/messages/convo/util'
import {useMessagesEventBus} from '#/state/messages/events'
import {useMarkAsReadMutation} from '#/state/queries/messages/conversation'
import {
RQKEY as getConvoKey,
useMarkAsReadMutation,
} from '#/state/queries/messages/conversation'
import {RQKEY as ListConvosQueryKey} from '#/state/queries/messages/list-conversations'
import {RQKEY as createProfileQueryKey} from '#/state/queries/profile'
import {useAgent} from '#/state/session'
@@ -60,14 +64,17 @@ export function ConvoProvider({
const queryClient = useQueryClient()
const agent = useAgent()
const events = useMessagesEventBus()
const [convo] = useState(
() =>
new Convo({
convoId,
agent,
events,
}),
)
const [convo] = useState(() => {
const placeholder = queryClient.getQueryData<ChatBskyConvoDefs.ConvoView>(
getConvoKey(convoId),
)
return new Convo({
convoId,
agent,
events,
placeholderData: placeholder ? {convo: placeholder} : undefined,
})
})
const service = useSyncExternalStore(convo.subscribe, convo.getSnapshot)
const {mutate: markAsRead} = useMarkAsReadMutation()
+9 -6
View File
@@ -11,6 +11,9 @@ export type ConvoParams = {
convoId: string
agent: BskyAgent
events: MessagesEventBus
placeholderData?: {
convo: ChatBskyConvoDefs.ConvoView
}
}
export enum ConvoStatus {
@@ -142,10 +145,10 @@ type FetchMessageHistory = () => Promise<void>
export type ConvoStateUninitialized = {
status: ConvoStatus.Uninitialized
items: []
convo: undefined
convo: ChatBskyConvoDefs.ConvoView | undefined
error: undefined
sender: undefined
recipients: undefined
sender: AppBskyActorDefs.ProfileViewBasic | undefined
recipients: AppBskyActorDefs.ProfileViewBasic[] | undefined
isFetchingHistory: false
deleteMessage: undefined
sendMessage: undefined
@@ -154,10 +157,10 @@ export type ConvoStateUninitialized = {
export type ConvoStateInitializing = {
status: ConvoStatus.Initializing
items: []
convo: undefined
convo: ChatBskyConvoDefs.ConvoView | undefined
error: undefined
sender: undefined
recipients: undefined
sender: AppBskyActorDefs.ProfileViewBasic | undefined
recipients: AppBskyActorDefs.ProfileViewBasic[] | undefined
isFetchingHistory: boolean
deleteMessage: undefined
sendMessage: undefined