mirror of
https://github.com/kmc7468/arkvault.git
synced 2026-02-03 23:56:53 +00:00
검색 필터에 즐겨찾기 여부 추가
This commit is contained in:
@@ -20,7 +20,12 @@ export const getFileCacheIndex = async () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const storeFileCacheIndex = async (fileCacheIndex: FileCacheIndex) => {
|
export const storeFileCacheIndex = async (fileCacheIndex: FileCacheIndex) => {
|
||||||
await cacheIndex.fileCache.put(fileCacheIndex);
|
await cacheIndex.fileCache.put({
|
||||||
|
fileId: fileCacheIndex.fileId,
|
||||||
|
cachedAt: fileCacheIndex.cachedAt,
|
||||||
|
lastRetrievedAt: fileCacheIndex.lastRetrievedAt,
|
||||||
|
size: fileCacheIndex.size,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const deleteFileCacheIndex = async (fileId: number) => {
|
export const deleteFileCacheIndex = async (fileId: number) => {
|
||||||
|
|||||||
@@ -74,7 +74,11 @@ export const getDirectoryInfo = async (id: number) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const storeDirectoryInfo = async (directoryInfo: DirectoryInfo) => {
|
export const storeDirectoryInfo = async (directoryInfo: DirectoryInfo) => {
|
||||||
await filesystem.directory.upsert(directoryInfo.id, { ...directoryInfo });
|
await filesystem.directory.upsert(directoryInfo.id, {
|
||||||
|
parentId: directoryInfo.parentId,
|
||||||
|
name: directoryInfo.name,
|
||||||
|
isFavorite: directoryInfo.isFavorite,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const deleteDirectoryInfo = async (id: number) => {
|
export const deleteDirectoryInfo = async (id: number) => {
|
||||||
@@ -108,7 +112,15 @@ export const bulkGetFileInfos = async (ids: number[]) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const storeFileInfo = async (fileInfo: FileInfo) => {
|
export const storeFileInfo = async (fileInfo: FileInfo) => {
|
||||||
await filesystem.file.upsert(fileInfo.id, { ...fileInfo });
|
await filesystem.file.upsert(fileInfo.id, {
|
||||||
|
parentId: fileInfo.parentId,
|
||||||
|
name: fileInfo.name,
|
||||||
|
contentType: fileInfo.contentType,
|
||||||
|
createdAt: fileInfo.createdAt,
|
||||||
|
lastModifiedAt: fileInfo.lastModifiedAt,
|
||||||
|
categoryIds: fileInfo.categoryIds,
|
||||||
|
isFavorite: fileInfo.isFavorite,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const deleteFileInfo = async (id: number) => {
|
export const deleteFileInfo = async (id: number) => {
|
||||||
@@ -135,7 +147,12 @@ export const getCategoryInfo = async (id: number) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const storeCategoryInfo = async (categoryInfo: CategoryInfo) => {
|
export const storeCategoryInfo = async (categoryInfo: CategoryInfo) => {
|
||||||
await filesystem.category.upsert(categoryInfo.id, { ...categoryInfo });
|
await filesystem.category.upsert(categoryInfo.id, {
|
||||||
|
parentId: categoryInfo.parentId,
|
||||||
|
name: categoryInfo.name,
|
||||||
|
files: categoryInfo.files,
|
||||||
|
isFileRecursive: categoryInfo.isFileRecursive,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const updateCategoryInfo = async (id: number, changes: { isFileRecursive?: boolean }) => {
|
export const updateCategoryInfo = async (id: number, changes: { isFileRecursive?: boolean }) => {
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
includeImages: boolean;
|
includeImages: boolean;
|
||||||
includeVideos: boolean;
|
includeVideos: boolean;
|
||||||
includeDirectories: boolean;
|
includeDirectories: boolean;
|
||||||
|
searchInFavorites: boolean;
|
||||||
searchInDirectory: boolean;
|
searchInDirectory: boolean;
|
||||||
categories: SearchFilter["categories"];
|
categories: SearchFilter["categories"];
|
||||||
}
|
}
|
||||||
@@ -36,6 +37,7 @@
|
|||||||
includeImages: false,
|
includeImages: false,
|
||||||
includeVideos: false,
|
includeVideos: false,
|
||||||
includeDirectories: false,
|
includeDirectories: false,
|
||||||
|
searchInFavorites: false,
|
||||||
searchInDirectory: false,
|
searchInDirectory: false,
|
||||||
categories: [],
|
categories: [],
|
||||||
});
|
});
|
||||||
@@ -45,6 +47,7 @@
|
|||||||
filters.includeImages ||
|
filters.includeImages ||
|
||||||
filters.includeVideos ||
|
filters.includeVideos ||
|
||||||
filters.includeDirectories ||
|
filters.includeDirectories ||
|
||||||
|
filters.searchInFavorites ||
|
||||||
filters.name.trim().length > 0,
|
filters.name.trim().length > 0,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -81,7 +84,9 @@
|
|||||||
|
|
||||||
return sortEntries(
|
return sortEntries(
|
||||||
[...directories, ...files].filter(
|
[...directories, ...files].filter(
|
||||||
({ name }) => !nameFilter || searchString(name, nameFilter),
|
(entry) =>
|
||||||
|
(!nameFilter || searchString(entry.name, nameFilter)) &&
|
||||||
|
(!filters.searchInFavorites || entry.isFavorite),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -118,7 +123,7 @@
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
$effect(() => {
|
$effect.pre(() => {
|
||||||
if (data.directoryId) {
|
if (data.directoryId) {
|
||||||
HybridPromise.resolve(getDirectoryInfo(data.directoryId, $masterKeyStore?.get(1)?.key!)).then(
|
HybridPromise.resolve(getDirectoryInfo(data.directoryId, $masterKeyStore?.get(1)?.key!)).then(
|
||||||
(res) => {
|
(res) => {
|
||||||
@@ -132,6 +137,10 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$effect.pre(() => {
|
||||||
|
filters.searchInFavorites = data.fromFavorites;
|
||||||
|
});
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
// Svelte sucks
|
// Svelte sucks
|
||||||
hasAnyFilter;
|
hasAnyFilter;
|
||||||
@@ -172,6 +181,7 @@
|
|||||||
{#if !hasCategoryFilter}
|
{#if !hasCategoryFilter}
|
||||||
<Chip bind:selected={filters.includeDirectories}>폴더</Chip>
|
<Chip bind:selected={filters.includeDirectories}>폴더</Chip>
|
||||||
{/if}
|
{/if}
|
||||||
|
<Chip bind:selected={filters.searchInFavorites}>즐겨찾기</Chip>
|
||||||
{#if directoryInfo?.exists}
|
{#if directoryInfo?.exists}
|
||||||
<Chip bind:selected={filters.searchInDirectory}>
|
<Chip bind:selected={filters.searchInDirectory}>
|
||||||
위치: {directoryInfo.name}
|
위치: {directoryInfo.name}
|
||||||
|
|||||||
@@ -4,15 +4,18 @@ import type { PageLoad } from "./$types";
|
|||||||
|
|
||||||
export const load: PageLoad = ({ url }) => {
|
export const load: PageLoad = ({ url }) => {
|
||||||
const directoryId = url.searchParams.get("directoryId");
|
const directoryId = url.searchParams.get("directoryId");
|
||||||
|
const from = url.searchParams.get("from");
|
||||||
|
|
||||||
const zodRes = z
|
const zodRes = z
|
||||||
.object({
|
.object({
|
||||||
directoryId: z.coerce.number().int().positive().nullable(),
|
directoryId: z.coerce.number().int().positive().nullable(),
|
||||||
|
from: z.enum(["favorites"]).nullable(),
|
||||||
})
|
})
|
||||||
.safeParse({ directoryId });
|
.safeParse({ directoryId, from });
|
||||||
if (!zodRes.success) error(400, "Invalid query parameters");
|
if (!zodRes.success) error(400, "Invalid query parameters");
|
||||||
|
|
||||||
return {
|
return {
|
||||||
directoryId: zodRes.data.directoryId,
|
directoryId: zodRes.data.directoryId,
|
||||||
|
fromFavorites: zodRes.data.from === "favorites",
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,11 +2,14 @@
|
|||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import { goto } from "$app/navigation";
|
import { goto } from "$app/navigation";
|
||||||
import { RowVirtualizer } from "$lib/components/atoms";
|
import { RowVirtualizer } from "$lib/components/atoms";
|
||||||
|
import { TopBar } from "$lib/components/molecules";
|
||||||
import { masterKeyStore } from "$lib/stores";
|
import { masterKeyStore } from "$lib/stores";
|
||||||
import Directory from "./Directory.svelte";
|
import Directory from "./Directory.svelte";
|
||||||
import File from "./File.svelte";
|
import File from "./File.svelte";
|
||||||
import { requestFavoriteEntries, requestRemoveFavorite, type FavoriteEntry } from "./service";
|
import { requestFavoriteEntries, requestRemoveFavorite, type FavoriteEntry } from "./service";
|
||||||
|
|
||||||
|
import IconSearch from "~icons/material-symbols/search";
|
||||||
|
|
||||||
let { data } = $props();
|
let { data } = $props();
|
||||||
|
|
||||||
let entries: FavoriteEntry[] = $state([]);
|
let entries: FavoriteEntry[] = $state([]);
|
||||||
@@ -41,14 +44,22 @@
|
|||||||
<title>즐겨찾기</title>
|
<title>즐겨찾기</title>
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
<div class="flex h-full flex-col p-4">
|
<TopBar title="즐겨찾기" showBackButton={false}>
|
||||||
|
<button
|
||||||
|
onclick={() => goto("/search?from=favorites")}
|
||||||
|
class="w-full rounded-full p-1 text-2xl active:bg-black active:bg-opacity-[0.04]"
|
||||||
|
>
|
||||||
|
<IconSearch />
|
||||||
|
</button>
|
||||||
|
</TopBar>
|
||||||
|
<div class="flex h-full flex-col p-4 !pt-0">
|
||||||
{#if isLoading}
|
{#if isLoading}
|
||||||
<div class="flex flex-grow items-center justify-center">
|
<div class="flex flex-grow items-center justify-center">
|
||||||
<p class="text-gray-500">
|
<p class="text-gray-500">
|
||||||
{#if data.favorites.files.length === 0 && data.favorites.directories.length === 0}
|
{#if data.favorites.files.length === 0 && data.favorites.directories.length === 0}
|
||||||
즐겨찾기한 항목이 없어요.
|
즐겨찾기한 항목이 없어요.
|
||||||
{:else}
|
{:else}
|
||||||
로딩 중...
|
즐겨찾기 목록을 불러오고 있어요.
|
||||||
{/if}
|
{/if}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -20,5 +20,5 @@
|
|||||||
actionButtonIcon={IconClose}
|
actionButtonIcon={IconClose}
|
||||||
onActionButtonClick={onRemoveClick}
|
onActionButtonClick={onRemoveClick}
|
||||||
>
|
>
|
||||||
<DirectoryEntryLabel type="directory" name={info.name} />
|
<DirectoryEntryLabel type="directory" name={info.name} isFavorite />
|
||||||
</ActionEntryButton>
|
</ActionEntryButton>
|
||||||
|
|||||||
@@ -23,5 +23,5 @@
|
|||||||
actionButtonIcon={IconClose}
|
actionButtonIcon={IconClose}
|
||||||
onActionButtonClick={onRemoveClick}
|
onActionButtonClick={onRemoveClick}
|
||||||
>
|
>
|
||||||
<DirectoryEntryLabel type="file" thumbnail={$thumbnail} name={info.name} />
|
<DirectoryEntryLabel type="file" thumbnail={$thumbnail} name={info.name} isFavorite />
|
||||||
</ActionEntryButton>
|
</ActionEntryButton>
|
||||||
|
|||||||
Reference in New Issue
Block a user