diff --git a/packages/app/src/components/PlayerControls.tsx b/packages/app/src/components/PlayerControls.tsx index 6ad1132..b2f4e3d 100644 --- a/packages/app/src/components/PlayerControls.tsx +++ b/packages/app/src/components/PlayerControls.tsx @@ -1,6 +1,7 @@ -import { Button, Select, SelectItem } from "@nextui-org/react"; +import { Button } from "@nextui-org/react"; import cn from "clsx"; import { useRef } from "react"; +import { Selection } from "./Selection"; import { usePlayerSelector } from "../context/PlayerContext"; import { useSeekbar } from "../hooks/useSeekbar"; import type { ReactNode, RefObject } from "react"; @@ -11,12 +12,11 @@ export function PlayerControls() { return null; } return ( -
+
-
@@ -59,8 +59,8 @@ function Seekbar() { > {hms(seekbar.value)} -
-
+
+
+
); } @@ -109,7 +110,7 @@ function Tooltip({
player.time); const seekableStart = usePlayerSelector((player) => player.seekableStart); const duration = usePlayerSelector((player) => player.duration); + const live = usePlayerSelector((player) => player.live); return ( -
- {hms(seekableStart)} +
+ {hms(time)}
- {hms(duration)} + {live ? `${hms(seekableStart)} - ${hms(duration)}` : `${hms(duration)}`}
); } @@ -159,49 +162,37 @@ function Time() { function Tracks() { const audioTracks = usePlayerSelector((player) => player.audioTracks); const setAudioTrack = usePlayerSelector((player) => player.setAudioTrack); - const audioKey = audioTracks.find((track) => track.active)?.id.toString(); const subtitleTracks = usePlayerSelector((player) => player.subtitleTracks); const setSubtitleTrack = usePlayerSelector( (player) => player.setSubtitleTrack, ); - const subtitleKey = subtitleTracks - .find((track) => track.active) - ?.id.toString(); return (
- - - + getKey={(item) => item.id} + getLabel={(item) => item.label} + onChange={(item) => setSubtitleTrack(item.id)} + />
); } diff --git a/packages/app/src/components/Selection.tsx b/packages/app/src/components/Selection.tsx new file mode 100644 index 0000000..e206753 --- /dev/null +++ b/packages/app/src/components/Selection.tsx @@ -0,0 +1,50 @@ +import { Select, SelectItem } from "@nextui-org/react"; + +interface SelectionProps { + items: T[]; + label: string; + getKey(item: T): number | string | null; + getLabel(item: T): string; + getActive(item: T): boolean; + onChange(item: T): void; +} + +export function Selection({ + items, + label, + getKey, + getLabel, + getActive, + onChange, +}: SelectionProps) { + const selectedKeys: string[] = []; + for (const item of items) { + if (getActive(item)) { + const key = getKey(item); + selectedKeys.push(String(key)); + } + } + + return ( + + ); +} diff --git a/packages/app/src/context/PlayerContext.tsx b/packages/app/src/context/PlayerContext.tsx index f6ab41a..4168536 100644 --- a/packages/app/src/context/PlayerContext.tsx +++ b/packages/app/src/context/PlayerContext.tsx @@ -25,6 +25,14 @@ export function PlayerProvider({ children }: PlayerProviderProps) { ); } +export function WithPlayer({ children }: { children: ReactNode }) { + const { player } = usePlayer(); + if (!player) { + return null; + } + return children; +} + export function usePlayer() { const context = useContext(PlayerContext); if (!context) { diff --git a/packages/app/src/routes/(dashboard)/_layout/player.tsx b/packages/app/src/routes/(dashboard)/_layout/player.tsx index 736c51b..63e6f2e 100644 --- a/packages/app/src/routes/(dashboard)/_layout/player.tsx +++ b/packages/app/src/routes/(dashboard)/_layout/player.tsx @@ -14,14 +14,9 @@ import { Player } from "../../../components/Player"; import { PlayerControls } from "../../../components/PlayerControls"; import { PlayerStats } from "../../../components/PlayerStats"; import { ScrollCard } from "../../../components/ScrollCard"; -import { - PlayerProvider, - usePlayer, - usePlayerSelector, -} from "../../../context/PlayerContext"; +import { PlayerProvider, WithPlayer } from "../../../context/PlayerContext"; import { useSwaggerSchema } from "../../../hooks/useSwaggerSchema"; import type { FormRef } from "../../../components/Form"; -import type { RefObject } from "react"; export const Route = createFileRoute("/(dashboard)/_layout/player")({ component: RouteComponent, @@ -69,7 +64,42 @@ function RouteComponent() {
- + + + + +
{ + setUrl(values.url); + }} + /> + + + + + + + + + + + + + +
@@ -96,70 +126,3 @@ function RouteComponent() {
); } - -function HasPlayer({ - url, - setUrl, - formRef, -}: { - url: string; - setUrl: (url: string) => void; - formRef: RefObject; -}) { - const { player } = usePlayer(); - - if (!player) { - return null; - } - - return ; -} - -function PlayerTabs({ - url, - setUrl, - formRef, -}: { - url: string; - setUrl: (url: string) => void; - formRef: RefObject; -}) { - const ready = usePlayerSelector((player) => player.ready); - - return ( - - - - { - setUrl(values.url); - }} - /> - - - - - - - - - - - - - - ); -}