diff --git a/src/components/player/VideoPlayer.tsx b/src/components/player/VideoPlayer.tsx index 096cca7..733941e 100644 --- a/src/components/player/VideoPlayer.tsx +++ b/src/components/player/VideoPlayer.tsx @@ -26,6 +26,8 @@ export const VideoPlayer = () => { useEffect(() => { videoContainerRef.current?.appendChild(videoElement); + if(videoElement.paused && videoElement.currentSrc && videoElement.currentTime) + videoElement.play(); return () => { videoElement.pause(); }; diff --git a/src/components/tabs/TabsRenderer.tsx b/src/components/tabs/TabsRenderer.tsx index 9d74947..19a309a 100644 --- a/src/components/tabs/TabsRenderer.tsx +++ b/src/components/tabs/TabsRenderer.tsx @@ -9,10 +9,18 @@ import { IconBrandYoutube, IconLayoutList, IconList, IconMessage } from "@tabler import { ChaptersTab } from "./comps/ChaptersTab"; import { clamp, useHotkeys } from "@mantine/hooks"; -export const TabsRenderer = () => { +export const TabsRenderer = ({ + isMobile, +}: { + isMobile?: boolean; +}) => { const { currentTab, setCurrentTab, availableTabs } = useContext(TabsContext); - const height = `calc(100vh - var(--app-shell-header-height) - calc(var(--app-shell-padding) * 2) - 3em)`; + const height = isMobile ? ( + `100%` + ) : ( + `calc(100vh - var(--app-shell-header-height) - calc(var(--app-shell-padding) * 2) - 3em)` + ); useHotkeys([ ["z", () => setCurrentTab(availableTabs[availableTabs.indexOf(currentTab) - 1] || availableTabs[availableTabs.length - 1])], @@ -58,7 +66,13 @@ export const TabsRenderer = () => { ))} - + {([ { diff --git a/src/hooks/useIsMobile.ts b/src/hooks/useIsMobile.ts index 22b8ba3..f55d73a 100644 --- a/src/hooks/useIsMobile.ts +++ b/src/hooks/useIsMobile.ts @@ -3,5 +3,5 @@ import { useMediaQuery } from "@mantine/hooks"; export const useIsMobile = () => { const { breakpoints } = useMantineTheme(); - return !useMediaQuery(`(min-width: ${breakpoints.md})`); + return !useMediaQuery(`(min-width: ${breakpoints.sm})`); }; diff --git a/src/site/pages/WatchPage.tsx b/src/site/pages/WatchPage.tsx index a95b4c0..1e2b90b 100644 --- a/src/site/pages/WatchPage.tsx +++ b/src/site/pages/WatchPage.tsx @@ -7,116 +7,14 @@ import { TabsRenderer } from "../../components/tabs/TabsRenderer"; import { useFullscreen, useHotkeys, usePrevious } from "@mantine/hooks"; import { usePreference } from "../../api/pref/Preferences"; import { VideoPlayerContext } from "../../api/player/VideoPlayerContext"; +import { useIsMobile } from "../../hooks/useIsMobile"; +import { WatchPageMobile } from "./WatchPageMobile"; +import { WatchPageDesktop } from "./WatchPageDesktop"; export const WatchPage = () => { - const { activeFormat } = useContext(VideoPlayerContext); - const animate = usePreference("watchPageAnimations"); - const { isTabsVisible: sidebarOpen, setTabsVisible } = useContext(TabsContext); - const { fullscreen, toggle: toggleFullscreen } = useFullscreen(); - - useHotkeys([ - ["t", () => setTabsVisible(!sidebarOpen)], - ["f", () => toggleFullscreen()], - ]); + const isMobile = useIsMobile(); return ( - + isMobile ? : ); }; - -const WatchPageLayout = ({ - theather, - fullscreen, - animate, - aspect, -}: { - theather: boolean; - fullscreen: boolean; - animate: boolean; - aspect?: number; -}) => { - const ref = useRef(null); - let nice = ref.current ? (aspect * ref.current.getBoundingClientRect().height) : null; - - const per = 0.65; - const { position, separatorProps, setPosition } = useResizable({ - axis: "x", - min: window.innerWidth * 0.4, - initial: nice || (window.innerWidth * per), - max: window.innerWidth * 0.8, - containerRef: ref, - }); - const prevOpen = usePrevious(theather) ?? theather; - const isClosing = prevOpen && !theather; - const isOpening = !prevOpen && theather; - - useEffect(() => { - if(ref.current && aspect) setPosition(aspect * ref.current.getBoundingClientRect().height); - }, [ref.current, aspect]); - - const height = !theather && fullscreen ? ( - `calc(100vh)` - ) : ( - `calc(100vh - var(--app-shell-header-height))` - ); - - return ( - - - - - - - - - - ); -}; - -const Seperator = (allProps: SeparatorProps & { show: boolean }) => { - const { - show, - style, - ...props - } = allProps; - - return ( - - ) -} diff --git a/src/site/pages/WatchPageDesktop.tsx b/src/site/pages/WatchPageDesktop.tsx new file mode 100644 index 0000000..bf778f6 --- /dev/null +++ b/src/site/pages/WatchPageDesktop.tsx @@ -0,0 +1,122 @@ +import { Box, Flex } from "@mantine/core"; +import { VideoPlayer } from "../../components/player/VideoPlayer"; +import { SeparatorProps, useResizable } from "react-resizable-layout"; +import { useContext, useEffect, useRef } from "react"; +import { TabsContext } from "../../components/tabs/TabsContext"; +import { TabsRenderer } from "../../components/tabs/TabsRenderer"; +import { useFullscreen, useHotkeys, usePrevious } from "@mantine/hooks"; +import { usePreference } from "../../api/pref/Preferences"; +import { VideoPlayerContext } from "../../api/player/VideoPlayerContext"; + +export const WatchPageDesktop = () => { + const { activeFormat } = useContext(VideoPlayerContext); + const animate = usePreference("watchPageAnimations"); + const { isTabsVisible: sidebarOpen, setTabsVisible } = useContext(TabsContext); + const { fullscreen, toggle: toggleFullscreen } = useFullscreen(); + + useHotkeys([ + ["t", () => setTabsVisible(!sidebarOpen)], + ["f", () => toggleFullscreen()], + ]); + + return ( + + ); +}; + +const WatchPageLayout = ({ + theather, + fullscreen, + animate, + aspect, +}: { + theather: boolean; + fullscreen: boolean; + animate: boolean; + aspect?: number; +}) => { + const ref = useRef(null); + let nice = ref.current ? (aspect * ref.current.getBoundingClientRect().height) : null; + + const per = 0.65; + const { position, separatorProps, setPosition } = useResizable({ + axis: "x", + min: window.innerWidth * 0.4, + initial: nice || (window.innerWidth * per), + max: window.innerWidth * 0.8, + containerRef: ref, + }); + const prevOpen = usePrevious(theather) ?? theather; + const isClosing = prevOpen && !theather; + const isOpening = !prevOpen && theather; + + useEffect(() => { + if(ref.current && aspect) setPosition(aspect * ref.current.getBoundingClientRect().height); + }, [ref.current, aspect]); + + const height = !theather && fullscreen ? ( + `calc(100vh)` + ) : ( + `calc(100vh - var(--app-shell-header-height))` + ); + + return ( + + + + + + + + + + ); +}; + +const Seperator = (allProps: SeparatorProps & { show: boolean }) => { + const { + show, + style, + ...props + } = allProps; + + return ( + + ) +} diff --git a/src/site/pages/WatchPageMobile.tsx b/src/site/pages/WatchPageMobile.tsx new file mode 100644 index 0000000..76e0474 --- /dev/null +++ b/src/site/pages/WatchPageMobile.tsx @@ -0,0 +1,60 @@ +import { Box, Flex, Stack } from "@mantine/core"; +import { VideoPlayer } from "../../components/player/VideoPlayer"; +import { SeparatorProps, useResizable } from "react-resizable-layout"; +import { useContext, useEffect, useRef, useState } from "react"; +import { TabsContext } from "../../components/tabs/TabsContext"; +import { TabsRenderer } from "../../components/tabs/TabsRenderer"; +import { useFullscreen, useHotkeys, usePrevious } from "@mantine/hooks"; +import { usePreference } from "../../api/pref/Preferences"; +import { VideoPlayerContext } from "../../api/player/VideoPlayerContext"; + +export const WatchPageMobile = () => { + const { activeFormat } = useContext(VideoPlayerContext); + + if(activeFormat) + console.log(`Aspect Ratio ${activeFormat.width} / ${activeFormat.height}`); + + return ( + + ); +}; + +const WatchPageLayout = ({ + aspect, +}: { + aspect: number; +}) => { + const ref = useRef(null); + // h = r/w + const [height, setHeight] = useState(window.innerWidth / aspect); + + useEffect(() => { + if(!ref.current) return; + setHeight(ref.current.getBoundingClientRect().width / aspect); + }, [ref.current, aspect]); + + return ( + + + + + + + + + ); +};