about summary refs log tree commit diff
path: root/src/state/messages
diff options
context:
space:
mode:
authorSamuel Newman <mozzius@protonmail.com>2025-02-03 14:37:24 -0800
committerGitHub <noreply@github.com>2025-02-03 22:37:24 +0000
commit32b28d666229ac24cf7b1ac328d1566fb089e1a1 (patch)
tree2e721117c9a859ca1cae52e1c15642d5e6db4d5b /src/state/messages
parentfa8607b861e0719d76778aa14af0745313640e33 (diff)
downloadvoidsky-32b28d666229ac24cf7b1ac328d1566fb089e1a1.tar.zst
Fix convo header loading state (#7603)
* get initial convo state from cache

* undo useConvoQuery changes

* fix shadowing situation with new hook
Diffstat (limited to 'src/state/messages')
-rw-r--r--src/state/messages/convo/agent.ts32
-rw-r--r--src/state/messages/convo/index.tsx25
-rw-r--r--src/state/messages/convo/types.ts15
3 files changed, 50 insertions, 22 deletions
diff --git a/src/state/messages/convo/agent.ts b/src/state/messages/convo/agent.ts
index 53d77046a..91dd59813 100644
--- a/src/state/messages/convo/agent.ts
+++ b/src/state/messages/convo/agent.ts
@@ -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()
diff --git a/src/state/messages/convo/index.tsx b/src/state/messages/convo/index.tsx
index 10ec2a348..a1750bdf0 100644
--- a/src/state/messages/convo/index.tsx
+++ b/src/state/messages/convo/index.tsx
@@ -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()
 
diff --git a/src/state/messages/convo/types.ts b/src/state/messages/convo/types.ts
index 21772262e..9f1707c71 100644
--- a/src/state/messages/convo/types.ts
+++ b/src/state/messages/convo/types.ts
@@ -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