mirror of
https://github.com/yuzu-emu/liftinstall.git
synced 2024-11-28 22:04:18 +01:00
Do that routing magic
This commit is contained in:
parent
0634e1a328
commit
cada46738a
20
Cargo.lock
generated
20
Cargo.lock
generated
@ -369,6 +369,7 @@ dependencies = [
|
||||
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"walkdir 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"web-view 0.2.1 (git+https://github.com/Boscop/web-view.git?rev=555f422d09cbb94e82a728d47e9e07ca91963f6e)",
|
||||
"winres 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"zip 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -732,6 +733,14 @@ name = "safemem"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
version = "0.1.10"
|
||||
@ -1089,6 +1098,15 @@ name = "void"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "want"
|
||||
version = "0.0.4"
|
||||
@ -1263,6 +1281,7 @@ dependencies = [
|
||||
"checksum relay 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f301bafeb60867c85170031bdb2fcf24c8041f33aee09e7b116a58d4e9f781c5"
|
||||
"checksum reqwest 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2abe46f8e00792693a2488e296c593d1f4ea39bb1178cfce081d6793657575e4"
|
||||
"checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f"
|
||||
"checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637"
|
||||
"checksum schannel 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "acece75e0f987c48863a6c792ec8b7d6c4177d4a027f8ccc72f849794f437016"
|
||||
"checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d"
|
||||
"checksum security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "dfa44ee9c54ce5eecc9de7d5acbad112ee58755239381f687e564004ba4a2332"
|
||||
@ -1309,6 +1328,7 @@ dependencies = [
|
||||
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
|
||||
"checksum version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6b772017e347561807c1aa192438c5fd74242a670a6cffacc40f2defd1dc069d"
|
||||
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||
"checksum walkdir 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f1b768ba943161a9226ccd59b26bcd901e5d60e6061f4fcad3034784e0c7372b"
|
||||
"checksum want 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a05d9d966753fa4b5c8db73fcab5eed4549cfe0e1e4e66911e5564a0085c35d1"
|
||||
"checksum web-view 0.2.1 (git+https://github.com/Boscop/web-view.git?rev=555f422d09cbb94e82a728d47e9e07ca91963f6e)" = "<none>"
|
||||
"checksum webview-sys 0.1.0 (git+https://github.com/Boscop/web-view.git?rev=555f422d09cbb94e82a728d47e9e07ca91963f6e)" = "<none>"
|
||||
|
@ -40,6 +40,9 @@ chrono = "0.4.5"
|
||||
|
||||
clap = "2.32.0"
|
||||
|
||||
[build-dependencies]
|
||||
walkdir = "2"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
# NFD is needed on Windows, as web-view doesn't work correctly here
|
||||
nfd = "0.0.4"
|
||||
|
103
build.rs
103
build.rs
@ -1,12 +1,111 @@
|
||||
extern crate walkdir;
|
||||
#[cfg(windows)]
|
||||
extern crate winres;
|
||||
|
||||
use walkdir::WalkDir;
|
||||
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use std::fs::copy;
|
||||
use std::fs::create_dir_all;
|
||||
use std::fs::File;
|
||||
|
||||
use std::io::BufRead;
|
||||
use std::io::BufReader;
|
||||
use std::io::Write;
|
||||
|
||||
const FILES_TO_PREPROCESS: &'static [&'static str] = &["helpers.js", "views.js"];
|
||||
|
||||
#[cfg(windows)]
|
||||
fn main() {
|
||||
fn handle_binary() {
|
||||
let mut res = winres::WindowsResource::new();
|
||||
res.set_icon("static/favicon.ico");
|
||||
res.compile().expect("Failed to generate metadata");
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
fn main() {}
|
||||
fn handle_binary() {}
|
||||
|
||||
fn main() {
|
||||
handle_binary();
|
||||
|
||||
let output_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
|
||||
|
||||
// Copy files from static/ to build dir
|
||||
for entry in WalkDir::new("static") {
|
||||
let entry = entry.expect("Unable to read output directory");
|
||||
|
||||
let output_file = output_dir.join(entry.path());
|
||||
|
||||
if entry.path().is_dir() {
|
||||
create_dir_all(output_file).expect("Unable to create dir");
|
||||
} else {
|
||||
let filename = entry
|
||||
.path()
|
||||
.file_name()
|
||||
.expect("Unable to parse filename")
|
||||
.to_str()
|
||||
.expect("Unable to convert to string");
|
||||
|
||||
if FILES_TO_PREPROCESS.contains(&filename) {
|
||||
// Do basic preprocessing - transcribe template string
|
||||
let source = BufReader::new(File::open(entry.path()).expect("Unable to copy file"));
|
||||
let mut target = File::create(output_file).expect("Unable to copy file");
|
||||
|
||||
let mut is_template_string = false;
|
||||
|
||||
for line in source.lines() {
|
||||
let line = line.expect("Unable to read line from JS file");
|
||||
|
||||
let mut is_break = false;
|
||||
let mut is_quote = false;
|
||||
|
||||
let mut output_line = String::new();
|
||||
|
||||
if is_template_string {
|
||||
output_line += "\"";
|
||||
}
|
||||
|
||||
for c in line.chars() {
|
||||
if c == '\\' {
|
||||
is_break = true;
|
||||
output_line.push('\\');
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == '\"' || c == '\'') && !is_break && !is_template_string {
|
||||
is_quote = !is_quote;
|
||||
}
|
||||
|
||||
if c == '`' && !is_break && !is_quote {
|
||||
output_line += "\"";
|
||||
is_template_string = !is_template_string;
|
||||
continue;
|
||||
}
|
||||
|
||||
if c == '"' && !is_break && is_template_string {
|
||||
output_line += "\\\"";
|
||||
continue;
|
||||
}
|
||||
|
||||
is_break = false;
|
||||
output_line.push(c);
|
||||
}
|
||||
|
||||
if is_template_string {
|
||||
output_line += "\" +";
|
||||
}
|
||||
|
||||
output_line.push('\n');
|
||||
|
||||
target
|
||||
.write(output_line.as_bytes())
|
||||
.expect("Unable to write line");
|
||||
}
|
||||
} else {
|
||||
copy(entry.path(), output_file).expect("Unable to copy file");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ macro_rules! include_files_as_assets {
|
||||
( $target_match:expr, $( $file_name:expr ),* ) => {
|
||||
match $target_match {
|
||||
$(
|
||||
$file_name => Some(include_bytes!(concat!("../static/", $file_name)).as_ref()),
|
||||
$file_name => Some(include_bytes!(concat!(concat!(env!("OUT_DIR"), "/static/"), $file_name)).as_ref()),
|
||||
)*
|
||||
_ => None
|
||||
}
|
||||
|
@ -17,8 +17,7 @@ pub fn setup_logger() -> Result<(), fern::InitError> {
|
||||
record.level(),
|
||||
message
|
||||
))
|
||||
})
|
||||
.level(log::LevelFilter::Info)
|
||||
}).level(log::LevelFilter::Info)
|
||||
.chain(io::stdout())
|
||||
.chain(fern::log_file("installer.log")?)
|
||||
.apply()?;
|
||||
|
@ -96,8 +96,7 @@ fn main() {
|
||||
.value_name("TARGET")
|
||||
.help("Launches the specified executable after checking for updates")
|
||||
.takes_value(true),
|
||||
)
|
||||
.get_matches();
|
||||
).get_matches();
|
||||
|
||||
info!("{} installer", app_name);
|
||||
|
||||
|
@ -59,8 +59,7 @@ impl WebServer {
|
||||
Ok(WebService {
|
||||
framework: framework.clone(),
|
||||
})
|
||||
})
|
||||
.log_expect("Failed to bind to port");
|
||||
}).log_expect("Failed to bind to port");
|
||||
|
||||
server.run().log_expect("Failed to run HTTP server");
|
||||
});
|
||||
|
@ -40,8 +40,7 @@ impl ReleaseSource for GithubReleases {
|
||||
.get(&format!(
|
||||
"https://api.github.com/repos/{}/releases",
|
||||
config.repo
|
||||
))
|
||||
.header(UserAgent::new("liftinstall (j-selby)"))
|
||||
)).header(UserAgent::new("liftinstall (j-selby)"))
|
||||
.send()
|
||||
.map_err(|x| format!("Error while sending HTTP request: {:?}", x))?;
|
||||
|
||||
@ -53,8 +52,8 @@ impl ReleaseSource for GithubReleases {
|
||||
.text()
|
||||
.map_err(|x| format!("Failed to decode HTTP response body: {:?}", x))?;
|
||||
|
||||
let result: serde_json::Value =
|
||||
serde_json::from_str(&body).map_err(|x| format!("Failed to parse response: {:?}", x))?;
|
||||
let result: serde_json::Value = serde_json::from_str(&body)
|
||||
.map_err(|x| format!("Failed to parse response: {:?}", x))?;
|
||||
|
||||
let result: &Vec<serde_json::Value> = result
|
||||
.as_array()
|
||||
|
@ -141,7 +141,7 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="modal is-active" v-if="confirm_uninstall">
|
||||
<!--<div class="modal is-active" v-if="confirm_uninstall">
|
||||
<div class="modal-background"></div>
|
||||
<div class="modal-card">
|
||||
<header class="modal-card-head">
|
||||
@ -152,7 +152,7 @@
|
||||
<button class="button" v-on:click="cancel_uninstall">No</button>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</div>-->
|
||||
</div>
|
||||
|
||||
<script src="/js/vue.js"></script>
|
||||
@ -196,32 +196,32 @@
|
||||
}
|
||||
|
||||
var app = new Vue({
|
||||
router,
|
||||
router: router,
|
||||
data: {
|
||||
attrs: base_attributes,
|
||||
config : {},
|
||||
install_location : "",
|
||||
// If the initial modify menu should be shown
|
||||
modify_install : false,
|
||||
/*modify_install : false,
|
||||
// If the package selection screen should be shown
|
||||
select_packages : true,
|
||||
// If an installation operation is happening
|
||||
is_installing : false,
|
||||
// If an installation has completed successfully
|
||||
is_finished : false,
|
||||
is_finished : false,*/
|
||||
// If the application should act as an launcher, rather than as an installer
|
||||
is_launcher : false,
|
||||
launcher_path : undefined,
|
||||
// If a confirmation prompt should be shown
|
||||
confirm_uninstall : false,
|
||||
/*confirm_uninstall : false,
|
||||
// If the downloading config page should be shown
|
||||
is_downloading_config : false,
|
||||
progress : 0,
|
||||
progress_message : "",
|
||||
has_error : false,
|
||||
has_error : false,*/
|
||||
// If the option to pick an install location should be provided
|
||||
show_install_location : true,
|
||||
error : "",
|
||||
//error : "",
|
||||
metadata : {
|
||||
database : [],
|
||||
install_path : "",
|
||||
@ -229,22 +229,6 @@
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
"back_to_packages": function() {
|
||||
app.select_packages = true;
|
||||
app.has_error = false;
|
||||
app.is_installing = false;
|
||||
app.is_finished = false;
|
||||
},
|
||||
"prepare_uninstall": function() {
|
||||
app.confirm_uninstall = true;
|
||||
},
|
||||
"cancel_uninstall": function() {
|
||||
app.confirm_uninstall = false;
|
||||
},
|
||||
"modify_packages": function() {
|
||||
app.select_packages = true;
|
||||
app.modify_install = false;
|
||||
},
|
||||
"exit": function() {
|
||||
ajax("/api/exit", function() {});
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
const DownloadConfig = {
|
||||
template: `
|
||||
<div class="column">
|
||||
<div class="column has-padding">
|
||||
<h4 class="subtitle">Downloading config...</h4>
|
||||
|
||||
<br />
|
||||
@ -14,19 +14,23 @@ const DownloadConfig = {
|
||||
},
|
||||
methods: {
|
||||
download_install_status: function() {
|
||||
ajax("/api/installation-status", (e) => {
|
||||
var that = this; // IE workaround
|
||||
|
||||
ajax("/api/installation-status", function(e) {
|
||||
app.metadata = e;
|
||||
|
||||
this.download_config();
|
||||
that.download_config();
|
||||
});
|
||||
},
|
||||
download_config: function() {
|
||||
ajax("/api/config", (e) => {
|
||||
var that = this; // IE workaround
|
||||
|
||||
ajax("/api/config", function(e) {
|
||||
app.config = e;
|
||||
|
||||
this.choose_next_state();
|
||||
that.choose_next_state();
|
||||
|
||||
}, (e) => {
|
||||
}, function(e) {
|
||||
console.error("Got error while downloading config: "
|
||||
+ e);
|
||||
|
||||
@ -71,7 +75,7 @@ const DownloadConfig = {
|
||||
|
||||
// Need to do a bit more digging to get at the
|
||||
// install location.
|
||||
ajax("/api/default-path", (e) => {
|
||||
ajax("/api/default-path", function(e) {
|
||||
if (e.path != null) {
|
||||
app.install_location = e.path;
|
||||
}
|
||||
@ -79,30 +83,13 @@ const DownloadConfig = {
|
||||
|
||||
router.replace("/packages");
|
||||
}
|
||||
|
||||
/*app.is_downloading_config = false;
|
||||
if (e.preexisting_install) {
|
||||
app.modify_install = true;
|
||||
app.select_packages = false;
|
||||
app.show_install_location = false;
|
||||
app.install_location = e.install_path;
|
||||
|
||||
|
||||
|
||||
if (e.is_launcher) {
|
||||
|
||||
app.is_launcher = true;
|
||||
app.install();
|
||||
}
|
||||
} else {
|
||||
}*/
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const SelectPackages = {
|
||||
template: `
|
||||
<div class="column">
|
||||
<div class="column has-padding">
|
||||
<h4 class="subtitle">Select your preferred settings:</h4>
|
||||
|
||||
<!-- Build options -->
|
||||
@ -130,13 +117,18 @@ const SelectPackages = {
|
||||
placeholder="Enter a install path here">
|
||||
</div>
|
||||
<div class="control">
|
||||
<a class="button is-info" v-on:click="select_file">
|
||||
<a class="button is-dark" v-on:click="select_file">
|
||||
Select
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a class="button is-primary is-pulled-right" v-on:click="install">Install!</a>
|
||||
<a class="button is-dark is-pulled-right" v-if="!$root.$data.metadata.preexisting_install"
|
||||
v-on:click="install">Install!</a>
|
||||
<a class="button is-dark is-pulled-right" v-if="$root.$data.metadata.preexisting_install"
|
||||
v-on:click="install">Modify</a>
|
||||
<a class="button is-pulled-left" v-if="$root.$data.metadata.preexisting_install"
|
||||
v-on:click="go_back">Back</a>
|
||||
</div>
|
||||
`,
|
||||
methods: {
|
||||
@ -149,13 +141,16 @@ const SelectPackages = {
|
||||
},
|
||||
install: function() {
|
||||
router.push("/install/regular");
|
||||
},
|
||||
go_back: function() {
|
||||
router.go(-1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const InstallPackages = {
|
||||
template: `
|
||||
<div class="column">
|
||||
<div class="column has-padding">
|
||||
<h4 class="subtitle" v-if="$root.$data.metadata.is_launcher">Checking for updates...</h4>
|
||||
<h4 class="subtitle" v-else-if="is_uninstall">Uninstalling...</h4>
|
||||
<h4 class="subtitle" v-else>Installing...</h4>
|
||||
@ -193,25 +188,27 @@ const InstallPackages = {
|
||||
|
||||
results["path"] = app.install_location;
|
||||
|
||||
var that = this; // IE workaround
|
||||
|
||||
stream_ajax(this.is_uninstall ? "/api/uninstall" :
|
||||
"/api/start-install", (line) => {
|
||||
"/api/start-install", function(line) {
|
||||
if (line.hasOwnProperty("Status")) {
|
||||
this.progress_message = line.Status[0];
|
||||
this.progress = line.Status[1] * 100;
|
||||
that.progress_message = line.Status[0];
|
||||
that.progress = line.Status[1] * 100;
|
||||
}
|
||||
|
||||
if (line.hasOwnProperty("Error")) {
|
||||
if (app.metadata.is_launcher) {
|
||||
app.exit();
|
||||
} else {
|
||||
this.failed_with_error = true;
|
||||
that.failed_with_error = true;
|
||||
router.replace({name: 'showerr', params: {msg: line.Error}});
|
||||
}
|
||||
}
|
||||
}, (e) => {
|
||||
}, function(e) {
|
||||
if (app.metadata.is_launcher) {
|
||||
app.exit();
|
||||
} else if (!this.failed_with_error) {
|
||||
} else if (!that.failed_with_error) {
|
||||
router.push("/complete");
|
||||
}
|
||||
}, undefined, results);
|
||||
@ -221,7 +218,7 @@ const InstallPackages = {
|
||||
|
||||
const ErrorView = {
|
||||
template: `
|
||||
<div class="column">
|
||||
<div class="column has-padding">
|
||||
<h4 class="subtitle">An error occurred:</h4>
|
||||
|
||||
<code>{{ msg }}</code>
|
||||
@ -242,7 +239,81 @@ const ErrorView = {
|
||||
}
|
||||
};
|
||||
|
||||
const
|
||||
const CompleteView = {
|
||||
template: `
|
||||
<div class="column has-padding">
|
||||
<h4 class="subtitle">Thanks for installing {{ $root.$data.attrs.name }}!</h4>
|
||||
|
||||
<a class="button is-dark is-pulled-right" v-on:click="exit">Exit</a>
|
||||
</div>
|
||||
`,
|
||||
methods: {
|
||||
exit: function() {
|
||||
app.exit();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const ModifyView = {
|
||||
template: `
|
||||
<div class="column has-padding">
|
||||
<h4 class="subtitle">Choose an option:</h4>
|
||||
|
||||
<div class="field is-grouped">
|
||||
<p class="control">
|
||||
<a class="button is-link" v-on:click="update">
|
||||
Update
|
||||
</a>
|
||||
</p>
|
||||
<p class="control">
|
||||
<a class="button" v-on:click="modify_packages">
|
||||
Modify
|
||||
</a>
|
||||
</p>
|
||||
<p class="control">
|
||||
<a class="button is-danger" v-on:click="prepare_uninstall">
|
||||
Uninstall
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="modal is-active" v-if="show_uninstall">
|
||||
<div class="modal-background"></div>
|
||||
<div class="modal-card">
|
||||
<header class="modal-card-head">
|
||||
<p class="modal-card-title">Are you sure you want to uninstall {{ $root.$data.attrs.name }}?</p>
|
||||
</header>
|
||||
<footer class="modal-card-foot">
|
||||
<button class="button is-danger" v-on:click="uninstall">Yes</button>
|
||||
<button class="button" v-on:click="cancel_uninstall">No</button>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
data: function() {
|
||||
return {
|
||||
show_uninstall: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
update: function() {
|
||||
router.push("/install/regular");
|
||||
},
|
||||
modify_packages: function() {
|
||||
router.push("/packages");
|
||||
},
|
||||
prepare_uninstall: function() {
|
||||
this.show_uninstall = true;
|
||||
},
|
||||
cancel_uninstall: function() {
|
||||
this.show_uninstall = false;
|
||||
},
|
||||
uninstall: function() {
|
||||
router.push("/install/uninstall");
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
const router = new VueRouter({
|
||||
routes: [
|
||||
@ -266,6 +337,16 @@ const router = new VueRouter({
|
||||
name: 'showerr',
|
||||
component: ErrorView
|
||||
},
|
||||
{
|
||||
path: '/complete',
|
||||
name: 'complete',
|
||||
component: CompleteView
|
||||
},
|
||||
{
|
||||
path: '/modify',
|
||||
name: 'modify',
|
||||
component: ModifyView
|
||||
},
|
||||
{
|
||||
path: '/',
|
||||
redirect: '/config'
|
||||
|
Loading…
Reference in New Issue
Block a user