| 1 | import { useAtomValue } from "@effect/atom-react"; |
| 2 | import type { PendingThreadRequests } from "@t3tools/client-runtime/state/thread-requests"; |
| 3 | import type { EnvironmentThread } from "@t3tools/client-runtime/state/shell"; |
| 4 | import type { EnvironmentId, OrchestrationV2ThreadProjection, ThreadId } from "@t3tools/contracts"; |
| 5 | import { Atom } from "effect/reactivity"; |
| 6 | |
| 7 | import { environmentThreadDetails, useEnvironmentThread } from "./threads"; |
| 8 | import { useThreadSelection } from "./use-thread-selection"; |
| 9 | |
| 10 | const EMPTY_THREAD_PROJECTION_ATOM = Atom.make<EnvironmentThread | null>(null).pipe( |
| 11 | Atom.withLabel("mobile-thread-projection:empty"), |
| 12 | ); |
| 13 | const EMPTY_VISIBLE_TURN_ITEMS_ATOM = Atom.make< |
| 14 | OrchestrationV2ThreadProjection["visibleTurnItems"] |
| 15 | >(Object.freeze([])).pipe(Atom.withLabel("mobile-thread-visible-turn-items:empty")); |
| 16 | |
| 17 | export interface ThreadDetailTarget { |
| 18 | readonly environmentId: EnvironmentId | null; |
| 19 | readonly threadId: ThreadId | null; |
| 20 | } |
| 21 | |
| 22 | export function useThreadDetail(target: ThreadDetailTarget) { |
| 23 | return useEnvironmentThread(target.environmentId, target.threadId); |
| 24 | } |
| 25 | |
| 26 | /** |
| 27 | * The selection owns the subscription so it can hold it back while a queued |
| 28 | * creation has not reached the server yet. |
| 29 | */ |
| 30 | export function useSelectedThreadDetailState() { |
| 31 | const { selectedThreadDetailRef } = useThreadSelection(); |
| 32 | return useEnvironmentThread( |
| 33 | selectedThreadDetailRef?.environmentId ?? null, |
| 34 | selectedThreadDetailRef?.threadId ?? null, |
| 35 | ); |
| 36 | } |
| 37 | |
| 38 | export function useThreadProjection(target: ThreadDetailTarget): EnvironmentThread | null { |
| 39 | return useAtomValue( |
| 40 | target.environmentId === null || target.threadId === null |
| 41 | ? EMPTY_THREAD_PROJECTION_ATOM |
| 42 | : environmentThreadDetails.threadAtom({ |
| 43 | environmentId: target.environmentId, |
| 44 | threadId: target.threadId, |
| 45 | }), |
| 46 | ); |
| 47 | } |
| 48 | |
| 49 | export function useSelectedThreadProjection(): EnvironmentThread | null { |
| 50 | const { selectedThreadDetailRef } = useThreadSelection(); |
| 51 | return useThreadProjection({ |
| 52 | environmentId: selectedThreadDetailRef?.environmentId ?? null, |
| 53 | threadId: selectedThreadDetailRef?.threadId ?? null, |
| 54 | }); |
| 55 | } |
| 56 | |
| 57 | export function useThreadVisibleTurnItems( |
| 58 | target: ThreadDetailTarget, |
| 59 | ): OrchestrationV2ThreadProjection["visibleTurnItems"] { |
| 60 | return useAtomValue( |
| 61 | target.environmentId === null || target.threadId === null |
| 62 | ? EMPTY_VISIBLE_TURN_ITEMS_ATOM |
| 63 | : environmentThreadDetails.visibleTurnItemsAtom({ |
| 64 | environmentId: target.environmentId, |
| 65 | threadId: target.threadId, |
| 66 | }), |
| 67 | ); |
| 68 | } |
| 69 | |
| 70 | export function useSelectedThreadVisibleTurnItems(): OrchestrationV2ThreadProjection["visibleTurnItems"] { |
| 71 | const { selectedThreadDetailRef } = useThreadSelection(); |
| 72 | return useThreadVisibleTurnItems({ |
| 73 | environmentId: selectedThreadDetailRef?.environmentId ?? null, |
| 74 | threadId: selectedThreadDetailRef?.threadId ?? null, |
| 75 | }); |
| 76 | } |
| 77 | |
| 78 | const EMPTY_WORKTREE_PATH_ATOM = Atom.make<string | null>(null); |
| 79 | const EMPTY_PENDING_REQUESTS_ATOM = Atom.make<PendingThreadRequests | null>(null); |
| 80 | |
| 81 | export function useSelectedThreadWorktreePath() { |
| 82 | const { selectedThreadDetailRef } = useThreadSelection(); |
| 83 | return useAtomValue( |
| 84 | selectedThreadDetailRef === null |
| 85 | ? EMPTY_WORKTREE_PATH_ATOM |
| 86 | : environmentThreadDetails.worktreePathAtom(selectedThreadDetailRef), |
| 87 | ); |
| 88 | } |
| 89 | |
| 90 | export function useSelectedThreadPendingRequests() { |
| 91 | const { selectedThreadDetailRef } = useThreadSelection(); |
| 92 | return useAtomValue( |
| 93 | selectedThreadDetailRef === null |
| 94 | ? EMPTY_PENDING_REQUESTS_ATOM |
| 95 | : environmentThreadDetails.pendingRequestsAtom(selectedThreadDetailRef), |
| 96 | ); |
| 97 | } |