Skip to content

fix(mobile): keep the branded splash on screen during Android cold start - #6355

Draft
iscekic wants to merge 1 commit into
mainfrom
kwf/explorer-app-cold-loading-cold-start-shows-a-bare-white-s-b6c69-4d7e
Draft

iscekic wants to merge 1 commit into
mainfrom
kwf/explorer-app-cold-loading-cold-start-shows-a-bare-white-s-b6c69-4d7e

Conversation

@iscekic

@iscekic iscekic commented Sep 19, 2026

Copy link
Copy Markdown
Collaborator

Changelog for users

  • The branded cold-start launch (brand-yellow with the dark Kilo mark) is defined once and used on iOS and Android, so the two platforms cannot drift apart.
  • Cold starts show that branded surface on both platforms; Android holds it through portrait and landscape until the app's own content appears.

Changelog for maintainers

  • Replaces the standalone Android splash plugin with ./plugins/withBrandedSplash, a single entry that registers Expo's native splash for iOS and Android and adds its own Android backing-surface mods.
  • The wrapper registers the Android mods before Expo's splash plugin internally, so callers cannot invert the mod order and the ordering contract is no longer exposed in the app config.
  • The Android mods stay a documented capability exception: Android has no root-backed launch-storyboard loading view, so its window drawable must cover the pre-React gap; they do not own splash dismissal.
  • MainActivity listens for React's CONTENT_APPEARED marker and, after a 3-second delay, restores the app background so the brand surface cannot outlive the launch; the hand-back waits for React content, not the first window draw.
  • The Android mods stay inert when the splash theme or the onCreate super call is absent, and on a Java activity where the Kotlin injection would not compile.
  • The config-contract script requires exactly one shared branded-splash entry, rejects a standalone expo-splash-screen or the removed plugin, rejects per-platform option overrides, and checks the options match the overlay (logo-mark.png, #FAF74F, width 100).
  • New plugin test compiles the shared plugin for iOS and Android and asserts both native surfaces — the iOS storyboard color/logo and the Android color and launch style — come from one option set; the mounted overlay test now runs on both platforms across app, login, consent, force-update and each error outcome.
  • Review hint: mod ordering and the Android capability exception are the risky parts; start with withBrandedSplash.js and the config contract. The earlier Android-only frame-by-frame proof is replaced by the device captures kept above and by the shared plugin test, which asserts both native surfaces from one option set. Live-device verification recorded no platform, so the request's Android and iOS live checks are skipped, pending owner verification.

E2E proof

Cold start on emulator-5602 (day mode): force-stop com.kilocode.kiloapp, launch it, and watch the first visible frames — the launch is the brand yellow splash with the dark Kilo mark; no bare white… — e1-portrait-splash.png

[e1] Cold start on emulator-5602 (day mode): force-stop com.kilocode.kiloapp, launch it, and watch the first visible frames — the launch is the brand yellow splash with the dark Kilo mark; no bare white… — prior/e1-portrait-content.png

[e1] Cold start on emulator-5602 (day mode): force-stop com.kilocode.kiloapp, launch it, and watch the first visible frames — the launch is the brand yellow splash with the dark Kilo mark; no bare white… — prior/e1-landscape-content.png

[e1] Cold start on emulator-5602 (day mode): force-stop com.kilocode.kiloapp, launch it, and watch the first visible frames — the launch is the brand yellow splash with the dark Kilo mark; no bare white… — e1-landscape-splash.png

Owner request

Explorer finding: app-cold-loading: Cold start shows a bare white screen with no logo, wordmark or progress affordance instead of the app's dark/yellow branded launch, so the first impression is an undesigned white flash.

The user-agent explorer found this while using the app like a user.
One finding per item; the explorer never edits product code.

Flow: app-cold-loading
Found on revision: fd04ca1

Repro:

  1. set this state first: account e2e-firstrun-1789781393@example.com (brand-new first-run, $10 credits, second org e2e-org-1789784588@example.com via w4c-org-pair, 3 Code Reviewer pull requests), device rotated to landscape, system day mode.
  2. open the app on emulator-5602
  3. reach the screen the capture names (app-cold-loading)
  4. the capture shows the defect named below

Observed: Cold start shows a bare white screen with no logo, wordmark or progress affordance instead of the app's dark/yellow branded launch, so the first impression is an undesigned white flash.
Expected: the screen renders without this defect

Evidence (from the device run):

E2E proof — log excerpts

[p1] Cold start on emulator-5602 (day mode): force-stop com.kilocode.kiloapp, la -> pass :: jev read the digest: pass (confidence 1.00)

Comment thread apps/mobile/plugins/android-splash-window-background.js
@kilo-code-bot

kilo-code-bot Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 1
WARNING 0
SUGGESTION 0
Issue Details (click to expand)

CRITICAL

File Line Issue
apps/mobile/plugins/android-splash-window-background.js 98 onDestroy removes an already-removed ReactMarker listener; RN's removeListener throws NoSuchElementException when not registered, crashing on every activity destroy after content appeared.
Files Reviewed (8 files)
  • apps/mobile/app.config.ts - no issues
  • apps/mobile/plugins/android-splash-window-background.js - 1 issue (previous WARNING resolved; new CRITICAL introduced)
  • apps/mobile/plugins/android-splash-window-background.test.ts - no issues
  • apps/mobile/plugins/branded-splash.test.ts - no issues
  • apps/mobile/plugins/withBrandedSplash.js - no issues
  • apps/mobile/scripts/assert-expo-config.mjs - no issues
  • apps/mobile/src/components/animated-splash-overlay.mounted.test.tsx - no issues
  • apps/mobile/plugins/withAndroidSplashWindowBackground.js - deleted

Fix these issues in Kilo Cloud

Previous Review Summary (commit e460f7e)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit e460f7e)

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
apps/mobile/plugins/android-splash-window-background.js 81 Process-global ReactMarker listener is only removed on CONTENT_APPEARED; a launch that never reaches the marker leaks the MainActivity and its view hierarchy.
Files Reviewed (6 files)
  • apps/mobile/app.config.ts - no issues
  • apps/mobile/plugins/android-splash-window-background.js - 1 issue
  • apps/mobile/plugins/android-splash-window-background.test.ts - no issues
  • apps/mobile/plugins/withAndroidSplashWindowBackground.js - no issues
  • apps/mobile/scripts/assert-expo-config.mjs - no issues
  • apps/mobile/vitest.pure.config.ts - no issues

