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

- 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:
Ilia Denisov
2026-06-15 17:22:09 +02:00
parent 01d2d1f368
commit 853730823b
9 changed files with 200 additions and 19 deletions
+38 -1
View File
@@ -1,5 +1,5 @@
import { afterEach, describe, expect, it, vi } from 'vitest';
import { insideTelegram, telegramLaunch } from './telegram';
import { insideTelegram, telegramClosingConfirmation, telegramLaunch } from './telegram';
function stubWebApp(initData: string, startParam?: string) {
vi.stubGlobal('window', {
@@ -37,3 +37,40 @@ describe('telegram launch detection', () => {
expect(launch.theme?.bg_color).toBe('#101418');
});
});
describe('telegramClosingConfirmation', () => {
afterEach(() => vi.unstubAllGlobals());
// stubClient stands up a fake WebApp on the given platform with spies for the close-guard
// toggles, so the platform gate can be asserted without a real Telegram client.
function stubClient(platform?: string) {
const enable = vi.fn();
const disable = vi.fn();
vi.stubGlobal('window', {
Telegram: { WebApp: { platform, enableClosingConfirmation: enable, disableClosingConfirmation: disable } },
});
return { enable, disable };
}
it('arms the close guard on mobile clients', () => {
for (const p of ['ios', 'android']) {
const { enable } = stubClient(p);
telegramClosingConfirmation(true);
expect(enable, `platform=${p}`).toHaveBeenCalledOnce();
}
});
it('skips the close guard on desktop clients (the dialog there is just noise)', () => {
for (const p of ['tdesktop', 'macos', 'web', undefined]) {
const { enable } = stubClient(p);
telegramClosingConfirmation(true);
expect(enable, `platform=${p}`).not.toHaveBeenCalled();
}
});
it('always lifts the guard on leave, regardless of platform', () => {
const { disable } = stubClient('tdesktop');
telegramClosingConfirmation(false);
expect(disable).toHaveBeenCalledOnce();
});
});