11import Splitter , { GutterTheme , SplitDirection } from "@devbookhq/splitter" ;
22import Tile from "../components/Tiles/Tile" ;
33import FileExplorer from "../components/Tiles/FileExplorer" ;
4- import { useCallback , useContext , useEffect , useRef , useState } from "react" ;
4+ import { useCallback , useContext , useEffect , useState } from "react" ;
55import Editor from "../components/Tiles/Editor" ;
66import MenuBar from "../components/Menu/MenuBar" ;
77import "./IDE.css" ;
@@ -11,7 +11,6 @@ import { useIDE } from "../utilities/IDEContext";
1111import { registerFileSystemOverlay } from "@codingame/monaco-vscode-files-service-override" ;
1212import TauriFileSystemProvider from "../utilities/TauriFileSystemProvider" ;
1313import { invoke } from "@tauri-apps/api/core" ;
14- import { path } from "@tauri-apps/api" ;
1514import {
1615 Button ,
1716 Divider ,
@@ -26,7 +25,6 @@ import { restartServer } from "../utilities/lsp-client";
2625import BottomBar from "../components/Tiles/BottomBar" ;
2726import { open as openFileDialog } from "@tauri-apps/plugin-dialog" ;
2827import { IStandaloneCodeEditor } from "@codingame/monaco-vscode-api/vscode/vs/editor/standalone/browser/standaloneCodeEditor" ;
29- import { readTextFile , writeTextFile } from "@tauri-apps/plugin-fs" ;
3028
3129export interface IDEProps { }
3230
@@ -43,11 +41,11 @@ export default () => {
4341 const { storeInitialized, store } = useContext ( StoreContext ) ;
4442 const [ openFile , setOpenFile ] = useState < string | null > ( null ) ;
4543 const [ openFiles , setOpenFiles ] = useState < string [ ] > ( [ ] ) ;
46- const [ saveFile , setSaveFile ] = useState < ( ( ) => void ) | null > ( null ) ;
44+ const [ saveFile , setSaveFile ] = useState < ( ( ) => Promise < void > ) | null > ( null ) ;
4745 const [ undo , setUndo ] = useState < ( ( ) => void ) | null > ( null ) ;
4846 const [ redo , setRedo ] = useState < ( ( ) => void ) | null > ( null ) ;
4947 const [ theme ] = useStore < "light" | "dark" > ( "appearance/theme" , "dark" ) ;
50- const { path : filePath } = useParams < "path" > ( ) ;
48+ const { path } = useParams < "path" > ( ) ;
5149 const { openFolderDialog, selectedToolchain, hasLimitedRam, initialized } =
5250 useIDE ( ) ;
5351 const [ sourcekitStartup , setSourcekitStartup ] = useStore < boolean | null > (
@@ -59,84 +57,48 @@ export default () => {
5957 false
6058 ) ;
6159
62- if ( ! filePath ) {
60+ if ( ! path ) {
6361 throw new Error ( "Path parameter is required in IDE component" ) ;
6462 }
6563
66- const [ callbacks , setCallbacks ] = useState < Record < string , ( ) => void > > ( { } ) ;
64+ const [ callbacks , setCallbacks ] = useState <
65+ Record < string , ( ( ) => void ) | ( ( ) => Promise < void > ) >
66+ > ( { } ) ;
6767 const navigate = useNavigate ( ) ;
6868 const [ projectValidation , setProjectValidation ] =
6969 useState < ProjectValidation | null > ( null ) ;
7070 const [ editor , setEditor ] = useState < IStandaloneCodeEditor | null > ( null ) ;
7171 const { addToast } = useToast ( ) ;
7272
73- const hasAttemptedToReadOpenFiles = useRef < string | null > ( null ) ;
74-
75- useEffect ( ( ) => {
76- ( async ( ) => {
77- if ( ! filePath ) return ;
78- const savePath = await path . join (
79- filePath ,
80- ".crosscode" ,
81- "openFiles.json"
82- ) ;
83- try {
84- let text = await readTextFile ( savePath ) ;
85- console . log ( text ) ;
86- if ( ! text ) return ;
87- let files = JSON . parse ( text ) as string [ ] ;
88- setOpenFiles ( files ) ;
89- } catch ( e ) {
90- void e ;
91- } finally {
92- hasAttemptedToReadOpenFiles . current = filePath ;
93- }
94- } ) ( ) ;
95- } , [ filePath ] ) ;
96-
97- useEffect ( ( ) => {
98- ( async ( ) => {
99- if ( ! filePath || hasAttemptedToReadOpenFiles . current !== filePath ) return ;
100- const savePath = await path . join (
101- filePath ,
102- ".crosscode" ,
103- "openFiles.json"
104- ) ;
105- writeTextFile ( savePath , JSON . stringify ( openFiles ) ) . catch ( ( err ) => {
106- console . error ( "Error writing openFiles.json:" , err ) ;
107- } ) ;
108- } ) ( ) ;
109- } , [ openFiles , filePath ] ) ;
110-
11173 useEffect ( ( ) => {
11274 ( async ( ) => {
113- if ( ! store || ! storeInitialized || ! filePath ) return ;
114- await store . set ( "last-opened-project" , encodeURIComponent ( filePath ! ) ) ;
75+ if ( ! store || ! storeInitialized || ! path ) return ;
76+ await store . set ( "last-opened-project" , encodeURIComponent ( path ! ) ) ;
11577 } ) ( ) ;
116- } , [ filePath , store , storeInitialized ] ) ;
78+ } , [ path , store , storeInitialized ] ) ;
11779
11880 useEffect ( ( ) => {
11981 if (
120- filePath === undefined ||
121- filePath === null ||
82+ path === undefined ||
83+ path === null ||
12284 selectedToolchain === null ||
12385 ! initialized
12486 )
12587 return ;
12688 setProjectValidation ( null ) ;
12789 ( async ( ) => {
128- if ( filePath ) {
90+ if ( path ) {
12991 const toolchainPath = selectedToolchain ?. path ?? "" ;
13092 const validation = await invoke < ProjectValidation > ( "validate_project" , {
131- projectPath : filePath ,
93+ projectPath : path ,
13294 toolchainPath : toolchainPath ,
13395 } ) ;
13496 if ( validation ) {
13597 setProjectValidation ( validation ) ;
13698 }
13799 }
138100 } ) ( ) ;
139- } , [ filePath , selectedToolchain , initialized ] ) ;
101+ } , [ path , selectedToolchain , initialized ] ) ;
140102
141103 useEffect ( ( ) => {
142104 if ( openFiles . length === 0 ) {
@@ -150,7 +112,7 @@ export default () => {
150112 useEffect ( ( ) => {
151113 let dispose = ( ) => { } ;
152114
153- if ( filePath ) {
115+ if ( path ) {
154116 const provider = new TauriFileSystemProvider ( false ) ;
155117 const overlayDisposable = registerFileSystemOverlay ( 1 , provider ) ;
156118 dispose = ( ) => {
@@ -161,7 +123,7 @@ export default () => {
161123 return ( ) => {
162124 dispose ( ) ;
163125 } ;
164- } , [ filePath ] ) ;
126+ } , [ path ] ) ;
165127
166128 useEffect ( ( ) => {
167129 let autoEnable = async ( ) => {
@@ -176,17 +138,17 @@ export default () => {
176138 if ( ! sourcekitStartup || selectedToolchain == null ) return ;
177139 requestAnimationFrame ( async ( ) => {
178140 try {
179- if ( autoStartedLsp === filePath ) return ;
180- autoStartedLsp = filePath ;
181- await restartServer ( filePath , selectedToolchain ) ;
141+ if ( autoStartedLsp === path ) return ;
142+ autoStartedLsp = path ;
143+ await restartServer ( path , selectedToolchain ) ;
182144 } catch ( e ) {
183145 console . error ( "Failed to start SourceKit-LSP:" , e ) ;
184146 addToast . error (
185147 "Failed to start SourceKit-LSP (see devtools for details). Some language features may not be available."
186148 ) ;
187149 }
188150 } ) ;
189- } , [ sourcekitStartup , filePath , selectedToolchain ] ) ;
151+ } , [ sourcekitStartup , path , selectedToolchain ] ) ;
190152
191153 const openNewFile = useCallback ( ( file : string ) => {
192154 setOpenFile ( file ) ;
@@ -205,7 +167,7 @@ export default () => {
205167
206168 useEffect ( ( ) => {
207169 setCallbacks ( {
208- save : saveFile ?? ( ( ) => { } ) ,
170+ save : saveFile ?? ( async ( ) => { } ) ,
209171 openFolderDialog,
210172 newProject : ( ) => navigate ( "/new" ) ,
211173 welcomePage : ( ) => navigate ( "/" ) ,
@@ -224,7 +186,7 @@ export default () => {
224186 initialSizes = { [ 20 , 80 ] }
225187 >
226188 < Tile className = "file-explorer-tile" >
227- < FileExplorer openFolder = { filePath } setOpenFile = { openNewFile } />
189+ < FileExplorer openFolder = { path } setOpenFile = { openNewFile } />
228190 </ Tile >
229191 < Splitter
230192 gutterTheme = { theme === "dark" ? GutterTheme . Dark : GutterTheme . Light }
0 commit comments