From 967c1481d3f40e2ed01823bd4a698cbd65ac93a6 Mon Sep 17 00:00:00 2001 From: Paulo Castellano Date: Sat, 9 May 2026 14:22:15 -0300 Subject: [PATCH] fix(tiktok): tile-level compliance is lenient when media has another viable variant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reverts the previous reactive watcher approach. Replaces it with two small, declarative changes: 1. platformIssues for TikTok now checks whether ANY variant (tiktok_video / tiktok_photo) accepts the current media. The tile only stays blocked when neither variant fits (e.g. a GIF, mixed media). This matches the platform's real capability — TikTok does accept both videos and photos — and stops disabling the tile based on the post-platform's stale default content_type. 2. togglePlatform, when SELECTING TikTok, switches the post-platform's content_type to the variant that matches the first attached media (tiktok_video for video, tiktok_photo for image). Runs only on selection, not as a watcher — no implicit reactivity, no side effects on subsequent media changes. The variant picker inside TikTokSettings remains the user's manual override. Reproducer fixed: new post → attach image → TikTok tile is now clickable instead of greyed out with 'Only videos are allowed for this format'. After clicking, content_type is tiktok_photo. --- resources/js/pages/posts/Edit.vue | 52 ++++++++++++++++++------------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/resources/js/pages/posts/Edit.vue b/resources/js/pages/posts/Edit.vue index c83c6089..8c7a7167 100644 --- a/resources/js/pages/posts/Edit.vue +++ b/resources/js/pages/posts/Edit.vue @@ -223,6 +223,18 @@ 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; + continue; + } + const reason = getMediaIncompatibilityReason(contentType, media.value); if (reason) issues[pp.id] = reason; } @@ -331,12 +343,30 @@ const togglePlatform = (platformId: string) => { if (isReadOnly.value) return; const index = selectedPlatformIds.value.indexOf(platformId); if (index === -1) { + adjustTikTokContentTypeForMedia(platformId); 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 @@ -392,28 +422,6 @@ const triggerAutosave = () => { } }; -// Auto-switch TikTok content_type to match the attached media. Without this, -// a fresh post defaults TikTok to tiktok_video, so attaching images first -// disables the TikTok tile (compliance check rejects images for video posts). -// User can still override via the variant picker in TikTokSettings. -watch(media, () => { - if (media.value.length === 0) return; - - const first = media.value[0]; - const isVideo = first.type === 'video' || first.mime_type?.startsWith('video/'); - const isImage = first.type === 'image' || first.mime_type?.startsWith('image/'); - const target = isVideo ? 'tiktok_video' : isImage ? 'tiktok_photo' : null; - if (!target) return; - - for (const pp of post.value.post_platforms) { - if (pp.platform !== Platform.TikTok) continue; - const current = platformContentTypes.value[pp.id]; - if (current && current !== target && (current === 'tiktok_video' || current === 'tiktok_photo')) { - platformContentTypes.value = { ...platformContentTypes.value, [pp.id]: target }; - } - } -}, { deep: true }); - watch([content, media, selectedPlatformIds, scheduledDateTime, selectedLabelIds, platformMeta, platformContentTypes], triggerAutosave, { deep: true }); onUnmounted(() => {