Applying the rest of a posted view after the camera was taken during its
terrain wait still let it change the camera: stop_tracking dropped a follow
the user had just started, and annotate_map framed the view's marks. A
camera taken during the wait now ends the view again, as before. The 2 s
terrain timeout and the per-view catch on the queue stay.
- The look-at longitude wraps fully, so a tilted camera at a pole gives a
point on the globe. The strict off-globe check on street_level is undone:
points are clamped again, as before.
- A posted view that fails is answered, and the views behind it still apply.
- A posted view waits at most 2 s for the terrain under its camera, then
keeps its own estimate.
- A camera taken during that wait stays where it is: the rest of the view
applies, and only its photos stand down.
- show_street_level keeps a search or a press on the globe made during its
own flight: it adopts only its own navigation stamps on landing, and a
gesture is never forgiven.
- Releasing a held viewer frees the old source's adapter without resetting
the panel, so a replacement's error, outcome and armed OPEN survive; a
cross-source replacement drops the old photo's details and marker.
- The action holds the open photo only for its own switch-off: a source
switched by hand during the load stops it and reports cancelled.
- A posted view waiting on terrain watches the camera and stands down after a
navigation or a globe press; a flat or straight-down camera asks no terrain.
- An arming link opens the panel without persisting the layout, and a posted
view's street-level step runs as programmatic.
- An off-globe street_level point throws TypeError.
- zh-Hant uses the file's wording for the new strings; README and
CURRENT-STATE count 35 tools.
show_in_gods_eye_view measured a view's altitude from the terrain before
taking the point the camera looks at; a view posted straight into the
embedded app used the ellipsoid altitude, so a camera over high ground
opened photos kilometres ahead. groundedLookAt moves to the view module,
and the embedded app uses it with the app's terrain heights for a posted
street_level that names no point.
- Comments in the action, the layer, embed, the Mapillary policy and the
controls say why in fewer words; restatements of the code are gone.
- CURRENT-STATE's "Show me X on Street View" section is a list by topic and
no longer says the browser gate aims at coverageLines.
- TOOLS.md's street-level view paragraph is shorter.
- A link's photo step compares with the navigation token its own restore
flight owned, so a navigation after the flight landed (while the layers
still load) keeps the camera.
- A request that switches the source keeps the open photo up until it is
replaced (holdViewer), so EXPAND stays across sources.
- A lookup given up while it looked leaves the open photo and the panel as
they were, also when it found nothing or failed.
- A failed replacement shows its error inside the expanded viewer.
- A replacing lookup stops a playing Mapillary sequence before the found
photo opens.
- The action refuses coordinates outside the globe, keeps a name given with
coordinates as its label, and fly: false keeps the camera only for
coordinates (its test-only entity and query branches are gone).
- Numbered entities carry their label; a view's street-level point is a pair.
- Mapillary's nearest search always asks for 50 m and 100 images.
- Tests: the lifecycle reproductions, PLAY on replacement, out-of-range
coordinates, half a point, and the named label; three layer tests share
enabledLayer; the second payload digest is gone.
- Docs: the tool count, the panel freshness rule, armed: false, the photo
replacement, the browser-gate comment and a shorter changelog fragment.
- A pasted or start-up link opens its photos only when its restore's camera
landed: a drag or search during the restore flight keeps the camera.
- A posted view whose photo step was cancelled or superseded no longer closes
the viewer or flies; one that found a photo it could not load keeps the error.
- openNearest gains `replace` (keep the open photo while it looks, close it
only when nothing opens, so EXPAND stays) and `proceed()` (asked before a
found photo loads); the action uses both, so a navigation, a gesture or a
hiding mode during the lookup loads no billed panorama.
- Mapillary's timeout message is a msg() string with all eleven translations.
Address samehkhamis's review on #1113:
- show_street_level checks the turn, the camera's owner (navigation stamp,
re-taken where its own flight lands, or a press/wheel on the globe) and
the hiding modes after the flight, the map switch, the layer switch-on and
the lookup; a photo that opened after either is closed again. The hidden
panel is also refused before the flight.
- An open photo closes before a new request arms or looks up, so a place
with no imagery shows its own error.
- The panel posts every view with `fresh`; the inline app opens a billed
photo only for a fresh one.
- A passed-through view's street_level point moves with a new camera
position; revealPanel does nothing above 720px, scrolling included.
- Document that the app's own links do not carry `sl`.
Review fixes for gekh's #1113 round:
- a link runs show_street_level with origin 'programmatic', so its source
switch and layer are not saved as the recipient's preferences;
- with no place named, the action looks under the screen centre
(aim 'screen-centre', armed false), keeps the sky refusal and leaves a
link's armed point alone;
- an armed OPEN aimed at the sky opens nothing instead of the far link point;
- an imagery-stage failure is spoken as an error, missing imagery as missing
(street.nearestOutcome); the card says "the view centre" in the interface
language;
- every photo the action opens reveals its panel, and revealPanel scrolls the
panel into view in the phone sheet;
- embed: EXPAND survives embed's own clean view, the lifted photo hides in
cockpit, recording and scene playback, and a failed photo step closes the
earlier photo before the view flies;
- links pasted into an open tab run their street-level step after the
restore settles; a superseded start link does not;
- Mapillary's nearest search gives up after 12 s, body included.
P1: on a phone the Street Level panel sits in the Cameras tab sheet, so the
action and sl= links opened photos nobody could see and still reported
success. A photo that opens, and a link that arms, now open that sheet
(revealPanel). In cockpit, clean view, recording or scene playback the action
stops at a new `view` stage before anything switches or loads.
P2s:
- Mapillary's nearest search asks for 100 photos, the API's most. It cuts
the radius's photos at the limit in no particular order, so 8 left the
distance sort and the imagery filter a few arbitrary photos.
- The MCP globe panel opens a billed photo only for a result issued in the
last five minutes (show_in_gods_eye_view stamps issued_at); a host that
mounts the panel again hands back the old result, which only arms.
- OPEN uses an armed link's point only while the view centre is within 1 km
of it; a user who moved on opens what the view shows.
- show_in_gods_eye_view measures a camera's altitude from the terrain under
it before taking its look-at point, so high cities no longer put the
photos kilometres too far ahead.
- The armed-link toast is translated, and the new view-stage message too,
in all 11 catalogs.
- Tests: a turn superseded during the geocode, flight or map switch changes
nothing; an unknown key state lets a cold sl= link through; a wide tilted
area still opens photos at its centre.
show_street_level (voice and typed) flies to a place and opens its nearest
street-level photo from Google Street View, Mapillary, KartaView or
Panoramax; Street View switches to Google 3D first. The view model gains a
street_level field, share links carry sl=<source>,<lat>,<lon>, and
show_in_gods_eye_view can open a photo. A plain sl=google link only arms the
point and waits for OPEN, so it never bills a key without a click.
Embed pages show an open photo in an overlay that Esc closes. On-screen
strings are translated into es, ru, zh-CN and zh-Hant. Covered by unit tests
and three new steps in the Street Level browser suite.
Main now has #1282, which pauses periodic layer polling in a hidden page
with its own catch-up and listener cleanup, so this PR drops its duplicate
lifecycle.js change and test in favor of main's.
Review fixes:
- data.js passes panelAwareVisibility(document) (new in app/embed.js) as
the lifecycle's visibility target, so an inline panel whose host reports
it hidden keeps polling. The HUD's 250 ms readout follows the same
document.hidden && !isEmbeddedInline() rule as tools.js.
- Tests: embed.test.mjs (layers poll in an inline panel reported hidden,
pause without the flag) and hudPageVisibility.test.mjs (HUD readout).
Both use mock timers and clean up in finally.
- changelog.d/1344-inline-panel-visibility.md and a note in
docs/CURRENT-STATE.md.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Knip, configured with the application, package exports, scripts, QA
harnesses, workers, tools and tests as entry points, reports exports
that no module imports. Each was checked by hand against string-based
and namespace imports.
- Symbols that are still used inside their own module lose only the
`export` keyword (176 constants and helpers).
- Unused re-exports are removed from barrel modules (flight, military,
vessel, CCTV, directions, transit history, local ADS-B and street-level
policy modules).
- Declarations that nothing uses at all are deleted, among them
AIS_WATCHDOG_STATUSES, applyFilter, isRadioCountryCode, compactText,
DENSITY_STOPS, the unused CCTV endpoint constants, and the SDR band
constants.
- Default exports that nothing imports are removed. The ones in
src/data/earthquakes.js, src/data/telegeographySubmarineCables.js,
src/data/wind.js and src/data/bhoteKoshiLocator.js each constructed a
layer instance at import time that nothing used; those instances are
no longer created.
Every export of a package.json entry stays, as does TOMTOM_CREDIT,
which the traffic layer reads from the credits namespace it is given.
Embed-mode documents now keep the server's framing protection unless
GEV_EMBED_FRAME_ANCESTORS names the pages that may frame them (or * for any
page). The MCP Apps panel loads the app into its own page and needs no
framing. View answers are posted to the origin that sent the view rather
than to any origin.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
A view's follow may ask for cockpit view, which the app enters after it
follows the aircraft; links cannot carry it and open the app following.
Applying a view no longer flies the camera when the followed entity is
already there, since the flight ended the follow; it flies only while
waiting for the entity. The panel applies its first view again only
when it asks for cockpit view.
Drop the render restarts added while chasing the black overlays; keep
the full render-error report and stop the timer after an error, as
Cesium does. Correct comments the investigation outran, share the
panel_request name, and document the host differences the panel works
around.
Cesium stops drawing after a render error and prints worker failures as
[object Object]. An inline panel now logs the error's details and starts
drawing again, up to three times.
Claude reports a panel on screen as hidden, which stopped the app's
render loop and the browser's animation frames, so no map was drawn. An
inline panel no longer suspends rendering when hidden, and draws from a
timer while animation frames stop arriving.
Hosts such as Claude do not let a panel frame other sites, so the panel
now loads the app's page, styles and scripts into itself in inline embed
mode, and declares the app and map providers as resource and connect
domains. The dev server answers panel origins with CORS.
?embed=1 shows the globe alone: clean view with the HUD, panels, welcome and
setup prompts hidden, and provider attribution kept. The page that frames it
sends views with postMessage; the app applies each through its own actions
and reports every step. Annotations in any link are drawn once it restores.
Only embed-mode documents may be framed; every other page keeps
X-Frame-Options DENY and frame-ancestors 'none', and
GEV_EMBED_FRAME_ANCESTORS can restrict who frames them.