Compare commits

..

2 Commits

Author SHA1 Message Date
Josh Hawkins
72c3b02420
Merge 73f0ca663b into 097673b845 2025-11-15 03:25:09 +00:00
Josh Hawkins
73f0ca663b ensure on demand recording stops when browser closes 2025-11-14 21:25:01 -06:00

View File

@ -850,6 +850,29 @@ function FrigateCameraFeatures({
} }
}, [activeToastId, t]); }, [activeToastId, t]);
const endEventViaBeacon = useCallback(() => {
if (!recordingEventIdRef.current) return;
const url = `${window.location.origin}/api/events/${recordingEventIdRef.current}/end`;
const payload = JSON.stringify({
end_time: Math.ceil(Date.now() / 1000),
});
// this needs to be a synchronous XMLHttpRequest to guarantee the PUT
// reaches the server before the browser kills the page
const xhr = new XMLHttpRequest();
try {
xhr.open("PUT", url, false);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader("X-CSRF-TOKEN", "1");
xhr.setRequestHeader("X-CACHE-BYPASS", "1");
xhr.withCredentials = true;
xhr.send(payload);
} catch (e) {
// Silently ignore errors during unload
}
}, []);
const handleEventButtonClick = useCallback(() => { const handleEventButtonClick = useCallback(() => {
if (isRecording) { if (isRecording) {
endEvent(); endEvent();
@ -887,8 +910,19 @@ function FrigateCameraFeatures({
}, [camera.name, isRestreamed, preferredLiveMode, t]); }, [camera.name, isRestreamed, preferredLiveMode, t]);
useEffect(() => { useEffect(() => {
// Handle page unload/close (browser close, tab close, refresh, navigation to external site)
const handleBeforeUnload = () => {
if (recordingEventIdRef.current) {
endEventViaBeacon();
}
};
window.addEventListener("beforeunload", handleBeforeUnload);
// ensure manual event is stopped when component unmounts // ensure manual event is stopped when component unmounts
return () => { return () => {
window.removeEventListener("beforeunload", handleBeforeUnload);
if (recordingEventIdRef.current) { if (recordingEventIdRef.current) {
endEvent(); endEvent();
} }