feat: add Alt+↑/↓ keyboard shortcuts to navigate between sessions
This commit is contained in:
15
src/App.tsx
15
src/App.tsx
@@ -40,7 +40,7 @@ export default function App() {
|
|||||||
return () => setBaseTitle(undefined);
|
return () => setBaseTitle(undefined);
|
||||||
}, [activeSession, sessions]);
|
}, [activeSession, sessions]);
|
||||||
|
|
||||||
// Close sidebar on Escape key, open shortcuts on ?
|
// Keyboard shortcuts: Escape, ?, Alt+↑/↓ for session navigation
|
||||||
const handleKeyDown = useCallback((e: KeyboardEvent) => {
|
const handleKeyDown = useCallback((e: KeyboardEvent) => {
|
||||||
if (e.key === 'Escape' && sidebarOpen) {
|
if (e.key === 'Escape' && sidebarOpen) {
|
||||||
setSidebarOpen(false);
|
setSidebarOpen(false);
|
||||||
@@ -52,7 +52,18 @@ export default function App() {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setShortcutsOpen(true);
|
setShortcutsOpen(true);
|
||||||
}
|
}
|
||||||
}, [sidebarOpen, shortcutsOpen]);
|
// Alt+↑ / Alt+↓ — switch to previous/next session
|
||||||
|
if (e.altKey && (e.key === 'ArrowUp' || e.key === 'ArrowDown')) {
|
||||||
|
e.preventDefault();
|
||||||
|
if (sessions.length < 2) return;
|
||||||
|
const idx = sessions.findIndex(s => s.key === activeSession);
|
||||||
|
if (idx === -1) return;
|
||||||
|
const next = e.key === 'ArrowUp'
|
||||||
|
? (idx - 1 + sessions.length) % sessions.length
|
||||||
|
: (idx + 1) % sessions.length;
|
||||||
|
switchSession(sessions[next].key);
|
||||||
|
}
|
||||||
|
}, [sidebarOpen, shortcutsOpen, sessions, activeSession, switchSession]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
document.addEventListener('keydown', handleKeyDown);
|
document.addEventListener('keydown', handleKeyDown);
|
||||||
|
|||||||
@@ -98,6 +98,10 @@ export function KeyboardShortcuts({ open, onClose }: Props) {
|
|||||||
keys={<><Kbd>{mod}</Kbd><span className="text-zinc-600">+</span><Kbd>K</Kbd></>}
|
keys={<><Kbd>{mod}</Kbd><span className="text-zinc-600">+</span><Kbd>K</Kbd></>}
|
||||||
label={t('shortcuts.search')}
|
label={t('shortcuts.search')}
|
||||||
/>
|
/>
|
||||||
|
<ShortcutRow
|
||||||
|
keys={<><Kbd>Alt</Kbd><span className="text-zinc-600">+</span><Kbd>↑</Kbd><span className="text-zinc-600">/</span><Kbd>↓</Kbd></>}
|
||||||
|
label={t('shortcuts.switchSession')}
|
||||||
|
/>
|
||||||
<ShortcutRow
|
<ShortcutRow
|
||||||
keys={<Kbd>Esc</Kbd>}
|
keys={<Kbd>Esc</Kbd>}
|
||||||
label={t('shortcuts.closeSidebar')}
|
label={t('shortcuts.closeSidebar')}
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ const en = {
|
|||||||
'shortcuts.send': 'Send message',
|
'shortcuts.send': 'Send message',
|
||||||
'shortcuts.newline': 'New line',
|
'shortcuts.newline': 'New line',
|
||||||
'shortcuts.search': 'Search sessions',
|
'shortcuts.search': 'Search sessions',
|
||||||
|
'shortcuts.switchSession': 'Previous / next session',
|
||||||
'shortcuts.closeSidebar': 'Close sidebar / search',
|
'shortcuts.closeSidebar': 'Close sidebar / search',
|
||||||
'shortcuts.stop': 'Stop generation',
|
'shortcuts.stop': 'Stop generation',
|
||||||
'shortcuts.help': 'Show shortcuts',
|
'shortcuts.help': 'Show shortcuts',
|
||||||
@@ -163,6 +164,7 @@ const fr: Record<keyof typeof en, string> = {
|
|||||||
'shortcuts.send': 'Envoyer le message',
|
'shortcuts.send': 'Envoyer le message',
|
||||||
'shortcuts.newline': 'Nouvelle ligne',
|
'shortcuts.newline': 'Nouvelle ligne',
|
||||||
'shortcuts.search': 'Rechercher des sessions',
|
'shortcuts.search': 'Rechercher des sessions',
|
||||||
|
'shortcuts.switchSession': 'Session précédente / suivante',
|
||||||
'shortcuts.closeSidebar': 'Fermer la barre / recherche',
|
'shortcuts.closeSidebar': 'Fermer la barre / recherche',
|
||||||
'shortcuts.stop': 'Arrêter la génération',
|
'shortcuts.stop': 'Arrêter la génération',
|
||||||
'shortcuts.help': 'Afficher les raccourcis',
|
'shortcuts.help': 'Afficher les raccourcis',
|
||||||
|
|||||||
Reference in New Issue
Block a user