Two Telegram-Mini-App follow-ups to the backend-unavailable screen:
- Reliable "Close" button (Telegram only) that actually EXITS the Mini App
instead of routing back. closeTelegramApp() tries the legacy
window.Telegram.WebApp.close() global (telegram-web-app.js), then the SDK
closeMiniApp(), then the raw postEvent('web_app_close') — all emit the same
close event, so it can't silently fail. Guarded so the first path never
silently no-ops.
- Eliminate the flash of the /login page before the outage screen. On the
bootstrap path (the app has never reached the backend) reportPossibleBackendDown()
now flips the screen IMMEDIATELY and synchronously instead of waiting on the
confirm probe, so the overlay is up before isLoading flips and /login can never
paint uncovered. Add an eager checkBackendOnStartup() liveness ping at launch
(parallel with auth) so even the no-stored-token / fresh-Telegram path that
makes no early request shows the screen at once. The confirm-probe still guards
already-loaded sessions from a one-off blip.
i18n close key added in ru/en/zh/fa.
Modal a11y:
- focus-trap + role=dialog/aria-modal/aria-labelledby on AdminRoles delete confirm
and AdminBanSystem user-detail modal (+ close aria-label)
Telegram theme/language sync (first run only, explicit choice always wins):
- getTelegramColorScheme() / getTelegramLanguageCode() helpers in useTelegramSDK
- useTheme initial state follows the Telegram client color scheme when no stored theme
- applyTelegramLanguage() adopts the Telegram client language when no stored choice,
called from main.tsx after SDK init (launch params unavailable before init)
- Fix stale initData comparison in clearStaleSessionIfNeeded that destroyed
valid refresh tokens on mobile WebView reopens
- Restrict X-Telegram-Init-Data header to auth endpoints only
- Close Mini App on auth retry to force fresh initData from Telegram
- Merge Connection page error/not-configured states for better UX
- Remove unnecessary comments across 40+ files (section dividers,
restating comments, noise catch block comments)
- Configure ESLint allowEmptyCatch to properly handle intentional
empty catch blocks (62 warnings resolved)
Полный переход с нативного window.Telegram.WebApp API на @telegram-apps/sdk-react v3.
Bridge SDK оборачивал receiveEvent, из-за чего popup_closed не доходил до нативного
обработчика — это было основной причиной бага с двойным открытием попапа.
Изменения:
- Удалён @telegram-apps/react-router-integration (привязан к SDK v1)
- Инициализация SDK v3 в main.tsx: init(), restoreInitData(), mount всех компонентов
- AppWithNavigator: убран TelegramRouter (initNavigator + useIntegration), все платформы
на BrowserRouter, добавлен TelegramBackButton через SDK v3
- useTelegramSDK: детекция через retrieveLaunchParams(), реактивные значения через
useSignal() (fullscreen, viewport, safe area insets), initData через retrieveRawInitData()
- TelegramAdapter: полная перезапись — попапы через showPopup() (Promise-based, без
ручного onEvent/offEvent/timeout), кнопки через setMainButtonParams/showBackButton,
haptic через hapticFeedbackImpactOccurred, тема через themeParamsState с конвертацией
camelCase→snake_case, cloud storage через getCloudStorageItem/setCloudStorageItem
- api/client.ts: initData через retrieveRawInitData() вместо window.Telegram.WebApp.initData
- AppHeader: фото пользователя через initDataUser() сигнал
- ConnectionModal: openLink через SDK вместо window.Telegram.WebApp.openLink
- ColorPicker: детекция Telegram через isInTelegramWebApp()
- Удалён интерфейс TelegramWebApp (368 строк) и Window augmentation из vite-env.d.ts
- Убрано поле telegram из PlatformContext в types.ts
- Обновлён manualChunks в vite.config.ts