File size: 1,497 Bytes
7bafae7 561e6f0 7bafae7 561e6f0 7bafae7 561e6f0 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | import {
optimizeImage,
supportsWebpOptimization,
} from "./image-optimizer";
/**
* Upload an image file to the backend.
* Optimizes to WebP variants client-side before uploading.
* Returns the URL of the largest variant for use in the editor.
*/
export async function uploadImage(file: File): Promise<string> {
// Try client-side optimization first
if (supportsWebpOptimization() && file.type.startsWith("image/")) {
try {
const optimized = await optimizeImage(file);
const urls: string[] = [];
for (const variant of optimized.variants) {
const ext = "webp";
const name = file.name.replace(/\.[^.]+$/, "");
const optimizedFile = new File(
[variant.blob],
`${name}-${variant.suffix}.${ext}`,
{ type: "image/webp" }
);
const url = await uploadSingleFile(optimizedFile);
urls.push(url);
}
// Return the largest variant URL
return urls[urls.length - 1];
} catch (err) {
console.warn("[upload] Client-side optimization failed, uploading original:", err);
}
}
return uploadSingleFile(file);
}
async function uploadSingleFile(file: File): Promise<string> {
const form = new FormData();
form.append("file", file);
const res = await fetch("/api/upload", { method: "POST", body: form });
if (!res.ok) {
const text = await res.text();
throw new Error(`Upload failed: ${text}`);
}
const { url } = await res.json();
return url;
}
|