From a4e9ebca3b22f4622eba951ff0254a84bd7868ba Mon Sep 17 00:00:00 2001 From: Rob Watson Date: Mon, 17 Jan 2022 18:58:13 +0100 Subject: [PATCH] Update duration display on selection change --- frontend/src/App.tsx | 35 ++++++++++++++++++++++++++++++----- frontend/src/ControlBar.tsx | 20 ++++++++++++++------ frontend/src/HudCanvas.tsx | 4 ++-- frontend/src/Overview.tsx | 2 +- frontend/src/SeekBar.tsx | 4 ++-- 5 files changed, 49 insertions(+), 16 deletions(-) diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 0f980d2..8a4d63c 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -17,8 +17,9 @@ import { firstValueFrom, from, Observable } from 'rxjs'; import { first, map } from 'rxjs/operators'; import millisFromDuration from './helpers/millisFromDuration'; import { zoomViewportIn, zoomViewportOut } from './helpers/zoom'; - -import { ExternalLinkIcon } from '@heroicons/react/solid'; +import toHHMMSS from './helpers/toHHMMSS'; +import framesToDuration from './helpers/framesToDuration'; +import { ClockIcon, ExternalLinkIcon } from '@heroicons/react/solid'; // ported from backend, where should they live? const thumbnailWidth = 177; // height 100 @@ -330,8 +331,6 @@ function App(): JSX.Element { })(); }; - const zoomMultiplier = 1.777; - const handleZoomIn = () => { if (mediaSet == null) { return; @@ -392,6 +391,26 @@ function App(): JSX.Element { [mediaSet] ); + const durationString = useCallback((): string => { + if (!mediaSet || !mediaSet.videoDuration) { + return ''; + } + + const totalDur = toHHMMSS(mediaSet.videoDuration); + if (selection.start == selection.end) { + return totalDur; + } + + const clipDur = toHHMMSS( + framesToDuration( + selection.end - selection.start, + mediaSet.audioSampleRate + ) + ); + + return `Selected ${clipDur} of ${totalDur}`; + }, [mediaSet, selection]); + // render component const offsetPixels = Math.floor(thumbnailWidth / 2); @@ -408,7 +427,7 @@ function App(): JSX.Element {

Clipper

-
+
{mediaSet.author} @@ -422,6 +441,10 @@ function App(): JSX.Element { > + + + {durationString()} +
+
void; onZoomIn: () => void; onZoomOut: () => void; + downloadClipEnabled: boolean; } const ControlBar: React.FC = React.memo((props: Props) => { const buttonStyle = 'bg-gray-700 hover:bg-gray-600 text-white font-bold py-2 px-4 rounded'; - const largeButtonStyle = - 'bg-green-700 hover:bg-green-600 text-white font-bold py-2 px-4 rounded absolute right-0'; + const downloadButtonStyle = props.downloadClipEnabled + ? 'bg-green-700 hover:bg-green-600 text-white font-bold py-2 px-4 rounded absolute right-0' + : 'bg-gray-700 hover:cursor-not-allowed text-gray-500 font-bold py-2 px-4 rounded absolute right-0'; - const iconStyle = 'inline h-6 w-6 text-white-500'; + const iconStyle = 'inline h-7 w-7 text-white-500'; const playPauseComponent = props.playState == PlayState.Playing ? ( @@ -34,6 +36,12 @@ const ControlBar: React.FC = React.memo((props: Props) => { ); + const handleClip = () => { + if (props.downloadClipEnabled) { + props.onClip(); + } + }; + // Detect if the space bar has been used to trigger this event, and ignore // it if so. This conflicts with the player interface. const filterMouseEvent = (evt: React.MouseEvent, cb: () => void) => { @@ -71,11 +79,11 @@ const ControlBar: React.FC = React.memo((props: Props) => {
diff --git a/frontend/src/HudCanvas.tsx b/frontend/src/HudCanvas.tsx index d71ff40..2835d48 100644 --- a/frontend/src/HudCanvas.tsx +++ b/frontend/src/HudCanvas.tsx @@ -136,8 +136,8 @@ export const HudCanvas: React.FC = ({ ctx.strokeStyle = positionStrokeStyle; ctx.lineWidth = positionLineWidth; ctx.moveTo(position, 0); - ctx.lineWidth = 4; - ctx.lineTo(position, canvas.height - 4); + ctx.lineWidth = position == 0 ? 8 : 4; + ctx.lineTo(position, canvas.height); ctx.stroke(); }); }, [selection, newSelection, position]); diff --git a/frontend/src/Overview.tsx b/frontend/src/Overview.tsx index a755d82..1e578ad 100644 --- a/frontend/src/Overview.tsx +++ b/frontend/src/Overview.tsx @@ -77,7 +77,7 @@ export const Overview: React.FC = ({ return ( <> -
+
= ({ canvas.width = canvas.height * (canvas.clientWidth / canvas.clientHeight); // background - ctx.fillStyle = '#444444'; + ctx.fillStyle = 'transparent'; ctx.fillRect(0, 0, canvas.width, canvas.height); // seek bar @@ -119,7 +119,7 @@ export const SeekBar: React.FC = ({ return ( <>