Commit Graph
16 Commits
Author SHA1 Message Date
German KhokhlovandClaude Opus 5.5 6390a3346f Merge origin/main: Google Street View, KartaView and Panoramax on the slim Street Level
Main gained three imagery providers (Google Street View, KartaView,
Panoramax), shared line-coverage, cone and photo-viewer modules, one source
lit at a time and the translated interface. Their shared modules still
carried what this branch removes, so the merge ports them onto it:

- lineCoverage.js is this branch's coverage.js made provider-neutral
  (draped lines near the ground only, the selection drawn over them, key
  and rate-limit blocking); sequenceCones.js is sequences.js the same way.
  Mapillary, KartaView and Panoramax all build on them; Mapillary moves
  back to providers/mapillary/ beside the others.
- No ground casting, mesh sampling, surface modes, FOLLOW, legend, prewarm,
  orbit overview points (Panoramax's density dots included), stale-tile
  swaps or water-filled point budget come back.
- Kept from main because the new providers need them: requiresMapStack and
  attachMapStackController (Street View on Google 3D only), ground clicks,
  openNearest with an optional provider nearestImage, openImage {frame},
  reportError, the view-cone marker (now an SVG glyph), filters /
  coverageLabel / sinceBasis, OPEN STREET VIEW, keyAlternatives and i18n.
- photoViewer.js treats the viewer as expanded when its wrap is full screen
  or the iPhone popover, as EXPAND now is.
- The fixture browser gate keeps its 8 steps and adds one each for
  KartaView and Panoramax; catalogs, docs, boundaries and format scope
  follow.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-19 13:51:45 +04:00
Meir Michanie eb802408e4 Merge upstream/main: Street View rework meets i18n
Upstream's Street View rework (second imagery provider, one source at a
time, OPEN STREET VIEW button, key-alternative guidance) rewrote exactly
the street-level regions this branch localizes.

Resolved as upstream logic + re-applied localization:

- keySetupCore: new unlock copy kept as msg() data; added
  keySetupAlternativeKeyNames() returning machine values (registry key
  names) so key-setup core stays English while presentation localizes.
- New src/ui/keyGuidance.js: localized key-guidance composer shared by
  layerPanel and streetLevelPresentation (requirement sentence plus the
  "or light X to use your Y key" alternatives tail, placeholders only).
- streetLevelPresentation: keyGuidance()/presentNearest()/presentMeta
  relocalized (t/tn + formatNumber instead of toLocaleString);
  renderModes and month-precision dates kept from upstream.
- layer-panels.html: upstream row ids, sl-meta-row and the new button
  kept, data-i18n hooks re-applied (incl. OPEN STREET VIEW fallback).
- es/ru catalogs: 13 new keys, stale unlock key replaced in place.

