feat(ui): refine Telegram invite & close UX
CI / changes (pull_request) Successful in 1s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 13s
CI / ui (pull_request) Successful in 47s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m2s
CI / changes (pull_request) Successful in 1s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 13s
CI / ui (pull_request) Successful in 47s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m2s
- Shared invite links open the Mini App fullscreen (mode=fullscreen), so a shared link matches the bot's own fullscreen launch. - A used or expired invite deep-link now lands the visitor in the lobby with a gentle notice pointing at the right bot (@<username>, by service language), instead of a red "code invalid/expired" error on the Friends screen. - The in-game close confirmation is armed only on Telegram mobile clients; on desktop (tdesktop/macOS/web) it is skipped, where the "changes may not be saved" dialog is just noise (drafts auto-save).
This commit is contained in:
+35
-8
@@ -8,6 +8,7 @@ import type { TelegramThemeParams } from './theme';
|
||||
interface TelegramWebApp {
|
||||
initData: string;
|
||||
initDataUnsafe?: { start_param?: string };
|
||||
platform?: string;
|
||||
themeParams?: TelegramThemeParams;
|
||||
colorScheme?: 'light' | 'dark';
|
||||
isFullscreen?: boolean;
|
||||
@@ -50,6 +51,19 @@ export function insideTelegram(): boolean {
|
||||
return !!w && typeof w.initData === 'string' && w.initData.length > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* telegramOpenLink opens a t.me link through the Mini App SDK, so Telegram navigates to
|
||||
* it natively (e.g. a bot chat) rather than spawning an in-app browser tab. Returns false
|
||||
* outside Telegram or when the SDK lacks the method, so the caller can fall back to a plain
|
||||
* window.open.
|
||||
*/
|
||||
export function telegramOpenLink(url: string): boolean {
|
||||
const w = webApp();
|
||||
if (!w?.openTelegramLink) return false;
|
||||
w.openTelegramLink(url);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* shareTelegramLink opens Telegram's native "share to a chat" picker for url with a
|
||||
* caption, through the Mini App SDK (https://t.me/share/url). Returns false outside
|
||||
@@ -57,10 +71,7 @@ export function insideTelegram(): boolean {
|
||||
* Share API. Works consistently on iOS and Android within Telegram.
|
||||
*/
|
||||
export function shareTelegramLink(url: string, text: string): boolean {
|
||||
const w = webApp();
|
||||
if (!w?.openTelegramLink) return false;
|
||||
w.openTelegramLink(`https://t.me/share/url?url=${encodeURIComponent(url)}&text=${encodeURIComponent(text)}`);
|
||||
return true;
|
||||
return telegramOpenLink(`https://t.me/share/url?url=${encodeURIComponent(url)}&text=${encodeURIComponent(text)}`);
|
||||
}
|
||||
|
||||
/** TelegramLaunch is the data a Mini App launch carries. */
|
||||
@@ -156,13 +167,29 @@ export function telegramHaptic(kind: Haptic): void {
|
||||
}
|
||||
|
||||
/**
|
||||
* telegramClosingConfirmation toggles the confirmation Telegram shows when the user
|
||||
* swipes the Mini App closed — enabled during an active game so it is not lost by accident.
|
||||
* isMobilePlatform reports whether the Mini App runs on a Telegram mobile client (iOS or
|
||||
* Android), where a stray swipe-down can drop the app. Desktop clients (tdesktop, macOS,
|
||||
* web) report other values and close only on a deliberate window action.
|
||||
*/
|
||||
function isMobilePlatform(): boolean {
|
||||
const p = webApp()?.platform;
|
||||
return p === 'ios' || p === 'android';
|
||||
}
|
||||
|
||||
/**
|
||||
* telegramClosingConfirmation toggles the confirmation Telegram shows when the user swipes
|
||||
* the Mini App closed — enabled during an active game so it is not lost by accident. The
|
||||
* guard is only armed on mobile clients: on desktop, closing a window is deliberate and
|
||||
* Telegram surfaces a "changes may not be saved" dialog that is just noise here (drafts
|
||||
* auto-save), so the confirmation is skipped there.
|
||||
*/
|
||||
export function telegramClosingConfirmation(on: boolean): void {
|
||||
const w = webApp();
|
||||
if (on) w?.enableClosingConfirmation?.();
|
||||
else w?.disableClosingConfirmation?.();
|
||||
if (on) {
|
||||
if (isMobilePlatform()) w?.enableClosingConfirmation?.();
|
||||
} else {
|
||||
w?.disableClosingConfirmation?.();
|
||||
}
|
||||
}
|
||||
|
||||
let backHandler: (() => void) | null = null;
|
||||
|
||||
Reference in New Issue
Block a user