| 1 | import type { EnvironmentId } from "@t3tools/contracts"; |
| 2 | import { useCallback } from "react"; |
| 3 | import { View } from "react-native"; |
| 4 | |
| 5 | import { EmptyState } from "../../components/EmptyState"; |
| 6 | import { environmentCatalog } from "../../connection/catalog"; |
| 7 | import type { AssetUrlFailureReason } from "../../state/asset-url-state"; |
| 8 | import { useAtomCommand } from "../../state/use-atom-command"; |
| 9 | import { useEnvironmentPresentation } from "../../state/presentation"; |
| 10 | import { EnvironmentConnectionNotice } from "../connection/EnvironmentConnectionNotice"; |
| 11 | |
| 12 | /** |
| 13 | * Terminal state for a preview whose signed asset URL will not arrive. A dead |
| 14 | * environment reuses the same notice the terminal and review sheets show, so the |
| 15 | * user gets one recognizable way back online. |
| 16 | */ |
| 17 | export function WorkspaceFilePreviewError(props: { |
| 18 | readonly environmentId: EnvironmentId | null; |
| 19 | readonly reason: AssetUrlFailureReason; |
| 20 | readonly onRetry: () => void; |
| 21 | }) { |
| 22 | const { environmentId, onRetry } = props; |
| 23 | const environment = useEnvironmentPresentation(environmentId); |
| 24 | const retryEnvironment = useAtomCommand(environmentCatalog.retryNow, "environment retry"); |
| 25 | const retryConnection = useCallback(() => { |
| 26 | if (environmentId !== null) void retryEnvironment(environmentId); |
| 27 | onRetry(); |
| 28 | }, [environmentId, onRetry, retryEnvironment]); |
| 29 | |
| 30 | if (props.reason === "disconnected") { |
| 31 | return ( |
| 32 | <View className="flex-1 bg-sheet"> |
| 33 | <EnvironmentConnectionNotice |
| 34 | environmentLabel={environment.presentation?.entry.target.label ?? "Environment"} |
| 35 | connection={ |
| 36 | environment.presentation?.connection ?? { |
| 37 | phase: "available", |
| 38 | error: null, |
| 39 | traceId: null, |
| 40 | } |
| 41 | } |
| 42 | resourceName="preview" |
| 43 | onRetry={retryConnection} |
| 44 | /> |
| 45 | </View> |
| 46 | ); |
| 47 | } |
| 48 | |
| 49 | return ( |
| 50 | <View className="flex-1 items-center justify-center bg-sheet px-6"> |
| 51 | <EmptyState |
| 52 | title="Preview unavailable" |
| 53 | detail="This file may be missing, unsupported, or unavailable on this environment." |
| 54 | actionLabel="Try again" |
| 55 | onAction={props.onRetry} |
| 56 | /> |
| 57 | </View> |
| 58 | ); |
| 59 | } |