refac
This commit is contained in:
@@ -89,6 +89,54 @@
|
|||||||
let loading = false;
|
let loading = false;
|
||||||
let error: string | null = null;
|
let error: string | null = null;
|
||||||
|
|
||||||
|
// ── 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;
|
||||||
|
// Skip if this is the same as the current entry
|
||||||
|
const current = navHistory[navIndex];
|
||||||
|
if (current && current.path === path && current.file === file) return;
|
||||||
|
// Truncate forward history when navigating to a new location
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
// ── File preview state ───────────────────────────────────────────────
|
// ── File preview state ───────────────────────────────────────────────
|
||||||
let selectedFile: string | null = null;
|
let selectedFile: string | null = null;
|
||||||
let previewPort: number | null = null;
|
let previewPort: number | null = null;
|
||||||
@@ -259,6 +307,7 @@
|
|||||||
clearFilePreview();
|
clearFilePreview();
|
||||||
currentPath = path;
|
currentPath = path;
|
||||||
savedPath = path;
|
savedPath = path;
|
||||||
|
pushNavHistory(path);
|
||||||
|
|
||||||
const result = await listFiles(terminal.url, terminal.key, path);
|
const result = await listFiles(terminal.url, terminal.key, path);
|
||||||
loading = false;
|
loading = false;
|
||||||
@@ -284,10 +333,12 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const filePath = `${currentPath}${entry.name}`;
|
||||||
|
pushNavHistory(currentPath, filePath);
|
||||||
|
|
||||||
const terminal = selectedTerminal;
|
const terminal = selectedTerminal;
|
||||||
if (!terminal) return;
|
if (!terminal) return;
|
||||||
|
|
||||||
const filePath = `${currentPath}${entry.name}`;
|
|
||||||
selectedFile = filePath;
|
selectedFile = filePath;
|
||||||
fileLoading = true;
|
fileLoading = true;
|
||||||
clearFilePreview();
|
clearFilePreview();
|
||||||
@@ -659,6 +710,10 @@
|
|||||||
breadcrumbs={buildBreadcrumbs(currentPath)}
|
breadcrumbs={buildBreadcrumbs(currentPath)}
|
||||||
{selectedFile}
|
{selectedFile}
|
||||||
{loading}
|
{loading}
|
||||||
|
{canGoBack}
|
||||||
|
{canGoForward}
|
||||||
|
onGoBack={goBack}
|
||||||
|
onGoForward={goForward}
|
||||||
onNavigate={loadDir}
|
onNavigate={loadDir}
|
||||||
onRefresh={() => {
|
onRefresh={() => {
|
||||||
if (selectedFile) {
|
if (selectedFile) {
|
||||||
|
|||||||
@@ -20,6 +20,12 @@
|
|||||||
export let onUploadFiles: (files: File[]) => void = () => {};
|
export let onUploadFiles: (files: File[]) => void = () => {};
|
||||||
export let onMove: (source: string, destFolder: string) => void = () => {};
|
export let onMove: (source: string, destFolder: string) => void = () => {};
|
||||||
|
|
||||||
|
// Back / forward navigation
|
||||||
|
export let canGoBack = false;
|
||||||
|
export let canGoForward = false;
|
||||||
|
export let onGoBack: () => void = () => {};
|
||||||
|
export let onGoForward: () => void = () => {};
|
||||||
|
|
||||||
let dragOverCrumb: number | null = null;
|
let dragOverCrumb: number | null = null;
|
||||||
|
|
||||||
let uploadInput: HTMLInputElement;
|
let uploadInput: HTMLInputElement;
|
||||||
@@ -32,6 +38,38 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex items-center px-2 pb-1.5 shrink-0 gap-1">
|
<div class="flex items-center px-2 pb-1.5 shrink-0 gap-1">
|
||||||
|
<!-- Back -->
|
||||||
|
<Tooltip content={$i18n.t('Back')}>
|
||||||
|
<button
|
||||||
|
class="shrink-0 p-1 rounded transition {canGoBack
|
||||||
|
? 'text-gray-400 dark:text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-800 hover:text-gray-600 dark:hover:text-gray-400'
|
||||||
|
: 'text-gray-200 dark:text-gray-700 cursor-default'}"
|
||||||
|
on:click={onGoBack}
|
||||||
|
disabled={!canGoBack}
|
||||||
|
aria-label={$i18n.t('Back')}
|
||||||
|
>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-3.5">
|
||||||
|
<path fill-rule="evenodd" d="M11.78 5.22a.75.75 0 0 1 0 1.06L8.06 10l3.72 3.72a.75.75 0 1 1-1.06 1.06l-4.25-4.25a.75.75 0 0 1 0-1.06l4.25-4.25a.75.75 0 0 1 1.06 0Z" clip-rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</Tooltip>
|
||||||
|
|
||||||
|
<!-- Forward -->
|
||||||
|
<Tooltip content={$i18n.t('Forward')}>
|
||||||
|
<button
|
||||||
|
class="shrink-0 p-1 rounded transition {canGoForward
|
||||||
|
? 'text-gray-400 dark:text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-800 hover:text-gray-600 dark:hover:text-gray-400'
|
||||||
|
: 'text-gray-200 dark:text-gray-700 cursor-default'}"
|
||||||
|
on:click={onGoForward}
|
||||||
|
disabled={!canGoForward}
|
||||||
|
aria-label={$i18n.t('Forward')}
|
||||||
|
>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-3.5">
|
||||||
|
<path fill-rule="evenodd" d="M8.22 5.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.75.75 0 1 1-1.06-1.06L11.94 10 8.22 6.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</Tooltip>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
bind:this={breadcrumbEl}
|
bind:this={breadcrumbEl}
|
||||||
class="flex items-center flex-1 min-w-0 overflow-x-auto scrollbar-none"
|
class="flex items-center flex-1 min-w-0 overflow-x-auto scrollbar-none"
|
||||||
|
|||||||
Reference in New Issue
Block a user