사소한 리팩토링

This commit is contained in:
static
2025-07-08 02:07:54 +09:00
parent 5d9042d149
commit 9b1e27c20b
5 changed files with 46 additions and 65 deletions

View File

@@ -11,7 +11,7 @@ import {
digestMessage,
signMessageHmac,
} from "$lib/modules/crypto";
import { generateImageThumbnail, generateVideoThumbnail } from "$lib/modules/thumbnail";
import { generateThumbnail } from "$lib/modules/thumbnail";
import type {
DuplicateFileScanRequest,
DuplicateFileScanResponse,
@@ -78,30 +78,6 @@ const extractExifDateTime = (fileBuffer: ArrayBuffer) => {
return new Date(utcDate - offsetMs);
};
const generateThumbnail = async (file: File, fileType: string) => {
let url;
try {
if (fileType === "image/heic") {
const { default: heic2any } = await import("heic2any");
url = URL.createObjectURL((await heic2any({ blob: file, toType: "image/png" })) as Blob);
return await generateImageThumbnail(url);
} else if (fileType.startsWith("image/")) {
url = URL.createObjectURL(file);
return await generateImageThumbnail(url);
} else if (fileType.startsWith("video/")) {
url = URL.createObjectURL(file);
return await generateVideoThumbnail(url);
}
return null;
} catch {
return null;
} finally {
if (url) {
URL.revokeObjectURL(url);
}
}
};
const encryptFile = limitFunction(
async (
status: Writable<FileUploadStatus>,
@@ -132,7 +108,7 @@ const encryptFile = limitFunction(
createdAt && (await encryptString(createdAt.getTime().toString(), dataKey));
const lastModifiedAtEncrypted = await encryptString(file.lastModified.toString(), dataKey);
const thumbnail = await generateThumbnail(file, fileType);
const thumbnail = await generateThumbnail(fileBuffer, fileType);
const thumbnailBuffer = await thumbnail?.arrayBuffer();
const thumbnailEncrypted = thumbnailBuffer ? await encryptData(thumbnailBuffer, dataKey) : null;

View File

@@ -12,7 +12,7 @@ const scaleSize = (width: number, height: number, targetSize: number) => {
};
};
export const generateImageThumbnail = (imageUrl: string) => {
const generateImageThumbnail = (imageUrl: string) => {
return new Promise<Blob>((resolve, reject) => {
const image = new Image();
image.onload = () => {
@@ -42,7 +42,7 @@ export const generateImageThumbnail = (imageUrl: string) => {
});
};
export const generateVideoThumbnail = (videoUrl: string, time = 0) => {
const generateVideoThumbnail = (videoUrl: string, time = 0) => {
return new Promise<Blob>((resolve, reject) => {
const video = document.createElement("video");
video.onloadeddata = () => {
@@ -77,6 +77,35 @@ export const generateVideoThumbnail = (videoUrl: string, time = 0) => {
});
};
export const generateThumbnail = async (fileBuffer: ArrayBuffer, fileType: string) => {
let url;
try {
if (fileType === "image/heic") {
const { default: heic2any } = await import("heic2any");
url = URL.createObjectURL(
(await heic2any({
blob: new Blob([fileBuffer], { type: fileType }),
toType: "image/png",
})) as Blob,
);
return await generateImageThumbnail(url);
} else if (fileType.startsWith("image/")) {
url = URL.createObjectURL(new Blob([fileBuffer], { type: fileType }));
return await generateImageThumbnail(url);
} else if (fileType.startsWith("video/")) {
url = URL.createObjectURL(new Blob([fileBuffer], { type: fileType }));
return await generateVideoThumbnail(url);
}
return null;
} catch {
return null;
} finally {
if (url) {
URL.revokeObjectURL(url);
}
}
};
export const getThumbnailUrl = (thumbnailBuffer: ArrayBuffer) => {
return `data:image/webp;base64,${encodeToBase64(thumbnailBuffer)}`;
};

View File

@@ -106,5 +106,5 @@ export const getMissingFileThumbnails = async (userId: number, limit: number = 1
)
.limit(limit)
.execute();
return files.map((file) => file.id);
return files.map(({ id }) => id);
};

View File

@@ -36,8 +36,8 @@ export const requestFileThumbnailDownload = async (fileId: number, dataKey: Cryp
if (!res.ok) return null;
const thumbnailEncrypted = await res.arrayBuffer();
const thumbnail = await decryptData(thumbnailEncrypted, thumbnailEncryptedIv, dataKey);
const thumbnailBuffer = await decryptData(thumbnailEncrypted, thumbnailEncryptedIv, dataKey);
storeFileThumbnailCache(fileId, thumbnail); // Intended
return getThumbnailUrl(thumbnail);
storeFileThumbnailCache(fileId, thumbnailBuffer); // Intended
return getThumbnailUrl(thumbnailBuffer);
};

View File

@@ -3,7 +3,7 @@ import { get, writable, type Writable } from "svelte/store";
import { encryptData } from "$lib/modules/crypto";
import { storeFileThumbnailCache } from "$lib/modules/file";
import type { FileInfo } from "$lib/modules/filesystem";
import { generateImageThumbnail, generateVideoThumbnail } from "$lib/modules/thumbnail";
import { generateThumbnail as doGenerateThumbnail } from "$lib/modules/thumbnail";
import type { FileThumbnailUploadRequest } from "$lib/server/schemas";
import { requestFileDownload } from "$lib/services/file";
@@ -38,42 +38,18 @@ const generateThumbnail = limitFunction(
fileType: string,
dataKey: CryptoKey,
) => {
let url, thumbnail;
status.set("generating");
try {
if (fileType === "image/heic") {
const { default: heic2any } = await import("heic2any");
url = URL.createObjectURL(
(await heic2any({
blob: new Blob([fileBuffer], { type: fileType }),
toType: "image/png",
})) as Blob,
);
thumbnail = await generateImageThumbnail(url);
} else if (fileType.startsWith("image/")) {
url = URL.createObjectURL(new Blob([fileBuffer], { type: fileType }));
thumbnail = await generateImageThumbnail(url);
} else if (fileType.startsWith("video/")) {
url = URL.createObjectURL(new Blob([fileBuffer], { type: fileType }));
thumbnail = await generateVideoThumbnail(url);
} else {
status.set("error");
return null;
}
const thumbnailBuffer = await thumbnail.arrayBuffer();
const thumbnailEncrypted = await encryptData(thumbnailBuffer, dataKey);
status.set("upload-pending");
return { plaintext: thumbnailBuffer, ...thumbnailEncrypted };
} catch {
const thumbnail = await doGenerateThumbnail(fileBuffer, fileType);
if (!thumbnail) {
status.set("error");
return null;
} finally {
if (url) {
URL.revokeObjectURL(url);
}
}
const thumbnailBuffer = await thumbnail.arrayBuffer();
const thumbnailEncrypted = await encryptData(thumbnailBuffer, dataKey);
status.set("upload-pending");
return { plaintext: thumbnailBuffer, ...thumbnailEncrypted };
},
{ concurrency: 4 },
);