mirror of
https://github.com/movie-web/movie-web.git
synced 2024-12-27 07:51:53 +01:00
volume storage fixed, title cleanup, settings cog start, touch controls start
Co-authored-by: Jip Frijlink <JipFr@users.noreply.github.com>
This commit is contained in:
parent
7b3452c535
commit
f3084d37a8
@ -1,10 +1,20 @@
|
|||||||
|
import classNames from "classnames";
|
||||||
import { ReactNode } from "react";
|
import { ReactNode } from "react";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
id: string;
|
id: string;
|
||||||
children?: ReactNode;
|
children?: ReactNode;
|
||||||
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function OverlayAnchor(props: Props) {
|
export function OverlayAnchor(props: Props) {
|
||||||
return <div id={`__overlayRouter::${props.id}`}>{props.children}</div>;
|
return (
|
||||||
|
<div className={classNames("relative", props.className)}>
|
||||||
|
<div
|
||||||
|
id={`__overlayRouter::${props.id}`}
|
||||||
|
className="absolute inset-0 -z-10"
|
||||||
|
/>
|
||||||
|
{props.children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,67 @@
|
|||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import { ReactNode } from "react";
|
import { ReactNode, useCallback, useEffect, useRef, useState } from "react";
|
||||||
|
|
||||||
|
import { useOverlayStore } from "@/stores/overlay/store";
|
||||||
|
|
||||||
interface AnchorPositionProps {
|
interface AnchorPositionProps {
|
||||||
children?: ReactNode;
|
children?: ReactNode;
|
||||||
className?: string;
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function useCalculatePositions() {
|
||||||
|
const anchorPoint = useOverlayStore((s) => s.anchorPoint);
|
||||||
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
|
const [left, setLeft] = useState<number>(0);
|
||||||
|
const [top, setTop] = useState<number>(0);
|
||||||
|
const [cardRect, setCardRect] = useState<DOMRect | null>(null);
|
||||||
|
|
||||||
|
const calculateAndSetCoords = useCallback(
|
||||||
|
(anchor: typeof anchorPoint, card: DOMRect) => {
|
||||||
|
if (!anchor) return;
|
||||||
|
const buttonCenter = anchor.x + anchor.w / 2;
|
||||||
|
const bottomReal = window.innerHeight - (anchor.y + anchor.h);
|
||||||
|
|
||||||
|
setTop(window.innerHeight - bottomReal - anchor.h - card.height - 30);
|
||||||
|
setLeft(
|
||||||
|
Math.min(
|
||||||
|
buttonCenter - card.width / 2,
|
||||||
|
window.innerWidth - card.width - 30
|
||||||
|
)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!anchorPoint || !cardRect) return;
|
||||||
|
calculateAndSetCoords(anchorPoint, cardRect);
|
||||||
|
}, [anchorPoint, calculateAndSetCoords, cardRect]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!ref.current) return;
|
||||||
|
function checkBox() {
|
||||||
|
const divRect = ref.current?.getBoundingClientRect();
|
||||||
|
setCardRect(divRect ?? null);
|
||||||
|
}
|
||||||
|
checkBox();
|
||||||
|
const observer = new ResizeObserver(checkBox);
|
||||||
|
observer.observe(ref.current);
|
||||||
|
return () => {
|
||||||
|
observer.disconnect();
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return [ref, left, top] as const;
|
||||||
|
}
|
||||||
|
|
||||||
export function OverlayAnchorPosition(props: AnchorPositionProps) {
|
export function OverlayAnchorPosition(props: AnchorPositionProps) {
|
||||||
|
const [ref, left, top] = useCalculatePositions();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
ref={ref}
|
||||||
style={{
|
style={{
|
||||||
transform: `translateX(0px) translateY(0px)`,
|
transform: `translateX(${left}px) translateY(${top}px)`,
|
||||||
}}
|
}}
|
||||||
className={classNames([
|
className={classNames([
|
||||||
"pointer-events-auto z-10 inline-block origin-top-left touch-none",
|
"pointer-events-auto z-10 inline-block origin-top-left touch-none",
|
||||||
|
@ -6,4 +6,5 @@ export * from "./base/BottomControls";
|
|||||||
export * from "./base/BlackOverlay";
|
export * from "./base/BlackOverlay";
|
||||||
export * from "./base/BackLink";
|
export * from "./base/BackLink";
|
||||||
export * from "./base/LeftSideControls";
|
export * from "./base/LeftSideControls";
|
||||||
|
export * from "./base/CenterMobileControls";
|
||||||
export * from "./internals/BookmarkButton";
|
export * from "./internals/BookmarkButton";
|
||||||
|
@ -2,7 +2,7 @@ import { Icons } from "@/components/Icon";
|
|||||||
import { VideoPlayerButton } from "@/components/player/internals/Button";
|
import { VideoPlayerButton } from "@/components/player/internals/Button";
|
||||||
import { usePlayerStore } from "@/stores/player/store";
|
import { usePlayerStore } from "@/stores/player/store";
|
||||||
|
|
||||||
export function Pause() {
|
export function Pause(props: { iconSizeClass?: string }) {
|
||||||
const display = usePlayerStore((s) => s.display);
|
const display = usePlayerStore((s) => s.display);
|
||||||
const { isPaused } = usePlayerStore((s) => s.mediaPlaying);
|
const { isPaused } = usePlayerStore((s) => s.mediaPlaying);
|
||||||
|
|
||||||
@ -13,6 +13,7 @@ export function Pause() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<VideoPlayerButton
|
<VideoPlayerButton
|
||||||
|
iconSizeClass={props.iconSizeClass}
|
||||||
onClick={toggle}
|
onClick={toggle}
|
||||||
icon={isPaused ? Icons.PLAY : Icons.PAUSE}
|
icon={isPaused ? Icons.PLAY : Icons.PAUSE}
|
||||||
/>
|
/>
|
||||||
|
38
src/components/player/atoms/Settings.tsx
Normal file
38
src/components/player/atoms/Settings.tsx
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import { useEffect } from "react";
|
||||||
|
|
||||||
|
import { Icons } from "@/components/Icon";
|
||||||
|
import { OverlayAnchor } from "@/components/overlays/OverlayAnchor";
|
||||||
|
import { Overlay } from "@/components/overlays/OverlayDisplay";
|
||||||
|
import { OverlayPage } from "@/components/overlays/OverlayPage";
|
||||||
|
import { OverlayRouter } from "@/components/overlays/OverlayRouter";
|
||||||
|
import { VideoPlayerButton } from "@/components/player/internals/Button";
|
||||||
|
import { useOverlayRouter } from "@/hooks/useOverlayRouter";
|
||||||
|
import { usePlayerStore } from "@/stores/player/store";
|
||||||
|
|
||||||
|
function SettingsOverlay({ id }: { id: string }) {
|
||||||
|
return (
|
||||||
|
<Overlay id={id}>
|
||||||
|
<OverlayRouter id={id}>
|
||||||
|
<OverlayPage id={id} path="/" width={400} height={400}>
|
||||||
|
<p>This is settings menu, welcome!</p>
|
||||||
|
</OverlayPage>
|
||||||
|
</OverlayRouter>
|
||||||
|
</Overlay>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Settings() {
|
||||||
|
const router = useOverlayRouter("settings");
|
||||||
|
const setHasOpenOverlay = usePlayerStore((s) => s.setHasOpenOverlay);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setHasOpenOverlay(router.isRouterActive);
|
||||||
|
}, [setHasOpenOverlay, router.isRouterActive]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<OverlayAnchor id={router.id}>
|
||||||
|
<VideoPlayerButton onClick={() => router.open()} icon={Icons.GEAR} />
|
||||||
|
<SettingsOverlay id={router.id} />
|
||||||
|
</OverlayAnchor>
|
||||||
|
);
|
||||||
|
}
|
@ -4,7 +4,7 @@ import { Icons } from "@/components/Icon";
|
|||||||
import { VideoPlayerButton } from "@/components/player/internals/Button";
|
import { VideoPlayerButton } from "@/components/player/internals/Button";
|
||||||
import { usePlayerStore } from "@/stores/player/store";
|
import { usePlayerStore } from "@/stores/player/store";
|
||||||
|
|
||||||
export function SkipForward() {
|
export function SkipForward(props: { iconSizeClass?: string }) {
|
||||||
const display = usePlayerStore((s) => s.display);
|
const display = usePlayerStore((s) => s.display);
|
||||||
const time = usePlayerStore((s) => s.progress.time);
|
const time = usePlayerStore((s) => s.progress.time);
|
||||||
|
|
||||||
@ -12,10 +12,16 @@ export function SkipForward() {
|
|||||||
display?.setTime(time + 10);
|
display?.setTime(time + 10);
|
||||||
}, [display, time]);
|
}, [display, time]);
|
||||||
|
|
||||||
return <VideoPlayerButton onClick={commit} icon={Icons.SKIP_FORWARD} />;
|
return (
|
||||||
|
<VideoPlayerButton
|
||||||
|
iconSizeClass={props.iconSizeClass || ""}
|
||||||
|
onClick={commit}
|
||||||
|
icon={Icons.SKIP_FORWARD}
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function SkipBackward() {
|
export function SkipBackward(props: { iconSizeClass?: string }) {
|
||||||
const display = usePlayerStore((s) => s.display);
|
const display = usePlayerStore((s) => s.display);
|
||||||
const time = usePlayerStore((s) => s.progress.time);
|
const time = usePlayerStore((s) => s.progress.time);
|
||||||
|
|
||||||
@ -23,5 +29,11 @@ export function SkipBackward() {
|
|||||||
display?.setTime(time - 10);
|
display?.setTime(time - 10);
|
||||||
}, [display, time]);
|
}, [display, time]);
|
||||||
|
|
||||||
return <VideoPlayerButton onClick={commit} icon={Icons.SKIP_BACKWARD} />;
|
return (
|
||||||
|
<VideoPlayerButton
|
||||||
|
iconSizeClass={props.iconSizeClass || ""}
|
||||||
|
onClick={commit}
|
||||||
|
icon={Icons.SKIP_BACKWARD}
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -2,5 +2,5 @@ import { usePlayerStore } from "@/stores/player/store";
|
|||||||
|
|
||||||
export function Title() {
|
export function Title() {
|
||||||
const title = usePlayerStore((s) => s.meta?.title);
|
const title = usePlayerStore((s) => s.meta?.title);
|
||||||
return <p>{title || "Beep beep, Richie!"}</p>;
|
return <p>{title}</p>;
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,6 @@ export function Volume(props: Props) {
|
|||||||
|
|
||||||
const commitVolume = useCallback(
|
const commitVolume = useCallback(
|
||||||
(percentage) => {
|
(percentage) => {
|
||||||
console.log("setting", percentage);
|
|
||||||
setVolume(percentage);
|
setVolume(percentage);
|
||||||
},
|
},
|
||||||
[setVolume]
|
[setVolume]
|
||||||
|
@ -8,3 +8,4 @@ export * from "./AutoPlayStart";
|
|||||||
export * from "./Volume";
|
export * from "./Volume";
|
||||||
export * from "./Title";
|
export * from "./Title";
|
||||||
export * from "./EpisodeTitle";
|
export * from "./EpisodeTitle";
|
||||||
|
export * from "./Settings";
|
||||||
|
26
src/components/player/base/CenterMobileControls.tsx
Normal file
26
src/components/player/base/CenterMobileControls.tsx
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import classNames from "classnames";
|
||||||
|
|
||||||
|
import { Transition } from "@/components/Transition";
|
||||||
|
|
||||||
|
export function CenterMobileControls(props: {
|
||||||
|
children: React.ReactNode;
|
||||||
|
show: boolean;
|
||||||
|
className?: string;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<Transition
|
||||||
|
animation="fade"
|
||||||
|
show={props.show}
|
||||||
|
className="pointer-events-none"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={classNames([
|
||||||
|
"absolute inset-0 flex space-x-6 items-center justify-center pointer-events-none [&>*]:pointer-events-auto",
|
||||||
|
props.className,
|
||||||
|
])}
|
||||||
|
>
|
||||||
|
{props.children}
|
||||||
|
</div>
|
||||||
|
</Transition>
|
||||||
|
);
|
||||||
|
}
|
@ -1,8 +1,12 @@
|
|||||||
|
import classNames from "classnames";
|
||||||
import { useCallback, useEffect } from "react";
|
import { useCallback, useEffect } from "react";
|
||||||
|
|
||||||
import { usePlayerStore } from "@/stores/player/store";
|
import { usePlayerStore } from "@/stores/player/store";
|
||||||
|
|
||||||
export function LeftSideControls(props: { children: React.ReactNode }) {
|
export function LeftSideControls(props: {
|
||||||
|
children: React.ReactNode;
|
||||||
|
className?: string;
|
||||||
|
}) {
|
||||||
const setHoveringLeftControls = usePlayerStore(
|
const setHoveringLeftControls = usePlayerStore(
|
||||||
(s) => s.setHoveringLeftControls
|
(s) => s.setHoveringLeftControls
|
||||||
);
|
);
|
||||||
@ -18,7 +22,10 @@ export function LeftSideControls(props: { children: React.ReactNode }) {
|
|||||||
}, [setHoveringLeftControls]);
|
}, [setHoveringLeftControls]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex space-x-3 items-center" onMouseLeave={mouseLeave}>
|
<div
|
||||||
|
className={classNames(["flex space-x-3 items-center", props.className])}
|
||||||
|
onMouseLeave={mouseLeave}
|
||||||
|
>
|
||||||
{props.children}
|
{props.children}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -1,9 +1,20 @@
|
|||||||
import { PlayerHoverState } from "@/stores/player/slices/interface";
|
import { PlayerHoverState } from "@/stores/player/slices/interface";
|
||||||
import { usePlayerStore } from "@/stores/player/store";
|
import { usePlayerStore } from "@/stores/player/store";
|
||||||
|
|
||||||
export function useShouldShowControls() {
|
export function useShouldShowControls(opts?: { touchOnly: boolean }) {
|
||||||
const { hovering } = usePlayerStore((s) => s.interface);
|
const hovering = usePlayerStore((s) => s.interface.hovering);
|
||||||
const { isPaused } = usePlayerStore((s) => s.mediaPlaying);
|
const lastHoveringState = usePlayerStore(
|
||||||
|
(s) => s.interface.lastHoveringState
|
||||||
|
);
|
||||||
|
const isPaused = usePlayerStore((s) => s.mediaPlaying.isPaused);
|
||||||
|
const hasOpenOverlay = usePlayerStore((s) => s.interface.hasOpenOverlay);
|
||||||
|
|
||||||
return hovering !== PlayerHoverState.NOT_HOVERING || isPaused;
|
const showTouchControls =
|
||||||
|
lastHoveringState === PlayerHoverState.MOBILE_TAPPED;
|
||||||
|
const notNotHovering = hovering !== PlayerHoverState.NOT_HOVERING;
|
||||||
|
|
||||||
|
if (opts?.touchOnly)
|
||||||
|
return (showTouchControls && notNotHovering) || isPaused || hasOpenOverlay;
|
||||||
|
|
||||||
|
return notNotHovering || isPaused || hasOpenOverlay;
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,26 @@
|
|||||||
import {
|
import { setStoredVolume } from "@/_oldvideo/components/hooks/volumeStore";
|
||||||
getStoredVolume,
|
|
||||||
setStoredVolume,
|
|
||||||
} from "@/_oldvideo/components/hooks/volumeStore";
|
|
||||||
import { usePlayerStore } from "@/stores/player/store";
|
import { usePlayerStore } from "@/stores/player/store";
|
||||||
|
|
||||||
// TODO use new stored volume
|
// TODO use new stored volume
|
||||||
|
|
||||||
export function useVolume() {
|
export function useVolume() {
|
||||||
const volume = usePlayerStore((s) => s.mediaPlaying.volume);
|
const volume = usePlayerStore((s) => s.mediaPlaying.volume);
|
||||||
|
const lastVolume = usePlayerStore((s) => s.interface.lastVolume);
|
||||||
|
const setLastVolume = usePlayerStore((s) => s.setLastVolume);
|
||||||
const display = usePlayerStore((s) => s.display);
|
const display = usePlayerStore((s) => s.display);
|
||||||
|
|
||||||
const toggleVolume = (_isKeyboardEvent = false) => {
|
const toggleVolume = (_isKeyboardEvent = false) => {
|
||||||
// TODO use keyboard event
|
// TODO use keyboard event
|
||||||
|
let newVolume = 0;
|
||||||
|
|
||||||
if (volume > 0) {
|
if (volume > 0) {
|
||||||
setStoredVolume(volume);
|
newVolume = 0;
|
||||||
display?.setVolume(0);
|
setLastVolume(volume);
|
||||||
} else {
|
} else if (lastVolume > 0) newVolume = lastVolume;
|
||||||
const storedVolume = getStoredVolume();
|
else newVolume = 1;
|
||||||
if (storedVolume > 0) display?.setVolume(storedVolume);
|
|
||||||
else display?.setVolume(1);
|
display?.setVolume(newVolume);
|
||||||
}
|
setStoredVolume(newVolume);
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -28,6 +29,7 @@ export function useVolume() {
|
|||||||
},
|
},
|
||||||
setVolume(vol: number) {
|
setVolume(vol: number) {
|
||||||
setStoredVolume(vol);
|
setStoredVolume(vol);
|
||||||
|
setLastVolume(vol);
|
||||||
display?.setVolume(vol);
|
display?.setVolume(vol);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -94,6 +94,7 @@ export function useOverlayRouter(id: string) {
|
|||||||
const router = useInternalOverlayRouter(id);
|
const router = useInternalOverlayRouter(id);
|
||||||
return {
|
return {
|
||||||
id,
|
id,
|
||||||
|
isRouterActive: router.isOverlayActive(),
|
||||||
open: router.open,
|
open: router.open,
|
||||||
close: router.close,
|
close: router.close,
|
||||||
navigate: router.navigate,
|
navigate: router.navigate,
|
||||||
|
@ -7,15 +7,21 @@ import { AutoPlayStart } from "@/components/player/atoms";
|
|||||||
import { usePlayer } from "@/components/player/hooks/usePlayer";
|
import { usePlayer } from "@/components/player/hooks/usePlayer";
|
||||||
import { useShouldShowControls } from "@/components/player/hooks/useShouldShowControls";
|
import { useShouldShowControls } from "@/components/player/hooks/useShouldShowControls";
|
||||||
import { ScrapingPart } from "@/pages/parts/player/ScrapingPart";
|
import { ScrapingPart } from "@/pages/parts/player/ScrapingPart";
|
||||||
|
import { PlayerHoverState } from "@/stores/player/slices/interface";
|
||||||
import {
|
import {
|
||||||
PlayerMeta,
|
PlayerMeta,
|
||||||
metaToScrapeMedia,
|
metaToScrapeMedia,
|
||||||
playerStatus,
|
playerStatus,
|
||||||
} from "@/stores/player/slices/source";
|
} from "@/stores/player/slices/source";
|
||||||
|
import { usePlayerStore } from "@/stores/player/store";
|
||||||
|
|
||||||
export function PlayerView() {
|
export function PlayerView() {
|
||||||
const { status, setScrapeStatus, playMedia, setMeta } = usePlayer();
|
const { status, setScrapeStatus, playMedia, setMeta } = usePlayer();
|
||||||
|
const { lastHoveringState } = usePlayerStore((s) => s.interface);
|
||||||
|
|
||||||
const desktopControlsVisible = useShouldShowControls();
|
const desktopControlsVisible = useShouldShowControls();
|
||||||
|
const touchControlsVisible = useShouldShowControls({ touchOnly: true });
|
||||||
|
|
||||||
const meta = useMemo<PlayerMeta>(
|
const meta = useMemo<PlayerMeta>(
|
||||||
() => ({
|
() => ({
|
||||||
type: "show",
|
type: "show",
|
||||||
@ -71,6 +77,15 @@ export function PlayerView() {
|
|||||||
<AutoPlayStart />
|
<AutoPlayStart />
|
||||||
</Player.CenterControls>
|
</Player.CenterControls>
|
||||||
|
|
||||||
|
<Player.CenterMobileControls
|
||||||
|
className="text-white"
|
||||||
|
show={touchControlsVisible}
|
||||||
|
>
|
||||||
|
<Player.SkipBackward iconSizeClass="text-3xl" />
|
||||||
|
<Player.Pause iconSizeClass="text-5xl" />
|
||||||
|
<Player.SkipForward iconSizeClass="text-3xl" />
|
||||||
|
</Player.CenterMobileControls>
|
||||||
|
|
||||||
<Player.TopControls show={desktopControlsVisible}>
|
<Player.TopControls show={desktopControlsVisible}>
|
||||||
<div className="grid grid-cols-[1fr,auto] xl:grid-cols-3 items-center">
|
<div className="grid grid-cols-[1fr,auto] xl:grid-cols-3 items-center">
|
||||||
<div className="flex space-x-3 items-center">
|
<div className="flex space-x-3 items-center">
|
||||||
@ -91,14 +106,19 @@ export function PlayerView() {
|
|||||||
<Player.BottomControls show={desktopControlsVisible}>
|
<Player.BottomControls show={desktopControlsVisible}>
|
||||||
<Player.ProgressBar />
|
<Player.ProgressBar />
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
<Player.LeftSideControls>
|
<Player.LeftSideControls className="hidden lg:flex">
|
||||||
<Player.Pause />
|
<Player.Pause />
|
||||||
<Player.SkipBackward />
|
<Player.SkipBackward />
|
||||||
<Player.SkipForward />
|
<Player.SkipForward />
|
||||||
<Player.Volume />
|
<Player.Volume />
|
||||||
<Player.Time />
|
<Player.Time />
|
||||||
</Player.LeftSideControls>
|
</Player.LeftSideControls>
|
||||||
<div>
|
<Player.LeftSideControls className="flex lg:hidden">
|
||||||
|
{/* Do mobile controls here :) */}
|
||||||
|
<Player.Time />
|
||||||
|
</Player.LeftSideControls>
|
||||||
|
<div className="flex items-center">
|
||||||
|
<Player.Settings />
|
||||||
<Player.Fullscreen />
|
<Player.Fullscreen />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import { useEffect, useRef } from "react";
|
|
||||||
|
|
||||||
import { OverlayAnchor } from "@/components/overlays/OverlayAnchor";
|
import { OverlayAnchor } from "@/components/overlays/OverlayAnchor";
|
||||||
import { Overlay, OverlayDisplay } from "@/components/overlays/OverlayDisplay";
|
import { Overlay, OverlayDisplay } from "@/components/overlays/OverlayDisplay";
|
||||||
import { OverlayPage } from "@/components/overlays/OverlayPage";
|
import { OverlayPage } from "@/components/overlays/OverlayPage";
|
||||||
@ -21,9 +19,10 @@ export default function TestView() {
|
|||||||
>
|
>
|
||||||
Open
|
Open
|
||||||
</button>
|
</button>
|
||||||
<OverlayAnchor id={router.id}>
|
<OverlayAnchor
|
||||||
<div className="h-20 w-20 hover:w-24 mt-[50rem] bg-white" />
|
id={router.id}
|
||||||
</OverlayAnchor>
|
className="h-20 w-20 hover:w-24 mt-[50rem] bg-white"
|
||||||
|
/>
|
||||||
<Overlay id={router.id}>
|
<Overlay id={router.id}>
|
||||||
<OverlayRouter id={router.id}>
|
<OverlayRouter id={router.id}>
|
||||||
<OverlayPage id={router.id} path="/" width={400} height={400}>
|
<OverlayPage id={router.id} path="/" width={400} height={400}>
|
||||||
|
@ -15,7 +15,10 @@ export interface InterfaceSlice {
|
|||||||
interface: {
|
interface: {
|
||||||
isFullscreen: boolean;
|
isFullscreen: boolean;
|
||||||
isSeeking: boolean;
|
isSeeking: boolean;
|
||||||
|
lastVolume: number;
|
||||||
|
hasOpenOverlay: boolean;
|
||||||
hovering: PlayerHoverState;
|
hovering: PlayerHoverState;
|
||||||
|
lastHoveringState: PlayerHoverState;
|
||||||
|
|
||||||
volumeChangedWithKeybind: boolean; // has the volume recently been adjusted with the up/down arrows recently?
|
volumeChangedWithKeybind: boolean; // has the volume recently been adjusted with the up/down arrows recently?
|
||||||
volumeChangedWithKeybindDebounce: NodeJS.Timeout | null; // debounce for the duration of the "volume changed thingamajig"
|
volumeChangedWithKeybindDebounce: NodeJS.Timeout | null; // debounce for the duration of the "volume changed thingamajig"
|
||||||
@ -27,19 +30,34 @@ export interface InterfaceSlice {
|
|||||||
setSeeking(seeking: boolean): void;
|
setSeeking(seeking: boolean): void;
|
||||||
setTimeFormat(format: VideoPlayerTimeFormat): void;
|
setTimeFormat(format: VideoPlayerTimeFormat): void;
|
||||||
setHoveringLeftControls(state: boolean): void;
|
setHoveringLeftControls(state: boolean): void;
|
||||||
|
setHasOpenOverlay(state: boolean): void;
|
||||||
|
setLastVolume(state: number): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createInterfaceSlice: MakeSlice<InterfaceSlice> = (set, get) => ({
|
export const createInterfaceSlice: MakeSlice<InterfaceSlice> = (set, get) => ({
|
||||||
interface: {
|
interface: {
|
||||||
|
hasOpenOverlay: false,
|
||||||
isFullscreen: false,
|
isFullscreen: false,
|
||||||
isSeeking: false,
|
isSeeking: false,
|
||||||
|
lastVolume: 0,
|
||||||
leftControlHovering: false,
|
leftControlHovering: false,
|
||||||
hovering: PlayerHoverState.NOT_HOVERING,
|
hovering: PlayerHoverState.NOT_HOVERING,
|
||||||
|
lastHoveringState: PlayerHoverState.NOT_HOVERING,
|
||||||
volumeChangedWithKeybind: false,
|
volumeChangedWithKeybind: false,
|
||||||
volumeChangedWithKeybindDebounce: null,
|
volumeChangedWithKeybindDebounce: null,
|
||||||
timeFormat: VideoPlayerTimeFormat.REGULAR,
|
timeFormat: VideoPlayerTimeFormat.REGULAR,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setLastVolume(state) {
|
||||||
|
set((s) => {
|
||||||
|
s.interface.lastVolume = state;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
setHasOpenOverlay(state) {
|
||||||
|
set((s) => {
|
||||||
|
s.interface.hasOpenOverlay = state;
|
||||||
|
});
|
||||||
|
},
|
||||||
setTimeFormat(format) {
|
setTimeFormat(format) {
|
||||||
set((s) => {
|
set((s) => {
|
||||||
s.interface.timeFormat = format;
|
s.interface.timeFormat = format;
|
||||||
@ -47,6 +65,8 @@ export const createInterfaceSlice: MakeSlice<InterfaceSlice> = (set, get) => ({
|
|||||||
},
|
},
|
||||||
updateInterfaceHovering(newState: PlayerHoverState) {
|
updateInterfaceHovering(newState: PlayerHoverState) {
|
||||||
set((s) => {
|
set((s) => {
|
||||||
|
if (newState !== PlayerHoverState.NOT_HOVERING)
|
||||||
|
s.interface.lastHoveringState = newState;
|
||||||
s.interface.hovering = newState;
|
s.interface.hovering = newState;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user