about summary refs log tree commit diff
path: root/src/state/messages
diff options
context:
space:
mode:
Diffstat (limited to 'src/state/messages')
-rw-r--r--src/state/messages/convo/agent.ts (renamed from src/state/messages/convo.ts)183
-rw-r--r--src/state/messages/convo/index.tsx75
-rw-r--r--src/state/messages/convo/types.ts178
-rw-r--r--src/state/messages/index.tsx74
4 files changed, 264 insertions, 246 deletions
diff --git a/src/state/messages/convo.ts b/src/state/messages/convo/agent.ts
index de21ef396..38a3f5e62 100644
--- a/src/state/messages/convo.ts
+++ b/src/state/messages/convo/agent.ts
@@ -9,178 +9,16 @@ import {nanoid} from 'nanoid/non-secure'
 
 import {logger} from '#/logger'
 import {isNative} from '#/platform/detection'
-
-export type ConvoParams = {
-  convoId: string
-  agent: BskyAgent
-  __tempFromUserDid: string
-}
-
-export enum ConvoStatus {
-  Uninitialized = 'uninitialized',
-  Initializing = 'initializing',
-  Ready = 'ready',
-  Error = 'error',
-  Backgrounded = 'backgrounded',
-  Suspended = 'suspended',
-}
-
-export enum ConvoItemError {
-  HistoryFailed = 'historyFailed',
-  PollFailed = 'pollFailed',
-  Network = 'network',
-}
-
-export enum ConvoErrorCode {
-  InitFailed = 'initFailed',
-}
-
-export type ConvoError = {
-  code: ConvoErrorCode
-  exception?: Error
-  retry: () => void
-}
-
-export enum ConvoDispatchEvent {
-  Init = 'init',
-  Ready = 'ready',
-  Resume = 'resume',
-  Background = 'background',
-  Suspend = 'suspend',
-  Error = 'error',
-}
-
-export type ConvoDispatch =
-  | {
-      event: ConvoDispatchEvent.Init
-    }
-  | {
-      event: ConvoDispatchEvent.Ready
-    }
-  | {
-      event: ConvoDispatchEvent.Resume
-    }
-  | {
-      event: ConvoDispatchEvent.Background
-    }
-  | {
-      event: ConvoDispatchEvent.Suspend
-    }
-  | {
-      event: ConvoDispatchEvent.Error
-      payload: ConvoError
-    }
-
-export type ConvoItem =
-  | {
-      type: 'message' | 'pending-message'
-      key: string
-      message: ChatBskyConvoDefs.MessageView
-      nextMessage:
-        | ChatBskyConvoDefs.MessageView
-        | ChatBskyConvoDefs.DeletedMessageView
-        | null
-    }
-  | {
-      type: 'deleted-message'
-      key: string
-      message: ChatBskyConvoDefs.DeletedMessageView
-      nextMessage:
-        | ChatBskyConvoDefs.MessageView
-        | ChatBskyConvoDefs.DeletedMessageView
-        | null
-    }
-  | {
-      type: 'pending-retry'
-      key: string
-      retry: () => void
-    }
-  | {
-      type: 'error-recoverable'
-      key: string
-      code: ConvoItemError
-      retry: () => void
-    }
-
-export type ConvoState =
-  | {
-      status: ConvoStatus.Uninitialized
-      items: []
-      convo: undefined
-      error: undefined
-      sender: undefined
-      recipients: undefined
-      isFetchingHistory: false
-      deleteMessage: undefined
-      sendMessage: undefined
-      fetchMessageHistory: undefined
-    }
-  | {
-      status: ConvoStatus.Initializing
-      items: []
-      convo: undefined
-      error: undefined
-      sender: undefined
-      recipients: undefined
-      isFetchingHistory: boolean
-      deleteMessage: undefined
-      sendMessage: undefined
-      fetchMessageHistory: undefined
-    }
-  | {
-      status: ConvoStatus.Ready
-      items: ConvoItem[]
-      convo: ChatBskyConvoDefs.ConvoView
-      error: undefined
-      sender: AppBskyActorDefs.ProfileViewBasic
-      recipients: AppBskyActorDefs.ProfileViewBasic[]
-      isFetchingHistory: boolean
-      deleteMessage: (messageId: string) => Promise<void>
-      sendMessage: (
-        message: ChatBskyConvoSendMessage.InputSchema['message'],
-      ) => void
-      fetchMessageHistory: () => void
-    }
-  | {
-      status: ConvoStatus.Suspended
-      items: ConvoItem[]
-      convo: ChatBskyConvoDefs.ConvoView
-      error: undefined
-      sender: AppBskyActorDefs.ProfileViewBasic
-      recipients: AppBskyActorDefs.ProfileViewBasic[]
-      isFetchingHistory: boolean
-      deleteMessage: (messageId: string) => Promise<void>
-      sendMessage: (
-        message: ChatBskyConvoSendMessage.InputSchema['message'],
-      ) => Promise<void>
-      fetchMessageHistory: () => Promise<void>
-    }
-  | {
-      status: ConvoStatus.Backgrounded
-      items: ConvoItem[]
-      convo: ChatBskyConvoDefs.ConvoView
-      error: undefined
-      sender: AppBskyActorDefs.ProfileViewBasic
-      recipients: AppBskyActorDefs.ProfileViewBasic[]
-      isFetchingHistory: boolean
-      deleteMessage: (messageId: string) => Promise<void>
-      sendMessage: (
-        message: ChatBskyConvoSendMessage.InputSchema['message'],
-      ) => Promise<void>
-      fetchMessageHistory: () => Promise<void>
-    }
-  | {
-      status: ConvoStatus.Error
-      items: []
-      convo: undefined
-      error: any
-      sender: undefined
-      recipients: undefined
-      isFetchingHistory: false
-      deleteMessage: undefined
-      sendMessage: undefined
-      fetchMessageHistory: undefined
-    }
+import {
+  ConvoDispatch,
+  ConvoDispatchEvent,
+  ConvoErrorCode,
+  ConvoItem,
+  ConvoItemError,
+  ConvoParams,
+  ConvoState,
+  ConvoStatus,
+} from '#/state/messages/convo/types'
 
 const ACTIVE_POLL_INTERVAL = 1e3
 const BACKGROUND_POLL_INTERVAL = 10e3
