Spaces:
Sleeping
Sleeping
copilot-swe-agent[bot] ArnavSingh76533 commited on
Commit ·
359e4b6
1
Parent(s): be73381
Implement features 4-5: PiP and music mode
Browse filesCo-authored-by: ArnavSingh76533 <160649079+ArnavSingh76533@users.noreply.github.com>
- components/icon/IconPip.tsx +15 -0
- components/player/Controls.tsx +36 -0
- components/player/Player.tsx +20 -1
components/icon/IconPip.tsx
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { FC } from "react"
|
| 2 |
+
import Icon, { IconProps } from "./Icon"
|
| 3 |
+
|
| 4 |
+
const IconPip: FC<IconProps> = ({ className = "" }) => {
|
| 5 |
+
return (
|
| 6 |
+
<Icon className={className} viewBox='0 0 24 24'>
|
| 7 |
+
<path
|
| 8 |
+
fill='currentColor'
|
| 9 |
+
d='M19 7h-8v6h8V7zm2-4H3c-1.1 0-2 .9-2 2v14c0 1.1.9 1.98 2 1.98h18c1.1 0 2-.88 2-1.98V5c0-1.1-.9-2-2-2zm0 16.01H3V4.98h18v14.03z'
|
| 10 |
+
/>
|
| 11 |
+
</Icon>
|
| 12 |
+
)
|
| 13 |
+
}
|
| 14 |
+
|
| 15 |
+
export default IconPip
|
components/player/Controls.tsx
CHANGED
|
@@ -19,6 +19,8 @@ import PlayerMenu from "./PlayerMenu"
|
|
| 19 |
import { Tooltip } from "react-tooltip"
|
| 20 |
import IconNewTab from "../icon/IconNewTab"
|
| 21 |
import Link from "next/link"
|
|
|
|
|
|
|
| 22 |
|
| 23 |
interface Props extends PlayerState {
|
| 24 |
roomId: string
|
|
@@ -35,6 +37,10 @@ interface Props extends PlayerState {
|
|
| 35 |
setSeeking: (seeking: boolean) => void
|
| 36 |
playAgain: () => void
|
| 37 |
isOwner: boolean
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
}
|
| 39 |
|
| 40 |
let interaction = false
|
|
@@ -69,6 +75,10 @@ const Controls: FC<Props> = ({
|
|
| 69 |
setSeeking,
|
| 70 |
playAgain,
|
| 71 |
isOwner,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 72 |
}) => {
|
| 73 |
const [showControls, setShowControls] = useState(true)
|
| 74 |
const [showTimePlayed, setShowTimePlayed] = useState(true)
|
|
@@ -280,6 +290,32 @@ const Controls: FC<Props> = ({
|
|
| 280 |
setMenuOpen={setMenuOpen}
|
| 281 |
/>
|
| 282 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 283 |
<ControlButton
|
| 284 |
tooltip={fullscreen ? "Leave fullscreen" : "Enter fullscreen"}
|
| 285 |
onClick={() => {
|
|
|
|
| 19 |
import { Tooltip } from "react-tooltip"
|
| 20 |
import IconNewTab from "../icon/IconNewTab"
|
| 21 |
import Link from "next/link"
|
| 22 |
+
import IconMusic from "../icon/IconMusic"
|
| 23 |
+
import IconPip from "../icon/IconPip"
|
| 24 |
|
| 25 |
interface Props extends PlayerState {
|
| 26 |
roomId: string
|
|
|
|
| 37 |
setSeeking: (seeking: boolean) => void
|
| 38 |
playAgain: () => void
|
| 39 |
isOwner: boolean
|
| 40 |
+
pipEnabled: boolean
|
| 41 |
+
setPipEnabled: (enabled: boolean) => void
|
| 42 |
+
musicMode: boolean
|
| 43 |
+
setMusicMode: (enabled: boolean) => void
|
| 44 |
}
|
| 45 |
|
| 46 |
let interaction = false
|
|
|
|
| 75 |
setSeeking,
|
| 76 |
playAgain,
|
| 77 |
isOwner,
|
| 78 |
+
pipEnabled,
|
| 79 |
+
setPipEnabled,
|
| 80 |
+
musicMode,
|
| 81 |
+
setMusicMode,
|
| 82 |
}) => {
|
| 83 |
const [showControls, setShowControls] = useState(true)
|
| 84 |
const [showTimePlayed, setShowTimePlayed] = useState(true)
|
|
|
|
| 290 |
setMenuOpen={setMenuOpen}
|
| 291 |
/>
|
| 292 |
|
| 293 |
+
<ControlButton
|
| 294 |
+
tooltip={musicMode ? "Exit music mode" : "Enter music mode"}
|
| 295 |
+
onClick={() => {
|
| 296 |
+
setMusicMode(!musicMode)
|
| 297 |
+
if (!musicMode && pipEnabled) {
|
| 298 |
+
setPipEnabled(false)
|
| 299 |
+
}
|
| 300 |
+
}}
|
| 301 |
+
interaction={showControlsAction}
|
| 302 |
+
>
|
| 303 |
+
<IconMusic />
|
| 304 |
+
</ControlButton>
|
| 305 |
+
|
| 306 |
+
<ControlButton
|
| 307 |
+
tooltip={pipEnabled ? "Exit PiP" : "Enter PiP"}
|
| 308 |
+
onClick={() => {
|
| 309 |
+
setPipEnabled(!pipEnabled)
|
| 310 |
+
if (!pipEnabled && musicMode) {
|
| 311 |
+
setMusicMode(false)
|
| 312 |
+
}
|
| 313 |
+
}}
|
| 314 |
+
interaction={showControlsAction}
|
| 315 |
+
>
|
| 316 |
+
<IconPip />
|
| 317 |
+
</ControlButton>
|
| 318 |
+
|
| 319 |
<ControlButton
|
| 320 |
tooltip={fullscreen ? "Leave fullscreen" : "Enter fullscreen"}
|
| 321 |
onClick={() => {
|
components/player/Player.tsx
CHANGED
|
@@ -130,6 +130,8 @@ const Player: FC<Props> = ({ roomId, socket, fullHeight }) => {
|
|
| 130 |
const [connected, setConnected] = useState(false)
|
| 131 |
const [unmuted, setUnmuted] = useState(false)
|
| 132 |
const [fullscreen, setFullscreen] = useState(false)
|
|
|
|
|
|
|
| 133 |
const fullscreenHandle = useFullScreenHandle()
|
| 134 |
const player = useRef<ReactPlayer>(null)
|
| 135 |
|
|
@@ -251,9 +253,22 @@ const Player: FC<Props> = ({ roomId, socket, fullHeight }) => {
|
|
| 251 |
}
|
| 252 |
}}
|
| 253 |
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 254 |
<ReactPlayer
|
| 255 |
style={{
|
| 256 |
maxHeight: fullscreen || fullHeight ? "100vh" : "calc(100vh - 210px)",
|
|
|
|
|
|
|
| 257 |
}}
|
| 258 |
ref={player}
|
| 259 |
width={"100%"}
|
|
@@ -273,7 +288,7 @@ const Player: FC<Props> = ({ roomId, socket, fullHeight }) => {
|
|
| 273 |
},
|
| 274 |
}}
|
| 275 |
url={currentSrc.src}
|
| 276 |
-
pip={
|
| 277 |
playing={!paused}
|
| 278 |
controls={false}
|
| 279 |
loop={loop}
|
|
@@ -428,6 +443,10 @@ const Player: FC<Props> = ({ roomId, socket, fullHeight }) => {
|
|
| 428 |
error={error}
|
| 429 |
playAgain={() => socket?.emit("playAgain")}
|
| 430 |
isOwner={isOwner}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 431 |
/>
|
| 432 |
|
| 433 |
<div className={"absolute top-1 left-1 flex flex-col gap-1 p-1"}>
|
|
|
|
| 130 |
const [connected, setConnected] = useState(false)
|
| 131 |
const [unmuted, setUnmuted] = useState(false)
|
| 132 |
const [fullscreen, setFullscreen] = useState(false)
|
| 133 |
+
const [pipEnabled, setPipEnabled] = useState(false)
|
| 134 |
+
const [musicMode, setMusicMode] = useState(false)
|
| 135 |
const fullscreenHandle = useFullScreenHandle()
|
| 136 |
const player = useRef<ReactPlayer>(null)
|
| 137 |
|
|
|
|
| 253 |
}
|
| 254 |
}}
|
| 255 |
>
|
| 256 |
+
{musicMode && (
|
| 257 |
+
<div className="absolute inset-0 flex items-center justify-center bg-gradient-to-br from-primary-900 to-dark-900">
|
| 258 |
+
<div className="flex flex-col items-center gap-4 text-primary-300">
|
| 259 |
+
<svg className="w-32 h-32" fill="currentColor" viewBox="0 0 512 512">
|
| 260 |
+
<path d='M470.38 1.51L150.41 96A32 32 0 0 0 128 126.51v261.41A139 139 0 0 0 96 384c-53 0-96 28.66-96 64s43 64 96 64 96-28.66 96-64V214.32l256-75v184.61a138.4 138.4 0 0 0-32-3.93c-53 0-96 28.66-96 64s43 64 96 64 96-28.65 96-64V32a32 32 0 0 0-41.62-30.49z' />
|
| 261 |
+
</svg>
|
| 262 |
+
<div className="text-2xl font-semibold">Music Mode</div>
|
| 263 |
+
<div className="text-sm text-primary-400">Audio continues playing</div>
|
| 264 |
+
</div>
|
| 265 |
+
</div>
|
| 266 |
+
)}
|
| 267 |
<ReactPlayer
|
| 268 |
style={{
|
| 269 |
maxHeight: fullscreen || fullHeight ? "100vh" : "calc(100vh - 210px)",
|
| 270 |
+
visibility: musicMode ? "hidden" : "visible",
|
| 271 |
+
height: musicMode ? "0px" : (fullscreen || fullHeight ? "100vh" : "calc((9 / 16) * 100vw)"),
|
| 272 |
}}
|
| 273 |
ref={player}
|
| 274 |
width={"100%"}
|
|
|
|
| 288 |
},
|
| 289 |
}}
|
| 290 |
url={currentSrc.src}
|
| 291 |
+
pip={pipEnabled}
|
| 292 |
playing={!paused}
|
| 293 |
controls={false}
|
| 294 |
loop={loop}
|
|
|
|
| 443 |
error={error}
|
| 444 |
playAgain={() => socket?.emit("playAgain")}
|
| 445 |
isOwner={isOwner}
|
| 446 |
+
pipEnabled={pipEnabled}
|
| 447 |
+
setPipEnabled={setPipEnabled}
|
| 448 |
+
musicMode={musicMode}
|
| 449 |
+
setMusicMode={setMusicMode}
|
| 450 |
/>
|
| 451 |
|
| 452 |
<div className={"absolute top-1 left-1 flex flex-col gap-1 p-1"}>
|