파일 관련 API 요청을 TanStack Query로 마이그레이션

This commit is contained in:
static
2025-07-17 13:09:02 +09:00
parent e10b600293
commit 27fcb7472e
18 changed files with 399 additions and 240 deletions

View File

@@ -3,12 +3,20 @@
import { goto } from "$app/navigation";
import { FloatingButton } from "$lib/components/atoms";
import { TopBar } from "$lib/components/molecules";
import { deleteFileCache, deleteFileThumbnailCache } from "$lib/modules/file";
import {
storeFileCache,
deleteFileCache,
storeFileThumbnailCache,
deleteFileThumbnailCache,
} from "$lib/modules/file";
import {
getDirectoryInfo,
useDirectoryCreation,
useDirectoryRename,
useDirectoryDeletion,
useFileUpload,
useFileRename,
useFileDeletion,
} from "$lib/modules/filesystem2";
import { masterKeyStore, hmacSecretStore } from "$lib/stores";
import DirectoryCreateModal from "./DirectoryCreateModal.svelte";
@@ -20,13 +28,7 @@
import EntryMenuBottomSheet from "./EntryMenuBottomSheet.svelte";
import EntryRenameModal from "./EntryRenameModal.svelte";
import UploadStatusCard from "./UploadStatusCard.svelte";
import {
createContext,
requestHmacSecretDownload,
requestFileUpload,
requestEntryRename,
requestEntryDeletion,
} from "./service.svelte";
import { createContext, requestHmacSecretDownload } from "./service.svelte";
import IconAdd from "~icons/material-symbols/add";
@@ -37,6 +39,11 @@
let requestDirectoryCreation = $derived(useDirectoryCreation(data.id, $masterKeyStore?.get(1)!));
let requestDirectoryRename = useDirectoryRename();
let requestDirectoryDeletion = $derived(useDirectoryDeletion(data.id));
let requestFileUpload = $derived(
useFileUpload(data.id, $masterKeyStore?.get(1)!, $hmacSecretStore?.get(1)!),
);
let requestFileRename = $derived(useFileRename());
let requestFileDeletion = $derived(useFileDeletion(data.id));
let fileInput: HTMLInputElement | undefined = $state();
let duplicatedFile: File | undefined = $state();
@@ -55,21 +62,24 @@
if (!files || files.length === 0) return;
for (const file of files) {
requestFileUpload(file, data.id, $hmacSecretStore?.get(1)!, $masterKeyStore?.get(1)!, () => {
return new Promise((resolve) => {
duplicatedFile = file;
resolveForDuplicateFileModal = resolve;
isDuplicateFileModalOpen = true;
});
})
.then((res) => {
if (!res) return;
// TODO: FIXME
// info = getDirectoryInfo(data.id, $masterKeyStore?.get(1)?.key!);
$requestFileUpload
.mutateAsync({
file,
onDuplicate: () => {
return new Promise((resolve) => {
duplicatedFile = file;
resolveForDuplicateFileModal = resolve;
isDuplicateFileModalOpen = true;
});
},
})
.catch((e: Error) => {
// TODO: FIXME
console.error(e);
.then((res) => {
if (res) {
storeFileCache(res.fileId, res.fileBuffer); // Intended
if (res.thumbnailBuffer) {
storeFileThumbnailCache(res.fileId, res.thumbnailBuffer); // Intended
}
}
});
}
@@ -174,11 +184,13 @@
});
return true; // TODO
} else {
if (await requestEntryRename(context.selectedEntry!, newName)) {
// info = getDirectoryInfo(data.id, $masterKeyStore?.get(1)?.key!); // TODO: FIXME
return true;
}
return false;
$requestFileRename.mutate({
id: context.selectedEntry!.id,
dataKey: context.selectedEntry!.dataKey,
dataKeyVersion: context.selectedEntry!.dataKeyVersion,
newName,
});
return true; // TODO
}
}}
/>
@@ -186,9 +198,7 @@
bind:isOpen={isEntryDeleteModalOpen}
onDeleteClick={async () => {
if (context.selectedEntry!.type === "directory") {
const res = await $requestDirectoryDeletion.mutateAsync({
id: context.selectedEntry!.id,
});
const res = await $requestDirectoryDeletion.mutateAsync({ id: context.selectedEntry!.id });
if (!res) return false;
await Promise.all(
res.deletedFiles.flatMap((fileId) => [
@@ -198,11 +208,12 @@
);
return true; // TODO
} else {
if (await requestEntryDeletion(context.selectedEntry!)) {
// info = getDirectoryInfo(data.id, $masterKeyStore?.get(1)?.key!); // TODO: FIXME
return true;
}
return false;
await $requestFileDeletion.mutateAsync({ id: context.selectedEntry!.id });
await Promise.all([
deleteFileCache(context.selectedEntry!.id),
deleteFileThumbnailCache(context.selectedEntry!.id),
]);
return true; // TODO
}
}}
/>

View File

@@ -1,11 +1,12 @@
<script lang="ts">
import { untrack } from "svelte";
import { get, type Writable } from "svelte/store";
import { getFileInfo, type FileInfo } from "$lib/modules/filesystem";
import {
getDirectoryInfo,
getFileInfo,
type DirectoryInfo,
type DirectoryInfoStore,
type FileInfoStore,
} from "$lib/modules/filesystem2";
import { SortBy, sortEntries } from "$lib/modules/util";
import {
@@ -37,7 +38,7 @@
| {
type: "file";
name?: string;
info: Writable<FileInfo | null>;
info: FileInfoStore;
}
| {
type: "uploading-file";
@@ -60,7 +61,7 @@
const info = getFileInfo(id, $masterKeyStore?.get(1)?.key!);
return {
type: "file",
name: get(info)?.name,
name: get(info).data?.name,
info,
};
})
@@ -93,13 +94,21 @@
}),
)
.concat(
files.map((file) =>
file.info.subscribe((value) => {
if (file.name === value?.name) return;
file.name = value?.name;
sort();
}),
),
files.map((file) => {
if (file.type === "file") {
return file.info.subscribe((value) => {
if (file.name === value.data?.name) return;
file.name = value.data?.name;
sort();
});
} else {
return file.info.subscribe((value) => {
if (file.name === value.name) return;
file.name = value.name;
sort();
});
}
}),
);
return () => unsubscribes.forEach((unsubscribe) => unsubscribe());
});

