Enhance image upload handling by integrating HEIC to JPEG conversion in receipts routes. Update ReceiptForm and related components to improve user feedback during image processing, ensuring compatibility with HEIC files. Refactor image handling logic for better maintainability and user experience.
CI / build (push) Has been skipped
CI / deploy (push) Successful in 1m35s

This commit is contained in:
eewing
2026-02-26 10:48:33 -06:00
parent 694a5295cc
commit b72df41ec7
8 changed files with 162 additions and 41 deletions
+39
View File
@@ -0,0 +1,39 @@
/**
* Server-side HEIC conversion using heic-convert (Node). Use in form actions only.
*/
export function isHeicFile(file: File): boolean {
const name = file.name.toLowerCase();
const type = (file.type ?? "").toLowerCase();
return (
name.endsWith(".heic") ||
name.endsWith(".heif") ||
type === "image/heic" ||
type === "image/heif"
);
}
/**
* If the file is HEIC/HEIF, convert to JPEG and return a new File. Otherwise return the original.
*/
export async function convertHeicFileToJpegIfNeeded(file: File): Promise<File> {
if (!isHeicFile(file)) return file;
const arrayBuffer = await file.arrayBuffer();
const inputBuffer = Buffer.from(arrayBuffer);
const convert = (await import("heic-convert")).default as (opts: {
buffer: Buffer;
format: string;
quality?: number;
}) => Promise<Buffer>;
const outputBuffer = await convert({
buffer: inputBuffer,
format: "JPEG",
quality: 0.92,
});
const baseName = file.name.replace(/\.[^.]+$/i, "") || "image";
return new File([outputBuffer], `${baseName}.jpg`, {
type: "image/jpeg",
lastModified: Date.now(),
});
}