Compare commits

...

4 Commits

Author SHA1 Message Date
Josh Hawkins
7edc36dbd4
Merge 426699d3d0 into de066d0062 2025-11-12 23:23:00 +00:00
Nicolas Mowen
426699d3d0 Use timeline tab by default for notifications but add a query arg for customization 2025-11-12 16:22:55 -07:00
Josh Hawkins
73b9193a19 fix blue line height calc for in progress events 2025-11-12 11:42:50 -06:00
Josh Hawkins
daa9919966 don't show object track until video metadata is loaded 2025-11-12 11:21:40 -06:00
4 changed files with 35 additions and 8 deletions

View File

@ -221,12 +221,26 @@ export function TrackingDetails({
displaySource, displaySource,
]); ]);
const isWithinEventRange = const isWithinEventRange = useMemo(() => {
effectiveTime !== undefined && if (effectiveTime === undefined || event.start_time === undefined) {
event.start_time !== undefined && return false;
event.end_time !== undefined && }
effectiveTime >= event.start_time &&
effectiveTime <= event.end_time; // If an event has not ended yet, fall back to last timestamp in eventSequence
let eventEnd = event.end_time;
if (eventEnd == null && eventSequence && eventSequence.length > 0) {
const last = eventSequence[eventSequence.length - 1];
if (last && last.timestamp !== undefined) {
eventEnd = last.timestamp;
}
}
if (eventEnd == null) {
return false;
}
return effectiveTime >= event.start_time && effectiveTime <= eventEnd;
}, [effectiveTime, event.start_time, event.end_time, eventSequence]);
// Calculate how far down the blue line should extend based on effectiveTime // Calculate how far down the blue line should extend based on effectiveTime
const calculateLineHeight = useCallback(() => { const calculateLineHeight = useCallback(() => {

View File

@ -318,6 +318,7 @@ export default function HlsVideoPlayer({
{isDetailMode && {isDetailMode &&
camera && camera &&
currentTime && currentTime &&
loadedMetadata &&
videoDimensions.width > 0 && videoDimensions.width > 0 &&
videoDimensions.height > 0 && ( videoDimensions.height > 0 && (
<div className="absolute z-50 size-full"> <div className="absolute z-50 size-full">

View File

@ -15,6 +15,7 @@ import {
ReviewSummary, ReviewSummary,
SegmentedReviewData, SegmentedReviewData,
} from "@/types/review"; } from "@/types/review";
import { TimelineType } from "@/types/timeline";
import { import {
getBeginningOfDayTimestamp, getBeginningOfDayTimestamp,
getEndOfDayTimestamp, getEndOfDayTimestamp,
@ -49,6 +50,16 @@ export default function Events() {
false, false,
); );
const [notificationTab, setNotificationTab] =
useState<TimelineType>("timeline");
useSearchEffect("tab", (tab: string) => {
if (tab === "timeline" || tab === "events" || tab === "detail") {
setNotificationTab(tab as TimelineType);
}
return true;
});
useSearchEffect("id", (reviewId: string) => { useSearchEffect("id", (reviewId: string) => {
axios axios
.get(`review/${reviewId}`) .get(`review/${reviewId}`)
@ -66,7 +77,7 @@ export default function Events() {
camera: resp.data.camera, camera: resp.data.camera,
startTime, startTime,
severity: resp.data.severity, severity: resp.data.severity,
timelineType: "detail", timelineType: notificationTab,
}, },
true, true,
); );

View File

@ -1,4 +1,5 @@
import { ReviewSeverity } from "./review"; import { ReviewSeverity } from "./review";
import { TimelineType } from "./timeline";
export type Recording = { export type Recording = {
id: string; id: string;
@ -37,7 +38,7 @@ export type RecordingStartingPoint = {
camera: string; camera: string;
startTime: number; startTime: number;
severity: ReviewSeverity; severity: ReviewSeverity;
timelineType?: "timeline" | "events" | "detail"; timelineType?: TimelineType;
}; };
export type RecordingPlayerError = "stalled" | "startup"; export type RecordingPlayerError = "stalled" | "startup";