fix(web): fix navigation in session creation flow with back buttons

- Add back buttons to MachinesPage and SpawnPage for non-Telegram environments
- Fix navigation after session creation to clear spawn flow from history
- Update useAppGoBack hook to use explicit path navigation for consistent behavior
This commit is contained in:
weishu
2025-12-21 23:55:33 +08:00
parent 04725dda72
commit 16c2e7c7ec
2 changed files with 53 additions and 9 deletions
+5 -6
View File
@@ -1,6 +1,5 @@
import { useCallback } from 'react'
import { useLocation, useNavigate, useRouter } from '@tanstack/react-router'
import { isTelegramApp } from '@/hooks/useTelegram'
export function useAppGoBack(): () => void {
const navigate = useNavigate()
@@ -8,11 +7,7 @@ export function useAppGoBack(): () => void {
const pathname = useLocation({ select: (location) => location.pathname })
return useCallback(() => {
if (!isTelegramApp()) {
router.history.back()
return
}
// Use explicit path navigation for consistent behavior across all environments
if (pathname.startsWith('/sessions/')) {
navigate({ to: '/sessions' })
return
@@ -25,6 +20,10 @@ export function useAppGoBack(): () => void {
if (pathname.startsWith('/machines')) {
navigate({ to: '/sessions' })
return
}
// Fallback to history.back() for other cases
router.history.back()
}, [navigate, pathname, router])
}
+48 -3
View File
@@ -15,6 +15,7 @@ import { MachineList } from '@/components/MachineList'
import { SpawnSession } from '@/components/SpawnSession'
import { useAppContext } from '@/lib/app-context'
import { useAppGoBack } from '@/hooks/useAppGoBack'
import { isTelegramApp } from '@/hooks/useTelegram'
import { useMessages } from '@/hooks/queries/useMessages'
import { useMachines } from '@/hooks/queries/useMachines'
import { useSession } from '@/hooks/queries/useSession'
@@ -24,6 +25,25 @@ import { queryKeys } from '@/lib/query-keys'
import FilesPage from '@/routes/sessions/files'
import FilePage from '@/routes/sessions/file'
function BackIcon(props: { className?: string }) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className={props.className}
>
<polyline points="15 18 9 12 15 6" />
</svg>
)
}
function SessionsPage() {
const { api } = useAppContext()
const navigate = useNavigate()
@@ -110,11 +130,21 @@ function SessionPage() {
function MachinesPage() {
const { api } = useAppContext()
const navigate = useNavigate()
const goBack = useAppGoBack()
const { machines, error: machinesError } = useMachines(api, true)
return (
<div className="flex-1 overflow-y-auto">
<div className="flex items-center gap-2 border-b border-[var(--app-border)] bg-[var(--app-bg)] p-3 pt-[calc(0.75rem+env(safe-area-inset-top))]">
{!isTelegramApp() && (
<button
type="button"
onClick={goBack}
className="flex h-8 w-8 items-center justify-center rounded-full text-[var(--app-hint)] transition-colors hover:bg-[var(--app-secondary-bg)] hover:text-[var(--app-fg)]"
>
<BackIcon />
</button>
)}
<div className="flex-1 font-semibold">Machines</div>
</div>
@@ -140,6 +170,7 @@ function SpawnPage() {
const { machineId } = useParams({ from: '/machines/$machineId/spawn' })
const { machines } = useMachines(api, true)
const navigate = useNavigate()
const goBack = useAppGoBack()
const queryClient = useQueryClient()
const machineForSpawn = machines.find((machine) => machine.id === machineId) ?? null
@@ -150,15 +181,29 @@ function SpawnPage() {
const handleSuccess = useCallback((sessionId: string) => {
void queryClient.invalidateQueries({ queryKey: queryKeys.sessions })
navigate({
to: '/sessions/$sessionId',
params: { sessionId },
// Replace current page with /sessions to clear spawn flow from history
navigate({ to: '/sessions', replace: true })
// Then navigate to new session
requestAnimationFrame(() => {
navigate({
to: '/sessions/$sessionId',
params: { sessionId },
})
})
}, [navigate, queryClient])
return (
<div className="flex-1 overflow-y-auto">
<div className="flex items-center gap-2 border-b border-[var(--app-border)] bg-[var(--app-bg)] p-3 pt-[calc(0.75rem+env(safe-area-inset-top))]">
{!isTelegramApp() && (
<button
type="button"
onClick={goBack}
className="flex h-8 w-8 items-center justify-center rounded-full text-[var(--app-hint)] transition-colors hover:bg-[var(--app-secondary-bg)] hover:text-[var(--app-fg)]"
>
<BackIcon />
</button>
)}
<div className="flex-1 font-semibold">Create Session</div>
</div>