fix(street-level): review round — safer docking, mount retry, provider fallthrough

- Only a user's own collapse docks a floating window; cockpit entry,
  restores and the Cyber accordion no longer dock it or delete its saved
  place, and the accordion leaves floating windows alone.
- The viewer host records an adapter as active only after its mount
  succeeds, so a library that failed to load once is retried; concurrent
  opens share one mount, and unmounting mid-mount leaves nothing active.
- openNearest tries every active provider; one provider's error (no key,
  offline) no longer hides the others' imagery.
- The SINCE readout shows its cut-off date as soon as the committed value
  matches the thumb, even while the slider keeps focus.
- A floating window that was only dragged is bounded to the viewport and
  scrolls instead of running off-screen.
- getStats summarises coverage (summarizeCoverage) instead of building a
  full UI snapshot every second; disable() uses credits.hideAll(); smaller
  cleanups in the viewer host and sequence snapshot.
- Unit tests: panel docking and header double press, viewer-host mount
  retry/sharing/cancel, coverage summary.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Said TurkseverandClaude Opus 5.5 committed 2026-09-25 20:56:12 +01:00
1 parent 5877f24f0b
commit 6207e4144e
12 files changed
+425 -55

No files matched your search

+12 -4
View File
@@ -341,11 +341,19 @@ export class StreetLevelControls {
button.classList.toggle('is-active', active);
button.setAttribute('aria-checked', String(active));
}
if (el.sinceRange && document.activeElement !== el.sinceRange) {
if (el.sinceRange) {
// Never move the thumb under the user's hand; once the committed value
// matches the thumb, show the full readout with its cut-off date.
const index = String(view.since.index);
if (el.sinceRange.value !== index) el.sinceRange.value = index;
if (el.sinceLabel) el.sinceLabel.textContent = view.since.label;
el.sinceRange.setAttribute('aria-valuetext', view.since.label);
if (
document.activeElement !== el.sinceRange &&
el.sinceRange.value !== index
)
el.sinceRange.value = index;
if (el.sinceRange.value === index) {
if (el.sinceLabel) el.sinceLabel.textContent = view.since.label;
el.sinceRange.setAttribute('aria-valuetext', view.since.label);
}
}
if (el.legend && el.legend.childElementCount !== view.legend.length) {
el.legend.replaceChildren(