({
defaultRelayUrl,
initialTransitionMode = "initial",
onComplete,
}: WelcomeSetupProps)
| 84 | } |
| 85 | |
| 86 | export function WelcomeSetup({ |
| 87 | defaultRelayUrl, |
| 88 | initialTransitionMode = "initial", |
| 89 | onComplete, |
| 90 | }: WelcomeSetupProps) { |
| 91 | const [page, setPage] = React.useState<WelcomeSetupPage>("welcome"); |
| 92 | const [transitionMode, setTransitionMode] = |
| 93 | React.useState<WelcomeTransitionMode>(initialTransitionMode); |
| 94 | const [customWorkspaceName, setCustomWorkspaceName] = React.useState(""); |
| 95 | const [customRelayUrl, setCustomRelayUrl] = React.useState(""); |
| 96 | const [isConnecting, setIsConnecting] = React.useState(false); |
| 97 | const [error, setError] = React.useState<string | null>(null); |
| 98 | const systemColorScheme = useSystemColorScheme(); |
| 99 | |
| 100 | const handleConnect = React.useCallback( |
| 101 | async (relayUrl: string, workspaceName?: string, pubkey?: string) => { |
| 102 | const trimmedUrl = relayUrl.trim(); |
| 103 | if (!trimmedUrl) { |
| 104 | setError("Please enter a workspace URL."); |
| 105 | return; |
| 106 | } |
| 107 | if (!workspaceName && isLocalDevRelayUrl(trimmedUrl)) { |
| 108 | setError("Enter your relay URL to join a workspace."); |
| 109 | setTransitionMode("forward"); |
| 110 | setPage("create-workspace"); |
| 111 | return; |
| 112 | } |
| 113 | |
| 114 | const handoffStartedAt = performance.now(); |
| 115 | flushSync(() => { |
| 116 | setIsConnecting(true); |
| 117 | setError(null); |
| 118 | }); |
| 119 | |
| 120 | try { |
| 121 | // We snapshot only the pubkey for display purposes (workspace switcher |
| 122 | // labels, etc.). The private key lives on disk in `identity.key` and |
| 123 | // is the single source of truth — never copied into localStorage. |
| 124 | const identityPubkey = pubkey ?? (await getIdentity()).pubkey; |
| 125 | const workspace = initFirstWorkspace( |
| 126 | trimmedUrl, |
| 127 | identityPubkey, |
| 128 | workspaceName, |
| 129 | ); |
| 130 | |
| 131 | if (!workspaceName) { |
| 132 | const elapsedMs = performance.now() - handoffStartedAt; |
| 133 | if (elapsedMs < DEFAULT_WORKSPACE_HANDOFF_MIN_MS) { |
| 134 | await wait(DEFAULT_WORKSPACE_HANDOFF_MIN_MS - elapsedMs); |
| 135 | } |
| 136 | } |
| 137 | |
| 138 | // The parent moves this workspace into React state so first-run setup |
| 139 | // can continue without a full page reload. |
| 140 | onComplete(workspace); |
| 141 | } catch (err) { |
| 142 | setError( |
| 143 | err instanceof Error ? err.message : "Failed to connect. Try again.", |
nothing calls this directly
no test coverage detected