파일 페이지에서 즐겨찾기 설정이 가능하도록 변경 및 즐겨찾기에 추가된 경우 목록에서 즐겨찾기 여부를 아이콘으로 표시하도록 개선

This commit is contained in:
static
2026-01-17 20:11:01 +09:00
parent 420e30f677
commit ff6ea3a0b9
18 changed files with 94 additions and 7 deletions

View File

@@ -18,6 +18,7 @@
requestThumbnailUpload,
requestFileAdditionToCategory,
requestVideoStream,
requestFavoriteToggle,
} from "./service";
import TopBarMenu from "./TopBarMenu.svelte";
@@ -75,6 +76,15 @@
void getFileInfo(data.id, $masterKeyStore?.get(1)?.key!); // TODO: FIXME
};
const toggleFavorite = async () => {
if (!info?.exists) return;
const isFavorite = !!info.isFavorite;
const success = await requestFavoriteToggle(data.id, isFavorite);
if (success) {
info.isFavorite = !isFavorite;
}
};
$effect(() => {
HybridPromise.resolve(getFileInfo(data.id, $masterKeyStore?.get(1)?.key!)).then((result) => {
if (data.id === result.id) {
@@ -158,6 +168,8 @@
{fileBlob}
downloadUrl={videoStreamUrl}
filename={info?.name}
isFavorite={info?.isFavorite}
onToggleFavorite={toggleFavorite}
/>
</div>
</TopBar>

View File

@@ -5,6 +5,8 @@
import { fly } from "svelte/transition";
import { goto } from "$app/navigation";
import IconFavorite from "~icons/material-symbols/favorite";
import IconFavoriteOutline from "~icons/material-symbols/favorite-outline";
import IconFolderOpen from "~icons/material-symbols/folder-open";
import IconCloudDownload from "~icons/material-symbols/cloud-download";
@@ -13,10 +15,20 @@
downloadUrl?: string;
fileBlob?: Blob;
filename?: string;
isFavorite?: boolean;
isOpen: boolean;
onToggleFavorite?: () => void;
}
let { directoryId, downloadUrl, fileBlob, filename, isOpen = $bindable() }: Props = $props();
let {
directoryId,
downloadUrl,
fileBlob,
filename,
isFavorite,
isOpen = $bindable(),
onToggleFavorite,
}: Props = $props();
const handleDownload = () => {
if (fileBlob && filename) {
@@ -34,7 +46,7 @@
{#if isOpen && (directoryId || downloadUrl || fileBlob)}
<div
class="absolute right-2 top-full z-20 space-y-1 rounded-lg bg-white px-1 py-2 shadow-2xl"
class="absolute right-2 top-full z-20 min-w-44 space-y-1 rounded-lg bg-white px-1 py-2 shadow-2xl"
transition:fly={{ y: -8, duration: 200 }}
>
<p class="px-3 pt-2 text-sm font-semibold text-gray-600">더보기</p>
@@ -54,6 +66,13 @@
</button>
{/snippet}
{#if typeof isFavorite === "boolean"}
{@render menuButton(
isFavorite ? IconFavorite : IconFavoriteOutline,
isFavorite ? "즐겨찾기 해제" : "즐겨찾기",
onToggleFavorite ?? (() => {}),
)}
{/if}
{#if directoryId}
{@render menuButton(IconFolderOpen, "폴더에서 보기", () =>
goto(

View File

@@ -48,3 +48,16 @@ export const requestFileAdditionToCategory = async (fileId: number, categoryId:
return false;
}
};
export const requestFavoriteToggle = async (fileId: number, isFavorite: boolean) => {
try {
if (isFavorite) {
await trpc().favorites.removeFile.mutate({ id: fileId });
} else {
await trpc().favorites.addFile.mutate({ id: fileId });
}
return true;
} catch {
return false;
}
};

View File

@@ -12,5 +12,5 @@
</script>
<ActionEntryButton class="h-14" {onclick}>
<DirectoryEntryLabel type="directory" name={info.name} />
<DirectoryEntryLabel type="directory" name={info.name} isFavorite={info.isFavorite} />
</ActionEntryButton>

View File

@@ -21,5 +21,6 @@
thumbnail={$thumbnail}
name={info.name}
subtext={formatDateTime(info.createdAt ?? info.lastModifiedAt)}
isFavorite={info.isFavorite}
/>
</ActionEntryButton>

View File

@@ -46,6 +46,7 @@ export const requestSearch = async (filter: SearchFilter, masterKey: CryptoKey)
exists: true,
parentId: directory.parent,
...metadata,
isFavorite: !!directory.isFavorite,
};
},
}),
@@ -65,6 +66,7 @@ export const requestSearch = async (filter: SearchFilter, masterKey: CryptoKey)
exists: true,
parentId: file.parent,
contentType: file.contentType,
isFavorite: !!file.isFavorite,
...metadata,
};
},