mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-04-01 10:01:07 +02:00
refactor(core): use Mutex in std to reduce async usage (#1350)
Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
This commit is contained in:
committed by
GitHub
parent
89a3380367
commit
1086b3b85f
@@ -17,7 +17,7 @@ fn main() {
|
||||
|
||||
tauri::AppBuilder::default()
|
||||
.setup(|webview_manager| async move {
|
||||
let dispatcher = webview_manager.current_webview().await.unwrap();
|
||||
let dispatcher = webview_manager.current_webview().unwrap();
|
||||
let dispatcher_ = dispatcher.clone();
|
||||
dispatcher.listen("js-event", move |msg| {
|
||||
println!("got js-event with message '{:?}'", msg);
|
||||
|
||||
@@ -15,7 +15,7 @@ fn main() {
|
||||
println!("got 'clicked' event on global channel");
|
||||
});
|
||||
}
|
||||
let current_webview = webview_manager.current_webview().await.unwrap();
|
||||
let current_webview = webview_manager.current_webview().unwrap();
|
||||
let label = webview_manager.current_window_label().to_string();
|
||||
current_webview.listen("clicked", move |_| {
|
||||
println!("got 'clicked' event on window '{}'", label)
|
||||
|
||||
@@ -3,9 +3,10 @@ use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value as JsonValue;
|
||||
use tauri_api::{config::Config, private::AsTauriContext};
|
||||
|
||||
use crate::async_runtime::Mutex;
|
||||
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
pub(crate) mod event;
|
||||
mod utils;
|
||||
@@ -99,7 +100,7 @@ impl<A: ApplicationExt + 'static> App<A> {
|
||||
/// Runs the app until it finishes.
|
||||
pub fn run(mut self) {
|
||||
{
|
||||
let mut window_labels = crate::async_runtime::block_on(self.window_labels.lock());
|
||||
let mut window_labels = self.window_labels.lock().unwrap();
|
||||
for window_config in self.context.config.tauri.windows.clone() {
|
||||
let window_url = window_config.url.clone();
|
||||
let window_label = window_config.label.to_string();
|
||||
@@ -128,8 +129,9 @@ impl<A: ApplicationExt + 'static> App<A> {
|
||||
arg: &JsonValue,
|
||||
) -> crate::Result<Option<InvokeResponse>> {
|
||||
if let Some(ref invoke_handler) = self.invoke_handler {
|
||||
let fut = invoke_handler(dispatcher.clone(), command, arg.clone());
|
||||
fut.await.map(Some)
|
||||
invoke_handler(dispatcher.clone(), command, arg.clone())
|
||||
.await
|
||||
.map(Some)
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
@@ -138,8 +140,7 @@ impl<A: ApplicationExt + 'static> App<A> {
|
||||
/// Runs the setup hook if defined.
|
||||
pub(crate) async fn run_setup(&self, dispatcher: WebviewManager<A>) {
|
||||
if let Some(ref setup) = self.setup {
|
||||
let fut = setup(dispatcher);
|
||||
fut.await;
|
||||
setup(dispatcher).await;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,23 +151,21 @@ impl<A: ApplicationExt + 'static> App<A> {
|
||||
payload: PageLoadPayload,
|
||||
) {
|
||||
if let Some(ref on_page_load) = self.on_page_load {
|
||||
let fut = on_page_load(dispatcher.clone(), payload);
|
||||
fut.await;
|
||||
on_page_load(dispatcher.clone(), payload).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type WebviewContext<A> = (
|
||||
<A as ApplicationExt>::WebviewBuilder,
|
||||
Option<WebviewRpcHandler<<A as ApplicationExt>::Dispatcher>>,
|
||||
Option<CustomProtocol>,
|
||||
Option<FileDropHandler>,
|
||||
);
|
||||
|
||||
#[async_trait::async_trait]
|
||||
trait WebviewInitializer<A: ApplicationExt> {
|
||||
async fn init_webview(
|
||||
&self,
|
||||
webview: Webview<A>,
|
||||
) -> crate::Result<(
|
||||
<A as ApplicationExt>::WebviewBuilder,
|
||||
Option<WebviewRpcHandler<A::Dispatcher>>,
|
||||
Option<CustomProtocol>,
|
||||
Option<FileDropHandler>,
|
||||
)>;
|
||||
fn init_webview(&self, webview: Webview<A>) -> crate::Result<WebviewContext<A>>;
|
||||
|
||||
async fn on_webview_created(
|
||||
&self,
|
||||
@@ -178,15 +177,7 @@ trait WebviewInitializer<A: ApplicationExt> {
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<A: ApplicationExt + 'static> WebviewInitializer<A> for Arc<App<A>> {
|
||||
async fn init_webview(
|
||||
&self,
|
||||
webview: Webview<A>,
|
||||
) -> crate::Result<(
|
||||
<A as ApplicationExt>::WebviewBuilder,
|
||||
Option<WebviewRpcHandler<A::Dispatcher>>,
|
||||
Option<CustomProtocol>,
|
||||
Option<FileDropHandler>,
|
||||
)> {
|
||||
fn init_webview(&self, webview: Webview<A>) -> crate::Result<WebviewContext<A>> {
|
||||
let webview_manager = WebviewManager::new(
|
||||
self.clone(),
|
||||
self.dispatchers.clone(),
|
||||
@@ -197,14 +188,14 @@ impl<A: ApplicationExt + 'static> WebviewInitializer<A> for Arc<App<A>> {
|
||||
webview,
|
||||
&webview_manager,
|
||||
&self.url,
|
||||
&self.window_labels.lock().await,
|
||||
&self.window_labels.lock().unwrap(),
|
||||
&self.plugin_initialization_script,
|
||||
&self.context,
|
||||
)?;
|
||||
let file_drop_handler: Box<dyn Fn(FileDropEvent) -> bool + Send> = Box::new(move |event| {
|
||||
let webview_manager = webview_manager.clone();
|
||||
crate::async_runtime::block_on(async move {
|
||||
let webview = webview_manager.current_webview().await.unwrap();
|
||||
let webview = webview_manager.current_webview().unwrap();
|
||||
let _ = match event {
|
||||
FileDropEvent::Hovered(paths) => webview.emit("tauri://file-drop-hover", Some(paths)),
|
||||
FileDropEvent::Dropped(paths) => webview.emit("tauri://file-drop", Some(paths)),
|
||||
@@ -227,14 +218,12 @@ impl<A: ApplicationExt + 'static> WebviewInitializer<A> for Arc<App<A>> {
|
||||
dispatcher: A::Dispatcher,
|
||||
manager: WebviewManager<A>,
|
||||
) {
|
||||
self.dispatchers.lock().await.insert(
|
||||
self.dispatchers.lock().unwrap().insert(
|
||||
webview_label.to_string(),
|
||||
WebviewDispatcher::new(dispatcher.clone(), webview_label),
|
||||
WebviewDispatcher::new(dispatcher, webview_label),
|
||||
);
|
||||
|
||||
crate::async_runtime::spawn_task(async move {
|
||||
crate::plugin::created(A::plugin_store(), &manager).await
|
||||
});
|
||||
crate::plugin::created(A::plugin_store(), &manager).await
|
||||
}
|
||||
}
|
||||
|
||||
@@ -366,9 +355,7 @@ impl Default for AppBuilder<Wry> {
|
||||
|
||||
fn run<A: ApplicationExt + 'static>(mut application: App<A>) -> crate::Result<()> {
|
||||
let plugin_config = application.context.config.plugins.clone();
|
||||
crate::async_runtime::block_on(async move {
|
||||
crate::plugin::initialize(A::plugin_store(), plugin_config).await
|
||||
})?;
|
||||
crate::async_runtime::block_on(crate::plugin::initialize(A::plugin_store(), plugin_config))?;
|
||||
|
||||
let webviews = application.webviews.take().unwrap();
|
||||
|
||||
@@ -387,7 +374,7 @@ fn run<A: ApplicationExt + 'static>(mut application: App<A>) -> crate::Result<()
|
||||
main_webview_manager = Some(webview_manager.clone());
|
||||
}
|
||||
let (webview_builder, rpc_handler, custom_protocol, file_drop_handler) =
|
||||
crate::async_runtime::block_on(application.init_webview(webview))?;
|
||||
application.init_webview(webview)?;
|
||||
|
||||
let dispatcher = webview_app.create_webview(
|
||||
webview_builder,
|
||||
|
||||
@@ -224,9 +224,7 @@ pub(super) fn build_webview<A: ApplicationExt + 'static>(
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
if let Ok(dispatcher) =
|
||||
crate::async_runtime::block_on(webview_manager.current_webview())
|
||||
{
|
||||
if let Ok(dispatcher) = webview_manager.current_webview() {
|
||||
let error: crate::Error = e.into();
|
||||
let _ = dispatcher.eval(&format!(
|
||||
r#"console.error({})"#,
|
||||
@@ -283,7 +281,7 @@ pub(super) fn build_webview<A: ApplicationExt + 'static>(
|
||||
/// If the Result `is_err()`, the callback will be the `error_callback` function name and the argument will be the Err value.
|
||||
async fn execute_promise<
|
||||
A: ApplicationExt + 'static,
|
||||
F: futures::Future<Output = crate::Result<InvokeResponse>> + Send + 'static,
|
||||
F: std::future::Future<Output = crate::Result<InvokeResponse>> + Send + 'static,
|
||||
>(
|
||||
webview_manager: &crate::WebviewManager<A>,
|
||||
task: F,
|
||||
@@ -301,7 +299,7 @@ async fn execute_promise<
|
||||
Ok(callback_string) => callback_string,
|
||||
Err(e) => format_callback(error_callback, e.to_string()),
|
||||
};
|
||||
if let Ok(dispatcher) = webview_manager.current_webview().await {
|
||||
if let Ok(dispatcher) = webview_manager.current_webview() {
|
||||
let _ = dispatcher.eval(callback_string.as_str());
|
||||
}
|
||||
}
|
||||
@@ -319,54 +317,46 @@ async fn on_message<A: ApplicationExt + 'static>(
|
||||
.await;
|
||||
crate::plugin::on_page_load(A::plugin_store(), &webview_manager, payload).await;
|
||||
Ok(().into())
|
||||
} else if let Some(module) = &message.tauri_module {
|
||||
crate::endpoints::handle(
|
||||
&webview_manager,
|
||||
module.to_string(),
|
||||
message.inner,
|
||||
&application.context,
|
||||
)
|
||||
.await
|
||||
} else {
|
||||
let response = if let Some(module) = &message.tauri_module {
|
||||
crate::endpoints::handle(
|
||||
&webview_manager,
|
||||
module.to_string(),
|
||||
message.inner,
|
||||
&application.context,
|
||||
)
|
||||
let mut response = match application
|
||||
.run_invoke_handler(&webview_manager, command.clone(), &message.inner)
|
||||
.await
|
||||
} else {
|
||||
let mut response = match application
|
||||
.run_invoke_handler(&webview_manager, command.clone(), &message.inner)
|
||||
{
|
||||
Ok(value) => {
|
||||
if let Some(value) = value {
|
||||
Ok(value)
|
||||
} else {
|
||||
Err(crate::Error::UnknownApi(None))
|
||||
}
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
};
|
||||
if let Err(crate::Error::UnknownApi(_)) = response {
|
||||
match crate::plugin::extend_api(A::plugin_store(), &webview_manager, command, &message.inner)
|
||||
.await
|
||||
{
|
||||
Ok(value) => {
|
||||
if let Some(value) = value {
|
||||
Ok(value)
|
||||
} else {
|
||||
Err(crate::Error::UnknownApi(None))
|
||||
// If value is None, that means that no plugin matched the command
|
||||
// and the UnknownApi error should be sent to the webview
|
||||
// Otherwise, send the result of plugin handler
|
||||
if value.is_some() {
|
||||
response = Ok(value.into());
|
||||
}
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
};
|
||||
if let Err(crate::Error::UnknownApi(_)) = response {
|
||||
match crate::plugin::extend_api(
|
||||
A::plugin_store(),
|
||||
&webview_manager,
|
||||
command,
|
||||
&message.inner,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(value) => {
|
||||
// If value is None, that means that no plugin matched the command
|
||||
// and the UnknownApi error should be sent to the webview
|
||||
// Otherwise, send the result of plugin handler
|
||||
if value.is_some() {
|
||||
response = Ok(value.into());
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
// A plugin handler was found but it failed
|
||||
response = Err(e);
|
||||
}
|
||||
Err(e) => {
|
||||
// A plugin handler was found but it failed
|
||||
response = Err(e);
|
||||
}
|
||||
}
|
||||
response
|
||||
};
|
||||
}
|
||||
response
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
use super::{
|
||||
App, ApplicationDispatcherExt, ApplicationExt, Icon, Webview, WebviewBuilderExt,
|
||||
WebviewInitializer,
|
||||
};
|
||||
use crate::{api::config::WindowUrl, async_runtime::Mutex, flavors::Wry};
|
||||
use crate::{api::config::WindowUrl, flavors::Wry};
|
||||
|
||||
use serde::Serialize;
|
||||
|
||||
@@ -213,19 +216,16 @@ impl<A: ApplicationExt + 'static> WebviewManager<A> {
|
||||
}
|
||||
|
||||
/// Gets the webview associated with the current context.
|
||||
pub async fn current_webview(&self) -> crate::Result<WebviewDispatcher<A::Dispatcher>> {
|
||||
self.get_webview(&self.current_webview_window_label).await
|
||||
pub fn current_webview(&self) -> crate::Result<WebviewDispatcher<A::Dispatcher>> {
|
||||
self.get_webview(&self.current_webview_window_label)
|
||||
}
|
||||
|
||||
/// Gets the webview associated with the given window label.
|
||||
pub async fn get_webview(
|
||||
&self,
|
||||
window_label: &str,
|
||||
) -> crate::Result<WebviewDispatcher<A::Dispatcher>> {
|
||||
pub fn get_webview(&self, window_label: &str) -> crate::Result<WebviewDispatcher<A::Dispatcher>> {
|
||||
self
|
||||
.dispatchers
|
||||
.lock()
|
||||
.await
|
||||
.unwrap()
|
||||
.get(window_label)
|
||||
.ok_or(crate::Error::WebviewNotFound)
|
||||
.map(|d| d.clone())
|
||||
@@ -248,12 +248,12 @@ impl<A: ApplicationExt + 'static> WebviewManager<A> {
|
||||
.application
|
||||
.window_labels
|
||||
.lock()
|
||||
.await
|
||||
.unwrap()
|
||||
.push(label.to_string());
|
||||
let (webview_builder, rpc_handler, custom_protocol, file_drop_handler) =
|
||||
self.application.init_webview(webview).await?;
|
||||
self.application.init_webview(webview)?;
|
||||
|
||||
let window_dispatcher = self.current_webview().await?.dispatcher.create_webview(
|
||||
let window_dispatcher = self.current_webview()?.dispatcher.create_webview(
|
||||
webview_builder,
|
||||
rpc_handler,
|
||||
custom_protocol,
|
||||
@@ -286,24 +286,24 @@ impl<A: ApplicationExt + 'static> WebviewManager<A> {
|
||||
}
|
||||
|
||||
/// Emits an event to all webviews.
|
||||
pub async fn emit<S: Serialize + Clone>(
|
||||
pub fn emit<S: Serialize + Clone>(
|
||||
&self,
|
||||
event: impl AsRef<str>,
|
||||
payload: Option<S>,
|
||||
) -> crate::Result<()> {
|
||||
for dispatcher in self.dispatchers.lock().await.values() {
|
||||
for dispatcher in self.dispatchers.lock().unwrap().values() {
|
||||
super::event::emit(&dispatcher, event.as_ref(), payload.clone())?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn emit_except<S: Serialize + Clone>(
|
||||
pub(crate) fn emit_except<S: Serialize + Clone>(
|
||||
&self,
|
||||
except_label: String,
|
||||
event: impl AsRef<str>,
|
||||
payload: Option<S>,
|
||||
) -> crate::Result<()> {
|
||||
for dispatcher in self.dispatchers.lock().await.values() {
|
||||
for dispatcher in self.dispatchers.lock().unwrap().values() {
|
||||
if dispatcher.window_label != except_label {
|
||||
super::event::emit(&dispatcher, event.as_ref(), payload.clone())?;
|
||||
}
|
||||
|
||||
@@ -1,30 +1,21 @@
|
||||
use once_cell::sync::OnceCell;
|
||||
use tokio::runtime::Runtime;
|
||||
|
||||
use std::sync::Mutex as StdMutex;
|
||||
|
||||
pub use tokio::sync::Mutex;
|
||||
|
||||
use std::{future::Future, sync::Mutex as StdMutex};
|
||||
|
||||
static RUNTIME: OnceCell<StdMutex<Runtime>> = OnceCell::new();
|
||||
|
||||
pub fn block_on<F: futures::Future>(task: F) -> F::Output {
|
||||
pub fn block_on<F: Future>(task: F) -> F::Output {
|
||||
let runtime = RUNTIME.get_or_init(|| StdMutex::new(Runtime::new().unwrap()));
|
||||
runtime.lock().unwrap().block_on(task)
|
||||
}
|
||||
|
||||
pub fn spawn<F>(task: F)
|
||||
where
|
||||
F: futures::Future + Send + 'static,
|
||||
F: Future + Send + 'static,
|
||||
F::Output: Send + 'static,
|
||||
{
|
||||
let runtime = RUNTIME.get_or_init(|| StdMutex::new(Runtime::new().unwrap()));
|
||||
runtime.lock().unwrap().spawn(task);
|
||||
}
|
||||
|
||||
pub fn spawn_task<F>(task: F)
|
||||
where
|
||||
F: futures::Future + Send + 'static,
|
||||
F::Output: Send + 'static,
|
||||
{
|
||||
tokio::spawn(task);
|
||||
}
|
||||
|
||||
@@ -40,16 +40,16 @@ impl Module {
|
||||
context: &Context,
|
||||
) -> crate::Result<InvokeResponse> {
|
||||
match self {
|
||||
Self::Fs(cmd) => cmd.run().await,
|
||||
Self::Fs(cmd) => cmd.run(),
|
||||
Self::Window(cmd) => cmd.run(webview_manager).await,
|
||||
Self::Shell(cmd) => cmd.run().await,
|
||||
Self::Event(cmd) => cmd.run(webview_manager).await,
|
||||
Self::Internal(cmd) => cmd.run().await,
|
||||
Self::Dialog(cmd) => cmd.run().await,
|
||||
Self::Cli(cmd) => cmd.run(context).await,
|
||||
Self::Notification(cmd) => cmd.run(context).await,
|
||||
Self::Http(cmd) => cmd.run().await,
|
||||
Self::GlobalShortcut(cmd) => cmd.run(webview_manager).await,
|
||||
Self::Shell(cmd) => cmd.run(),
|
||||
Self::Event(cmd) => cmd.run(webview_manager),
|
||||
Self::Internal(cmd) => cmd.run(),
|
||||
Self::Dialog(cmd) => cmd.run(),
|
||||
Self::Cli(cmd) => cmd.run(context),
|
||||
Self::Notification(cmd) => cmd.run(context),
|
||||
Self::Http(cmd) => crate::async_runtime::block_on(cmd.run()),
|
||||
Self::GlobalShortcut(cmd) => cmd.run(webview_manager),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ pub enum Cmd {
|
||||
|
||||
impl Cmd {
|
||||
#[allow(unused_variables)]
|
||||
pub async fn run(self, context: &crate::app::Context) -> crate::Result<InvokeResponse> {
|
||||
pub fn run(self, context: &crate::app::Context) -> crate::Result<InvokeResponse> {
|
||||
match self {
|
||||
#[allow(unused_variables)]
|
||||
Self::CliMatches => {
|
||||
|
||||
@@ -65,7 +65,7 @@ pub enum Cmd {
|
||||
}
|
||||
|
||||
impl Cmd {
|
||||
pub async fn run(self) -> crate::Result<InvokeResponse> {
|
||||
pub fn run(self) -> crate::Result<InvokeResponse> {
|
||||
match self {
|
||||
Self::OpenDialog { options } => {
|
||||
#[cfg(dialog_open)]
|
||||
|
||||
@@ -23,7 +23,7 @@ pub enum Cmd {
|
||||
}
|
||||
|
||||
impl Cmd {
|
||||
pub async fn run<A: crate::ApplicationExt + 'static>(
|
||||
pub fn run<A: crate::ApplicationExt + 'static>(
|
||||
self,
|
||||
webview_manager: &crate::WebviewManager<A>,
|
||||
) -> crate::Result<InvokeResponse> {
|
||||
@@ -34,7 +34,7 @@ impl Cmd {
|
||||
once,
|
||||
} => {
|
||||
let js_string = listen_fn(event, handler, once)?;
|
||||
webview_manager.current_webview().await?.eval(&js_string)?;
|
||||
webview_manager.current_webview()?.eval(&js_string)?;
|
||||
}
|
||||
Self::Emit {
|
||||
event,
|
||||
@@ -42,7 +42,7 @@ impl Cmd {
|
||||
payload,
|
||||
} => {
|
||||
if let Some(label) = window_label {
|
||||
let dispatcher = webview_manager.get_webview(&label).await?;
|
||||
let dispatcher = webview_manager.get_webview(&label)?;
|
||||
// dispatch the event to Rust listeners
|
||||
dispatcher.on_event(event.to_string(), payload.clone());
|
||||
// dispatch the event to JS listeners
|
||||
@@ -51,7 +51,7 @@ impl Cmd {
|
||||
// dispatch the event to Rust listeners
|
||||
webview_manager.on_event(event.to_string(), payload.clone());
|
||||
// dispatch the event to JS listeners
|
||||
webview_manager.emit(event, payload).await?;
|
||||
webview_manager.emit(event, payload)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,11 +91,11 @@ pub enum Cmd {
|
||||
}
|
||||
|
||||
impl Cmd {
|
||||
pub async fn run(self) -> crate::Result<InvokeResponse> {
|
||||
pub fn run(self) -> crate::Result<InvokeResponse> {
|
||||
match self {
|
||||
Self::ReadTextFile { path, options } => {
|
||||
#[cfg(fs_read_text_file)]
|
||||
return read_text_file(path, options).await.map(Into::into);
|
||||
return read_text_file(path, options).map(Into::into);
|
||||
#[cfg(not(fs_read_text_file))]
|
||||
Err(crate::Error::ApiNotAllowlisted(
|
||||
"fs > readTextFile".to_string(),
|
||||
@@ -103,7 +103,7 @@ impl Cmd {
|
||||
}
|
||||
Self::ReadBinaryFile { path, options } => {
|
||||
#[cfg(fs_read_binary_file)]
|
||||
return read_binary_file(path, options).await.map(Into::into);
|
||||
return read_binary_file(path, options).map(Into::into);
|
||||
#[cfg(not(fs_read_binary_file))]
|
||||
Err(crate::Error::ApiNotAllowlisted(
|
||||
"readBinaryFile".to_string(),
|
||||
@@ -115,7 +115,7 @@ impl Cmd {
|
||||
options,
|
||||
} => {
|
||||
#[cfg(fs_write_file)]
|
||||
return write_file(path, contents, options).await.map(Into::into);
|
||||
return write_file(path, contents, options).map(Into::into);
|
||||
#[cfg(not(fs_write_file))]
|
||||
Err(crate::Error::ApiNotAllowlisted(
|
||||
"fs > writeFile".to_string(),
|
||||
@@ -127,9 +127,7 @@ impl Cmd {
|
||||
options,
|
||||
} => {
|
||||
#[cfg(fs_write_binary_file)]
|
||||
return write_binary_file(path, contents, options)
|
||||
.await
|
||||
.map(Into::into);
|
||||
return write_binary_file(path, contents, options).map(Into::into);
|
||||
#[cfg(not(fs_write_binary_file))]
|
||||
Err(crate::Error::ApiNotAllowlisted(
|
||||
"writeBinaryFile".to_string(),
|
||||
@@ -137,7 +135,7 @@ impl Cmd {
|
||||
}
|
||||
Self::ReadDir { path, options } => {
|
||||
#[cfg(fs_read_dir)]
|
||||
return read_dir(path, options).await.map(Into::into);
|
||||
return read_dir(path, options).map(Into::into);
|
||||
#[cfg(not(fs_read_dir))]
|
||||
Err(crate::Error::ApiNotAllowlisted("fs > readDir".to_string()))
|
||||
}
|
||||
@@ -147,15 +145,13 @@ impl Cmd {
|
||||
options,
|
||||
} => {
|
||||
#[cfg(fs_copy_file)]
|
||||
return copy_file(source, destination, options)
|
||||
.await
|
||||
.map(Into::into);
|
||||
return copy_file(source, destination, options).map(Into::into);
|
||||
#[cfg(not(fs_copy_file))]
|
||||
Err(crate::Error::ApiNotAllowlisted("fs > copyFile".to_string()))
|
||||
}
|
||||
Self::CreateDir { path, options } => {
|
||||
#[cfg(fs_create_dir)]
|
||||
return create_dir(path, options).await.map(Into::into);
|
||||
return create_dir(path, options).map(Into::into);
|
||||
#[cfg(not(fs_create_dir))]
|
||||
Err(crate::Error::ApiNotAllowlisted(
|
||||
"fs > createDir".to_string(),
|
||||
@@ -163,7 +159,7 @@ impl Cmd {
|
||||
}
|
||||
Self::RemoveDir { path, options } => {
|
||||
#[cfg(fs_remove_dir)]
|
||||
return remove_dir(path, options).await.map(Into::into);
|
||||
return remove_dir(path, options).map(Into::into);
|
||||
#[cfg(not(fs_remove_dir))]
|
||||
Err(crate::Error::ApiNotAllowlisted(
|
||||
"fs > removeDir".to_string(),
|
||||
@@ -171,7 +167,7 @@ impl Cmd {
|
||||
}
|
||||
Self::RemoveFile { path, options } => {
|
||||
#[cfg(fs_remove_file)]
|
||||
return remove_file(path, options).await.map(Into::into);
|
||||
return remove_file(path, options).map(Into::into);
|
||||
#[cfg(not(fs_remove_file))]
|
||||
Err(crate::Error::ApiNotAllowlisted(
|
||||
"fs > removeFile".to_string(),
|
||||
@@ -183,9 +179,7 @@ impl Cmd {
|
||||
options,
|
||||
} => {
|
||||
#[cfg(fs_rename_file)]
|
||||
return rename_file(old_path, new_path, options)
|
||||
.await
|
||||
.map(Into::into);
|
||||
return rename_file(old_path, new_path, options).map(Into::into);
|
||||
#[cfg(not(fs_rename_file))]
|
||||
Err(crate::Error::ApiNotAllowlisted(
|
||||
"fs > renameFile".to_string(),
|
||||
@@ -193,7 +187,7 @@ impl Cmd {
|
||||
}
|
||||
Self::ResolvePath { path, directory } => {
|
||||
#[cfg(fs_path)]
|
||||
return resolve_path_handler(path, directory).await.map(Into::into);
|
||||
return resolve_path_handler(path, directory).map(Into::into);
|
||||
#[cfg(not(fs_path))]
|
||||
Err(crate::Error::ApiNotAllowlisted("fs > pathApi".to_string()))
|
||||
}
|
||||
@@ -203,7 +197,7 @@ impl Cmd {
|
||||
|
||||
/// Reads a directory.
|
||||
#[cfg(fs_read_dir)]
|
||||
pub async fn read_dir(
|
||||
pub fn read_dir(
|
||||
path: PathBuf,
|
||||
options: Option<DirOperationOptions>,
|
||||
) -> crate::Result<Vec<dir::DiskEntry>> {
|
||||
@@ -217,7 +211,7 @@ pub async fn read_dir(
|
||||
|
||||
/// Copies a file.
|
||||
#[cfg(fs_copy_file)]
|
||||
pub async fn copy_file(
|
||||
pub fn copy_file(
|
||||
source: PathBuf,
|
||||
destination: PathBuf,
|
||||
options: Option<FileOperationOptions>,
|
||||
@@ -235,7 +229,7 @@ pub async fn copy_file(
|
||||
|
||||
/// Creates a directory.
|
||||
#[cfg(fs_create_dir)]
|
||||
pub async fn create_dir(path: PathBuf, options: Option<DirOperationOptions>) -> crate::Result<()> {
|
||||
pub fn create_dir(path: PathBuf, options: Option<DirOperationOptions>) -> crate::Result<()> {
|
||||
let (recursive, dir) = if let Some(options_value) = options {
|
||||
(options_value.recursive, options_value.dir)
|
||||
} else {
|
||||
@@ -253,7 +247,7 @@ pub async fn create_dir(path: PathBuf, options: Option<DirOperationOptions>) ->
|
||||
|
||||
/// Removes a directory.
|
||||
#[cfg(fs_remove_dir)]
|
||||
pub async fn remove_dir(path: PathBuf, options: Option<DirOperationOptions>) -> crate::Result<()> {
|
||||
pub fn remove_dir(path: PathBuf, options: Option<DirOperationOptions>) -> crate::Result<()> {
|
||||
let (recursive, dir) = if let Some(options_value) = options {
|
||||
(options_value.recursive, options_value.dir)
|
||||
} else {
|
||||
@@ -271,10 +265,7 @@ pub async fn remove_dir(path: PathBuf, options: Option<DirOperationOptions>) ->
|
||||
|
||||
/// Removes a file
|
||||
#[cfg(fs_remove_file)]
|
||||
pub async fn remove_file(
|
||||
path: PathBuf,
|
||||
options: Option<FileOperationOptions>,
|
||||
) -> crate::Result<()> {
|
||||
pub fn remove_file(path: PathBuf, options: Option<FileOperationOptions>) -> crate::Result<()> {
|
||||
let resolved_path = resolve_path(path, options.and_then(|o| o.dir))?;
|
||||
fs::remove_file(resolved_path)?;
|
||||
Ok(())
|
||||
@@ -282,7 +273,7 @@ pub async fn remove_file(
|
||||
|
||||
/// Renames a file.
|
||||
#[cfg(fs_rename_file)]
|
||||
pub async fn rename_file(
|
||||
pub fn rename_file(
|
||||
old_path: PathBuf,
|
||||
new_path: PathBuf,
|
||||
options: Option<FileOperationOptions>,
|
||||
@@ -299,7 +290,7 @@ pub async fn rename_file(
|
||||
|
||||
/// Writes a text file.
|
||||
#[cfg(fs_write_file)]
|
||||
pub async fn write_file(
|
||||
pub fn write_file(
|
||||
path: PathBuf,
|
||||
contents: String,
|
||||
options: Option<FileOperationOptions>,
|
||||
@@ -312,7 +303,7 @@ pub async fn write_file(
|
||||
|
||||
/// Writes a binary file.
|
||||
#[cfg(fs_write_binary_file)]
|
||||
pub async fn write_binary_file(
|
||||
pub fn write_binary_file(
|
||||
path: PathBuf,
|
||||
contents: String,
|
||||
options: Option<FileOperationOptions>,
|
||||
@@ -329,7 +320,7 @@ pub async fn write_binary_file(
|
||||
|
||||
/// Reads a text file.
|
||||
#[cfg(fs_read_text_file)]
|
||||
pub async fn read_text_file(
|
||||
pub fn read_text_file(
|
||||
path: PathBuf,
|
||||
options: Option<FileOperationOptions>,
|
||||
) -> crate::Result<String> {
|
||||
@@ -339,7 +330,7 @@ pub async fn read_text_file(
|
||||
|
||||
/// Reads a binary file.
|
||||
#[cfg(fs_read_binary_file)]
|
||||
pub async fn read_binary_file(
|
||||
pub fn read_binary_file(
|
||||
path: PathBuf,
|
||||
options: Option<FileOperationOptions>,
|
||||
) -> crate::Result<Vec<u8>> {
|
||||
@@ -348,7 +339,7 @@ pub async fn read_binary_file(
|
||||
}
|
||||
|
||||
#[cfg(fs_path)]
|
||||
pub async fn resolve_path_handler(
|
||||
pub fn resolve_path_handler(
|
||||
path: String,
|
||||
directory: Option<BaseDirectory>,
|
||||
) -> crate::Result<PathBuf> {
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
#[cfg(global_shortcut_all)]
|
||||
use crate::api::shortcuts::ShortcutManager;
|
||||
use crate::{
|
||||
app::{InvokeResponse, WebviewDispatcher},
|
||||
async_runtime::Mutex,
|
||||
};
|
||||
use crate::app::{InvokeResponse, WebviewDispatcher};
|
||||
use once_cell::sync::Lazy;
|
||||
use serde::Deserialize;
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
#[cfg(global_shortcut_all)]
|
||||
type ShortcutManagerHandle = Arc<Mutex<ShortcutManager>>;
|
||||
@@ -55,7 +52,7 @@ fn register_shortcut<A: crate::ApplicationDispatcherExt + 'static>(
|
||||
}
|
||||
|
||||
impl Cmd {
|
||||
pub async fn run<A: crate::ApplicationExt + 'static>(
|
||||
pub fn run<A: crate::ApplicationExt + 'static>(
|
||||
self,
|
||||
webview_manager: &crate::WebviewManager<A>,
|
||||
) -> crate::Result<InvokeResponse> {
|
||||
@@ -66,31 +63,31 @@ impl Cmd {
|
||||
#[cfg(global_shortcut_all)]
|
||||
match self {
|
||||
Self::Register { shortcut, handler } => {
|
||||
let dispatcher = webview_manager.current_webview().await?.clone();
|
||||
let mut manager = manager_handle().lock().await;
|
||||
let dispatcher = webview_manager.current_webview()?;
|
||||
let mut manager = manager_handle().lock().unwrap();
|
||||
register_shortcut(dispatcher, &mut manager, shortcut, handler)?;
|
||||
Ok(().into())
|
||||
}
|
||||
Self::RegisterAll { shortcuts, handler } => {
|
||||
let dispatcher = webview_manager.current_webview().await?.clone();
|
||||
let mut manager = manager_handle().lock().await;
|
||||
let dispatcher = webview_manager.current_webview()?;
|
||||
let mut manager = manager_handle().lock().unwrap();
|
||||
for shortcut in shortcuts {
|
||||
register_shortcut(dispatcher.clone(), &mut manager, shortcut, handler.clone())?;
|
||||
}
|
||||
Ok(().into())
|
||||
}
|
||||
Self::Unregister { shortcut } => {
|
||||
let mut manager = manager_handle().lock().await;
|
||||
let mut manager = manager_handle().lock().unwrap();
|
||||
manager.unregister(shortcut)?;
|
||||
Ok(().into())
|
||||
}
|
||||
Self::UnregisterAll => {
|
||||
let mut manager = manager_handle().lock().await;
|
||||
let mut manager = manager_handle().lock().unwrap();
|
||||
manager.unregister_all()?;
|
||||
Ok(().into())
|
||||
}
|
||||
Self::IsRegistered { shortcut } => {
|
||||
let manager = manager_handle().lock().await;
|
||||
let manager = manager_handle().lock().unwrap();
|
||||
Ok(manager.is_registered(shortcut)?.into())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
use crate::{app::InvokeResponse, async_runtime::Mutex};
|
||||
use crate::app::InvokeResponse;
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
use serde::Deserialize;
|
||||
use tauri_api::http::{Client, ClientBuilder, HttpRequestBuilder, ResponseData};
|
||||
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
type ClientId = u32;
|
||||
type ClientStore = Arc<Mutex<HashMap<ClientId, Client>>>;
|
||||
@@ -34,13 +37,13 @@ impl Cmd {
|
||||
match self {
|
||||
Self::CreateClient { options } => {
|
||||
let client = options.unwrap_or_default().build()?;
|
||||
let mut store = clients().lock().await;
|
||||
let mut store = clients().lock().unwrap();
|
||||
let id = rand::random::<ClientId>();
|
||||
store.insert(id, client);
|
||||
Ok(id.into())
|
||||
}
|
||||
Self::DropClient { client } => {
|
||||
let mut store = clients().lock().await;
|
||||
let mut store = clients().lock().unwrap();
|
||||
store.remove(&client);
|
||||
Ok(().into())
|
||||
}
|
||||
@@ -64,7 +67,7 @@ pub async fn make_request(
|
||||
) -> crate::Result<ResponseData> {
|
||||
let client = clients()
|
||||
.lock()
|
||||
.await
|
||||
.unwrap()
|
||||
.get(&client_id)
|
||||
.ok_or(crate::Error::HttpClientNotInitialized)?
|
||||
.clone();
|
||||
|
||||
@@ -9,7 +9,7 @@ pub enum Cmd {
|
||||
}
|
||||
|
||||
impl Cmd {
|
||||
pub async fn run(self) -> crate::Result<InvokeResponse> {
|
||||
pub fn run(self) -> crate::Result<InvokeResponse> {
|
||||
match self {
|
||||
Self::ValidateSalt { salt } => validate_salt(salt),
|
||||
}
|
||||
|
||||
@@ -27,17 +27,17 @@ pub enum Cmd {
|
||||
}
|
||||
|
||||
impl Cmd {
|
||||
pub async fn run(self, context: &crate::app::Context) -> crate::Result<InvokeResponse> {
|
||||
pub fn run(self, context: &crate::app::Context) -> crate::Result<InvokeResponse> {
|
||||
match self {
|
||||
Self::Notification { options } => {
|
||||
#[cfg(notification_all)]
|
||||
return send(options, &context.config).await.map(Into::into);
|
||||
return send(options, &context.config).map(Into::into);
|
||||
#[cfg(not(notification_all))]
|
||||
Err(crate::Error::ApiNotAllowlisted("notification".to_string()))
|
||||
}
|
||||
Self::IsNotificationPermissionGranted => {
|
||||
#[cfg(notification_all)]
|
||||
return is_permission_granted().await.map(Into::into);
|
||||
return is_permission_granted().map(Into::into);
|
||||
#[cfg(not(notification_all))]
|
||||
Err(crate::Error::ApiNotAllowlisted("notification".to_string()))
|
||||
}
|
||||
@@ -52,7 +52,7 @@ impl Cmd {
|
||||
}
|
||||
|
||||
#[cfg(notification_all)]
|
||||
pub async fn send(options: NotificationOptions, config: &Config) -> crate::Result<InvokeResponse> {
|
||||
pub fn send(options: NotificationOptions, config: &Config) -> crate::Result<InvokeResponse> {
|
||||
let identifier = config.tauri.bundle.identifier.clone();
|
||||
let mut notification = Notification::new(identifier).title(options.title);
|
||||
if let Some(body) = options.body {
|
||||
@@ -66,7 +66,7 @@ pub async fn send(options: NotificationOptions, config: &Config) -> crate::Resul
|
||||
}
|
||||
|
||||
#[cfg(notification_all)]
|
||||
pub async fn is_permission_granted() -> crate::Result<InvokeResponse> {
|
||||
pub fn is_permission_granted() -> crate::Result<InvokeResponse> {
|
||||
let settings = crate::settings::read_settings()?;
|
||||
if let Some(allow_notification) = settings.allow_notification {
|
||||
Ok(allow_notification.into())
|
||||
|
||||
@@ -17,7 +17,7 @@ pub enum Cmd {
|
||||
}
|
||||
|
||||
impl Cmd {
|
||||
pub async fn run(self) -> crate::Result<InvokeResponse> {
|
||||
pub fn run(self) -> crate::Result<InvokeResponse> {
|
||||
match self {
|
||||
Self::Execute {
|
||||
command: _,
|
||||
|
||||
@@ -96,7 +96,7 @@ impl Cmd {
|
||||
if cfg!(not(window_all)) {
|
||||
Err(crate::Error::ApiNotAllowlisted("window > all".to_string()))
|
||||
} else {
|
||||
let current_webview = webview_manager.current_webview().await?;
|
||||
let current_webview = webview_manager.current_webview()?;
|
||||
match self {
|
||||
Self::CreateWebview { options } => {
|
||||
#[cfg(not(window_create))]
|
||||
@@ -111,13 +111,11 @@ impl Cmd {
|
||||
Ok(crate::app::webview::WindowConfig(options).into())
|
||||
})
|
||||
.await?;
|
||||
webview_manager
|
||||
.emit_except(
|
||||
label.to_string(),
|
||||
"tauri://window-created",
|
||||
Some(WindowCreatedEvent { label }),
|
||||
)
|
||||
.await?;
|
||||
webview_manager.emit_except(
|
||||
label.to_string(),
|
||||
"tauri://window-created",
|
||||
Some(WindowCreatedEvent { label }),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
Self::SetResizable { resizable } => current_webview.set_resizable(resizable)?,
|
||||
|
||||
@@ -65,14 +65,9 @@ pub(crate) async fn initialize<A: ApplicationExt + 'static>(
|
||||
plugins_config: PluginConfig,
|
||||
) -> crate::Result<()> {
|
||||
let mut plugins = store.lock().await;
|
||||
let mut futures = Vec::new();
|
||||
for plugin in plugins.iter_mut() {
|
||||
let plugin_config = plugins_config.get(plugin.name());
|
||||
futures.push(plugin.initialize(plugin_config));
|
||||
}
|
||||
|
||||
for res in join_all(futures).await {
|
||||
res?;
|
||||
plugin.initialize(plugin_config).await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
Reference in New Issue
Block a user