View File

@@ -1,8 +1,7 @@
<script lang="ts">
import type { Writable } from "svelte/store";
import { ActionEntryButton } from "$lib/components/atoms";
import { DirectoryEntryLabel } from "$lib/components/molecules";
import type { FileInfo } from "$lib/modules/filesystem";
import type { FileInfo, FileInfoStore } from "$lib/modules/filesystem2";
import { formatDateTime } from "$lib/modules/util";
import { requestFileThumbnailDownload } from "./service";
import type { SelectedEntry } from "../service.svelte";
@@ -10,7 +9,7 @@
import IconMoreVert from "~icons/material-symbols/more-vert";
interface Props {
info: Writable<FileInfo | null>;
info: FileInfoStore;
onclick: (selectedEntry: SelectedEntry) => void;
onOpenMenuClick: (selectedEntry: SelectedEntry) => void;
}
@@ -20,22 +19,22 @@
let thumbnail: string | undefined = $state();
const openFile = () => {
const { id, dataKey, dataKeyVersion, name } = $info!;
const { id, dataKey, dataKeyVersion, name } = $info.data as FileInfo;
if (!dataKey || !dataKeyVersion) return; // TODO: Error handling
onclick({ type: "file", id, dataKey, dataKeyVersion, name });
};
const openMenu = () => {
const { id, dataKey, dataKeyVersion, name } = $info!;
const { id, dataKey, dataKeyVersion, name } = $info.data as FileInfo;
if (!dataKey || !dataKeyVersion) return; // TODO: Error handling
onOpenMenuClick({ type: "file", id, dataKey, dataKeyVersion, name });
};
$effect(() => {
if ($info?.dataKey) {
requestFileThumbnailDownload($info.id, $info.dataKey)
if ($info.data?.dataKey) {
requestFileThumbnailDownload($info.data.id, $info.data.dataKey)
.then((thumbnailUrl) => {
thumbnail = thumbnailUrl ?? undefined;
})
@@ -49,7 +48,7 @@
});
</script>
{#if $info}
{#if $info.status === "success"}
<ActionEntryButton
class="h-14"
onclick={openFile}
@@ -59,8 +58,8 @@
<DirectoryEntryLabel
type="file"
{thumbnail}
name={$info.name}
subtext={formatDateTime($info.createdAt ?? $info.lastModifiedAt)}
name={$info.data.name}
subtext={formatDateTime($info.data.createdAt ?? $info.data.lastModifiedAt)}
/>
</ActionEntryButton>
{/if}