@@ -12,6 +12,11 @@ import { Log } from "./logger";
1212import { sc } from "./sizeScaler" ;
1313import { Server } from "./types" ;
1414import { useGenericPersistentState } from "../states/genericStates" ;
15+ import { save } from '@tauri-apps/api/dialog' ;
16+ import { writeTextFile } from '@tauri-apps/api/fs' ;
17+ import { useNotification } from "../states/notification" ;
18+ import { open } from '@tauri-apps/api/dialog' ;
19+ import { readTextFile } from '@tauri-apps/api/fs' ;
1520
1621export const copySharedFilesIntoGameFolder = async ( ) => {
1722 const { gtasaPath } = useSettings . getState ( ) ;
@@ -315,3 +320,153 @@ export const checkDirectoryValidity = async (
315320
316321 return true ;
317322} ;
323+
324+ export const exportFavoriteListFile = async ( ) => {
325+ const { favorites } = usePersistentServers . getState ( ) ;
326+
327+ if ( ! favorites . length ) {
328+ const { showMessageBox } = useMessageBox . getState ( ) ;
329+ showMessageBox ( {
330+ title : t ( "export_no_servers_title" ) ,
331+ description : t ( "export_no_servers_description" ) ,
332+ buttons : [
333+ {
334+ title : "OK" ,
335+ onPress : ( ) => { } ,
336+ } ,
337+ ] ,
338+ } ) ;
339+ return ;
340+ }
341+
342+ try {
343+ const exportData = {
344+ version : 1 ,
345+ servers : favorites . map ( server => ( {
346+ ip : server . ip ,
347+ port : server . port ,
348+ name : server . hostname ,
349+ password : server . password || ""
350+ } ) )
351+ } ;
352+
353+ const jsonString = JSON . stringify ( exportData , null , 2 ) ;
354+
355+ const savePath = await save ( {
356+ filters : [ {
357+ name : 'JSON' ,
358+ extensions : [ 'json' ]
359+ } ] ,
360+ defaultPath : 'omp_servers.json'
361+ } ) ;
362+
363+ if ( savePath ) {
364+ await writeTextFile ( savePath , jsonString ) ;
365+
366+ const { showNotification } = useNotification . getState ( ) ;
367+ showNotification (
368+ t ( "export_successful_title" ) ,
369+ t ( "export_successful_description" , { count : favorites . length , path : savePath } )
370+ ) ;
371+ }
372+ } catch ( error ) {
373+ Log . debug ( "Error exporting servers:" , error ) ;
374+ const { showMessageBox } = useMessageBox . getState ( ) ;
375+ showMessageBox ( {
376+ title : t ( "export_failed_title" ) ,
377+ description : t ( "export_failed_description" ) ,
378+ buttons : [
379+ {
380+ title : "OK" ,
381+ onPress : ( ) => { } ,
382+ } ,
383+ ] ,
384+ } ) ;
385+ }
386+ } ;
387+
388+ export const importFavoriteListFile = async ( ) => {
389+ try {
390+ const selected = await open ( {
391+ multiple : false ,
392+ filters : [ {
393+ name : 'JSON' ,
394+ extensions : [ 'json' ]
395+ } ]
396+ } ) ;
397+
398+ if ( ! selected ) return ; // User cancelled the dialog
399+
400+ const fileContent = await readTextFile ( selected as string ) ;
401+ const { addToFavorites } = usePersistentServers . getState ( ) ;
402+ const { showNotification } = useNotification . getState ( ) ;
403+
404+ try {
405+ const data = JSON . parse ( fileContent ) ;
406+
407+ if ( ! data . servers || ! Array . isArray ( data . servers ) ) {
408+ throw new Error ( "Invalid file format: missing servers array" ) ;
409+ }
410+
411+ let importCount = 0 ;
412+
413+ for ( const importedServer of data . servers ) {
414+ if ( importedServer . ip && importedServer . port ) {
415+ const serverInfo : Server = {
416+ ip : importedServer . ip ,
417+ port : Number ( importedServer . port ) ,
418+ hostname : importedServer . name || "Imported Server" ,
419+ playerCount : 0 ,
420+ maxPlayers : 0 ,
421+ gameMode : "-" ,
422+ language : "-" ,
423+ hasPassword : ! ! importedServer . password ,
424+ version : "-" ,
425+ usingOmp : false ,
426+ partner : false ,
427+ ping : 9999 ,
428+ players : [ ] ,
429+ password : importedServer . password || "" ,
430+ rules : { } as Server [ "rules" ] ,
431+ } ;
432+
433+ addToFavorites ( serverInfo ) ;
434+ importCount ++ ;
435+ }
436+ }
437+
438+ showNotification (
439+ t ( "import_successful_title" ) ,
440+ t ( "import_successful_description" , { count : importCount , path : selected } )
441+ ) ;
442+
443+ } catch ( parseError ) {
444+ const { showMessageBox } = useMessageBox . getState ( ) ;
445+ showMessageBox ( {
446+ title : t ( "import_failed_title" ) ,
447+ description : t ( "import_invalid_data_description" ) ,
448+ buttons : [
449+ {
450+ title : "OK" ,
451+ onPress : ( ) => { } ,
452+ } ,
453+ ] ,
454+ } ) ;
455+ Log . debug ( "Error parsing imported file:" , parseError ) ;
456+ }
457+
458+ } catch ( error ) {
459+ const { showMessageBox } = useMessageBox . getState ( ) ;
460+ showMessageBox ( {
461+ title : t ( "import_failed_title" ) ,
462+ description : t ( "import_failed_description" ) ,
463+ buttons : [
464+ {
465+ title : "OK" ,
466+ onPress : ( ) => { } ,
467+ } ,
468+ ] ,
469+ } ) ;
470+ Log . debug ( "Error importing servers:" , error ) ;
471+ }
472+ } ;
0 commit comments