mirror of
https://github.com/kmc7468/arkvault.git
synced 2025-12-14 22:08:45 +00:00
사소한 리팩토링
This commit is contained in:
@@ -11,7 +11,7 @@ import {
|
|||||||
digestMessage,
|
digestMessage,
|
||||||
signMessageHmac,
|
signMessageHmac,
|
||||||
} from "$lib/modules/crypto";
|
} from "$lib/modules/crypto";
|
||||||
import { generateImageThumbnail, generateVideoThumbnail } from "$lib/modules/thumbnail";
|
import { generateThumbnail } from "$lib/modules/thumbnail";
|
||||||
import type {
|
import type {
|
||||||
DuplicateFileScanRequest,
|
DuplicateFileScanRequest,
|
||||||
DuplicateFileScanResponse,
|
DuplicateFileScanResponse,
|
||||||
@@ -78,30 +78,6 @@ const extractExifDateTime = (fileBuffer: ArrayBuffer) => {
|
|||||||
return new Date(utcDate - offsetMs);
|
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(
|
const encryptFile = limitFunction(
|
||||||
async (
|
async (
|
||||||
status: Writable<FileUploadStatus>,
|
status: Writable<FileUploadStatus>,
|
||||||
@@ -132,7 +108,7 @@ const encryptFile = limitFunction(
|
|||||||
createdAt && (await encryptString(createdAt.getTime().toString(), dataKey));
|
createdAt && (await encryptString(createdAt.getTime().toString(), dataKey));
|
||||||
const lastModifiedAtEncrypted = await encryptString(file.lastModified.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 thumbnailBuffer = await thumbnail?.arrayBuffer();
|
||||||
const thumbnailEncrypted = thumbnailBuffer ? await encryptData(thumbnailBuffer, dataKey) : null;
|
const thumbnailEncrypted = thumbnailBuffer ? await encryptData(thumbnailBuffer, dataKey) : null;
|
||||||
|
|
||||||
|
|||||||
@@ -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) => {
|
return new Promise<Blob>((resolve, reject) => {
|
||||||
const image = new Image();
|
const image = new Image();
|
||||||
image.onload = () => {
|
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) => {
|
return new Promise<Blob>((resolve, reject) => {
|
||||||
const video = document.createElement("video");
|
const video = document.createElement("video");
|
||||||
video.onloadeddata = () => {
|
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) => {
|
export const getThumbnailUrl = (thumbnailBuffer: ArrayBuffer) => {
|
||||||
return `data:image/webp;base64,${encodeToBase64(thumbnailBuffer)}`;
|
return `data:image/webp;base64,${encodeToBase64(thumbnailBuffer)}`;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -106,5 +106,5 @@ export const getMissingFileThumbnails = async (userId: number, limit: number = 1
|
|||||||
)
|
)
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
.execute();
|
.execute();
|
||||||
return files.map((file) => file.id);
|
return files.map(({ id }) => id);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ export const requestFileThumbnailDownload = async (fileId: number, dataKey: Cryp
|
|||||||
if (!res.ok) return null;
|
if (!res.ok) return null;
|
||||||
|
|
||||||
const thumbnailEncrypted = await res.arrayBuffer();
|
const thumbnailEncrypted = await res.arrayBuffer();
|
||||||
const thumbnail = await decryptData(thumbnailEncrypted, thumbnailEncryptedIv, dataKey);
|
const thumbnailBuffer = await decryptData(thumbnailEncrypted, thumbnailEncryptedIv, dataKey);
|
||||||
|
|
||||||
storeFileThumbnailCache(fileId, thumbnail); // Intended
|
storeFileThumbnailCache(fileId, thumbnailBuffer); // Intended
|
||||||
return getThumbnailUrl(thumbnail);
|
return getThumbnailUrl(thumbnailBuffer);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { get, writable, type Writable } from "svelte/store";
|
|||||||
import { encryptData } from "$lib/modules/crypto";
|
import { encryptData } from "$lib/modules/crypto";
|
||||||
import { storeFileThumbnailCache } from "$lib/modules/file";
|
import { storeFileThumbnailCache } from "$lib/modules/file";
|
||||||
import type { FileInfo } from "$lib/modules/filesystem";
|
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 type { FileThumbnailUploadRequest } from "$lib/server/schemas";
|
||||||
import { requestFileDownload } from "$lib/services/file";
|
import { requestFileDownload } from "$lib/services/file";
|
||||||
|
|
||||||
@@ -38,42 +38,18 @@ const generateThumbnail = limitFunction(
|
|||||||
fileType: string,
|
fileType: string,
|
||||||
dataKey: CryptoKey,
|
dataKey: CryptoKey,
|
||||||
) => {
|
) => {
|
||||||
let url, thumbnail;
|
|
||||||
status.set("generating");
|
status.set("generating");
|
||||||
|
const thumbnail = await doGenerateThumbnail(fileBuffer, fileType);
|
||||||
try {
|
if (!thumbnail) {
|
||||||
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 {
|
|
||||||
status.set("error");
|
status.set("error");
|
||||||
return null;
|
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 },
|
{ concurrency: 4 },
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user