use unix timestamps everywhere

This commit is contained in:
Josh Hawkins 2024-02-20 11:46:22 -06:00
parent 62d95cca71
commit 12ed066dce
6 changed files with 28 additions and 30 deletions

View File

@ -89,7 +89,7 @@ export function EventReviewTimeline({
const segmentAlignedTime = alignDateToTimeline(timelineStart); const segmentAlignedTime = alignDateToTimeline(timelineStart);
return Array.from({ length: segmentCount }, (_, index) => { return Array.from({ length: segmentCount }, (_, index) => {
const segmentTime = segmentAlignedTime - index * segmentDuration * 1000; const segmentTime = segmentAlignedTime - index * segmentDuration;
return ( return (
<EventSegment <EventSegment
@ -134,7 +134,7 @@ export function EventReviewTimeline({
requestAnimationFrame(() => { requestAnimationFrame(() => {
if (currentTimeRef.current && currentTimeSegment) { if (currentTimeRef.current && currentTimeSegment) {
currentTimeRef.current.textContent = new Date( currentTimeRef.current.textContent = new Date(
currentTimeSegment currentTimeSegment * 1000
).toLocaleTimeString([], { ).toLocaleTimeString([], {
hour: "2-digit", hour: "2-digit",
minute: "2-digit", minute: "2-digit",
@ -156,7 +156,7 @@ export function EventReviewTimeline({
// Calculate the segment index corresponding to the target time // Calculate the segment index corresponding to the target time
const alignedHandlebarTime = alignDateToTimeline(handlebarTime); const alignedHandlebarTime = alignDateToTimeline(handlebarTime);
const segmentIndex = Math.ceil( const segmentIndex = Math.ceil(
(timelineStart - alignedHandlebarTime) / (segmentDuration * 1000) (timelineStart - alignedHandlebarTime) / segmentDuration
); );
// Calculate the top position based on the segment index // Calculate the top position based on the segment index

View File

@ -46,7 +46,7 @@ function MinimapBounds({
<> <>
{isFirstSegmentInMinimap && ( {isFirstSegmentInMinimap && (
<div className="absolute inset-0 -bottom-5 w-full flex items-center justify-center text-xs text-primary font-medium z-20 text-center text-[9px]"> <div className="absolute inset-0 -bottom-5 w-full flex items-center justify-center text-xs text-primary font-medium z-20 text-center text-[9px]">
{new Date(alignedMinimapStartTime).toLocaleTimeString([], { {new Date(alignedMinimapStartTime * 1000).toLocaleTimeString([], {
hour: "2-digit", hour: "2-digit",
minute: "2-digit", minute: "2-digit",
month: "short", month: "short",
@ -57,7 +57,7 @@ function MinimapBounds({
{isLastSegmentInMinimap && ( {isLastSegmentInMinimap && (
<div className="absolute inset-0 -top-1 w-full flex items-center justify-center text-xs text-primary font-medium z-20 text-center text-[9px]"> <div className="absolute inset-0 -top-1 w-full flex items-center justify-center text-xs text-primary font-medium z-20 text-center text-[9px]">
{new Date(alignedMinimapEndTime).toLocaleTimeString([], { {new Date(alignedMinimapEndTime * 1000).toLocaleTimeString([], {
hour: "2-digit", hour: "2-digit",
minute: "2-digit", minute: "2-digit",
month: "short", month: "short",
@ -153,11 +153,8 @@ export function EventSegment({
[shouldShowRoundedCorners, segmentTime] [shouldShowRoundedCorners, segmentTime]
); );
const timestamp = useMemo(() => new Date(segmentTime), [segmentTime]); const timestamp = useMemo(() => new Date(segmentTime * 1000), [segmentTime]);
const segmentKey = useMemo( const segmentKey = useMemo(() => segmentTime, [segmentTime]);
() => Math.floor(segmentTime / 1000),
[segmentTime]
);
const alignedMinimapStartTime = useMemo( const alignedMinimapStartTime = useMemo(
() => alignDateToTimeline(minimapStartTime ?? 0), () => alignDateToTimeline(minimapStartTime ?? 0),

View File

@ -5,7 +5,7 @@ export const useEventUtils = (events: Event[], segmentDuration: number) => {
const isStartOfEvent = useCallback((time: number): boolean => { const isStartOfEvent = useCallback((time: number): boolean => {
return events.some((event) => { return events.some((event) => {
const segmentStart = getSegmentStart(event.start_time); const segmentStart = getSegmentStart(event.start_time);
return time >= segmentStart && time < segmentStart + segmentDuration * 1000; return time >= segmentStart && time < segmentStart + segmentDuration;
}); });
}, [events, segmentDuration]); }, [events, segmentDuration]);
@ -13,23 +13,23 @@ export const useEventUtils = (events: Event[], segmentDuration: number) => {
return events.some((event) => { return events.some((event) => {
if (typeof event.end_time === 'number') { if (typeof event.end_time === 'number') {
const segmentEnd = getSegmentEnd(event.end_time); const segmentEnd = getSegmentEnd(event.end_time);
return time >= segmentEnd - segmentDuration * 1000 && time < segmentEnd; return time >= segmentEnd - segmentDuration && time < segmentEnd;
} }
return false; // Return false if end_time is undefined return false; // Return false if end_time is undefined
}); });
}, [events, segmentDuration]); }, [events, segmentDuration]);
const getSegmentStart = useCallback((time: number): number => { const getSegmentStart = useCallback((time: number): number => {
return Math.floor(time / (segmentDuration * 1000)) * (segmentDuration * 1000); return Math.floor(time / (segmentDuration)) * (segmentDuration);
}, [segmentDuration]); }, [segmentDuration]);
const getSegmentEnd = useCallback((time: number): number => { const getSegmentEnd = useCallback((time: number): number => {
return Math.ceil(time / (segmentDuration * 1000)) * (segmentDuration * 1000); return Math.ceil(time / (segmentDuration)) * (segmentDuration);
}, [segmentDuration]); }, [segmentDuration]);
const alignDateToTimeline = useCallback((time: number): number => { const alignDateToTimeline = useCallback((time: number): number => {
const remainder = time % (segmentDuration * 1000); const remainder = time % (segmentDuration);
const adjustment = remainder !== 0 ? segmentDuration * 1000 - remainder : 0; const adjustment = remainder !== 0 ? segmentDuration - remainder : 0;
return time + adjustment; return time + adjustment;
}, [segmentDuration]); }, [segmentDuration]);

View File

@ -91,7 +91,7 @@ function useDraggableHandler({
const segmentIndex = Math.floor(newHandlePosition / segmentHeight); const segmentIndex = Math.floor(newHandlePosition / segmentHeight);
const segmentStartTime = alignDateToTimeline( const segmentStartTime = alignDateToTimeline(
Math.floor(timelineStart - segmentIndex * segmentDuration * 1000) timelineStart - segmentIndex * segmentDuration
); );
if (showHandlebar) { if (showHandlebar) {
@ -100,7 +100,7 @@ function useDraggableHandler({
thumb.style.top = `${newHandlePosition - segmentHeight}px`; thumb.style.top = `${newHandlePosition - segmentHeight}px`;
if (currentTimeRef.current) { if (currentTimeRef.current) {
currentTimeRef.current.textContent = new Date( currentTimeRef.current.textContent = new Date(
segmentStartTime segmentStartTime*1000
).toLocaleTimeString([], { ).toLocaleTimeString([], {
hour: "2-digit", hour: "2-digit",
minute: "2-digit", minute: "2-digit",

View File

@ -7,14 +7,14 @@ export const useSegmentUtils = (
severityType: string, severityType: string,
) => { ) => {
const getSegmentStart = useCallback((time: number): number => { const getSegmentStart = useCallback((time: number): number => {
return Math.floor(time / (segmentDuration * 1000)) * (segmentDuration * 1000); return Math.floor(time / (segmentDuration)) * (segmentDuration);
}, [segmentDuration]); }, [segmentDuration]);
const getSegmentEnd = useCallback((time: number | undefined): number => { const getSegmentEnd = useCallback((time: number | undefined): number => {
if (time) { if (time) {
return Math.ceil(time / (segmentDuration * 1000)) * (segmentDuration * 1000); return Math.ceil(time / (segmentDuration)) * (segmentDuration);
} else { } else {
return Date.now()+(segmentDuration*1000); return (Date.now()/1000)+(segmentDuration);
} }
}, [segmentDuration]); }, [segmentDuration]);
@ -61,8 +61,8 @@ export const useSegmentUtils = (
const shouldShowRoundedCorners = useCallback( const shouldShowRoundedCorners = useCallback(
(segmentTime: number): boolean => { (segmentTime: number): boolean => {
const prevSegmentTime = segmentTime - segmentDuration * 1000; const prevSegmentTime = segmentTime - segmentDuration;
const nextSegmentTime = segmentTime + segmentDuration * 1000; const nextSegmentTime = segmentTime + segmentDuration;
const hasPrevEvent = events.some((e) => { const hasPrevEvent = events.some((e) => {
return ( return (

View File

@ -59,12 +59,12 @@ function eventsToScrubberItems(events: Event[]): ScrubberItem[] {
} }
const generateRandomEvent = (): Event => { const generateRandomEvent = (): Event => {
const start_time = Date.now() - Math.random() * 3600000 * 3; const start_time = Math.floor(Date.now() / 1000) - Math.random() * 60 * 60;
const end_time = start_time + Math.random() * 360000; const end_time = Math.floor(start_time + Math.random() * 60 * 10);
const severities = ["motion", "detection", "alert"]; const severities = ["motion", "detection", "alert"];
const severity = severities[Math.floor(Math.random() * severities.length)]; const severity = severities[Math.floor(Math.random() * severities.length)];
const has_been_reviewed = Math.random() < 0.2; const has_been_reviewed = Math.random() < 0.2;
const id = new Date(start_time).toISOString(); // Date string as mock ID const id = new Date(start_time * 1000).toISOString(); // Date string as mock ID
return { id, start_time, end_time, severity, has_been_reviewed }; return { id, start_time, end_time, severity, has_been_reviewed };
}; };
@ -91,6 +91,7 @@ function UIPlayground() {
useMemo(() => { useMemo(() => {
const initialEvents = Array.from({ length: 50 }, generateRandomEvent); const initialEvents = Array.from({ length: 50 }, generateRandomEvent);
setMockEvents(initialEvents); setMockEvents(initialEvents);
console.log(initialEvents);
}, []); }, []);
return ( return (
@ -161,13 +162,13 @@ function UIPlayground() {
<EventReviewTimeline <EventReviewTimeline
segmentDuration={60} // seconds per segment segmentDuration={60} // seconds per segment
timestampSpread={15} // minutes between each major timestamp timestampSpread={15} // minutes between each major timestamp
timelineStart={Date.now()} // start of the timeline - all times are numeric, not Date objects timelineStart={Math.floor(Date.now() / 1000)} // start of the timeline - all times are numeric, not Date objects
timelineDuration={24 * 60 * 60} // in minutes, defaults to 24 hours timelineDuration={24 * 60 * 60} // in minutes, defaults to 24 hours
showHandlebar // show / hide the handlebar showHandlebar // show / hide the handlebar
handlebarTime={Date.now() - 27 * 60 * 1000} // set the time of the handlebar handlebarTime={Math.floor(Date.now() / 1000) - 27 * 60} // set the time of the handlebar
showMinimap // show / hide the minimap showMinimap // show / hide the minimap
minimapStartTime={Date.now() - 35 * 60 * 1000} // start time of the minimap - the earlier time (eg 1:00pm) minimapStartTime={Math.floor(Date.now() / 1000) - 35 * 60} // start time of the minimap - the earlier time (eg 1:00pm)
minimapEndTime={Date.now() - 21 * 60 * 1000} // end of the minimap - the later time (eg 3:00pm) minimapEndTime={Math.floor(Date.now() / 1000) - 21 * 60} // end of the minimap - the later time (eg 3:00pm)
events={mockEvents} // events, including new has_been_reviewed and severity properties events={mockEvents} // events, including new has_been_reviewed and severity properties
severityType={"alert"} // choose the severity type for the middle line - all other severity types are to the right severityType={"alert"} // choose the severity type for the middle line - all other severity types are to the right
contentRef={contentRef} // optional content ref where previews are, can be used for observing/scrolling later contentRef={contentRef} // optional content ref where previews are, can be used for observing/scrolling later