/ opencodehub / src / lib / inbox-shortcuts.ts
Swadhin Biswas fix(ts): eliminate all 127 TypeScript errors · 4/21/2026
18087d6
96 lines · 2.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/**
 * Inbox Keyboard Shortcuts
 * Graphite-style keyboard navigation for PR inbox
 */

import { logger } from "@/lib/logger";

// Keyboard shortcut handler
export function initInboxKeyboardShortcuts() {
    let selectedIndex = 0;
    const prItems = document.querySelectorAll('[data-pr-item]');

    if (prItems.length === 0) return;

    // Highlight the first item
    const highlightPR = (index: number) => {
        prItems.forEach((item, i) => {
            if (i === index) {
                item.classList.add('ring-2', 'ring-primary', 'bg-primary/5');
                item.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
            } else {
                item.classList.remove('ring-2', 'ring-primary', 'bg-primary/5');
            }
        });
    };

    // Initialize
    highlightPR(0);

    // Add keyboard listener
    document.addEventListener('keydown', (e) => {
        // Don't trigger if user is typing in an input
        if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) {
            return;
        }

        switch (e.key.toLowerCase()) {
            case 'j': // Next PR
                e.preventDefault();
                selectedIndex = Math.min(selectedIndex + 1, prItems.length - 1);
                highlightPR(selectedIndex);
                break;

            case 'k': // Previous PR
                e.preventDefault();
                selectedIndex = Math.max(selectedIndex - 1, 0);
                highlightPR(selectedIndex);
                break;

            case 'o': // Open PR
            case 'enter':
                e.preventDefault();
                const selectedItem = prItems[selectedIndex] as HTMLAnchorElement;
                selectedItem?.click();
                break;

            case 'r': // Refresh
                e.preventDefault();
                window.location.reload();
                break;

            case '?': // Show help
                e.preventDefault();
                toggleHelpModal();
                break;

            case 'escape':
                e.preventDefault();
                closeHelpModal();
                break;
        }
    });

    // Help modal
    function toggleHelpModal() {
        const modal = document.getElementById('keyboard-shortcuts-modal');
        if (modal) {
            modal.classList.toggle('hidden');
        }
    }

    function closeHelpModal() {
        const modal = document.getElementById('keyboard-shortcuts-modal');
        if (modal) {
            modal.classList.add('hidden');
        }
    }

    logger.info('✅ Inbox keyboard shortcuts active');
}

// Auto-init on page load
if (typeof window !== 'undefined') {
    document.addEventListener('DOMContentLoaded', initInboxKeyboardShortcuts);
}