@@ -6,37 +6,74 @@ import { UserRole } from "@/src/types/shared/sidebar";
66import { TOOLTIPS_DICT } from "@/src/util/tooltip-constants" ;
77import { Tooltip } from "@nextui-org/react" ;
88import { IconCirclePlus } from "@tabler/icons-react" ;
9- import { Fragment , useEffect , useState } from "react" ;
9+ import { Fragment , useEffect , useState , useCallback } from "react" ;
1010import { useSelector } from "react-redux" ;
1111
12+ const eventListenersMap = new Map ( ) ;
13+
1214export default function LabelSelectionBox ( props : LabelSelectionBoxProps ) {
1315 const user = useSelector ( selectUser ) ;
1416 const settings = useSelector ( selectSettings ) ;
1517
1618 const [ newLabelDict , setNewLabelDict ] = useState ( { } ) ;
1719 const [ taskFilteredDict , setTaskFilteredDict ] = useState ( { } ) ;
20+ const [ currentLabelHotkeys , setCurrentLabelHotkeys ] = useState < any > ( { } ) ;
21+ const [ currentActiveTasks , setCurrentActiveTasks ] = useState ( [ ] ) ;
1822
1923 useEffect ( ( ) => {
20- if ( ! props . labelHotkeys ) return ;
21- document . addEventListener ( 'keyup' , handleKeyboardEvent ) ;
22- return ( ) => {
23- document . removeEventListener ( 'keyup' , handleKeyboardEvent ) ;
24- } ;
25- } , [ props . labelHotkeys , props . activeTasks ] ) ;
24+ if ( props . activeTasks && props . activeTasks . length > 0 ) {
25+ setCurrentActiveTasks ( props . activeTasks ) ;
26+ }
27+ } , [ props . activeTasks ] ) ;
28+
29+ useEffect ( ( ) => {
30+ let missingValues = 0 ;
31+ for ( let key in props . labelHotkeys ) {
32+ if ( ( 'taskId' in props . labelHotkeys [ key ] && 'labelId' in props . labelHotkeys [ key ] ) === false ) {
33+ missingValues ++ ;
34+ }
35+ }
36+
37+ if ( missingValues == 0 ) {
38+ setCurrentLabelHotkeys ( props . labelHotkeys ) ;
39+ }
40+ } , [ currentActiveTasks ] ) ;
2641
27- function handleKeyboardEvent ( event ) {
42+ const handleKeyboardEvent = useCallback ( ( event ) => {
2843 const labelSelection = document . getElementById ( 'label-selection-box' ) ;
2944 if ( ! labelSelection || labelSelection . classList . contains ( 'hidden' ) ) return ;
30- for ( const key in props . labelHotkeys ) {
45+ for ( const key in currentLabelHotkeys ) {
3146 if ( key == event . key ) {
32- const activeTasks = props . activeTasks . map ( x => x . task ) ;
33- const task = activeTasks . find ( t => t . id == props . labelHotkeys [ key ] . taskId ) ;
34- props . addRla ( task , props . labelHotkeys [ key ] . labelId ) ;
47+ const activeTasks = currentActiveTasks . map ( x => x . task ) ;
48+ const task = activeTasks . find ( t => t . id == currentLabelHotkeys [ key ] . taskId ) ;
49+ props . addRla ( task , currentLabelHotkeys [ key ] . labelId ) ;
3550 event . preventDefault ( ) ;
3651 event . stopPropagation ( ) ;
3752 return ;
3853 }
3954 }
55+ } , [ currentLabelHotkeys ] ) ;
56+
57+ useEffect ( ( ) => {
58+ addUniqueEventListener ( "handleKeyboardEventID" , 'keyup' , handleKeyboardEvent ) ;
59+ return ( ) => {
60+ removeAllEventListeners ( 'keyup' ) ;
61+ } ;
62+ } , [ handleKeyboardEvent ] ) ;
63+
64+ function addUniqueEventListener ( id , eventType , handler ) {
65+ removeAllEventListeners ( 'keyup' ) ;
66+ document . addEventListener ( eventType , handler ) ;
67+ eventListenersMap . set ( id , { eventType, listener : handler } ) ;
68+ }
69+
70+ function removeAllEventListeners ( eventType ) {
71+ for ( let [ id , handler ] of eventListenersMap . entries ( ) ) {
72+ if ( handler . eventType === eventType ) {
73+ document . removeEventListener ( eventType , handler . listener ) ;
74+ eventListenersMap . delete ( id ) ;
75+ }
76+ }
4077 }
4178
4279 useEffect ( ( ) => {
0 commit comments