diff --git a/src/lib/components/chat/PyodideFileNav.svelte b/src/lib/components/chat/PyodideFileNav.svelte index ca2c5eb467..0780d2b92a 100644 --- a/src/lib/components/chat/PyodideFileNav.svelte +++ b/src/lib/components/chat/PyodideFileNav.svelte @@ -44,6 +44,52 @@ let newFileName = ''; let newFileInput: HTMLInputElement; + // ── Navigation history ────────────────────────────────────────────────── + type NavEntry = { path: string; file: string | null }; + let navHistory: NavEntry[] = []; + let navIndex = -1; + let navigatingHistory = false; + + $: canGoBack = navIndex > 0; + $: canGoForward = navIndex < navHistory.length - 1; + + const pushNavHistory = (path: string, file: string | null = null) => { + if (navigatingHistory) return; + const current = navHistory[navIndex]; + if (current && current.path === path && current.file === file) return; + if (navIndex < navHistory.length - 1) { + navHistory = navHistory.slice(0, navIndex + 1); + } + navHistory = [...navHistory, { path, file }]; + navIndex = navHistory.length - 1; + }; + + const goBack = async () => { + if (!canGoBack) return; + navigatingHistory = true; + navIndex -= 1; + const entry = navHistory[navIndex]; + await loadDir(entry.path); + if (entry.file) { + const fileName = entry.file.split('/').pop() ?? ''; + await openEntry({ name: fileName, type: 'file', size: 0 }); + } + navigatingHistory = false; + }; + + const goForward = async () => { + if (!canGoForward) return; + navigatingHistory = true; + navIndex += 1; + const entry = navHistory[navIndex]; + await loadDir(entry.path); + if (entry.file) { + const fileName = entry.file.split('/').pop() ?? ''; + await openEntry({ name: fileName, type: 'file', size: 0 }); + } + navigatingHistory = false; + }; + let _reqId = 0; const IMAGE_EXTS = new Set(['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp', 'ico', 'avif']); @@ -106,6 +152,7 @@ clearPreview(); currentPath = path.endsWith('/') ? path : path + '/'; savedPyodidePath = currentPath; + pushNavHistory(currentPath); try { const res = await sendWorkerMessage({ @@ -130,6 +177,7 @@ } const filePath = `${currentPath}${entry.name}`; + pushNavHistory(currentPath, filePath); selectedFile = filePath; fileLoading = true; clearPreview(); @@ -346,19 +394,22 @@ {breadcrumbs} {selectedFile} {loading} + {canGoBack} + {canGoForward} + onGoBack={goBack} + onGoForward={goForward} onNavigate={(path) => loadDir(path)} onRefresh={async () => { - // Sync from IndexedDB first to pick up files written by code execution - try { - await sendWorkerMessage({ type: 'fs:sync' }); - } catch {} - if (selectedFile) { - const name = selectedFile.split('/').pop() ?? ''; - openEntry({ name, type: 'file', size: 0 }); - } else { - loadDir(currentPath); - } - }} + try { + await sendWorkerMessage({ type: 'fs:sync' }); + } catch {} + if (selectedFile) { + const name = selectedFile.split('/').pop() ?? ''; + openEntry({ name, type: 'file', size: 0 }); + } else { + loadDir(currentPath); + } + }} onNewFolder={startNewFolder} onNewFile={startNewFile} onUploadFiles={uploadFiles} @@ -384,28 +435,6 @@ /> -