From 4bbdabdbde3185103e5bc60e0431a2dd549ba209 Mon Sep 17 00:00:00 2001 From: michaelschal <35957947-michaelschal@users.noreply.replit.com> Date: Thu, 2 Oct 2025 12:28:33 +0000 Subject: [PATCH] Update image display to support multiple sizes and background colors Configure Cloudinary service to generate multiple image transformations (Facebook Feed, Instagram Feed, Instagram Story) upon upload and update frontend to use these generated URLs, adjusting CSS from `object-contain` to `object-cover` for proper display. Replit-Commit-Author: Agent Replit-Commit-Session-Id: ae4037a0-2a6f-4530-9bac-79b543286bda Replit-Commit-Checkpoint-Type: intermediate_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/397bca8c-984f-43ff-841a-10897aeb8140/ae4037a0-2a6f-4530-9bac-79b543286bda/nGcGXQw --- .replit | 4 ++++ client/src/components/media-upload.tsx | 6 +++--- server/services/cloudinary.ts | 23 +++++++++++++++-------- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/.replit b/.replit index ffeb98a..472ebee 100644 --- a/.replit +++ b/.replit @@ -26,6 +26,10 @@ externalPort = 3000 localPort = 43245 externalPort = 3001 +[[ports]] +localPort = 44783 +externalPort = 3003 + [env] PORT = "5000" diff --git a/client/src/components/media-upload.tsx b/client/src/components/media-upload.tsx index a780733..01c4378 100644 --- a/client/src/components/media-upload.tsx +++ b/client/src/components/media-upload.tsx @@ -167,7 +167,7 @@ export default function MediaUpload() { Facebook preview ) : (
@@ -191,7 +191,7 @@ export default function MediaUpload() { Instagram feed preview ) : (
@@ -215,7 +215,7 @@ export default function MediaUpload() { Instagram story preview ) : (
diff --git a/server/services/cloudinary.ts b/server/services/cloudinary.ts index 4d48812..e22da9f 100644 --- a/server/services/cloudinary.ts +++ b/server/services/cloudinary.ts @@ -31,13 +31,22 @@ class CloudinaryService { const isVideo = mimeType.startsWith('video/'); - // Upload to Cloudinary (without eager transformations) + // Define eager transformations for images (generated during upload) + const eagerTransformations = !isVideo ? [ + { width: 1200, height: 630, crop: 'pad', gravity: 'center', background: 'auto' }, // Facebook Feed + { width: 1080, height: 1080, crop: 'pad', gravity: 'center', background: 'auto' }, // Instagram Feed + { width: 1080, height: 1920, crop: 'pad', gravity: 'center', background: 'auto' } // Instagram Story + ] : undefined; + + // Upload to Cloudinary with eager transformations const uploadResult = await new Promise((resolve, reject) => { const uploadStream = cloudinary.uploader.upload_stream( { folder: 'social-flow', public_id: `${Date.now()}-${fileName.replace(/\.[^/.]+$/, '')}`, resource_type: isVideo ? 'video' : 'image', + eager: eagerTransformations, + eager_async: false, // Generate transformations immediately }, (error, result) => { if (error) reject(error); @@ -51,17 +60,15 @@ class CloudinaryService { const publicId = uploadResult.public_id; const originalUrl = uploadResult.secure_url; - // For now, use the original URL for all formats - no transformations - // The frontend will handle display with CSS to prevent cropping + // Extract eager transformation URLs (generated by Cloudinary during upload) let facebookFeedUrl = null; let instagramFeedUrl = null; let instagramStoryUrl = null; - if (!isVideo) { - // Use original image for all formats - NO CROPPING - facebookFeedUrl = originalUrl; - instagramFeedUrl = originalUrl; - instagramStoryUrl = originalUrl; + if (!isVideo && uploadResult.eager && uploadResult.eager.length === 3) { + facebookFeedUrl = uploadResult.eager[0].secure_url; // Facebook Feed (1200x630) + instagramFeedUrl = uploadResult.eager[1].secure_url; // Instagram Feed (1080x1080) + instagramStoryUrl = uploadResult.eager[2].secure_url; // Instagram Story (1080x1920) } return {