11import { useEffect } from 'react' ;
2- import { Outlet , useParams } from 'react-router' ;
2+ import { Outlet , useLocation , useNavigate , useParams } from 'react-router' ;
33import EditorBar from './EditorBar/EditorBar' ;
44import { SettingsEffects } from './features/settings/SettingsEffects' ;
55import { useAuthStore } from '@/auth/useAuthStore' ;
@@ -10,6 +10,8 @@ import { useSettingsStore } from './store/useSettingsStore';
1010
1111function Editor ( ) {
1212 const { projectId } = useParams ( ) ;
13+ const location = useLocation ( ) ;
14+ const navigate = useNavigate ( ) ;
1315 const token = useAuthStore ( ( state ) => state . token ) ;
1416 const setProject = useEditorStore ( ( state ) => state . setProject ) ;
1517 const setMirDoc = useEditorStore ( ( state ) => state . setMirDoc ) ;
@@ -94,6 +96,47 @@ function Editor() {
9496
9597 useEffect ( ( ) => mountGraphExecutionBridge ( ) , [ ] ) ;
9698
99+ useEffect ( ( ) => {
100+ if ( ! projectId ) return ;
101+
102+ const isEditableTarget = ( target : EventTarget | null ) => {
103+ if ( ! ( target instanceof HTMLElement ) ) return false ;
104+ if ( target . isContentEditable ) return true ;
105+ const tagName = target . tagName . toLowerCase ( ) ;
106+ return (
107+ tagName === 'input' || tagName === 'textarea' || tagName === 'select'
108+ ) ;
109+ } ;
110+
111+ const routeByDigit : Record < string , string > = {
112+ '1' : `/editor/project/${ projectId } ` ,
113+ '2' : `/editor/project/${ projectId } /blueprint` ,
114+ '3' : `/editor/project/${ projectId } /nodegraph` ,
115+ '4' : `/editor/project/${ projectId } /animation` ,
116+ '5' : `/editor/project/${ projectId } /component` ,
117+ '6' : `/editor/project/${ projectId } /resources` ,
118+ '7' : `/editor/project/${ projectId } /test` ,
119+ '8' : `/editor/project/${ projectId } /export` ,
120+ '9' : `/editor/project/${ projectId } /deployment` ,
121+ } ;
122+
123+ const onKeyDown = ( event : globalThis . KeyboardEvent ) => {
124+ if ( event . defaultPrevented ) return ;
125+ if ( isEditableTarget ( event . target ) ) return ;
126+ if ( ! event . altKey || event . ctrlKey || event . metaKey || event . shiftKey ) {
127+ return ;
128+ }
129+ const nextPath = routeByDigit [ event . key ] ;
130+ if ( ! nextPath ) return ;
131+ if ( location . pathname === nextPath ) return ;
132+ event . preventDefault ( ) ;
133+ navigate ( nextPath ) ;
134+ } ;
135+
136+ window . addEventListener ( 'keydown' , onKeyDown ) ;
137+ return ( ) => window . removeEventListener ( 'keydown' , onKeyDown ) ;
138+ } , [ location . pathname , navigate , projectId ] ) ;
139+
97140 return (
98141 < div className = "flex min-h-screen max-h-screen flex-row bg-[linear-gradient(120deg,var(--color-0)_20%,var(--color-1)_100%)]" >
99142 < SettingsEffects />
0 commit comments