# Earth Frontend Context This document describes the current real structure of the Earth display frontend. The focus is on helping future changes to the HUD, layers, media panel, real terrain, and BGP visualization avoid repeating past structural and state-sync pitfalls. Related references: - Repository root `rules.md` - [Frontend Layout Guidelines](/home/ray/dev/linkong/planet/docs/technical/en/frontend-layout-guidelines.md) ## Current Goal The Earth frontend is not an ordinary admin page — it is an independent large-screen display frontend. Current product goals: - Maintain the spatial depth and readability of the globe view - Keep HUD, layers, media panel, BGP, satellites, cables, and similar elements in a unified interaction model - Clearly represent states like loading, enabled, hidden, and locked ## Current Entry Point React route entry: - [Earth.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/Earth/Earth.tsx) The current approach is simple: - The React page only provides a full-screen `iframe` - The actual Earth application runs at: - [index.html](/home/ray/dev/linkong/planet/frontend/public/earth/index.html) Earth frontend is essentially a standalone static application under `public/earth`. ## Current File Layers ### 1. Page Entry and Structure - [index.html](/home/ray/dev/linkong/planet/frontend/public/earth/index.html) Responsibilities: - Base HUD DOM - Layer panel - Media panel - Toolbar - Settings dialog - Legacy element ID compatibility ### 2. Main Runtime - [main.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/main.js) Responsibilities: - Globe initialization - Three.js scene assembly - Data loading and refresh - Layer module integration - Earth-level state synchronization Earth treats `/ws` `earth_updates` as refresh hints only; real data is fetched again from `/api/v1/visualization/...`. Backend database-driven refresh now has the listener clear cache and broadcast directly instead of going through the default `earth_refresh` job queue. After `database_changed`, the frontend applies the per-layer `clear_then_reload`, `reload`, or `delta` strategy. `clear_then_reload` must clear Three.js objects before a no-store refetch, and summary is only a consistency check, not a reason to skip a layer reload when the count is `0`. See [Data Jobs and Outbox Architecture](/home/ray/dev/linkong/planet/docs/technical/en/data-job-earth-sync-architecture.md) for the technical pipeline and [Business Architecture and Data Flows](/home/ray/dev/linkong/planet/docs/technical/en/platform-data-flows.md) for business data flows. ### 3. Earth Control Layer - [controls.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/controls.js) Responsibilities: - Toolbar interaction - Layer panel interaction - Rotation / zoom / layout - HUD panel drag - Layer toggle state machine - Earth settings read, persist, and reset This is currently the most critical UI control entry point for the Earth frontend. Earth settings are now grouped by `data-settings-tab` and `data-settings-tab-panel`. Desktop and mobile share the same category semantics: Runtime, Display, Panels, Motion, Shortcuts, and System. When adding a setting, first choose its category, then add the DOM, persistence field, and restore logic; do not keep growing one long undifferentiated panel. Earth runs inside an independent iframe / static application, so it cannot directly reuse React Admin's `react-i18next` context. `public/earth` uses its own [i18n.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/i18n.js) runtime to read and write the global `planet-locale`, while keeping the legacy `docs-lang` in sync. This keeps Docs, the console, and Earth on the same language preference. The language switch belongs in the Settings `System` tab, and desktop/mobile both use the same `data-earth-locale` buttons; do not put language selection into layer, display, or runtime-mode settings. The news category selector in Display reuses the same chip-selector pattern as Cruise Modules. It only filters news categories for the current browser on the Earth frontend. It does not toggle layers, basemap, boundaries, TV, data points, BGP, vessels, satellites, or compute centers; those remain owned by the layer panel, media panel, and admin configuration. `controls.js` persists only `shared.newsCategoryFilters` and broadcasts `earth:news-category-filters-change`; `news.js` sends the selected categories and current locale to `/api/v1/news/earth-feed?categories=...&locale=...`, so Web and UE clients share the same backend category filtering path. In English mode, Earth news must render only English title/summary text. Chinese source items without `en-US` localization are filtered from the visible cards/ticker/cruise until the backend enrichment finishes, and source/feed labels fall back to English-safe names instead of rendering Chinese labels. The news panel, ticker, and news cruise must consume `items` / `cruise_items` from the same `/api/v1/news/earth-feed` response instead of keeping separate regional caches. `news.js` builds a refresh request key from region, category, source, and limit; only concurrent requests with the same key reuse the promise, and stale responses from an older region are dropped by token. Source filtering is also region-scoped: when the user moves from Asia Pacific to Europe or another region, source IDs saved for the old region must not be appended to the next fetch. After the new payload arrives, the saved source list is intersected with the available `sources`; if the intersection is empty, the current region falls back to all available sources. This keeps the ticker, panel, and cruise cards aligned after region switches. Shortcut configuration is a device-local preference owned by `controls.js`: read, capture, enable/disable, and reset all stay in the Earth frontend. It should not be written to backend user settings and should not affect other browsers. New shortcuts must provide a default key, display label, disabled/enabled state, and reset path instead of being hard-coded only in a keydown handler. ### 4. UI and Status Messages - [ui.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/ui.js) Responsibilities: - Loading panel - Status message - Tooltip / error / cleanup logic ### 5. Motion Capture Control Adapter - [motion-control.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/motion-control.js) Responsibilities: - Act as the Motion Provider manager for both `browser_camera` and `motion_agent`. - Use browser `getUserMedia` plus local MediaPipe recognition by default; advanced setups can connect to the local Motion Capture Agent WebSocket. - Handle browser camera permission/secure-context errors, plus Agent disconnects, reconnects, `status`, and `heartbeat` messages. - Filter low-confidence and overly repeated gesture events. - Map `rotate_left`, `rotate_right`, `rotate_up`, `rotate_down`, `zoom_in`, `zoom_out`, `focus_prev`, `focus_next`, `layer_prev`, `layer_next`, and `confirm` to the action entry points exposed by `main.js`. - Parse `skeleton` debug events and dispatch `earth:motion-debug-frame`. Gesture recognition may run locally in the browser or inside the local Agent, but neither path sends realtime camera frames to the SaaS cloud. `main.js` exposes rotation, zoom, target focus, layer switching, and confirm entry points, plus a `window.__planetEarth.motion` debug entry. The adapter starts only when `?motion=1` is present, browser local storage contains `planet-earth-motion-control-enabled=true`, or Earth settings enable Motion Debug Mode. `shared.motionEnabledGestures` stores the user-approved gesture whitelist; the browser filters locally, and Motion Agent mode also synchronizes it through `set_enabled_gestures`. [motion-debug-panel.js](/home/ray/dev/linkong/planet/frontend/public/earth/js/motion-debug-panel.js) owns the debug panel. It listens for `earth:motion-debug-frame` and draws normalized skeleton joints and bones on a canvas. The Browser Camera provider also emits `earth:motion-debug-video-source` with the local `