From 4cbdfa37d75b2adc79910aa38d91ca1c920085c6 Mon Sep 17 00:00:00 2001 From: Paulo Castellano Date: Fri, 24 Jul 2026 23:29:58 -0300 Subject: [PATCH] Hide video-only formats in the automation Generate node. AI generate only produces images, so Video Pin / Reel / TikTok Video are filtered out in previewOnly and rejected server-side with a clear error. Co-authored-by: Cursor --- app/Enums/PostPlatform/ContentType.php | 1 + .../Automation/GenerateNodeValidator.php | 10 +++--- lang/ar/automations.php | 1 + lang/de/automations.php | 1 + lang/el/automations.php | 1 + lang/en/automations.php | 1 + lang/es/automations.php | 1 + lang/fr/automations.php | 1 + lang/it/automations.php | 1 + lang/ja/automations.php | 1 + lang/ko/automations.php | 1 + lang/nl/automations.php | 1 + lang/pl/automations.php | 1 + lang/pt-BR/automations.php | 1 + lang/ru/automations.php | 1 + lang/tr/automations.php | 1 + lang/zh/automations.php | 1 + .../automations/config/GenerateNodeConfig.vue | 2 +- .../posts/editor/FacebookSettings.vue | 20 ++++++++++-- .../posts/editor/InstagramSettings.vue | 20 ++++++++++-- .../posts/editor/PinterestSettings.vue | 21 ++++++++++-- .../posts/editor/TikTokSettings.vue | 16 +++++++++- resources/js/lib/aiGenerateVariants.ts | 32 +++++++++++++++++++ .../Automation/GenerateNodeValidationTest.php | 19 +++++++++++ 24 files changed, 141 insertions(+), 15 deletions(-) create mode 100644 resources/js/lib/aiGenerateVariants.ts diff --git a/app/Enums/PostPlatform/ContentType.php b/app/Enums/PostPlatform/ContentType.php index 70aa293b..e97f45e7 100644 --- a/app/Enums/PostPlatform/ContentType.php +++ b/app/Enums/PostPlatform/ContentType.php @@ -506,6 +506,7 @@ public static function aiSupported(): array self::MastodonPost, self::FacebookPost, self::PinterestPin, + self::PinterestCarousel, ]; } diff --git a/app/Services/Automation/GenerateNodeValidator.php b/app/Services/Automation/GenerateNodeValidator.php index e04991b2..633527a0 100644 --- a/app/Services/Automation/GenerateNodeValidator.php +++ b/app/Services/Automation/GenerateNodeValidator.php @@ -54,12 +54,14 @@ public function issueFor(array $config): ?string private function issueForAccount(ContentType $contentType, int $imageCount): ?string { - if ($contentType->requiresMedia() && $imageCount === 0) { - return __('posts.edit.compliance.requires_media'); + // Generate only produces images — video-only formats (Reel, Video Pin, …) + // can never be satisfied by this node. + if (! $contentType->supportsImage()) { + return __('automations.errors.generate_image_format_required'); } - if ($imageCount > 0 && ! $contentType->supportsImage()) { - return __('posts.edit.compliance.no_images'); + if ($contentType->requiresMedia() && $imageCount === 0) { + return __('posts.edit.compliance.requires_media'); } $max = min(self::MAX_GENERATED_IMAGES, $contentType->maxMediaCount()); diff --git a/lang/ar/automations.php b/lang/ar/automations.php index 229fedbc..b2ca859b 100644 --- a/lang/ar/automations.php +++ b/lang/ar/automations.php @@ -408,5 +408,6 @@ 'http_request_exception' => 'أطلق طلب HTTP استثناءً.', 'http_request_failed' => 'فشل طلب HTTP.', 'http_items_path_not_array' => 'لم يُفضِ مسار العناصر إلى قائمة.', + 'generate_image_format_required' => 'توليد الذكاء الاصطناعي ينشئ صورًا فقط. اختر تنسيق صورة (وليس فيديو).', ], ]; diff --git a/lang/de/automations.php b/lang/de/automations.php index 69c5ca54..528cbffe 100644 --- a/lang/de/automations.php +++ b/lang/de/automations.php @@ -408,5 +408,6 @@ 'http_request_exception' => 'Die HTTP-Anfrage hat eine Ausnahme ausgelöst.', 'http_request_failed' => 'Die HTTP-Anfrage ist fehlgeschlagen.', 'http_items_path_not_array' => 'Der Pfad zu den Einträgen ergab keine Liste.', + 'generate_image_format_required' => 'KI-Generierung erstellt nur Bilder. Wähle ein Bildformat (kein Video).', ], ]; diff --git a/lang/el/automations.php b/lang/el/automations.php index d40fffbc..da46f16c 100644 --- a/lang/el/automations.php +++ b/lang/el/automations.php @@ -408,5 +408,6 @@ 'http_request_exception' => 'Το αίτημα HTTP προκάλεσε εξαίρεση.', 'http_request_failed' => 'Το αίτημα HTTP απέτυχε.', 'http_items_path_not_array' => 'Η διαδρομή στοιχείων δεν αντιστοιχήθηκε σε λίστα.', + 'generate_image_format_required' => 'Η δημιουργία AI παράγει μόνο εικόνες. Επίλεξε μορφή εικόνας (όχι βίντεο).', ], ]; diff --git a/lang/en/automations.php b/lang/en/automations.php index ecc6b353..aa10e72b 100644 --- a/lang/en/automations.php +++ b/lang/en/automations.php @@ -408,5 +408,6 @@ 'http_request_exception' => 'The HTTP request threw an exception.', 'http_request_failed' => 'The HTTP request failed.', 'http_items_path_not_array' => 'The items path did not resolve to a list.', + 'generate_image_format_required' => 'AI generate only creates images. Pick an image format (not video).', ], ]; diff --git a/lang/es/automations.php b/lang/es/automations.php index 33df6255..b8a05cd3 100644 --- a/lang/es/automations.php +++ b/lang/es/automations.php @@ -408,5 +408,6 @@ 'http_request_exception' => 'La petición HTTP lanzó una excepción.', 'http_request_failed' => 'La petición HTTP falló.', 'http_items_path_not_array' => 'El items path no resolvió a una lista.', + 'generate_image_format_required' => 'La generación con IA solo crea imágenes. Elige un formato de imagen (no vídeo).', ], ]; diff --git a/lang/fr/automations.php b/lang/fr/automations.php index 835282c8..28e92a23 100644 --- a/lang/fr/automations.php +++ b/lang/fr/automations.php @@ -408,5 +408,6 @@ 'http_request_exception' => 'La requête HTTP a levé une exception.', 'http_request_failed' => 'La requête HTTP a échoué.', 'http_items_path_not_array' => 'Le chemin des éléments ne correspond pas à une liste.', + 'generate_image_format_required' => 'La génération IA ne crée que des images. Choisissez un format image (pas vidéo).', ], ]; diff --git a/lang/it/automations.php b/lang/it/automations.php index 37490287..2d01db01 100644 --- a/lang/it/automations.php +++ b/lang/it/automations.php @@ -408,5 +408,6 @@ 'http_request_exception' => 'La richiesta HTTP ha generato un\'eccezione.', 'http_request_failed' => 'La richiesta HTTP non è riuscita.', 'http_items_path_not_array' => 'Il percorso degli elementi non ha restituito un elenco.', + 'generate_image_format_required' => 'La generazione AI crea solo immagini. Scegli un formato immagine (non video).', ], ]; diff --git a/lang/ja/automations.php b/lang/ja/automations.php index 96f67641..0fd2f6ce 100644 --- a/lang/ja/automations.php +++ b/lang/ja/automations.php @@ -408,5 +408,6 @@ 'http_request_exception' => 'HTTP リクエストで例外が発生しました。', 'http_request_failed' => 'HTTP リクエストが失敗しました。', 'http_items_path_not_array' => 'アイテムのパスがリストとして解決されませんでした。', + 'generate_image_format_required' => 'AI生成は画像のみ作成します。画像フォーマットを選んでください(動画不可)。', ], ]; diff --git a/lang/ko/automations.php b/lang/ko/automations.php index 88af31f9..420b941f 100644 --- a/lang/ko/automations.php +++ b/lang/ko/automations.php @@ -408,5 +408,6 @@ 'http_request_exception' => 'HTTP 요청에서 예외가 발생했습니다.', 'http_request_failed' => 'HTTP 요청이 실패했습니다.', 'http_items_path_not_array' => '항목 경로가 목록으로 해석되지 않았습니다.', + 'generate_image_format_required' => 'AI 생성은 이미지만 만듭니다. 이미지 형식을 선택하세요(동영상 불가).', ], ]; diff --git a/lang/nl/automations.php b/lang/nl/automations.php index 8a0c082a..eb5fde1c 100644 --- a/lang/nl/automations.php +++ b/lang/nl/automations.php @@ -408,5 +408,6 @@ 'http_request_exception' => 'Het HTTP-verzoek gaf een uitzondering.', 'http_request_failed' => 'Het HTTP-verzoek is mislukt.', 'http_items_path_not_array' => 'Het itempad verwees niet naar een lijst.', + 'generate_image_format_required' => 'AI-generatie maakt alleen afbeeldingen. Kies een afbeeldingsformaat (geen video).', ], ]; diff --git a/lang/pl/automations.php b/lang/pl/automations.php index d40b87c8..5a898471 100644 --- a/lang/pl/automations.php +++ b/lang/pl/automations.php @@ -408,5 +408,6 @@ 'http_request_exception' => 'Żądanie HTTP zgłosiło wyjątek.', 'http_request_failed' => 'Żądanie HTTP nie powiodło się.', 'http_items_path_not_array' => 'Ścieżka do elementów nie zwróciła listy.', + 'generate_image_format_required' => 'Generowanie AI tworzy tylko obrazy. Wybierz format obrazu (nie wideo).', ], ]; diff --git a/lang/pt-BR/automations.php b/lang/pt-BR/automations.php index 7b4bdfcf..3603ca2a 100644 --- a/lang/pt-BR/automations.php +++ b/lang/pt-BR/automations.php @@ -408,5 +408,6 @@ 'http_request_exception' => 'A requisição HTTP lançou uma exceção.', 'http_request_failed' => 'A requisição HTTP falhou.', 'http_items_path_not_array' => 'O items path não resultou em uma lista.', + 'generate_image_format_required' => 'A geração por IA só cria imagens. Escolha um formato de imagem (não vídeo).', ], ]; diff --git a/lang/ru/automations.php b/lang/ru/automations.php index 2c059b83..1de196ba 100644 --- a/lang/ru/automations.php +++ b/lang/ru/automations.php @@ -408,5 +408,6 @@ 'http_request_exception' => 'HTTP-запрос вызвал исключение.', 'http_request_failed' => 'HTTP-запрос не удался.', 'http_items_path_not_array' => 'Путь к элементам не привёл к списку.', + 'generate_image_format_required' => 'ИИ генерирует только изображения. Выберите формат изображения (не видео).', ], ]; diff --git a/lang/tr/automations.php b/lang/tr/automations.php index a033f4f9..402d06c3 100644 --- a/lang/tr/automations.php +++ b/lang/tr/automations.php @@ -408,5 +408,6 @@ 'http_request_exception' => 'HTTP isteği bir istisna oluşturdu.', 'http_request_failed' => 'HTTP isteği başarısız oldu.', 'http_items_path_not_array' => 'Öğe yolu bir listeye çözümlenmedi.', + 'generate_image_format_required' => 'AI oluşturma yalnızca görsel üretir. Görsel formatı seçin (video değil).', ], ]; diff --git a/lang/zh/automations.php b/lang/zh/automations.php index b1643e2d..e8bbb4e5 100644 --- a/lang/zh/automations.php +++ b/lang/zh/automations.php @@ -408,5 +408,6 @@ 'http_request_exception' => 'HTTP 请求抛出了异常。', 'http_request_failed' => 'HTTP 请求失败。', 'http_items_path_not_array' => '条目路径未解析为列表。', + 'generate_image_format_required' => 'AI 生成仅创建图片。请选择图片格式(不支持视频)。', ], ]; diff --git a/resources/js/components/automations/config/GenerateNodeConfig.vue b/resources/js/components/automations/config/GenerateNodeConfig.vue index 983015c7..c860736a 100644 --- a/resources/js/components/automations/config/GenerateNodeConfig.vue +++ b/resources/js/components/automations/config/GenerateNodeConfig.vue @@ -113,7 +113,7 @@ const defaultContentTypeFor = (platform: string): string => { case Platform.LinkedInPage: return ContentType.LinkedInPagePost; case Platform.TikTok: - return ContentType.TikTokVideo; + return ContentType.TikTokPhoto; case Platform.Pinterest: return ContentType.PinterestPin; case Platform.YouTube: diff --git a/resources/js/components/posts/editor/FacebookSettings.vue b/resources/js/components/posts/editor/FacebookSettings.vue index af379ebb..65d5ef21 100644 --- a/resources/js/components/posts/editor/FacebookSettings.vue +++ b/resources/js/components/posts/editor/FacebookSettings.vue @@ -1,10 +1,11 @@