This commit is contained in:
Timothy Jaeryang Baek committed 2026-08-13 14:46:08 -06:00
1 parent 5cb87e6630
commit a17cb174ad
3 files changed
+25 -20

No files matched your search

+13 -11
View File
@@ -48,7 +48,7 @@
import PortPreview from './FileNav/PortPreview.svelte'; import PortPreview from './FileNav/PortPreview.svelte';
import XTerminal from './XTerminal.svelte'; import XTerminal from './XTerminal.svelte';
const i18n = getContext('i18n'); const i18n: any = getContext('i18n');
export let onAttach: ((blob: Blob, name: string, contentType: string) => void) | null = null; export let onAttach: ((blob: Blob, name: string, contentType: string) => void) | null = null;
export let overlay = false; export let overlay = false;
@@ -251,8 +251,9 @@
terminalChatContextPending = chatScoped && !terminalChatContextHidden && !isSavedChatId(chatId); terminalChatContextPending = chatScoped && !terminalChatContextHidden && !isSavedChatId(chatId);
if (terminalChatContextHidden || terminalChatContextPending) return null; if (terminalChatContextHidden || terminalChatContextPending) return null;
const userTerminal = ($settings?.terminalServers ?? []).find( const settingsValue: any = $settings;
(s) => s.url === $selectedTerminalId const userTerminal = (settingsValue?.terminalServers ?? []).find(
(s: any) => s.url === $selectedTerminalId
); );
const isSystem = !!systemTerminal; const isSystem = !!systemTerminal;
@@ -324,11 +325,16 @@
return normalized.endsWith('/') ? normalized : `${normalized}/`; return normalized.endsWith('/') ? normalized : `${normalized}/`;
}; };
const labelFromPath = (path: string) => {
const parts = normalizePath(path).split('/').filter(Boolean);
return parts.at(-1) ?? '/';
};
const setFileRoot = (root?: TerminalFileRoot) => { const setFileRoot = (root?: TerminalFileRoot) => {
fileRoot = root?.path fileRoot = root?.path
? { ? {
path: asDirectoryPath(root.path), path: asDirectoryPath(root.path),
label: root.label || 'Home' label: root.label || labelFromPath(root.path)
} }
: null; : null;
}; };
@@ -1435,14 +1441,10 @@
{:else if error} {:else if error}
<div class="p-4 text-xs">{error}</div> <div class="p-4 text-xs">{error}</div>
{:else if entries.length === 0 && !creatingFolder && !creatingFile} {:else if entries.length === 0 && !creatingFolder && !creatingFile}
<div class="flex flex-col items-center justify-center gap-1.5 py-12 text-center"> <div class="flex items-center justify-center py-12">
<Folder className="size-6 text-gray-200 dark:text-gray-700" />
<div class="text-xs text-gray-400 dark:text-gray-500"> <div class="text-xs text-gray-400 dark:text-gray-500">
{$i18n.t('This folder is empty')} {$i18n.t('This folder is empty')}
</div> </div>
<div class="text-[0.6875rem] text-gray-300 dark:text-gray-600">
{$i18n.t('Drop files here to upload')}
</div>
</div> </div>
{/if} {/if}
@@ -1520,7 +1522,7 @@
<!-- Port detection --> <!-- Port detection -->
{#if selectedTerminal && !selectedFile && previewPort === null} {#if selectedTerminal && !selectedFile && previewPort === null}
<div class="shrink-0 border-t border-gray-100 dark:border-gray-800"> <div class="shrink-0 border-t border-gray-50 dark:border-gray-850/30">
<PortList <PortList
baseUrl={selectedTerminal.url} baseUrl={selectedTerminal.url}
apiKey={selectedTerminal.key} apiKey={selectedTerminal.key}
@@ -1535,7 +1537,7 @@
<!-- Terminal bottom panel --> <!-- Terminal bottom panel -->
{#if terminalEnabled} {#if terminalEnabled}
<div class="shrink-0 border-t border-gray-100 dark:border-gray-800 bg-white dark:bg-gray-850"> <div class="shrink-0 border-t border-gray-50 dark:border-gray-850/30">
{#if terminalExpanded} {#if terminalExpanded}
<!-- Drag handle (at top of panel) --> <!-- Drag handle (at top of panel) -->
<!-- svelte-ignore a11y-no-static-element-interactions --> <!-- svelte-ignore a11y-no-static-element-interactions -->
@@ -12,7 +12,7 @@
import Pencil from '../../icons/Pencil.svelte'; import Pencil from '../../icons/Pencil.svelte';
import Clipboard from '../../icons/Clipboard.svelte'; import Clipboard from '../../icons/Clipboard.svelte';
const i18n = getContext('i18n'); const i18n: any = getContext('i18n');
export let entry: FileEntry; export let entry: FileEntry;
export let currentPath: string; export let currentPath: string;
@@ -140,7 +140,7 @@
<li class="group"> <li class="group">
<div <div
class="w-full flex items-center transition class="w-full flex items-center transition
{selected ? 'bg-blue-50 dark:bg-blue-900/20' : 'hover:bg-gray-50 dark:hover:bg-gray-800'} {selected ? 'bg-blue-50 dark:bg-blue-900/20' : 'hover:bg-gray-50/40 dark:hover:bg-gray-850/30'}
{dragOverFolder {dragOverFolder
? 'bg-blue-50 dark:bg-blue-900/30 ring-1 ring-blue-400 dark:ring-blue-500 ring-inset' ? 'bg-blue-50 dark:bg-blue-900/30 ring-1 ring-blue-400 dark:ring-blue-500 ring-inset'
: ''}" : ''}"
@@ -303,7 +303,9 @@
{/if} {/if}
<span class="text-xs text-gray-400 shrink-0">{formatFileSize(entry.size)}</span> <span class="text-xs text-gray-400 shrink-0">{formatFileSize(entry.size)}</span>
{:else if entry.type === 'directory' && showDate && entry.modified && !renaming} {:else if entry.type === 'directory' && showDate && entry.modified && !renaming}
<span class="text-[0.625rem] text-gray-400 shrink-0">{formatRelativeTime(entry.modified)}</span> <span class="text-[0.625rem] text-gray-400 shrink-0"
>{formatRelativeTime(entry.modified)}</span
>
{/if} {/if}
</button> </button>
@@ -9,7 +9,7 @@
import Dropdown from '$lib/components/common/Dropdown.svelte'; import Dropdown from '$lib/components/common/Dropdown.svelte';
import DropdownMenu from '$lib/components/common/DropdownMenu.svelte'; import DropdownMenu from '$lib/components/common/DropdownMenu.svelte';
const i18n = getContext('i18n'); const i18n: any = getContext('i18n');
export let breadcrumbs: { label: string; path: string }[] = []; export let breadcrumbs: { label: string; path: string }[] = [];
export let selectedFile: string | null = null; export let selectedFile: string | null = null;
@@ -40,6 +40,9 @@
let uploadInput: HTMLInputElement; let uploadInput: HTMLInputElement;
let breadcrumbEl: HTMLDivElement; let breadcrumbEl: HTMLDivElement;
const showSeparator = (index: number) =>
index > 0 && (breadcrumbs[0]?.label !== '/' || index > 1);
// Scroll breadcrumb to the end after every DOM update // Scroll breadcrumb to the end after every DOM update
afterUpdate(() => { afterUpdate(() => {
if (breadcrumbEl) breadcrumbEl.scrollLeft = breadcrumbEl.scrollWidth; if (breadcrumbEl) breadcrumbEl.scrollLeft = breadcrumbEl.scrollWidth;
@@ -102,11 +105,11 @@
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"
> >
{#each breadcrumbs as crumb, i} {#each breadcrumbs as crumb, i}
{#if i > 1} {#if showSeparator(i)}
<span class="text-gray-300 dark:text-gray-600 text-xs shrink-0 select-none mx-0.5">/</span> <span class="text-gray-300 dark:text-gray-600 text-xs shrink-0 select-none mx-0.5">/</span>
{/if} {/if}
<button <button
class="text-xs shrink-0 px-1 py-0.5 rounded hover:bg-gray-100 dark:hover:bg-gray-800 transition class="text-xs shrink-0 px-1 py-0.5 rounded transition
{!selectedFile && i === breadcrumbs.length - 1 {!selectedFile && i === breadcrumbs.length - 1
? 'text-gray-700 dark:text-gray-300' ? 'text-gray-700 dark:text-gray-300'
: 'text-gray-400 dark:text-gray-500 hover:text-gray-600 dark:hover:text-gray-400'} : 'text-gray-400 dark:text-gray-500 hover:text-gray-600 dark:hover:text-gray-400'}
@@ -149,9 +152,7 @@
{/if} {/if}
</div> </div>
{#if !writable} {#if !writable}
<span class="text-[0.625rem] text-gray-400 dark:text-gray-500 shrink-0"> <span class="text-[0.625rem] text-gray-400 dark:text-gray-500 shrink-0"> Read-only </span>
Read-only
</span>
{/if} {/if}
<Tooltip content={$i18n.t('Refresh')}> <Tooltip content={$i18n.t('Refresh')}>