import { useEffect, useState, type JSX } from 'react'; import { useAppStore } from '../../store'; import { uiStrings } from '../../content'; /** * Persistence-result toast (CONTEXT D-30 + UX-13). * * One-time soft toast in voice on first save if `navigator.storage.persist()` * was denied; nothing if granted. State remembered via * `settings.persistenceToastShown` so the toast only fires once across * sessions. * * Triggered by src/PhaserGame.tsx after the boot path's requestPersistence * call resolves with `granted=false && apiAvailable=true && !persistenceToastShown`. * * Anti-FOMO compliant — the copy is in the gardener-keeper voice * (uiStrings[1].settings.persistence_denied_toast: "The garden may forget, * if your browser asks it to."). No nag, no streak, no daily-login pressure. */ const TOAST_DURATION_MS = 6500; export function PersistenceToast({ show }: { show: boolean }): JSX.Element | null { const [visible, setVisible] = useState(show); const setShown = useAppStore((s) => s.setPersistenceToastShown); const strings = uiStrings[1]?.settings; useEffect(() => { if (!show) { setVisible(false); return; } setVisible(true); const t = setTimeout(() => { setVisible(false); setShown(true); }, TOAST_DURATION_MS); return () => clearTimeout(t); }, [show, setShown]); if (!visible || !strings) return null; return (