From d88a12a61608e42c557856b854c4254c061b98de Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Tue, 27 Feb 2024 09:51:41 -0600 Subject: [PATCH] hover thumbnails --- .../timeline/EventReviewTimeline.tsx | 60 +++++++++------- web/src/components/timeline/EventSegment.tsx | 72 ++++++++++++------- web/src/hooks/use-segment-utils.ts | 54 ++++++++++---- 3 files changed, 121 insertions(+), 65 deletions(-) diff --git a/web/src/components/timeline/EventReviewTimeline.tsx b/web/src/components/timeline/EventReviewTimeline.tsx index d8c3a3250..428a9ec37 100644 --- a/web/src/components/timeline/EventReviewTimeline.tsx +++ b/web/src/components/timeline/EventReviewTimeline.tsx @@ -10,6 +10,7 @@ import { import EventSegment from "./EventSegment"; import { useEventUtils } from "@/hooks/use-event-utils"; import { ReviewSegment, ReviewSeverity } from "@/types/review"; +import { TooltipProvider } from "../ui/tooltip"; export type EventReviewTimelineProps = { segmentDuration: number; @@ -212,39 +213,44 @@ export function EventReviewTimeline({ ]); return ( -
-
{segments}
- {showHandlebar && ( -
-
-
+ +
+
{segments}
+ {showHandlebar && ( +
+
+ className={`bg-destructive rounded-full mx-auto ${ + segmentDuration < 60 ? "w-20" : "w-16" + } h-5 flex items-center justify-center`} + > +
+
+
-
-
- )} -
+ )} +
+ ); } diff --git a/web/src/components/timeline/EventSegment.tsx b/web/src/components/timeline/EventSegment.tsx index da9b3aa61..30b11e200 100644 --- a/web/src/components/timeline/EventSegment.tsx +++ b/web/src/components/timeline/EventSegment.tsx @@ -1,3 +1,4 @@ +import { useApiHost } from "@/api"; import { useEventUtils } from "@/hooks/use-event-utils"; import { useSegmentUtils } from "@/hooks/use-segment-utils"; import { ReviewSegment, ReviewSeverity } from "@/types/review"; @@ -8,6 +9,8 @@ import React, { useMemo, useRef, } from "react"; +import { Tooltip, TooltipContent } from "../ui/tooltip"; +import { TooltipTrigger } from "@radix-ui/react-tooltip"; type EventSegmentProps = { events: ReviewSegment[]; @@ -146,6 +149,7 @@ export function EventSegment({ displaySeverityType, shouldShowRoundedCorners, getEventStart, + getEventThumbnail, } = useSegmentUtils(segmentDuration, events, severityType); const { alignDateToTimeline } = useEventUtils(events, segmentDuration); @@ -154,22 +158,35 @@ export function EventSegment({ () => getSeverity(segmentTime, displaySeverityType), [getSeverity, segmentTime] ); + const reviewed = useMemo( () => getReviewed(segmentTime), [getReviewed, segmentTime] ); - const { roundTop, roundBottom } = useMemo( + + const { + roundTopPrimary, + roundBottomPrimary, + roundTopSecondary, + roundBottomSecondary, + } = useMemo( () => shouldShowRoundedCorners(segmentTime), [shouldShowRoundedCorners, segmentTime] ); + const startTimestamp = useMemo(() => { const eventStart = getEventStart(segmentTime); if (eventStart) { - console.log("event start: " + new Date(eventStart * 1000)); return alignDateToTimeline(eventStart); } }, [getEventStart, segmentTime]); + const apiHost = useApiHost(); + + const eventThumbnail = useMemo(() => { + return getEventThumbnail(segmentTime); + }, [getEventThumbnail, segmentTime]); + const timestamp = useMemo(() => new Date(segmentTime * 1000), [segmentTime]); const segmentKey = useMemo(() => segmentTime, [segmentTime]); @@ -247,7 +264,6 @@ export function EventSegment({ const segmentClick = useCallback(() => { if (contentRef.current && startTimestamp) { - console.log(new Date(startTimestamp * 1000)); const element = contentRef.current.querySelector( `[data-segment-start="${startTimestamp - segmentDuration}"]` ); @@ -297,23 +313,31 @@ export function EventSegment({ {severity.map((severityValue, index) => ( {severityValue === displaySeverityType && ( -
+
{ - segmentClick(); - }} - >
-
+ className="mr-3 w-[8px] h-2 flex justify-left items-end" + data-severity={severityValue} + > + +
+
+ + + +
+ )} {severityValue !== displaySeverityType && ( @@ -321,11 +345,11 @@ export function EventSegment({
)} diff --git a/web/src/hooks/use-segment-utils.ts b/web/src/hooks/use-segment-utils.ts index 60da2fb35..57025a42b 100644 --- a/web/src/hooks/use-segment-utils.ts +++ b/web/src/hooks/use-segment-utils.ts @@ -84,7 +84,14 @@ export const useSegmentUtils = ( ); const shouldShowRoundedCorners = useCallback( - (segmentTime: number): { roundTop: boolean; roundBottom: boolean } => { + ( + segmentTime: number + ): { + roundTopPrimary: boolean; + roundBottomPrimary: boolean; + roundTopSecondary: boolean; + roundBottomSecondary: boolean; + } => { const prevSegmentTime = segmentTime - segmentDuration; const nextSegmentTime = segmentTime + segmentDuration; @@ -134,23 +141,26 @@ export const useSegmentUtils = ( ); }); - let roundTop = false; - let roundBottom = false; + let roundTopPrimary = false; + let roundBottomPrimary = false; + let roundTopSecondary = false; + let roundBottomSecondary = false; if (hasOverlappingSeverityEvent) { - roundBottom = !hasPrevSeverityEvent; - roundTop = !hasNextSeverityEvent; - } else if (hasOverlappingOtherEvent) { - roundBottom = !hasPrevOtherEvent; - roundTop = !hasNextOtherEvent; - } else { - roundTop = !hasNextSeverityEvent || !hasNextOtherEvent; - roundBottom = !hasPrevSeverityEvent || !hasPrevOtherEvent; + roundBottomPrimary = !hasPrevSeverityEvent; + roundTopPrimary = !hasNextSeverityEvent; + } + + if (hasOverlappingOtherEvent) { + roundBottomSecondary = !hasPrevOtherEvent; + roundTopSecondary = !hasNextOtherEvent; } return { - roundTop, - roundBottom, + roundTopPrimary, + roundBottomPrimary, + roundTopSecondary, + roundBottomSecondary, }; }, [events, getSegmentStart, getSegmentEnd, segmentDuration, severityType] @@ -171,6 +181,21 @@ export const useSegmentUtils = ( [events, getSegmentStart, getSegmentEnd, severityType] ); + const getEventThumbnail = useCallback( + (time: number): string => { + const matchingEvent = events.find((event) => { + return ( + time >= getSegmentStart(event.start_time) && + time < getSegmentEnd(event.end_time) && + event.severity == severityType + ); + }); + + return matchingEvent?.thumb_path ?? ""; + }, + [events, getSegmentStart, getSegmentEnd, severityType] + ); + return { getSegmentStart, getSegmentEnd, @@ -179,5 +204,6 @@ export const useSegmentUtils = ( getReviewed, shouldShowRoundedCorners, getEventStart, + getEventThumbnail }; -}; \ No newline at end of file +};