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 {