From f95350d245001dc6c925e416455e6220c8181545 Mon Sep 17 00:00:00 2001 From: weishu Date: Thu, 18 Dec 2025 16:06:10 +0800 Subject: [PATCH] fix: integrate History API for browser back button navigation Syncs React routing state with browser History API. Clicking the browser back button now navigates within the app instead of exiting. Telegram BackButton behavior is preserved by checking for initData. --- web/src/App.tsx | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/web/src/App.tsx b/web/src/App.tsx index 1d75fe82..37c2148d 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -135,6 +135,14 @@ export function App() { return { type: 'sessions' } }) + // Navigate and sync browser history (browser only, not Telegram) + const navigateTo = useCallback((newScreen: Screen) => { + setScreen(newScreen) + if (!getTelegramWebApp()?.initData) { + history.pushState({ screen: newScreen }, '') + } + }, []) + const [sessions, setSessions] = useState([]) const [sessionsLoading, setSessionsLoading] = useState(false) const [sessionsError, setSessionsError] = useState(null) @@ -199,7 +207,31 @@ export function App() { } }, []) + // Handle browser back button (browser only, not Telegram) + useEffect(() => { + if (getTelegramWebApp()?.initData) return + + const handlePopState = (event: PopStateEvent) => { + if (event.state?.screen) { + setScreen(event.state.screen) + } else { + setScreen({ type: 'sessions' }) + } + } + + window.addEventListener('popstate', handlePopState) + history.replaceState({ screen }, '') + + return () => window.removeEventListener('popstate', handlePopState) + }, []) + const goBack = useCallback(() => { + // Browser: use native back (triggers popstate) + if (!getTelegramWebApp()?.initData) { + history.back() + return + } + // Telegram: update state directly setScreen((prev) => { if (prev.type === 'session') return { type: 'sessions' } if (prev.type === 'machines') return { type: 'sessions' } @@ -481,8 +513,8 @@ export function App() { {sessionsError ?
{sessionsError}
: null} setScreen({ type: 'session', sessionId })} - onNewSession={() => setScreen({ type: 'machines' })} + onSelect={(sessionId) => navigateTo({ type: 'session', sessionId })} + onNewSession={() => navigateTo({ type: 'machines' })} onRefresh={loadSessions} isLoading={sessionsLoading} /> @@ -570,7 +602,7 @@ export function App() { setScreen({ type: 'spawn', machineId })} + onSelect={(machineId) => navigateTo({ type: 'spawn', machineId })} /> ) : ( @@ -586,7 +618,7 @@ export function App() { onCancel={goBack} onSuccess={(sessionId) => { loadSessions() - setScreen({ type: 'session', sessionId }) + navigateTo({ type: 'session', sessionId }) }} />