import { useEffect, useMemo, useState } from "react"; import useTranslation from "next-translate/useTranslation"; import { useRouter } from "next/router"; import { getBilingualText } from "./summary/utils/helpers"; /** * MediaDetails * - Renders a YouTube player + a list of videos from mediaObj.value * - Loads first item by default (no autoplay) * - Plays only when user selects an item * - Stops playback when leaving the "case-media" parent tab (pass whichTab) * - Shows thumbnail with play overlay * - Optional duration badge (if you supply v.duration) * - "Watched" badge once a video has been played (session only) */ const extractYouTubeId = (input) => { if (!input) return null; // Already looks like a YouTube ID? if (/^[a-zA-Z0-9_-]{11}$/.test(input)) return input; try { const url = new URL(input); // youtu.be/ if (url.hostname.includes("youtu.be")) { return url.pathname.replace("/", "") || null; } // youtube.com/watch?v= const v = url.searchParams.get("v"); if (v) return v; // youtube.com/embed/ const embedMatch = url.pathname.match(/\/embed\/([^/]+)/); if (embedMatch?.[1]) return embedMatch[1]; // youtube.com/shorts/ const shortsMatch = url.pathname.match(/\/shorts\/([^/]+)/); if (shortsMatch?.[1]) return shortsMatch[1]; return null; } catch { return null; } }; const MediaDetails = ({ mediaObj, whichTab, title, useNoCookie = true }) => { const { t } = useTranslation(); const router = useRouter(); const sourceMedia = mediaObj?.value; const isActive = whichTab ? whichTab === "case-media" : true; // Build list of playable items (publishable only) const videoItems = useMemo(() => { const isWelsh = router.locale === "cy"; return (sourceMedia || []) .filter((x) => x?.pinswg_publishtoweb) .map((item) => { const link = isWelsh ? item.pinswg_videoplatformurlwelsh : item.pinswg_videoplatformurl; const videoId = extractYouTubeId(link); if (!videoId) return null; return { key: item.pinswg_documentid || item.pinswg_mediaid || `${item.pinswg_eventrecordingid}-${videoId}`, videoId, name: item.pinswg_eventrecordingname || "Video", description: item.pinswg_description || "", // If you later store duration in CRM, map it here (e.g. "03:42") duration: item.pinswg_duration || null, thumbnailHQ: `https://img.youtube.com/vi/${videoId}/hqdefault.jpg`, thumbnailMax: `https://img.youtube.com/vi/${videoId}/maxresdefault.jpg`, raw: item }; }) .filter(Boolean); }, [sourceMedia, router.locale]); const [selectedIndex, setSelectedIndex] = useState(0); // Default false so first item loads but does not play. const [autoplay, setAutoplay] = useState(false); // Bump this to force iframe remount (hard stop playback). const [playerInstance, setPlayerInstance] = useState(0); // Track which videos have been played (session only). const [watchedIds, setWatchedIds] = useState(() => new Set()); // When list or locale changes: reset selection and do not autoplay useEffect(() => { setSelectedIndex(0); setAutoplay(false); setPlayerInstance((n) => n + 1); }, [videoItems.length, router.locale]); // When leaving the media tab: hard stop playback useEffect(() => { if (!isActive) { setAutoplay(false); setPlayerInstance((n) => n + 1); } }, [isActive]); const selected = videoItems[selectedIndex] || null; const domain = useNoCookie ? "https://www.youtube-nocookie.com" : "https://www.youtube.com"; const embedSrc = selected ? `${domain}/embed/${selected.videoId}?rel=0&modestbranding=1&playsinline=1&autoplay=${ autoplay ? "1" : "0" }` : ""; if (!videoItems.length) return null; return (

{t("case:media-title")}

{/* Player: unmount when not active (guarantees playback stops) */} {isActive && (