import { useEffect, useState, type ReactNode } from "react";
import { LoadingPanel, ProblemPanel } from "./common";
import { Button } from "../../ui/button";
import {
useOptionalBrowserAccountBridge,
type BrowserAccountSafeSlot,
} from "../lib/browser-account-bridge";
type Slot = BrowserAccountSafeSlot;
export function CrossSlotDeepLinkRecovery(props: { path: string; fallback: ReactNode }) {
const accounts = useOptionalBrowserAccountBridge();
const resolveDeepLink = accounts?.resolveDeepLink;
const selectSlot = accounts?.selectSlot;
const [attempt, setAttempt] = useState(0);
const [state, setState] = useState<
{ kind: "loading" } | { kind: "fallback" } | { kind: "error" } | { kind: "switch"; slot: Slot }
>(() => (resolveDeepLink ? { kind: "loading" } : { kind: "fallback" }));
useEffect(() => {
if (!resolveDeepLink) {
setState({ kind: "fallback" });
return;
}
let cancelled = false;
setState({ kind: "loading" });
void resolveDeepLink(props.path)
.then((resolution) => {
if (cancelled) return;
setState(
resolution.kind === "switch_required"
? { kind: "switch", slot: resolution.slot }
: { kind: "fallback" },
);
})
.catch(() => {
if (!cancelled) setState({ kind: "error" });
});
return () => {
cancelled = true;
};
}, [attempt, props.path, resolveDeepLink]);
if (state.kind === "loading") return ;
if (state.kind === "fallback") return props.fallback;
if (state.kind === "error") {
return (
setAttempt((value) => value + 1)}>
Try again
}
/>
);
}
return (
{
const slot = state.slot;
setState({ kind: "loading" });
void selectSlot?.(slot.id)
.then((settled) => {
if (!settled) setState({ kind: "switch", slot });
})
.catch(() => setState({ kind: "error" }));
}}
>
Open as {state.slot.displayName}
}
/>
);
}