1- import { Button } from "@hypr/ui/components/ui/button" ;
2- import { cn } from "@hypr/utils" ;
3-
41import { useRouteContext } from "@tanstack/react-router" ;
2+ import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow" ;
53import { ArrowLeftIcon , ArrowRightIcon , PanelLeftOpenIcon , PlusIcon } from "lucide-react" ;
64import { Reorder } from "motion/react" ;
75import { useCallback , useEffect , useRef } from "react" ;
6+ import { useHotkeys } from "react-hotkeys-hook" ;
87
8+ import { Button } from "@hypr/ui/components/ui/button" ;
9+ import { cn } from "@hypr/utils" ;
910import { useShell } from "../../../contexts/shell" ;
1011import { type Tab , uniqueIdfromTab , useTabs } from "../../../store/zustand/tabs" ;
1112import { id } from "../../../utils" ;
@@ -36,25 +37,13 @@ export function Body() {
3637}
3738
3839function Header ( { tabs } : { tabs : Tab [ ] } ) {
39- const { persistedStore, internalStore } = useRouteContext ( { from : "__root__" } ) ;
40-
4140 const { leftsidebar } = useShell ( ) ;
42- const { select, close, reorder, openNew , goBack, goNext, canGoBack, canGoNext, closeOthers, closeAll } = useTabs ( ) ;
41+ const { select, close, reorder, goBack, goNext, canGoBack, canGoNext, closeOthers, closeAll } = useTabs ( ) ;
4342 const tabsScrollContainerRef = useRef < HTMLDivElement > ( null ) ;
44- const setTabRef = useScrollActiveTabIntoView ( tabs ) ;
45-
46- const handleNewNote = useCallback ( ( ) => {
47- const sessionId = id ( ) ;
48- const user_id = internalStore ?. getValue ( "user_id" ) ;
43+ const handleNewNote = useNewTab ( ) ;
4944
50- persistedStore ?. setRow ( "sessions" , sessionId , { user_id, created_at : new Date ( ) . toISOString ( ) , title : "" } ) ;
51- openNew ( {
52- type : "sessions" ,
53- id : sessionId ,
54- active : true ,
55- state : { editor : "raw" } ,
56- } ) ;
57- } , [ persistedStore , internalStore , openNew ] ) ;
45+ const setTabRef = useScrollActiveTabIntoView ( tabs ) ;
46+ useTabsShortcuts ( ) ;
5847
5948 return (
6049 < div
@@ -65,9 +54,7 @@ function Header({ tabs }: { tabs: Tab[] }) {
6554 >
6655 { ! leftsidebar . expanded && (
6756 < Button size = "icon" variant = "ghost" onClick = { ( ) => leftsidebar . setExpanded ( true ) } >
68- < PanelLeftOpenIcon
69- size = { 16 }
70- />
57+ < PanelLeftOpenIcon size = { 16 } />
7158 </ Button >
7259 ) }
7360
@@ -310,3 +297,82 @@ function useScrollActiveTabIntoView(tabs: Tab[]) {
310297
311298 return setTabRef ;
312299}
300+
301+ function useTabsShortcuts ( ) {
302+ const { tabs, currentTab, close, select } = useTabs ( ) ;
303+ const newTab = useNewTab ( ) ;
304+
305+ useHotkeys (
306+ "mod+n" ,
307+ ( ) => {
308+ if ( currentTab ) {
309+ close ( currentTab ) ;
310+ }
311+ newTab ( ) ;
312+ } ,
313+ { preventDefault : true } ,
314+ [ currentTab , close , newTab ] ,
315+ ) ;
316+
317+ useHotkeys (
318+ "mod+t" ,
319+ ( ) => newTab ( ) ,
320+ { preventDefault : true } ,
321+ [ newTab ] ,
322+ ) ;
323+
324+ useHotkeys (
325+ "mod+w" ,
326+ async ( ) => {
327+ if ( currentTab && tabs . length > 1 ) {
328+ close ( currentTab ) ;
329+ } else {
330+ const appWindow = getCurrentWebviewWindow ( ) ;
331+ await appWindow . close ( ) ;
332+ }
333+ } ,
334+ { preventDefault : true } ,
335+ [ tabs , currentTab , close ] ,
336+ ) ;
337+
338+ useHotkeys (
339+ "mod+1, mod+2, mod+3, mod+4, mod+5, mod+6, mod+7, mod+8, mod+9" ,
340+ ( event ) => {
341+ const key = event . key ;
342+ const targetIndex = key === "9" ? tabs . length - 1 : Number . parseInt ( key , 10 ) - 1 ;
343+ const target = tabs [ targetIndex ] ;
344+ if ( target ) {
345+ select ( target ) ;
346+ }
347+ } ,
348+ { preventDefault : true } ,
349+ [ tabs , select ] ,
350+ ) ;
351+
352+ return { } ;
353+ }
354+
355+ function useNewTab ( ) {
356+ const { persistedStore, internalStore } = useRouteContext ( { from : "__root__" } ) ;
357+ const { openNew } = useTabs ( ) ;
358+
359+ const handler = useCallback ( ( ) => {
360+ const user_id = internalStore ?. getValue ( "user_id" ) ;
361+ const sessionId = id ( ) ;
362+
363+ persistedStore ?. setRow ( "sessions" , sessionId , {
364+ user_id,
365+ created_at : new Date ( ) . toISOString ( ) ,
366+ title : "" ,
367+ } ) ;
368+
369+ openNew ( {
370+ type : "sessions" ,
371+ id : sessionId ,
372+ active : true ,
373+ state : { editor : "raw" } ,
374+ } ) ;
375+ } , [ persistedStore , internalStore , openNew ] ) ;
376+
377+ return handler ;
378+ }
0 commit comments