Skip to content

Commit 453907e

Browse files
committed
feat: Quality picker in player page
1 parent dbb8c52 commit 453907e

File tree

1 file changed

+41
-9
lines changed

1 file changed

+41
-9
lines changed

packages/app/src/components/PlayerControls.tsx

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,15 @@ import type { ReactNode, RefObject } from "react";
1010
export function PlayerControls() {
1111
return (
1212
<div className="flex flex-col gap-4 overflow-hidden">
13-
<div className="flex justify-center">
13+
<div className="flex justify-center items-center">
1414
<PlayButton />
15+
<div className="ml-auto max-w-64 w-full">
16+
<Qualities />
17+
</div>
1518
</div>
1619
<div className="p-3 rounded-md bg-default-100">
17-
<Time />
1820
<Seekbar />
21+
<Time />
1922
</div>
2023
<Tracks />
2124
</div>
@@ -78,31 +81,37 @@ function Seekbar() {
7881
}
7982

8083
return (
81-
<div {...seekbar.rootProps} className="w-full relative cursor-pointer">
84+
<div {...seekbar.rootProps} className="w-full relative cursor-pointer py-2">
8285
<Tooltip
8386
x={seekbar.x}
8487
seekbarRef={seekbar.rootProps.ref}
8588
visible={seekbar.active}
8689
>
8790
{hms(seekbar.value)}
8891
</Tooltip>
89-
<div className="relative flex items-center">
90-
<div className="h-2 bg-default-200 w-full" />
92+
<div className="relative flex items-center h-1">
93+
<div className="h-1 bg-default-200 w-full" />
9194
<div
9295
className={cn(
93-
"h-2 absolute left-0 right-0 bg-default-300 origin-left opacity-0 transition-opacity",
96+
"h-1 absolute left-0 right-0 bg-default-300 origin-left opacity-0 transition-opacity",
9497
seekbar.hover && "opacity-100",
9598
)}
9699
style={{
97100
transform: `scaleX(${seekbar.x})`,
98101
}}
99102
/>
100103
<div
101-
className={cn("h-2 absolute left-0 right-0 bg-black origin-left")}
104+
className={cn("h-1 absolute left-0 right-0 bg-black origin-left")}
102105
style={{
103106
transform: `scaleX(${percentage})`,
104107
}}
105108
/>
109+
<div
110+
className="h-4 absolute w-[3px] bg-black rounded-full -translate-x-1/2 outline-default-100 outline outline-2 z-10"
111+
style={{
112+
left: `${percentage * 100}%`,
113+
}}
114+
/>
106115
</div>
107116
<CuePoints />
108117
</div>
@@ -137,7 +146,7 @@ function Tooltip({
137146
<div
138147
ref={ref}
139148
className={cn(
140-
"pointer-events-none absolute h-6 -top-8 -translate-x-1/2 opacity-0 transition-opacity text-xs text-white bg-black px-1 flex items-center rounded-md",
149+
"pointer-events-none absolute h-6 -top-6 -translate-x-1/2 opacity-0 transition-opacity text-xs text-white bg-black px-1 flex items-center rounded-md",
141150
visible && "opacity-100",
142151
)}
143152
style={{
@@ -155,7 +164,7 @@ function CuePoints() {
155164
const seekableStart = usePlayerSelector((player) => player.seekableStart);
156165

157166
return (
158-
<div className="relative h-4 bg-gray-100 rounded-lg">
167+
<div className="relative h-4">
159168
{cuePoints.map((cuePoint) => {
160169
return (
161170
<div
@@ -227,6 +236,29 @@ function Tracks() {
227236
);
228237
}
229238

239+
function Qualities() {
240+
const qualities = usePlayerSelector((player) => player.qualities);
241+
const autoQuality = usePlayerSelector((player) => player.autoQuality);
242+
const setQuality = usePlayerSelector((player) => player.setQuality);
243+
244+
return (
245+
<Selection
246+
items={[
247+
...qualities,
248+
{
249+
height: null,
250+
active: autoQuality,
251+
},
252+
]}
253+
label="Quality"
254+
getActive={(item) => item.active}
255+
getKey={(item) => item.height}
256+
getLabel={(item) => item.height?.toString() ?? "Auto"}
257+
onChange={(item) => setQuality(item.height)}
258+
/>
259+
);
260+
}
261+
230262
function hms(seconds: number) {
231263
return (
232264
new Date(seconds * 1000).toUTCString().match(/(\d\d:\d\d:\d\d)/)?.[0] ??

0 commit comments

Comments
 (0)