Files
frigate/web/src/hooks/use-event-segment-utils.ts
T

220 lines
6.1 KiB
TypeScript
Raw Normal View History

2024-02-21 11:58:41 -06:00
import { useCallback, useMemo } from "react";
import { ReviewSegment } from "@/types/review";
2024-02-20 17:22:59 -06:00
2024-03-04 10:42:51 -06:00
export const useEventSegmentUtils = (
2024-02-20 17:22:59 -06:00
segmentDuration: number,
events: ReviewSegment[],
2024-02-28 15:23:56 -07:00
severityType: string,
2024-02-20 17:22:59 -06:00
) => {
2024-02-21 11:58:41 -06:00
const getSegmentStart = useCallback(
(time: number): number => {
return Math.floor(time / segmentDuration) * segmentDuration;
},
2024-02-28 15:23:56 -07:00
[segmentDuration],
2024-02-21 11:58:41 -06:00
);
2024-02-20 17:22:59 -06:00
2024-02-21 11:58:41 -06:00
const getSegmentEnd = useCallback(
(time: number | undefined): number => {
if (time) {
return (
Math.floor(time / segmentDuration) * segmentDuration + segmentDuration
);
} else {
return Date.now() / 1000 + segmentDuration;
}
},
2024-02-28 15:23:56 -07:00
[segmentDuration],
2024-02-21 11:58:41 -06:00
);
2024-02-20 17:22:59 -06:00
const mapSeverityToNumber = useCallback((severity: string): number => {
switch (severity) {
case "significant_motion":
return 1;
case "detection":
return 2;
case "alert":
return 3;
default:
return 0;
}
}, []);
const displaySeverityType = useMemo(
() => mapSeverityToNumber(severityType ?? ""),
2024-02-28 15:23:56 -07:00
[mapSeverityToNumber, severityType],
2024-02-20 17:22:59 -06:00
);
2024-02-21 11:58:41 -06:00
const getSeverity = useCallback(
(time: number, displaySeverityType: number): number[] => {
2024-03-24 12:39:28 -05:00
let highestSeverityValue = 0;
let highestOtherSeverityValue = 0;
let hasDisplaySeverityType = false;
for (const event of events || []) {
2024-02-21 11:58:41 -06:00
const segmentStart = getSegmentStart(event.start_time);
const segmentEnd = getSegmentEnd(event.end_time);
2024-02-20 17:22:59 -06:00
2024-03-24 12:39:28 -05:00
if (time >= segmentStart && time < segmentEnd) {
const severity = mapSeverityToNumber(event.severity);
2024-02-21 11:58:41 -06:00
2024-03-24 12:39:28 -05:00
if (severity === displaySeverityType) {
hasDisplaySeverityType = true;
highestOtherSeverityValue = Math.max(
highestOtherSeverityValue,
highestSeverityValue,
);
} else {
highestSeverityValue = Math.max(highestSeverityValue, severity);
}
}
}
if (hasDisplaySeverityType) {
2024-03-20 21:56:15 -05:00
return [displaySeverityType, highestOtherSeverityValue];
2024-03-24 12:39:28 -05:00
} else if (highestSeverityValue === 0) {
return [0];
2024-02-21 11:58:41 -06:00
} else {
return [highestSeverityValue];
}
},
2024-02-28 15:23:56 -07:00
[events, getSegmentStart, getSegmentEnd, mapSeverityToNumber],
2024-02-21 11:58:41 -06:00
);
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
);
});
},
2024-02-28 15:23:56 -07:00
[events, getSegmentStart, getSegmentEnd],
2024-02-21 11:58:41 -06:00
);
2024-02-20 17:22:59 -06:00
const shouldShowRoundedCorners = useCallback(
2024-02-27 13:41:26 -06:00
(
2024-02-28 15:23:56 -07:00
segmentTime: number,
2024-02-27 13:41:26 -06:00
): {
roundTopPrimary: boolean;
roundBottomPrimary: boolean;
roundTopSecondary: boolean;
roundBottomSecondary: boolean;
} => {
2024-02-20 17:22:59 -06:00
const prevSegmentTime = segmentTime - segmentDuration;
const nextSegmentTime = segmentTime + segmentDuration;
2024-02-21 11:58:41 -06:00
const severityEvents = events.filter((e) => e.severity === severityType);
2024-02-20 17:22:59 -06:00
2024-02-21 11:58:41 -06:00
const otherEvents = events.filter((e) => e.severity !== severityType);
2024-02-20 17:22:59 -06:00
2024-02-21 11:58:41 -06:00
const hasPrevSeverityEvent = severityEvents.some((e) => {
2024-02-20 17:22:59 -06:00
return (
prevSegmentTime >= getSegmentStart(e.start_time) &&
prevSegmentTime < getSegmentEnd(e.end_time)
);
});
2024-02-21 11:58:41 -06:00
const hasNextSeverityEvent = severityEvents.some((e) => {
2024-02-20 17:22:59 -06:00
return (
nextSegmentTime >= getSegmentStart(e.start_time) &&
nextSegmentTime < getSegmentEnd(e.end_time)
);
});
2024-02-21 11:58:41 -06:00
const hasPrevOtherEvent = otherEvents.some((e) => {
return (
prevSegmentTime >= getSegmentStart(e.start_time) &&
prevSegmentTime < getSegmentEnd(e.end_time)
);
2024-02-20 17:22:59 -06:00
});
2024-02-21 11:58:41 -06:00
const hasNextOtherEvent = otherEvents.some((e) => {
return (
nextSegmentTime >= getSegmentStart(e.start_time) &&
nextSegmentTime < getSegmentEnd(e.end_time)
);
2024-02-20 17:22:59 -06:00
});
2024-02-21 11:58:41 -06:00
const hasOverlappingSeverityEvent = severityEvents.some((e) => {
return (
segmentTime >= getSegmentStart(e.start_time) &&
segmentTime < getSegmentEnd(e.end_time)
);
2024-02-20 17:22:59 -06:00
});
2024-02-21 11:58:41 -06:00
const hasOverlappingOtherEvent = otherEvents.some((e) => {
return (
segmentTime >= getSegmentStart(e.start_time) &&
segmentTime < getSegmentEnd(e.end_time)
);
2024-02-20 17:22:59 -06:00
});
2024-02-27 13:41:26 -06:00
let roundTopPrimary = false;
let roundBottomPrimary = false;
let roundTopSecondary = false;
let roundBottomSecondary = false;
2024-02-20 17:22:59 -06:00
if (hasOverlappingSeverityEvent) {
2024-02-27 13:41:26 -06:00
roundBottomPrimary = !hasPrevSeverityEvent;
roundTopPrimary = !hasNextSeverityEvent;
}
if (hasOverlappingOtherEvent) {
roundBottomSecondary = !hasPrevOtherEvent;
roundTopSecondary = !hasNextOtherEvent;
2024-02-20 17:22:59 -06:00
}
return {
2024-02-27 13:41:26 -06:00
roundTopPrimary,
roundBottomPrimary,
roundTopSecondary,
roundBottomSecondary,
2024-02-20 17:22:59 -06:00
};
},
2024-02-28 15:23:56 -07:00
[events, getSegmentStart, getSegmentEnd, segmentDuration, severityType],
2024-02-20 17:22:59 -06:00
);
2024-02-27 13:41:26 -06:00
const getEventStart = useCallback(
(time: number): number => {
const matchingEvent = events.find((event) => {
return (
time >= getSegmentStart(event.start_time) &&
time < getSegmentEnd(event.end_time) &&
event.severity == severityType
);
});
return matchingEvent?.start_time ?? 0;
},
2024-02-28 15:23:56 -07:00
[events, getSegmentStart, getSegmentEnd, severityType],
2024-02-27 13:41:26 -06:00
);
2025-11-05 08:48:47 -07:00
const getEvent = useCallback(
(time: number): ReviewSegment | undefined => {
2024-02-27 13:41:26 -06:00
const matchingEvent = events.find((event) => {
return (
time >= getSegmentStart(event.start_time) &&
time < getSegmentEnd(event.end_time) &&
event.severity == severityType
);
});
2025-11-05 08:48:47 -07:00
return matchingEvent;
2024-02-27 13:41:26 -06:00
},
2024-02-28 15:23:56 -07:00
[events, getSegmentStart, getSegmentEnd, severityType],
2024-02-27 13:41:26 -06:00
);
2024-02-21 11:58:41 -06:00
return {
getSegmentStart,
getSegmentEnd,
getSeverity,
displaySeverityType,
getReviewed,
shouldShowRoundedCorners,
2024-02-27 13:41:26 -06:00
getEventStart,
2025-11-05 08:48:47 -07:00
getEvent,
2024-02-21 11:58:41 -06:00
};
2024-02-27 13:41:26 -06:00
};