Commit Graph
1037 Commits
Author SHA1 Message Date
Sameh Khamis e200e46695 Merge branch 'main' into fix/e-context-heading-north 2026-11-01 21:41:48 -08:00
Sameh Khamis 0e942de38c Merge branch 'main' into fix/e-cctv-heading-north 2026-11-01 21:28:43 -08:00
Sameh Khamis 87e2a2eaa8 Merge branch 'main' into fix/b-vessel-course-north 2026-11-01 21:16:27 -08:00
Sameh Khamis 188dd4fd29 Merge branch 'main' into fix/e-alpr-direction-360 2026-11-01 21:04:29 -08:00
Sameh Khamis 37d12ad731 Merge branch 'main' into fix/e-context-heading-north 2026-11-01 20:53:42 -08:00
Sameh Khamis c62e580d7e Merge branch 'main' into fix/e-cctv-heading-north
# Conflicts:
#	src/ui/cctvPresentation.js
2026-11-01 20:52:40 -08:00
Sameh Khamis 08265d94d4 Merge branch 'main' into fix/b-vessel-course-north 2026-11-01 20:52:20 -08:00
Sameh Khamis 66d7a4ebce Merge branch 'main' into fix/e-transit-heading-north 2026-11-01 20:52:05 -08:00
Sameh Khamis bc5d038afd Merge Core main into german/hal-644-ar: Arabic on the Vue UI
Main moved the UI to Vue views and Pinia stores, so the Arabic changes to
the old DOM controllers now live in their views: the rail legend range
comes from formatScaleRange (keeping units a source supplies as given),
the voice timeout options are worded by Intl unit formatting in
VoiceControl, and the scene editor's JSON fields stay left to right in
SceneDialog. Main's CCTV status line, launch panel and calibration values
keep the Arabic isolates and Western-digit formatting.

isolate() and keepCodesWithValues() read the locale through getLocale(),
which follows the page's vue-i18n instance, and the Intl formatters take
intlLocale(getLocale()). A language switch now applies in place, and
applyDocumentLanguage sets <html dir> on every switch, so the page mirrors
without a reload.

The icon rails and their tips are placed with logical properties, so they
stay on the outer side of the mirrored stacks; Cyber's new stack offsets,
padding and edge lines are logical too, and rtl.css moves Cyber's right
stack to its new rail clearance. Main removed the Context mini radio, so its
right-to-left rules and test go.

The Arabic catalog gains main's new strings and drops the ones main no
longer uses; the other catalogs keep main's new keys and the branch's
landing labels.
2026-11-01 20:15:02 -08:00
Sameh Khamis 5605fdc60a Merge Core main into sameh/core-vue
railCardBlocks.js is the Vue wrapper on this branch, so main's verbatim
legend units move into RailCardBlocks.vue.
2026-11-01 17:37:56 -08:00
Sameh Khamis b20c80e590 Switch language in place, without a reload
Choosing a language in the picker now applies it at once. The choice is
stored and ?lang is kept in step through replaceState, and the picker keeps
focus.

Code that writes translated text itself re-presents it on a switch:
onLocaleChange() lets an owner listen, removed at teardown, and status
writers hand over a function of the locale (voice cards, scene director,
SDR, draw hints, imagery split, map sources, Bhote Koshi media) so the
words are rebuilt rather than re-sent. The HUD, cockpit, radio, CCTV,
launch, awareness and credit texts follow the same hook, and
applyDocumentTranslations can be applied again without undoing text code
wrote since.

