mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 13:51:13 -05:00
feat: Enhance image uploader with context menu and deferred upload
This commit is contained in:
78
src/lib/imageUploadHelper.ts
Normal file
78
src/lib/imageUploadHelper.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import type { UploadedImage } from '@/components/upload/EntityMultiImageUploader';
|
||||
|
||||
export interface CloudflareUploadResponse {
|
||||
result: {
|
||||
id: string;
|
||||
variants: string[];
|
||||
};
|
||||
success: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uploads pending local images to Cloudflare via Supabase Edge Function
|
||||
* @param images Array of UploadedImage objects (mix of local and already uploaded)
|
||||
* @returns Array of UploadedImage objects with all images uploaded
|
||||
*/
|
||||
export async function uploadPendingImages(images: UploadedImage[]): Promise<UploadedImage[]> {
|
||||
const uploadedImages: UploadedImage[] = [];
|
||||
|
||||
for (const image of images) {
|
||||
if (image.isLocal && image.file) {
|
||||
try {
|
||||
// Step 1: Get upload URL from our Supabase Edge Function
|
||||
const { data: uploadUrlData, error: urlError } = await supabase.functions.invoke('upload-image', {
|
||||
body: { action: 'get-upload-url' }
|
||||
});
|
||||
|
||||
if (urlError || !uploadUrlData?.uploadURL) {
|
||||
console.error('Error getting upload URL:', urlError);
|
||||
throw new Error('Failed to get upload URL from Cloudflare');
|
||||
}
|
||||
|
||||
// Step 2: Upload file directly to Cloudflare
|
||||
const formData = new FormData();
|
||||
formData.append('file', image.file);
|
||||
|
||||
const uploadResponse = await fetch(uploadUrlData.uploadURL, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
});
|
||||
|
||||
if (!uploadResponse.ok) {
|
||||
throw new Error(`Upload failed with status: ${uploadResponse.status}`);
|
||||
}
|
||||
|
||||
const result: CloudflareUploadResponse = await uploadResponse.json();
|
||||
|
||||
if (!result.success || !result.result) {
|
||||
throw new Error('Cloudflare upload returned unsuccessful response');
|
||||
}
|
||||
|
||||
// Step 3: Return uploaded image metadata
|
||||
uploadedImages.push({
|
||||
url: result.result.variants[0], // Use first variant (usually the original)
|
||||
cloudflare_id: result.result.id,
|
||||
caption: image.caption,
|
||||
isLocal: false,
|
||||
});
|
||||
|
||||
// Clean up object URL
|
||||
URL.revokeObjectURL(image.url);
|
||||
} catch (error) {
|
||||
console.error('Error uploading image:', error);
|
||||
throw new Error(`Failed to upload image: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||
}
|
||||
} else {
|
||||
// Already uploaded, keep as is
|
||||
uploadedImages.push({
|
||||
url: image.url,
|
||||
cloudflare_id: image.cloudflare_id,
|
||||
caption: image.caption,
|
||||
isLocal: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return uploadedImages;
|
||||
}
|
||||
Reference in New Issue
Block a user