forked from c-fu/arah2
feat(03-02): Fix type + three source adapters (telegram/webview/chat-pin) — GEO-01 wrappers
- types.ts: the shared Fix shape + LocationState machine (type-only, D-04/D-05/D-07) - telegram.ts: version-gated LocationManager init/getLocation, hard 8s timeout (Pitfall 3), null-safe telegramLocationSupported (plain browser/Desktop = false, not TypeError), looksStale + haversine + the Android nudge (issue #56 navbar read DISCARDED, then retry) - webview.ts: one-shot geolocation read, maximumAge: 0 (freshness axis), 8s timeout - chat-pin.ts: bounded 60s poll of GET /api/location (Bearer token) + POST /api/location-fallback throw-on-fail so the ASK VIA CHAT handler can revalidate (D-03) - telegram/webapp.ts created early (Rule 3: task 1 imports TelegramWebAppLike from task 3's file; declared the narrow hand-rolled interface now, verbatim per plan)
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* webapp.ts — the ONE narrow typed accessor for window.Telegram.WebApp
|
||||
* (D-11, RESEARCH §Standard Stack note).
|
||||
* -------------------------------------------------------------------
|
||||
* `@types/telegram-web-app` is deliberately NOT a dependency (plan 03-01
|
||||
* dropped it): this hand-rolled `TelegramWebAppLike` IS the contract —
|
||||
* every test fake, the D-11 harness mock, and the production clients
|
||||
* satisfy exactly these ~12 members. The official 500-member `WebApp`
|
||||
* type would force each fake to stub ~50 members.
|
||||
*
|
||||
* getWebApp() may honestly return NULL (plain browser, no Telegram) —
|
||||
* that null is the contract the location chain must handle. All
|
||||
* `Telegram.WebApp.*` calls must originate from the app's own document
|
||||
* (Bot API 10.2 origin restriction).
|
||||
*/
|
||||
export interface TelegramWebAppLike {
|
||||
initData: string;
|
||||
colorScheme?: "light" | "dark";
|
||||
themeParams?: { header_bg_color?: string };
|
||||
version?: string;
|
||||
platform?: string;
|
||||
safeAreaInset?: { top: number; bottom: number; left: number; right: number };
|
||||
contentSafeAreaInset?: { top: number; bottom: number; left: number; right: number };
|
||||
isVersionAtLeast(version: string): boolean;
|
||||
close(): void;
|
||||
onEvent?(event: string, cb: () => void): void;
|
||||
offEvent?(event: string, cb: () => void): void;
|
||||
BackButton?: { show(): void; hide(): void; onClick(cb: () => void): void; offClick(cb: () => void): void };
|
||||
LocationManager?: {
|
||||
isInited: boolean;
|
||||
isLocationAvailable?: boolean;
|
||||
isAccessRequested?: boolean;
|
||||
isAccessGranted?: boolean;
|
||||
init(cb: () => void): void;
|
||||
getLocation(cb: (data: unknown | null) => void): void;
|
||||
openSettings?(): void;
|
||||
};
|
||||
}
|
||||
|
||||
export function getWebApp(): TelegramWebAppLike | null {
|
||||
const w = window as unknown as { Telegram?: { WebApp?: TelegramWebAppLike } };
|
||||
return w.Telegram?.WebApp ?? null;
|
||||
}
|
||||
Reference in New Issue
Block a user