feat: use async fd when using tokio (#4927)
* feat: use async fd when using tokio * whoops fix ios
This commit is contained in:
1 parent
75bb61ea67
commit
1236296ea6
3 files changed
+112
-7
No files matched your search
Generated
+1
-1
@@ -5839,7 +5839,7 @@ dependencies = [
|
|||||||
"getrandom 0.3.4",
|
"getrandom 0.3.4",
|
||||||
"http-range",
|
"http-range",
|
||||||
"ouroboros",
|
"ouroboros",
|
||||||
"pollster",
|
"pollster 0.4.0",
|
||||||
"rand 0.9.2",
|
"rand 0.9.2",
|
||||||
"reqwest 0.12.24",
|
"reqwest 0.12.24",
|
||||||
"separator",
|
"separator",
|
||||||
|
|||||||
@@ -54,6 +54,19 @@ impl FileDialogRequest {
|
|||||||
vec![]
|
vec![]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(any(
|
||||||
|
target_os = "windows",
|
||||||
|
target_os = "macos",
|
||||||
|
target_os = "linux",
|
||||||
|
target_os = "dragonfly",
|
||||||
|
target_os = "freebsd",
|
||||||
|
target_os = "netbsd",
|
||||||
|
target_os = "openbsd"
|
||||||
|
)))]
|
||||||
|
pub(crate) async fn get_file_event_async(&self) -> Vec<PathBuf> {
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
target_os = "windows",
|
target_os = "windows",
|
||||||
target_os = "macos",
|
target_os = "macos",
|
||||||
@@ -63,9 +76,8 @@ impl FileDialogRequest {
|
|||||||
target_os = "netbsd",
|
target_os = "netbsd",
|
||||||
target_os = "openbsd"
|
target_os = "openbsd"
|
||||||
))]
|
))]
|
||||||
pub(crate) fn get_file_event(&self) -> Vec<PathBuf> {
|
pub(crate) fn get_file_event_sync(&self) -> Vec<PathBuf> {
|
||||||
let dialog = rfd::FileDialog::new();
|
let dialog = rfd::FileDialog::new();
|
||||||
|
|
||||||
if self.directory {
|
if self.directory {
|
||||||
self.get_file_event_for_folder(dialog)
|
self.get_file_event_for_folder(dialog)
|
||||||
} else {
|
} else {
|
||||||
@@ -73,6 +85,78 @@ impl FileDialogRequest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(
|
||||||
|
target_os = "windows",
|
||||||
|
target_os = "macos",
|
||||||
|
target_os = "linux",
|
||||||
|
target_os = "dragonfly",
|
||||||
|
target_os = "freebsd",
|
||||||
|
target_os = "netbsd",
|
||||||
|
target_os = "openbsd"
|
||||||
|
))]
|
||||||
|
pub(crate) async fn get_file_event_async(&self) -> Vec<PathBuf> {
|
||||||
|
let mut dialog = rfd::AsyncFileDialog::new();
|
||||||
|
|
||||||
|
if self.directory {
|
||||||
|
if self.multiple {
|
||||||
|
dialog
|
||||||
|
.pick_folders()
|
||||||
|
.await
|
||||||
|
.into_iter()
|
||||||
|
.flatten()
|
||||||
|
.map(|f| f.path().to_path_buf())
|
||||||
|
.collect()
|
||||||
|
} else {
|
||||||
|
dialog
|
||||||
|
.pick_folder()
|
||||||
|
.await
|
||||||
|
.into_iter()
|
||||||
|
.map(|f| f.path().to_path_buf())
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let filters: Vec<_> = self
|
||||||
|
.accept
|
||||||
|
.as_deref()
|
||||||
|
.unwrap_or(".*")
|
||||||
|
.split(',')
|
||||||
|
.filter_map(|s| Filters::from_str(s.trim()).ok())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let file_extensions: Vec<_> = filters
|
||||||
|
.iter()
|
||||||
|
.flat_map(|f| f.as_extensions().into_iter())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let filter_name = file_extensions
|
||||||
|
.iter()
|
||||||
|
.map(|extension| format!("*.{extension}"))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(", ");
|
||||||
|
|
||||||
|
dialog = dialog.add_filter(filter_name, file_extensions.as_slice());
|
||||||
|
|
||||||
|
let files: Vec<_> = if self.multiple {
|
||||||
|
dialog
|
||||||
|
.pick_files()
|
||||||
|
.await
|
||||||
|
.into_iter()
|
||||||
|
.flatten()
|
||||||
|
.map(|f| f.path().to_path_buf())
|
||||||
|
.collect()
|
||||||
|
} else {
|
||||||
|
dialog
|
||||||
|
.pick_file()
|
||||||
|
.await
|
||||||
|
.into_iter()
|
||||||
|
.map(|f| f.path().to_path_buf())
|
||||||
|
.collect()
|
||||||
|
};
|
||||||
|
|
||||||
|
files
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
target_os = "windows",
|
target_os = "windows",
|
||||||
target_os = "macos",
|
target_os = "macos",
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use crate::{assets::*, webview::WebviewEdits};
|
use crate::{assets::*, webview::WebviewEdits};
|
||||||
use crate::{document::NATIVE_EVAL_JS, file_upload::FileDialogRequest};
|
use crate::{document::NATIVE_EVAL_JS, file_upload::FileDialogRequest};
|
||||||
use base64::prelude::BASE64_STANDARD;
|
use base64::prelude::BASE64_STANDARD;
|
||||||
@@ -63,9 +65,10 @@ pub(super) fn desktop_handler(
|
|||||||
|
|
||||||
// If the request is asking for a file dialog, handle that, returning the list of files selected
|
// If the request is asking for a file dialog, handle that, returning the list of files selected
|
||||||
if trimmed_uri == "__file_dialog" {
|
if trimmed_uri == "__file_dialog" {
|
||||||
if let Err(err) = file_dialog_responder(request, responder) {
|
if let Err(err) = file_dialog_responder_sync(request, responder) {
|
||||||
tracing::error!("Failed to handle file dialog request: {err:?}");
|
tracing::error!("Failed to handle file dialog request: {err:?}");
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,7 +180,7 @@ fn module_loader(root_id: &str, headless: bool, edit_state: &WebviewEdits) -> St
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn file_dialog_responder(
|
fn file_dialog_responder_sync(
|
||||||
request: wry::http::Request<Vec<u8>>,
|
request: wry::http::Request<Vec<u8>>,
|
||||||
responder: wry::RequestAsyncResponder,
|
responder: wry::RequestAsyncResponder,
|
||||||
) -> dioxus_core::Result<()> {
|
) -> dioxus_core::Result<()> {
|
||||||
@@ -191,11 +194,29 @@ fn file_dialog_responder(
|
|||||||
let data_from_header = base64::Engine::decode(&BASE64_STANDARD, header.as_bytes())
|
let data_from_header = base64::Engine::decode(&BASE64_STANDARD, header.as_bytes())
|
||||||
.context("Failed to decode x-dioxus-data header from base64")?;
|
.context("Failed to decode x-dioxus-data header from base64")?;
|
||||||
|
|
||||||
let mut file_dialog: FileDialogRequest = serde_json::from_slice(&data_from_header)
|
let file_dialog: FileDialogRequest = serde_json::from_slice(&data_from_header)
|
||||||
.context("Failed to parse x-dioxus-data header as JSON")?;
|
.context("Failed to parse x-dioxus-data header as JSON")?;
|
||||||
|
|
||||||
let file_list = file_dialog.get_file_event();
|
#[cfg(feature = "tokio_runtime")]
|
||||||
|
tokio::spawn(async move {
|
||||||
|
let file_list = file_dialog.get_file_event_async().await;
|
||||||
|
_ = respond_to_file_dialog(file_dialog, file_list, responder);
|
||||||
|
});
|
||||||
|
|
||||||
|
#[cfg(not(feature = "tokio_runtime"))]
|
||||||
|
{
|
||||||
|
let file_list = file_dialog.get_file_event_sync();
|
||||||
|
respond_to_file_dialog(file_dialog, file_list, responder)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn respond_to_file_dialog(
|
||||||
|
mut file_dialog: FileDialogRequest,
|
||||||
|
file_list: Vec<PathBuf>,
|
||||||
|
responder: wry::RequestAsyncResponder,
|
||||||
|
) -> dioxus_core::Result<()> {
|
||||||
// Get the position of the entry we're updating, so we can insert new entries in the same place
|
// Get the position of the entry we're updating, so we can insert new entries in the same place
|
||||||
// If we can't find it, just append to the end. This is usually due to the input not being in a form element.
|
// If we can't find it, just append to the end. This is usually due to the input not being in a form element.
|
||||||
let position_of_entry = file_dialog
|
let position_of_entry = file_dialog
|
||||||
|
|||||||
Reference in new issue
Block a user