diff --git a/src-tauri/src/desktop/diagnostics.rs b/src-tauri/src/desktop/diagnostics.rs index c741e2a4e..71005f98f 100644 --- a/src-tauri/src/desktop/diagnostics.rs +++ b/src-tauri/src/desktop/diagnostics.rs @@ -7,17 +7,20 @@ use tauri_plugin_dialog::DialogExt; const DEFAULT_ARCHIVE_NAME: &str = "sable-diagnostics.zip"; #[tauri::command] -pub fn export_diagnostics( +pub async fn export_diagnostics( app: AppHandle, frontend_logs: Option, ) -> Result, String> { - let Some(path) = app - .dialog() + let (sender, receiver) = tokio::sync::oneshot::channel(); + app.dialog() .file() .set_file_name(DEFAULT_ARCHIVE_NAME) .add_filter("ZIP archive", &["zip"]) - .blocking_save_file() - else { + .save_file(move |path| { + let _ = sender.send(path); + }); + + let Some(path) = receiver.await.map_err(|error| error.to_string())? else { return Ok(None); }; diff --git a/src-tauri/src/desktop/download.rs b/src-tauri/src/desktop/download.rs index 30078f801..55285af74 100644 --- a/src-tauri/src/desktop/download.rs +++ b/src-tauri/src/desktop/download.rs @@ -2,17 +2,20 @@ use tauri::AppHandle; use tauri_plugin_dialog::DialogExt; #[tauri::command] -pub fn save_download( +pub async fn save_download( app: AppHandle, filename: String, bytes: Vec, ) -> Result { - let Some(path) = app - .dialog() + let (sender, receiver) = tokio::sync::oneshot::channel(); + app.dialog() .file() .set_file_name(&filename) - .blocking_save_file() - else { + .save_file(move |path| { + let _ = sender.send(path); + }); + + let Some(path) = receiver.await.map_err(|error| error.to_string())? else { return Ok(false); }; diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 7fcfe176c..6f762fde7 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -43,7 +43,7 @@ pub(crate) fn main_window_title(app: &AppHandle) -> &str { target_os = "netbsd" ) ))] -fn prompt_webview_permission(message: &str) -> bool { +fn prompt_webview_permission(message: &str, resolve: impl FnOnce(bool) + 'static) { use gtk::prelude::*; use gtk::{ButtonsType, DialogFlags, MessageDialog, MessageType, ResponseType}; @@ -55,9 +55,14 @@ fn prompt_webview_permission(message: &str) -> bool { message, ); dialog.set_title("Permission request"); - let response = dialog.run(); - dialog.close(); - matches!(response, ResponseType::Yes) + let resolve = std::cell::Cell::new(Some(resolve)); + dialog.connect_response(move |dialog, response| { + if let Some(resolve) = resolve.take() { + resolve(matches!(response, ResponseType::Yes)); + } + dialog.close(); + }); + dialog.show(); } // Return the remembered decision for a webview permission, or prompt the user @@ -76,7 +81,8 @@ fn resolve_webview_permission( app: &AppHandle, key: &str, message: &str, -) -> bool { + resolve: impl FnOnce(bool) + 'static, +) { use tauri_plugin_store::StoreExt; let store = app.store("permissions.json").ok(); @@ -85,17 +91,18 @@ fn resolve_webview_permission( .and_then(|store| store.get(key)) .and_then(|value| value.as_bool()) { - return allowed; - } - - let allowed = prompt_webview_permission(message); - - if let Some(store) = &store { - store.set(key, allowed); - let _ = store.save(); + resolve(allowed); + return; } - allowed + let key = key.to_owned(); + prompt_webview_permission(message, move |allowed| { + if let Some(store) = &store { + store.set(&key, allowed); + let _ = store.save(); + } + resolve(allowed); + }); } #[cfg(all(feature = "cef", target_os = "linux"))] @@ -259,6 +266,7 @@ pub fn show_or_create_main_window(app: &AppHandle) -> taur gtk_webview.connect_permission_request(move |_wv, request| { // Ask the user (once per permission type, then remember the choice) // for the permissions Sable actually uses; deny anything else. + let request = request.clone(); let decision = if request .downcast_ref::() .is_some() @@ -282,12 +290,17 @@ pub fn show_or_create_main_window(app: &AppHandle) -> taur }; match decision { - Some((key, message)) - if resolve_webview_permission(&app_handle, key, message) => - { - request.allow(); + Some((key, message)) => { + let request = request.clone(); + resolve_webview_permission(&app_handle, key, message, move |allowed| { + if allowed { + request.allow(); + } else { + request.deny(); + } + }); } - _ => request.deny(), + None => request.deny(), } true });