1- import { invoke } from "@tauri-apps/api/core" ;
2- import { emit , listen } from "@tauri-apps/api/event" ;
3- import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow" ;
41import { enableMapSet } from "immer" ;
52import { useEffect } from "react" ;
63import { useKeymapContext } from "@/features/keymaps/hooks/use-keymap-context" ;
74import { useKeymaps } from "@/features/keymaps/hooks/use-keymaps" ;
5+ import { useRemoteConnection } from "@/features/remote/hooks/use-remote-connection" ;
6+ import { useRemoteWindowClose } from "@/features/remote/hooks/use-remote-window-close" ;
87import { FontStyleInjector } from "@/features/settings/components/font-style-injector" ;
8+ import { useContextMenuPrevention } from "@/features/window/hooks/use-context-menu-prevention" ;
9+ import { useFontLoading } from "@/features/window/hooks/use-font-loading" ;
10+ import { usePlatformSetup } from "@/features/window/hooks/use-platform-setup" ;
911import { useScroll } from "@/features/window/hooks/use-scroll" ;
1012import { initializeIconThemes } from "./extensions/icon-themes/icon-theme-initializer" ;
1113import { initializeThemeSystem } from "./extensions/themes/theme-initializer" ;
1214import {
1315 cleanupFileWatcherListener ,
1416 initializeFileWatcherListener ,
1517} from "./features/file-system/controllers/file-watcher-store" ;
16- import { isMac } from "./features/file-system/controllers/platform" ;
1718import { MainLayout } from "./features/layout/components/main-layout" ;
1819import { ZoomIndicator } from "./features/layout/components/zoom-indicator" ;
19- import { useAppStore } from "./stores/app-store" ;
20- import { useFontStore } from "./stores/font-store" ;
21- import { useSidebarStore } from "./stores/sidebar-store" ;
2220import { useZoomStore } from "./stores/zoom-store" ;
2321import { ToastContainer } from "./ui/toast" ;
2422import { cn } from "./utils/cn" ;
@@ -37,150 +35,35 @@ import { initializeExtensionStore } from "./extensions/registry/extension-store"
3735import { initializeWasmTokenizer } from "./features/editor/lib/wasm-parser" ;
3836import { initializeKeymaps } from "./features/keymaps/init" ;
3937
40- // Initialize WASM tokenizer (required for parser infrastructure)
4138initializeWasmTokenizer ( ) . catch ( console . error ) ;
42-
4339extensionLoader . initialize ( ) . catch ( console . error ) ;
44-
45- // Initialize extension store (load available and installed extensions)
4640initializeExtensionStore ( ) . catch ( console . error ) ;
47-
48- // Initialize keymaps system
4941initializeKeymaps ( ) ;
5042
5143function App ( ) {
5244 enableMapSet ( ) ;
5345
54- const { cleanup } = useAppStore . use . actions ( ) ;
55- const { loadAvailableFonts } = useFontStore . use . actions ( ) ;
56- const setRemoteWindow = useSidebarStore . use . setRemoteWindow ( ) ;
5746 const zoomLevel = useZoomStore . use . windowZoomLevel ( ) ;
5847
59- // Platform-specific setup
60- useEffect ( ( ) => {
61- if ( isMac ( ) ) {
62- document . documentElement . classList . add ( "platform-macos" ) ;
63- } else {
64- document . documentElement . classList . add ( "platform-other" ) ;
65- }
66-
67- return ( ) => {
68- document . documentElement . classList . remove ( "platform-macos" , "platform-other" ) ;
69- cleanup ( ) ; // Cleanup autosave timeouts
70- } ;
71- } , [ cleanup ] ) ;
72-
73- // Initialize fonts on app start (will use cache if available)
74- useEffect ( ( ) => {
75- loadAvailableFonts ( ) ;
76- } , [ loadAvailableFonts ] ) ;
77-
78- // Mouse wheel zoom functionality
48+ // App initialization and setup hooks
49+ usePlatformSetup ( ) ;
50+ useFontLoading ( ) ;
7951 useScroll ( ) ;
80-
81- // Extension installation prompts
8252 useExtensionInstallPrompt ( ) ;
83-
84- // Track keymap contexts (editor focus, vim mode, etc.)
8553 useKeymapContext ( ) ;
86-
87- // Unified keyboard handler
8854 useKeymaps ( ) ;
55+ useRemoteConnection ( ) ;
56+ useRemoteWindowClose ( ) ;
57+ useContextMenuPrevention ( ) ;
8958
90- // Initialize file watcher
59+ // File watcher setup
9160 useEffect ( ( ) => {
9261 initializeFileWatcherListener ( ) ;
9362 return ( ) => {
9463 cleanupFileWatcherListener ( ) ;
9564 } ;
9665 } , [ ] ) ;
9766
98- // Listen for remote connection info and handle remote window setup
99- useEffect ( ( ) => {
100- // Check if this is a remote window from URL parameter
101- const urlParams = new URLSearchParams ( window . location . search ) ;
102- const remoteParam = urlParams . get ( "remote" ) ;
103- if ( remoteParam ) {
104- setRemoteWindow ( true , undefined , remoteParam ) ;
105- }
106-
107- // Set up event listener for remote connection info from Tauri
108- let unlistenRemoteInfo : ( ( ) => void ) | null = null ;
109-
110- const setupRemoteListener = async ( ) => {
111- try {
112- unlistenRemoteInfo = await listen < {
113- connectionId : string ;
114- connectionName : string ;
115- isRemoteWindow : boolean ;
116- } > ( "remote-connection-info" , ( event ) => {
117- const { isRemoteWindow, connectionName, connectionId } = event . payload ;
118- setRemoteWindow ( isRemoteWindow , connectionName , connectionId ) ;
119- } ) ;
120- } catch ( error ) {
121- console . error ( "Failed to set up remote connection listener:" , error ) ;
122- }
123- } ;
124-
125- setupRemoteListener ( ) ;
126-
127- return ( ) => {
128- if ( unlistenRemoteInfo ) {
129- unlistenRemoteInfo ( ) ;
130- }
131- } ;
132- } , [ setRemoteWindow ] ) ;
133-
134- // Handle window close request for remote connections
135- useEffect ( ( ) => {
136- const urlParams = new URLSearchParams ( window . location . search ) ;
137- const remoteParam = urlParams . get ( "remote" ) ;
138-
139- if ( ! remoteParam ) return ;
140-
141- let unlistenCloseRequested : ( ( ) => void ) | null = null ;
142-
143- const setupCloseListener = async ( ) => {
144- try {
145- const currentWindow = getCurrentWebviewWindow ( ) ;
146-
147- unlistenCloseRequested = await currentWindow . onCloseRequested ( async ( event ) => {
148- event . preventDefault ( ) ;
149-
150- try {
151- await invoke ( "ssh_disconnect_only" , { connectionId : remoteParam } ) ;
152- await emit ( "remote-connection-disconnected" , { connectionId : remoteParam } ) ;
153- await currentWindow . destroy ( ) ;
154- } catch ( error ) {
155- console . error ( "Failed to cleanup on window close:" , error ) ;
156- await currentWindow . destroy ( ) ;
157- }
158- } ) ;
159- } catch ( error ) {
160- console . error ( "Failed to set up window close listener:" , error ) ;
161- }
162- } ;
163-
164- setupCloseListener ( ) ;
165-
166- return ( ) => {
167- unlistenCloseRequested ?.( ) ;
168- } ;
169- } , [ ] ) ;
170-
171- // Hide native context menu
172- useEffect ( ( ) => {
173- if ( import . meta. env . MODE === "production" ) {
174- const handleContextMenu = ( event : MouseEvent ) => {
175- event . preventDefault ( ) ;
176- } ;
177- document . addEventListener ( "contextmenu" , handleContextMenu ) ;
178- return ( ) => {
179- document . removeEventListener ( "contextmenu" , handleContextMenu ) ;
180- } ;
181- }
182- } , [ ] ) ;
183-
18467 return (
18568 < div
18669 className = { cn ( "h-screen w-screen overflow-hidden bg-transparent" ) }
0 commit comments