about summary refs log tree commit diff
path: root/src/state
diff options
context:
space:
mode:
authorEric Bailey <git@esb.lol>2024-05-14 11:59:53 -0500
committerGitHub <noreply@github.com>2024-05-14 11:59:53 -0500
commit1c51a48764e4145679198f68368713410e28c8da (patch)
tree6f2840665b10dfbb3591f0a694c9d5165f383be3 /src/state
parentbffb9b590672c1e636083bdf9873f5cd8ab97b57 (diff)
downloadvoidsky-1c51a48764e4145679198f68368713410e28c8da.tar.zst
[🐴] Make status checks easier, fix load state (#4010)
* Make status checks easier, fix load state

* Make naming more clear

* Split up types for easier re-use

* Replace hacky usage
Diffstat (limited to 'src/state')
-rw-r--r--src/state/messages/convo/index.tsx32
-rw-r--r--src/state/messages/convo/types.ts162
-rw-r--r--src/state/messages/convo/util.ts22
3 files changed, 137 insertions, 79 deletions
diff --git a/src/state/messages/convo/index.tsx b/src/state/messages/convo/index.tsx
index 9c5295832..e955d4118 100644
--- a/src/state/messages/convo/index.tsx
+++ b/src/state/messages/convo/index.tsx
@@ -3,11 +3,20 @@ import {AppState} from 'react-native'
 import {useFocusEffect, useIsFocused} from '@react-navigation/native'
 
 import {Convo} from '#/state/messages/convo/agent'
-import {ConvoParams, ConvoState} from '#/state/messages/convo/types'
+import {
+  ConvoParams,
+  ConvoState,
+  ConvoStateBackgrounded,
+  ConvoStateReady,
+  ConvoStateSuspended,
+} 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 {useAgent} from '#/state/session'
 
+export * from '#/state/messages/convo/util'
+
 const ChatContext = React.createContext<ConvoState | null>(null)
 
 export function useConvo() {
@@ -18,6 +27,27 @@ export function useConvo() {
   return ctx
 }
 
+/**
+ * This hook should only be used when the Convo is "active", meaning the chat
+ * is loaded and ready to be used, or its in a suspended or background state,
+ * and ready for resumption.
+ */
+export function useConvoActive() {
+  const ctx = useContext(ChatContext) as
+    | ConvoStateReady
+    | ConvoStateBackgrounded
+    | ConvoStateSuspended
+  if (!ctx) {
+    throw new Error('useConvo must be used within a ConvoProvider')
+  }
+  if (!isConvoActive(ctx)) {
+    throw new Error(
+      `useConvoActive must only be rendered when the Convo is ready.`,
+    )
+  }
+  return ctx
+}
+
 export function ConvoProvider({
   children,
   convoId,
diff --git a/src/state/messages/convo/types.ts b/src/state/messages/convo/types.ts
index 4615acc2d..6ce4d40bd 100644
--- a/src/state/messages/convo/types.ts
+++ b/src/state/messages/convo/types.ts
@@ -107,82 +107,88 @@ export type ConvoItem =
       retry: () => void
     }
 
+type DeleteMessage = (messageId: string) => Promise<void>
+type SendMessage = (
+  message: ChatBskyConvoSendMessage.InputSchema['message'],
+) => Promise<void>
+type FetchMessageHistory = () => Promise<void>
+
+export type ConvoStateUninitialized = {
+  status: ConvoStatus.Uninitialized
+  items: []
+  convo: undefined
+  error: undefined
+  sender: undefined
+  recipients: undefined
+  isFetchingHistory: false
+  deleteMessage: undefined
+  sendMessage: undefined
+  fetchMessageHistory: undefined
+}
+export type ConvoStateInitializing = {
+  status: ConvoStatus.Initializing
+  items: []
+  convo: undefined
+  error: undefined
+  sender: undefined
+  recipients: undefined
+  isFetchingHistory: boolean
+  deleteMessage: undefined
+  sendMessage: undefined
+  fetchMessageHistory: undefined
+}
+export type ConvoStateReady = {
+  status: ConvoStatus.Ready
+  items: ConvoItem[]
+  convo: ChatBskyConvoDefs.ConvoView
+  error: undefined
+  sender: AppBskyActorDefs.ProfileViewBasic
+  recipients: AppBskyActorDefs.ProfileViewBasic[]
+  isFetchingHistory: boolean
+  deleteMessage: DeleteMessage
+  sendMessage: SendMessage
+  fetchMessageHistory: FetchMessageHistory
+}
+export type ConvoStateBackgrounded = {
+  status: ConvoStatus.Backgrounded
+  items: ConvoItem[]
+  convo: ChatBskyConvoDefs.ConvoView
+  error: undefined
+  sender: AppBskyActorDefs.ProfileViewBasic
+  recipients: AppBskyActorDefs.ProfileViewBasic[]
+  isFetchingHistory: boolean
+  deleteMessage: DeleteMessage
+  sendMessage: SendMessage
+  fetchMessageHistory: FetchMessageHistory
+}
+export type ConvoStateSuspended = {
+  status: ConvoStatus.Suspended
+  items: ConvoItem[]
+  convo: ChatBskyConvoDefs.ConvoView
+  error: undefined
+  sender: AppBskyActorDefs.ProfileViewBasic
+  recipients: AppBskyActorDefs.ProfileViewBasic[]
+  isFetchingHistory: boolean
+  deleteMessage: DeleteMessage
+  sendMessage: SendMessage
+  fetchMessageHistory: FetchMessageHistory
+}
+export type ConvoStateError = {
+  status: ConvoStatus.Error
+  items: []
+  convo: undefined
+  error: any
+  sender: undefined
+  recipients: undefined
+  isFetchingHistory: false
+  deleteMessage: undefined
+  sendMessage: undefined
+  fetchMessageHistory: undefined
+}
 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
-    }
+  | ConvoStateUninitialized
+  | ConvoStateInitializing
+  | ConvoStateReady
+  | ConvoStateBackgrounded
+  | ConvoStateSuspended
+  | ConvoStateError
diff --git a/src/state/messages/convo/util.ts b/src/state/messages/convo/util.ts
new file mode 100644
index 000000000..ffaa4104a
--- /dev/null
+++ b/src/state/messages/convo/util.ts
@@ -0,0 +1,22 @@
+import {
+  ConvoState,
+  ConvoStateBackgrounded,
+  ConvoStateReady,
+  ConvoStateSuspended,
+  ConvoStatus,
+} from './types'
+
+/**
+ * Checks if a `Convo` has a `status` that is "active", meaning the chat is
+ * loaded and ready to be used, or its in a suspended or background state, and
+ * ready for resumption.
+ */
+export function isConvoActive(
+  convo: ConvoState,
+): convo is ConvoStateReady | ConvoStateBackgrounded | ConvoStateSuspended {
+  return (
+    convo.status === ConvoStatus.Ready ||
+    convo.status === ConvoStatus.Backgrounded ||
+    convo.status === ConvoStatus.Suspended
+  )
+}