feat(tauri) core template isolated (#18)

This commit is contained in:
Lucas Fernandes Nogueira 2019-08-16 07:58:30 -03:00 committed by nothingismagick
parent 3b272bad8c
commit 4c2c9d00b9
8 changed files with 235 additions and 176 deletions

View File

@ -31,11 +31,14 @@ uuid = { version = "0.7", features = ["v4"] }
lazy_static = "1.3.0"
includedir = "0.5.0"
tiny_http = "0.6"
clap = {version = "2.33", features = ["yaml"]}
[build-dependencies]
includedir_codegen = "0.5.0"
[features]
dev = []
embedded-server = []
all-api = []
readTextFile = []
readBinaryFile = []

View File

@ -1,10 +1,15 @@
extern crate includedir_codegen;
use includedir_codegen::Compression;
use std::env;
static CARGOENV: &str = "cargo:rustc-env=";
fn main() {
let dist_path = format!("{}/../../../../{}", env::var("OUT_DIR").unwrap(), "compiled-web");
println!("{}TAURI_DIST_DIR={}", CARGOENV, dist_path);
includedir_codegen::start("ASSETS")
.dir("./target/compiled-web", Compression::Gzip)
.dir(dist_path, Compression::None)
.build("data.rs")
.unwrap();
}

46
lib/rust/src/app.rs Normal file
View File

@ -0,0 +1,46 @@
mod runner;
use tauri_ui::WebView;
//type FnMut(&mut InvokeHandler<WebView<'_, ()>>, &str) = FnMut(&mut FnMut(&mut InvokeHandler<WebView<'_, ()>>, &str)<WebView<'_, ()>>, &str);
pub struct App {
invoke_handler: Option<Box<dyn FnMut(&mut WebView<'_, ()>, &str)>>
}
impl App {
pub fn run(mut self) {
runner::run(&mut self);
}
pub fn run_invoke_handler(&mut self, webview: &mut WebView<'_, ()>, arg: &str) {
match self.invoke_handler {
Some(ref mut invoke_handler) => {
invoke_handler(webview, arg);
},
None => {}
}
}
}
pub struct AppBuilder {
invoke_handler: Option<Box<dyn FnMut(&mut WebView<'_, ()>, &str)>>
}
impl AppBuilder {
pub fn new() -> Self {
Self {
invoke_handler: None
}
}
pub fn invoke_handler<F: FnMut(&mut WebView<'_, ()>, &str) + 'static>(mut self, invoke_handler: F) -> Self {
self.invoke_handler = Some(Box::new(invoke_handler));
self
}
pub fn build(self) -> App {
App {
invoke_handler: self.invoke_handler
}
}
}

157
lib/rust/src/app/runner.rs Normal file
View File

@ -0,0 +1,157 @@
#[cfg(feature = "dev")]
use clap::{App, Arg};
#[cfg(not(feature = "dev"))]
#[cfg(feature = "embedded-server")]
use std::thread;
pub(crate) fn run(application: &mut crate::App) {
let debug;
let content;
let config = crate::config::get();
#[cfg(feature = "embedded-server")]
let server_url: String;
#[cfg(feature = "updater")]
{
thread::spawn(|| {
crate::command::spawn_relative_command(
"updater".to_string(),
Vec::new(),
std::process::Stdio::inherit(),
)
.unwrap();
});
}
#[cfg(feature = "dev")]
{
let app = App::new("app")
.version("1.0.0")
.author("Author")
.about("About")
.arg(
Arg::with_name("url")
.short("u")
.long("url")
.value_name("URL")
.help("Loads the specified URL into webview")
.required(true)
.takes_value(true),
);
let matches = app.get_matches();
content = tauri_ui::Content::Url(matches.value_of("url").unwrap().to_owned());
debug = true;
}
#[cfg(not(feature = "dev"))]
{
debug = cfg!(debug_assertions);
#[cfg(not(feature = "embedded-server"))]
{
content = tauri_ui::Content::Html(include_str!(concat!(env!("TAURI_DIST_DIR"), "/index.html")));
}
#[cfg(feature = "embedded-server")]
{
let port;
let port_valid;
if config.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.embedded_server.port;
port_valid = crate::tcp::port_is_available(port.parse::<u16>().expect(&format!("Invalid port {}", port)));
}
if port_valid {
server_url = format!("{}:{}", config.embedded_server.host, port);
content = tauri_ui::Content::Url(server_url.clone());
} else {
panic!(format!("Port {} is not valid or not open", port));
}
}
}
let webview = tauri_ui::builder()
.title(&config.window.title)
.size(config.window.width, config.window.height)
.resizable(config.window.resizable)
.debug(debug)
.user_data(())
.invoke_handler(|webview, arg| {
// leave this as is to use the tauri API from your JS code
if !crate::api::handler(webview, arg) {
application.run_invoke_handler(webview, arg);
}
Ok(())
})
.content(content)
.build()
.unwrap();
webview
.handle()
.dispatch(move |_webview| {
_webview
.eval(&format!(
"window['{queue}'] = [];
window['{fn}'] = function (payload, salt, ignoreQueue) {{
window.tauri.promisified({{
cmd: 'validateSalt',
salt
}}).then(function () {{
const listeners = (window['{listeners}'] && window['{listeners}'][payload.type]) || []
if (!ignoreQueue && listeners.length === 0) {{
window['{queue}'].push({{
payload: payload,
salt: salt
}})
}}
for (let i = listeners.length - 1; i >= 0; i--) {{
const listener = listeners[i]
if (listener.once)
listeners.splice(i, 1)
listener.handler(payload)
}}
}})
}}",
fn = crate::event::emit_function_name(),
listeners = crate::event::event_listeners_object_name(),
queue = crate::event::event_queue_object_name()
))
.unwrap();
Ok(())
})
.unwrap();
#[cfg(not(feature = "dev"))]
{
#[cfg(feature = "embedded-server")]
{
thread::spawn(move || {
let server = tiny_http::Server::http(server_url.clone()).expect(&format!("Could not start embedded server with the specified url: {}", server_url));
for request in server.incoming_requests() {
let mut url = request.url().to_string();
if url == "/" {
url = "/index.html".to_string();
}
request.respond(crate::server::asset_response(&url)).unwrap();
}
});
}
}
webview.run().unwrap();
}

View File

@ -25,7 +25,10 @@ pub mod salt;
pub mod tcp;
pub mod updater;
pub mod version;
#[cfg(feature = "embedded-server")]
pub mod server;
mod app;
pub use app::*;
use tauri_ui::WebView;

View File

@ -4,7 +4,7 @@ include!(concat!(env!("OUT_DIR"), "/data.rs"));
pub fn asset_response(path: &str) -> Response<std::io::Cursor<Vec<u8>>> {
let asset = ASSETS
.get(&format!("./target/compiled-web{}", path))
.get(&format!("{}{}", env!("TAURI_DIST_DIR"), path))
.unwrap()
.into_owned();
let mut response = Response::from_data(asset);

View File

@ -15,14 +15,13 @@ serde_json = "1.0.39"
serde = "1.0"
serde_derive = "1.0"
tiny_http = "0.6"
clap = {version = "2.33", features = ["yaml"]}
phf = "0.7.21"
includedir = "0.5.0"
tauri = { path = "../../tauri/lib/rust" }
[features]
dev = [] # has no explicit dependencies
embedded-server = [] # has no explicit dependencies
dev = ["tauri/dev"] # has no explicit dependencies
embedded-server = ["tauri/embedded-server"] # has no explicit dependencies
[package.metadata.bundle]
identifier = "com.quasar.dev"

View File

@ -1,181 +1,27 @@
#[macro_use]
extern crate serde_derive;
extern crate clap;
extern crate tauri;
extern crate tauri_ui;
extern crate serde_json;
#[cfg(not(feature = "dev"))]
extern crate tiny_http;
#[cfg(feature = "dev")]
use clap::{App, Arg};
#[cfg(not(feature = "dev"))]
#[cfg(feature = "embedded-server")]
use std::thread;
mod cmd;
extern crate tauri;
#[macro_use]
extern crate serde_derive;
fn main() {
let debug;
let content;
let config = tauri::config::get();
#[cfg(feature = "embedded-server")]
let server_url: String;
#[cfg(feature = "updater")]
{
thread::spawn(|| {
tauri::command::spawn_relative_command(
"updater".to_string(),
Vec::new(),
std::process::Stdio::inherit(),
)
.unwrap();
});
}
#[cfg(feature = "dev")]
{
let app = App::new("app")
.version("1.0.0")
.author("Author")
.about("About")
.arg(
Arg::with_name("url")
.short("u")
.long("url")
.value_name("URL")
.help("Loads the specified URL into webview")
.required(true)
.takes_value(true),
);
let matches = app.get_matches();
content = tauri_ui::Content::Url(matches.value_of("url").unwrap().to_owned());
debug = true;
}
#[cfg(not(feature = "dev"))]
{
debug = cfg!(debug_assertions);
#[cfg(not(feature = "embedded-server"))]
{
content = tauri_ui::Content::Html(include_str!("../target/compiled-web/index.html"));
}
#[cfg(feature = "embedded-server")]
{
let port;
let port_valid;
if config.embedded_server.port == "random" {
match tauri::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.embedded_server.port;
port_valid = tauri::tcp::port_is_available(port.parse::<u16>().expect(&format!("Invalid port {}", port)));
}
if port_valid {
server_url = format!("{}:{}", config.embedded_server.host, port);
content = tauri_ui::Content::Url(server_url.clone());
} else {
panic!(format!("Port {} is not valid or not open", port));
}
}
}
let webview = tauri_ui::builder()
.title(&config.window.title)
.size(config.window.width, config.window.height)
.resizable(config.window.resizable)
.debug(debug)
.user_data(())
.invoke_handler(|webview, arg| {
// leave this as is to use the tauri API from your JS code
if !tauri::api::handler(webview, arg) {
use cmd::Cmd::*;
match serde_json::from_str(arg) {
Err(_) => {}
Ok(command) => {
match command {
// definitions for your custom commands from Cmd here
MyCustomCommand { argument } => {
// your command code
println!("{}", argument);
}
tauri::AppBuilder::new()
.invoke_handler(|_webview, arg| {
use cmd::Cmd::*;
match serde_json::from_str(arg) {
Err(_) => {}
Ok(command) => {
match command {
// definitions for your custom commands from Cmd here
MyCustomCommand { argument } => {
// your command code
println!("{}", argument);
}
}
}
}
Ok(())
})
.content(content)
.build()
.unwrap();
webview
.handle()
.dispatch(move |_webview| {
_webview
.eval(&format!(
"window['{queue}'] = [];
window['{fn}'] = function (payload, salt, ignoreQueue) {{
window.tauri.promisified({{
cmd: 'validateSalt',
salt
}}).then(function () {{
const listeners = (window['{listeners}'] && window['{listeners}'][payload.type]) || []
if (!ignoreQueue && listeners.length === 0) {{
window['{queue}'].push({{
payload: payload,
salt: salt
}})
}}
for (let i = listeners.length - 1; i >= 0; i--) {{
const listener = listeners[i]
if (listener.once)
listeners.splice(i, 1)
listener.handler(payload)
}}
}})
}}",
fn = tauri::event::emit_function_name(),
listeners = tauri::event::event_listeners_object_name(),
queue = tauri::event::event_queue_object_name()
))
.unwrap();
Ok(())
})
.unwrap();
#[cfg(not(feature = "dev"))]
{
#[cfg(feature = "embedded-server")]
{
thread::spawn(move || {
let server = tiny_http::Server::http(server_url.clone()).expect(&format!("Could not start embedded server with the specified url: {}", server_url));
for request in server.incoming_requests() {
let mut url = request.url().to_string();
if url == "/" {
url = "/index.html".to_string();
}
request.respond(tauri::server::asset_response(&url)).unwrap();
}
});
}
}
webview.run().unwrap();
.run();
}