Skip to content

Commit

Permalink
Merge pull request #48 from stephane-r/update-player-ui
Browse files Browse the repository at this point in the history
feat: ajust some player UI details on medium screen
  • Loading branch information
stephane-r authored Oct 17, 2023
2 parents 7b103ba + 40e209f commit 0a10471
Show file tree
Hide file tree
Showing 8 changed files with 203 additions and 50 deletions.
2 changes: 1 addition & 1 deletion src/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export const App = () => {
}} // Stay in inline-styles for now
>
<Flex>
<Box style={{ flex: 1 }}>
<Box style={{ flex: 1, zIndex: 1 }}>
<Header />
<Main>
<Outlet />
Expand Down
29 changes: 27 additions & 2 deletions src/components/ButtonFavorite.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { ActionIcon, ActionIconProps } from "@mantine/core";
import {
ActionIcon,
ActionIconProps,
Menu,
useMantineTheme,
} from "@mantine/core";
import { notifications } from "@mantine/notifications";
import { IconHeart } from "@tabler/icons-react";
import { IconHeart, IconHeartFilled } from "@tabler/icons-react";
import { memo } from "react";
import { useTranslation } from "react-i18next";

Expand All @@ -16,6 +21,7 @@ interface ButtonFavoriteProps extends ActionIconProps {
video?: Video;
iconSize?: number;
buttonSize?: number;
render?: "menu";
}

