feat(telegram): re-apply theme live on themeChanged
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Has been skipped
CI / integration (pull_request) Has been skipped
CI / ui (pull_request) Successful in 56s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m21s
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Has been skipped
CI / integration (pull_request) Has been skipped
CI / ui (pull_request) Successful in 56s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m21s
The Mini App read Telegram's themeParams/colorScheme only once at launch, so switching Telegram's light/dark theme (or its auto day/night) while the app was open left the SPA on stale colours until a relaunch. Subscribe to the themeChanged WebApp event and re-apply the theme live. Extract the launch-time token + colour-scheme + chrome application into syncTelegramTheme (reading live themeParams when no launch snapshot is passed) and call it from both applyTelegramChrome (launch) and the new event handler. Add a telegramThemeParams live getter (+ unit test). Drop the stale 'immersive fullscreen' note from applyTelegramChrome — the app deliberately does not request fullscreen.
This commit is contained in:
@@ -9,7 +9,7 @@ import { GatewayError } from './client';
|
||||
import { navigate, router } from './router.svelte';
|
||||
import { errorKey, localeFrom, setLocale, t, type Locale } from './i18n/index.svelte';
|
||||
import { languageNeedsServerSync } from './language';
|
||||
import { applyReduceMotion, applyTelegramTheme, applyTheme, type ThemePref } from './theme';
|
||||
import { applyReduceMotion, applyTelegramTheme, applyTheme, type ThemePref, type TelegramThemeParams } from './theme';
|
||||
import {
|
||||
insideTelegram,
|
||||
collectTelegramDiag,
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
hasLaunchFragment,
|
||||
loadTelegramSDK,
|
||||
telegramColorScheme,
|
||||
telegramThemeParams,
|
||||
telegramContentSafeAreaTop,
|
||||
telegramSafeAreaTop,
|
||||
telegramDisableVerticalSwipes,
|
||||
@@ -554,20 +555,31 @@ function syncViewportHeight(): void {
|
||||
}
|
||||
|
||||
/**
|
||||
* applyTelegramChrome applies a Mini App launch's visual integration: Telegram's authoritative
|
||||
* colour scheme and theme, the matching header / background / bottom chrome, the safe-area insets,
|
||||
* the swipe-down guard, and immersive fullscreen on mobile. It is idempotent, so both the initial
|
||||
* bootstrap and a manual launch retry call it.
|
||||
* syncTelegramTheme re-applies Telegram's theme integration — the themeParams token overrides,
|
||||
* Telegram's authoritative colour scheme, and the matching chrome — from theme, or from the SDK's
|
||||
* current themeParams when omitted. Called on launch with the launch snapshot and live on the
|
||||
* themeChanged event, so switching Telegram's light/dark theme while the app is open is picked up
|
||||
* without a relaunch.
|
||||
*/
|
||||
function applyTelegramChrome(launch: TelegramLaunch): void {
|
||||
if (launch.theme) applyTelegramTheme(launch.theme);
|
||||
function syncTelegramTheme(theme: TelegramThemeParams | undefined = telegramThemeParams()): void {
|
||||
if (theme) applyTelegramTheme(theme);
|
||||
// Inside Telegram the colour scheme is Telegram's to decide; force it explicitly so the OS
|
||||
// prefers-color-scheme (which leaks into the Telegram Desktop webview) cannot fight it. Falls
|
||||
// back to the stored preference when the SDK omits it.
|
||||
applyTheme(telegramColorScheme() ?? app.theme);
|
||||
// Match Telegram's chrome to the app and stop its swipe-down-to-minimise from fighting tile
|
||||
// drag / board scroll.
|
||||
syncTelegramChrome();
|
||||
}
|
||||
|
||||
/**
|
||||
* applyTelegramChrome applies a Mini App launch's visual integration: Telegram's authoritative
|
||||
* colour scheme and theme (syncTelegramTheme), the matching header / background / bottom chrome,
|
||||
* the safe-area insets, and the swipe-down-to-minimise guard. It is idempotent, so both the
|
||||
* initial bootstrap and a manual launch retry call it.
|
||||
*/
|
||||
function applyTelegramChrome(launch: TelegramLaunch): void {
|
||||
syncTelegramTheme(launch.theme);
|
||||
// Mirror the safe-area insets and stop Telegram's swipe-down-to-minimise from fighting tile drag
|
||||
// / board scroll.
|
||||
syncTelegramSafeArea();
|
||||
telegramDisableVerticalSwipes();
|
||||
}
|
||||
@@ -625,6 +637,8 @@ export async function bootstrap(): Promise<void> {
|
||||
telegramOnEvent('contentSafeAreaChanged', syncTelegramSafeArea);
|
||||
telegramOnEvent('safeAreaChanged', syncTelegramSafeArea);
|
||||
telegramOnEvent('fullscreenChanged', syncTelegramSafeArea);
|
||||
// Re-apply the theme live when the user switches Telegram's light/dark mode while the app is open.
|
||||
telegramOnEvent('themeChanged', () => syncTelegramTheme());
|
||||
await bootTelegram(launch);
|
||||
app.ready = true;
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user