Skip to content

Commit 0d05d25

Browse files
authored
refactor: Leverage AbortController to remove events (#195)
1 parent a67ae26 commit 0d05d25

File tree

4 files changed

+57
-28
lines changed

4 files changed

+57
-28
lines changed

web_ui/src/hooks/event-listener/event-listener.hook.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,22 +35,27 @@ export function useEventListener<
3535
}, [handler]);
3636

3737
useEffect(() => {
38+
const controller = new AbortController();
3839
const targetElement = determineTargetElement(element);
3940

4041
if (targetElement === null) {
4142
return;
4243
}
4344

44-
const eventListener: (event: EventType[EventName]) => void = (event) => {
45-
if (savedHandler.current !== undefined) {
46-
savedHandler.current(event);
45+
targetElement.addEventListener(
46+
eventName,
47+
(event) => {
48+
if (savedHandler.current !== undefined) {
49+
savedHandler.current(event as EventType[EventName]);
50+
}
51+
},
52+
{
53+
signal: controller.signal,
4754
}
48-
};
49-
50-
targetElement.addEventListener(eventName, eventListener as EventListenerOrEventListenerObject);
55+
);
5156

5257
return () => {
53-
targetElement.removeEventListener(eventName, eventListener as EventListenerOrEventListenerObject);
58+
controller.abort();
5459
};
5560
}, [eventName, element]);
5661
}

