diff --git a/docs/plans/splash_mascot.md b/docs/plans/splash_mascot.md deleted file mode 100644 index 13c5c609..00000000 --- a/docs/plans/splash_mascot.md +++ /dev/null @@ -1,130 +0,0 @@ -# Splash & mascot — open notes - -State of play after the connection-indicator (`SyncIndicator`) work landed. -Anything in this file is **deferred / future work**, not active. Treat it as -context for the next person to pick up the splash topic. - -## Current visible chain (cold load, web/desktop) - -1. **Initial blank** — HTML loaded, React mounts. ~50ms. `body` background - is `#0d0e11` (the `--vojo-safe-area-bg` var), so it's a dark frame, not - white. -2. **`ConfigConfigLoading` mascot splash** — - [`pages/ConfigConfig.tsx`](../../src/app/pages/ConfigConfig.tsx) renders - `` (mascot + footer) while `/config.json` is fetched. - ~50–300ms on Caddy-served static. -3. **`SpecVersions` mascot splash** — - [`pages/client/SpecVersions.tsx`](../../src/app/pages/client/SpecVersions.tsx) - renders `` while `/_matrix/client/versions` is fetched - from the homeserver. **0.5–2s, network-bound, the longest of the chain.** -4. **`ClientRoot` mascot splash** — - [`pages/client/ClientRoot.tsx`](../../src/app/pages/client/ClientRoot.tsx) - `loading || !mx ? : ...`. Shown while `initClient` - runs (IndexedDB open + crypto WASM init, ~300–700ms) AND while waiting - for `SyncState.Prepared` (the `useSyncState` gate at line ~200). The - Prepared wait can be 1–30s depending on cache warmth and account size. -5. App tree mounts. `SyncIndicator` takes over for the residual sync - activity (green slide while sync is still settling, hidden once Syncing). - -## Current visible chain (Android native) - -1. **OS system splash** — Android 12+ enforces a system splash with the - launcher icon centered over `windowBackground`. Configured via - [`android/app/src/main/res/values/styles.xml`](../../android/app/src/main/res/values/styles.xml) - `AppTheme.NoActionBarLaunch` → `windowBackground=@android:color/black`. - Cannot be fully eliminated; ~300–500ms while Android starts the process - and Capacitor loads the WebView. -2. Then the web chain (steps 1–5 above). - -So an Android cold-launch sees: black-icon (OS) → black blank (HTML) → -mascot (config + spec-versions + initClient + Prepared) → app. - -## What we tried and reverted (during the SyncIndicator work) - -In the 0.3.0 attempt that got reverted, we made several aggressive changes -to shorten the chain. They worked, but introduced subtle bugs that the user -chose to roll back to keep the diff clean. Specifically: - -### A. SpecVersions made non-blocking - -[Commit reverted in `ff01e6c`.] The change made `SpecVersions` render -children immediately with `versions: []` and hydrate the real value in the -background (with retry on `online` event). This eliminated the 0.5–2s -mascot in step 3. - -**Why reverted**: it surfaced a latent bug in -[`components/message/content/ImageContent.tsx`](../../src/app/components/message/content/ImageContent.tsx) -and `VideoContent.tsx`. While `versions: []`, `useMediaAuthentication()` -returns false, autoPlay images load with unauth URLs, the server rejects, -the local `error=true` flag latches and is never cleared on the post- -hydration retry. The reviewer flagged this as a blocker. - -**Fix attempted**: reset `error` and `load` state in the `loadSrc`-deps -useEffect AND in `handleLoad` — both `ImageContent.tsx` and -`VideoContent.tsx`. The fix was correct but the user judged it as out-of- -scope scope-creep for the connection-indicator feature and rolled the -whole change back. - -**To redo cleanly**: ship SpecVersions-non-blocking and the -ImageContent/VideoContent fix together, in a separate dedicated commit -(scope = "make boot non-blocking", not bundled with the indicator). - -### B. ClientRoot loading paths replaced with `null` - -[`pages/ConfigConfig.tsx::ConfigConfigLoading`](../../src/app/pages/ConfigConfig.tsx) -returned `null` instead of ``. Same for the `!mx` branch -in `ClientRoot`. Eliminated the mascot during steps 2 and 4-init-only. -Reverted as part of the same revert. - -**To redo**: low risk on its own. Change those two callsites to render -`null` (the dark body background shows through). Skip the Prepared gate -removal (that's the deeper change). - -### C. ClientRoot Prepared gate removed - -The ambitious move: render `MatrixClientProvider` as soon as `mx` is created -(after `initClient`), not after `Prepared`. Eliminates the 1–30s wait for -first sync — app shell renders against the IndexedDB cache while sync -populates new events in background. - -**Why reverted**: needed an extra fix in -[`pages/client/direct/RoomProvider.tsx`](../../src/app/pages/client/direct/RoomProvider.tsx) -to add `useAtomValue(allRoomsAtom)` so cold-start deep-links (push tap) -re-render when the room arrives. Plus arguably exposes a brief empty-UI -flash on first-time logins. - -**To redo**: do it after a careful audit of every consumer of -`mx.getRoom()` / `mx.getRooms()` to make sure they all tolerate empty -stores. The deep-link re-render fix in `direct/RoomProvider.tsx` is the -mechanical trigger; there may be others. - -## What's open - -In rough priority order: - -1. **SpecVersions non-blocking + media-auth race fix** (B above). - Biggest win for cold-start time-to-interactive (~1.5s saved). Bundle - with the ImageContent/VideoContent error reset in one commit. -2. **`null` instead of mascot during ConfigConfig + `!mx` loading** - (B above, simpler half). ~400ms shaved. -3. **Drop the Prepared gate** (C above). Most invasive; needs full audit. - Could wait until `dm_1x1_redesign.md` or another major-mode change is - ready to absorb the risk. -4. **OS system splash on Android** — currently iconic-on-black via - `AppTheme.NoActionBarLaunch`. Can't eliminate on Android 12+ but can - be tuned (different background color, different icon) via - `android/app/src/main/res/values/styles.xml`. Not user-reported as a - problem, just noting the lever exists. - -## Don't break - -- **`body { background: var(--vojo-safe-area-bg, #0d0e11) }`** in - `src/index.css` — the dark frame is what makes a `null` loading path - look intentional. Without it the user sees a white flash. -- **Mascot on auth pages** (`/login`, `/register`) is INTENDED — those - pages design the mascot in deliberately. Don't gate-remove it there. - Only the loading-state mascot is the candidate for removal. -- **The error-retry mascot in `ClientRoot`** (the - `{retry-dialog}` branch in - `ClientRoot.tsx`) is the rare case where the mascot is fine to keep — - it's a hard-error context that needs anchoring for the dialog.