refac
This commit is contained in:
1 parent
c1f914a626
commit
c93c6d6fc4
3 files changed
+108
-52
No files matched your search
@@ -116,10 +116,6 @@
|
|||||||
let loadingDirs: Set<string> = new Set();
|
let loadingDirs: Set<string> = new Set();
|
||||||
let directoryMenu: { x: number; y: number } | null = null;
|
let directoryMenu: { x: number; y: number } | null = null;
|
||||||
|
|
||||||
const invalidateVisibleRows = () => {
|
|
||||||
entries = [...entries];
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Normalize Windows backslashes and collapse duplicate separators. */
|
/** Normalize Windows backslashes and collapse duplicate separators. */
|
||||||
const normalizePath = (path: string) => path.replace(/\\/g, '/').replace(/\/{2,}/g, '/');
|
const normalizePath = (path: string) => path.replace(/\\/g, '/').replace(/\/{2,}/g, '/');
|
||||||
|
|
||||||
@@ -145,26 +141,26 @@
|
|||||||
return normalizePath(`${parent}${child}`);
|
return normalizePath(`${parent}${child}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const sortEntries = (items: FileEntry[]): FileEntry[] => {
|
const sortEntries = (items: FileEntry[], mode: SortMode, asc: boolean): FileEntry[] => {
|
||||||
return [...items].sort((a, b) => {
|
return [...items].sort((a, b) => {
|
||||||
// Directories always first
|
// Directories always first
|
||||||
if (a.type !== b.type) return a.type === 'directory' ? -1 : 1;
|
if (a.type !== b.type) return a.type === 'directory' ? -1 : 1;
|
||||||
if (sortBy === 'date') {
|
if (mode === 'date') {
|
||||||
if (a.modified !== undefined && b.modified !== undefined) {
|
if (a.modified !== undefined && b.modified !== undefined) {
|
||||||
return sortAsc ? a.modified - b.modified : b.modified - a.modified;
|
return asc ? a.modified - b.modified : b.modified - a.modified;
|
||||||
}
|
}
|
||||||
const cmp = a.name.localeCompare(b.name);
|
const cmp = a.name.localeCompare(b.name);
|
||||||
return sortAsc ? cmp : -cmp;
|
return asc ? cmp : -cmp;
|
||||||
}
|
}
|
||||||
if (sortBy === 'size') {
|
if (mode === 'size') {
|
||||||
if (a.size !== undefined && b.size !== undefined) {
|
if (a.size !== undefined && b.size !== undefined) {
|
||||||
return sortAsc ? a.size - b.size : b.size - a.size;
|
return asc ? a.size - b.size : b.size - a.size;
|
||||||
}
|
}
|
||||||
const cmp = a.name.localeCompare(b.name);
|
const cmp = a.name.localeCompare(b.name);
|
||||||
return sortAsc ? cmp : -cmp;
|
return asc ? cmp : -cmp;
|
||||||
}
|
}
|
||||||
const cmp = a.name.localeCompare(b.name);
|
const cmp = a.name.localeCompare(b.name);
|
||||||
return sortAsc ? cmp : -cmp;
|
return asc ? cmp : -cmp;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -175,16 +171,16 @@
|
|||||||
sortBy = mode;
|
sortBy = mode;
|
||||||
sortAsc = true;
|
sortAsc = true;
|
||||||
}
|
}
|
||||||
invalidateVisibleRows();
|
|
||||||
treeCache = new Map(treeCache);
|
|
||||||
void refreshBrowser();
|
void refreshBrowser();
|
||||||
};
|
};
|
||||||
|
|
||||||
const filterEntries = (items: FileEntry[]) =>
|
const filterEntries = (items: FileEntry[], hiddenVisible: boolean) =>
|
||||||
showHidden ? items : items.filter((entry) => !entry.name.startsWith('.'));
|
hiddenVisible ? items : items.filter((entry) => !entry.name.startsWith('.'));
|
||||||
|
|
||||||
const entryPath = (parentPath: string, entry: FileEntry) =>
|
const entryPath = (parentPath: string, entry: FileEntry) =>
|
||||||
entry.type === 'directory' ? asDirectoryPath(joinPath(parentPath, entry.name)) : joinPath(parentPath, entry.name);
|
entry.type === 'directory'
|
||||||
|
? asDirectoryPath(joinPath(parentPath, entry.name))
|
||||||
|
: joinPath(parentPath, entry.name);
|
||||||
|
|
||||||
const withRowIndexes = (rows: Omit<BrowserRow, 'rowIndex'>[]): BrowserRow[] =>
|
const withRowIndexes = (rows: Omit<BrowserRow, 'rowIndex'>[]): BrowserRow[] =>
|
||||||
rows.map((row, rowIndex) => ({ ...row, rowIndex }));
|
rows.map((row, rowIndex) => ({ ...row, rowIndex }));
|
||||||
@@ -192,19 +188,35 @@
|
|||||||
const buildVisibleRows = (
|
const buildVisibleRows = (
|
||||||
items: FileEntry[],
|
items: FileEntry[],
|
||||||
parentPath: string,
|
parentPath: string,
|
||||||
|
expanded: Set<string>,
|
||||||
|
cache: Map<string, FileEntry[]>,
|
||||||
|
hiddenVisible: boolean,
|
||||||
|
mode: SortMode,
|
||||||
|
asc: boolean,
|
||||||
depth = 0
|
depth = 0
|
||||||
): Omit<BrowserRow, 'rowIndex'>[] =>
|
): Omit<BrowserRow, 'rowIndex'>[] =>
|
||||||
sortEntries(filterEntries(items)).flatMap((entry) => {
|
sortEntries(filterEntries(items, hiddenVisible), mode, asc).flatMap((entry) => {
|
||||||
const fullPath = entryPath(parentPath, entry);
|
const fullPath = entryPath(parentPath, entry);
|
||||||
const row = { ...entry, fullPath, parentPath, depth };
|
const row = { ...entry, fullPath, parentPath, depth };
|
||||||
const children =
|
const children =
|
||||||
entry.type === 'directory' && expandedDirs.has(fullPath)
|
entry.type === 'directory' && expanded.has(fullPath)
|
||||||
? buildVisibleRows(treeCache.get(fullPath) ?? [], fullPath, depth + 1)
|
? buildVisibleRows(
|
||||||
|
cache.get(fullPath) ?? [],
|
||||||
|
fullPath,
|
||||||
|
expanded,
|
||||||
|
cache,
|
||||||
|
hiddenVisible,
|
||||||
|
mode,
|
||||||
|
asc,
|
||||||
|
depth + 1
|
||||||
|
)
|
||||||
: [];
|
: [];
|
||||||
return [row, ...children];
|
return [row, ...children];
|
||||||
});
|
});
|
||||||
|
|
||||||
$: visibleEntries = withRowIndexes(buildVisibleRows(entries, currentPath));
|
$: visibleEntries = withRowIndexes(
|
||||||
|
buildVisibleRows(entries, currentPath, expandedDirs, treeCache, showHidden, sortBy, sortAsc)
|
||||||
|
);
|
||||||
|
|
||||||
// ── Navigation history ──────────────────────────────────────────────
|
// ── Navigation history ──────────────────────────────────────────────
|
||||||
type NavEntry = { path: string; file: string | null };
|
type NavEntry = { path: string; file: string | null };
|
||||||
@@ -465,18 +477,29 @@
|
|||||||
return isInsideFileRoot(path) ? asDirectoryPath(path) : fileRoot.path;
|
return isInsideFileRoot(path) ? asDirectoryPath(path) : fileRoot.path;
|
||||||
};
|
};
|
||||||
|
|
||||||
const applyCwd = (cwd: TerminalCwd | null, preferredPath?: string) => {
|
const rootFromCwd = (cwd: TerminalCwd | null, pathHint?: string) => {
|
||||||
const cwdPath = cwd?.cwd ? asDirectoryPath(cwd.cwd) : null;
|
const cwdPath = cwd?.cwd ? asDirectoryPath(cwd.cwd) : null;
|
||||||
const homePath = cwd?.home ? asDirectoryPath(cwd.home) : null;
|
const homePath = cwd?.home ? asDirectoryPath(cwd.home) : null;
|
||||||
const preferredDirectory = preferredPath ? asDirectoryPath(preferredPath) : null;
|
const hintPath = pathHint ? asDirectoryPath(pathHint) : null;
|
||||||
const pathForRoot =
|
|
||||||
preferredDirectory && preferredDirectory !== '/' ? preferredDirectory : cwdPath;
|
|
||||||
const homeRoot =
|
|
||||||
homePath && pathForRoot && (pathForRoot === homePath || pathForRoot.startsWith(homePath))
|
|
||||||
? { path: homePath, label: 'Home' }
|
|
||||||
: undefined;
|
|
||||||
const rootPath = cwd?.root?.path ? asDirectoryPath(cwd.root.path) : null;
|
const rootPath = cwd?.root?.path ? asDirectoryPath(cwd.root.path) : null;
|
||||||
setFileRoot(rootPath && rootPath !== '/' ? cwd?.root : (homeRoot ?? cwd?.root));
|
|
||||||
|
if (rootPath && rootPath !== '/') return cwd?.root;
|
||||||
|
|
||||||
|
const pathForHome = hintPath && hintPath !== '/' ? hintPath : cwdPath;
|
||||||
|
if (
|
||||||
|
homePath &&
|
||||||
|
pathForHome &&
|
||||||
|
(pathForHome === homePath || pathForHome.startsWith(homePath))
|
||||||
|
) {
|
||||||
|
return { path: homePath, label: 'Home' };
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
const applyCwd = (cwd: TerminalCwd | null, pathHint?: string) => {
|
||||||
|
const cwdPath = cwd?.cwd ? asDirectoryPath(cwd.cwd) : null;
|
||||||
|
setFileRoot(rootFromCwd(cwd, pathHint));
|
||||||
const path = cwdPath ?? fileRoot?.path ?? '/';
|
const path = cwdPath ?? fileRoot?.path ?? '/';
|
||||||
return clampToFileRoot(path);
|
return clampToFileRoot(path);
|
||||||
};
|
};
|
||||||
@@ -609,7 +632,6 @@
|
|||||||
next.delete(directory);
|
next.delete(directory);
|
||||||
expandedDirs = next;
|
expandedDirs = next;
|
||||||
saveTreeState();
|
saveTreeState();
|
||||||
invalidateVisibleRows();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -624,7 +646,6 @@
|
|||||||
saveTreeState();
|
saveTreeState();
|
||||||
toast.error($i18n.t('Failed to load folder'));
|
toast.error($i18n.t('Failed to load folder'));
|
||||||
} else {
|
} else {
|
||||||
invalidateVisibleRows();
|
|
||||||
treeCache = new Map(treeCache);
|
treeCache = new Map(treeCache);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -1140,20 +1161,21 @@
|
|||||||
if (!handledDisplayFile && terminal) {
|
if (!handledDisplayFile && terminal) {
|
||||||
loading = true;
|
loading = true;
|
||||||
|
|
||||||
void (async () => {
|
void (async () => {
|
||||||
// Discover server features on initial mount
|
// Discover server features on initial mount
|
||||||
const config = await getTerminalConfig(terminal.url, terminal.key);
|
const config = await getTerminalConfig(terminal.url, terminal.key);
|
||||||
terminalEnabled = config?.features?.terminal !== false;
|
terminalEnabled = config?.features?.terminal !== false;
|
||||||
|
|
||||||
const serverCwd = await getCwd(terminal.url, terminal.key, chatId ?? undefined);
|
const serverCwd = await getCwd(terminal.url, terminal.key, chatId ?? undefined);
|
||||||
const serverPath = applyCwd(serverCwd, savedPath);
|
const useServerPath = !!chatId || savedPath === '/';
|
||||||
if (chatId || savedPath === '/') {
|
const serverPath = applyCwd(serverCwd, useServerPath ? undefined : savedPath);
|
||||||
// Fetch session-specific cwd from the server (or global default for new chats)
|
if (useServerPath) {
|
||||||
savedPath = serverPath;
|
// Fetch session-specific cwd from the server (or global default for new chats)
|
||||||
}
|
savedPath = serverPath;
|
||||||
savedPath = clampToFileRoot(savedPath);
|
}
|
||||||
loadDir(savedPath, { restoreTree: true });
|
savedPath = clampToFileRoot(savedPath);
|
||||||
})();
|
loadDir(savedPath, { restoreTree: true });
|
||||||
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
mounted = true;
|
mounted = true;
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
$: directoryPath = entryPath.endsWith('/') ? entryPath : `${entryPath}/`;
|
$: directoryPath = entryPath.endsWith('/') ? entryPath : `${entryPath}/`;
|
||||||
$: writable = entry.writable !== false;
|
$: writable = entry.writable !== false;
|
||||||
$: canMutate = parentWritable && writable;
|
$: canMutate = parentWritable && writable;
|
||||||
$: rowIndent = `${12 + depth * 16}px`;
|
$: rowIndent = `${8 + depth * 16}px`;
|
||||||
|
|
||||||
const formatRelativeTime = (epoch: number): string => {
|
const formatRelativeTime = (epoch: number): string => {
|
||||||
const diff = Math.floor(Date.now() / 1000) - epoch;
|
const diff = Math.floor(Date.now() / 1000) - epoch;
|
||||||
@@ -62,6 +62,7 @@
|
|||||||
|
|
||||||
let dragOverFolder = false;
|
let dragOverFolder = false;
|
||||||
let expandTimer: ReturnType<typeof setTimeout> | null = null;
|
let expandTimer: ReturnType<typeof setTimeout> | null = null;
|
||||||
|
let menuOpen = false;
|
||||||
|
|
||||||
const clearExpandTimer = () => {
|
const clearExpandTimer = () => {
|
||||||
if (!expandTimer) return;
|
if (!expandTimer) return;
|
||||||
@@ -209,7 +210,7 @@
|
|||||||
{#if entry.type === 'directory'}
|
{#if entry.type === 'directory'}
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="mr-1 flex w-3 shrink-0 items-center self-stretch justify-center text-gray-400 dark:text-gray-600 hover:text-gray-600 dark:hover:text-gray-400"
|
class="mr-1.5 flex w-5 shrink-0 items-center self-stretch justify-center text-gray-400 dark:text-gray-600 hover:text-gray-600 dark:hover:text-gray-400"
|
||||||
style="margin-left: {rowIndent};"
|
style="margin-left: {rowIndent};"
|
||||||
on:click|stopPropagation={() => onToggleExpand(directoryPath)}
|
on:click|stopPropagation={() => onToggleExpand(directoryPath)}
|
||||||
aria-label={expanded ? $i18n.t('Collapse') : $i18n.t('Expand')}
|
aria-label={expanded ? $i18n.t('Collapse') : $i18n.t('Expand')}
|
||||||
@@ -222,7 +223,7 @@
|
|||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
{:else}
|
{:else}
|
||||||
<span class="mr-1 w-4 shrink-0 self-stretch" style="margin-left: {rowIndent};"></span>
|
<span class="mr-1.5 w-5 shrink-0 self-stretch" style="margin-left: {rowIndent};"></span>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<button
|
<button
|
||||||
@@ -291,7 +292,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<FileTypeIcon name={entry.name} type={entry.type} size={13} />
|
<FileTypeIcon name={entry.name} type={entry.type} size={12} />
|
||||||
{#if renaming}
|
{#if renaming}
|
||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
<input
|
<input
|
||||||
@@ -333,7 +334,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<Dropdown align="end" sideOffset={4}>
|
<Dropdown bind:show={menuOpen} align="end" sideOffset={4}>
|
||||||
<button
|
<button
|
||||||
class="shrink-0 flex h-5 w-5 items-center justify-center mr-1 rounded transition
|
class="shrink-0 flex h-5 w-5 items-center justify-center mr-1 rounded transition
|
||||||
text-gray-400 hover:text-gray-600 dark:text-gray-500 dark:hover:text-gray-400
|
text-gray-400 hover:text-gray-600 dark:text-gray-500 dark:hover:text-gray-400
|
||||||
@@ -350,6 +351,7 @@
|
|||||||
class="select-none flex h-7 w-full items-center gap-2 rounded-lg px-2 text-xs hover:bg-gray-50/40 dark:hover:bg-white/4 transition"
|
class="select-none flex h-7 w-full items-center gap-2 rounded-lg px-2 text-xs hover:bg-gray-50/40 dark:hover:bg-white/4 transition"
|
||||||
on:click={(e) => {
|
on:click={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
menuOpen = false;
|
||||||
onOpen(entry);
|
onOpen(entry);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -369,6 +371,7 @@
|
|||||||
class="select-none flex h-7 w-full items-center gap-2 rounded-lg px-2 text-xs hover:bg-gray-50/40 dark:hover:bg-white/4 transition"
|
class="select-none flex h-7 w-full items-center gap-2 rounded-lg px-2 text-xs hover:bg-gray-50/40 dark:hover:bg-white/4 transition"
|
||||||
on:click={(e) => {
|
on:click={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
menuOpen = false;
|
||||||
onToggleExpand(directoryPath);
|
onToggleExpand(directoryPath);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -387,6 +390,7 @@
|
|||||||
class="select-none flex h-7 w-full items-center gap-2 rounded-lg px-2 text-xs hover:bg-gray-50/40 dark:hover:bg-white/4 transition"
|
class="select-none flex h-7 w-full items-center gap-2 rounded-lg px-2 text-xs hover:bg-gray-50/40 dark:hover:bg-white/4 transition"
|
||||||
on:click={(e) => {
|
on:click={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
menuOpen = false;
|
||||||
onDownload(entryPath);
|
onDownload(entryPath);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -400,6 +404,7 @@
|
|||||||
class="select-none flex h-7 w-full items-center gap-2 rounded-lg px-2 text-xs hover:bg-gray-50/40 dark:hover:bg-white/4 transition"
|
class="select-none flex h-7 w-full items-center gap-2 rounded-lg px-2 text-xs hover:bg-gray-50/40 dark:hover:bg-white/4 transition"
|
||||||
on:click={(e) => {
|
on:click={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
menuOpen = false;
|
||||||
navigator.clipboard.writeText(entryPath).then(() => {
|
navigator.clipboard.writeText(entryPath).then(() => {
|
||||||
toast.success($i18n.t('Path copied'));
|
toast.success($i18n.t('Path copied'));
|
||||||
});
|
});
|
||||||
@@ -416,6 +421,7 @@
|
|||||||
on:click={(e) => {
|
on:click={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
if (!canMutate) return;
|
if (!canMutate) return;
|
||||||
|
menuOpen = false;
|
||||||
startRename();
|
startRename();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -430,6 +436,7 @@
|
|||||||
on:click={(e) => {
|
on:click={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
if (!canMutate) return;
|
if (!canMutate) return;
|
||||||
|
menuOpen = false;
|
||||||
onDelete(entryPath.replace(/\/$/, ''), entry.name);
|
onDelete(entryPath.replace(/\/$/, ''), entry.name);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
let mounted = false;
|
let mounted = false;
|
||||||
let initializedSlide = '';
|
let initializedSlide = '';
|
||||||
let hideThumbs = false;
|
let hideThumbs = false;
|
||||||
|
const slideShortcutKeys = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'];
|
||||||
|
|
||||||
$: safeSlide = Math.min(Math.max(0, currentSlide), Math.max(0, slides.length - 1));
|
$: safeSlide = Math.min(Math.max(0, currentSlide), Math.max(0, slides.length - 1));
|
||||||
$: selectedSlide = slides[safeSlide] ?? '';
|
$: selectedSlide = slides[safeSlide] ?? '';
|
||||||
@@ -45,6 +46,7 @@
|
|||||||
bounds: true,
|
bounds: true,
|
||||||
boundsPadding: 0.1,
|
boundsPadding: 0.1,
|
||||||
zoomSpeed: 0.065,
|
zoomSpeed: 0.065,
|
||||||
|
filterKey: (e?: KeyboardEvent) => !!e && slideShortcutKeys.includes(e.key),
|
||||||
beforeWheel: (e) => {
|
beforeWheel: (e) => {
|
||||||
if (!e.ctrlKey && !e.metaKey) return true;
|
if (!e.ctrlKey && !e.metaKey) return true;
|
||||||
return false;
|
return false;
|
||||||
@@ -63,13 +65,36 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
const selectSlide = (index: number) => {
|
const selectSlide = (index: number) => {
|
||||||
currentSlide = index;
|
const nextSlide = Math.min(Math.max(0, index), Math.max(0, slides.length - 1));
|
||||||
|
if (nextSlide === safeSlide) return;
|
||||||
|
|
||||||
|
currentSlide = nextSlide;
|
||||||
void tick().then(() => {
|
void tick().then(() => {
|
||||||
updateFitScale();
|
updateFitScale();
|
||||||
resetView();
|
resetView();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleKeyDown = (e: KeyboardEvent) => {
|
||||||
|
if (
|
||||||
|
e.defaultPrevented ||
|
||||||
|
e.altKey ||
|
||||||
|
e.ctrlKey ||
|
||||||
|
e.metaKey ||
|
||||||
|
slides.length === 0 ||
|
||||||
|
!slideShortcutKeys.includes(e.key)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
e.preventDefault();
|
||||||
|
if (e.key === 'ArrowUp' || e.key === 'ArrowLeft') {
|
||||||
|
selectSlide(safeSlide - 1);
|
||||||
|
} else {
|
||||||
|
selectSlide(safeSlide + 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const zoomIn = () => {
|
const zoomIn = () => {
|
||||||
if (!pzInstance || !stageEl) return;
|
if (!pzInstance || !stageEl) return;
|
||||||
pzInstance.zoomTo(stageEl.clientWidth / 2, stageEl.clientHeight / 2, 1.25);
|
pzInstance.zoomTo(stageEl.clientWidth / 2, stageEl.clientHeight / 2, 1.25);
|
||||||
@@ -129,6 +154,8 @@
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<svelte:window on:keydown={handleKeyDown} />
|
||||||
|
|
||||||
<div
|
<div
|
||||||
bind:this={rootEl}
|
bind:this={rootEl}
|
||||||
class="relative grid {hideThumbs
|
class="relative grid {hideThumbs
|
||||||
@@ -138,7 +165,7 @@
|
|||||||
<aside
|
<aside
|
||||||
class={hideThumbs
|
class={hideThumbs
|
||||||
? 'hidden'
|
? 'hidden'
|
||||||
: 'overflow-y-auto px-2.5 pt-3.5 pb-16 border-r border-gray-200/60 dark:border-white/10 bg-transparent'}
|
: 'scrollbar-hidden overflow-y-auto px-2.5 pt-3.5 pb-16 border-r border-gray-200/60 dark:border-white/10 bg-transparent'}
|
||||||
aria-label="Slides"
|
aria-label="Slides"
|
||||||
>
|
>
|
||||||
{#each slides as slide, index}
|
{#each slides as slide, index}
|
||||||
|
|||||||
Reference in new issue
Block a user