2023-08-04 20:33:50 -07:00
use serde ::{ Deserialize , Serialize } ;
2023-06-30 08:11:32 -07:00
use theseus ::{ handler , prelude ::CommandPayload , State } ;
2023-06-02 07:09:46 -07:00
use crate ::api ::Result ;
2023-06-30 08:11:32 -07:00
use std ::{ env , process ::Command } ;
2023-06-02 07:09:46 -07:00
2023-06-28 09:58:58 -07:00
pub fn init < R : tauri ::Runtime > ( ) -> tauri ::plugin ::TauriPlugin < R > {
tauri ::plugin ::Builder ::new ( " utils " )
. invoke_handler ( tauri ::generate_handler! [
2023-08-04 20:33:50 -07:00
get_os ,
2023-06-28 09:58:58 -07:00
should_disable_mouseover ,
show_in_folder ,
progress_bars_list ,
2023-06-30 08:11:32 -07:00
safety_check_safe_loading_bars ,
get_opening_command ,
await_sync ,
2023-08-04 19:51:46 -07:00
is_offline ,
refresh_offline
2023-06-28 09:58:58 -07:00
] )
. build ( )
}
2023-08-04 20:33:50 -07:00
/// Gets OS
#[ tauri::command ]
pub fn get_os ( ) -> OS {
#[ cfg(target_os = " windows " ) ]
let os = OS ::Windows ;
#[ cfg(target_os = " linux " ) ]
let os = OS ::Linux ;
#[ cfg(target_os = " macos " ) ]
let os = OS ::MacOS ;
os
}
#[ derive(Debug, Clone, Serialize, Deserialize) ]
pub enum OS {
Windows ,
Linux ,
MacOS ,
}
2023-06-28 09:58:58 -07:00
// Lists active progress bars
// Create a new HashMap with the same keys
// Values provided should not be used directly, as they are not guaranteed to be up-to-date
#[ tauri::command ]
pub async fn progress_bars_list (
) -> Result < std ::collections ::HashMap < uuid ::Uuid , theseus ::LoadingBar > > {
let res = theseus ::EventState ::list_progress_bars ( ) . await ? ;
Ok ( res )
}
2023-06-30 08:11:32 -07:00
// Check if there are any safe loading bars running
#[ tauri::command ]
pub async fn safety_check_safe_loading_bars ( ) -> Result < bool > {
Ok ( theseus ::safety ::check_safe_loading_bars ( ) . await ? )
}
2023-06-02 07:09:46 -07:00
// cfg only on mac os
// disables mouseover and fixes a random crash error only fixed by recent versions of macos
#[ cfg(target_os = " macos " ) ]
#[ tauri::command ]
pub async fn should_disable_mouseover ( ) -> bool {
// We try to match version to 12.2 or higher. If unrecognizable to pattern or lower, we default to the css with disabled mouseover for safety
let os = os_info ::get ( ) ;
if let os_info ::Version ::Semantic ( major , minor , _ ) = os . version ( ) {
if * major > = 12 & & * minor > = 3 {
// Mac os version is 12.3 or higher, we allow mouseover
return false ;
}
}
true
}
#[ cfg(not(target_os = " macos " )) ]
#[ tauri::command ]
pub async fn should_disable_mouseover ( ) -> bool {
false
}
#[ tauri::command ]
pub fn show_in_folder ( path : String ) -> Result < ( ) > {
{
#[ cfg(target_os = " windows " ) ]
{
Command ::new ( " explorer " )
2023-07-28 19:56:49 -07:00
. args ( [ & path ] ) // The comma after select is not a typo
2023-06-02 07:09:46 -07:00
. spawn ( ) ? ;
}
#[ cfg(target_os = " linux " ) ]
{
use std ::fs ::metadata ;
use std ::path ::PathBuf ;
2023-06-26 14:29:53 -07:00
if path . contains ( ',' ) {
2023-06-02 07:09:46 -07:00
// see https://gitlab.freedesktop.org/dbus/dbus/-/issues/76
let new_path = match metadata ( & path ) ? . is_dir ( ) {
2023-06-26 14:29:53 -07:00
true = > path ,
2023-06-02 07:09:46 -07:00
false = > {
2023-06-26 14:29:53 -07:00
let mut path2 = PathBuf ::from ( path ) ;
2023-06-02 07:09:46 -07:00
path2 . pop ( ) ;
path2 . to_string_lossy ( ) . to_string ( )
}
} ;
Command ::new ( " xdg-open " ) . arg ( & new_path ) . spawn ( ) ? ;
} else {
2023-06-22 19:04:15 +02:00
Command ::new ( " xdg-open " ) . arg ( & path ) . spawn ( ) ? ;
2023-06-02 07:09:46 -07:00
}
}
#[ cfg(target_os = " macos " ) ]
{
2023-07-28 19:56:49 -07:00
Command ::new ( " open " ) . args ( [ & path ] ) . spawn ( ) ? ;
2023-06-02 07:09:46 -07:00
}
Ok ::< ( ) , theseus ::Error > ( ( ) )
} ? ;
Ok ( ( ) )
}
2023-06-30 08:11:32 -07:00
// Get opening command
// For example, if a user clicks on an .mrpack to open the app.
// This should be called once and only when the app is done booting up and ready to receive a command
// Returns a Command struct- see events.js
#[ tauri::command ]
pub async fn get_opening_command ( ) -> Result < Option < CommandPayload > > {
// Tauri is not CLI, we use arguments as path to file to call
let cmd_arg = env ::args_os ( ) . nth ( 1 ) ;
let cmd_arg = cmd_arg . map ( | path | path . to_string_lossy ( ) . to_string ( ) ) ;
if let Some ( cmd ) = cmd_arg {
tracing ::debug! ( " Opening command: {:?} " , cmd ) ;
return Ok ( Some ( handler ::parse_command ( & cmd ) . await ? ) ) ;
}
Ok ( None )
}
// helper function called when redirected by a weblink (ie: modrith://do-something) or when redirected by a .mrpack file (in which case its a filepath)
// We hijack the deep link library (which also contains functionality for instance-checking)
pub async fn handle_command ( command : String ) -> Result < ( ) > {
Ok ( theseus ::handler ::parse_and_emit_command ( & command ) . await ? )
}
// Waits for state to be synced
#[ tauri::command ]
pub async fn await_sync ( ) -> Result < ( ) > {
State ::sync ( ) . await ? ;
2023-07-21 20:16:07 -07:00
tracing ::debug! ( " State synced " ) ;
2023-06-30 08:11:32 -07:00
Ok ( ( ) )
}
2023-08-04 19:51:46 -07:00
/// Check if theseus is currently in offline mode, without a refresh attempt
#[ tauri::command ]
pub async fn is_offline ( ) -> Result < bool > {
let state = State ::get ( ) . await ? ;
let offline = * state . offline . read ( ) . await ;
Ok ( offline )
}
/// Refreshes whether or not theseus is in offline mode, and returns the new value
#[ tauri::command ]
pub async fn refresh_offline ( ) -> Result < bool > {
let state = State ::get ( ) . await ? ;
state . refresh_offline ( ) . await ? ;
let offline = * state . offline . read ( ) . await ;
Ok ( offline )
}