@@ -110,24 +110,21 @@ function getSizeInKB(variable) {
110110}
111111
112112const commands = {
113- help : ( ) => {
114- term . writeln ( '\r\nAvailable commands:' ) ;
115- term . writeln ( ' help - Show this help message' ) ;
116- term . writeln ( ' clear - Clear the terminal' ) ;
117- term . writeln ( ' echo - Echo back your message' ) ;
118- term . writeln ( ' date - Show current date and time' ) ;
119- term . writeln ( ' cd - Change directory: cd dirname or cd .. or cd (for root)' ) ;
120- term . writeln ( ' ls - List files in the current directory' ) ;
121- term . writeln ( ' cat - Show file contents: cat filename' ) ;
122- term . writeln ( ' write - Write to a file: write filename content' ) ;
123- term . writeln ( ' mkdir - Create directory: mkdir dirname' ) ;
124- term . writeln ( ' rmdir - Remove directory: rmdir dirname' ) ;
125- term . writeln ( ' rm - Remove a file: rm filename' ) ;
126- term . writeln ( ' save - Save VFS to browser storage' ) ;
127- term . writeln ( ' load - Load VFS from browser storage' ) ;
128- term . writeln ( ' import - Import VFS from JSON file: import filename.json' ) ;
129- term . writeln ( ' storage - Show VFS storage usage' ) ;
130- term . writeln ( ' about - About this terminal' ) ;
113+ help : async ( ) => {
114+ await fetch ( './assets/help.txt' )
115+ . then ( response => {
116+ if ( response . status === 200 ) {
117+ return response . text ( ) ;
118+ } else {
119+ throw new Error ( 'HTTP ' + response . status ) ;
120+ }
121+ } )
122+ . then ( text => {
123+ text . split ( / \r ? \n / ) . forEach ( line => term . writeln ( line ) ) ;
124+ } )
125+ . catch ( error => {
126+ term . writeln ( 'Error loading file: ' + error ) ;
127+ } ) ;
131128 } ,
132129 clear : ( ) => {
133130 setTimeout ( ( ) => {
@@ -250,27 +247,45 @@ const commands = {
250247 loadVFS ( ) ;
251248 term . writeln ( '\r\nVFS loaded from browser storage.' ) ;
252249 } ,
253- import : ( args ) => {
254- if ( ! args [ 0 ] ) {
255- term . writeln ( '\r\nUsage: import filename.json' ) ;
256- return ;
257- }
258- const filename = args [ 0 ] ;
259- fetch ( filename )
260- . then ( response => {
261- if ( ! response . ok ) {
262- throw new Error ( `HTTP ${ response . status } ` ) ;
250+ import : async ( ) => {
251+ try {
252+ // Open the file picker
253+ const [ fileHandle ] = await window . showOpenFilePicker ( ) ;
254+ const file = await fileHandle . getFile ( ) ;
255+ if ( file . size > 512 * 1024 ) {
256+ term . writeln ( '\r\nFile is too large. Maximum size is 512 KB.' ) ;
257+ return ;
258+ }
259+ const fileContent = await file . text ( ) ;
260+ //check if valid json
261+ try {
262+ const importedVFS = JSON . parse ( fileContent ) ;
263+ if ( typeof importedVFS === 'object' && importedVFS !== null ) {
264+ vfs = importedVFS ;
265+ cwd_path = '/' ; // Reset to root after import
266+ term . writeln ( '\r\nVFS imported successfully.' ) ;
267+ } else {
268+ term . writeln ( '\r\nInvalid VFS format. Must be a JSON object.' ) ;
263269 }
264- return response . json ( ) ;
265- } )
266- . then ( data => {
267- Object . assign ( vfs , data ) ;
268- saveVFS ( ) ;
269- term . writeln ( `\r\nImported ${ Object . keys ( data ) . length } files from ${ filename } ` ) ;
270- } )
271- . catch ( error => {
272- term . writeln ( `\r\nError importing ${ filename } : ${ error . message } ` ) ;
273- } ) ;
270+ } catch ( e ) {
271+ term . writeln ( '\r\nError parsing VFS file. Ensure it is a valid JSON object.' ) ;
272+ }
273+ } catch ( error ) {
274+ term . writeln ( '\r\nError importing VFS:' , error ) ;
275+ }
276+ } ,
277+ export : ( ) => {
278+ const vfsString = JSON . stringify ( vfs , null , 2 ) ;
279+ const blob = new Blob ( [ vfsString ] , { type : 'application/json' } ) ;
280+ const url = URL . createObjectURL ( blob ) ;
281+ const a = document . createElement ( 'a' ) ;
282+ a . href = url ;
283+ a . download = 'vfs.json' ;
284+ document . body . appendChild ( a ) ;
285+ a . click ( ) ;
286+ document . body . removeChild ( a ) ;
287+ URL . revokeObjectURL ( url ) ;
288+ term . writeln ( '\r\nVFS exported as vfs.json' ) ;
274289 } ,
275290 storage : ( ) => {
276291 term . writeln ( '\r\nVirtual File System Storage:' ) ;
@@ -295,10 +310,23 @@ function executeCommand(input) {
295310 }
296311
297312 if ( commands [ command ] ) {
298- commands [ command ] ( args ) ;
313+ const result = commands [ command ] ( args ) ;
314+ // If the command returns a promise, wait for it to complete
315+ if ( result instanceof Promise ) {
316+ result . then ( ( ) => {
317+ prompt ( ) ;
318+ } ) . catch ( error => {
319+ term . writeln ( '\r\nCommand error: ' + error . message ) ;
320+ prompt ( ) ;
321+ } ) ;
322+ } else {
323+ // For non-async commands, show prompt immediately
324+ prompt ( ) ;
325+ }
299326 } else {
300327 term . writeln ( '\r\nCommand not found: ' + command ) ;
301328 term . writeln ( 'Type "help" for available commands.' ) ;
329+ prompt ( ) ;
302330 }
303331}
304332
@@ -314,7 +342,7 @@ term.onData(data => {
314342 if ( code === 13 ) { // Enter key
315343 executeCommand ( currentInput ) ;
316344 currentInput = '' ;
317- prompt ( ) ;
345+ // Note: prompt() is now called from executeCommand after async operations complete
318346 } else if ( code === 127 ) { // Backspace
319347 if ( currentInput . length > 0 ) {
320348 currentInput = currentInput . slice ( 0 , - 1 ) ;
0 commit comments