mirror of
https://github.com/kmc7468/arkvault.git
synced 2025-12-12 21:08:46 +00:00
썸네일 표시 구현
This commit is contained in:
@@ -10,18 +10,45 @@
|
||||
name: string;
|
||||
subtext?: string;
|
||||
textClass?: ClassValue;
|
||||
thumbnail?: ArrayBuffer;
|
||||
type: "directory" | "file";
|
||||
}
|
||||
|
||||
let { class: className, name, subtext, textClass: textClassName, type }: Props = $props();
|
||||
let {
|
||||
class: className,
|
||||
name,
|
||||
subtext,
|
||||
textClass: textClassName,
|
||||
thumbnail,
|
||||
type,
|
||||
}: Props = $props();
|
||||
|
||||
let thumbnailUrl: string | undefined = $state();
|
||||
|
||||
$effect(() => {
|
||||
thumbnailUrl = thumbnail && URL.createObjectURL(new Blob([thumbnail]));
|
||||
return () => thumbnailUrl && URL.revokeObjectURL(thumbnailUrl);
|
||||
});
|
||||
</script>
|
||||
|
||||
{#snippet iconSnippet()}
|
||||
<div class="flex h-10 w-10 items-center justify-center overflow-y-hidden text-xl">
|
||||
{#if thumbnailUrl}
|
||||
<img src={thumbnailUrl} alt={name} loading="lazy" />
|
||||
{:else if type === "directory"}
|
||||
<IconFolder />
|
||||
{:else}
|
||||
<IconDraft />
|
||||
{/if}
|
||||
</div>
|
||||
{/snippet}
|
||||
|
||||
{#snippet subtextSnippet()}
|
||||
{subtext}
|
||||
{/snippet}
|
||||
|
||||
<IconLabel
|
||||
icon={type === "directory" ? IconFolder : IconDraft}
|
||||
icon={iconSnippet}
|
||||
iconClass={type === "file" ? "text-blue-400" : undefined}
|
||||
subtext={subtext ? subtextSnippet : undefined}
|
||||
class={className}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
interface Props {
|
||||
children: Snippet;
|
||||
class?: ClassValue;
|
||||
icon: Component<SvelteHTMLElements["svg"]>;
|
||||
icon: Component<SvelteHTMLElements["svg"]> | Snippet;
|
||||
iconClass?: ClassValue;
|
||||
subtext?: Snippet;
|
||||
textClass?: ClassValue;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
import { DirectoryEntryLabel } from "$lib/components/molecules";
|
||||
import type { FileInfo } from "$lib/modules/filesystem";
|
||||
import { formatDateTime } from "$lib/modules/util";
|
||||
import { getFileThumbnail } from "./service";
|
||||
import type { SelectedEntry } from "../service.svelte";
|
||||
|
||||
import IconMoreVert from "~icons/material-symbols/more-vert";
|
||||
@@ -16,6 +17,8 @@
|
||||
|
||||
let { info, onclick, onOpenMenuClick }: Props = $props();
|
||||
|
||||
let thumbnail: ArrayBuffer | undefined = $state();
|
||||
|
||||
const openFile = () => {
|
||||
const { id, dataKey, dataKeyVersion, name } = $info!;
|
||||
if (!dataKey || !dataKeyVersion) return; // TODO: Error handling
|
||||
@@ -29,6 +32,21 @@
|
||||
|
||||
onOpenMenuClick({ type: "file", id, dataKey, dataKeyVersion, name });
|
||||
};
|
||||
|
||||
$effect(() => {
|
||||
if ($info?.dataKey) {
|
||||
getFileThumbnail($info.id, $info.dataKey)
|
||||
.then((thumbnailData) => {
|
||||
thumbnail = thumbnailData ?? undefined;
|
||||
})
|
||||
.catch(() => {
|
||||
// TODO: Error handling
|
||||
thumbnail = undefined;
|
||||
});
|
||||
} else {
|
||||
thumbnail = undefined;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
{#if $info}
|
||||
@@ -40,6 +58,7 @@
|
||||
>
|
||||
<DirectoryEntryLabel
|
||||
type="file"
|
||||
{thumbnail}
|
||||
name={$info.name}
|
||||
subtext={formatDateTime($info.createdAt ?? $info.lastModifiedAt)}
|
||||
/>
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import { callGetApi } from "$lib/hooks";
|
||||
import { decryptData } from "$lib/modules/crypto";
|
||||
import type { FileThumbnailInfoResponse } from "$lib/server/schemas";
|
||||
|
||||
export const getFileThumbnail = async (fileId: number, dataKey: CryptoKey) => {
|
||||
let res = await callGetApi(`/api/file/${fileId}/thumbnail`);
|
||||
if (!res.ok) return null;
|
||||
|
||||
const { contentIv: thumbnailEncryptedIv }: FileThumbnailInfoResponse = await res.json();
|
||||
|
||||
res = await callGetApi(`/api/file/${fileId}/thumbnail/download`);
|
||||
if (!res.ok) return null;
|
||||
|
||||
const thumbnailEncrypted = await res.arrayBuffer();
|
||||
const thumbnail = await decryptData(thumbnailEncrypted, thumbnailEncryptedIv, dataKey);
|
||||
return thumbnail;
|
||||
};
|
||||
Reference in New Issue
Block a user