The unsaved-work registry and persistLocaleAndReload existed only to guard
the reload, so they go, with their catalog entries.
2026-11-01 16:47:39 -08:00
Sameh Khamis e5fa31d01e feat(controls): render every segmented group with UiSegmented
Street Level's fit and panorama filters and Recent Imagery's mode render
through the kit's UiSegmented, and their owners answer the choice
through the Street Level store (setPano, setRenderMode) and the
readout's onSetMode. The imperative segmentedControl.js adapter and its
test go. UiSegmented moves focus at once on a key, a radio group from
the option holding focus and an arrows group from the selection, and
asks for a change only when the key lands somewhere new.
2026-11-01 10:38:25 -08:00
Sameh Khamis 039b0828b7 Let a weather source describe its own products
A weather source can describe its own products (credit, units, coverage,
legend) through an optional `display` object in each product manifest:
source, credit, units, coverage, info, legend and extent. The weather
layer uses each valid field in the row summary, legend, info text,
coverage navigation, outside-coverage status, layer stats and imagery
credit, and keeps today's built-in value for any field that is absent or
invalid. Units and legend describe one scale, so they apply only as a
valid pair; otherwise both keep their built-in values, and the radar
info heading names the units in use.

Text is single-line and length-capped. It rejects control characters
(U+0000-U+001F, U+007F-U+009F), line and paragraph separators, and
invisible or format characters: soft hyphen (U+00AD), combining grapheme
joiner (U+034F), Arabic letter mark (U+061C), Mongolian vowel separator
(U+180E), zero-width and direction marks (U+200B-U+200F), bidi embedding
and override (U+202A-U+202E), word joiner, invisible operators and bidi
isolates (U+2060-U+2069), variation selectors (U+FE00-U+FE0F), the
byte-order mark (U+FEFF) and tag characters (U+E0000-U+E007F).

Legends need 2-16 stops whose labels are plain decimal numbers or short
text and whose colours are #rrggbb. A number label must read back
exactly as the legend shows it: within the safe integer range, with no
leading zeros and no digits lost to rounding. Extents must be finite, in
range and non-empty. Supplied source and units text is data: the layer
marks it so the panels show it untranslated, while built-in values are
translated as before.

The imagery credit is escaped as plain text and follows a refreshed
manifest even when the shown frame stays the same. A refresh changes
only the credit: the shown frame keeps the snapshot it was staged from,
so a later host switch restages it with its own time and bounds and the
refreshed credit. Manifests without `display`, including the bundled
nowCOAST ones, render exactly as before.
2026-10-31 22:42:01 -07:00
Sameh Khamis 3c391482f6 feat(ui): render the status chips and their split-flap labels from a store
ShellFeedback publishes the loading status and the road network chip, and
CctvControls the camera grid chip, to the gev-status store; the scene
chrome renders them. SplitFlapText plays the departure-board cascade that
splitFlap.js plans, writing only the label's one text node, and rests when
its owner is destroyed. setSplitFlapText and disposeSplitFlap are gone.
2026-10-31 19:51:39 -07:00
Sameh Khamis 2ffd7a4afd refactor(ui): remove the action button and status badge builders
The Vue views apply the gev-action-button and gev-status-badge classes
themselves, so the DOM builders have no users left. The docs describe the
views instead.
2026-10-31 18:40:25 -07:00
Said Turksever 84028f71fe Merge branch 'main' into fix/e-draw-area-unit 2026-10-31 23:18:42 +00:00
Sameh Khamis bca7495cbf feat(ui): render the generated style parameter rows through Vue 2026-10-30 23:23:58 -07:00
Sameh Khamis 6c7035f617 feat(ui): render the CCTV calibration readout and its pose editor from the store
presentCctvCalibration() joins the panel view: ADJUST, SAVE CAL, RESET CAL
and the seven pose chips render from the gev-cctv store. The inline editor
is store state: starting an edit publishes its field, starting value and
finish(), and the CctvCalValue chip renders the number input. The draft is
set once on mount so a refresh while typing keeps it; each edit gets its
own input. Commit and cancel rules, the captured base pose and the camera
guards stay with CctvControls.

