* various tweaks

* update debounce time

* scroll to top with new events
This commit is contained in:
Josh Hawkins 2024-02-23 07:52:54 -06:00 committed by GitHub
parent fc94fcb2ac
commit 7d18c2c03d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 91 additions and 64 deletions

View File

@ -187,14 +187,7 @@ export function EventReviewTimeline({
setCurrentTimeSegment(alignedHandlebarTime);
}
}, [
handlebarTime,
segmentDuration,
showHandlebar,
timelineDuration,
timelineStart,
alignDateToTimeline,
]);
}, []);
useEffect(() => {
generateSegments();

View File

@ -186,14 +186,20 @@ export function EventSegment({
const firstMinimapSegmentRef = useRef<HTMLDivElement>(null);
let debounceTimer: ReturnType<typeof setTimeout>;
function debounceScrollIntoView(element: HTMLElement) {
clearTimeout(debounceTimer);
debounceTimer = setTimeout(() => {
element.scrollIntoView({ behavior: "smooth", block: "center" });
}, 100);
}
useEffect(() => {
// Check if the first segment is out of view
const firstSegment = firstMinimapSegmentRef.current;
if (firstSegment && showMinimap && isFirstSegmentInMinimap) {
firstSegment.scrollIntoView({
behavior: "smooth",
block: "center",
});
debounceScrollIntoView(firstSegment);
}
}, [showMinimap, isFirstSegmentInMinimap, events, segmentDuration]);

View File

@ -113,7 +113,10 @@ function useDraggableHandler({
}
});
if (setHandlebarTime) {
setHandlebarTime(timelineStart - segmentIndex * segmentDuration);
setHandlebarTime(
timelineStart -
(newHandlePosition / segmentHeight) * segmentDuration
);
}
}
}
@ -132,10 +135,10 @@ function useDraggableHandler({
// TODO: determine when we want to do this
const handlebar = scrollTimeRef.current;
if (handlebar && showHandlebar) {
// handlebar.scrollIntoView({
// behavior: "smooth",
// block: "center",
// });
handlebar.scrollIntoView({
behavior: "smooth",
block: "center",
});
}
}, []);

View File

@ -102,7 +102,7 @@ function UIPlayground() {
const contentRef = useRef<HTMLDivElement>(null);
const [mockEvents, setMockEvents] = useState<ReviewSegment[]>([]);
const [handlebarTime, setHandlebarTime] = useState(
Math.floor(Date.now() / 1000) - 7 * 60
Math.floor(Date.now() / 1000) - 15 * 60
);
const onSelect = useCallback(({ items }: { items: string[] }) => {
@ -217,7 +217,16 @@ function UIPlayground() {
<Heading as="h4" className="my-5">
Timeline
</Heading>
<p className="text-small">Handlebar timestamp: {handlebarTime}</p>
<p className="text-small">
Handlebar timestamp: {handlebarTime} -&nbsp;
{new Date(handlebarTime * 1000).toLocaleTimeString([], {
hour: "2-digit",
minute: "2-digit",
month: "short",
day: "2-digit",
second: "2-digit",
})}
</p>
<p className="text-small">
Handlebar is dragging: {isDragging ? "yes" : "no"}
</p>

View File

@ -247,58 +247,74 @@ export default function DesktopEventView({
</div>
</div>
{hasUpdate && (
<Button
className="absolute top-14 left-[50%] -translate-x-[50%] z-30 bg-gray-400 text-white"
variant="secondary"
onClick={() => {
setHasUpdate(false);
pullLatestData();
}}
>
<LuRefreshCcw className="w-4 h-4 mr-2" />
New Items To Review
</Button>
)}
<div className="flex h-full overflow-hidden">
<div
ref={contentRef}
className="flex flex-1 flex-wrap content-start gap-2 overflow-y-auto no-scrollbar"
>
{currentItems ? (
currentItems.map((value, segIdx) => {
const lastRow = segIdx == reviewItems[severity].length - 1;
const relevantPreview = Object.values(
relevantPreviews || []
).find(
(preview) =>
preview.camera == value.camera &&
preview.start < value.start_time &&
preview.end > value.end_time
);
return (
<div
key={value.id}
ref={lastRow ? lastReviewRef : minimapRef}
data-start={value.start_time}
{hasUpdate && (
<div className="absolute w-full z-30">
<div className="flex justify-center items-center mr-[100px]">
<Button
className={`${
hasUpdate
? "animate-in slide-in-from-top duration-500"
: "invisible"
} text-center mt-5 mx-auto bg-gray-400 text-white`}
variant="secondary"
onClick={() => {
setHasUpdate(false);
pullLatestData();
if (contentRef.current) {
contentRef.current.scrollTo({
top: 0,
behavior: "smooth",
});
}
}}
>
<div className="h-[234px] aspect-video rounded-lg overflow-hidden">
<PreviewThumbnailPlayer
review={value}
relevantPreview={relevantPreview}
setReviewed={() => markItemAsReviewed(value.id)}
onClick={() => onSelectReview(value.id)}
/>
</div>
{lastRow && !reachedEnd && <ActivityIndicator />}
</div>
);
})
) : (
<div ref={lastReviewRef} />
<LuRefreshCcw className="w-4 h-4 mr-2" />
New Items To Review
</Button>
</div>
</div>
)}
<div className="w-full mr-4 md:grid md:grid-cols-3 3xl:grid-cols-4 gap-4 overflow-y-auto no-scrollbar">
{currentItems ? (
currentItems.map((value, segIdx) => {
const lastRow = segIdx == reviewItems[severity].length - 1;
const relevantPreview = Object.values(
relevantPreviews || []
).find(
(preview) =>
preview.camera == value.camera &&
preview.start < value.start_time &&
preview.end > value.end_time
);
return (
<div
key={value.id}
ref={lastRow ? lastReviewRef : minimapRef}
data-start={value.start_time}
>
<div className="aspect-video rounded-lg overflow-hidden">
<PreviewThumbnailPlayer
review={value}
relevantPreview={relevantPreview}
setReviewed={() => markItemAsReviewed(value.id)}
onClick={() => onSelectReview(value.id)}
/>
</div>
{lastRow && !reachedEnd && <ActivityIndicator />}
</div>
);
})
) : (
<div ref={lastReviewRef} />
)}
</div>
</div>
<div className="md:w-[100px] overflow-y-auto no-scrollbar">
<EventReviewTimeline