Add cloud breadcrumbs and even out cloud cards

This commit is contained in:
2026-07-18 19:40:42 -04:00
parent 470d8c3d25
commit 5cb37ff80d
2 changed files with 61 additions and 7 deletions
+38 -3
View File
@@ -6,6 +6,7 @@
app,
breadcrumbs,
browseTo,
cloudBreadcrumbs,
linkedDocument,
linkedSpace,
openCloudFolder,
@@ -53,6 +54,7 @@
let menuAt = $state({ x: 0, y: 0 });
const trail = $derived(breadcrumbs());
const cloudTrail = $derived(cloudBreadcrumbs());
$effect(() => {
if (app.scope === "cloud" && app.account) {
@@ -200,10 +202,10 @@
<div
class="group flex flex-col overflow-hidden rounded-lg border border-[var(--color-line)] bg-[var(--color-surface)] transition hover:border-[var(--color-accent)] hover:shadow-sm"
>
{#if link && cloudThumbs[link.path]}
<div
class="flex h-24 items-center justify-center overflow-hidden border-b border-[var(--color-line)] bg-[var(--color-surface-muted)]"
>
{#if link && cloudThumbs[link.path]}
{#if cloudThumbs[link.path].kind === "svg"}
<span
class="flex w-full items-start justify-center bg-white p-1 [&_svg]:h-auto [&_svg]:w-full"
@@ -217,12 +219,18 @@
class="h-full w-full object-contain"
/>
{/if}
</div>
{:else}
<Icon
{icon}
class="text-3xl {link
? 'text-[var(--color-accent)]'
: 'text-[var(--color-ink-muted)]'}"
/>
{/if}
</div>
<div class="flex flex-col gap-2.5 p-3">
<div class="flex items-start gap-2">
<Icon {icon} class="shrink-0 text-xl text-[var(--color-accent)]" />
<div class="min-w-0 flex-1">
<p class="truncate text-xs font-medium" {title}>{title}</p>
<p class="truncate text-[10px] text-[var(--color-ink-muted)]">{meta}</p>
@@ -676,6 +684,33 @@
{/if}
</div>
{#if cloudTrail.length > 0}
<div class="mb-3 flex flex-wrap items-center gap-1 text-xs">
<button
class="rounded px-2 py-1 text-[var(--color-ink-muted)] transition hover:bg-[var(--color-surface)] hover:text-[var(--color-ink)]"
onclick={() => openCloudFolder(null)}
>
My Drive
</button>
{#each cloudTrail as folder, index}
<Icon
icon="ph:caret-right"
class="text-[10px] text-[var(--color-ink-muted)]"
/>
<button
class="rounded px-2 py-1 transition hover:bg-[var(--color-surface)]
{index === cloudTrail.length - 1
? 'font-medium'
: 'text-[var(--color-ink-muted)] hover:text-[var(--color-ink)]'}"
onclick={() => openCloudFolder(folder.id)}
>
{folder.name}
</button>
{/each}
</div>
{/if}
{#if app.cloudFolders.length > 0}
<div
class="mb-4 grid grid-cols-[repeat(auto-fill,minmax(210px,1fr))] gap-2"
+19
View File
@@ -31,6 +31,7 @@ interface AppState {
spaces: SpaceSummary[];
cloudFolder: string | null | "shared";
cloudFolders: CloudFolder[];
cloudFolderTree: CloudFolder[];
cloudDocuments: CloudDocument[];
cloudFiles: CloudFile[];
cloudLoading: boolean;
@@ -65,6 +66,7 @@ export const app = $state<AppState>({
spaces: [],
cloudFolder: null,
cloudFolders: [],
cloudFolderTree: [],
cloudDocuments: [],
cloudFiles: [],
cloudLoading: false,
@@ -188,6 +190,7 @@ export async function refreshCloud() {
api.cloudListSpaces(),
api.cloudListFiles(app.cloudFolder),
]);
app.cloudFolderTree = folders;
app.cloudFolders = folders.filter(
(folder) => (folder.parent_id ?? null) === app.cloudFolder,
);
@@ -202,6 +205,22 @@ export async function refreshCloud() {
}
}
/** Trail from the drive root down to the folder being viewed. */
export function cloudBreadcrumbs(): CloudFolder[] {
if (app.cloudFolder === "shared" || app.cloudFolder === null) return [];
const byId = new Map(app.cloudFolderTree.map((folder) => [folder.id, folder]));
const trail: CloudFolder[] = [];
let current = byId.get(app.cloudFolder);
while (current) {
trail.unshift(current);
current = current.parent_id ? byId.get(current.parent_id) : undefined;
}
return trail;
}
export async function openCloudFolder(id: string | null | "shared") {
app.cloudFolder = id;
await refreshCloud();