frigate/web/src/utils/recordingReviewUrl.ts

67 lines
1.7 KiB
TypeScript
Raw Normal View History

2026-03-19 17:33:30 +03:00
import { formatInTimeZone, fromZonedTime } from "date-fns-tz";
export const RECORDING_REVIEW_START_PARAM = "start_time";
2026-03-19 17:33:30 +03:00
export const RECORDING_REVIEW_TIMEZONE_PARAM = "timezone";
export type RecordingReviewLinkState = {
camera: string;
timestamp: number;
};
2026-03-19 17:33:30 +03:00
function formatRecordingReviewTimestamp(
timestamp: number,
timezone: string | undefined,
): string {
const date = new Date(Math.floor(timestamp) * 1000);
if (timezone) {
return formatInTimeZone(date, timezone, "yyyy-MM-dd'T'HH:mm:ss");
}
return formatInTimeZone(date, "UTC", "yyyy-MM-dd'T'HH:mm:ss'Z'");
}
export function parseRecordingReviewLink(
camera: string | null,
start: string | null,
2026-03-19 17:33:30 +03:00
timezone: string | null,
): RecordingReviewLinkState | undefined {
if (!camera || !start) {
return undefined;
}
2026-03-19 17:33:30 +03:00
const parsedDate = timezone
? fromZonedTime(start, timezone)
: new Date(start);
const parsedTimestamp = parsedDate.getTime() / 1000;
if (!Number.isFinite(parsedTimestamp)) {
return undefined;
}
return {
camera,
timestamp: Math.floor(parsedTimestamp),
};
}
export function createRecordingReviewUrl(
pathname: string,
state: RecordingReviewLinkState,
2026-03-19 17:33:30 +03:00
timezone?: string,
): string {
2026-03-19 17:33:30 +03:00
const url = new URL(globalThis.location.href);
const formattedTimestamp = formatRecordingReviewTimestamp(
state.timestamp,
timezone,
);
2026-03-19 17:33:30 +03:00
const normalizedPathname = pathname.startsWith("/")
? pathname
: `/${pathname}`;
const timezoneParam = timezone
? `&${RECORDING_REVIEW_TIMEZONE_PARAM}=${encodeURIComponent(timezone)}`
: "";
2026-03-19 17:33:30 +03:00
return `${url.origin}${normalizedPathname}?${RECORDING_REVIEW_START_PARAM}=${formattedTimestamp}${timezoneParam}#${encodeURIComponent(state.camera)}`;
}