fix: app states

This commit is contained in:
DecDuck
2025-07-26 17:57:12 +10:00
parent f92ec38231
commit aad2d964eb
7 changed files with 53 additions and 43 deletions
+1
View File
@@ -22,6 +22,7 @@ const router = useRouter();
const state = useAppState(); const state = useAppState();
try { try {
state.value = JSON.parse(await invoke("fetch_state")); state.value = JSON.parse(await invoke("fetch_state"));
console.log(state.value)
} catch (e) { } catch (e) {
console.error("failed to parse state", e); console.error("failed to parse state", e);
} }
+4 -3
View File
@@ -1,10 +1,11 @@
use log::{debug, error}; use log::{debug, error};
use tauri::AppHandle; use tauri::AppHandle;
use tokio::sync::Mutex;
use crate::AppState; use crate::AppState;
#[tauri::command] #[tauri::command]
pub async fn quit(app: tauri::AppHandle, state: tauri::State<'_, std::sync::Mutex<AppState<'_>>>) -> Result<(), ()> { pub async fn quit(app: tauri::AppHandle, state: tauri::State<'_, Mutex<AppState<'_>>>) -> Result<(), ()> {
cleanup_and_exit(&app, &state).await; cleanup_and_exit(&app, &state).await;
Ok(()) Ok(())
@@ -12,10 +13,10 @@ pub async fn quit(app: tauri::AppHandle, state: tauri::State<'_, std::sync::Mute
pub async fn cleanup_and_exit( pub async fn cleanup_and_exit(
app: &AppHandle, app: &AppHandle,
state: &tauri::State<'_, std::sync::Mutex<AppState<'_>>>, state: &tauri::State<'_, Mutex<AppState<'_>>>,
) { ) {
debug!("cleaning up and exiting application"); debug!("cleaning up and exiting application");
let download_manager = state.lock().unwrap().download_manager.clone(); let download_manager = state.lock().await.download_manager.clone();
match download_manager.ensure_terminated().await { match download_manager.ensure_terminated().await {
Ok(res) => match res { Ok(res) => match res {
Ok(_) => debug!("download manager terminated correctly"), Ok(_) => debug!("download manager terminated correctly"),
+5 -3
View File
@@ -1,10 +1,12 @@
use tokio::sync::Mutex;
use crate::AppState; use crate::AppState;
#[tauri::command] #[tauri::command]
pub fn fetch_state( pub async fn fetch_state(
state: tauri::State<'_, std::sync::Mutex<AppState<'_>>>, state: tauri::State<'_, Mutex<AppState<'_>>>,
) -> Result<String, String> { ) -> Result<String, String> {
let guard = state.lock().unwrap(); let guard = state.lock().await;
let cloned_state = serde_json::to_string(&guard.clone()).map_err(|e| e.to_string())?; let cloned_state = serde_json::to_string(&guard.clone()).map_err(|e| e.to_string())?;
drop(guard); drop(guard);
Ok(cloned_state) Ok(cloned_state)
+16 -12
View File
@@ -1,31 +1,35 @@
use std::sync::Mutex; use tokio::sync::Mutex;
use crate::{database::models::data::DownloadableMetadata, AppState}; use crate::{database::models::data::DownloadableMetadata, AppState};
#[tauri::command] #[tauri::command]
pub fn pause_downloads(state: tauri::State<'_, Mutex<AppState>>) { pub async fn pause_downloads(state: tauri::State<'_, Mutex<AppState<'_>>>) -> Result<(), ()> {
state.lock().unwrap().download_manager.pause_downloads() state.lock().await.download_manager.pause_downloads();
Ok(())
} }
#[tauri::command] #[tauri::command]
pub fn resume_downloads(state: tauri::State<'_, Mutex<AppState>>) { pub async fn resume_downloads(state: tauri::State<'_, Mutex<AppState<'_>>>) -> Result<(), ()> {
state.lock().unwrap().download_manager.resume_downloads() state.lock().await.download_manager.resume_downloads();
Ok(())
} }
#[tauri::command] #[tauri::command]
pub fn move_download_in_queue( pub async fn move_download_in_queue(
state: tauri::State<'_, Mutex<AppState>>, state: tauri::State<'_, Mutex<AppState<'_>>>,
old_index: usize, old_index: usize,
new_index: usize, new_index: usize,
) { ) -> Result<(), ()> {
state state
.lock() .lock()
.unwrap() .await
.download_manager .download_manager
.rearrange(old_index, new_index) .rearrange(old_index, new_index);
Ok(())
} }
#[tauri::command] #[tauri::command]
pub fn cancel_game(state: tauri::State<'_, Mutex<AppState>>, meta: DownloadableMetadata) { pub async fn cancel_game(state: tauri::State<'_, Mutex<AppState<'_>>>, meta: DownloadableMetadata) -> Result<(), ()> {
state.lock().unwrap().download_manager.cancel(meta) state.lock().await.download_manager.cancel(meta);
Ok(())
} }
+22 -18
View File
@@ -58,6 +58,7 @@ use remote::commands::{
use remote::fetch_object::{fetch_object, fetch_object_offline}; use remote::fetch_object::{fetch_object, fetch_object_offline};
use remote::server_proto::{handle_server_proto, handle_server_proto_offline}; use remote::server_proto::{handle_server_proto, handle_server_proto_offline};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::fs::File; use std::fs::File;
use std::io::Write; use std::io::Write;
use std::panic::PanicHookInfo; use std::panic::PanicHookInfo;
@@ -65,13 +66,13 @@ use std::path::Path;
use std::str::FromStr; use std::str::FromStr;
use std::sync::Arc; use std::sync::Arc;
use std::time::SystemTime; use std::time::SystemTime;
use std::collections::HashMap;
use std::{env, panic}; use std::{env, panic};
use tauri::menu::{Menu, MenuItem, PredefinedMenuItem}; use tauri::menu::{Menu, MenuItem, PredefinedMenuItem};
use tauri::tray::TrayIconBuilder; use tauri::tray::TrayIconBuilder;
use tauri::{AppHandle, Manager, RunEvent, WindowEvent}; use tauri::{AppHandle, Manager, RunEvent, WindowEvent};
use tauri_plugin_deep_link::DeepLinkExt; use tauri_plugin_deep_link::DeepLinkExt;
use tauri_plugin_dialog::DialogExt; use tauri_plugin_dialog::DialogExt;
use tokio::runtime::Handle;
use tokio::sync::Mutex; use tokio::sync::Mutex;
#[derive(Clone, Copy, Serialize, Eq, PartialEq)] #[derive(Clone, Copy, Serialize, Eq, PartialEq)]
@@ -317,11 +318,14 @@ pub async fn run() {
)) ))
.setup(|app| { .setup(|app| {
let app = app.handle().clone(); let app = app.handle().clone();
let runtime = Handle::current();
tauri::async_runtime::spawn(async move { runtime.spawn(async move {
let state = setup(app.clone()).await; let state = setup(app.clone()).await;
debug!("initialized drop client"); info!("initialized drop client");
app.manage(Mutex::new(state)); if !app.manage(Mutex::new(state)) {
panic!("failed to setup drop state before Tauri does")
}
{ {
use tauri_plugin_deep_link::DeepLinkExt; use tauri_plugin_deep_link::DeepLinkExt;
@@ -329,20 +333,6 @@ pub async fn run() {
debug!("registered all pre-defined deep links"); debug!("registered all pre-defined deep links");
} }
let _main_window = tauri::WebviewWindowBuilder::new(
&app,
"main", // BTW this is not the name of the window, just the label. Keep this 'main', there are permissions & configs that depend on it
tauri::WebviewUrl::App("index.html".into()),
)
.title("Drop Desktop App")
.min_inner_size(1000.0, 500.0)
.inner_size(1536.0, 864.0)
.decorations(false)
.shadow(false)
.data_directory(DATA_ROOT_DIR.join(".webview"))
.build()
.unwrap();
let deep_link_handle = app.clone(); let deep_link_handle = app.clone();
app.deep_link().on_open_url(move |event| { app.deep_link().on_open_url(move |event| {
@@ -413,6 +403,20 @@ pub async fn run() {
.show(|_| {}); .show(|_| {});
} }
}; };
let _main_window = tauri::WebviewWindowBuilder::new(
&app,
"main", // BTW this is not the name of the window, just the label. Keep this 'main', there are permissions & configs that depend on it
tauri::WebviewUrl::App("index.html".into()),
)
.title("Drop Desktop App")
.min_inner_size(1000.0, 500.0)
.inner_size(1536.0, 864.0)
.decorations(false)
.shadow(false)
.data_directory(DATA_ROOT_DIR.join(".webview"))
.build()
.unwrap();
}); });
Ok(()) Ok(())
}) })
+3 -4
View File
@@ -1,8 +1,7 @@
use std::sync::Mutex;
use log::debug; use log::debug;
use reqwest::Client; use reqwest::Client;
use tauri::{AppHandle, Emitter, Manager}; use tauri::{AppHandle, Emitter, Manager};
use tokio::sync::Mutex;
use url::Url; use url::Url;
use crate::{ use crate::{
@@ -72,7 +71,7 @@ pub async fn sign_out(app: AppHandle) {
// Update app state // Update app state
{ {
let app_state = app.state::<Mutex<AppState>>(); let app_state = app.state::<Mutex<AppState>>();
let mut app_state_handle = app_state.lock().unwrap(); let mut app_state_handle = app_state.lock().await;
app_state_handle.status = AppStatus::SignedOut; app_state_handle.status = AppStatus::SignedOut;
app_state_handle.user = None; app_state_handle.user = None;
} }
@@ -85,7 +84,7 @@ pub async fn sign_out(app: AppHandle) {
pub async fn retry_connect(state: tauri::State<'_, Mutex<AppState<'_>>>) -> Result<(), ()> { pub async fn retry_connect(state: tauri::State<'_, Mutex<AppState<'_>>>) -> Result<(), ()> {
let (app_status, user) = setup().await; let (app_status, user) = setup().await;
let mut guard = state.lock().unwrap(); let mut guard = state.lock().await;
guard.status = app_status; guard.status = app_status;
guard.user = user; guard.user = user;
drop(guard); drop(guard);
+2 -3
View File
@@ -1,7 +1,6 @@
use std::sync::Mutex;
use log::{debug, warn}; use log::{debug, warn};
use serde::Deserialize; use serde::Deserialize;
use tokio::sync::Mutex;
use url::Url; use url::Url;
use crate::{ use crate::{
@@ -34,7 +33,7 @@ pub async fn use_remote_logic(
} }
{ {
let mut app_state = state.lock().unwrap(); let mut app_state = state.lock().await;
app_state.status = AppStatus::SignedOut; app_state.status = AppStatus::SignedOut;
} }