|
@@ -1,141 +1,202 @@
|
|
|
-pub(crate) fn run(application: &mut crate::App) {
|
|
|
- let debug = cfg!(debug_assertions);
|
|
|
- let config = crate::config::get();
|
|
|
+#[allow(unused_imports)]
|
|
|
+use std::{fs::read_to_string, path::Path, process::Stdio, thread::spawn};
|
|
|
|
|
|
- let content;
|
|
|
- #[cfg(not(any(feature = "embedded-server", feature = "no-server")))]
|
|
|
- {
|
|
|
- content = if config.build.dev_path.starts_with("http") {
|
|
|
- web_view::Content::Url(config.build.dev_path)
|
|
|
- } else {
|
|
|
- let dev_path = std::path::Path::new(&config.build.dev_path).join("index.tauri.html");
|
|
|
- web_view::Content::Html(
|
|
|
- std::fs::read_to_string(dev_path).expect("failed to read index.tauri.html"),
|
|
|
- )
|
|
|
- };
|
|
|
+use web_view::{builder, Content, WebView};
|
|
|
+
|
|
|
+use crate::config::{get, Config};
|
|
|
+#[cfg(feature = "embedded-server")]
|
|
|
+use crate::tcp::{get_available_port, port_is_available};
|
|
|
+use crate::App;
|
|
|
+use crate::TauriResult;
|
|
|
+
|
|
|
+// JavaScript string literal
|
|
|
+const JS_STRING: &'static str = r#"
|
|
|
+if (window.onTauriInit !== void 0) {
|
|
|
+ window.onTauriInit()
|
|
|
+ window.onTauriInit = void 0
|
|
|
+}
|
|
|
+Object.defineProperty(window, 'onTauriInit', {
|
|
|
+ set: function(val) {
|
|
|
+ if (typeof(val) === 'function') {
|
|
|
+ val()
|
|
|
+ }
|
|
|
}
|
|
|
+})
|
|
|
+"#;
|
|
|
|
|
|
- #[cfg(feature = "embedded-server")]
|
|
|
- let server_url;
|
|
|
+// Main entry point function for running the Webview
|
|
|
+pub(crate) fn run(application: &mut App) -> TauriResult<()> {
|
|
|
+ // get the tauri config struct
|
|
|
+ let config = get()?;
|
|
|
|
|
|
+ // setup the content using the config struct depending on the compile target
|
|
|
+ let content = setup_content(config.clone())?;
|
|
|
+
|
|
|
+ // setup the server url for the embedded-server
|
|
|
#[cfg(feature = "embedded-server")]
|
|
|
- {
|
|
|
- // define URL
|
|
|
- let port;
|
|
|
- let port_valid;
|
|
|
- if config.tauri.embedded_server.port == "random" {
|
|
|
- match crate::tcp::get_available_port() {
|
|
|
- Some(available_port) => {
|
|
|
- port = available_port.to_string();
|
|
|
- port_valid = true;
|
|
|
- }
|
|
|
- None => {
|
|
|
- port = "0".to_string();
|
|
|
- port_valid = false;
|
|
|
- }
|
|
|
- }
|
|
|
- } else {
|
|
|
- port = config.tauri.embedded_server.port;
|
|
|
- port_valid = crate::tcp::port_is_available(
|
|
|
- port
|
|
|
- .parse::<u16>()
|
|
|
- .expect(&format!("Invalid port {}", port)),
|
|
|
- );
|
|
|
- }
|
|
|
- if port_valid {
|
|
|
- let mut url = format!("{}:{}", config.tauri.embedded_server.host, port);
|
|
|
- if !url.starts_with("http") {
|
|
|
- url = format!("http://{}", url);
|
|
|
- }
|
|
|
- server_url = url.clone();
|
|
|
- content = web_view::Content::Url(url.to_string());
|
|
|
+ let server_url = {
|
|
|
+ if let Content::Url(ref url) = &content {
|
|
|
+ String::from(url)
|
|
|
} else {
|
|
|
- panic!(format!("Port {} is not valid or not open", port));
|
|
|
+ String::from("")
|
|
|
}
|
|
|
+ };
|
|
|
+
|
|
|
+ // build the webview
|
|
|
+ let webview = build_webview(application, config, content)?;
|
|
|
+
|
|
|
+ // on dev-server grab a handler and execute the tauri.js API entry point.
|
|
|
+ #[cfg(feature = "dev-server")]
|
|
|
+ webview
|
|
|
+ .handle()
|
|
|
+ .dispatch(|_webview| _webview.eval(include_str!(concat!(env!("TAURI_DIR"), "/tauri.js"))))?;
|
|
|
+
|
|
|
+ // spawn the embedded server on our server url
|
|
|
+ #[cfg(feature = "embedded-server")]
|
|
|
+ spawn_server(server_url.to_string())?;
|
|
|
+
|
|
|
+ // spin up the updater process
|
|
|
+ #[cfg(feature = "updater")]
|
|
|
+ spawn_updater()?;
|
|
|
+
|
|
|
+ // run the webview
|
|
|
+ webview.run()?;
|
|
|
+
|
|
|
+ Ok(())
|
|
|
+}
|
|
|
+
|
|
|
+// setup content for dev-server
|
|
|
+#[cfg(not(any(feature = "embedded-server", feature = "no-server")))]
|
|
|
+fn setup_content(config: Config) -> TauriResult<Content<String>> {
|
|
|
+ if config.build.dev_path.starts_with("http") {
|
|
|
+ Ok(Content::Url(config.build.dev_path))
|
|
|
+ } else {
|
|
|
+ let dev_path = Path::new(env!("TAURI_DIST_DIR")).join("index.tauri.html");
|
|
|
+ Ok(Content::Html(read_to_string(dev_path)?))
|
|
|
}
|
|
|
+}
|
|
|
+
|
|
|
+// setup content for embedded server
|
|
|
+#[cfg(feature = "embedded-server")]
|
|
|
+fn setup_content(config: Config) -> TauriResult<Content<String>> {
|
|
|
+ let (port, valid) = setup_port(config.clone()).expect("Unable to setup Port");
|
|
|
+ let url = setup_server_url(config.clone(), valid, port).expect("Unable to setup URL");
|
|
|
+
|
|
|
+ Ok(Content::Url(url.to_string()))
|
|
|
+}
|
|
|
+
|
|
|
+// setup content for no-server
|
|
|
+#[cfg(feature = "no-server")]
|
|
|
+fn setup_content(_: Config) -> TauriResult<Content<String>> {
|
|
|
+ let index_path = Path::new(env!("TAURI_DIST_DIR")).join("index.tauri.html");
|
|
|
+ Ok(Content::Html(read_to_string(index_path)?))
|
|
|
+}
|
|
|
|
|
|
- #[cfg(feature = "no-server")]
|
|
|
- {
|
|
|
- let index_path = std::path::Path::new(env!("TAURI_DIST_DIR")).join("index.tauri.html");
|
|
|
- content =
|
|
|
- web_view::Content::Html(std::fs::read_to_string(index_path).expect("failed to read string"));
|
|
|
+// get the port for the embedded server
|
|
|
+#[cfg(feature = "embedded-server")]
|
|
|
+fn setup_port(config: Config) -> Option<(String, bool)> {
|
|
|
+ if config.tauri.embedded_server.port == "random" {
|
|
|
+ match get_available_port() {
|
|
|
+ Some(available_port) => Some((available_port.to_string(), true)),
|
|
|
+ None => Some(("0".to_string(), false)),
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ let port = config.tauri.embedded_server.port;
|
|
|
+ let port_valid = port_is_available(
|
|
|
+ port
|
|
|
+ .parse::<u16>()
|
|
|
+ .expect(&format!("Invalid port {}", port)),
|
|
|
+ );
|
|
|
+ Some((port, port_valid))
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
- #[cfg(feature = "updater")]
|
|
|
- {
|
|
|
- std::thread::spawn(|| {
|
|
|
- crate::command::spawn_relative_command(
|
|
|
- "updater".to_string(),
|
|
|
- Vec::new(),
|
|
|
- std::process::Stdio::inherit(),
|
|
|
- )
|
|
|
- .expect("Failed to spawn updater thread");
|
|
|
- });
|
|
|
+// setup the server url for embedded server
|
|
|
+#[cfg(feature = "embedded-server")]
|
|
|
+fn setup_server_url(config: Config, valid: bool, port: String) -> Option<String> {
|
|
|
+ if valid {
|
|
|
+ let mut url = format!("{}:{}", config.tauri.embedded_server.host, port);
|
|
|
+ if !url.starts_with("http") {
|
|
|
+ url = format!("http://{}", url);
|
|
|
+ }
|
|
|
+ Some(url)
|
|
|
+ } else {
|
|
|
+ None
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
- let webview = web_view::builder()
|
|
|
- .title(&config.tauri.window.title)
|
|
|
- .size(config.tauri.window.width, config.tauri.window.height)
|
|
|
- .resizable(config.tauri.window.resizable)
|
|
|
- .debug(debug)
|
|
|
- .user_data(())
|
|
|
- .invoke_handler(|webview, arg| {
|
|
|
- if arg == r#"{"cmd":"__initialized"}"# {
|
|
|
- application.run_setup(webview);
|
|
|
- webview.eval("
|
|
|
- if (window.onTauriInit !== void 0) {
|
|
|
- window.onTauriInit()
|
|
|
- window.onTauriInit = void 0
|
|
|
- }
|
|
|
- Object.defineProperty(window, 'onTauriInit', {
|
|
|
- set: function(val) {
|
|
|
- if (typeof(val) === 'function') {
|
|
|
- val()
|
|
|
- }
|
|
|
- }
|
|
|
- })
|
|
|
- ").expect("failed to evaluate window.onTauriInit");
|
|
|
- } else if !crate::endpoints::handle(webview, arg) {
|
|
|
- application.run_invoke_handler(webview, arg);
|
|
|
+// spawn the embedded server
|
|
|
+#[cfg(feature = "embedded-server")]
|
|
|
+fn spawn_server(server_url: String) -> TauriResult<()> {
|
|
|
+ spawn(move || {
|
|
|
+ let server = tiny_http::Server::http(
|
|
|
+ server_url
|
|
|
+ .clone()
|
|
|
+ .replace("http://", "")
|
|
|
+ .replace("https://", ""),
|
|
|
+ )
|
|
|
+ .expect("Unable to spawn server");
|
|
|
+ for request in server.incoming_requests() {
|
|
|
+ let url = match request.url() {
|
|
|
+ "/" => "/index.tauri.html",
|
|
|
+ url => url,
|
|
|
}
|
|
|
+ .to_string();
|
|
|
+ request
|
|
|
+ .respond(crate::server::asset_response(&url))
|
|
|
+ .expect("unable to setup response");
|
|
|
+ }
|
|
|
+ });
|
|
|
|
|
|
- Ok(())
|
|
|
- })
|
|
|
- .content(content)
|
|
|
- .build()
|
|
|
- .expect("Failed to build webview builder");
|
|
|
+ Ok(())
|
|
|
+}
|
|
|
|
|
|
- #[cfg(feature = "dev-server")]
|
|
|
- webview
|
|
|
- .handle()
|
|
|
- .dispatch(|_webview| _webview.eval(include_str!(concat!(env!("TAURI_DIR"), "/tauri.js"))))
|
|
|
- .expect("Failed to grab webview handle");
|
|
|
+// spawn an updater process.
|
|
|
+#[cfg(feature = "updater")]
|
|
|
+fn spawn_updater() -> TauriResult<()> {
|
|
|
+ spawn(|| {
|
|
|
+ tauri_api::command::spawn_relative_command(
|
|
|
+ "updater".to_string(),
|
|
|
+ Vec::new(),
|
|
|
+ Stdio::inherit(),
|
|
|
+ )?;
|
|
|
+ });
|
|
|
+ Ok(())
|
|
|
+}
|
|
|
|
|
|
- #[cfg(feature = "embedded-server")]
|
|
|
- {
|
|
|
- std::thread::spawn(move || {
|
|
|
- let server = tiny_http::Server::http(
|
|
|
- server_url
|
|
|
- .clone()
|
|
|
- .replace("http://", "")
|
|
|
- .replace("https://", ""),
|
|
|
- )
|
|
|
- .expect(&format!(
|
|
|
- "Could not start embedded server with the specified url: {}",
|
|
|
- server_url
|
|
|
- ));
|
|
|
- for request in server.incoming_requests() {
|
|
|
- let url = match request.url() {
|
|
|
- "/" => "/index.tauri.html",
|
|
|
- url => url,
|
|
|
+// build the webview struct
|
|
|
+fn build_webview(
|
|
|
+ application: &mut App,
|
|
|
+ config: Config,
|
|
|
+ content: Content<String>,
|
|
|
+) -> TauriResult<WebView<'_, ()>> {
|
|
|
+ let debug = cfg!(debug_assertions);
|
|
|
+ // get properties from config struct
|
|
|
+ let width = config.tauri.window.width;
|
|
|
+ let height = config.tauri.window.height;
|
|
|
+ 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);
|
|
|
+ }
|
|
|
}
|
|
|
- .to_string();
|
|
|
- request
|
|
|
- .respond(crate::server::asset_response(&url))
|
|
|
- .expect("Failed to read asset type");
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
|
|
|
- webview.run().expect("Failed to run webview");
|
|
|
+ Ok(())
|
|
|
+ })
|
|
|
+ .content(content)
|
|
|
+ .build()?,
|
|
|
+ )
|
|
|
}
|