@@ -32,6 +32,7 @@ import {
32
32
deleteEmails ,
33
33
markReadThreads ,
34
34
} from "@/store/archive-queue" ;
35
+ import { useTableKeyboardNavigation } from "@/hooks/useTableKeyboardNavigation" ;
35
36
36
37
export function List ( {
37
38
emails,
@@ -364,52 +365,70 @@ export function EmailList({
364
365
) ;
365
366
} , [ selectedRows , refetch ] ) ;
366
367
367
- const [ focusedIndex , setFocusedIndex ] = useState ( 0 ) ;
368
-
369
- useEffect ( ( ) => {
370
- function handleKeyDown ( e : KeyboardEvent ) {
371
- if (
372
- document . activeElement ?. tagName === "INPUT" ||
373
- document . activeElement ?. tagName === "TEXTAREA"
374
- )
375
- return ;
376
-
377
- const isCmdOrCtrl = e . metaKey || e . ctrlKey ;
378
-
379
- if ( e . key === "ArrowDown" ) {
380
- setFocusedIndex ( ( prev ) => Math . min ( prev + 1 , threads . length - 1 ) ) ;
381
- }
382
-
383
- if ( e . key === "ArrowUp" ) {
384
- setFocusedIndex ( ( prev ) => Math . max ( prev - 1 , 0 ) ) ;
385
- }
386
-
387
- if ( e . key === "r" || e . key === "R" ) {
388
- if ( isCmdOrCtrl ) {
389
- e . preventDefault ( ) ;
390
- }
391
- const thread = threads [ focusedIndex ] ;
392
- if ( thread ) {
393
- setOpenThreadId ( thread . id ) ;
394
- markReadThreads ( [ thread . id ] , ( ) => refetch ( ) ) ;
395
- scrollToId ( thread . id ) ;
396
- }
397
- }
398
-
399
- if ( e . key === "e" || e . key === "E" ) {
400
- if ( isCmdOrCtrl ) {
401
- e . preventDefault ( ) ;
402
- }
403
- const thread = threads [ focusedIndex ] ;
404
- if ( thread ) {
405
- onArchive ( thread ) ;
406
- }
368
+ // useEffect(() => {
369
+ // function handleKeyDown(e: KeyboardEvent) {
370
+ // if (
371
+ // document.activeElement?.tagName === "INPUT" ||
372
+ // document.activeElement?.tagName === "TEXTAREA"
373
+ // )
374
+ // return;
375
+
376
+ // const isCmdOrCtrl = e.metaKey || e.ctrlKey;
377
+
378
+ // if (e.key === "ArrowDown") {
379
+ // setFocusedIndex((prev) => Math.min(prev + 1, threads.length - 1));
380
+ // }
381
+
382
+ // if (e.key === "ArrowUp") {
383
+ // setFocusedIndex((prev) => Math.max(prev - 1, 0));
384
+ // }
385
+
386
+ // if (e.key === "r" || e.key === "R") {
387
+ // if (isCmdOrCtrl) {
388
+ // e.preventDefault();
389
+ // }
390
+ // const thread = threads[focusedIndex];
391
+ // if (thread) {
392
+ // setOpenThreadId(thread.id);
393
+ // markReadThreads([thread.id], () => refetch());
394
+ // scrollToId(thread.id);
395
+ // }
396
+ // }
397
+
398
+ // if (e.key === "e" || e.key === "E") {
399
+ // if (isCmdOrCtrl) {
400
+ // e.preventDefault();
401
+ // }
402
+ // const thread = threads[focusedIndex];
403
+ // if (thread) {
404
+ // onArchive(thread);
405
+ // }
406
+ // }
407
+ // }
408
+
409
+ // window.addEventListener("keydown", handleKeyDown);
410
+ // return () => window.removeEventListener("keydown", handleKeyDown);
411
+ // }, [threads, focusedIndex, setOpenThreadId, onArchive, refetch]);
412
+
413
+ // const [focusedIndex, setFocusedIndex] = useState(0);
414
+
415
+ const handleAction = useCallback (
416
+ async ( index : number , action : "reply" | "archive" ) => {
417
+ const thread = threads [ index ] ;
418
+ if ( ! thread ) return ;
419
+
420
+ if ( action === "reply" ) {
421
+ setOpenThreadId ( thread . id ) ;
422
+ markReadThreads ( [ thread . id ] , ( ) => refetch ( ) ) ;
423
+ scrollToId ( thread . id ) ;
424
+ } else if ( action === "archive" ) {
425
+ onArchive ( thread ) ;
407
426
}
408
- }
427
+ } ,
428
+ [ threads , setOpenThreadId ] ,
429
+ ) ;
409
430
410
- window . addEventListener ( "keydown" , handleKeyDown ) ;
411
- return ( ) => window . removeEventListener ( "keydown" , handleKeyDown ) ;
412
- } , [ threads , focusedIndex , setOpenThreadId , onArchive , refetch ] ) ;
431
+ const { selectedIndex } = useEmailListKeyboardNav ( threads , handleAction ) ;
413
432
414
433
const onPlanAiBulk = useCallback ( async ( ) => {
415
434
toast . promise (
@@ -502,7 +521,6 @@ export function EmailList({
502
521
503
522
return (
504
523
< EmailListItem
505
- focused = { focusedIndex === index }
506
524
key = { thread . id }
507
525
ref = { ( node ) => {
508
526
const map = getMap ( ) ;
@@ -516,7 +534,7 @@ export function EmailList({
516
534
thread = { thread }
517
535
opened = { openThreadId === thread . id }
518
536
closePanel = { closePanel }
519
- selected = { selectedRows [ thread . id ] }
537
+ selected = { selectedIndex === index }
520
538
onSelected = { onSetSelectedRow }
521
539
splitView = { ! ! openThreadId }
522
540
onClick = { onOpen }
@@ -574,6 +592,26 @@ export function EmailList({
574
592
) ;
575
593
}
576
594
595
+ function useEmailListKeyboardNav (
596
+ items : { id : string } [ ] ,
597
+ onAction : ( index : number , action : "reply" | "archive" ) => void ,
598
+ ) {
599
+ const handleKeyAction = useCallback (
600
+ ( index : number , key : string ) => {
601
+ if ( key === "r" ) onAction ( index , "reply" ) ;
602
+ else if ( key === "e" ) onAction ( index , "archive" ) ;
603
+ } ,
604
+ [ onAction ] ,
605
+ ) ;
606
+
607
+ const { selectedIndex, setSelectedIndex, getRefCallback } =
608
+ useTableKeyboardNavigation ( {
609
+ items,
610
+ onKeyAction : handleKeyAction ,
611
+ } ) ;
612
+ return { selectedIndex, setSelectedIndex, getRefCallback } ;
613
+ }
614
+
577
615
function ResizeGroup ( {
578
616
left,
579
617
right,
0 commit comments