const getItemId = (item: Video) => {
Expand All @@ -36,11 +42,13 @@ export const ButtonFavorite: React.FC<ButtonFavoriteProps> = memo(
iconSize = 18,
variant = "default",
buttonSize = 36,
render = null,
}) => {
const favorite = useFavorite();
const setFavorite = useSetFavorite();
const { video: currentVideo } = usePlayerVideo();
const { t } = useTranslation();
const theme = useMantineTheme();

const video = parentVideo ?? (currentVideo as Video);

Expand Down Expand Up @@ -94,6 +102,23 @@ export const ButtonFavorite: React.FC<ButtonFavoriteProps> = memo(
return handleAdd();
};

if (render === "menu") {
return (
<Menu.Item
onClick={onClick}
icon={
isFavorite ? (
<IconHeartFilled style={{ color: theme.colors.pink[8] }} />
) : (
<IconHeart />
)
}
>
Favorite
</Menu.Item>
);
}

return (
<ActionIcon
variant={isFavorite ? "filled" : variant}
Expand Down
13 changes: 11 additions & 2 deletions src/components/ButtonPlayerModeVideo.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ActionIcon, Tooltip } from "@mantine/core";
import { ActionIcon, Menu, Tooltip } from "@mantine/core";
import { IconVideo } from "@tabler/icons-react";
import { memo } from "react";
import { useTranslation } from "react-i18next";
Expand All @@ -8,10 +8,11 @@ import { usePlayerMode, useSetPlayerMode } from "../providers/PlayerMode";

interface ButtonPlayerModeVideoProps {
iconSize?: number;
render: "menu" | "button";
}

export const ButtonPlayerModeVideo: React.FC<ButtonPlayerModeVideoProps> = memo(
({ iconSize }) => {
({ iconSize, render = "button" }) => {
const setPlayerMode = useSetPlayerMode();
const playerMode = usePlayerMode();
const playerAudio = usePlayerAudio();
Expand All @@ -25,6 +26,14 @@ export const ButtonPlayerModeVideo: React.FC<ButtonPlayerModeVideoProps> = memo(
audio.pause();
};

if (render === "menu") {
return (
<Menu.Item onClick={handleClick} icon={<IconVideo />}>
Video mode
</Menu.Item>
);
}

return (
<Tooltip label={t("video.mode")}>
<ActionIcon
Expand Down
4 changes: 3 additions & 1 deletion src/components/DrawerPlayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { ButtonFavorite } from "./ButtonFavorite";
import { ButtonPlayerModeVideo } from "./ButtonPlayerModeVideo";
import { ButtonRepeat } from "./ButtonRepeat";
import { ButtonShare } from "./ButtonShare";
import { ButtonVolume } from "./Player";
import { PlayerActions } from "./PlayerActions";
import { PlayerBackground } from "./PlayerBackground";
import { PlayerLoadingOverlay } from "./PlayerLoadingOverlay";
Expand Down Expand Up @@ -106,7 +107,8 @@ export const DrawerPlayerVideo = memo(() => {
<Flex gap="md">
<ButtonDownload iconSize={16} />
<ButtonShare iconSize={16} />
<ButtonPlayerModeVideo iconSize={16} />
<ButtonPlayerModeVideo render="button" iconSize={16} />
<ButtonVolume />
</Flex>
<Space h="xl" />
<Flex className={classes.progressContainer}>
Expand Down
107 changes: 64 additions & 43 deletions src/components/Player.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,23 @@ import {
Box,
Drawer,
Flex,
Menu,
Popover,
ScrollArea,
Slider,
Space,
Text,
createStyles,
useMantineTheme,
} from "@mantine/core";
import { useDocumentTitle, useMediaQuery } from "@mantine/hooks";
import { IconPlaylist, IconVolume } from "@tabler/icons-react";
import {
IconDotsVertical,
IconPlaylist,
IconVolume,
} from "@tabler/icons-react";
import { memo, useState } from "react";
import { useTranslation } from "react-i18next";

import { useDevices } from "../hooks/useDevices";
import {
usePlayerAudio,
usePlayerState,
Expand All @@ -31,6 +36,7 @@ import { PlayerActions } from "./PlayerActions";
import { PlayerBackground } from "./PlayerBackground";
import { PlayerLoadingOverlay } from "./PlayerLoadingOverlay";
import { PlayerProgress } from "./PlayerProgress";
import { VerticalSlider } from "./VerticalSlider";
import { VideoList } from "./VideoList";

const useStyles = createStyles((theme) => ({
Expand Down Expand Up @@ -58,7 +64,7 @@ const useStyles = createStyles((theme) => ({
},

[`@media (min-width: ${theme.breakpoints.md})`]: {
maxWidth: 280,
maxWidth: 260,
},

[`@media (min-width: ${theme.breakpoints.lg})`]: {
Expand All @@ -69,7 +75,6 @@ const useStyles = createStyles((theme) => ({
maxWidth: 440,
},
},
volume: {},
thumbnail: {
flex: "0 0 50px",
height: 50,
Expand All @@ -83,49 +88,51 @@ const useStyles = createStyles((theme) => ({

export const Player = memo(() => {
const { classes } = useStyles();
const matches = useMediaQuery("(max-width: 2140px)");
const theme = useMantineTheme();
const showProgressBar = useMediaQuery(`(min-width: ${theme.breakpoints.md})`);
const showVolumeBar = useMediaQuery(`(min-width: ${theme.breakpoints.xl})`);
const showPlayerBar = useMediaQuery("(max-width: 2140px)");
const { isMedium, isLarge, isLessThanLarge, isXlarge } = useDevices();

return (
<Box
className={classes.container}
style={{ display: matches ? "block" : "none" }}
style={{ display: showPlayerBar ? "block" : "none" }}
>
<Flex align="center" className={classes.content}>
<PlayerLoadingOverlay />
{matches ? (
{showPlayerBar ? (
<>
<PlayerBackground />
<VideoInformations />
<Space w={60} />
<Space w={isXlarge ? 60 : 30} />
<Flex align="center" style={{ flex: 1 }}>
<PlayerActions />
<Space w={60} />
{showProgressBar ? (
<Space w={isLessThanLarge ? 30 : 60} />
{isMedium ? (
<>
<PlayerProgress />
<Space w={60} />
<Space w={isLarge ? 60 : 30} />
</>
) : null}
<ButtonRepeat iconSize={20} />
<Space w="lg" />
<Space w={20} />
<ButtonDownload iconSize={20} />
<Space w="lg" />
<Space w={20} />
<ButtonShare iconSize={20} />
<Space w="lg" />
<ButtonPlayerModeVideo />
<Space w="lg" />
<ButtonFavorite iconSize={20} variant="transparent" />
{showVolumeBar ? (
{isLarge ? (
<>
<Space w={20} />
<PlayerVolume />
<ButtonFavorite iconSize={20} variant="transparent" />
</>
) : null}
<Space w={40} />
<Space w={20} />
<ButtonVolume />
<Space w={20} />
<PlayerPlaylist />
{isLessThanLarge ? (
<>
<Space w={20} />
<MoreSubMenu />
</>
) : null}
</Flex>
</>
) : null}
Expand All @@ -140,6 +147,8 @@ const VideoInformations = memo(() => {

useDocumentTitle(video?.title as string);

if (!video) return null;

return (
<Flex
align="center"
Expand All @@ -152,20 +161,19 @@ const VideoInformations = memo(() => {
}}
className={classes.thumbnail}
/>
<Box maw="100%">
<Text color="white" lineClamp={1}>
{video?.title}
<Box maw="100%" pr="lg">
<Text color="white" lineClamp={1} title={video.title}>
{video.title}
</Text>
<Text color="white" size="sm" lineClamp={1}>
{video?.description}
{video.description}
</Text>
</Box>
</Flex>
);
});

const PlayerVolume = memo(() => {
const { classes } = useStyles();
export const ButtonVolume = memo(() => {
const playerState = usePlayerState();
const playerAudio = usePlayerAudio();

Expand All @@ -176,22 +184,19 @@ const PlayerVolume = memo(() => {
};

return (
<Flex align="center" gap="sm" w={140} className={classes.volume}>
<ActionIcon>
<IconVolume size={20} />
</ActionIcon>
<Box style={{ flex: 1 }}>
<Slider
<Popover shadow="md">
<Popover.Target>
<ActionIcon>
<IconVolume size={20} />
</ActionIcon>
</Popover.Target>
<Popover.Dropdown>
<VerticalSlider
value={playerState.volume * 100}
size="xs"
styles={{
thumb: { display: "none" },
bar: { background: "white" },
}}
onChangeEnd={handleChangeEnd}
/>
</Box>
</Flex>
</Popover.Dropdown>
</Popover>
);
});

Expand Down Expand Up @@ -228,3 +233,19 @@ export const PlayerSpace = memo(() => {

return <Box style={{ height }} />;
});

const MoreSubMenu = memo(() => {
return (
<Menu shadow="md" width={200} position="top">
<Menu.Target>
<ActionIcon>
<IconDotsVertical />
</ActionIcon>
</Menu.Target>
<Menu.Dropdown>
<ButtonPlayerModeVideo render="menu" />
<ButtonFavorite render="menu" />
</Menu.Dropdown>
</Menu>
);
});
4 changes: 3 additions & 1 deletion src/components/PlayerProgress.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { Box, Flex, Slider, Text } from "@mantine/core";
import { memo } from "react";

import { useDevices } from "../hooks/useDevices";
import { useSponsorBlock } from "../hooks/useSponsorBlock";
import { usePlayerAudio, usePlayerState } from "../providers/Player";
import { SponsorBlockBar } from "./SponsorBlockBar";

export const PlayerProgress = memo(() => {
const playerAudio = usePlayerAudio();
const playerState = usePlayerState();
const { isLarge } = useDevices();

useSponsorBlock();

Expand All @@ -18,7 +20,7 @@ export const PlayerProgress = memo(() => {
};

return (
<Flex align="center" gap="xl" style={{ flex: 1 }}>
<Flex align="center" gap={isLarge ? "xl" : "md"} style={{ flex: 1 }}>
<Text size="xs" color="white">
{String(playerState.formatedCurrentTime ?? "00:00")}
</Text>
Expand Down
Loading

0 comments on commit 0a10471

Please sign in to comment.