UI: fix the lobby slide on Telegram cold launch (correct the cause)
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 45s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 57s
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 45s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 57s
The first attempt (the App.svelte `started` gate) targeted the first pane mount,
but the slide is a second render. On a Telegram cold launch the URL fragment is
Telegram's #tgWebAppData=... launch params, which the router parsed as notfound;
bootstrap's navigate('/') then corrected it to the lobby asynchronously, re-keying
the route pane (notfound -> lobby) and sliding the lobby in as if returning from a
screen. A reload was static because the hash was already #/.
Treat a Telegram launch fragment as the lobby root in the router, so the route is
correct from the first pane (no re-key, no slide). Extract the pure hash->Route
parsing into routeparse.ts so it unit-tests without a DOM, and revert the gate
(the first pane never slid — local transitions skip the initial mount, as clean
browser launches showed).
Tests: routeparse unit tests (incl. the tgWebApp fragment); an e2e that launches
with the fragment in the URL and asserts the lobby plus the normalised #/ hash.
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { parse } from './routeparse';
|
||||
|
||||
describe('parse', () => {
|
||||
it('maps the empty hash and the root to the lobby', () => {
|
||||
expect(parse('').name).toBe('lobby');
|
||||
expect(parse('#/').name).toBe('lobby');
|
||||
});
|
||||
|
||||
it('maps known paths to their routes', () => {
|
||||
expect(parse('#/login').name).toBe('login');
|
||||
expect(parse('#/new').name).toBe('new');
|
||||
expect(parse('#/settings').name).toBe('settings');
|
||||
expect(parse('#/stats').name).toBe('stats');
|
||||
expect(parse('#/game/abc')).toEqual({ name: 'game', params: { id: 'abc' } });
|
||||
expect(parse('#/game/abc/chat')).toEqual({ name: 'gameChat', params: { id: 'abc' } });
|
||||
expect(parse('#/game/abc/check')).toEqual({ name: 'gameCheck', params: { id: 'abc' } });
|
||||
});
|
||||
|
||||
it('maps an unknown path and a game without an id to notfound', () => {
|
||||
expect(parse('#/bogus').name).toBe('notfound');
|
||||
expect(parse('#/game').name).toBe('notfound');
|
||||
});
|
||||
|
||||
it('treats a Telegram launch fragment as the lobby root, not notfound', () => {
|
||||
// Telegram appends its Mini App launch params to the URL fragment on a cold launch; they
|
||||
// are launch metadata, not a route. Parsing them as notfound made bootstrap's navigate('/')
|
||||
// re-key the route pane (notfound -> lobby) and slide the lobby in on launch.
|
||||
expect(parse('#tgWebAppData=query_id%3Dx&tgWebAppVersion=7.0&tgWebAppPlatform=ios').name).toBe(
|
||||
'lobby',
|
||||
);
|
||||
expect(parse('#tgWebAppStartParam=foo').name).toBe('lobby');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user