about summary refs log tree commit diff
path: root/src/state/messages/convo/index.tsx
diff options
context:
space:
mode:
authorEric Bailey <git@esb.lol>2024-05-07 21:46:59 -0500
committerGitHub <noreply@github.com>2024-05-07 19:46:59 -0700
commit56f713077f6e663ac77df20f1d67b55fd1da153a (patch)
tree87b3d5d11a728d1fcdbf434ce73ef364e2340a13 /src/state/messages/convo/index.tsx
parent814ec2bd7f2fa4506b528da9d8d6f912ddc5422e (diff)
downloadvoidsky-56f713077f6e663ac77df20f1d67b55fd1da153a.tar.zst
[🐴] Reorg convo files (#3909)
* Remove unused prop

* Reorganize
Diffstat (limited to 'src/state/messages/convo/index.tsx')
-rw-r--r--src/state/messages/convo/index.tsx75
1 files changed, 75 insertions, 0 deletions
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>
+}