11import { Delete , Redo , Undo } from '@mui/icons-material' ;
22import { IconButton , Tooltip } from '@mui/material' ;
3- import React , { useContext , useEffect , useRef , useState } from 'react' ;
3+ import React , { useCallback , useContext , useEffect , useRef , useState } from 'react' ;
44
55import { AppContext } from '../../context/AppContext' ;
66import { CourseContext } from '../../context/CourseContext' ;
@@ -221,53 +221,75 @@ const History: React.FC = () => {
221221 * Undo/redo accordingly when a hotkey is pressed
222222 * @param event The keyboard event that was triggered
223223 */
224- const handleKeyDown = ( event : KeyboardEvent ) => {
225- // event.metaKey corresponds to the Cmd key on Mac
226- if ( ! ( event . ctrlKey || event . metaKey ) || ! ( event . key === 'z' || event . key === 'y' || event . key === 'd' ) ) return ;
227- if ( ! term ) return ;
228-
229- const currentTimetable = displayTimetables [ term ] [ selectedTimetable ] ;
230-
231- event . preventDefault ( ) ;
232-
233- if ( ! isMacOS && event . ctrlKey ) {
234- if ( event . key === 'z' && ! disableLeft && actionsPointer . current [ currentTimetable . id ] > 1 ) {
235- changeHistory ( - 1 ) ;
224+ const handleKeyDown = useCallback (
225+ ( event : KeyboardEvent ) => {
226+ // event.metaKey corresponds to the Cmd key on Mac
227+ if ( ! ( event . ctrlKey || event . metaKey ) || ! ( event . key === 'z' || event . key === 'y' || event . key === 'd' ) ) return ;
228+ if ( ! term ) return ;
229+
230+ const currentTimetable = displayTimetables [ term ] [ selectedTimetable ] ;
231+
232+ event . preventDefault ( ) ;
233+ if ( ! isMacOS && event . ctrlKey ) {
234+ if ( event . key === 'z' && ! disableLeft ) {
235+ changeHistory ( - 1 ) ;
236+ }
237+ if (
238+ event . key === 'y' &&
239+ ! disableRight &&
240+ actionsPointer . current [ currentTimetable . id ] + 1 < timetableActions . current [ currentTimetable . id ] . length
241+ ) {
242+ changeHistory ( 1 ) ;
243+ }
244+ if ( event . key === 'd' ) {
245+ setClearOpen ( ( prev ) => ! prev ) ;
246+ }
236247 }
237- if (
238- event . key === 'y' &&
239- ! disableRight &&
240- actionsPointer . current [ currentTimetable . id ] + 1 < timetableActions . current [ currentTimetable . id ] . length
241- ) {
242- changeHistory ( 1 ) ;
243- }
244- if ( event . key === 'd' ) {
245- setClearOpen ( ( prev ) => ! prev ) ;
246- }
247- }
248248
249- if ( isMacOS && event . metaKey ) {
250- if ( ! event . shiftKey && event . key === 'z' && ! disableLeft && actionsPointer . current [ currentTimetable . id ] > 1 ) {
251- changeHistory ( - 1 ) ;
252- }
253- if (
254- event . shiftKey &&
255- event . key === 'z' &&
256- ! disableRight &&
257- actionsPointer . current [ currentTimetable . id ] + 1 < timetableActions . current [ currentTimetable . id ] . length
258- ) {
259- changeHistory ( 1 ) ;
249+ if ( isMacOS && event . metaKey ) {
250+ if ( ! event . shiftKey && event . key === 'z' && ! disableLeft ) {
251+ changeHistory ( - 1 ) ;
252+ }
253+ if (
254+ event . shiftKey &&
255+ event . key === 'z' &&
256+ ! disableRight &&
257+ actionsPointer . current [ currentTimetable . id ] + 1 < timetableActions . current [ currentTimetable . id ] . length
258+ ) {
259+ changeHistory ( 1 ) ;
260+ }
261+ if ( event . key === 'd' ) {
262+ setClearOpen ( ( prev ) => ! prev ) ;
263+ }
260264 }
261- if ( event . key === 'd' ) {
262- setClearOpen ( ( prev ) => ! prev ) ;
263- }
264- }
265- } ;
265+ } ,
266+ [
267+ term ,
268+ displayTimetables ,
269+ selectedTimetable ,
270+ isMacOS ,
271+ disableLeft ,
272+ disableRight ,
273+ actionsPointer ,
274+ timetableActions ,
275+ changeHistory ,
276+ setClearOpen ,
277+ ] ,
278+ ) ;
279+
280+ const handleMouseUp = useCallback ( ( ) => {
281+ setIsDrag ( false ) ;
282+ } , [ ] ) ;
266283
267284 useEffect ( ( ) => {
268- window . addEventListener ( 'keydown' , handleKeyDown ) ;
269- window . addEventListener ( 'mouseup' , ( ) => setIsDrag ( false ) ) ; // Only triggers useEffect function if isDrag was true previously
270- } , [ disableLeft , disableRight ] ) ;
285+ document . addEventListener ( 'keydown' , handleKeyDown ) ;
286+ document . addEventListener ( 'mouseup' , handleMouseUp ) ; // Only triggers useEffect function if isDrag was true previously
287+
288+ return ( ) => {
289+ document . removeEventListener ( 'keydown' , handleKeyDown ) ;
290+ document . removeEventListener ( 'mouseup' , handleMouseUp ) ;
291+ } ;
292+ } , [ handleKeyDown , disableLeft , disableRight ] ) ;
271293
272294 // Hotkey to confirm delete all timetables by pressing enter button
273295 useEffect ( ( ) => {
@@ -282,7 +304,6 @@ const History: React.FC = () => {
282304
283305 document . addEventListener ( 'keydown' , handleDeleteEnterShortcut ) ;
284306
285- // Removing the event listener when the component unmounts
286307 return ( ) => {
287308 document . removeEventListener ( 'keydown' , handleDeleteEnterShortcut ) ;
288309 } ;
0 commit comments