kaneo (minimalist kanban) fork to experiment adding a tangled integration github.com/usekaneo/kaneo
at main 85 lines 1.8 kB view raw
1import createImageUpload, { 2 finalizeImageUpload, 3} from "@/fetchers/task/create-image-upload"; 4 5const allowedImageMimeTypes = new Set([ 6 "image/apng", 7 "image/avif", 8 "image/gif", 9 "image/heic", 10 "image/heif", 11 "image/jpeg", 12 "image/jpg", 13 "image/png", 14 "image/svg+xml", 15 "image/webp", 16]); 17 18type UploadSurface = "description" | "comment"; 19 20export function isSupportedImageFile(file: File) { 21 return allowedImageMimeTypes.has(file.type.toLowerCase()); 22} 23 24export function isSupportedTaskAsset(file: File) { 25 return file.size > 0; 26} 27 28export function getImageAltText(filename: string) { 29 return filename 30 .replace(/\.[^/.]+$/, "") 31 .replace(/[-_]+/g, " ") 32 .trim(); 33} 34 35export async function uploadTaskImage({ 36 taskId, 37 surface, 38 file, 39}: { 40 taskId: string; 41 surface: UploadSurface; 42 file: File; 43}) { 44 if (!isSupportedImageFile(file)) { 45 if (!isSupportedTaskAsset(file)) { 46 throw new Error("Only non-empty file uploads are supported."); 47 } 48 } 49 50 const upload = await createImageUpload({ 51 taskId, 52 filename: file.name || "image", 53 contentType: file.type, 54 size: file.size, 55 surface, 56 }); 57 58 const response = await fetch(upload.uploadUrl, { 59 method: "PUT", 60 headers: upload.headers, 61 body: file, 62 }); 63 64 if (!response.ok) { 65 throw new Error("Failed to upload file to storage."); 66 } 67 68 const asset = await finalizeImageUpload({ 69 taskId, 70 key: upload.key, 71 filename: file.name || "image", 72 contentType: file.type, 73 size: file.size, 74 surface, 75 }); 76 77 return { 78 url: asset.url, 79 alt: getImageAltText(file.name || "image"), 80 filename: file.name || "file", 81 kind: isSupportedImageFile(file) ? "image" : "attachment", 82 mimeType: file.type, 83 size: file.size, 84 }; 85}