From 43d4869f7e0e103f865bb4ce1de83f1bf5bacf05 Mon Sep 17 00:00:00 2001 From: mrjvs Date: Fri, 20 Oct 2023 22:39:56 +0200 Subject: [PATCH] chromecasting connectivity --- src/components/player/atoms/Chromecast.tsx | 56 +++++++++++++++++++ src/components/player/atoms/index.ts | 1 + src/components/player/base/Container.tsx | 2 + src/components/player/internals/Button.tsx | 17 ++++-- .../player/internals/CastingInternal.tsx | 47 ++++++++++++++++ src/pages/parts/player/PlayerPart.tsx | 3 + src/stores/player/slices/casting.ts | 47 ++++++++++++++++ src/stores/player/slices/interface.ts | 2 + src/stores/player/slices/types.ts | 4 +- src/stores/player/store.ts | 2 + 10 files changed, 175 insertions(+), 6 deletions(-) create mode 100644 src/components/player/atoms/Chromecast.tsx create mode 100644 src/components/player/internals/CastingInternal.tsx create mode 100644 src/stores/player/slices/casting.ts diff --git a/src/components/player/atoms/Chromecast.tsx b/src/components/player/atoms/Chromecast.tsx new file mode 100644 index 00000000..f096eea3 --- /dev/null +++ b/src/components/player/atoms/Chromecast.tsx @@ -0,0 +1,56 @@ +import { useCallback, useEffect, useRef, useState } from "react"; + +import { Icons } from "@/components/Icon"; +import { VideoPlayerButton } from "@/components/player/internals/Button"; +import { usePlayerStore } from "@/stores/player/store"; + +export interface ChromecastProps { + className?: string; +} + +export function Chromecast(props: ChromecastProps) { + const [hidden, setHidden] = useState(false); + const isCasting = usePlayerStore((s) => s.interface.isCasting); + const ref = useRef(null); + + const setButtonVisibility = useCallback( + (tag: HTMLElement) => { + const isVisible = (tag.getAttribute("style") ?? "").includes("inline"); + setHidden(!isVisible); + }, + [setHidden] + ); + + useEffect(() => { + const tag = ref.current?.querySelector("google-cast-launcher"); + if (!tag) return; + + const observer = new MutationObserver(() => { + setButtonVisibility(tag); + }); + + observer.observe(tag, { attributes: true, attributeFilter: ["style"] }); + setButtonVisibility(tag); + + return () => { + observer.disconnect(); + }; + }, [setButtonVisibility]); + + return ( +