From cab17e68325a38493fc3dad32c084d2c3ddf71fb Mon Sep 17 00:00:00 2001 From: James Date: Fri, 3 Aug 2018 21:49:38 +1000 Subject: [PATCH] Use web-view file dialogs where possible --- Cargo.toml | 7 ++++--- src/installer.rs | 1 - src/main.rs | 38 +++++++++++++++++++++++++++++++++++--- src/rest.rs | 20 -------------------- static/index.html | 13 ++++++++----- 5 files changed, 47 insertions(+), 32 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0f88f8b..3e4a178 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,10 +23,11 @@ serde_json = "1.0.9" toml = "0.4" -# TODO: Use web-view for this one -nfd = "0.0.4" - semver = {version = "0.9.0", features = ["serde"]} regex = "0.2" zip = "0.2.8" + +[target.'cfg(windows)'.dependencies] +# NFD is needed on Windows, as web-view doesn't work correctly here +nfd = "0.0.4" diff --git a/src/installer.rs b/src/installer.rs index 3f8dbcf..da0176e 100644 --- a/src/installer.rs +++ b/src/installer.rs @@ -1,7 +1,6 @@ /// installer.rs /// /// Contains the main installer structure, as well as high-level means of controlling it. - use serde_json; use std::fs::File; diff --git a/src/main.rs b/src/main.rs index 6147929..867f56f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,8 @@ #![windows_subsystem = "windows"] +#[cfg(windows)] +extern crate nfd; + extern crate web_view; extern crate futures; @@ -33,11 +36,17 @@ use config::Config; use installer::InstallerFramework; +use nfd::Response; use rest::WebServer; // TODO: Fetch this over a HTTP request? static RAW_CONFIG: &'static str = include_str!("../config.toml"); +#[derive(Deserialize, Debug)] +enum CallbackType { + SelectInstallDir { callback_name: String }, +} + fn main() { let config = Config::from_toml_str(RAW_CONFIG).unwrap(); @@ -74,9 +83,32 @@ fn main() { debug, |_| {}, |wv, msg, _| { - println!("Incoming payload: {:?}", msg); - if msg == "select-install-dir" { - wv.dialog(Dialog::ChooseDirectory, "Select a install directory...", ""); + let command: CallbackType = + serde_json::from_str(msg).expect(&format!("Unable to parse string: {:?}", msg)); + + println!("Incoming payload: {:?}", command); + + match command { + CallbackType::SelectInstallDir { callback_name } => { + #[cfg(windows)] + let result = + match nfd::open_pick_folder(None).expect("Unable to open folder dialog") { + Response::Okay(v) => v, + _ => return, + }; + + #[cfg(not(windows))] + let result = + wv.dialog(Dialog::ChooseDirectory, "Select a install directory...", ""); + + if result.len() > 0 { + let result = + serde_json::to_string(&result).expect("Unable to serialize response"); + let command = format!("{}({});", callback_name, result); + println!("Injecting response: {}", command); + wv.eval(&command); + } + } } }, (), diff --git a/src/rest.rs b/src/rest.rs index a20a0a4..8ea85f1 100644 --- a/src/rest.rs +++ b/src/rest.rs @@ -2,11 +2,8 @@ /// /// Provides a HTTP/REST server for both frontend<->backend communication, as well /// as talking to external applications. -extern crate nfd; extern crate url; -use self::nfd::Response as NfdResponse; - use serde_json; use futures::future; @@ -115,23 +112,6 @@ impl Service for WebService { .with_header(ContentType::json()) .with_body(file) } - // Opens a file dialog and returns the path as a string - (&Get, "/api/file-select") => { - let file_dialog = nfd::open_pick_folder(None).unwrap(); - let file = match file_dialog { - NfdResponse::Okay(path) => Some(path), - _ => None, - }; - - let response = FileSelection { path: file }; - - let file = serde_json::to_string(&response).unwrap(); - - Response::::new() - .with_header(ContentLength(file.len() as u64)) - .with_header(ContentType::json()) - .with_body(file) - } // Returns the default path for a installation (&Get, "/api/default-path") => { let framework = self.framework.read().unwrap(); diff --git a/static/index.html b/static/index.html index dd8da6f..8f9e902 100644 --- a/static/index.html +++ b/static/index.html @@ -143,6 +143,10 @@