Use web-view file dialogs where possible

This commit is contained in:
James 2018-08-03 21:49:38 +10:00
parent 1f6d1e8d52
commit cab17e6832
5 changed files with 47 additions and 32 deletions

View File

@ -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"

View File

@ -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;

View File

@ -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" {
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);
}
}
}
},
(),

View File

@ -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::<hyper::Body>::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();

View File

@ -143,6 +143,10 @@
<script src="/js/helpers.js"></script>
<script src="/js/vue.js"></script>
<script>
function selectFileCallback(name) {
app.install_location = name;
}
var app = new Vue({
el: '#app',
data: {
@ -165,12 +169,11 @@
},
methods: {
"select_file": function() {
window.external.invoke("select-install-dir");
/*ajax("/api/file-select", function(e) {
if (e.path != null) {
app.install_location = e.path;
window.external.invoke(JSON.stringify({
SelectInstallDir: {
callback_name: "selectFileCallback"
}
});*/
}));
},
"install": function() {
this.select_packages = false;