chromecast button styling

Co-authored-by: Jip Frijlink <JipFr@users.noreply.github.com>
Co-authored-by: James Hawkins <jhawki2005@gmail.com>
Co-authored-by: William Oldham <wegg7250@gmail.com>
This commit is contained in:
mrjvs 2023-02-19 21:00:22 +01:00
parent 0c57aa1a73
commit d6d318006b
3 changed files with 60 additions and 9 deletions

View File

@ -50,7 +50,6 @@ body[data-no-select] {
overflow: hidden;
}
google-cast-launcher {
@apply pointer-events-auto m-2 text-white flex items-center justify-center p-2;
@apply transition-[background-color,transform] duration-100 rounded-full bg-denim-600 bg-opacity-0 hover:bg-opacity-50 active:bg-denim-500 active:bg-opacity-100 active:scale-110;
.google-cast-button:not(.casting) google-cast-launcher {
@apply brightness-[500];
}

View File

@ -1,12 +1,60 @@
import { Icons } from "@/components/Icon";
import { VideoPlayerIconButton } from "@/video/components/parts/VideoPlayerIconButton";
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
import { useMisc } from "@/video/state/logic/misc";
import { useCallback, useEffect, useRef, useState } from "react";
interface Props {
className?: string;
}
export function ChromecastAction(props: Props) {
const [hidden, setHidden] = useState(false);
const descriptor = useVideoPlayerDescriptor();
const misc = useMisc(descriptor);
const isCasting = misc.isCasting;
const ref = useRef<HTMLDivElement>(null);
const setButtonVisibility = useCallback(
(tag: HTMLElement) => {
const isVisible = (tag.getAttribute("style") ?? "").includes("inline");
setHidden(!isVisible);
},
[setHidden]
);
useEffect(() => {
const tag = ref.current?.querySelector<HTMLElement>("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 (
<VideoPlayerIconButton className={props.className} icon={Icons.CASTING} />
<VideoPlayerIconButton
ref={ref}
className={[
props.className ?? "",
"google-cast-button",
isCasting ? "casting" : "",
hidden ? "hidden" : "",
].join(" ")}
icon={Icons.CASTING}
onClick={(e) => {
const castButton = e.currentTarget.querySelector(
"google-cast-launcher"
);
if (castButton) (castButton as HTMLDivElement).click();
}}
/>
);
}

View File

@ -1,5 +1,5 @@
import { Icon, Icons } from "@/components/Icon";
import React from "react";
import React, { forwardRef } from "react";
export interface VideoPlayerIconButtonProps {
onClick?: (e: React.MouseEvent<HTMLButtonElement>) => void;
@ -9,11 +9,15 @@ export interface VideoPlayerIconButtonProps {
iconSize?: string;
active?: boolean;
wide?: boolean;
noPadding?: boolean;
}
export function VideoPlayerIconButton(props: VideoPlayerIconButtonProps) {
export const VideoPlayerIconButton = forwardRef<
HTMLDivElement,
VideoPlayerIconButtonProps
>((props, ref) => {
return (
<div className={props.className}>
<div className={props.className} ref={ref}>
<button
type="button"
onClick={props.onClick}
@ -23,7 +27,7 @@ export function VideoPlayerIconButton(props: VideoPlayerIconButtonProps) {
className={[
"flex items-center justify-center rounded-full bg-denim-600 bg-opacity-0 transition-colors duration-100 group-hover:bg-opacity-50 group-active:bg-denim-500 group-active:bg-opacity-100",
props.active ? "!bg-denim-500 !bg-opacity-100" : "",
props.wide ? "py-2 px-4" : "p-2",
!props.noPadding ? (props.wide ? "py-2 px-4" : "p-2") : "",
].join(" ")}
>
<Icon icon={props.icon} className={props.iconSize ?? "text-2xl"} />
@ -32,4 +36,4 @@ export function VideoPlayerIconButton(props: VideoPlayerIconButtonProps) {
</button>
</div>
);
}
});