"use client"; /* The onboarding auth chrome: an ink header, the accent rule, a scrolling form and a docked primary bar. Shared by sign in and create account so the two can't drift apart. Fields are numbered — 01, 02, 03 — a counted form on an app about counting. */ import Link from "next/link"; import { usePathname, useRouter } from "next/navigation"; import { useEffect, useId, useState } from "react"; export const INK = "var(--color-text)"; export const PAPER = "var(--color-bg)"; export function MAuthHeader({ kicker, title, back = true }: { kicker: string; title: React.ReactNode; back?: boolean }) { const router = useRouter(); const path = usePathname(); /* The chevron used to be a plain router.back(), which on a fresh install did nothing at all. * The Android shell leaves its welcome screen with location.replace(), so these two screens are * the first entry in the WebView's history: someone who taps "Sign up", changes their mind and * taps back was stuck, with only the footer link out — the hardware back button quits the app * from here, because MainActivity hands the gesture to the system once canGoBack() is false. * * So: pop the history when there really is something behind, and otherwise fall back to sign in, * which is where every other auth screen is reached from. Sign in itself has nothing behind it, * so it draws no chevron at all rather than a dead one. history.length can only be read after * mount, hence the state — the server render assumes the worst case of no history. */ const [canPop, setCanPop] = useState(false); useEffect(() => { setCanPop(window.history.length > 1); }, []); const fallback = path === "/m/login" ? null : "/m/login"; const showBack = back && (canPop || fallback !== null); return (
{showBack && ( )}
{kicker}

{title}

); } /** A numbered field. The index is the device that makes this form ThreadCount’s. * * The label is a real