npm run i18n: complete for es and ru. npm test: 6345/6347; the one
failure (devFreshDotenv provenance) also fails on plain upstream/main
and on the pre-merge tip here - this machine leaks OPENAI_API_KEY into
spawned children with a replaced env, so it is environmental.
2026-10-13 18:33:44 +02:00
Said TurkseverandClaude Opus 5.5 48ca99a38a fix(street-level): keep OPEN STREET VIEW whole beside a long coverage line
.scene-btn (flex: 1) loads after street-level.css and outranked the
button's flex: 0 0 auto, so with Mapillary and Street View both lit the
button shrank to its 72px minimum and its one-line label ran past the
panel edge. Scope the rule under .sl-meta-row; the coverage line wraps
instead. The live gate gives the share-link check 30 s, as the link is
written only once the view rests.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 13:36:01 +01:00
German KhokhlovandClaude Fable 5.1 c29ccd55d6 Merge origin/main: keep the provider registry, slim it
main grew the Street Level provider registry while this branch removed it
(#982–#985: injected providers, an empty composition, the `r` switch field).
The registry, params, uiState and pick router come back as main has them and
the slimmed layer sits behind the provider contract:

- The core (index.js) drives providers as on main, without surface modes,
  ground casting, FOLLOW, prewarm and nearest-image lookups. A provider's key
  status is asked with a 10 s timeout and asked again on a switch-on while no
  key is known.
- Mapillary is mapillaryProvider.js over the slim coverage, sequences and
  viewer modules, which read the filter and the active flag from the provider
  context.
- The viewer host mounts one provider adapter at a time, no prewarm.
- The panel has a chip per provider again (the pill switches the layer);
  no legend, EXPAND stays the Fullscreen API.
- The contract drops what no provider implements: groundCaster, meshSampler,
  getSurface/setSurface, nearestImage, prewarm, reportError, the legend and
  surface fields of the UI snapshot.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-13 13:24:25 +04:00
German KhokhlovandClaude Opus 5.5 6ff7afcc8b fix(i18n): translate the Street Level and Draw panels
Both panels landed after the original string extraction, so they rendered
English in every locale. Mark their markup and runtime text (status, SINCE
stops, provider tooltips, coverage meta, viewer captions, draw hints and
colours), the layer-list names kept in PANEL_LABELS, and add 90 es and ru
entries. Street Level is «Уличные снимки» / «A pie de calle».

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 18:32:28 +04:00
German KhokhlovandClaude Opus 5.5 ad58a0bdc4 refactor(street-level): trim QA, tests, styles and docs
The browser gate is one pass over the remaining flows: rail strip and
expand, coverage with fixtures, the ON/OFF pill, 360° and SINCE filters,
KEY REJECTED, nearest photo with caption, × close, phone fit, keyless
KEY REQUIRED on a second page and no page errors. Panel controls are
pressed through the DOM; pick-point search, line/cone clicks, the
framing-cancel, reload/share and status-route probes, the second
viewport and pointer-settling retries are gone (unit tests cover them).

Tests that pinned constants, copy, CSS or source text, or repeated
another test, are removed or merged. CSS loses an unused variable and
duplicate rules. Docs describe the slimmed feature; unused exports and
the layer's dead setCoverageFilter/refreshCoverage surface are removed.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-07 22:41:29 +04:00
German KhokhlovandClaude Opus 5.5 7dec7883aa refactor(street-level): simpler panel — native fullscreen, no FOLLOW button, no provider chips
EXPAND now uses the browser's Fullscreen API on the viewer element, which
stays in the panel; the hand-built modal (re-parenting to <body>, inert
siblings, focus trap, document-level Esc/Tab, Clean View/recording/cockpit
hide rules) is gone. The button is hidden where the API is missing.

The FOLLOW button and the PROVIDERS chip row are removed. The header pill is
the only layer switch and re-enables a provider switched off elsewhere; under
KEY REQUIRED the error line says which key to add. Chip colour support in
chipGroup, dead CSS and tests pinning the removed behaviour go with them.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-07 21:50:11 +04:00
German KhokhlovandClaude Opus 5.5 fbbc4cda5c refactor(ui): remove floating, resizable rail panels
PR #768 bundled a portable-panel windowing system with the Street Level
layer. Remove it so CCTV and Street Level are ordinary docked right-rail
panels again, as on main before the merge.

Removed:
- header drag to float, 8-way edge/corner resize, double-press snap-back,
  dockOnCollapse, command-dock clearance, float hint toast, floating z floor,
  persisted floating geometry and ResizeObserver re-clamping
  (panelPositionControls.js restored to its pre-#768 version)
- src/ui/panelResize.js and its tests, panelDock.test.mjs
- onPanelResized/dockPanel wiring in PanelChrome, the application shell and
  StreetLevelControls (EXPAND/SHRINK no longer docks)
- :not(.panel-floating) guards and .panel-floating/.panel-portable/resize CSS
- qa:panel-resize, qa-panel-resize.mjs, qa-panelDrag.mjs, their tests, the
  CI "Portable panel gate" step, QA_FAIL_ON_RETRY, and the Street Level
  gate's float/resize/dock steps
- floating-panel docs in README, CHANGELOG, CURRENT-STATE, KNOWN-ISSUES

Kept: the Street Level panel as a docked rail panel (share/cockpit/rail
lists, layout controller, rail and Cyber CSS, EXPAND viewer), and the
independent right-rail alignment fix (settledLeftRailTop, 9dde7b4).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-07 21:39:33 +04:00
Said TurkseverandClaude Opus 5.5 4ea6631425 docs(street-level): shorten docs and comments before merge
Trim the doc text this PR adds (README, CHANGELOG, CURRENT-STATE,
KNOWN-ISSUES, SECURITY, DATA_SOURCES, .env.example, the CI job comment),
drop code comments that restate the code, cut design-note JSDoc to a line
or two, and drop review tags from test names. Comments only; no code
changes.

Also: README key count (seven keys, two metered), CURRENT-STATE's gate
paragraph (CI runs a production build with a dummy token), the stacked
doc above meshBoxInRange and the orphaned inMeshRange line in
coverage.js, and a duplicate ALPR row in DATA_SOURCES that a merge had
brought back.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-06 21:59:12 +01:00
Said TurkseverandClaude Opus 5.5 038d8facc2 fix(street-level): modal viewer, pinned redirects, real-route CI checks
From the IC8 review of #768, each with tests that fail before:

- P2: the expanded viewer is a real modal: while it is on screen every
  other <body> child is inert (only the ones it set are restored, on
  shrink, close and destroy, and when Clean View/recording/cockpit hide
  it). The voice pill and toasts are not clickable while it is expanded.
- P2: the tile proxy follows redirects by hand, at most 3 hops, each one
  HTTPS on exactly https://tiles.mapillary.com without credentials;
  anything else is a 502 and the token never leaves that origin.
- P2: the real dev and preview server smoke tests request
  /api/mapillary/status and a tile, and the browser gate first checks the
  server's real status route before any interception, so CI fails if the
  Mapillary plugin is not registered.
- P2: both gates press panel headers through one shared helper
  (scripts/qa-panelDrag.mjs): re-resolve the header until it is under the
  pointer, record what the press hit, wait on the real floating/docked
  state, and retry only a press that provably missed the header.

Verified: unit 5910 pass; fixture gate 17/17; panel gate 5/5; live gate
with a real Mapillary token 22/22.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-06 15:16:57 +01:00
Said TurkseverandClaude Opus 5.5 48276450ec fix(street-level): the panel respects restores, modes, focus and keys
From gekh's review of #768, each with a test that fails before:

- P2: the panel no longer reopens on every page load. The shell reports
  who asked for Street Level to switch on; only a user, voice or tool
  request (isExplicitLayerStateOrigin) or an opening photo opens it, and
  those automatic opens are never stored. Without the hook, a stored or
  shared "collapsed" choice wins during the restore window.
- P2: the expanded photo hides in Clean View, recording and the cockpit,
  and holds neither Esc nor Tab while hidden.
- Esc/Tab are taken only from the viewer, body or globe, not app-wide;
  FIT/FILL show the right choice while expanded; a 0x0 viewer is never
  resized (no z=NaN tile request); the expanded viewer keeps the panel's
  CSS tokens; KEY REQUIRED hides the raw "no_key" code.
- Share links carry the panel's collapsed state (ui token t); the Cyber
  theme frames the panel like its rail peers (the pinned Cyber selector
  tests now list it).
- Accessibility: radiogroups move with arrow keys and are one tab stop,
  their focus ring is no longer clipped, and the provider chips sit
  outside the disabled fieldset so the "how to add the key" hint stays
  reachable (a gated chip explains instead of toggling).
- Renders write only changed attributes (the rail's MutationObserver
  relaid out on every write); one coalesced resize per open; the legacy
  render-mode key migration is gone.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 18:35:30 +01:00
Said TurkseverandClaude Opus 5.5 e6c2c812f9 fix(street-level): fit the whole photo on phones
At phone width the right rail is the band between mid-screen and the credit
line, so a 16:10 viewer plus its bar and caption was cut off. Below 720 px
the viewer's height is derived from that band (clamped 110-320 px); floating
and expanded viewers reset to auto height. The QA harness checks the photo
and caption fit at 390x844, and CURRENT-STATE documents the docking rules
and phone sizing.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-25 21:18:40 +01:00
Said TurkseverandClaude Opus 5.5 6207e4144e 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]>
2026-09-25 20:56:12 +01:00
Said TurkseverandClaude Opus 5.5 5877f24f0b feat(street-level): movable, simplified panel with the photo first
- The viewer opens at the top of the panel, under the header, so the photo
  is on screen without scrolling; its tools (EXPAND, FIT/FILL, FOLLOW, close)
  sit in a bar above the image, clear of the provider's own overlays, and the
  caption wraps instead of truncating.
- No separate ON/OFF or OPEN NEAREST PHOTO buttons: the header pill is the
  layer switch, and a provider chip is lit only while the layer is on (the
  last lit chip switches the layer off).
- SINCE is a stepped slider (any date to the last month) whose readout names
  the cut-off date and is announced via aria-valuetext.
- The panel floats and resizes (portable spec); in a resized window the
  viewer takes the spare height and only the settings scroll. SHRINK after
  EXPAND, collapsing, or a header double-click docks it at its default size.
- FIT/FILL tooltips say what they do.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-25 20:45:17 +01:00
Said TurkseverandClaude Fable 5.1 28e6a1faa7 feat(street-level): provider contract with Mapillary as the first provider
Street Level is now a provider-neutral layer modelled on the iD editor's
photo overlay. The core owns what every imagery provider shares: the
enable state and a switch per provider, the imagery filter (360°/flat and
captured-since in relative days), one click handler routed by pick prefix,
one viewer host that mounts whichever provider's viewer adapter owns the
open image, the position marker, camera follow, one on-globe credit per
active provider, and share-link parameters (one bit per provider plus the
filter). Providers implement the contract in registry.js: coverage,
sequences, nearest-image lookup and a viewer adapter emitting a common
pose. Mapillary is the only registered provider; Google Street View,
KartaView and Panoramax slot in beside it.

Panel: a PROVIDERS chip row (one chip per registered provider, keyless
chips read as errors), relative-day SINCE options, a provider-neutral
caption whose link label follows the provider, and no vendor mark in the
header. The panel inner is a rail scroller like CCTV's.

Tests cover the registry, params codec, filter, pick router, UI-state
composition, the provider definition and coverage-tile decoding; the QA
harness switches the provider off and on and checks the filter.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-25 18:34:09 +01:00
Said TurkseverandClaude Fable 5.1 2dbc684fb1 refactor(street-level): rename the Mapillary layer to street-level
Pure move: the layer id, panel id, CSS prefix, classes, exports and config
paths become provider-neutral (street-level, #street-level-panel, sl-);
the Mapillary-specific modules move under providers/mapillary/. Behaviour
is unchanged. The two sprite collections now register under distinct ids
instead of overwriting each other under 'mapillary'.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-25 18:13:53 +01:00