Files
Homarr/packages/widgets/src/video/component.tsx
Meier Lukas 2f1c800844 feat: add everyone group (#1322)
* feat: add everyone group through seed

* feat: add reserved group name check in group router actions

* feat: improve user interface for everyone group

* fix: reserved group alert is a server component

* feat: add all users to everyone group

* chore: update lockfile

* fix: format issues

* fix: lint issues

* fix: lint format issues

* test: add unit tests for everyone group

* refactor: add codegen for documentation urls by sitemap

* refactor: change group query to count

* chore: remove migrations temporarily

* chore: add migrations again

* chore: add lint rule to prevent usage of raw documentation links

* fix: format issues
2024-10-21 17:23:51 +02:00

87 lines
2.3 KiB
TypeScript

"use client";
import { useEffect, useRef } from "react";
import { Anchor, Center, Group, Stack, Title } from "@mantine/core";
import { IconBrandYoutube, IconDeviceCctvOff } from "@tabler/icons-react";
import combineClasses from "clsx";
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 { createDocumentationLink } from "@homarr/definitions";
export default function VideoWidget({ options }: WidgetComponentProps<"video">) {
if (options.feedUrl.trim() === "") {
return <NoUrl />;
}
if (options.feedUrl.trim().startsWith("https://www.youtube.com/watch")) {
return <ForYoutubeUseIframe />;
}
return <Feed options={options} />;
}
const NoUrl = () => {
const t = useI18n();
return (
<Center h="100%">
<Stack align="center">
<IconDeviceCctvOff />
<Title order={4}>{t("widget.video.error.noUrl")}</Title>
</Stack>
</Center>
);
};
const ForYoutubeUseIframe = () => {
const t = useI18n();
return (
<Center h="100%">
<Stack align="center" gap="xs">
<IconBrandYoutube />
<Title order={4}>{t("widget.video.error.forYoutubeUseIframe")}</Title>
<Anchor href={createDocumentationLink("/docs/widgets/iframe")}>{t("common.action.checkoutDocs")}</Anchor>
</Stack>
</Center>
);
};
const Feed = ({ options }: Pick<WidgetComponentProps<"video">, "options">) => {
const videoRef = useRef<HTMLVideoElement>(null);
useEffect(() => {
if (!videoRef.current) {
return;
}
// Initialize Video.js player if it's not already initialized
if (!("player" in videoRef.current)) {
videojs(
videoRef.current,
{
autoplay: options.hasAutoPlay,
muted: options.isMuted,
controls: options.hasControls,
},
() => undefined,
);
}
}, [options.hasAutoPlay, options.hasControls, options.isMuted, videoRef]);
return (
<Group justify="center" w="100%" h="100%" pos="relative">
<video className={combineClasses("video-js", classes.video)} ref={videoRef}>
<source src={options.feedUrl} />
</video>
</Group>
);
};