import { Link, Stack, useRouter } from "expo-router"; import { SymbolView } from "expo-symbols"; import type { EnvironmentId, ProjectId } from "@t3tools/contracts"; import { useMemo } from "react"; import { ActivityIndicator, Pressable, ScrollView, View } from "react-native"; import { useSafeAreaInsets } from "react-native-safe-area-context"; import { useThemeColor } from "../../lib/useThemeColor"; import { AppText as Text } from "../../components/AppText"; import { ProjectFavicon } from "../../components/ProjectFavicon"; import { useProjects, useThreadShells } from "../../state/entities"; import type { WorkspaceState } from "../../state/workspaceModel"; import { useWorkspaceState } from "../../state/workspace"; import { groupProjectsByRepository } from "../../lib/repositoryGroups"; function deriveProjectEmptyState(catalogState: WorkspaceState): { readonly title: string; readonly detail: string; readonly loading: boolean; } { if (catalogState.isLoadingConnections) { return { title: "Loading environments", detail: "Checking saved environments on this device.", loading: true, }; } if (!catalogState.hasConnections) { return { title: "No environments connected", detail: "Add an environment before creating a task.", loading: false, }; } if ( (catalogState.connectionState === "available" || catalogState.connectionState === "offline" || catalogState.connectionState === "error") && !catalogState.hasLoadedShellSnapshot ) { return { title: "Environment unavailable", detail: catalogState.connectionError ?? "The saved environment is offline. Check the URL or start the environment, then retry.", loading: false, }; } if ( catalogState.hasConnectingEnvironment && !catalogState.hasLoadedShellSnapshot && catalogState.connectionError === null ) { return { title: "Connecting to environment", detail: "Loading projects from the saved environment.", loading: true, }; } return { title: "No projects found", detail: "The connected environment did not report any projects.", loading: false, }; } export default function NewTaskRoute() { const projects = useProjects(); const threads = useThreadShells(); const { state: catalogState } = useWorkspaceState(); const router = useRouter(); const insets = useSafeAreaInsets(); const chevronColor = useThemeColor("--color-chevron"); const accentColor = useThemeColor("--color-icon-muted"); const borderSubtleColor = useThemeColor("--color-border-subtle"); const repositoryGroups = useMemo( () => groupProjectsByRepository({ projects, threads }), [projects, threads], ); const items = useMemo(() => { const nextItems: Array<{ readonly environmentId: EnvironmentId; readonly id: ProjectId; readonly key: string; readonly title: string; readonly workspaceRoot: string; }> = []; for (const group of repositoryGroups) { const project = group.projects[0]?.project; if (!project) { continue; } nextItems.push({ environmentId: project.environmentId, id: project.id, key: group.key, title: project.title, workspaceRoot: project.workspaceRoot, }); } return nextItems; }, [repositoryGroups]); const projectEmptyState = deriveProjectEmptyState(catalogState); return ( router.push("/new/add-project")} separateBackground /> {items.length === 0 ? ( {projectEmptyState.loading ? : null} {projectEmptyState.title} {projectEmptyState.detail} {!catalogState.hasReadyEnvironment ? ( router.push("/connections/new")} > Add environment ) : ( router.push("/new/add-project")} > Add new project )} ) : ( {items.map((item, index) => { const isFirst = index === 0; const isLast = index === items.length - 1; return ( {item.title} ); })} )} ); }