add top bar and improve ui feel

This commit is contained in:
Jelle van Snik 2023-01-10 00:27:04 +01:00
parent 024325f640
commit 351b35ef98
6 changed files with 52 additions and 11 deletions

View File

@ -5,8 +5,11 @@ import { PauseControl } from "./controls/PauseControl";
import { ProgressControl } from "./controls/ProgressControl"; import { ProgressControl } from "./controls/ProgressControl";
import { TimeControl } from "./controls/TimeControl"; import { TimeControl } from "./controls/TimeControl";
import { VolumeControl } from "./controls/VolumeControl"; import { VolumeControl } from "./controls/VolumeControl";
import { VideoPlayerHeader } from "./parts/VideoPlayerHeader";
import { VideoPlayer, VideoPlayerProps } from "./VideoPlayer"; import { VideoPlayer, VideoPlayerProps } from "./VideoPlayer";
// TODO animate items away when hidden
export function DecoratedVideoPlayer(props: VideoPlayerProps) { export function DecoratedVideoPlayer(props: VideoPlayerProps) {
return ( return (
<VideoPlayer autoPlay={props.autoPlay}> <VideoPlayer autoPlay={props.autoPlay}>
@ -14,9 +17,9 @@ export function DecoratedVideoPlayer(props: VideoPlayerProps) {
<div className="absolute inset-0 flex items-center justify-center"> <div className="absolute inset-0 flex items-center justify-center">
<LoadingControl /> <LoadingControl />
</div> </div>
<div className="pointer-events-auto absolute inset-x-0 bottom-0 mb-4 flex flex-col px-6"> <div className="pointer-events-auto absolute inset-x-0 bottom-0 flex flex-col px-4 pb-2">
<ProgressControl /> <ProgressControl />
<div className="flex items-center"> <div className="flex items-center px-2">
<PauseControl /> <PauseControl />
<VolumeControl className="mr-2" /> <VolumeControl className="mr-2" />
<TimeControl /> <TimeControl />
@ -24,6 +27,9 @@ export function DecoratedVideoPlayer(props: VideoPlayerProps) {
<FullscreenControl /> <FullscreenControl />
</div> </div>
</div> </div>
<div className="pointer-events-auto absolute inset-x-0 top-0 flex flex-col py-6 px-8 pb-2">
<VideoPlayerHeader title="Spiderman: Coming House" />
</div>
</BackdropControl> </BackdropControl>
{props.children} {props.children}
</VideoPlayer> </VideoPlayer>

View File

@ -5,6 +5,8 @@ interface BackdropControlProps {
children?: React.ReactNode; children?: React.ReactNode;
} }
// TODO add double click to toggle fullscreen
export function BackdropControl(props: BackdropControlProps) { export function BackdropControl(props: BackdropControlProps) {
const { videoState } = useVideoPlayerState(); const { videoState } = useVideoPlayerState();
const [moved, setMoved] = useState(false); const [moved, setMoved] = useState(false);
@ -50,12 +52,12 @@ export function BackdropControl(props: BackdropControlProps) {
}`} }`}
/> />
<div <div
className={`pointer-events-none absolute inset-x-0 bottom-0 h-[30%] bg-gradient-to-t from-black to-transparent opacity-75 transition-opacity duration-200 ${ className={`pointer-events-none absolute inset-x-0 bottom-0 h-[20%] bg-gradient-to-t from-black to-transparent transition-opacity duration-200 ${
!showUI ? "!opacity-0" : "" !showUI ? "!opacity-0" : ""
}`} }`}
/> />
<div <div
className={`pointer-events-none absolute inset-x-0 top-0 h-[30%] bg-gradient-to-b from-black to-transparent opacity-75 transition-opacity duration-200 ${ className={`pointer-events-none absolute inset-x-0 top-0 h-[20%] bg-gradient-to-b from-black to-transparent transition-opacity duration-200 ${
!showUI ? "!opacity-0" : "" !showUI ? "!opacity-0" : ""
}`} }`}
/> />

View File

@ -44,13 +44,13 @@ export function ProgressControl() {
}`} }`}
> >
<div <div
className="absolute inset-y-0 left-0 flex items-center justify-end rounded-full bg-gray-300 bg-opacity-50" className="absolute inset-y-0 left-0 flex items-center justify-end rounded-full bg-gray-300 bg-opacity-20"
style={{ style={{
width: bufferProgress, width: bufferProgress,
}} }}
/> />
<div <div
className="absolute inset-y-0 left-0 flex items-center justify-end rounded-full bg-bink-500" className="absolute inset-y-0 left-0 flex items-center justify-end rounded-full bg-bink-600"
style={{ style={{
width: watchProgress, width: watchProgress,
}} }}

View File

@ -60,12 +60,12 @@ export function VolumeControl(props: Props) {
</div> </div>
<div <div
className={`-ml-2 w-0 overflow-hidden transition-[width,opacity] duration-300 ease-in ${ className={`-ml-2 w-0 overflow-hidden transition-[width,opacity] duration-300 ease-in ${
hoveredOnce ? "!w-20 opacity-100" : "w-4 opacity-0" hoveredOnce ? "!w-24 opacity-100" : "w-4 opacity-0"
}`} }`}
> >
<div <div
ref={ref} ref={ref}
className="flex h-10 w-16 items-center px-2" className="flex h-10 w-20 items-center px-2"
onMouseDown={dragMouseDown} onMouseDown={dragMouseDown}
> >
<div className="relative h-1 flex-1 rounded-full bg-gray-500 bg-opacity-50"> <div className="relative h-1 flex-1 rounded-full bg-gray-500 bg-opacity-50">

View File

@ -0,0 +1,28 @@
import { Icon, Icons } from "@/components/Icon";
import { BrandPill } from "@/components/layout/BrandPill";
interface VideoPlayerHeaderProps {
title: string;
onClick?: () => void;
}
export function VideoPlayerHeader(props: VideoPlayerHeaderProps) {
return (
<div className="flex items-center">
<div className="flex flex-1 items-center">
<p className="flex items-center">
<span
onClick={props.onClick}
className="flex cursor-pointer items-center py-1 text-white opacity-50 transition-opacity hover:opacity-100"
>
<Icon className="mr-2" icon={Icons.ARROW_LEFT} />
<span>Back to home</span>
</span>
<span className="mx-4 h-6 w-[1.5px] rotate-[30deg] bg-white opacity-50" />
<span className="text-white">{props.title}</span>
</p>
</div>
<BrandPill />
</div>
);
}

View File

@ -5,13 +5,18 @@ import { useCallback, useState } from "react";
// test videos: https://gist.github.com/jsturgis/3b19447b304616f18657 // test videos: https://gist.github.com/jsturgis/3b19447b304616f18657
// TODO video todos: // TODO video todos:
// - make pretty // - improve seekables (if possible)
// - improve seekables
// - error handling // - error handling
// - middle pause button // - middle pause button
// - double click backdrop to toggle fullscreen
// - make volume bar collapse when hovering away from left control section
// - animate UI when showing/hiding
// - shortcuts when player is active
// - save volume in localstorage so persists between page reloads
// - improve pausing while seeking/buffering // - improve pausing while seeking/buffering
// - volume control flashes old value when updating
// - progress control flashes old value when updating
// - captions // - captions
// - backdrop better click handling
// - IOS support: (no volume, fullscreen video element instead of wrapper) // - IOS support: (no volume, fullscreen video element instead of wrapper)
// - IpadOS support: (fullscreen video wrapper should work, see (lookmovie.io) ) // - IpadOS support: (fullscreen video wrapper should work, see (lookmovie.io) )
// - HLS support: feature detection otherwise use HLS.js // - HLS support: feature detection otherwise use HLS.js