From 16d81de5e17a37c27f8dfddea2480a9fb9a8ffad Mon Sep 17 00:00:00 2001 From: Nicolas Mowen Date: Wed, 21 Feb 2024 11:30:59 -0700 Subject: [PATCH] Rework scrolling to fix nested scrolling --- web/src/App.tsx | 4 +- web/src/components/Wrapper.tsx | 2 +- .../player/PreviewThumbnailPlayer.tsx | 40 +++++++++++++++---- .../timeline/EventReviewTimeline.tsx | 2 +- web/src/hooks/use-segment-utils.ts | 39 ++++++++++++------ web/src/pages/Live.tsx | 4 +- web/src/views/events/DesktopEventView.tsx | 27 +++++++++++-- web/src/views/events/MobileEventView.tsx | 12 +++--- 8 files changed, 93 insertions(+), 37 deletions(-) diff --git a/web/src/App.tsx b/web/src/App.tsx index 0639a03a2..4ef41b0ed 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -28,11 +28,11 @@ function App() {
-
+
} /> diff --git a/web/src/components/Wrapper.tsx b/web/src/components/Wrapper.tsx index e9920b76b..0726d280e 100644 --- a/web/src/components/Wrapper.tsx +++ b/web/src/components/Wrapper.tsx @@ -5,7 +5,7 @@ type TWrapperProps = { }; const Wrapper = ({ children }: TWrapperProps) => { - return
{children}
; + return
{children}
; }; export default Wrapper; diff --git a/web/src/components/player/PreviewThumbnailPlayer.tsx b/web/src/components/player/PreviewThumbnailPlayer.tsx index 6011e1ee3..97050d3ed 100644 --- a/web/src/components/player/PreviewThumbnailPlayer.tsx +++ b/web/src/components/player/PreviewThumbnailPlayer.tsx @@ -1,5 +1,11 @@ import VideoPlayer from "./VideoPlayer"; -import React, { useCallback, useMemo, useRef, useState } from "react"; +import React, { + useCallback, + useEffect, + useMemo, + useRef, + useState, +} from "react"; import { useApiHost } from "@/api"; import Player from "video.js/dist/types/player"; import { formatUnixTimestampToDateTime } from "@/utils/dateUtil"; @@ -37,14 +43,34 @@ export default function PreviewThumbnailPlayer({ const playerRef = useRef(null); const [hoverTimeout, setHoverTimeout] = useState(); - const [hover, setHover] = useState(false); + const [playback, setPlayback] = useState(false); const [progress, setProgress] = useState(0); const playingBack = useMemo( - () => relevantPreview && (hover || autoPlayback), - [hover, autoPlayback, relevantPreview] + () => relevantPreview && playback, + [playback, autoPlayback, relevantPreview] ); + useEffect(() => { + if (!autoPlayback) { + setPlayback(false); + + if (hoverTimeout) { + clearTimeout(hoverTimeout); + } + return; + } + + const timeout = setTimeout(() => { + setPlayback(true); + setHoverTimeout(null); + }, 500); + + return () => { + clearTimeout(timeout); + }; + }, [autoPlayback]); + const onPlayback = useCallback( (isHovered: Boolean) => { if (!relevantPreview) { @@ -54,7 +80,7 @@ export default function PreviewThumbnailPlayer({ if (isHovered) { setHoverTimeout( setTimeout(() => { - setHover(true); + setPlayback(true); setHoverTimeout(null); }, 500) ); @@ -63,7 +89,7 @@ export default function PreviewThumbnailPlayer({ clearTimeout(hoverTimeout); } - setHover(false); + setPlayback(false); setProgress(0); if (playerRef.current) { @@ -203,7 +229,7 @@ function PreviewContent({ (player.currentTime() || 0) - playerStartTime; // end with a bit of padding - const playerDuration = (review.end_time - review.start_time) + 8; + const playerDuration = review.end_time - review.start_time + 8; const playerPercent = (playerProgress / playerDuration) * 100; if ( diff --git a/web/src/components/timeline/EventReviewTimeline.tsx b/web/src/components/timeline/EventReviewTimeline.tsx index e4f1cb866..725d0de3c 100644 --- a/web/src/components/timeline/EventReviewTimeline.tsx +++ b/web/src/components/timeline/EventReviewTimeline.tsx @@ -47,7 +47,7 @@ export function EventReviewTimeline({ const currentTimeRef = useRef(null); const observer = useRef(null); const timelineDuration = useMemo( - () => timelineEnd - timelineStart, + () => timelineStart - timelineEnd, [timelineEnd, timelineStart] ); diff --git a/web/src/hooks/use-segment-utils.ts b/web/src/hooks/use-segment-utils.ts index 873fc7f23..967bd3586 100644 --- a/web/src/hooks/use-segment-utils.ts +++ b/web/src/hooks/use-segment-utils.ts @@ -6,9 +6,12 @@ export const useSegmentUtils = ( events: ReviewSegment[], severityType: string ) => { - const getSegmentStart = useCallback((time: number): number => { - return Math.floor(time / (segmentDuration)) * (segmentDuration); - }, [segmentDuration]); + const getSegmentStart = useCallback( + (time: number): number => { + return Math.floor(time / segmentDuration) * segmentDuration; + }, + [segmentDuration] + ); const getSegmentEnd = useCallback( (time: number | undefined): number => { @@ -67,15 +70,18 @@ export const useSegmentUtils = ( [events, getSegmentStart, getSegmentEnd, mapSeverityToNumber] ); - const getReviewed = useCallback((time: number): boolean => { - return events.some((event) => { - const segmentStart = getSegmentStart(event.start_time); - const segmentEnd = getSegmentEnd(event.end_time); - return ( - time >= segmentStart && time < segmentEnd && event.has_been_reviewed - ); - }); - }, [events, getSegmentStart, getSegmentEnd]); + const getReviewed = useCallback( + (time: number): boolean => { + return events.some((event) => { + const segmentStart = getSegmentStart(event.start_time); + const segmentEnd = getSegmentEnd(event.end_time); + return ( + time >= segmentStart && time < segmentEnd && event.has_been_reviewed + ); + }); + }, + [events, getSegmentStart, getSegmentEnd] + ); const shouldShowRoundedCorners = useCallback( (segmentTime: number): { roundTop: boolean; roundBottom: boolean } => { @@ -150,5 +156,12 @@ export const useSegmentUtils = ( [events, getSegmentStart, getSegmentEnd, segmentDuration, severityType] ); - return { getSegmentStart, getSegmentEnd, getSeverity, displaySeverityType, getReviewed, shouldShowRoundedCorners }; + return { + getSegmentStart, + getSegmentEnd, + getSeverity, + displaySeverityType, + getReviewed, + shouldShowRoundedCorners, + }; }; \ No newline at end of file diff --git a/web/src/pages/Live.tsx b/web/src/pages/Live.tsx index d7d98c68c..fd13a4a9c 100644 --- a/web/src/pages/Live.tsx +++ b/web/src/pages/Live.tsx @@ -79,7 +79,7 @@ function Live() { }, []); return ( - <> +
{events && events.length > 0 && ( @@ -115,7 +115,7 @@ function Live() { ); })}
- +
); } diff --git a/web/src/views/events/DesktopEventView.tsx b/web/src/views/events/DesktopEventView.tsx index c1827f3c2..78e42e450 100644 --- a/web/src/views/events/DesktopEventView.tsx +++ b/web/src/views/events/DesktopEventView.tsx @@ -244,6 +244,8 @@ export default function DesktopEventView() { return ; } + console.log("end of the timeline is " + after + " vs " + (Math.floor(Date.now() / 1000) + 2 * 60 * 60)) + return (
@@ -329,23 +331,40 @@ export default function DesktopEventView() { })}
- + />)}
); } +/** + * + */ + function ReviewCalendarButton() { const disabledDates = useMemo(() => { const tomorrow = new Date(); diff --git a/web/src/views/events/MobileEventView.tsx b/web/src/views/events/MobileEventView.tsx index 49d7b1d98..eb4c9fb29 100644 --- a/web/src/views/events/MobileEventView.tsx +++ b/web/src/views/events/MobileEventView.tsx @@ -139,7 +139,6 @@ export default function MobileEventView() { (entries) => { entries.forEach((entry) => { const start = (entry.target as HTMLElement).dataset.start; - console.log(`${start} has been updated as intersect ${entry.isIntersecting}`) if (!start) { return; @@ -153,7 +152,8 @@ export default function MobileEventView() { setMinimap([...visibleTimestamps]); }); - }, { threshold: 0.5 } + }, + { threshold: 0.5 } ); return () => { @@ -186,8 +186,6 @@ export default function MobileEventView() { data.start = parseFloat(list[0]); } - console.log("the new times are " + JSON.stringify(data)) - return data; }, [minimap]); @@ -237,7 +235,7 @@ export default function MobileEventView() { } return ( -
+ <> {reviewItems[severity]?.map((value, segIdx) => { const lastRow = segIdx == reviewItems[severity].length - 1; @@ -308,6 +306,6 @@ export default function MobileEventView() { ); })}
-
+ ); }