Skip to content

Commit

Permalink
mobile accessible watch page
Browse files Browse the repository at this point in the history
  • Loading branch information
TheAlan404 committed May 19, 2024
1 parent 2f2ad7a commit 915fb75
Show file tree
Hide file tree
Showing 6 changed files with 207 additions and 111 deletions.
2 changes: 2 additions & 0 deletions src/components/player/VideoPlayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ export const VideoPlayer = () => {

useEffect(() => {
videoContainerRef.current?.appendChild(videoElement);
if(videoElement.paused && videoElement.currentSrc && videoElement.currentTime)
videoElement.play();
return () => {
videoElement.pause();
};
Expand Down
20 changes: 17 additions & 3 deletions src/components/tabs/TabsRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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])],
Expand Down Expand Up @@ -58,7 +66,13 @@ export const TabsRenderer = () => {
</Tabs.Panel>
))}

<Tabs.List grow>
<Tabs.List grow style={isMobile ? {
position: "absolute",
bottom: "0px",
width: "100%",
backgroundColor: "var(--mantine-color-dark-filled)",
zIndex: "300",
} : {}}>
<Tooltip.Group>
{([
{
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/useIsMobile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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})`);
};
112 changes: 5 additions & 107 deletions src/site/pages/WatchPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<WatchPageLayout
theather={sidebarOpen}
fullscreen={fullscreen}
animate={animate}
aspect={activeFormat ? (activeFormat.width / activeFormat.height) : 16/9}
/>
isMobile ? <WatchPageMobile /> : <WatchPageDesktop />
);
};

const WatchPageLayout = ({
theather,
fullscreen,
animate,
aspect,
}: {
theather: boolean;
fullscreen: boolean;
animate: boolean;
aspect?: number;
}) => {
const ref = useRef<HTMLDivElement>(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 (
<Flex ref={ref} w="100%" h={height} style={{ overflow: "hidden" }}>
<Box h="100%" style={{
width: theather ? position : "100%",
transition: (animate && (isOpening || isClosing)) ? "0.5s" : undefined,
}}>
<VideoPlayer />
</Box>
<Seperator
show={theather}
style={{
transition: (animate && (isOpening || isClosing)) ? "0.5s" : undefined,
}}
{...separatorProps}
/>
<Box
mah={height}
style={{
overflow: "hidden",
width: theather ? `calc(100% - ${position}px)` : "0px",
marginLeft: "auto",
transition: (animate && (isOpening || isClosing)) ? "0.5s" : undefined,
}}>
<TabsRenderer />
</Box>
</Flex>
);
};

const Seperator = (allProps: SeparatorProps & { show: boolean }) => {
const {
show,
style,
...props
} = allProps;

return (
<Box
h="100%"
bg="dark.4"
className="hoverable"
{...props}
style={{
...style,
userSelect: "none",
cursor: "col-resize",
...(show ? {
marginLeft: "0.1em",
marginRight: "0.1em",
width: "0.5em",
} : {}),
}}
/>
)
}
122 changes: 122 additions & 0 deletions src/site/pages/WatchPageDesktop.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<WatchPageLayout
theather={sidebarOpen}
fullscreen={fullscreen}
animate={animate}
aspect={activeFormat ? (activeFormat.width / activeFormat.height) : 16/9}
/>
);
};

const WatchPageLayout = ({
theather,
fullscreen,
animate,
aspect,
}: {
theather: boolean;
fullscreen: boolean;
animate: boolean;
aspect?: number;
}) => {
const ref = useRef<HTMLDivElement>(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 (
<Flex ref={ref} w="100%" h={height} style={{ overflow: "hidden" }}>
<Box h="100%" style={{
width: theather ? position : "100%",
transition: (animate && (isOpening || isClosing)) ? "0.5s" : undefined,
}}>
<VideoPlayer />
</Box>
<Seperator
show={theather}
style={{
transition: (animate && (isOpening || isClosing)) ? "0.5s" : undefined,
}}
{...separatorProps}
/>
<Box
mah={height}
style={{
overflow: "hidden",
width: theather ? `calc(100% - ${position}px)` : "0px",
marginLeft: "auto",
transition: (animate && (isOpening || isClosing)) ? "0.5s" : undefined,
}}>
<TabsRenderer />
</Box>
</Flex>
);
};

const Seperator = (allProps: SeparatorProps & { show: boolean }) => {
const {
show,
style,
...props
} = allProps;

return (
<Box
h="100%"
bg="dark.4"
className="hoverable"
{...props}
style={{
...style,
userSelect: "none",
cursor: "col-resize",
...(show ? {
marginLeft: "0.1em",
marginRight: "0.1em",
width: "0.5em",
} : {}),
}}
/>
)
}
60 changes: 60 additions & 0 deletions src/site/pages/WatchPageMobile.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<WatchPageLayout
aspect={activeFormat ? (activeFormat.width / activeFormat.height) : 16/9}
/>
);
};

const WatchPageLayout = ({
aspect,
}: {
aspect: number;
}) => {
const ref = useRef<HTMLDivElement>(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 (
<Stack
gap={0}
ref={ref}
w="100%"
h={`calc(100vh - var(--app-shell-header-height))`}
style={{ overflow: "hidden" }}
>
<Box w="100%" style={{
height: `${height}px`,
}}>
<VideoPlayer />
</Box>
<Box
style={{
overflow: "hidden",
height: `calc(100% - ${height - 200}px)`,
}}>
<TabsRenderer isMobile />
</Box>
</Stack>
);
};

0 comments on commit 915fb75

Please sign in to comment.