@@ -235,7 +73,6 @@ export class Convo {
   private headerItems: Map<string, ConvoItem> = new Map()
 
   private isProcessingPendingMessages = false
-  private pendingPoll: Promise<void> | undefined
   private nextPoll: NodeJS.Timeout | undefined
 
   convoId: string
diff --git a/src/state/messages/convo/index.tsx b/src/state/messages/convo/index.tsx
new file mode 100644
index 000000000..c4fe71d30
--- /dev/null
+++ b/src/state/messages/convo/index.tsx
@@ -0,0 +1,75 @@
+import React, {useContext, useState, useSyncExternalStore} from 'react'
+import {AppState} from 'react-native'
+import {BskyAgent} from '@atproto-labs/api'
+import {useFocusEffect, useIsFocused} from '@react-navigation/native'
+
+import {Convo} from '#/state/messages/convo/agent'
+import {ConvoParams, ConvoState} from '#/state/messages/convo/types'
+import {useMarkAsReadMutation} from '#/state/queries/messages/conversation'
+import {useAgent} from '#/state/session'
+import {useDmServiceUrlStorage} from '#/screens/Messages/Temp/useDmServiceUrlStorage'
+
+const ChatContext = React.createContext<ConvoState | null>(null)
+
+export function useConvo() {
+  const ctx = useContext(ChatContext)
+  if (!ctx) {
+    throw new Error('useConvo must be used within a ConvoProvider')
+  }
+  return ctx
+}
+
+export function ConvoProvider({
+  children,
+  convoId,
+}: Pick<ConvoParams, 'convoId'> & {children: React.ReactNode}) {
+  const isScreenFocused = useIsFocused()
+  const {serviceUrl} = useDmServiceUrlStorage()
+  const {getAgent} = useAgent()
+  const [convo] = useState(
+    () =>
+      new Convo({
+        convoId,
+        agent: new BskyAgent({
+          service: serviceUrl,
+        }),
+        __tempFromUserDid: getAgent().session?.did!,
+      }),
+  )
+  const service = useSyncExternalStore(convo.subscribe, convo.getSnapshot)
+  const {mutate: markAsRead} = useMarkAsReadMutation()
+
+  useFocusEffect(
+    React.useCallback(() => {
+      convo.resume()
+      markAsRead({convoId})
+
+      return () => {
+        convo.background()
+        markAsRead({convoId})
+      }
+    }, [convo, convoId, markAsRead]),
+  )
+
+  React.useEffect(() => {
+    const handleAppStateChange = (nextAppState: string) => {
+      if (isScreenFocused) {
+        if (nextAppState === 'active') {
+          convo.resume()
+        } else {
+          convo.background()
+        }
+
+        markAsRead({convoId})
+      }
+    }
+
+    const sub = AppState.addEventListener('change', handleAppStateChange)
+
+    return () => {
+      sub.remove()
+    }
+  }, [convoId, convo, isScreenFocused, markAsRead])
+
+  return <ChatContext.Provider value={service}>{children}</ChatContext.Provider>
+}
diff --git a/src/state/messages/convo/types.ts b/src/state/messages/convo/types.ts
new file mode 100644
index 000000000..cfbde6d7e
--- /dev/null
+++ b/src/state/messages/convo/types.ts
@@ -0,0 +1,178 @@
+import {AppBskyActorDefs} from '@atproto/api'
+import {
+  BskyAgent,
+  ChatBskyConvoDefs,
+  ChatBskyConvoSendMessage,
+} from '@atproto-labs/api'
+
+export type ConvoParams = {
+  convoId: string
+  agent: BskyAgent
+  __tempFromUserDid: string
+}
+
+export enum ConvoStatus {
+  Uninitialized = 'uninitialized',
+  Initializing = 'initializing',
+  Ready = 'ready',
+  Error = 'error',
+  Backgrounded = 'backgrounded',
+  Suspended = 'suspended',
+}
+
+export enum ConvoItemError {
+  HistoryFailed = 'historyFailed',
+  PollFailed = 'pollFailed',
+  Network = 'network',
+}
+
+export enum ConvoErrorCode {
+  InitFailed = 'initFailed',
+}
+
+export type ConvoError = {
+  code: ConvoErrorCode
+  exception?: Error
+  retry: () => void
+}
+
+export enum ConvoDispatchEvent {
+  Init = 'init',
+  Ready = 'ready',
+  Resume = 'resume',
+  Background = 'background',
+  Suspend = 'suspend',
+  Error = 'error',
+}
+
+export type ConvoDispatch =
+  | {
+      event: ConvoDispatchEvent.Init
+    }
+  | {
+      event: ConvoDispatchEvent.Ready
+    }
+  | {
+      event: ConvoDispatchEvent.Resume
+    }
+  | {
+      event: ConvoDispatchEvent.Background
+    }
+  | {
+      event: ConvoDispatchEvent.Suspend
+    }
+  | {
+      event: ConvoDispatchEvent.Error
+      payload: ConvoError
+    }
+
+export type ConvoItem =
+  | {
+      type: 'message' | 'pending-message'
+      key: string
+      message: ChatBskyConvoDefs.MessageView
+      nextMessage:
+        | ChatBskyConvoDefs.MessageView
+        | ChatBskyConvoDefs.DeletedMessageView
+        | null
+    }
+  | {
+      type: 'deleted-message'
+      key: string
+      message: ChatBskyConvoDefs.DeletedMessageView
+      nextMessage:
+        | ChatBskyConvoDefs.MessageView
+        | ChatBskyConvoDefs.DeletedMessageView
+        | null
+    }
+  | {
+      type: 'pending-retry'
+      key: string
+      retry: () => void
+    }
+  | {
+      type: 'error-recoverable'
+      key: string
+      code: ConvoItemError
+      retry: () => void
+    }
+
+export type ConvoState =
+  | {
+      status: ConvoStatus.Uninitialized
+      items: []
+      convo: undefined
+      error: undefined
+      sender: undefined
+      recipients: undefined
+      isFetchingHistory: false
+      deleteMessage: undefined
+      sendMessage: undefined
+      fetchMessageHistory: undefined
+    }
+  | {
+      status: ConvoStatus.Initializing
+      items: []
+      convo: undefined
+      error: undefined
+      sender: undefined
+      recipients: undefined
+      isFetchingHistory: boolean
+      deleteMessage: undefined
+      sendMessage: undefined
+      fetchMessageHistory: undefined
+    }
+  | {
+      status: ConvoStatus.Ready
+      items: ConvoItem[]
+      convo: ChatBskyConvoDefs.ConvoView
+      error: undefined
+      sender: AppBskyActorDefs.ProfileViewBasic
+      recipients: AppBskyActorDefs.ProfileViewBasic[]
+      isFetchingHistory: boolean
+      deleteMessage: (messageId: string) => Promise<void>
+      sendMessage: (
+        message: ChatBskyConvoSendMessage.InputSchema['message'],
+      ) => void
+      fetchMessageHistory: () => void
+    }
+  | {
+      status: ConvoStatus.Suspended
+      items: ConvoItem[]
+      convo: ChatBskyConvoDefs.ConvoView
+      error: undefined
+      sender: AppBskyActorDefs.ProfileViewBasic
+      recipients: AppBskyActorDefs.ProfileViewBasic[]
+      isFetchingHistory: boolean
+      deleteMessage: (messageId: string) => Promise<void>
+      sendMessage: (
+        message: ChatBskyConvoSendMessage.InputSchema['message'],
+      ) => Promise<void>
+      fetchMessageHistory: () => Promise<void>
+    }
+  | {
+      status: ConvoStatus.Backgrounded
+      items: ConvoItem[]
+      convo: ChatBskyConvoDefs.ConvoView
+      error: undefined
+      sender: AppBskyActorDefs.ProfileViewBasic
+      recipients: AppBskyActorDefs.ProfileViewBasic[]
+      isFetchingHistory: boolean
+      deleteMessage: (messageId: string) => Promise<void>
+      sendMessage: (
+        message: ChatBskyConvoSendMessage.InputSchema['message'],
+      ) => Promise<void>
+      fetchMessageHistory: () => Promise<void>
+    }
+  | {
+      status: ConvoStatus.Error
+      items: []
+      convo: undefined
+      error: any
+      sender: undefined
+      recipients: undefined
+      isFetchingHistory: false
+      deleteMessage: undefined
+      sendMessage: undefined
+      fetchMessageHistory: undefined
+    }
diff --git a/src/state/messages/index.tsx b/src/state/messages/index.tsx
index 60538615a..205d17e8c 100644
--- a/src/state/messages/index.tsx
+++ b/src/state/messages/index.tsx
@@ -1,79 +1,7 @@
-import React, {useContext, useState, useSyncExternalStore} from 'react'
-import {AppState} from 'react-native'
-import {BskyAgent} from '@atproto-labs/api'
-import {useFocusEffect, useIsFocused} from '@react-navigation/native'
+import React from 'react'
 
-import {Convo, ConvoParams, ConvoState} from '#/state/messages/convo'
 import {CurrentConvoIdProvider} from '#/state/messages/current-convo-id'
 import {MessagesEventBusProvider} from '#/state/messages/events'
-import {useMarkAsReadMutation} from '#/state/queries/messages/conversation'
-import {useAgent} from '#/state/session'
-import {useDmServiceUrlStorage} from '#/screens/Messages/Temp/useDmServiceUrlStorage'
-
-const ChatContext = React.createContext<ConvoState | null>(null)
-
-export function useChat() {
-  const ctx = useContext(ChatContext)
-  if (!ctx) {
-    throw new Error('useChat must be used within a ChatProvider')
-  }
-  return ctx
-}
-
-export function ChatProvider({
-  children,
-  convoId,
-}: Pick<ConvoParams, 'convoId'> & {children: React.ReactNode}) {
-  const isScreenFocused = useIsFocused()
-  const {serviceUrl} = useDmServiceUrlStorage()
-  const {getAgent} = useAgent()
-  const [convo] = useState(
-    () =>
-      new Convo({
-        convoId,
-        agent: new BskyAgent({
-          service: serviceUrl,
-        }),
-        __tempFromUserDid: getAgent().session?.did!,
-      }),
-  )
-  const service = useSyncExternalStore(convo.subscribe, convo.getSnapshot)
-  const {mutate: markAsRead} = useMarkAsReadMutation()
-
-  useFocusEffect(
-    React.useCallback(() => {
-      convo.resume()
-      markAsRead({convoId})
-
-      return () => {
-        convo.background()
-        markAsRead({convoId})
-      }
-    }, [convo, convoId, markAsRead]),
-  )
-
-  React.useEffect(() => {
-    const handleAppStateChange = (nextAppState: string) => {
-      if (isScreenFocused) {
-        if (nextAppState === 'active') {
-          convo.resume()
-        } else {
-          convo.background()
-        }
-
-        markAsRead({convoId})
-      }
-    }
-
-    const sub = AppState.addEventListener('change', handleAppStateChange)
-
-    return () => {
-      sub.remove()
-    }
-  }, [convoId, convo, isScreenFocused, markAsRead])
-
-  return <ChatContext.Provider value={service}>{children}</ChatContext.Provider>
-}
 
 export function MessagesProvider({children}: {children: React.ReactNode}) {
   return (