formField.js had no other user and is removed.
2026-10-30 21:45:24 -07:00
Sameh Khamis ce6040bde1 feat(ui): render the rail timeline as a component behind its builder
The observed-history transport is RailTimeline in src/ui/rail/, rendered
by createRailTimeline() with the same update and destroy API. Drag preview,
the coalesced 150 ms commit, release, cancel and blur behave as before; the
slider keeps the ticks it is dragged over, an update from inside a preview
cannot move the handle back, and readouts follow the handle within the same
task. utcClock moves to its own module and is still exported here.
2026-10-30 18:41:31 -07:00
Sameh Khamis 6802c9c8b0 feat(ui): render every application template except the loading screen as a Vue view
The scene chrome, cockpit, Display controls, command dock, layer panels,
Context rail, welcome card and Provider Settings move verbatim into
src/ui/views and mount into their hosts before the page is translated and
wired. Each view renders the same elements, attributes and text as its
template; Vue keeps whitespace between elements as one space, and no view
markup sits under a white-space: pre rule.

Template asset URLs stay literal, view files are left out of Prettier so
the markup is not reflowed, and the Node component loader moves to build/
and is exported as build/register-vue for host test runners. Hosts that do
not initialize Core's locale pass localePicker: false instead of editing
the markup.
2026-10-30 17:47:52 -07:00
Sameh Khamis 3d5d3ef014 feat(ui): add a desktop panel rail to each sidebar
Each side stack hosts a Vue rail listing its panels; selecting one opens it
through PanelChrome. The shell owns one Vue runtime and Pinia instance, and a
panel store mirrors each side's panels from the DOM. The rail hides with its
stack, in Cockpit, clean view and recording, and on phones. Panels without a
catalog entry get a generic item, and Data Layers leaves the rail while the
f shortcut hides it.
2026-10-30 16:41:29 -07:00
Said Turksever 3119b2cf9c Merge branch 'main' into authoring-panel 2026-10-30 16:40:50 +00:00
Said Turksever b442cfdb54 Merge branch 'main' into panel-chrome-consistency 2026-10-30 16:09:12 +00:00
Said Turksever 3a681accfa Merge branch 'main' into fix/firms-ipv4-fallback 2026-10-30 15:08:35 +00:00
Said Turksever 47f3377d2b Merge branch 'main' into panel-chrome-consistency 2026-10-30 15:00:57 +00:00
Said Turksever 38302a27a4 Merge upstream/main into feat/cctv-a22-autobrennero
Resolve conflicts with the NYC, Toronto, Lithuania, Florida, Taiwan and
Kartverket work on main. The CHANGELOG entry moves to
changelog.d/956-a22-brennero-webcams.md, as main now asks.
2026-10-30 14:50:41 +00:00
Said Turksever df01964171 fix(firms): keep the IPv4 retry from crashing the server; guard the call sites
- fetchIpv4 builds its Response inside the https response callback, outside
  the promise. A 204, 205 or 304, a status above 599 or an invalid reason
  phrase made the Response constructor throw there, an uncaught exception
  that stops the dev server. Null-body statuses now get a null body and
  anything else that cannot become a Response rejects, as the Radio Browser
  transport does.
- A non-OK FIRMS or mapkey-status response cancels its body so the IPv4
  socket closes at once instead of at the deadline.
- Tests: the crash cases (fail on the old code), a source check that every
  upstream request goes through fetchFirms and that fetchSource's body read
  shares its deadline (fails if either call reverts to fetch), a real-fetch
  contract test for the address-selection error shape, and an explicit skip
  in the IPv4-only socket test where the host cannot tell the families apart.
- Changelog entry moves to changelog.d/1078-firms-ipv4-fallback.md per
  CONTRIBUTING; CURRENT-STATE says which timeouts are retried and that the
  retry does not follow redirects.
2026-10-30 14:50:27 +00:00
Said Turksever bae3433b24 Merge upstream/main into fix/firms-ipv4-fallback
Resolve fetchSource onto main's shared deadline: one AbortSignal covers the
fetchFirms request and the capped body read. The CHANGELOG entry moves to a
changelog.d fragment in the next commit.
2026-10-30 14:50:27 +00:00
Said Turksever 44f9138d1e Keep panel titles inside their cards and scope the hover
Collapsed Recent Imagery (English) and Data Layers (Portuguese) pushed
their toggles out of the card. Collapsed rail launchers now drop the
divider and pack closer, translated collapsed titles use compact type,
and any title that still does not fit ends in an ellipsis.

