From 314ea03a1e57bd8c04cdaa2c0fa0878ed387ff91 Mon Sep 17 00:00:00 2001 From: Paulo Castellano Date: Sat, 9 May 2026 14:24:44 -0300 Subject: [PATCH] refactor(posts): extract firstCompatibleVariant helper for platforms with variant pickers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces two TikTok-specific code paths (one in platformIssues, one in togglePlatform) with a single generic helper. PLATFORM_VARIANTS maps each platform that exposes multiple content types via a variant picker to the list of those content types; firstCompatibleVariant returns the first variant that fits the current media (or null when none fits). Both consumers — the tile-level compliance check and the on-select content_type snap — now share the same helper. Adding another platform later (Instagram already has multiple variants if its default ever changes) only requires extending the map, no logic changes. Net effect: -15 lines, no TikTok-specific branching in logic, only data. --- resources/js/pages/posts/Edit.vue | 55 ++++++++++++++++--------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/resources/js/pages/posts/Edit.vue b/resources/js/pages/posts/Edit.vue index 8c7a7167..ceb9007f 100644 --- a/resources/js/pages/posts/Edit.vue +++ b/resources/js/pages/posts/Edit.vue @@ -213,6 +213,20 @@ const getMediaIncompatibilityReason = (contentType: string, mediaItems: MediaIte return null; }; +// Platforms whose tile should consider every available content type when +// deciding whether the attached media is compatible. The user's actual +// variant is picked inside the platform's settings panel — at the tile +// level we just need to know if any variant works. +const PLATFORM_VARIANTS: Record = { + [Platform.TikTok]: ['tiktok_video', 'tiktok_photo'], +}; + +const firstCompatibleVariant = (platform: string, mediaItems: MediaItem[]): string | null => { + const variants = PLATFORM_VARIANTS[platform]; + if (!variants) return null; + return variants.find((ct) => !getMediaIncompatibilityReason(ct, mediaItems)) ?? null; +}; + const platformIssues = computed>(() => { const issues: Record = {}; @@ -223,15 +237,13 @@ const platformIssues = computed>(() => { continue; } - // TikTok has two content types (video / photo) that the user toggles - // inside TikTokSettings. The tile-level check is lenient: a tile is - // only blocked when neither variant accepts the current media. If the - // current variant doesn't fit but the other one does, togglePlatform - // auto-corrects on selection. - if (pp.platform === Platform.TikTok) { - const videoReason = getMediaIncompatibilityReason('tiktok_video', media.value); - const photoReason = getMediaIncompatibilityReason('tiktok_photo', media.value); - if (videoReason && photoReason) issues[pp.id] = videoReason; + // For platforms that expose multiple content types via a variant picker, + // the tile is only blocked when no variant fits — togglePlatform will + // switch to a compatible variant on selection. + if (PLATFORM_VARIANTS[pp.platform]) { + if (!firstCompatibleVariant(pp.platform, media.value)) { + issues[pp.id] = getMediaIncompatibilityReason(contentType, media.value) ?? ''; + } continue; } @@ -343,30 +355,19 @@ const togglePlatform = (platformId: string) => { if (isReadOnly.value) return; const index = selectedPlatformIds.value.indexOf(platformId); if (index === -1) { - adjustTikTokContentTypeForMedia(platformId); + // For platforms with a variant picker, snap the post-platform's + // content_type to one that fits the current media before selection. + const pp = post.value.post_platforms.find((p) => p.id === platformId); + const variant = pp ? firstCompatibleVariant(pp.platform, media.value) : null; + if (variant && platformContentTypes.value[platformId] !== variant) { + platformContentTypes.value = { ...platformContentTypes.value, [platformId]: variant }; + } selectedPlatformIds.value.push(platformId); } else { selectedPlatformIds.value.splice(index, 1); } }; -// TikTok has two content types (video, photo) backed by different API endpoints. -// When the user picks the TikTok tile while media is already attached, switch -// to the matching variant so they don't land on tiktok_video with images and -// see a compliance error. The variant picker in TikTokSettings can still override. -const adjustTikTokContentTypeForMedia = (platformId: string) => { - const pp = post.value.post_platforms.find((p) => p.id === platformId); - if (!pp || pp.platform !== Platform.TikTok || media.value.length === 0) return; - - const first = media.value[0]; - const isImage = first.type === 'image' || first.mime_type?.startsWith('image/'); - const isVideo = first.type === 'video' || first.mime_type?.startsWith('video/'); - const target = isImage ? 'tiktok_photo' : isVideo ? 'tiktok_video' : null; - if (!target || platformContentTypes.value[platformId] === target) return; - - platformContentTypes.value = { ...platformContentTypes.value, [platformId]: target }; -}; - // Save logic const getSubmitData = () => { const platforms = post.value.post_platforms