Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions src-tauri/src/desktop/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<crate::BrowserEngine>,
frontend_logs: Option<String>,
) -> Result<Option<String>, 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);
};

Expand Down
13 changes: 8 additions & 5 deletions src-tauri/src/desktop/download.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<crate::BrowserEngine>,
filename: String,
bytes: Vec<u8>,
) -> Result<bool, String> {
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);
};

Expand Down
51 changes: 32 additions & 19 deletions src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub(crate) fn main_window_title(app: &AppHandle<crate::BrowserEngine>) -> &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};

Expand All @@ -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
Expand All @@ -76,7 +81,8 @@ fn resolve_webview_permission(
app: &AppHandle<crate::BrowserEngine>,
key: &str,
message: &str,
) -> bool {
resolve: impl FnOnce(bool) + 'static,
) {
use tauri_plugin_store::StoreExt;

let store = app.store("permissions.json").ok();
Expand All @@ -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"))]
Expand Down Expand Up @@ -259,6 +266,7 @@ pub fn show_or_create_main_window(app: &AppHandle<crate::BrowserEngine>) -> 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::<UserMediaPermissionRequest>()
.is_some()
Expand All @@ -282,12 +290,17 @@ pub fn show_or_create_main_window(app: &AppHandle<crate::BrowserEngine>) -> 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
});
Expand Down
Loading