import type { DialogHandle } from '#/components/Dialog';
import { useFocusEffect, useLocation } from '#/router';
/**
* the starter pack wizard is a route, not a dialog, so by the time a pack is created the dialog that launched
* it is long closed and the screen owning it may not even be mounted. a callback route param can't bridge
* that gap — a function survives neither a reload nor a deep link — so the launch is parked here and claimed
* by the origin screen once it is back in view.
*/
type WizardLaunch = {
/** route key of the screen owning the dialog, so no other screen can claim the reopen */
originKey: string;
/** the wizard only asks for a reopen once a pack actually exists; a wizard backed out of is dropped */
packCreated: boolean;
targetDid: string;
};
let launch: WizardLaunch | undefined;
/**
* records that the starter pack wizard was opened from the "add to starter pack" dialog on the given screen.
* call it right before navigating to the wizard.
*
* @param originKey route key of the screen the dialog belongs to
* @param targetDid subject of the dialog
*/
export const markStarterPackWizardLaunched = (originKey: string, targetDid: string): void => {
launch = { originKey, packCreated: false, targetDid };
};
/** records that the wizard created a pack, arming the reopen of the dialog that launched it. */
export const markStarterPackCreated = (): void => {
if (launch) {
launch.packCreated = true;
}
};
/**
* reopens `handle` when the screen it belongs to comes back into view after the wizard it launched created a
* pack. a no-op for a wizard that was reached any other way, or backed out of.
*
* @param handle the "add to starter pack" dialog
* @param targetDid subject of the dialog
*/
export const useStarterPackDialogReopen = (handle: DialogHandle, targetDid: string): void => {
const { key } = useLocation();
useFocusEffect(() => {
if (!launch?.packCreated || launch.originKey !== key || launch.targetDid !== targetDid) {
return;
}
launch = undefined;
// the shell closes every dialog whenever the navigation state changes, and that listener sits
// above the navigator — so it runs *after* this focus effect, on the very navigation that
// brought us back here. reopen once the effect flush (and with it the close) is done.
queueMicrotask(() => handle.open(null));
});
};