From ae21874817a5ecc75a9fc365b2ef7fa7221a2e48 Mon Sep 17 00:00:00 2001 From: Renn F Date: Sun, 19 Jul 2026 00:22:12 +0200 Subject: [PATCH] =?UTF-8?q?feat(tg):=20P0=20=E2=80=94=20dev=20mock=20bridg?= =?UTF-8?q?e=20+=20Telegram-native=20foundations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mini App V4 phase 0. The (tg) shell gains the groundwork every later phase builds on: - Dev mock bridge: outside Telegram, a development build falls back to a no-op WebApp object and skips the webapp-auth POST (the regular panel session cookie authorizes API calls), so the cockpit is workable in a plain browser. Production keeps the "Open from Telegram" wall. - Telegram theme adoption: themeParams map onto the shadcn CSS variables scoped to #tg-shell (desktop dashboard untouched), colorScheme drives the dark class, themeChanged re-applies live. Non-hex values are dropped at the trust boundary. - Viewport/swipe correctness: shell height rides Telegram's own --tg-viewport-stable-height (100dvh fallback), vertical swipe-to-close disabled so list scrolling can't dismiss the app. - Native chrome bindings: TgWebAppProvider context plus useMainButton / useBackButton declarative hooks and a null-safe haptics helper — consumers never touch window.Telegram directly. --- panel/src/app/(tg)/layout.tsx | 12 +- panel/src/app/(tg)/tg/__tests__/page.test.tsx | 61 +++++++- panel/src/app/(tg)/tg/page.tsx | 55 +++++-- .../src/lib/telegram/__tests__/hooks.test.tsx | 145 ++++++++++++++++++ .../src/lib/telegram/__tests__/theme.test.ts | 115 ++++++++++++++ panel/src/lib/telegram/hooks.tsx | 128 ++++++++++++++++ panel/src/lib/telegram/theme.ts | 75 +++++++++ panel/src/lib/telegram/webapp.ts | 109 ++++++++++++- 8 files changed, 682 insertions(+), 18 deletions(-) create mode 100644 panel/src/lib/telegram/__tests__/hooks.test.tsx create mode 100644 panel/src/lib/telegram/__tests__/theme.test.ts create mode 100644 panel/src/lib/telegram/hooks.tsx create mode 100644 panel/src/lib/telegram/theme.ts diff --git a/panel/src/app/(tg)/layout.tsx b/panel/src/app/(tg)/layout.tsx index 853bf386..7e10abe0 100644 --- a/panel/src/app/(tg)/layout.tsx +++ b/panel/src/app/(tg)/layout.tsx @@ -11,6 +11,12 @@ import Script from "next/script"; * `afterInteractive` strategy instead — `waitForTelegramWebApp` (in * lib/telegram/webapp.ts) briefly polls for `window.Telegram.WebApp` to * absorb the resulting load race rather than assuming it's present on mount. + * + * Height reads `--tg-viewport-stable-height`, a :root variable the Telegram + * script itself maintains (steady during keyboard/panel animations, unlike + * dvh inside the webview); outside Telegram it's unset and 100dvh applies. + * `#tg-shell` is the hook the page uses to scope Telegram theme variables + * to this surface only. */ export default function TelegramLayout({ children, @@ -18,7 +24,11 @@ export default function TelegramLayout({ children: React.ReactNode; }) { return ( -
+