diff --git a/src/lib/components/TopBar.svelte b/src/lib/components/TopBar.svelte index e245e8b..6f885ef 100644 --- a/src/lib/components/TopBar.svelte +++ b/src/lib/components/TopBar.svelte @@ -17,13 +17,15 @@
- {#if title} -

{title}

- {/if} - {#if children} - {@render children?.()} +

{title}

{/if} +
+ {#if children} + {@render children?.()} + {/if} +
diff --git a/src/routes/(main)/directory/[[id]]/+page.server.ts b/src/routes/(main)/directory/[[id]]/+page.server.ts index 58d64d4..d71982e 100644 --- a/src/routes/(main)/directory/[[id]]/+page.server.ts +++ b/src/routes/(main)/directory/[[id]]/+page.server.ts @@ -1,6 +1,6 @@ import { error } from "@sveltejs/kit"; import { z } from "zod"; -import type { DirectroyInfoResponse } from "$lib/server/schemas"; +import type { DirectroyInfoResponse, FileInfoResponse } from "$lib/server/schemas"; import type { PageServerLoad } from "./$types"; export const load: PageServerLoad = async ({ params, fetch }) => { @@ -27,7 +27,16 @@ export const load: PageServerLoad = async ({ params, fetch }) => { }; }), ); - const fileInfos = directoryInfo.files; // TODO + const fileInfos = await Promise.all( + directoryInfo.files.map(async (fileId) => { + const res = await fetch(`/api/file/${fileId}`); + if (!res.ok) error(500, "Internal server error"); + return { + ...((await res.json()) as FileInfoResponse), + id: fileId, + }; + }), + ); return { id: directoryId, diff --git a/src/routes/(main)/directory/[[id]]/+page.svelte b/src/routes/(main)/directory/[[id]]/+page.svelte index 53f4270..ae0c95d 100644 --- a/src/routes/(main)/directory/[[id]]/+page.svelte +++ b/src/routes/(main)/directory/[[id]]/+page.svelte @@ -5,7 +5,12 @@ import CreateBottomSheet from "./CreateBottomSheet.svelte"; import CreateDirectoryModal from "./CreateDirectoryModal.svelte"; import DirectoryEntry from "./DirectoryEntry.svelte"; - import { decryptDirectroyMetadata, requestDirectroyCreation, requestFileUpload } from "./service"; + import { + decryptDirectroyMetadata, + decryptFileMetadata, + requestDirectroyCreation, + requestFileUpload, + } from "./service"; import IconAdd from "~icons/material-symbols/add"; @@ -43,6 +48,20 @@ }); } }); + const files = $derived.by(() => { + const { files } = data; + if ($masterKeyStore) { + return Promise.all( + files.map(async (file) => ({ + ...(await decryptFileMetadata(file!, $masterKeyStore.get(file.mekVersion)!.key)), + id: file.id, + })), + ).then((files) => { + files.sort((a, b) => a.name.localeCompare(b.name)); + return files; + }); + } + }); const createDirectory = async (name: string) => { await requestDirectroyCreation( @@ -84,7 +103,14 @@ {#if subDirectories} {#await subDirectories then subDirectories} {#each subDirectories as { id, name }} - + + {/each} + {/await} + {/if} + {#if files} + {#await files then files} + {#each files as { id, name }} + {/each} {/await} {/if} diff --git a/src/routes/(main)/directory/[[id]]/DirectoryEntry.svelte b/src/routes/(main)/directory/[[id]]/DirectoryEntry.svelte index 87c739b..69a589d 100644 --- a/src/routes/(main)/directory/[[id]]/DirectoryEntry.svelte +++ b/src/routes/(main)/directory/[[id]]/DirectoryEntry.svelte @@ -2,34 +2,42 @@ import { goto } from "$app/navigation"; import IconFolder from "~icons/material-symbols/folder"; + import IconDraft from "~icons/material-symbols/draft"; import IconMoreVert from "~icons/material-symbols/more-vert"; interface Props { id: number; name: string; + type: "directory" | "file"; } - let { id, name }: Props = $props(); + let { id, name, type }: Props = $props(); - const openDirectory = () => { + const open = () => { setTimeout(() => { - goto(`/directory/${id}`); + goto(`/${type}/${id}`); }, 100); }; -
-
-
- -

{name}

+
+
+
+ {#if type === "directory"} + + {:else if type === "file"} + + {/if}
+

+ {name} +

diff --git a/src/routes/(main)/directory/[[id]]/service.ts b/src/routes/(main)/directory/[[id]]/service.ts index 8baead9..b093e61 100644 --- a/src/routes/(main)/directory/[[id]]/service.ts +++ b/src/routes/(main)/directory/[[id]]/service.ts @@ -14,6 +14,7 @@ import type { DirectroyInfoResponse, DirectoryCreateRequest, FileUploadRequest, + FileInfoResponse, } from "$lib/server/schemas"; import type { MasterKey } from "$lib/stores"; @@ -29,6 +30,15 @@ export const decryptDirectroyMetadata = async ( }; }; +export const decryptFileMetadata = async (metadata: FileInfoResponse, masterKey: CryptoKey) => { + const { dataKey } = await unwrapDataKey(metadata.dek, masterKey); + return { + name: new TextDecoder().decode( + await decryptData(decodeFromBase64(metadata.name), metadata.nameIv, dataKey), + ), + }; +}; + export const requestDirectroyCreation = async ( name: string, parentId: "root" | number,