mirror of
https://github.com/sussy-code/smov.git
synced 2024-12-20 14:37:43 +01:00
add top bar and improve ui feel
This commit is contained in:
parent
024325f640
commit
351b35ef98
6 changed files with 52 additions and 11 deletions
|
@ -5,8 +5,11 @@ import { PauseControl } from "./controls/PauseControl";
|
|||
import { ProgressControl } from "./controls/ProgressControl";
|
||||
import { TimeControl } from "./controls/TimeControl";
|
||||
import { VolumeControl } from "./controls/VolumeControl";
|
||||
import { VideoPlayerHeader } from "./parts/VideoPlayerHeader";
|
||||
import { VideoPlayer, VideoPlayerProps } from "./VideoPlayer";
|
||||
|
||||
// TODO animate items away when hidden
|
||||
|
||||
export function DecoratedVideoPlayer(props: VideoPlayerProps) {
|
||||
return (
|
||||
<VideoPlayer autoPlay={props.autoPlay}>
|
||||
|
@ -14,9 +17,9 @@ export function DecoratedVideoPlayer(props: VideoPlayerProps) {
|
|||
<div className="absolute inset-0 flex items-center justify-center">
|
||||
<LoadingControl />
|
||||
</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 />
|
||||
<div className="flex items-center">
|
||||
<div className="flex items-center px-2">
|
||||
<PauseControl />
|
||||
<VolumeControl className="mr-2" />
|
||||
<TimeControl />
|
||||
|
@ -24,6 +27,9 @@ export function DecoratedVideoPlayer(props: VideoPlayerProps) {
|
|||
<FullscreenControl />
|
||||
</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>
|
||||
{props.children}
|
||||
</VideoPlayer>
|
||||
|
|
|
@ -5,6 +5,8 @@ interface BackdropControlProps {
|
|||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
// TODO add double click to toggle fullscreen
|
||||
|
||||
export function BackdropControl(props: BackdropControlProps) {
|
||||
const { videoState } = useVideoPlayerState();
|
||||
const [moved, setMoved] = useState(false);
|
||||
|
@ -50,12 +52,12 @@ export function BackdropControl(props: BackdropControlProps) {
|
|||
}`}
|
||||
/>
|
||||
<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" : ""
|
||||
}`}
|
||||
/>
|
||||
<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" : ""
|
||||
}`}
|
||||
/>
|
||||
|
|
|
@ -44,13 +44,13 @@ export function ProgressControl() {
|
|||
}`}
|
||||
>
|
||||
<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={{
|
||||
width: bufferProgress,
|
||||
}}
|
||||
/>
|
||||
<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={{
|
||||
width: watchProgress,
|
||||
}}
|
||||
|
|
|
@ -60,12 +60,12 @@ export function VolumeControl(props: Props) {
|
|||
</div>
|
||||
<div
|
||||
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
|
||||
ref={ref}
|
||||
className="flex h-10 w-16 items-center px-2"
|
||||
className="flex h-10 w-20 items-center px-2"
|
||||
onMouseDown={dragMouseDown}
|
||||
>
|
||||
<div className="relative h-1 flex-1 rounded-full bg-gray-500 bg-opacity-50">
|
||||
|
|
28
src/components/video/parts/VideoPlayerHeader.tsx
Normal file
28
src/components/video/parts/VideoPlayerHeader.tsx
Normal 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>
|
||||
);
|
||||
}
|
|
@ -5,13 +5,18 @@ import { useCallback, useState } from "react";
|
|||
// test videos: https://gist.github.com/jsturgis/3b19447b304616f18657
|
||||
|
||||
// TODO video todos:
|
||||
// - make pretty
|
||||
// - improve seekables
|
||||
// - improve seekables (if possible)
|
||||
// - error handling
|
||||
// - 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
|
||||
// - volume control flashes old value when updating
|
||||
// - progress control flashes old value when updating
|
||||
// - captions
|
||||
// - backdrop better click handling
|
||||
// - IOS support: (no volume, fullscreen video element instead of wrapper)
|
||||
// - IpadOS support: (fullscreen video wrapper should work, see (lookmovie.io) )
|
||||
// - HLS support: feature detection otherwise use HLS.js
|
||||
|
|
Loading…
Reference in a new issue