Fix these issues in Kilo Cloud


Reviewed by deepseek-v4.1-flash · Input: 0 · Output: 0 · Cached: 0

Review guidance: REVIEW.md from base branch main

@iscekic
iscekic marked this pull request as draft September 19, 2026 08:56
@iscekic
iscekic force-pushed the kwf/explorer-app-cold-loading-cold-start-shows-a-bare-white-s-b6c69-4d7e branch from e460f7e to b676feb Compare September 19, 2026 09:26
@iscekic
iscekic force-pushed the kwf/explorer-app-cold-loading-cold-start-shows-a-bare-white-s-b6c69-4d7e branch from b676feb to ac5fe31 Compare September 19, 2026 11:17
@iscekic

iscekic commented Sep 19, 2026

Copy link
Copy Markdown
Collaborator Author

bot: Cross-platform fix. Pushed ac5fe31 (kwf kwf-fix-platform-69cf).

What changed:

  • Replaces the standalone Android splash plugin with ./plugins/withBrandedSplash, a single entry that registers Expo's native splash for iOS and Android and adds its own Android backing-surface mods.
  • The wrapper registers the Android mods before Expo's splash plugin internally, so callers cannot invert the mod order and the ordering contract is no longer exposed in the app config.
  • The Android mods stay a documented capability exception: Android has no root-backed launch-storyboard loading view, so its window drawable must cover the pre-React gap. They do not own splash dismissal.
  • The config-contract script now requires exactly one shared branded-splash entry, rejects a standalone expo-splash-screen or the removed plugin, and checks the options match the overlay (logo-mark.png, #FAF74F, width 100).
  • The same script rejects per-platform option overrides, so the native launch cannot fork by platform at config level.
  • New plugin test compiles the shared plugin for iOS and Android and asserts both native surfaces — the iOS storyboard color/logo and the Android color and launch style — come from the one option set.
  • The mounted overlay test now runs on both platforms across every startup outcome (app, login, consent, force-update, and each error screen), plus logo-timeout and no-replay-after-complete cases.
  • Review hints: iOS native behavior is unchanged; the risk sits in mod ordering and the Android capability exception. Start with withBrandedSplash.js and the config contract.

@iscekic
iscekic marked this pull request as ready for review September 19, 2026 12:07
Comment thread apps/mobile/plugins/android-splash-window-background.js
@iscekic
iscekic marked this pull request as draft September 19, 2026 12:18
@iscekic
iscekic force-pushed the kwf/explorer-app-cold-loading-cold-start-shows-a-bare-white-s-b6c69-4d7e branch from ac5fe31 to c424df6 Compare September 19, 2026 13:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant