Fix review findings: readout occlusion, contrast, date bounds, disposal#7
Merged
Merged
Conversation
Review of the planetarium surfaced several defects, verified against a production build driven in Chromium. Selected Object readout was unreadable. It anchors bottom-left, but the Location + Time panels fill the left column at common window sizes and the Time panel paints over it — only a ~14 px sliver showed at 1280x720 and 900x600. updateChromeLayout now slides the readout clear to the right of that column when they would overlap, mirroring the existing Reset All vs. Display panel avoidance. `left` is computed once and assigned once because this runs re-entrantly from selectionPanel.boundsProperty. Search results were invisible. Result rows and the "no matches" line sit on the dark panel fill but used LIGHT_SURFACE_TEXT_FILL (near-black), giving ~1.04:1 contrast; the highlighted row was white on the light accent at 1.81:1. Both now take the correct side of that pairing, and the rule is written down in CLAUDE.md so the mixup does not recur. The `date` deep link accepted any parseable timestamp while the UI is bounded to 1900-2100, so ?date=1850-01-01 silently rendered 1900 and ?date=2150-06-01 rendered 2100 — a shared link showed a different sky than it named. The parameter is now validated against CIVIL_TIME_MS_RANGE (derived from CIVIL_YEAR_RANGE) and falls back to the documented default. Civil time is held inside the same range at runtime via setCivilTimeMs(), so playback stops at the edge instead of leaving the Year spinner displaying 2101. The epoch combo always read "Custom time": the timer starts playing, so the first step advanced civil time a few milliseconds and marked the preset CUSTOM while the minute-precision readout still showed the preset epoch. It now flips only once the clock is a full minute off, matching the readout. Locale parity only asserted en<->fr, so a key missing from strings_es.json was not a build error despite CONVENTIONS.md sec. 4 requiring it. Both directions are now asserted for es as well (verified by deleting a key). Also: dispose SelectedObjectReadout's axon graph (a Multilink, ~20 DerivedProperties and their pattern Properties stayed subscribed to the model and StringManager after teardown) and call it from ZenithScreenView.dispose; drop the empty `credits` block that rendered blank rows in Help > About; replace literal rgba(0,0,0,0) hit-target fills with Color.TRANSPARENT; remove the unused ZenithPreferencesModel.reset(), which invited wiring preferences into Reset All against the documented contract; and document the "Use my location" third-party IP fallback in the README and model doc. Tests: 154 -> 163. npm run lint, check, build, and test all pass.
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A review of the planetarium turned up ten issues. Each was reproduced against a production build driven in Chromium (not just read off the source), and each fix was re-verified the same way.
User-visible defects
The Selected Object readout was unreadable. It anchors bottom-left, but the Location + Time panels fill the left column at common window sizes and the Time panel paints over it — only a ~14 px sliver showed at both 1280×720 and 900×600. Since "click to identify" is a core feature, its primary output being hidden is the most serious item here.
updateChromeLayoutnow slides the readout clear to the right of that column when they would overlap, mirroring the existing Reset All vs. Display panel avoidance.Search results were invisible. Result rows and the "no matches" line sit on the dark panel fill but used
LIGHT_SURFACE_TEXT_FILL(near-black) — 1.04:1 contrast. The highlighted row was white on the light accent at 1.81:1. Both now take the correct side of that pairing (~15:1 and ~9.6:1).ZenithButtonOptions.tsalready warned about this mixup in the opposite direction; the rule is now written down inCLAUDE.mdso it does not recur.?date=rendered a different sky than it named. The parameter accepted any parseable timestamp while the UI is bounded to 1900–2100, so?date=1850-01-01silently showed 1900 and?date=2150-06-01showed 2100 — a shared classroom link quietly resolving to the wrong epoch. It is now validated against a newCIVIL_TIME_MS_RANGE(derived fromCIVIL_YEAR_RANGE) and falls back to the documented default with the standard invalid-parameter notice. Civil time is held inside the same range at runtime throughsetCivilTimeMs(), so playback stops at the edge instead of leaving the Year spinner displaying 2101.The epoch combo always read "Custom time". The timer starts playing, so the first
step()advanced civil time by a few milliseconds and marked the preset CUSTOM while the minute-precision readout still showed the preset epoch. It now flips only once the clock is a full minute off, matching the readout — so the selector can actually display a preset, including right after one is chosen.Correctness and hygiene
strings_es.jsonwas not a build error despite CONVENTIONS.md §4 requiring it. Both directions are now asserted forestoo — verified by deleting a key and watchingnpm run checkfail.SelectedObjectReadoutnever released its axon graph — aMultilink, ~20DerivedPropertys and their pattern Properties stayed subscribed to the model and the sharedStringManagerafter teardown. It now disposes in dependency order andZenithScreenView.dispose()calls it.creditsblock, which rendered blank labelled rows in Help → About.rgba(0,0,0,0)hit-target fills withColor.TRANSPARENT.ZenithPreferencesModel.reset(), which invited wiring preferences into Reset All against the documented "preferences outlive Reset All" contract.get.geojs.io,ipapi.co) in the README and model doc — it was explained in code but nowhere a teacher would look.Verification
npm run lint,npm run check,npm run build, andnpm testall pass. Tests: 154 → 163, adding coverage for the epoch tolerance, the civil-time clamp, out-of-rangedatelinks, and readout disposal (GC reachability plus no-throw-after-dispose).Re-driving the production build in Chromium confirms the readout is fully legible at both window sizes, search results are readable, the epoch combo shows the preset, and
?date=1850-01-01falls back to 2024-06-21 18:00. The Sirius readout also checks out astronomically — RA 6.75 h, Dec −16.7°, mag −1.46, transiting in 1h 43m from LST 5.03 h.Not addressed
The invalid-parameter dialog renders joist's own untranslated
Property#464{...}placeholders. That is pre-existing framework string loading, unrelated to these changes, and left for a separate look.🤖 Generated with Claude Code
https://claude.ai/code/session_01P93K8JHzi5ytJDsGm1w1K9
Generated by Claude Code