129 lines · 4.5 KB · TypeScript
RawDownload
import { DEFAULT_RUNTIME_MODE, type ProjectId, ThreadId } from "@t3tools/contracts";import { useNavigate, useParams } from "@tanstack/react-router";import { useCallback } from "react";import { inferProviderForModel } from "@t3tools/shared/model";import {  type DraftThreadEnvMode,  type DraftThreadState,  useComposerDraftStore,} from "../composerDraftStore";import { newThreadId } from "../lib/utils";import { useStore } from "../store"; export function useHandleNewThread() {  const projects = useStore((store) => store.projects);  const threads = useStore((store) => store.threads);  const stickyModel = useComposerDraftStore((store) => store.stickyModel);  const stickyModelOptions = useComposerDraftStore((store) => store.stickyModelOptions);  const navigate = useNavigate();  const routeThreadId = useParams({    strict: false,    select: (params) => (params.threadId ? ThreadId.makeUnsafe(params.threadId) : null),  });  const activeDraftThread = useComposerDraftStore((store) =>    routeThreadId ? (store.draftThreadsByThreadId[routeThreadId] ?? null) : null,  );   const activeThread = routeThreadId    ? threads.find((thread) => thread.id === routeThreadId)    : undefined;   const handleNewThread = useCallback(    (      projectId: ProjectId,      options?: {        branch?: string | null;        worktreePath?: string | null;        envMode?: DraftThreadEnvMode;      },    ): Promise<void> => {      const {        clearProjectDraftThreadId,        getDraftThread,        getDraftThreadByProjectId,        setModel,        setModelOptions,        setProvider,        setDraftThreadContext,        setProjectDraftThreadId,      } = useComposerDraftStore.getState();      const hasBranchOption = options?.branch !== undefined;      const hasWorktreePathOption = options?.worktreePath !== undefined;      const hasEnvModeOption = options?.envMode !== undefined;      const storedDraftThread = getDraftThreadByProjectId(projectId);      const latestActiveDraftThread: DraftThreadState | null = routeThreadId        ? getDraftThread(routeThreadId)        : null;      if (storedDraftThread) {        return (async () => {          if (hasBranchOption || hasWorktreePathOption || hasEnvModeOption) {            setDraftThreadContext(storedDraftThread.threadId, {              ...(hasBranchOption ? { branch: options?.branch ?? null } : {}),              ...(hasWorktreePathOption ? { worktreePath: options?.worktreePath ?? null } : {}),              ...(hasEnvModeOption ? { envMode: options?.envMode } : {}),            });          }          setProjectDraftThreadId(projectId, storedDraftThread.threadId);          if (routeThreadId === storedDraftThread.threadId) {            return;          }          await navigate({            to: "/$threadId",            params: { threadId: storedDraftThread.threadId },          });        })();      }       clearProjectDraftThreadId(projectId);       if (        latestActiveDraftThread &&        routeThreadId &&        latestActiveDraftThread.projectId === projectId      ) {        if (hasBranchOption || hasWorktreePathOption || hasEnvModeOption) {          setDraftThreadContext(routeThreadId, {            ...(hasBranchOption ? { branch: options?.branch ?? null } : {}),            ...(hasWorktreePathOption ? { worktreePath: options?.worktreePath ?? null } : {}),            ...(hasEnvModeOption ? { envMode: options?.envMode } : {}),          });        }        setProjectDraftThreadId(projectId, routeThreadId);        return Promise.resolve();      }       const threadId = newThreadId();      const createdAt = new Date().toISOString();      return (async () => {        setProjectDraftThreadId(projectId, threadId, {          createdAt,          branch: options?.branch ?? null,          worktreePath: options?.worktreePath ?? null,          envMode: options?.envMode ?? "local",          runtimeMode: DEFAULT_RUNTIME_MODE,        });        if (stickyModel) {          setProvider(threadId, inferProviderForModel(stickyModel));          setModel(threadId, stickyModel);        }        if (Object.keys(stickyModelOptions).length > 0) {          setModelOptions(threadId, stickyModelOptions);        }         await navigate({          to: "/$threadId",          params: { threadId },        });      })();    },    [navigate, routeThreadId, stickyModel, stickyModelOptions],  );   return {    activeDraftThread,    activeThread,    handleNewThread,    projects,    routeThreadId,  };}