mirror of https://github.com/tauri-apps/tauri
feat(tauri) add splashscreen API (#400)
* feat(tauri) add splashscreen API * fix(examples) quasar example building
This commit is contained in:
parent
a572fb3dc7
commit
3e1ce404f5
|
@ -18,6 +18,20 @@
|
|||
* and also whitelist them based upon the developer's settings.
|
||||
*/
|
||||
|
||||
// makes the window.external.invoke API available after window.location.href changes
|
||||
if (navigator.platform != "Win64" && navigator.plaform != "Win32") {
|
||||
window.external = this
|
||||
if (navigator.platform == "MacIntel") {
|
||||
invoke = function (x) {
|
||||
webkit.messageHandlers.invoke.postMessage(x);
|
||||
}
|
||||
} else {
|
||||
invoke = function (x) {
|
||||
window.webkit.messageHandlers.external.postMessage(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function s4() {
|
||||
return Math.floor((1 + Math.random()) * 0x10000)
|
||||
.toString(16)
|
||||
|
|
|
@ -13,8 +13,8 @@ use std::io::BufRead;
|
|||
|
||||
fn main() {
|
||||
tauri::AppBuilder::new()
|
||||
.setup(|_webview| {
|
||||
let handle1 = _webview.handle();
|
||||
.setup(|webview, _| {
|
||||
let handle1 = webview.handle();
|
||||
std::thread::spawn(move || {
|
||||
let resource_dir = tauri::api::platform::resource_dir().expect("failed to get resource dir");
|
||||
let node_package_path = resource_dir.join("resources/packaged-node.js");
|
||||
|
@ -35,7 +35,7 @@ fn main() {
|
|||
});
|
||||
});
|
||||
|
||||
let handle2 = _webview.handle();
|
||||
let handle2 = webview.handle();
|
||||
tauri::event::listen(String::from("hello"), move |msg| {
|
||||
#[derive(Serialize)]
|
||||
pub struct Reply {
|
||||
|
|
|
@ -6,7 +6,8 @@ mod runner;
|
|||
|
||||
pub struct App {
|
||||
invoke_handler: Option<Box<dyn FnMut(&mut WebView<'_, ()>, &str)>>,
|
||||
setup: Option<Box<dyn FnMut(&mut WebView<'_, ()>)>>,
|
||||
setup: Option<Box<dyn FnMut(&mut WebView<'_, ()>, String)>>,
|
||||
splashscreen_html: Option<String>,
|
||||
}
|
||||
|
||||
impl App {
|
||||
|
@ -23,19 +24,24 @@ impl App {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn run_setup(&mut self, webview: &mut WebView<'_, ()>) {
|
||||
pub(crate) fn run_setup(&mut self, webview: &mut WebView<'_, ()>, source: String) {
|
||||
match self.setup {
|
||||
Some(ref mut setup) => {
|
||||
setup(webview);
|
||||
setup(webview, source);
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn splashscreen_html(&self) -> Option<&String> {
|
||||
self.splashscreen_html.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AppBuilder {
|
||||
invoke_handler: Option<Box<dyn FnMut(&mut WebView<'_, ()>, &str)>>,
|
||||
setup: Option<Box<dyn FnMut(&mut WebView<'_, ()>)>>,
|
||||
setup: Option<Box<dyn FnMut(&mut WebView<'_, ()>, String)>>,
|
||||
splashscreen_html: Option<String>
|
||||
}
|
||||
|
||||
impl AppBuilder {
|
||||
|
@ -43,6 +49,7 @@ impl AppBuilder {
|
|||
Self {
|
||||
invoke_handler: None,
|
||||
setup: None,
|
||||
splashscreen_html: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,15 +61,21 @@ impl AppBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn setup<F: FnMut(&mut WebView<'_, ()>) + 'static>(mut self, setup: F) -> Self {
|
||||
pub fn setup<F: FnMut(&mut WebView<'_, ()>, String) + 'static>(mut self, setup: F) -> Self {
|
||||
self.setup = Some(Box::new(setup));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn splashscreen_html(mut self, html: &str) -> Self {
|
||||
self.splashscreen_html = Some(html.to_string());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> App {
|
||||
App {
|
||||
invoke_handler: self.invoke_handler,
|
||||
setup: self.setup,
|
||||
splashscreen_html: self.splashscreen_html,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,12 +35,12 @@ pub(crate) fn run(application: &mut App) -> crate::Result<()> {
|
|||
let config = get()?;
|
||||
|
||||
// setup the content using the config struct depending on the compile target
|
||||
let content = setup_content(config.clone())?;
|
||||
let main_content = setup_content(config.clone())?;
|
||||
|
||||
// setup the server url for the embedded-server
|
||||
#[cfg(feature = "embedded-server")]
|
||||
let server_url = {
|
||||
if let Content::Url(ref url) = &content {
|
||||
if let Content::Url(ref url) = &main_content {
|
||||
String::from(url)
|
||||
} else {
|
||||
String::from("")
|
||||
|
@ -48,8 +48,16 @@ pub(crate) fn run(application: &mut App) -> crate::Result<()> {
|
|||
};
|
||||
|
||||
// build the webview
|
||||
let mut webview = build_webview(application, config, content)?;
|
||||
webview.set_color((255, 255, 255));
|
||||
let webview = build_webview(
|
||||
application,
|
||||
config,
|
||||
main_content,
|
||||
if application.splashscreen_html().is_some() {
|
||||
Some(Content::Html(application.splashscreen_html().expect("failed to get splashscreen_html").to_string()))
|
||||
} else {
|
||||
None
|
||||
},
|
||||
)?;
|
||||
|
||||
// on dev-server grab a handler and execute the tauri.js API entry point.
|
||||
#[cfg(feature = "dev-server")]
|
||||
|
@ -172,7 +180,12 @@ fn build_webview(
|
|||
application: &mut App,
|
||||
config: Config,
|
||||
content: Content<String>,
|
||||
splashscreen_content: Option<Content<String>>
|
||||
) -> crate::Result<WebView<'_, ()>> {
|
||||
let content_clone = match content {
|
||||
Content::Html(ref html) => Content::Html(html.clone()),
|
||||
Content::Url(ref url) => Content::Url(url.clone()),
|
||||
};
|
||||
let debug = cfg!(debug_assertions);
|
||||
// get properties from config struct
|
||||
let width = config.tauri.window.width;
|
||||
|
@ -180,28 +193,54 @@ fn build_webview(
|
|||
let resizable = config.tauri.window.resizable;
|
||||
let title = config.tauri.window.title.into_boxed_str();
|
||||
|
||||
Ok(
|
||||
builder()
|
||||
.title(Box::leak(title))
|
||||
.size(width, height)
|
||||
.resizable(resizable)
|
||||
.debug(debug)
|
||||
.user_data(())
|
||||
.invoke_handler(move |webview, arg| {
|
||||
if arg == r#"{"cmd":"__initialized"}"# {
|
||||
application.run_setup(webview);
|
||||
webview.eval(JS_STRING)?;
|
||||
} else if let Ok(b) = crate::endpoints::handle(webview, arg) {
|
||||
if !b {
|
||||
application.run_invoke_handler(webview, arg);
|
||||
}
|
||||
}
|
||||
let has_splashscreen = splashscreen_content.is_some();
|
||||
let mut initialized_splashscreen = false;
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.content(content)
|
||||
.build()?,
|
||||
)
|
||||
let webview = builder()
|
||||
.title(Box::leak(title))
|
||||
.size(width, height)
|
||||
.resizable(resizable)
|
||||
.debug(debug)
|
||||
.user_data(())
|
||||
.invoke_handler(move |webview, arg| {
|
||||
if arg == r#"{"cmd":"__initialized"}"# {
|
||||
let source = if has_splashscreen && !initialized_splashscreen {
|
||||
initialized_splashscreen = true;
|
||||
"splashscreen"
|
||||
} else {
|
||||
"window-1"
|
||||
};
|
||||
application.run_setup(webview, source.to_string());
|
||||
webview.eval(JS_STRING)?;
|
||||
} else if arg == r#"{"cmd":"closeSplashscreen"}"# {
|
||||
let content_href = match content_clone {
|
||||
Content::Html(ref html) => html,
|
||||
Content::Url(ref url) => url,
|
||||
};
|
||||
webview.eval(&format!("window.location.href = `{}`", content_href))?;
|
||||
} else if let Ok(b) = crate::endpoints::handle(webview, arg) {
|
||||
if !b {
|
||||
application.run_invoke_handler(webview, arg);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.content(if splashscreen_content.is_some() {
|
||||
splashscreen_content.expect("failed to get splashscreen content")
|
||||
} else {
|
||||
content
|
||||
})
|
||||
.build()?;
|
||||
|
||||
if has_splashscreen {
|
||||
// trigger the init hook for the splashscreen since we're not injecting the tauri.js entry point
|
||||
webview.handle().dispatch(|webview| {
|
||||
webview.eval(r#"window.external.invoke(JSON.stringify({ cmd: "__initialized" }))"#)
|
||||
}).expect("failed to initialize splashscreen");
|
||||
}
|
||||
|
||||
Ok(webview)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -36,7 +36,7 @@ use threadpool::ThreadPool;
|
|||
use error_chain::error_chain;
|
||||
|
||||
pub use app::*;
|
||||
use web_view::WebView;
|
||||
use web_view::{WebView, Handle};
|
||||
|
||||
pub use tauri_api as api;
|
||||
|
||||
|
@ -106,6 +106,14 @@ pub fn call<T: 'static>(
|
|||
);
|
||||
}
|
||||
|
||||
pub fn close_splashscreen<T: 'static>(webview_handle: &Handle<T>) -> crate::Result<()> {
|
||||
webview_handle.dispatch(|webview| {
|
||||
// send a signal to the runner so it knows that it should redirect to the main app content
|
||||
webview.eval(r#"window.external.invoke(JSON.stringify({ cmd: "closeSplashscreen" }))"#)
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use proptest::prelude::*;
|
||||
|
|
Loading…
Reference in New Issue