From 53540911ccf926774817a8aa5adec2c23bb6417a Mon Sep 17 00:00:00 2001 From: robbond Date: Wed, 4 Feb 2026 11:22:11 +0000 Subject: [PATCH] 21254 youtube media player --- components/case/media.js | 646 +++++++++++++++++++++++++ middleware.js | 12 +- pages/case/[ticketnumber].js | 24 +- styles/sass/welshgov/_application.scss | 104 ++++ 4 files changed, 774 insertions(+), 12 deletions(-) create mode 100644 components/case/media.js diff --git a/components/case/media.js b/components/case/media.js new file mode 100644 index 00000000..558f919e --- /dev/null +++ b/components/case/media.js @@ -0,0 +1,646 @@ +// // import { setEventDetails } from "../../store/searchOutput/action"; +// // import { setCurrentPage } from "../../store/currentView/action"; +// // import { connect } from "react-redux"; +// // import useTranslation from "next-translate/useTranslation"; +// // import { formatDates } from "../utils"; + +// // const MediaDetails = (props) => { +// // let { t } = useTranslation(); + +// // const MediaView = (mediaArr) => { +// // mediaArr = mediaArr.value; + +// // return mediaArr.map((item, key) => { +// //
{item.pinswg_name}
; +// // }); +// // }; + +// // const mediaArr = props.mediaObj?.value || []; + +// // // event publishiing flag set to true displa + +// // function hasOwnPropertyAndNotNull(obj, property) { +// // return obj.hasOwnProperty(property) && obj[property] !== null; +// // } + +// // //console.log(eventsArr.length > 0); + +// // return ( +// // mediaArr.length > 0 && ( +// //
+// //
+// //
+// //

+// // {t("case:event-title")}Media +// //

+// // {mediaArr.map( +// // (item, key) => +// // item.pinswg_publishtoweb && ( +// // <> +// // {" "} +// //
+// //
+// //
+// // +// // {" "} +// // {t( +// // "case:event-name-label", +// // )} +// // +// // : {item.pinswg_name} +// //
+// // {hasOwnPropertyAndNotNull( +// // item, +// // "pinswg_description", +// // ) && ( +// //
+// // +// // {t( +// // "case:event-event-name-label", +// // )} +// // +// // :{" "} +// // { +// // item.pinswg_description +// // } +// //
+// // )} +// //
+// //
+// // +// // ), +// // )}{" "} +// //
+// //
+// //
+// // ) +// // ); +// // }; + +// // const mapStateToProps = (state) => { +// // return { +// // ...state, +// // }; +// // }; + +// // const mapDispatchToProps = (dispatch) => { +// // return { +// // setEventDetails: (mediaObj) => { +// // dispatch(setEventDetails(mediaObj)); +// // }, +// // setCurrentPage: (currentPage) => { +// // dispatch(setCurrentPage(currentPage)); +// // }, +// // }; +// // }; + +// // export default connect(mapStateToProps, mapDispatchToProps)(MediaDetails); +// import { useEffect, useMemo, useState } from "react"; +// import { connect } from "react-redux"; +// import useTranslation from "next-translate/useTranslation"; +// import { useRouter } from "next/router"; + +// const extractYouTubeId = (input) => { +// if (!input) return null; +// if (/^[a-zA-Z0-9_-]{11}$/.test(input)) return input; + +// try { +// const url = new URL(input); +// if (url.hostname.includes("youtu.be")) +// return url.pathname.slice(1) || null; + +// const v = url.searchParams.get("v"); +// if (v) return v; + +// const embedMatch = url.pathname.match(/\/embed\/([^/]+)/); +// if (embedMatch?.[1]) return embedMatch[1]; + +// const shortsMatch = url.pathname.match(/\/shorts\/([^/]+)/); +// if (shortsMatch?.[1]) return shortsMatch[1]; + +// return null; +// } catch { +// return null; +// } +// }; + +// export default function MediaDetails({ mediaObj, whichTab }) { +// const router = useRouter(); +// const mediaArr = mediaObj?.value || []; + +// const videoItems = useMemo(() => { +// const isWelsh = router.locale === "cy"; + +// return (mediaArr || []) +// .filter((x) => x?.pinswg_publishtoweb) +// .map((item) => { +// const url = isWelsh +// ? item.pinswg_mediaLinkCY +// : item.pinswg_mediaLinkEN; +// const videoId = extractYouTubeId(url); +// if (!videoId) return null; + +// return { +// key: +// item.pinswg_documentid || +// `${item.pinswg_name}-${videoId}`, +// videoId, +// name: item.pinswg_name || "Video", +// description: item.pinswg_description || "", +// thumbnail: `https://img.youtube.com/vi/${videoId}/hqdefault.jpg`, +// }; +// }) +// .filter(Boolean); +// }, [mediaArr, router.locale]); + +// const [watchedIds, setWatchedIds] = useState(new Set()); +// const [selectedIndex, setSelectedIndex] = useState(0); + +// // Forces a fresh iframe instance whenever we need to hard-stop playback +// const [playerInstance, setPlayerInstance] = useState(0); + +// const isActive = whichTab === "case-media"; +// const selected = videoItems[selectedIndex] || null; + +// // When leaving the media tab, hard-stop playback by unmounting (and bumping instance) +// useEffect(() => { +// if (!isActive) { +// setPlayerInstance((n) => n + 1); +// } +// }, [isActive]); + +// // When list/locale changes, reset to first (no autoplay) +// useEffect(() => { +// setSelectedIndex(0); +// setPlayerInstance((n) => n + 1); +// }, [videoItems.length, router.locale]); + +// if (!videoItems.length) return null; + +// const embedBase = "https://www.youtube-nocookie.com/embed"; + +// // IMPORTANT: +// // - autoplay=0 for initial load +// // - autoplay=1 only when user clicks an item +// const [autoplay, setAutoplay] = useState(false); + +// useEffect(() => { +// // whenever we leave tab or reset player, don't autoplay next time +// if (!isActive) setAutoplay(false); +// }, [isActive]); + +// const embedSrc = selected +// ? `${embedBase}/${selected.videoId}?rel=0&modestbranding=1&playsinline=1&autoplay=${autoplay ? "1" : "0"}` +// : ""; + +// return ( +//
+//
+//
+//

Media

+ +// {/* Player: only render when tab is active */} +// {isActive && ( +//
+//