2026-06-11 00:24:40 -04:00
|
|
|
export interface IntroSplashDecisionInput {
|
|
|
|
|
seenIntro: boolean
|
|
|
|
|
routePath: string
|
|
|
|
|
fromBoot: boolean
|
|
|
|
|
devMode?: string
|
|
|
|
|
onboardingComplete: boolean | null
|
2026-07-15 10:48:39 +01:00
|
|
|
/** Explicit "Replay intro" click — overrides every suppression rule. */
|
|
|
|
|
replayRequested?: boolean
|
2026-06-11 00:24:40 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function shouldShowIntroSplash(input: IntroSplashDecisionInput): boolean {
|
2026-07-15 10:48:39 +01:00
|
|
|
if (input.replayRequested) return true
|
2026-07-20 06:07:28 +01:00
|
|
|
|
|
|
|
|
const isDirectRoute = input.routePath !== '/'
|
|
|
|
|
// A node the backend CONFIRMS has never completed onboarding always gets
|
|
|
|
|
// the full intro on a root boot. `seenIntro` is per-origin browser state —
|
|
|
|
|
// after a reinstall (or a DHCP-recycled IP), the browser still carries the
|
|
|
|
|
// previous node's flag at the same origin, which silently muted the intro
|
|
|
|
|
// on genuinely fresh installs.
|
|
|
|
|
if (input.onboardingComplete === false && (input.fromBoot || (!isDirectRoute && input.devMode !== 'boot'))) {
|
|
|
|
|
return true
|
|
|
|
|
}
|
2026-06-11 00:24:40 -04:00
|
|
|
if (input.seenIntro) return false
|
|
|
|
|
if (input.onboardingComplete === true) return false
|
|
|
|
|
|
|
|
|
|
if (input.fromBoot) return true
|
|
|
|
|
if (input.devMode === 'boot') return false
|
|
|
|
|
return !isDirectRoute
|
|
|
|
|
}
|