bunch of chromecast fixes

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 22:22:01 +01:00
parent d6d318006b
commit b886443ea7
9 changed files with 61 additions and 34 deletions

View File

@ -12,7 +12,6 @@ interface Props {
animation: TransitionAnimations;
className?: string;
children?: ReactNode;
appearOnMount?: boolean;
isChild?: boolean;
}
@ -62,23 +61,14 @@ export function Transition(props: Props) {
if (props.isChild) {
return (
<HeadlessTransition.Child
as={Fragment}
appear={props.appearOnMount}
{...classes}
>
<HeadlessTransition.Child as={Fragment} {...classes}>
<div className={props.className}>{props.children}</div>
</HeadlessTransition.Child>
);
}
return (
<HeadlessTransition
show={props.show}
as={Fragment}
appear={props.appearOnMount}
{...classes}
>
<HeadlessTransition show={props.show} as={Fragment} {...classes}>
<div className={props.className}>{props.children}</div>
</HeadlessTransition>
);

View File

@ -13,13 +13,11 @@ export function ModalFrame(props: Props) {
<Transition
className="fixed inset-0 z-[9999]"
animation="none"
appearOnMount
show={props.show}
>
<Overlay>
<Transition
isChild
appearOnMount
className="flex h-full w-full items-center justify-center"
animation="slide-up"
>

View File

@ -79,9 +79,13 @@
}
},
"v3": {
"newSiteTitle": "Version 3 has released!",
"newSiteTitle": "New version now released!",
"newDomain": "https://movie-web.app",
"newDomainText": "We have a new domain. You can now access our website on <0>https://movie-web.app</0>. Make sure to update all your bookmarks as <1>the old link will stop working on {{date}}.</1>",
"tireless": "We've worked tirelessly on this new update, we hope you will enjoy what we've been cooking up for the past months."
"newDomainText": "movie-web will soon be moving to a new domain: <0>https://movie-web.app</0>. Make sure to update all your bookmarks as <1>the old website will stop working on {{date}}.</1>",
"tireless": "We've worked tirelessly on this new update, we hope you will enjoy what we've been cooking up for the past months.",
"leaveAnnouncement": "Take me there!"
},
"casting": {
"casting": "Casting to device..."
}
}

View File

@ -29,6 +29,7 @@ import { useControls } from "@/video/state/logic/controls";
import { ReactNode, useCallback, useState } from "react";
import { PopoutProviderAction } from "@/video/components/popouts/PopoutProviderAction";
import { ChromecastAction } from "@/video/components/actions/ChromecastAction";
import { CastingTextAction } from "@/video/components/actions/CastingTextAction";
type Props = VideoPlayerBaseProps;
@ -94,6 +95,9 @@ export function VideoPlayer(props: Props) {
<CenterPosition>
<LoadingAction />
</CenterPosition>
<CenterPosition>
<CastingTextAction />
</CenterPosition>
<CenterPosition>
<MiddlePauseAction />
</CenterPosition>

View File

@ -0,0 +1,22 @@
import { Icon, Icons } from "@/components/Icon";
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
import { useMisc } from "@/video/state/logic/misc";
import { useTranslation } from "react-i18next";
export function CastingTextAction() {
const { t } = useTranslation();
const descriptor = useVideoPlayerDescriptor();
const misc = useMisc(descriptor);
if (!misc.isCasting) return null;
return (
<div className="flex flex-col items-center justify-center gap-4">
<div className="rounded-full bg-denim-200 p-3 brightness-100 grayscale">
<Icon icon={Icons.CASTING} />
</div>
<p className="text-center text-gray-300">{t("casting.casting")}</p>
</div>
);
}

View File

@ -16,13 +16,17 @@ export function CastingInternal() {
useEffect(() => {
if (lastValue.current === isCasting) return;
if (!isCasting) return;
lastValue.current = isCasting;
if (!isCasting) return;
const provider = createCastingStateProvider(descriptor);
setProvider(descriptor, provider);
const { destroy } = provider.providerStart();
return () => {
unsetStateProvider(descriptor, provider.getId());
try {
unsetStateProvider(descriptor, provider.getId());
} catch {
// ignore errors from missing player state, we need to run destroy()!
}
destroy();
};
}, [descriptor, isCasting]);

View File

@ -27,7 +27,11 @@ function VideoElement(props: Props) {
setProvider(descriptor, provider);
const { destroy } = provider.providerStart();
return () => {
unsetStateProvider(descriptor, provider.getId());
try {
unsetStateProvider(descriptor, provider.getId());
} catch {
// ignore errors from missing player state, we need to run destroy()!
}
destroy();
};
}, [descriptor, initalized, stateProviderId]);

View File

@ -18,9 +18,7 @@ import { VideoPlayerStateProvider } from "./providerTypes";
import { updateProgress } from "../logic/progress";
// TODO startAt when switching state providers
// TODO cast -> uncast -> cast will break
// TODO chromecast button has incorrect hitbox and badly styled
// TODO casting text middle of screen
// TODO test HLS
export function createCastingStateProvider(
descriptor: string
): VideoPlayerStateProvider {
@ -112,8 +110,10 @@ export function createCastingStateProvider(
const movieMeta = new chrome.cast.media.MovieMediaMetadata();
movieMeta.title = state.meta?.meta.meta.title ?? "";
// TODO contentId?
const mediaInfo = new chrome.cast.media.MediaInfo("hello", "video/mp4");
const mediaInfo = new chrome.cast.media.MediaInfo(
state.meta?.meta.meta.id ?? "hello",
"video/mp4"
);
(mediaInfo as any).contentUrl = source?.source;
mediaInfo.streamType = chrome.cast.media.StreamType.BUFFERED;
mediaInfo.metadata = movieMeta;
@ -167,17 +167,16 @@ export function createCastingStateProvider(
updateProgress(descriptor, state);
break;
case "mediaInfo":
state.progress.duration = e.value.duration;
updateProgress(descriptor, state);
if (e.value) {
state.progress.duration = e.value.duration;
updateProgress(descriptor, state);
}
break;
case "playerState":
state.mediaPlaying.isLoading = e.value === "BUFFERING";
updateMediaPlaying(descriptor, state);
break;
case "isPaused":
state.mediaPlaying.isPaused = e.value;
state.mediaPlaying.isPlaying = !e.value;
if (!e.value) state.mediaPlaying.hasPlayedOnce = true;
state.mediaPlaying.isPaused = e.value !== "PLAYING";
state.mediaPlaying.isPlaying = e.value === "PLAYING";
if (e.value === "PLAYING") state.mediaPlaying.hasPlayedOnce = true;
updateMediaPlaying(descriptor, state);
break;
case "isMuted":
@ -188,6 +187,7 @@ export function createCastingStateProvider(
case "displayStatus":
case "canSeek":
case "title":
case "isPaused":
break;
default:
console.log(e.type, e.field, e.value);
@ -229,6 +229,7 @@ export function createCastingStateProvider(
state.wrapperElement?.removeEventListener("mouseenter", isFocused);
state.wrapperElement?.removeEventListener("mouseleave", isFocused);
fscreen.removeEventListener("fullscreenchange", fullscreenchange);
ins?.endCurrentSession(true);
},
};
},

View File

@ -161,7 +161,7 @@ function NewDomainModal() {
</div>
<div className="mt-16 mb-6 flex items-center justify-center">
<Button icon={Icons.PLAY} onClick={() => setShow(false)}>
Take me to the app
{t("v3.leaveAnnouncement")}
</Button>
</div>
</ModalCard>