fix: handle dirty state before first build - #1064
Conversation
When library:changed marks Songs dirty before its DOM shell exists, reload cannot build the screen and the first entry remains blank. Reload only an already-built screen; otherwise continue through the full render path. Keep screen:changed as the primary navigation contract, preserve one rapid re-entry while entry is in flight, and remove the MutationObserver recovery that did not address this path. Signed-off-by: Ionut Adrian Ciolan <iadrian@ciolan.net>
📝 WalkthroughWalkthroughThe Songs screen now coordinates navigation entry events, avoids reloading before its DOM exists, and preserves queued or retried entry work. Tests cover event timing, repeated navigation, coalescing, rejection recovery, and initial rendering. ChangesSongs lifecycle
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant Navigation
participant SongsEntryLifecycle
participant SongsScreen
Navigation->>SongsEntryLifecycle: detect Songs activation
SongsEntryLifecycle->>SongsScreen: run entry work
SongsScreen->>SongsScreen: reload only when DOM is built
SongsEntryLifecycle-->>Navigation: preserve queued follow-up entry
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@static/v3/songs.js`:
- Around line 3942-3949: Update onScreenChanged() so runEntry() is called only
on a false-to-true transition of wasActive, ignoring duplicate v3-songs
activation events while already active. Preserve the existing leave-event
handling so a genuine leave followed by rapid re-entry can still queue one
rerun.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 07f27fb5-f12a-441d-a086-0481d32cfef2
📒 Files selected for processing (3)
CHANGELOG.mdstatic/v3/songs.jstests/js/v3_songs_entry_lifecycle.test.js
Summary
Fix the Song Library blank screen on its first activation when a library change arrives before the Songs screen has built its DOM shell.
screen:changedremains the primary navigation contract. The fix also keeps a one-time active-state check for late script registration and coalesces duplicate entry delivery while retaining one genuine rapid re-entry.Root cause
On cold startup,
library:changedcan mark the library dirty whilestate.builtis still false and#v3-songs-griddoes not exist. The first Song Library entry then took this path:reload()assumes the Songs DOM shell already exists, so the first entry stayed blank. The second entry reached the full render path and created the shell.The dirty path now reloads and returns only when the screen is already built; otherwise it falls through to the existing full render path.
Why remove the MutationObserver
Event-order instrumentation showed that
songs.jsevaluated, the event bus was available, listeners registered before navigation, andscreen:changedwas emitted and received. The class-onlyMutationObserverrecovery did not repair the dirty-before-first-build path and was unnecessary once the actual mechanism was fixed, so it was removed rather than retained as a second lifecycle source.TDD evidence
RED before the root fix:
reload=0, render=1; observedreload=1, render=0;GREEN after the root fix:
Reproduction and live verification
Ten cold-start trials per implementation:
Root-fix stability checks:
First-render latency samples in milliseconds:
Median:
169.5 ms. No pass/fail latency threshold was applied.Packaged-artifact check
A fresh signed downstream Arch package build completed successfully. Its packaged
songs.jswas byte-identical to the tested root-fix candidate:Summary by CodeRabbit
Bug Fixes
Documentation