From 84ad154bd48c3b7fa5e2d1428905a918f1a66bd9 Mon Sep 17 00:00:00 2001 From: ThisBirchWood Date: Fri, 23 May 2025 10:53:52 +0200 Subject: [PATCH] ADD custom play controls --- package-lock.json | 10 +++ package.json | 6 +- src/main/frontend/components/Playbar.tsx | 82 ++++++++++++++++++++++++ src/main/frontend/views/video/{id}.tsx | 1 + 4 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 src/main/frontend/components/Playbar.tsx diff --git a/package-lock.json b/package-lock.json index e04a12f..4d14ea6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,6 +27,7 @@ "construct-style-sheets-polyfill": "3.1.0", "date-fns": "2.29.3", "lit": "3.3.0", + "lucide-react": "^0.511.0", "react": "18.3.1", "react-dom": "18.3.1", "react-player": "^2.16.0", @@ -7764,6 +7765,15 @@ "yallist": "^3.0.2" } }, + "node_modules/lucide-react": { + "version": "0.511.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.511.0.tgz", + "integrity": "sha512-VK5a2ydJ7xm8GvBeKLS9mu1pVK6ucef9780JVUjw6bAjJL/QXnd4Y0p7SPeOUMC27YhzNCZvm5d/QX0Tp3rc0w==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/magic-string": { "version": "0.30.17", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", diff --git a/package.json b/package.json index 2b93a07..9a73bdb 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,7 @@ "construct-style-sheets-polyfill": "3.1.0", "date-fns": "2.29.3", "lit": "3.3.0", + "lucide-react": "^0.511.0", "react": "18.3.1", "react-dom": "18.3.1", "react-player": "^2.16.0", @@ -124,7 +125,7 @@ "workbox-core": "7.3.0", "workbox-precaching": "7.3.0" }, - "hash": "6691688a44297a5558ef37db2e66ab96a2b26de25ce9dd16419318e19f092916" + "hash": "1d057234cd785dc523e68f6ac1cfce6362e77ff83cc8e5f2a36003d75fe127ea" }, "type": "module", "overrides": { @@ -156,6 +157,7 @@ "react-router-dom": "$react-router-dom", "react-player": "$react-player", "react-range-slider-input": "$react-range-slider-input", - "react-slider": "$react-slider" + "react-slider": "$react-slider", + "lucide-react": "$lucide-react" } } \ No newline at end of file diff --git a/src/main/frontend/components/Playbar.tsx b/src/main/frontend/components/Playbar.tsx new file mode 100644 index 0000000..49288cc --- /dev/null +++ b/src/main/frontend/components/Playbar.tsx @@ -0,0 +1,82 @@ +import {ChangeEventHandler, useEffect, useState} from "react"; +import { Volume, Play, Pause } from 'lucide-react'; + +type Props = { + video: HTMLVideoElement | null; +}; + +function formatTime(seconds: number): string { + const h = Math.floor(seconds / 3600); + const m = Math.floor((seconds % 3600) / 60); + const s = Math.floor(seconds % 60); + + const padded = (n: number) => n.toString().padStart(2, '0'); + + if (h > 0) { + return `${h}:${padded(m)}:${padded(s)}`; + } else { + return `${m}:${padded(s)}`; + } +} + +export default function Playbar({ video }: Props) { + const [isPlaying, setIsPlaying] = useState(false); + const [volume, setVolume] = useState(100); + + const togglePlay = () => { + if (!video) return; + + if (video.paused) { + video.play(); + setIsPlaying(true); + } else { + video.pause(); + setIsPlaying(false); + } + }; + + const updateVolume = (e: React.ChangeEvent) => { + if (!video) return; + + video.volume = parseInt(e.target.value) / 100; + setVolume(parseInt(e.target.value)); + } + + // Sync state with video element changes (e.g., if someone presses spacebar or clicks on the video) + useEffect(() => { + if (!video) return; + + const handlePlay = () => setIsPlaying(true); + const handlePause = () => setIsPlaying(false); + + video.addEventListener("play", handlePlay); + video.addEventListener("pause", handlePause); + + return () => { + video.removeEventListener("play", handlePlay); + video.removeEventListener("pause", handlePause); + }; + }, [video]); + + return ( +
+
+ + +
+ + +
+ ); +} \ No newline at end of file diff --git a/src/main/frontend/views/video/{id}.tsx b/src/main/frontend/views/video/{id}.tsx index 87e312c..6777c81 100644 --- a/src/main/frontend/views/video/{id}.tsx +++ b/src/main/frontend/views/video/{id}.tsx @@ -90,6 +90,7 @@ export default function VideoId() { {metadata &&
+