The hover now matches the dock trays' hover rather than their pinned
look, only on pointers that can hover, and recolours only the hovered
panel's own header, so Radio and body labels keep their colours.

The cyber theme keeps main's gutters and Display toggle size, the dock
and rails share --dock-label-* tokens, and the dimmed open Context title
rule is gone.
2026-10-30 13:05:33 +00:00
Sameh Khamis 93942d0dbe Show only the CCTV cameras in view, thinned to one per ground cell when zoomed out
The CCTV layer kept every loaded camera live: each view change touched every
icon, every notification rebuilt every camera's state, and the picker listed
the whole catalog. With the default 4,000 cameras, a continental drag ran at
152-179 fps with 18-24 frames over 30 ms (worst 112 ms). It now runs at
235 fps with none. The layer now:

- shows icons only on or near the screen, and when zoomed out keeps one camera
  per world-anchored cell (healthy feeds first), so panning keeps the same
  cameras;
- grounds and draws coverage only for the cameras in view, the active camera
  and its coverage neighbours, retrying a camera at most twice per view regime;
- reruns the view pass while the camera moves, paced by its own cost, and
  projects with one matrix per pass instead of a Cesium call per camera;
- keeps the billboard buffer-usage hint fixed, so showing or hiding a few
  icons no longer rewrites the vertex data of every billboard;
- lists the cameras in view (active camera first) in the picker, closing with
  the count of cameras outside the view, and builds the full camera list in
  the UI state only when it is read.
2026-10-29 21:31:59 -07:00
Said Turksever 2b05461232 Merge remote-tracking branch 'origin/main' into authoring-panel
# Conflicts:
#	docs/CURRENT-STATE.md
2026-10-29 18:40:02 +00:00
Said Turksever 5a80facf8d Address review: playable PLAY/NEXT, visible rename editor, accurate copy
- PLAY and NEXT continue into the following scenes, so they stay
  enabled while any scene in the project has a shot, not only the
  selected one.
- Renaming a shot drops the number and ellipsis so the editor is no
  longer hidden; qa-scene-controls checks a long rename stays visible.
- PLAY, NEXT, EDIT DETAILS and SHARE SCENE tooltips describe what the
  buttons do, translated in every shipped language.
- The primary actions and the file row keep a hover state.
- Docs: the EXPORT rename in DIRECTOR-SHARING and the playback button
  states in CURRENT-STATE are accurate.
- Test the voice "authoring" alias through set_panel_open.
2026-10-29 18:39:53 +00:00
Said Turksever a370742e25 Merge remote-tracking branch 'origin/main' into ux/context-panel-cleanup 2026-10-29 16:42:17 +00:00
Said Turksever 9520238bfb Move the changelog entry to changelog.d and clear review leftovers
The entry now lives in changelog.d/1471-context-panel-cleanup.md with
credit, as CONTRIBUTING asks, and CHANGELOG.md is back to main.

CURRENT-STATE no longer lists a compact Radio power control and scopes
the readability description to what Cyber keeps. The responsive glow
comment no longer cites the removed Radio popover, and qa-radio's
pick-buffer comment is back above settleRadioFrames.

