release: v1.4.1 — Telegram nav (windowed, own back button, debug panel) #129
+9
-1
@@ -4,7 +4,7 @@
|
|||||||
import { app, bootstrap } from './lib/app.svelte';
|
import { app, bootstrap } from './lib/app.svelte';
|
||||||
import { navigate, router, type RouteName } from './lib/router.svelte';
|
import { navigate, router, type RouteName } from './lib/router.svelte';
|
||||||
import { t } from './lib/i18n/index.svelte';
|
import { t } from './lib/i18n/index.svelte';
|
||||||
import { insideTelegram, telegramBackButton } from './lib/telegram';
|
import { insideTelegram, telegramBackButton, telegramChromeDiag } from './lib/telegram';
|
||||||
import Toast from './components/Toast.svelte';
|
import Toast from './components/Toast.svelte';
|
||||||
import Splash from './components/Splash.svelte';
|
import Splash from './components/Splash.svelte';
|
||||||
import StaleInviteModal from './components/StaleInviteModal.svelte';
|
import StaleInviteModal from './components/StaleInviteModal.svelte';
|
||||||
@@ -138,6 +138,14 @@
|
|||||||
<Splash />
|
<Splash />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
<!-- TEMP DIAGNOSTIC overlay (Android nav debug) — REMOVE before merge -->
|
||||||
|
{#if app.ready && insideTelegram()}
|
||||||
|
{#key router.route.name + (router.route.params.id ?? '')}
|
||||||
|
<pre
|
||||||
|
style="position:fixed;left:0;right:0;bottom:0;z-index:9999;margin:0;padding:6px 8px;font:10px/1.35 ui-monospace,monospace;white-space:pre-wrap;overflow-wrap:anywhere;background:rgba(0,0,0,0.85);color:#3f3;max-height:45vh;overflow:auto;pointer-events:none">{telegramChromeDiag()}</pre>
|
||||||
|
{/key}
|
||||||
|
{/if}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.splash {
|
.splash {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { navigate } from '../lib/router.svelte';
|
import { navigate } from '../lib/router.svelte';
|
||||||
import { insideTelegram } from '../lib/telegram';
|
import { insideTelegram, isTelegramAndroid } from '../lib/telegram';
|
||||||
import { connection } from '../lib/connection.svelte';
|
import { connection } from '../lib/connection.svelte';
|
||||||
import { t } from '../lib/i18n/index.svelte';
|
import { t } from '../lib/i18n/index.svelte';
|
||||||
import { app } from '../lib/app.svelte';
|
import { app } from '../lib/app.svelte';
|
||||||
@@ -9,9 +9,10 @@
|
|||||||
|
|
||||||
let { title, back, grow = false }: { title: string; back?: string; grow?: boolean } = $props();
|
let { title, back, grow = false }: { title: string; back?: string; grow?: boolean } = $props();
|
||||||
|
|
||||||
// Inside Telegram the native header back button (App.svelte) is the back control, so
|
// Inside Telegram the native header back button (App.svelte) is the back control, so the app's
|
||||||
// the app's own chevron is hidden to avoid two back affordances.
|
// own chevron is hidden to avoid two back affordances — except on Android, where the native
|
||||||
const showBack = $derived(!!back && !insideTelegram());
|
// BackButton does not render in the (non-fullscreen) presentation, so the app shows its own.
|
||||||
|
const showBack = $derived(!!back && (!insideTelegram() || isTelegramAndroid()));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<header class="nav" class:grow>
|
<header class="nav" class:grow>
|
||||||
|
|||||||
+29
-7
@@ -36,6 +36,7 @@ interface TelegramWebApp {
|
|||||||
selectionChanged?: () => void;
|
selectionChanged?: () => void;
|
||||||
};
|
};
|
||||||
BackButton?: {
|
BackButton?: {
|
||||||
|
isVisible?: boolean;
|
||||||
show?: () => void;
|
show?: () => void;
|
||||||
hide?: () => void;
|
hide?: () => void;
|
||||||
onClick?: (cb: () => void) => void;
|
onClick?: (cb: () => void) => void;
|
||||||
@@ -303,10 +304,22 @@ export function telegramHaptic(kind: Haptic): void {
|
|||||||
* Android, on desktop, or on clients predating the method.
|
* Android, on desktop, or on clients predating the method.
|
||||||
*/
|
*/
|
||||||
export function telegramRequestFullscreen(): void {
|
export function telegramRequestFullscreen(): void {
|
||||||
if (webApp()?.platform === 'ios') webApp()?.requestFullscreen?.();
|
// TEMP (owner test): fullscreen fully disabled, incl. iOS, to confirm the Android "fullscreen
|
||||||
|
// look" is Telegram's own Mini App presentation, not our requestFullscreen (isFullscreen is
|
||||||
|
// already false on Android). Restore the iOS path after the test:
|
||||||
|
// if (webApp()?.platform === 'ios') webApp()?.requestFullscreen?.();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** isTelegramAndroid reports whether the Mini App runs on a Telegram Android client (reported as
|
||||||
|
* 'android', or 'android_x' for Telegram X). The native header BackButton does not render in the
|
||||||
|
* Android (non-fullscreen) presentation, so back navigation there uses the app's own chevron. */
|
||||||
|
export function isTelegramAndroid(): boolean {
|
||||||
|
const p = webApp()?.platform;
|
||||||
|
return p === 'android' || p === 'android_x';
|
||||||
}
|
}
|
||||||
|
|
||||||
let backHandler: (() => void) | null = null;
|
let backHandler: (() => void) | null = null;
|
||||||
|
let lastBackShow = false; // TEMP diag: the last telegramBackButton(show) request
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* telegramBackButton shows or hides Telegram's native header back button, wiring its
|
* telegramBackButton shows or hides Telegram's native header back button, wiring its
|
||||||
@@ -314,6 +327,7 @@ let backHandler: (() => void) | null = null;
|
|||||||
* inside Telegram so only the native control shows.
|
* inside Telegram so only the native control shows.
|
||||||
*/
|
*/
|
||||||
export function telegramBackButton(show: boolean, onClick?: () => void): void {
|
export function telegramBackButton(show: boolean, onClick?: () => void): void {
|
||||||
|
lastBackShow = show;
|
||||||
const b = webApp()?.BackButton;
|
const b = webApp()?.BackButton;
|
||||||
if (!b) return;
|
if (!b) return;
|
||||||
if (backHandler) b.offClick?.(backHandler);
|
if (backHandler) b.offClick?.(backHandler);
|
||||||
@@ -481,14 +495,22 @@ export function collectTelegramDiag(): TelegramDiag {
|
|||||||
export function telegramChromeDiag(): string {
|
export function telegramChromeDiag(): string {
|
||||||
const w = webApp();
|
const w = webApp();
|
||||||
if (!w) return 'no telegram';
|
if (!w) return 'no telegram';
|
||||||
const ih = typeof window === 'undefined' ? 0 : window.innerHeight;
|
const win = typeof window === 'undefined' ? undefined : window;
|
||||||
const sh = typeof screen === 'undefined' ? 0 : screen.height;
|
const scr = typeof screen === 'undefined' ? undefined : screen;
|
||||||
|
const vv = win?.visualViewport ?? undefined;
|
||||||
|
const bar = typeof document === 'undefined' ? null : (document.querySelector('.bar')?.getBoundingClientRect() ?? null);
|
||||||
|
const sa = w.safeAreaInset;
|
||||||
|
const csa = w.contentSafeAreaInset;
|
||||||
|
const n = (v: number | undefined): string => (v === undefined ? '—' : String(Math.round(v)));
|
||||||
return [
|
return [
|
||||||
`platform: ${w.platform ?? '—'} version: ${w.version ?? '—'}`,
|
`platform: ${w.platform ?? '—'} version: ${w.version ?? '—'} scheme: ${w.colorScheme ?? '—'}`,
|
||||||
`isFullscreen: ${w.isFullscreen} isExpanded: ${w.isExpanded}`,
|
`isFullscreen: ${w.isFullscreen} isExpanded: ${w.isExpanded}`,
|
||||||
`viewportH: ${w.viewportHeight ?? '—'} stableH: ${w.viewportStableHeight ?? '—'}`,
|
`inTG: ${insideTelegram()} backReq: ${lastBackShow} backPresent: ${!!w.BackButton} backVisible: ${w.BackButton?.isVisible}`,
|
||||||
`innerH: ${ih} screenH: ${sh}`,
|
`innerH: ${n(win?.innerHeight)} outerH: ${n(win?.outerHeight)} screenH: ${n(scr?.height)} availH: ${n(scr?.availHeight)}`,
|
||||||
`contentSafeTop: ${w.contentSafeAreaInset?.top ?? '—'} safeTop: ${w.safeAreaInset?.top ?? '—'}`,
|
`screenY: ${n(win?.screenY)} vv.offTop: ${n(vv?.offsetTop)} vv.h: ${n(vv?.height)}`,
|
||||||
|
`tgViewportH: ${n(w.viewportHeight)} stableH: ${n(w.viewportStableHeight)}`,
|
||||||
|
`safeArea T/B: ${n(sa?.top)}/${n(sa?.bottom)} contentSafe T/B: ${n(csa?.top)}/${n(csa?.bottom)}`,
|
||||||
|
`appHeader top/h: ${bar ? Math.round(bar.top) : '—'}/${bar ? Math.round(bar.height) : '—'}`,
|
||||||
].join('\n');
|
].join('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
import { gateway } from '../lib/gateway';
|
import { gateway } from '../lib/gateway';
|
||||||
import { navigate } from '../lib/router.svelte';
|
import { navigate } from '../lib/router.svelte';
|
||||||
import { t } from '../lib/i18n/index.svelte';
|
import { t } from '../lib/i18n/index.svelte';
|
||||||
import { insideTelegram, telegramChromeDiag } from '../lib/telegram'; // TEMP diag — remove before merge
|
|
||||||
import { resultBadge } from '../lib/result';
|
import { resultBadge } from '../lib/result';
|
||||||
import { badgeKind } from '../lib/unread';
|
import { badgeKind } from '../lib/unread';
|
||||||
import { getLobby, setLobby } from '../lib/lobbycache';
|
import { getLobby, setLobby } from '../lib/lobbycache';
|
||||||
@@ -224,12 +223,6 @@
|
|||||||
|
|
||||||
<Screen title={app.profile?.displayName ?? t('app.title')}>
|
<Screen title={app.profile?.displayName ?? t('app.title')}>
|
||||||
<div class="lobby">
|
<div class="lobby">
|
||||||
<!-- TEMP DIAGNOSTIC (Android fullscreen debug) — REMOVE before merge -->
|
|
||||||
{#if insideTelegram()}
|
|
||||||
<pre
|
|
||||||
style="margin:0 0 8px;padding:8px;font:11px/1.4 ui-monospace,monospace;white-space:pre-wrap;overflow-wrap:anywhere;background:var(--bg-elev);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text)"
|
|
||||||
>{telegramChromeDiag()}</pre>
|
|
||||||
{/if}
|
|
||||||
{#if invitations.length}
|
{#if invitations.length}
|
||||||
<section>
|
<section>
|
||||||
<h2>{t('lobby.invitations')}</h2>
|
<h2>{t('lobby.invitations')}</h2>
|
||||||
|
|||||||
Reference in New Issue
Block a user