mirror of
https://github.com/movie-web/movie-web.git
synced 2024-11-14 10:05:05 +01:00
Add chromecasting UI
This commit is contained in:
parent
fac61d26da
commit
436a75d3f2
@ -94,6 +94,9 @@
|
|||||||
"failure": "Error occurred"
|
"failure": "Error occurred"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"casting": {
|
||||||
|
"enabled": "Casting to device..."
|
||||||
|
},
|
||||||
"playbackError": {
|
"playbackError": {
|
||||||
"badge": "Playback error",
|
"badge": "Playback error",
|
||||||
"title": "Failed to play video!",
|
"title": "Failed to play video!",
|
||||||
|
22
src/components/player/atoms/CastingNotification.tsx
Normal file
22
src/components/player/atoms/CastingNotification.tsx
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
import { Icon, Icons } from "@/components/Icon";
|
||||||
|
import { usePlayerStore } from "@/stores/player/store";
|
||||||
|
|
||||||
|
export function CastingNotification() {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const isLoading = usePlayerStore((s) => s.mediaPlaying.isLoading);
|
||||||
|
const display = usePlayerStore((s) => s.display);
|
||||||
|
const isCasting = display?.getType() === "casting";
|
||||||
|
|
||||||
|
if (isLoading || !isCasting) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col items-center justify-center gap-4">
|
||||||
|
<div className="rounded-full bg-opacity-10 bg-video-buttonBackground p-3 brightness-100 grayscale">
|
||||||
|
<Icon icon={Icons.CASTING} />
|
||||||
|
</div>
|
||||||
|
<p className="text-center">{t("player.casting.enabled")}</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -15,3 +15,4 @@ export * from "./Airplay";
|
|||||||
export * from "./VolumeChangedPopout";
|
export * from "./VolumeChangedPopout";
|
||||||
export * from "./NextEpisodeButton";
|
export * from "./NextEpisodeButton";
|
||||||
export * from "./Chromecast";
|
export * from "./Chromecast";
|
||||||
|
export * from "./CastingNotification";
|
||||||
|
@ -107,8 +107,10 @@ export function SubtitleRenderer() {
|
|||||||
export function SubtitleView(props: { controlsShown: boolean }) {
|
export function SubtitleView(props: { controlsShown: boolean }) {
|
||||||
const caption = usePlayerStore((s) => s.caption.selected);
|
const caption = usePlayerStore((s) => s.caption.selected);
|
||||||
const captionAsTrack = usePlayerStore((s) => s.caption.asTrack);
|
const captionAsTrack = usePlayerStore((s) => s.caption.asTrack);
|
||||||
|
const display = usePlayerStore((s) => s.display);
|
||||||
|
const isCasting = display?.getType() === "casting";
|
||||||
|
|
||||||
if (captionAsTrack || !caption) return null;
|
if (captionAsTrack || !caption || isCasting) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Transition
|
<Transition
|
||||||
|
@ -253,6 +253,9 @@ export function makeVideoElementDisplayInterface(): DisplayInterface {
|
|||||||
return {
|
return {
|
||||||
on,
|
on,
|
||||||
off,
|
off,
|
||||||
|
getType() {
|
||||||
|
return "web";
|
||||||
|
},
|
||||||
destroy: () => {
|
destroy: () => {
|
||||||
destroyVideoElement();
|
destroyVideoElement();
|
||||||
fscreen.removeEventListener("fullscreenchange", fullscreenChange);
|
fscreen.removeEventListener("fullscreenchange", fullscreenChange);
|
||||||
|
@ -158,6 +158,9 @@ export function makeChromecastDisplayInterface(
|
|||||||
return {
|
return {
|
||||||
on,
|
on,
|
||||||
off,
|
off,
|
||||||
|
getType() {
|
||||||
|
return "casting";
|
||||||
|
},
|
||||||
destroy: () => {
|
destroy: () => {
|
||||||
stopListening();
|
stopListening();
|
||||||
destroyVideoElement();
|
destroyVideoElement();
|
||||||
|
@ -46,6 +46,8 @@ export interface DisplayCaption {
|
|||||||
url?: string;
|
url?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type DisplayType = "web" | "casting";
|
||||||
|
|
||||||
export interface DisplayInterface extends Listener<DisplayInterfaceEvents> {
|
export interface DisplayInterface extends Listener<DisplayInterfaceEvents> {
|
||||||
play(): void;
|
play(): void;
|
||||||
pause(): void;
|
pause(): void;
|
||||||
@ -66,4 +68,5 @@ export interface DisplayInterface extends Listener<DisplayInterfaceEvents> {
|
|||||||
setPlaybackRate(rate: number): void;
|
setPlaybackRate(rate: number): void;
|
||||||
setMeta(meta: DisplayMeta): void;
|
setMeta(meta: DisplayMeta): void;
|
||||||
setCaption(caption: DisplayCaption | null): void;
|
setCaption(caption: DisplayCaption | null): void;
|
||||||
|
getType(): DisplayType;
|
||||||
}
|
}
|
||||||
|
@ -31,10 +31,15 @@ export function PlayerPart(props: PlayerPartProps) {
|
|||||||
<Player.SubtitleView controlsShown={showTargets} />
|
<Player.SubtitleView controlsShown={showTargets} />
|
||||||
|
|
||||||
{status === playerStatus.PLAYING ? (
|
{status === playerStatus.PLAYING ? (
|
||||||
|
<>
|
||||||
<Player.CenterControls>
|
<Player.CenterControls>
|
||||||
<Player.LoadingSpinner />
|
<Player.LoadingSpinner />
|
||||||
<Player.AutoPlayStart />
|
<Player.AutoPlayStart />
|
||||||
</Player.CenterControls>
|
</Player.CenterControls>
|
||||||
|
<Player.CenterControls>
|
||||||
|
<Player.CastingNotification />
|
||||||
|
</Player.CenterControls>
|
||||||
|
</>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<Player.CenterMobileControls
|
<Player.CenterMobileControls
|
||||||
|
Loading…
Reference in New Issue
Block a user