feat(07-01): wire fullscreen + safe-area watch onto the guidance lifecycle edges
- route.ts: requestGuidanceFullscreen at BOTH guidance-start edges (activateGuidance + resume) directly after engageCloseProtection — synchronous, best-effort, return ignored - route.ts: exitGuidanceFullscreen at BOTH teardown edges (teardownGuidance + stopGuidanceArtifacts) directly after releaseCloseProtection - route.ts: watchFullscreenEvents registered exactly ONCE at the guidance-start edge; the callback is a deliberate no-op (observability only, D-14) - main.ts: watchSafeAreaChanges(getWebApp()) called at the boot site directly after applySafeArea(resolveSafeInsets(getWebApp())) — insets re-resolve at runtime, not only once at boot (T-07-06b) - no new logging; the route module's state-token console law unchanged
This commit is contained in:
+6
-1
@@ -33,7 +33,7 @@ import { createRecenterControl } from "./ui/recenter.ts";
|
|||||||
import { getWebApp } from "./telegram/webapp.ts";
|
import { getWebApp } from "./telegram/webapp.ts";
|
||||||
import { watchTheme } from "./telegram/theme.ts";
|
import { watchTheme } from "./telegram/theme.ts";
|
||||||
import { wireBackButton } from "./telegram/backbutton.ts";
|
import { wireBackButton } from "./telegram/backbutton.ts";
|
||||||
import { resolveSafeInsets, applySafeArea } from "./telegram/safe-area.ts";
|
import { resolveSafeInsets, applySafeArea, watchSafeAreaChanges } from "./telegram/safe-area.ts";
|
||||||
import { createSession } from "./session/client.ts";
|
import { createSession } from "./session/client.ts";
|
||||||
import { getSession, isSessionStale } from "./session/store.ts";
|
import { getSession, isSessionStale } from "./session/store.ts";
|
||||||
import { acquireFix, isFixStale, fixAgeSeconds } from "./location/chain.ts";
|
import { acquireFix, isFixStale, fixAgeSeconds } from "./location/chain.ts";
|
||||||
@@ -72,6 +72,11 @@ void boot();
|
|||||||
async function boot(): Promise<void> {
|
async function boot(): Promise<void> {
|
||||||
// 1 — safe-area vars are set before any layout reads them (PX-03 groundwork).
|
// 1 — safe-area vars are set before any layout reads them (PX-03 groundwork).
|
||||||
applySafeArea(resolveSafeInsets(getWebApp()));
|
applySafeArea(resolveSafeInsets(getWebApp()));
|
||||||
|
// PX-04/D-03: the insets re-resolve at RUNTIME too — rotation and fullscreen
|
||||||
|
// transitions re-apply through the same union authority on the client's
|
||||||
|
// inset events. Same one-shot getWebApp() value as the apply line above;
|
||||||
|
// internally guarded (null WebApp / missing onEvent → returns immediately).
|
||||||
|
watchSafeAreaChanges(getWebApp());
|
||||||
|
|
||||||
// 3 (declared ahead of their first use inside the closures below) — the
|
// 3 (declared ahead of their first use inside the closures below) — the
|
||||||
// single-shell state the BackButton resolver and the stale branch read:
|
// single-shell state the BackButton resolver and the stale branch read:
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ import { clearRouteLayers, setRouteDrawn } from "./route-layers.ts";
|
|||||||
import type { buildRouteCard, buildRoutePendingCard } from "./route-card.ts";
|
import type { buildRouteCard, buildRoutePendingCard } from "./route-card.ts";
|
||||||
import { createGuidanceCamera } from "../guidance/camera.ts";
|
import { createGuidanceCamera } from "../guidance/camera.ts";
|
||||||
import { engageCloseProtection, releaseCloseProtection } from "../guidance/close-protection.ts";
|
import { engageCloseProtection, releaseCloseProtection } from "../guidance/close-protection.ts";
|
||||||
|
import { requestGuidanceFullscreen, exitGuidanceFullscreen, watchFullscreenEvents } from "../telegram/fullscreen.ts";
|
||||||
import { fireHaptic } from "../guidance/haptics.ts";
|
import { fireHaptic } from "../guidance/haptics.ts";
|
||||||
import {
|
import {
|
||||||
buildConfirmCard,
|
buildConfirmCard,
|
||||||
@@ -339,6 +340,10 @@ export function createRouteController(deps: RouteControllerDeps): {
|
|||||||
if (g === null || g.active) return;
|
if (g === null || g.active) return;
|
||||||
g.active = true;
|
g.active = true;
|
||||||
engageCloseProtection(deps.wa ?? null);
|
engageCloseProtection(deps.wa ?? null);
|
||||||
|
// PX-04/D-03: the native fullscreen request is BEST EFFORT — a refusal is a supported fallback, never a guidance failure.
|
||||||
|
requestGuidanceFullscreen(deps.wa ?? null);
|
||||||
|
// PX-04/D-03: the fullscreen events are observability only — no state, no logging (D-14 category-only law).
|
||||||
|
watchFullscreenEvents(deps.wa ?? null, () => { /* observability only — no state, no logging */ });
|
||||||
if (deps.shellRoot !== undefined) deps.shellRoot.dataset.guidance = "active";
|
if (deps.shellRoot !== undefined) deps.shellRoot.dataset.guidance = "active";
|
||||||
foldEta(g);
|
foldEta(g);
|
||||||
camera.easeToSnapped(g.lastSnapped); // the locked-follow pose over the SNAPPED line
|
camera.easeToSnapped(g.lastSnapped); // the locked-follow pose over the SNAPPED line
|
||||||
@@ -479,6 +484,8 @@ export function createRouteController(deps: RouteControllerDeps): {
|
|||||||
stopWatch();
|
stopWatch();
|
||||||
deleteEnvelope();
|
deleteEnvelope();
|
||||||
releaseCloseProtection(deps.wa ?? null);
|
releaseCloseProtection(deps.wa ?? null);
|
||||||
|
// PX-04/D-03: the trip end releases fullscreen alongside the close protection — best effort, same law.
|
||||||
|
exitGuidanceFullscreen(deps.wa ?? null);
|
||||||
if (deps.shellRoot !== undefined) delete deps.shellRoot.dataset.guidance;
|
if (deps.shellRoot !== undefined) delete deps.shellRoot.dataset.guidance;
|
||||||
stopBlink();
|
stopBlink();
|
||||||
if (deps.bannerHost !== undefined) deps.bannerHost.replaceChildren();
|
if (deps.bannerHost !== undefined) deps.bannerHost.replaceChildren();
|
||||||
@@ -614,6 +621,8 @@ export function createRouteController(deps: RouteControllerDeps): {
|
|||||||
};
|
};
|
||||||
envelopeId = trip.envelopeId;
|
envelopeId = trip.envelopeId;
|
||||||
engageCloseProtection(deps.wa ?? null);
|
engageCloseProtection(deps.wa ?? null);
|
||||||
|
// PX-04/D-03: a resumed trip is a live guidance session — the same best-effort fullscreen request as a fresh start.
|
||||||
|
requestGuidanceFullscreen(deps.wa ?? null);
|
||||||
if (deps.shellRoot !== undefined) deps.shellRoot.dataset.guidance = "active";
|
if (deps.shellRoot !== undefined) deps.shellRoot.dataset.guidance = "active";
|
||||||
setRouteDrawn(deps.map, { points: trip.model.points }, []);
|
setRouteDrawn(deps.map, { points: trip.model.points }, []);
|
||||||
const first = points[0];
|
const first = points[0];
|
||||||
@@ -690,6 +699,8 @@ export function createRouteController(deps: RouteControllerDeps): {
|
|||||||
stopWatch();
|
stopWatch();
|
||||||
if (guidance === null) return;
|
if (guidance === null) return;
|
||||||
releaseCloseProtection(deps.wa ?? null);
|
releaseCloseProtection(deps.wa ?? null);
|
||||||
|
// PX-04/D-03: the walk-back teardown releases fullscreen alongside the close protection.
|
||||||
|
exitGuidanceFullscreen(deps.wa ?? null);
|
||||||
if (deps.shellRoot !== undefined) delete deps.shellRoot.dataset.guidance;
|
if (deps.shellRoot !== undefined) delete deps.shellRoot.dataset.guidance;
|
||||||
stopBlink();
|
stopBlink();
|
||||||
if (deps.bannerHost !== undefined) deps.bannerHost.replaceChildren();
|
if (deps.bannerHost !== undefined) deps.bannerHost.replaceChildren();
|
||||||
|
|||||||
Reference in New Issue
Block a user