Add comments

This commit is contained in:
0x464e 2026-03-19 20:37:15 +02:00
parent 5639fdfd6a
commit b4a632e818
No known key found for this signature in database
GPG Key ID: E6D221DF6CBFBFFA
3 changed files with 16 additions and 3 deletions

View File

@ -238,6 +238,8 @@ function CustomTimestampSelector({
return 0; return 0;
} }
// the picker edits a timestamp in the configured UI timezone,
// but the stored value remains a unix timestamp
return (timezoneOffset - localTimeOffset) * 60; return (timezoneOffset - localTimeOffset) * 60;
}, [timezoneOffset, localTimeOffset]); }, [timezoneOffset, localTimeOffset]);
@ -262,6 +264,7 @@ function CustomTimestampSelector({
const setFromDisplayDate = useCallback( const setFromDisplayDate = useCallback(
(date: Date) => { (date: Date) => {
// convert the edited display time back into the underlying Unix timestamp
setTimestamp(date.getTime() / 1000 - offsetDeltaSeconds); setTimestamp(date.getTime() / 1000 - offsetDeltaSeconds);
}, },
[offsetDeltaSeconds, setTimestamp], [offsetDeltaSeconds, setTimestamp],

View File

@ -247,6 +247,11 @@ export default function Events() {
[recording, setRecording, setReviewFilter], [recording, setRecording, setReviewFilter],
); );
// shared recording links enter /review through query params, but the
// existing recording view is opened via router state (`recording`)
// this effect translates the URL entry point into the state shape the
// rest of the page already uses, then cleans the URL back to plain /review
useEffect(() => { useEffect(() => {
const timestamp = searchParams.get(RECORDING_REVIEW_START_PARAM); const timestamp = searchParams.get(RECORDING_REVIEW_START_PARAM);
const timezone = searchParams.get(RECORDING_REVIEW_TIMEZONE_PARAM); const timezone = searchParams.get(RECORDING_REVIEW_TIMEZONE_PARAM);
@ -262,16 +267,18 @@ export default function Events() {
const reviewLink = parseRecordingReviewLink(camera, timestamp, timezone); const reviewLink = parseRecordingReviewLink(camera, timestamp, timezone);
if (!reviewLink) { if (!reviewLink) {
navigate(location.pathname + location.hash, { navigate(location.pathname, {
state: location.state, state: location.state,
replace: true, replace: true,
}); });
return; return;
} }
const nextRecording = { const nextRecording: RecordingStartingPoint = {
camera: reviewLink.camera, camera: reviewLink.camera,
startTime: reviewLink.timestamp, startTime: reviewLink.timestamp,
// severity not actually applicable here, but the type requires it
// this pattern is also used LiveCameraView to enter recording view
severity: "alert" as const, severity: "alert" as const,
}; };
@ -280,7 +287,7 @@ export default function Events() {
...getReviewDayBounds(new Date(reviewLink.timestamp * 1000)), ...getReviewDayBounds(new Date(reviewLink.timestamp * 1000)),
}); });
navigate(location.pathname + location.hash, { navigate(location.pathname, {
state: { state: {
...location.state, ...location.state,
recording: nextRecording, recording: nextRecording,

View File

@ -15,9 +15,12 @@ function formatRecordingReviewTimestamp(
const date = new Date(Math.floor(timestamp) * 1000); const date = new Date(Math.floor(timestamp) * 1000);
if (timezone) { if (timezone) {
// when the UI timezone is configured, keep the URL readable by storing
// local time plus a separate timezone query param
return formatInTimeZone(date, timezone, "yyyy-MM-dd'T'HH:mm:ss"); return formatInTimeZone(date, timezone, "yyyy-MM-dd'T'HH:mm:ss");
} }
// without a configured UI timezone, fall back to UTC timestamp
return formatInTimeZone(date, "UTC", "yyyy-MM-dd'T'HH:mm:ss'Z'"); return formatInTimeZone(date, "UTC", "yyyy-MM-dd'T'HH:mm:ss'Z'");
} }