You've already forked AstralRinth
forked from didirus/AstralRinth
0.8.0 beta fixes (#2154)
* initial fixes * 0.8.0 beta fixes * run actions * run fmt * Fix windows build * Add purge cache opt * add must revalidate to project req * lint + clippy * fix processes, open folder * Update migrator to use old launcher cache for perf * fix empty dirs not moving * fix lint + create natives dir if not exist * fix large request batches * finish * Fix deep linking on mac * fix comp err * fix comp err (2) --------- Signed-off-by: Geometrically <18202329+Geometrically@users.noreply.github.com>
This commit is contained in:
@@ -6,19 +6,20 @@ macro_rules! impl_cache_methods {
|
||||
$(
|
||||
paste::paste! {
|
||||
#[tauri::command]
|
||||
pub async fn [<get_ $variant:snake>](id: &str) -> Result<Option<$type>>
|
||||
pub async fn [<get_ $variant:snake>](id: &str, cache_behaviour: Option<CacheBehaviour>) -> Result<Option<$type>>
|
||||
{
|
||||
Ok(theseus::cache::[<get_ $variant:snake>](id).await?)
|
||||
Ok(theseus::cache::[<get_ $variant:snake>](id, cache_behaviour).await?)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn [<get_ $variant:snake _many>](
|
||||
ids: Vec<String>,
|
||||
cache_behaviour: Option<CacheBehaviour>,
|
||||
) -> Result<Vec<$type>>
|
||||
{
|
||||
let ids = ids.iter().map(|x| &**x).collect::<Vec<&str>>();
|
||||
let entries =
|
||||
theseus::cache::[<get_ $variant:snake _many>](&*ids).await?;
|
||||
theseus::cache::[<get_ $variant:snake _many>](&*ids, cache_behaviour).await?;
|
||||
|
||||
Ok(entries)
|
||||
}
|
||||
@@ -51,6 +52,12 @@ pub fn init<R: tauri::Runtime>() -> tauri::plugin::TauriPlugin<R> {
|
||||
get_organization_many,
|
||||
get_search_results,
|
||||
get_search_results_many,
|
||||
purge_cache_types,
|
||||
])
|
||||
.build()
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn purge_cache_types(cache_types: Vec<CacheValueType>) -> Result<()> {
|
||||
Ok(theseus::cache::purge_cache_types(&cache_types).await?)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use crate::api::Result;
|
||||
use theseus::prelude::*;
|
||||
use uuid::Uuid;
|
||||
|
||||
pub fn init<R: tauri::Runtime>() -> tauri::plugin::TauriPlugin<R> {
|
||||
tauri::plugin::Builder::new("process")
|
||||
@@ -13,21 +14,23 @@ pub fn init<R: tauri::Runtime>() -> tauri::plugin::TauriPlugin<R> {
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn process_get_all() -> Result<Vec<Process>> {
|
||||
pub async fn process_get_all() -> Result<Vec<ProcessMetadata>> {
|
||||
Ok(process::get_all().await?)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn process_get_by_profile_path(path: &str) -> Result<Vec<Process>> {
|
||||
pub async fn process_get_by_profile_path(
|
||||
path: &str,
|
||||
) -> Result<Vec<ProcessMetadata>> {
|
||||
Ok(process::get_by_profile_path(path).await?)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn process_kill(pid: i32) -> Result<()> {
|
||||
Ok(process::kill(pid).await?)
|
||||
pub async fn process_kill(uuid: Uuid) -> Result<()> {
|
||||
Ok(process::kill(uuid).await?)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn process_wait_for(pid: i32) -> Result<()> {
|
||||
Ok(process::wait_for(pid).await?)
|
||||
pub async fn process_wait_for(uuid: Uuid) -> Result<()> {
|
||||
Ok(process::wait_for(uuid).await?)
|
||||
}
|
||||
|
||||
@@ -63,8 +63,9 @@ pub async fn profile_get_many(paths: Vec<String>) -> Result<Vec<Profile>> {
|
||||
#[tauri::command]
|
||||
pub async fn profile_get_projects(
|
||||
path: &str,
|
||||
cache_behaviour: Option<CacheBehaviour>,
|
||||
) -> Result<DashMap<String, ProfileFile>> {
|
||||
let res = profile::get_projects(path).await?;
|
||||
let res = profile::get_projects(path, cache_behaviour).await?;
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
@@ -111,7 +112,7 @@ pub async fn profile_check_installed(
|
||||
) -> Result<bool> {
|
||||
let check_project_id = project_id;
|
||||
|
||||
if let Ok(projects) = profile::get_projects(path).await {
|
||||
if let Ok(projects) = profile::get_projects(path, None).await {
|
||||
Ok(projects.into_iter().any(|(_, project)| {
|
||||
if let Some(metadata) = &project.metadata {
|
||||
check_project_id == metadata.project_id
|
||||
@@ -248,7 +249,7 @@ pub async fn profile_get_pack_export_candidates(
|
||||
// for the actual Child in the state.
|
||||
// invoke('plugin:profile|profile_run', path)
|
||||
#[tauri::command]
|
||||
pub async fn profile_run(path: &str) -> Result<Process> {
|
||||
pub async fn profile_run(path: &str) -> Result<ProcessMetadata> {
|
||||
let process = profile::run(path).await?;
|
||||
|
||||
Ok(process)
|
||||
@@ -262,7 +263,7 @@ pub async fn profile_run(path: &str) -> Result<Process> {
|
||||
pub async fn profile_run_credentials(
|
||||
path: &str,
|
||||
credentials: Credentials,
|
||||
) -> Result<Process> {
|
||||
) -> Result<ProcessMetadata> {
|
||||
let process = profile::run_credentials(path, &credentials).await?;
|
||||
|
||||
Ok(process)
|
||||
|
||||
@@ -3,7 +3,11 @@ use theseus::prelude::*;
|
||||
|
||||
pub fn init<R: tauri::Runtime>() -> tauri::plugin::TauriPlugin<R> {
|
||||
tauri::plugin::Builder::new("settings")
|
||||
.invoke_handler(tauri::generate_handler![settings_get, settings_set])
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
settings_get,
|
||||
settings_set,
|
||||
cancel_directory_change
|
||||
])
|
||||
.build()
|
||||
}
|
||||
|
||||
@@ -22,3 +26,9 @@ pub async fn settings_set(settings: Settings) -> Result<()> {
|
||||
settings::set(settings).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn cancel_directory_change() -> Result<()> {
|
||||
settings::cancel_directory_change().await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -5,7 +5,8 @@ use theseus::{
|
||||
};
|
||||
|
||||
use crate::api::Result;
|
||||
use std::{env, path::PathBuf, process::Command};
|
||||
use dashmap::DashMap;
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub fn init<R: tauri::Runtime>() -> tauri::plugin::TauriPlugin<R> {
|
||||
tauri::plugin::Builder::new("utils")
|
||||
@@ -44,7 +45,7 @@ pub enum OS {
|
||||
// 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>> {
|
||||
) -> Result<DashMap<uuid::Uuid, theseus::LoadingBar>> {
|
||||
let res = theseus::EventState::list_progress_bars().await?;
|
||||
Ok(res)
|
||||
}
|
||||
@@ -71,72 +72,20 @@ pub async fn should_disable_mouseover() -> bool {
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn show_in_folder(path: PathBuf) -> Result<()> {
|
||||
{
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
if path.is_dir() {
|
||||
Command::new("explorer")
|
||||
.args([&path]) // The comma after select is not a typo
|
||||
.spawn()?;
|
||||
} else {
|
||||
Command::new("explorer")
|
||||
.args(["/select,", &path.to_string_lossy()]) // The comma after select is not a typo
|
||||
.spawn()?;
|
||||
}
|
||||
}
|
||||
pub fn show_in_folder(path: PathBuf) {
|
||||
let res = opener::reveal(path);
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
use std::fs::metadata;
|
||||
|
||||
let mut path = path;
|
||||
let path_string = path.to_string_lossy().to_string();
|
||||
|
||||
if metadata(&path)?.is_dir() {
|
||||
Command::new("xdg-open").arg(&path).spawn()?;
|
||||
} else if path_string.contains(',') {
|
||||
// see https://gitlab.freedesktop.org/dbus/dbus/-/issues/76
|
||||
path.pop();
|
||||
Command::new("xdg-open").arg(&path).spawn()?;
|
||||
} else {
|
||||
Command::new("dbus-send")
|
||||
.args([
|
||||
"--session",
|
||||
"--dest=org.freedesktop.FileManager1",
|
||||
"--type=method_call",
|
||||
"/org/freedesktop/FileManager1",
|
||||
"org.freedesktop.FileManager1.ShowItems",
|
||||
format!("array:string:file://{}", path_string).as_str(),
|
||||
"string:\"\"",
|
||||
])
|
||||
.spawn()?;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
if path.is_dir() {
|
||||
Command::new("open").args([&path]).spawn()?;
|
||||
} else {
|
||||
Command::new("open")
|
||||
.args(["-R", &path.as_os_str().to_string_lossy()])
|
||||
.spawn()?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok::<(), theseus::Error>(())
|
||||
}?;
|
||||
|
||||
Ok(())
|
||||
if let Err(e) = res {
|
||||
tracing::error!("Failed to open folder: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn show_launcher_logs_folder() -> Result<()> {
|
||||
pub fn show_launcher_logs_folder() {
|
||||
let path = DirectoryInfo::launcher_logs_dir().unwrap_or_default();
|
||||
// failure to get folder just opens filesystem
|
||||
// (ie: if in debug mode only and launcher_logs never created)
|
||||
show_in_folder(path)
|
||||
show_in_folder(path);
|
||||
}
|
||||
|
||||
// Get opening command
|
||||
@@ -144,9 +93,28 @@ pub fn show_launcher_logs_folder() -> Result<()> {
|
||||
// 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]
|
||||
#[cfg(target_os = "macos")]
|
||||
pub async fn get_opening_command(
|
||||
state: tauri::State<'_, crate::macos::deep_link::InitialPayload>,
|
||||
) -> Result<Option<CommandPayload>> {
|
||||
let payload = state.payload.lock().await;
|
||||
|
||||
return if let Some(payload) = payload.as_ref() {
|
||||
tracing::info!("opening command {payload}");
|
||||
|
||||
Ok(Some(handler::parse_command(payload).await?))
|
||||
} else {
|
||||
Ok(None)
|
||||
};
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
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 = std::env::args_os().nth(1);
|
||||
|
||||
tracing::info!("opening command {cmd_arg:?}");
|
||||
|
||||
let cmd_arg = cmd_arg.map(|path| path.to_string_lossy().to_string());
|
||||
if let Some(cmd) = cmd_arg {
|
||||
|
||||
6
apps/app/src/macos/deep_link.rs
Normal file
6
apps/app/src/macos/deep_link.rs
Normal file
@@ -0,0 +1,6 @@
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
pub struct InitialPayload {
|
||||
pub payload: Arc<Mutex<Option<String>>>,
|
||||
}
|
||||
@@ -1,2 +1,3 @@
|
||||
pub mod deep_link;
|
||||
pub mod delegate;
|
||||
pub mod window_ext;
|
||||
|
||||
@@ -16,12 +16,25 @@ mod macos;
|
||||
#[tracing::instrument(skip_all)]
|
||||
#[tauri::command]
|
||||
async fn initialize_state(app: tauri::AppHandle) -> api::Result<()> {
|
||||
theseus::EventState::init(app).await?;
|
||||
theseus::EventState::init(app.clone()).await?;
|
||||
State::init().await?;
|
||||
|
||||
let state = State::get().await?;
|
||||
app.asset_protocol_scope()
|
||||
.allow_directory(state.directories.caches_dir(), true)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Should be call once Vue has mounted the app
|
||||
#[tracing::instrument(skip_all)]
|
||||
#[tauri::command]
|
||||
fn show_window(app: tauri::AppHandle) {
|
||||
let win = app.get_window("main").unwrap();
|
||||
win.show().unwrap();
|
||||
win.set_focus().unwrap();
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn is_dev() -> bool {
|
||||
cfg!(debug_assertions)
|
||||
@@ -76,41 +89,84 @@ fn main() {
|
||||
}))
|
||||
.plugin(tauri_plugin_window_state::Builder::default().build())
|
||||
.setup(|app| {
|
||||
// Register deep link handler, allowing reading of modrinth:// links
|
||||
if let Err(e) = tauri_plugin_deep_link::register(
|
||||
#[cfg(target_os = "macos")]
|
||||
let res = {
|
||||
use macos::deep_link::InitialPayload;
|
||||
let mtx = std::sync::Arc::new(tokio::sync::Mutex::new(None));
|
||||
|
||||
app.manage(InitialPayload {
|
||||
payload: mtx.clone(),
|
||||
});
|
||||
|
||||
let mtx_copy = mtx.clone();
|
||||
macos::delegate::register_open_file(move |filename| {
|
||||
let mtx_copy = mtx_copy.clone();
|
||||
|
||||
tauri::async_runtime::spawn(async move {
|
||||
tracing::info!("Handling file open {filename}");
|
||||
|
||||
let mut payload = mtx_copy.lock().await;
|
||||
if payload.is_none() {
|
||||
*payload = Some(filename.clone());
|
||||
}
|
||||
|
||||
let _ = api::utils::handle_command(filename).await;
|
||||
});
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let mtx_copy = mtx.clone();
|
||||
tauri_plugin_deep_link::register(
|
||||
"modrinth",
|
||||
move |request: String| {
|
||||
let mtx_copy = mtx_copy.clone();
|
||||
|
||||
tauri::async_runtime::spawn(async move {
|
||||
tracing::info!("Handling deep link {request}");
|
||||
|
||||
let mut payload = mtx_copy.lock().await;
|
||||
if payload.is_none() {
|
||||
*payload = Some(request.clone());
|
||||
}
|
||||
|
||||
let _ = api::utils::handle_command(request).await;
|
||||
});
|
||||
},
|
||||
)
|
||||
};
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
let res = tauri_plugin_deep_link::register(
|
||||
"modrinth",
|
||||
|request: String| {
|
||||
tracing::info!("Handling deep link {request}");
|
||||
tauri::async_runtime::spawn(api::utils::handle_command(
|
||||
request,
|
||||
));
|
||||
},
|
||||
) {
|
||||
// Allow it to fail- see https://github.com/FabianLars/tauri-plugin-deep-link/issues/19
|
||||
);
|
||||
|
||||
if let Err(e) = res {
|
||||
tracing::error!("Error registering deep link handler: {}", e);
|
||||
}
|
||||
|
||||
let win = app.get_window("main").unwrap();
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
{
|
||||
use window_shadows::set_shadow;
|
||||
set_shadow(&win, true).unwrap();
|
||||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
use macos::window_ext::WindowExt;
|
||||
win.set_transparent_titlebar(true);
|
||||
win.position_traffic_lights(9.0, 16.0);
|
||||
if let Some(window) = app.get_window("main") {
|
||||
// Hide window to prevent white flash on startup
|
||||
window.hide().unwrap();
|
||||
|
||||
macos::delegate::register_open_file(|filename| {
|
||||
tauri::async_runtime::spawn(api::utils::handle_command(
|
||||
filename,
|
||||
));
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
{
|
||||
use window_shadows::set_shadow;
|
||||
set_shadow(&window, true).unwrap();
|
||||
}
|
||||
|
||||
// Show app now that we are setup
|
||||
win.show().unwrap();
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
use macos::window_ext::WindowExt;
|
||||
window.set_transparent_titlebar(true);
|
||||
window.position_traffic_lights(9.0, 16.0);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
});
|
||||
@@ -148,6 +204,7 @@ fn main() {
|
||||
toggle_decorations,
|
||||
api::auth::auth_login,
|
||||
api::mr_auth::modrinth_auth_login,
|
||||
show_window,
|
||||
]);
|
||||
|
||||
builder
|
||||
|
||||
Reference in New Issue
Block a user