diff --git a/src/lib/components/organisms/Category/Category.svelte b/src/lib/components/organisms/Category/Category.svelte
index 81471e6..3728f5f 100644
--- a/src/lib/components/organisms/Category/Category.svelte
+++ b/src/lib/components/organisms/Category/Category.svelte
@@ -1,6 +1,7 @@
diff --git a/src/lib/modules/filesystem/category.ts b/src/lib/modules/filesystem/category.ts
index 310a220..dc25506 100644
--- a/src/lib/modules/filesystem/category.ts
+++ b/src/lib/modules/filesystem/category.ts
@@ -52,25 +52,76 @@ const fetchFromServer = async (id: CategoryId, masterKey: CryptoKey) => {
metadata,
subCategories: subCategoriesRaw,
files: filesRaw,
- } = await trpc().category.get.query({ id });
- const [subCategories, files] = await Promise.all([
- Promise.all(
- subCategoriesRaw.map(async (category) => ({
+ } = await trpc().category.get.query({ id, recurse: true });
+ const subCategories = await Promise.all(
+ subCategoriesRaw.map(async (category) => {
+ const decrypted = await decryptCategoryMetadata(category, masterKey);
+ const existing = await IndexedDB.getCategoryInfo(category.id);
+ await IndexedDB.storeCategoryInfo({
id: category.id,
- ...(await decryptCategoryMetadata(category, masterKey)),
- })),
- ),
- filesRaw
- ? Promise.all(
- filesRaw.map(async (file) => ({
+ parentId: id,
+ name: decrypted.name,
+ files: existing?.files ?? [],
+ isFileRecursive: existing?.isFileRecursive ?? false,
+ });
+ return {
+ id: category.id,
+ ...decrypted,
+ };
+ }),
+ );
+
+ const existingFiles = filesRaw
+ ? await IndexedDB.bulkGetFileInfos(filesRaw.map((file) => file.id))
+ : [];
+ const files = filesRaw
+ ? await Promise.all(
+ filesRaw.map(async (file, index) => {
+ const decrypted = await decryptFileMetadata(file, masterKey);
+ const existing = existingFiles[index];
+ if (existing) {
+ const categoryIds = file.isRecursive
+ ? existing.categoryIds
+ : Array.from(new Set([...existing.categoryIds, id as number]));
+ await IndexedDB.storeFileInfo({
+ id: file.id,
+ parentId: existing.parentId,
+ contentType: file.contentType,
+ name: decrypted.name,
+ createdAt: decrypted.createdAt,
+ lastModifiedAt: decrypted.lastModifiedAt,
+ categoryIds,
+ });
+ }
+ return {
id: file.id,
contentType: file.contentType,
isRecursive: file.isRecursive,
- ...(await decryptFileMetadata(file, masterKey)),
- })),
- )
- : undefined,
- ]);
+ ...decrypted,
+ };
+ }),
+ )
+ : undefined;
+
+ const decryptedMetadata = metadata
+ ? await decryptCategoryMetadata(metadata, masterKey)
+ : undefined;
+ if (id !== "root" && metadata && decryptedMetadata) {
+ const existingCategory = await IndexedDB.getCategoryInfo(id);
+ await IndexedDB.storeCategoryInfo({
+ id: id as number,
+ parentId: metadata.parent,
+ name: decryptedMetadata.name,
+ files:
+ files?.map((file) => ({
+ id: file.id,
+ isRecursive: file.isRecursive,
+ })) ??
+ existingCategory?.files ??
+ [],
+ isFileRecursive: existingCategory?.isFileRecursive ?? false,
+ });
+ }
if (id === "root") {
return {
@@ -84,7 +135,7 @@ const fetchFromServer = async (id: CategoryId, masterKey: CryptoKey) => {
exists: true as const,
subCategories,
files,
- ...(await decryptCategoryMetadata(metadata!, masterKey)),
+ ...decryptedMetadata!,
};
}
} catch (e) {
diff --git a/src/lib/modules/filesystem/directory.ts b/src/lib/modules/filesystem/directory.ts
index 6417758..6449480 100644
--- a/src/lib/modules/filesystem/directory.ts
+++ b/src/lib/modules/filesystem/directory.ts
@@ -39,22 +39,52 @@ const fetchFromServer = async (id: DirectoryId, masterKey: CryptoKey) => {
subDirectories: subDirectoriesRaw,
files: filesRaw,
} = await trpc().directory.get.query({ id });
- const [subDirectories, files] = await Promise.all([
+ const existingFiles = await IndexedDB.bulkGetFileInfos(filesRaw.map((file) => file.id));
+ const [subDirectories, files, decryptedMetadata] = await Promise.all([
Promise.all(
- subDirectoriesRaw.map(async (directory) => ({
- id: directory.id,
- ...(await decryptDirectoryMetadata(directory, masterKey)),
- })),
+ subDirectoriesRaw.map(async (directory) => {
+ const decrypted = await decryptDirectoryMetadata(directory, masterKey);
+ await IndexedDB.storeDirectoryInfo({
+ id: directory.id,
+ parentId: id,
+ name: decrypted.name,
+ });
+ return {
+ id: directory.id,
+ ...decrypted,
+ };
+ }),
),
Promise.all(
- filesRaw.map(async (file) => ({
- id: file.id,
- contentType: file.contentType,
- ...(await decryptFileMetadata(file, masterKey)),
- })),
+ filesRaw.map(async (file, index) => {
+ const decrypted = await decryptFileMetadata(file, masterKey);
+ await IndexedDB.storeFileInfo({
+ id: file.id,
+ parentId: id,
+ contentType: file.contentType,
+ name: decrypted.name,
+ createdAt: decrypted.createdAt,
+ lastModifiedAt: decrypted.lastModifiedAt,
+ categoryIds: existingFiles[index]?.categoryIds ?? [],
+ });
+ return {
+ id: file.id,
+ contentType: file.contentType,
+ ...decrypted,
+ };
+ }),
),
+ metadata ? decryptDirectoryMetadata(metadata, masterKey) : undefined,
]);
+ if (id !== "root" && metadata && decryptedMetadata) {
+ await IndexedDB.storeDirectoryInfo({
+ id,
+ parentId: metadata.parent,
+ name: decryptedMetadata.name,
+ });
+ }
+
if (id === "root") {
return {
id,
@@ -69,7 +99,7 @@ const fetchFromServer = async (id: DirectoryId, masterKey: CryptoKey) => {
parentId: metadata!.parent,
subDirectories,
files,
- ...(await decryptDirectoryMetadata(metadata!, masterKey)),
+ ...decryptedMetadata!,
};
}
} catch (e) {
diff --git a/src/lib/modules/filesystem/file.ts b/src/lib/modules/filesystem/file.ts
index d8411bf..45fef78 100644
--- a/src/lib/modules/filesystem/file.ts
+++ b/src/lib/modules/filesystem/file.ts
@@ -66,15 +66,26 @@ const bulkFetchFromIndexedDB = async (ids: number[]) => {
const fetchFromServer = async (id: number, masterKey: CryptoKey) => {
try {
const { categories: categoriesRaw, ...metadata } = await trpc().file.get.query({ id });
- const [categories] = await Promise.all([
+ const [categories, decryptedMetadata] = await Promise.all([
Promise.all(
categoriesRaw.map(async (category) => ({
id: category.id,
...(await decryptCategoryMetadata(category, masterKey)),
})),
),
+ decryptFileMetadata(metadata, masterKey),
]);
+ await IndexedDB.storeFileInfo({
+ id,
+ parentId: metadata.parent,
+ contentType: metadata.contentType,
+ name: decryptedMetadata.name,
+ createdAt: decryptedMetadata.createdAt,
+ lastModifiedAt: decryptedMetadata.lastModifiedAt,
+ categoryIds: categories.map((category) => category.id),
+ });
+
return {
id,
exists: true as const,
@@ -82,7 +93,7 @@ const fetchFromServer = async (id: number, masterKey: CryptoKey) => {
contentType: metadata.contentType,
contentIv: metadata.contentIv,
categories,
- ...(await decryptFileMetadata(metadata, masterKey)),
+ ...decryptedMetadata,
};
} catch (e) {
if (isTRPCClientError(e) && e.data?.code === "NOT_FOUND") {
@@ -97,12 +108,25 @@ const bulkFetchFromServer = async (ids: number[], masterKey: CryptoKey) => {
const filesRaw = await trpc().file.bulkGet.query({ ids });
const files = await Promise.all(
filesRaw.map(async (file) => {
- const categories = await Promise.all(
- file.categories.map(async (category) => ({
- id: category.id,
- ...(await decryptCategoryMetadata(category, masterKey)),
- })),
- );
+ const [categories, decryptedMetadata] = await Promise.all([
+ Promise.all(
+ file.categories.map(async (category) => ({
+ id: category.id,
+ ...(await decryptCategoryMetadata(category, masterKey)),
+ })),
+ ),
+ decryptFileMetadata(file, masterKey),
+ ]);
+
+ await IndexedDB.storeFileInfo({
+ id: file.id,
+ parentId: file.parent,
+ contentType: file.contentType,
+ name: decryptedMetadata.name,
+ createdAt: decryptedMetadata.createdAt,
+ lastModifiedAt: decryptedMetadata.lastModifiedAt,
+ categoryIds: categories.map((category) => category.id),
+ });
return {
id: file.id,
exists: true as const,
@@ -110,7 +134,7 @@ const bulkFetchFromServer = async (ids: number[], masterKey: CryptoKey) => {
contentType: file.contentType,
contentIv: file.contentIv,
categories,
- ...(await decryptFileMetadata(file, masterKey)),
+ ...decryptedMetadata,
};
}),
);