"use client"; import { useEffect, useRef } from "react"; import { Anchor, Box, Center, Group, Stack, Title } from "@mantine/core"; import { IconBrandYoutube, IconDeviceCctvOff } from "@tabler/icons-react"; import videojs from "video.js"; import { useI18n } from "@homarr/translation/client"; import type { WidgetComponentProps } from "../definition"; import classes from "./component.module.css"; import "video.js/dist/video-js.css"; import type Player from "video.js/dist/types/player"; import { createDocumentationLink } from "@homarr/definitions"; export default function VideoWidget({ options }: WidgetComponentProps<"video">) { if (options.feedUrl.trim() === "") { return ; } if (options.feedUrl.trim().startsWith("https://www.youtube.com/watch")) { return ; } return ; } const NoUrl = () => { const t = useI18n(); return (
{t("widget.video.error.noUrl")}
); }; const ForYoutubeUseIframe = () => { const t = useI18n(); return (
{t("widget.video.error.forYoutubeUseIframe")} {t("common.action.checkoutDocs")}
); }; const Feed = ({ options }: Pick, "options">) => { const videoRef = useRef(null); const playerRef = useRef(null); useEffect(() => { if (playerRef.current) return; const videoElement = document.createElement("video-js"); videoElement.classList.add("vjs-big-play-centered"); if (classes.video) { videoElement.classList.add(classes.video); } videoRef.current?.appendChild(videoElement); playerRef.current = videojs(videoElement, { autoplay: options.hasAutoPlay, muted: options.isMuted, controls: options.hasControls, sources: [ { src: options.feedUrl, }, ], }); // All other properties are updated with other useEffect // eslint-disable-next-line react-hooks/exhaustive-deps }, [videoRef]); useEffect(() => { if (!playerRef.current) return; playerRef.current.src(options.feedUrl); }, [options.feedUrl]); useEffect(() => { if (!playerRef.current) return; playerRef.current.autoplay(options.hasAutoPlay); }, [options.hasAutoPlay]); useEffect(() => { if (!playerRef.current) return; playerRef.current.muted(options.isMuted); }, [options.isMuted]); useEffect(() => { if (!playerRef.current) return; playerRef.current.controls(options.hasControls); }, [options.hasControls]); useEffect(() => { const player = playerRef.current; return () => { if (player && !player.isDisposed()) { player.dispose(); playerRef.current = null; } }; }, [playerRef]); return ( ); };