web_ui/src/hooks/use-storage/use-storage.ts

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,26 @@ export const useStorage = () => {
1414
const [isOpenDialogAccessDenied, setIsOpenDialogAccessDenied] = useState<boolean>(false);
1515

1616
useEffect(() => {
17-
const listenerCallback = () => {
18-
if (localStorage.getItem(LOCAL_STORAGE_KEYS.UNAUTHORIZED) === 'true') {
19-
errorHandler({ message: StatusCodes.UNAUTHORIZED });
20-
removeLocalStorageKey(LOCAL_STORAGE_KEYS.UNAUTHORIZED);
21-
} else if (localStorage.getItem(LOCAL_STORAGE_KEYS.SERVICE_UNAVAILABLE) === 'true') {
22-
errorHandler({ message: StatusCodes.SERVICE_UNAVAILABLE });
23-
removeLocalStorageKey(LOCAL_STORAGE_KEYS.SERVICE_UNAVAILABLE);
24-
} else if (localStorage.getItem(LOCAL_STORAGE_KEYS.PROJECT_ACCESS_DENIED) === 'true') {
25-
setIsOpenDialogAccessDenied(true);
26-
}
27-
};
28-
29-
window.addEventListener('storage', listenerCallback);
17+
const controller = new AbortController();
18+
19+
window.addEventListener(
20+
'storage',
21+
() => {
22+
if (localStorage.getItem(LOCAL_STORAGE_KEYS.UNAUTHORIZED) === 'true') {
23+
errorHandler({ message: StatusCodes.UNAUTHORIZED });
24+
removeLocalStorageKey(LOCAL_STORAGE_KEYS.UNAUTHORIZED);
25+
} else if (localStorage.getItem(LOCAL_STORAGE_KEYS.SERVICE_UNAVAILABLE) === 'true') {
26+
errorHandler({ message: StatusCodes.SERVICE_UNAVAILABLE });
27+
removeLocalStorageKey(LOCAL_STORAGE_KEYS.SERVICE_UNAVAILABLE);
28+
} else if (localStorage.getItem(LOCAL_STORAGE_KEYS.PROJECT_ACCESS_DENIED) === 'true') {
29+
setIsOpenDialogAccessDenied(true);
30+
}
31+
},
32+
{ signal: controller.signal }
33+
);
3034

3135
return () => {
32-
window.removeEventListener('storage', listenerCallback);
36+
controller.abort();
3337
};
3438
}, [errorHandler]);
3539

web_ui/src/pages/camera-page/providers/video-recording-provider.component.tsx

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ const onValidChunk = runWhen<BlobEvent>(({ data }) => data.size > 0);
4040

4141
export const VideoRecordingProvider = ({ children }: { children: ReactNode }) => {
4242
const { webcamRef } = useDeviceSettings();
43+
const controller = useRef(new AbortController());
4344
const timeoutId = useRef<ReturnType<typeof setInterval> | null>(null);
4445
const recordedChunks = useRef<Blob[]>([]);
4546
const mediaRecorderRef = useRef<MediaRecorder | null>(null);
@@ -48,8 +49,11 @@ export const VideoRecordingProvider = ({ children }: { children: ReactNode }) =>
4849
const [recordedSeconds, setRecordedSeconds] = useState(0);
4950

5051
useEffect(() => {
52+
const abortController = controller.current;
53+
5154
return () => {
5255
timeoutId.current && clearInterval(timeoutId.current);
56+
abortController.abort();
5357
};
5458
}, []);
5559

@@ -68,14 +72,19 @@ export const VideoRecordingProvider = ({ children }: { children: ReactNode }) =>
6872

6973
mediaRecorderRef.current.addEventListener(
7074
DataEvents.DataAvailable,
71-
onValidChunk(({ data }: BlobEvent) => recordedChunks.current.push(data))
75+
onValidChunk(({ data }: BlobEvent) => recordedChunks.current.push(data)),
76+
{ signal: controller.current.signal }
7277
);
7378

74-
mediaRecorderRef.current.addEventListener(DataEvents.Stop, () => {
75-
onVideoReady(new File(recordedChunks.current, `${name}.${format}`, { type: `video/${format}` }));
79+
mediaRecorderRef.current.addEventListener(
80+
DataEvents.Stop,
81+
() => {
82+
onVideoReady(new File(recordedChunks.current, `${name}.${format}`, { type: `video/${format}` }));
7683

77-
recordedChunks.current = [];
78-
});
84+
recordedChunks.current = [];
85+
},
86+
{ signal: controller.current.signal }
87+
);
7988

8089
mediaRecorderRef.current.start();
8190
};

web_ui/src/pages/camera-support/use-camera.hook.tsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright (C) 2022-2025 Intel Corporation
22
// LIMITED EDGE SOFTWARE DISTRIBUTION LICENSE
33

4-
import { RefObject, useCallback, useRef, useState } from 'react';
4+
import { RefObject, useCallback, useEffect, useRef, useState } from 'react';
55

66
import { isEmpty } from 'lodash-es';
77
import Webcam from 'react-webcam';
@@ -37,6 +37,7 @@ const defaultMediaConstraints: Partial<MediaTrackSettings> = {
3737

3838
export const useCamera = (): UseCameraProps => {
3939
const webcamRef = useRef<Webcam>(null);
40+
const controller = useRef(new AbortController());
4041
const mediaRecorderRef = useRef<MediaRecorder | null>(null);
4142

4243
const [recordingVideo, setRecordingVideo] = useState(false);
@@ -93,7 +94,9 @@ export const useCamera = (): UseCameraProps => {
9394
mediaRecorderRef.current = new MediaRecorder(webcamRef.current.stream, {
9495
mimeType: 'video/webm',
9596
});
96-
mediaRecorderRef.current.addEventListener('dataavailable', handleDataAvailable);
97+
mediaRecorderRef.current.addEventListener('dataavailable', handleDataAvailable, {
98+
signal: controller.current.signal,
99+
});
97100
mediaRecorderRef.current.start();
98101
}
99102
}, [handleDataAvailable]);
@@ -170,6 +173,14 @@ export const useCamera = (): UseCameraProps => {
170173
}));
171174
};
172175

176+
useEffect(() => {
177+
const abortController = controller.current;
178+
179+
return () => {
180+
abortController.abort();
181+
};
182+
}, []);
183+
173184
return {
174185
webcamRef,
175186
handleDownloadVideo,

0 commit comments

Comments
 (0)