diff --git a/src/lib/server/db/file.ts b/src/lib/server/db/file.ts index b99bd38..a42235b 100644 --- a/src/lib/server/db/file.ts +++ b/src/lib/server/db/file.ts @@ -129,14 +129,15 @@ export const unregisterDirectory = async (userId: number, directoryId: number) = return await db.transaction( async (tx) => { const unregisterFiles = async (parentId: number) => { - const files = await tx + return await tx .delete(file) .where(and(eq(file.userId, userId), eq(file.parentId, parentId))) - .returning({ path: file.path }); - return files.map(({ path }) => path); + .returning({ id: file.id, path: file.path }); }; - const unregisterDirectoryRecursively = async (directoryId: number): Promise => { - const filePaths = await unregisterFiles(directoryId); + const unregisterDirectoryRecursively = async ( + directoryId: number, + ): Promise<{ id: number; path: string }[]> => { + const files = await unregisterFiles(directoryId); const subDirectories = await tx .select({ id: directory.id }) .from(directory) @@ -149,7 +150,7 @@ export const unregisterDirectory = async (userId: number, directoryId: number) = if (deleteRes.changes === 0) { throw new IntegrityError("Directory not found"); } - return filePaths.concat(...subDirectoryFilePaths); + return files.concat(...subDirectoryFilePaths); }; return await unregisterDirectoryRecursively(directoryId); }, diff --git a/src/lib/server/schemas/directory.ts b/src/lib/server/schemas/directory.ts index 5f526aa..17d5720 100644 --- a/src/lib/server/schemas/directory.ts +++ b/src/lib/server/schemas/directory.ts @@ -15,6 +15,11 @@ export const directoryInfoResponse = z.object({ }); export type DirectoryInfoResponse = z.infer; +export const directoryDeleteResponse = z.object({ + deletedFiles: z.number().int().positive().array(), +}); +export type DirectoryDeleteResponse = z.infer; + export const directoryRenameRequest = z.object({ dekVersion: z.string().datetime(), name: z.string().base64().nonempty(), diff --git a/src/lib/server/services/directory.ts b/src/lib/server/services/directory.ts index aba0343..3f6b55d 100644 --- a/src/lib/server/services/directory.ts +++ b/src/lib/server/services/directory.ts @@ -34,8 +34,13 @@ export const getDirectoryInformation = async (userId: number, directoryId: "root export const deleteDirectory = async (userId: number, directoryId: number) => { try { - const filePaths = await unregisterDirectory(userId, directoryId); - filePaths.map((path) => unlink(path)); // Intended + const files = await unregisterDirectory(userId, directoryId); + return { + files: files.map(({ id, path }) => { + unlink(path); // Intended + return id; + }), + }; } catch (e) { if (e instanceof IntegrityError && e.message === "Directory not found") { error(404, "Invalid directory id"); diff --git a/src/routes/(fullscreen)/setting/cache/+page.svelte b/src/routes/(fullscreen)/setting/cache/+page.svelte index a32b5c6..6f3770e 100644 --- a/src/routes/(fullscreen)/setting/cache/+page.svelte +++ b/src/routes/(fullscreen)/setting/cache/+page.svelte @@ -29,7 +29,12 @@ fileInfo: getFileInfo(index.fileId, $masterKeyStore?.get(1)?.key!), })) .sort((a, b) => a.index.lastRetrievedAt.getTime() - b.index.lastRetrievedAt.getTime()); - fileCacheTotalSize = fileCache.reduce((acc, { index }) => acc + index.size, 0); + }); + + $effect(() => { + if (fileCache) { + fileCacheTotalSize = fileCache.reduce((acc, { index }) => acc + index.size, 0); + } }); @@ -39,7 +44,7 @@
- {#if fileCache} + {#if fileCache && fileCache.length > 0}

@@ -56,7 +61,13 @@

{:else}
-

캐시 목록을 불러오고 있어요.

+

+ {#if fileCache} + 캐시된 파일이 없어요. + {:else} + 캐시 목록을 불러오고 있어요. + {/if} +

{/if}
diff --git a/src/routes/(main)/directory/[[id]]/service.ts b/src/routes/(main)/directory/[[id]]/service.ts index bf1f867..00d28ab 100644 --- a/src/routes/(main)/directory/[[id]]/service.ts +++ b/src/routes/(main)/directory/[[id]]/service.ts @@ -19,6 +19,7 @@ import type { HmacSecretListResponse, DuplicateFileScanRequest, DuplicateFileScanResponse, + DirectoryDeleteResponse, } from "$lib/server/schemas"; import { hmacSecretStore, type MasterKey, type HmacSecret } from "$lib/stores"; @@ -191,6 +192,15 @@ export const requestDirectoryEntryRename = async ( }; export const requestDirectoryEntryDeletion = async (entry: SelectedDirectoryEntry) => { - await callPostApi(`/api/${entry.type}/${entry.id}/delete`); - await deleteFileCache(entry.id); + const res = await callPostApi(`/api/${entry.type}/${entry.id}/delete`); + if (!res.ok) return false; + + if (entry.type === "directory") { + const { deletedFiles }: DirectoryDeleteResponse = await res.json(); + await Promise.all(deletedFiles.map(deleteFileCache)); + return true; + } else { + await deleteFileCache(entry.id); + return true; + } }; diff --git a/src/routes/api/directory/[id]/delete/+server.ts b/src/routes/api/directory/[id]/delete/+server.ts index 4873912..4d29fd8 100644 --- a/src/routes/api/directory/[id]/delete/+server.ts +++ b/src/routes/api/directory/[id]/delete/+server.ts @@ -1,6 +1,7 @@ -import { error, text } from "@sveltejs/kit"; +import { error, json } from "@sveltejs/kit"; import { z } from "zod"; import { authorize } from "$lib/server/modules/auth"; +import { directoryDeleteResponse, type DirectoryDeleteResponse } from "$lib/server/schemas"; import { deleteDirectory } from "$lib/server/services/directory"; import type { RequestHandler } from "./$types"; @@ -15,6 +16,8 @@ export const POST: RequestHandler = async ({ locals, params }) => { if (!zodRes.success) error(400, "Invalid path parameters"); const { id } = zodRes.data; - await deleteDirectory(userId, id); - return text("Directory deleted", { headers: { "Content-Type": "text/plain" } }); + const { files } = await deleteDirectory(userId, id); + return json( + directoryDeleteResponse.parse({ deletedFiles: files } satisfies DirectoryDeleteResponse), + ); };