Better segment clicking (#10321)

* better segment clicking on motion segments

* move handlebar on click when handlebar is showing

* only scroll handlebar if needed
This commit is contained in:
Josh Hawkins 2024-03-07 22:02:29 -06:00 committed by GitHub
parent 507c6afa2c
commit dfab850b61
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 34 additions and 18 deletions

View File

@ -97,6 +97,7 @@ export function EventReviewTimeline({
minimapEndTime={minimapEndTime} minimapEndTime={minimapEndTime}
severityType={severityType} severityType={severityType}
contentRef={contentRef} contentRef={contentRef}
setHandlebarTime={setHandlebarTime}
/> />
); );
}); });

View File

@ -29,6 +29,7 @@ type EventSegmentProps = {
minimapEndTime?: number; minimapEndTime?: number;
severityType: ReviewSeverity; severityType: ReviewSeverity;
contentRef: RefObject<HTMLDivElement>; contentRef: RefObject<HTMLDivElement>;
setHandlebarTime?: React.Dispatch<React.SetStateAction<number>>;
}; };
export function EventSegment({ export function EventSegment({
@ -41,6 +42,7 @@ export function EventSegment({
minimapEndTime, minimapEndTime,
severityType, severityType,
contentRef, contentRef,
setHandlebarTime,
}: EventSegmentProps) { }: EventSegmentProps) {
const { const {
getSeverity, getSeverity,
@ -192,6 +194,10 @@ export function EventSegment({
element.classList.add("outline-0", "shadow-none"); element.classList.add("outline-0", "shadow-none");
}, 3000); }, 3000);
} }
if (setHandlebarTime) {
setHandlebarTime(startTimestamp);
}
} }
// we know that these deps are correct // we know that these deps are correct
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps

View File

@ -82,6 +82,19 @@ export function MotionSegment({
return isMobile ? 30 : 50; return isMobile ? 30 : 50;
}, []); }, []);
const segmentWidth = useMemo(() => {
return interpolateMotionAudioData(
getMotionSegmentValue(segmentTime + segmentDuration / 2),
maxSegmentWidth,
);
}, [
segmentTime,
segmentDuration,
maxSegmentWidth,
getMotionSegmentValue,
interpolateMotionAudioData,
]);
const alignedMinimapStartTime = useMemo( const alignedMinimapStartTime = useMemo(
() => alignStartDateToTimeline(minimapStartTime ?? 0), () => alignStartDateToTimeline(minimapStartTime ?? 0),
[minimapStartTime, alignStartDateToTimeline], [minimapStartTime, alignStartDateToTimeline],
@ -154,13 +167,18 @@ export function MotionSegment({
}; };
const segmentClick = useCallback(() => { const segmentClick = useCallback(() => {
if (startTimestamp && setHandlebarTime) { if (startTimestamp && setHandlebarTime && segmentWidth > 1) {
setHandlebarTime(startTimestamp); setHandlebarTime(startTimestamp);
} }
}, [startTimestamp, setHandlebarTime]); }, [startTimestamp, setHandlebarTime, segmentWidth]);
return ( return (
<div key={segmentKey} className={segmentClasses}> <div
key={segmentKey}
className={segmentClasses}
onClick={segmentClick}
onTouchStart={(event) => handleTouchStart(event, segmentClick)}
>
<MinimapBounds <MinimapBounds
isFirstSegmentInMinimap={isFirstSegmentInMinimap} isFirstSegmentInMinimap={isFirstSegmentInMinimap}
isLastSegmentInMinimap={isLastSegmentInMinimap} isLastSegmentInMinimap={isLastSegmentInMinimap}
@ -185,13 +203,8 @@ export function MotionSegment({
<div <div
key={`${segmentKey}_motion_data_1`} key={`${segmentKey}_motion_data_1`}
className={`h-[2px] rounded-full bg-motion_review`} className={`h-[2px] rounded-full bg-motion_review`}
onClick={segmentClick}
onTouchStart={(event) => handleTouchStart(event, segmentClick)}
style={{ style={{
width: interpolateMotionAudioData( width: segmentWidth,
getMotionSegmentValue(segmentTime + segmentDuration / 2),
maxSegmentWidth,
),
}} }}
></div> ></div>
</div> </div>
@ -202,13 +215,8 @@ export function MotionSegment({
<div <div
key={`${segmentKey}_motion_data_2`} key={`${segmentKey}_motion_data_2`}
className={`h-[2px] rounded-full bg-motion_review`} className={`h-[2px] rounded-full bg-motion_review`}
onClick={segmentClick}
onTouchStart={(event) => handleTouchStart(event, segmentClick)}
style={{ style={{
width: interpolateMotionAudioData( width: segmentWidth,
getMotionSegmentValue(segmentTime),
maxSegmentWidth,
),
}} }}
></div> ></div>
</div> </div>

View File

@ -130,6 +130,7 @@ function useDraggableHandler({
scrollIntoView(thumb, { scrollIntoView(thumb, {
block: "center", block: "center",
behavior: "smooth", behavior: "smooth",
scrollMode: "if-needed",
}); });
} }
} }

View File

@ -43,7 +43,7 @@ export const useMotionSegmentUtils = (
const matchingEvent = motion_events.find((event) => { const matchingEvent = motion_events.find((event) => {
return ( return (
time >= getSegmentStart(event.start_time) && time >= getSegmentStart(event.start_time) &&
time < getSegmentEnd(event.start_time) time <= getSegmentEnd(event.start_time)
); );
}); });

View File

@ -124,7 +124,7 @@ function UIPlayground() {
const [mockEvents, setMockEvents] = useState<ReviewSegment[]>([]); const [mockEvents, setMockEvents] = useState<ReviewSegment[]>([]);
const [mockMotionData, setMockMotionData] = useState<MotionData[]>([]); const [mockMotionData, setMockMotionData] = useState<MotionData[]>([]);
const [handlebarTime, setHandlebarTime] = useState( const [handlebarTime, setHandlebarTime] = useState(
Math.floor(Date.now() / 1000) - 15 * 60, Math.round((Date.now() / 1000 - 15 * 60) / 60) * 60,
); );
useMemo(() => { useMemo(() => {
@ -285,7 +285,7 @@ function UIPlayground() {
<MotionReviewTimeline <MotionReviewTimeline
segmentDuration={zoomSettings.segmentDuration} // seconds per segment segmentDuration={zoomSettings.segmentDuration} // seconds per segment
timestampSpread={zoomSettings.timestampSpread} // minutes between each major timestamp timestampSpread={zoomSettings.timestampSpread} // minutes between each major timestamp
timelineStart={Math.floor(Date.now() / 1000)} // timestamp start of the timeline - the earlier time timelineStart={Math.round(((Date.now() / 1000) * 60) / 60) * 60} // timestamp start of the timeline - the earlier time
timelineEnd={Math.floor(Date.now() / 1000) - 6 * 60 * 60} // end of timeline - the later time timelineEnd={Math.floor(Date.now() / 1000) - 6 * 60 * 60} // end of timeline - the later time
showHandlebar // show / hide the handlebar showHandlebar // show / hide the handlebar
handlebarTime={handlebarTime} // set the time of the handlebar handlebarTime={handlebarTime} // set the time of the handlebar