diff options
author | Eric Bailey <git@esb.lol> | 2024-05-14 11:59:53 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-14 11:59:53 -0500 |
commit | 1c51a48764e4145679198f68368713410e28c8da (patch) | |
tree | 6f2840665b10dfbb3591f0a694c9d5165f383be3 /src/state/messages/convo | |
parent | bffb9b590672c1e636083bdf9873f5cd8ab97b57 (diff) | |
download | voidsky-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/messages/convo')
-rw-r--r-- | src/state/messages/convo/index.tsx | 32 | ||||
-rw-r--r-- | src/state/messages/convo/types.ts | 162 | ||||
-rw-r--r-- | src/state/messages/convo/util.ts | 22 |
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 + ) +} |