Four test fixtures stop stubbing the removed launcher sync, and
PanelChrome drops the _syncRailPanelCollapseButton pass-through, wiring
the layout controller straight to _syncPanelCollapseButton.
2026-10-29 16:35:44 +00:00
Said Turksever c227f89852 Merge branch 'main' into fix/remove-operator-hud-layout 2026-10-29 16:23:27 +00:00
German Khokhlov 188a6086b8 Merge remote-tracking branch 'origin/main' into german/hal-644-ar
# Conflicts:
#	docs/CURRENT-STATE.md
#	docs/TRANSLATORS.md
#	scripts/package-boundaries.json
#	src/hudLocalityFormat.js
#	src/i18n/index.js
#	src/i18n/locale.js
#	src/i18n/same-as-english.json
#	src/layers/cctv/presentation.js
#	src/scenes/recipes.js
#	src/ui/localePicker.test.mjs
#	src/ui/unitLabels.js
2026-10-29 20:05:03 +04:00
German Khokhlov 812308d0ee Merge remote-tracking branch 'origin/main' into german/hal-642-ja
# Conflicts:
#	docs/CURRENT-STATE.md
#	docs/TRANSLATORS.md
#	scripts/package-boundaries.json
#	src/i18n/i18n.test.mjs
#	src/i18n/index.js
#	src/i18n/locale.js
#	src/i18n/same-as-english.json
#	src/layers/cctv/presentation.js
#	src/ui/localePicker.test.mjs
2026-10-29 19:47:54 +04:00
Said Turksever d0059575d4 Merge branch 'main' into fix/remove-operator-hud-layout 2026-10-29 15:45:26 +00:00
Said Turksever 8348402a56 Merge branch 'main' into fix/remove-operator-hud-layout 2026-10-29 15:39:45 +00:00
German Khokhlov a092933ad6 Merge remote-tracking branch 'origin/main' into german/hal-639-de
# Conflicts:
#	docs/CURRENT-STATE.md
#	docs/TRANSLATORS.md
#	src/i18n/i18n.test.mjs
#	src/i18n/index.js
#	src/i18n/locale.js
#	src/layers/cyclones/source.js
#	src/scenes/recipes.js
#	src/scenes/sceneTitleDisplay.test.mjs
#	src/ui/localePicker.test.mjs
2026-10-29 19:00:19 +04:00
German Khokhlov b84f7f346c Merge branch 'main' into german/hal-638-fr 2026-10-29 18:26:36 +04:00
Said Turksever adb21d098d Merge branch 'main' into fix/remove-operator-hud-layout 2026-10-29 14:22:01 +00:00
Said Turksever aa0f6d4e52 Remove the HUD top bar that no layout shows
Operator was the only layout that displayed the top banner bar. Its markup, styles and keep-out selectors are removed, and the Cyber style test now checks that none remain.
2026-10-29 14:04:28 +00:00
Said Turksever 3bcdc16dde Merge branch 'main' into fix/remove-operator-hud-layout 2026-10-29 13:55:54 +00:00
German Khokhlov 727825b576 Merge remote-tracking branch 'origin/main' into german/hal-638-fr
# Conflicts:
#	docs/CURRENT-STATE.md
#	docs/TRANSLATORS.md
#	scripts/package-boundaries.json
#	src/i18n/i18n.test.mjs
#	src/i18n/index.js
#	src/i18n/locale.js
#	src/i18n/same-as-english.json
#	src/scenes/recipes.js
#	src/ui/localePicker.test.mjs
#	src/ui/templates/context.html
2026-10-29 17:55:01 +04:00
Said Turksever 1990228889 Merge branch 'main' into fix/remove-snow-preset 2026-10-29 13:53:35 +00:00
German Khokhlov 4ed06fac22 Merge branch 'main' into fix/remove-operator-hud-layout 2026-10-29 17:45:40 +04:00
German Khokhlov 4877be7f9b Merge branch 'main' into fix/remove-snow-preset 2026-10-29 17:45:25 +04:00
German Khokhlov 95ded4c6b9 Merge remote-tracking branch 'origin/main' into german/hal-640-pt
# Conflicts:
#	docs/CURRENT-STATE.md
#	docs/TRANSLATORS.md
#	scripts/package-boundaries.json
#	src/i18n/i18n.test.mjs
#	src/i18n/index.js
#	src/i18n/locale.js
#	src/i18n/same-as-english.json
#	src/scenes/recipes.js
#	src/scenes/sceneTitleDisplay.test.mjs
#	src/ui/localePicker.test.mjs
2026-10-29 17:42:05 +04:00
German Khokhlov 59f06c9918 Merge remote-tracking branch 'origin/main' into german/hal-641-it
# Conflicts:
#	docs/CURRENT-STATE.md
#	docs/TRANSLATORS.md
#	src/i18n/index.js
#	src/i18n/locale.js
#	src/ui/localePicker.test.mjs
2026-10-29 17:05:28 +04:00