wip
This commit is contained in:
parent
89e36d7eb0
commit
78153e8bf4
3 changed files with 50 additions and 34 deletions
17
src/lib.rs
17
src/lib.rs
|
@ -1,17 +0,0 @@
|
||||||
mod utils;
|
|
||||||
|
|
||||||
// use wasm_bindgen::prelude::*;
|
|
||||||
//
|
|
||||||
// #[cfg(feature = "wee_alloc")]
|
|
||||||
// #[global_allocator]
|
|
||||||
// static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
|
|
||||||
//
|
|
||||||
// #[wasm_bindgen]
|
|
||||||
// pub fn merge(files: js_sys::Array) -> wasm_bindgen::JsValue {
|
|
||||||
// utils::set_panic_hook();
|
|
||||||
// let files: Vec<String> = utils::translate_js_to_rust(files);
|
|
||||||
// let merged: gpx::Gpx = utils::join_gpx_files(files);
|
|
||||||
// let out_vec: Vec<u8> = utils::write_gpx_to_buffer(merged);
|
|
||||||
//
|
|
||||||
// JsValue::from_str(&String::from_utf8(out_vec).unwrap())
|
|
||||||
// }
|
|
|
@ -9,7 +9,7 @@ use super::utils;
|
||||||
|
|
||||||
pub enum Msg {
|
pub enum Msg {
|
||||||
FileLoaded(String, String),
|
FileLoaded(String, String),
|
||||||
Files(Vec<File>),
|
StartLoad(Vec<File>),
|
||||||
FilesLoaded,
|
FilesLoaded,
|
||||||
Reset,
|
Reset,
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,9 @@ pub struct Loader {
|
||||||
readers: HashMap<String, FileReader>,
|
readers: HashMap<String, FileReader>,
|
||||||
files: Vec<String>,
|
files: Vec<String>,
|
||||||
count: usize,
|
count: usize,
|
||||||
|
is_loading: bool,
|
||||||
|
// This field is to handle resetting the native HTML widget's state on error
|
||||||
|
field_value: &'static str,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Component for Loader {
|
impl Component for Loader {
|
||||||
|
@ -29,6 +32,8 @@ impl Component for Loader {
|
||||||
readers: HashMap::default(),
|
readers: HashMap::default(),
|
||||||
files: vec![],
|
files: vec![],
|
||||||
count: 0,
|
count: 0,
|
||||||
|
is_loading: false,
|
||||||
|
field_value: "",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,8 +48,15 @@ impl Component for Loader {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
Msg::Files(files) => {
|
Msg::StartLoad(files) => {
|
||||||
self.count = files.len();
|
self.count = files.len();
|
||||||
|
if self.count < 2 {
|
||||||
|
utils::alert("must load two or more files");
|
||||||
|
ctx.link().send_message(Msg::Reset);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
self.is_loading = true;
|
||||||
|
|
||||||
for file in files.into_iter() {
|
for file in files.into_iter() {
|
||||||
let file_name = file.name();
|
let file_name = file.name();
|
||||||
let task = {
|
let task = {
|
||||||
|
@ -64,7 +76,14 @@ impl Component for Loader {
|
||||||
}
|
}
|
||||||
|
|
||||||
Msg::FilesLoaded => {
|
Msg::FilesLoaded => {
|
||||||
let merged = utils::merge(&self.files);
|
let merged = match utils::merge(&self.files) {
|
||||||
|
Ok(result) => result,
|
||||||
|
Err(err) => {
|
||||||
|
utils::alert(&err.to_string());
|
||||||
|
ctx.link().send_message(Msg::Reset);
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let window = web_sys::window().expect("no global `window` exists");
|
let window = web_sys::window().expect("no global `window` exists");
|
||||||
let document = window.document().expect("should have a document on window");
|
let document = window.document().expect("should have a document on window");
|
||||||
|
@ -75,6 +94,8 @@ impl Component for Loader {
|
||||||
anchor_element.set_attribute("href", &url).unwrap();
|
anchor_element.set_attribute("href", &url).unwrap();
|
||||||
anchor_element.set_attribute("download", "merged.gpx").unwrap();
|
anchor_element.set_attribute("download", "merged.gpx").unwrap();
|
||||||
|
|
||||||
|
self.is_loading = false;
|
||||||
|
|
||||||
let event = MouseEvent::new("click").unwrap();
|
let event = MouseEvent::new("click").unwrap();
|
||||||
anchor_element.dispatch_event(&event).unwrap();
|
anchor_element.dispatch_event(&event).unwrap();
|
||||||
|
|
||||||
|
@ -85,6 +106,8 @@ impl Component for Loader {
|
||||||
self.readers = HashMap::default();
|
self.readers = HashMap::default();
|
||||||
self.files = vec![];
|
self.files = vec![];
|
||||||
self.count = 0;
|
self.count = 0;
|
||||||
|
self.is_loading = false;
|
||||||
|
self.field_value = "";
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,8 +116,10 @@ impl Component for Loader {
|
||||||
fn view(&self, ctx: &Context<Self>) -> Html {
|
fn view(&self, ctx: &Context<Self>) -> Html {
|
||||||
let link = ctx.link();
|
let link = ctx.link();
|
||||||
html! {
|
html! {
|
||||||
<>
|
if self.is_loading {
|
||||||
<input type="file" multiple=true onchange={link.callback(move |e: Event| {
|
<span>{"loading..."}</span>
|
||||||
|
} else {
|
||||||
|
<input type="file" value={self.field_value} multiple=true onchange={link.callback(move |e: Event| {
|
||||||
let mut result = Vec::new();
|
let mut result = Vec::new();
|
||||||
let input: HtmlInputElement = e.target_unchecked_into();
|
let input: HtmlInputElement = e.target_unchecked_into();
|
||||||
|
|
||||||
|
@ -106,10 +131,10 @@ impl Component for Loader {
|
||||||
.map(File::from);
|
.map(File::from);
|
||||||
result.extend(files);
|
result.extend(files);
|
||||||
}
|
}
|
||||||
Msg::Files(result)
|
Msg::StartLoad(result)
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
</>
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
28
src/utils.rs
28
src/utils.rs
|
@ -1,12 +1,14 @@
|
||||||
|
use std::error::Error;
|
||||||
use web_sys::Blob;
|
use web_sys::Blob;
|
||||||
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
fn join_gpx_files(files: &Vec<String>) -> gpx::Gpx {
|
fn join_gpx_files(files: &Vec<String>) -> Result<gpx::Gpx, Box<dyn Error>> {
|
||||||
let mut merged_gpx: gpx::Gpx = Default::default();
|
let mut merged_gpx: gpx::Gpx = Default::default();
|
||||||
let mut merged_track: gpx::Track = gpx::Track::new();
|
let mut merged_track: gpx::Track = gpx::Track::new();
|
||||||
|
|
||||||
for file in files.iter() {
|
for file in files.iter() {
|
||||||
let buffer = std::io::BufReader::new(file.as_bytes());
|
let buffer = std::io::BufReader::new(file.as_bytes());
|
||||||
let mut parsed_gpx: gpx::Gpx = gpx::read(buffer).expect("invalid gpx");
|
let mut parsed_gpx: gpx::Gpx = gpx::read(buffer)?;
|
||||||
|
|
||||||
// consolidate all track segements into one single track.
|
// consolidate all track segements into one single track.
|
||||||
for track in parsed_gpx.tracks {
|
for track in parsed_gpx.tracks {
|
||||||
|
@ -36,22 +38,28 @@ fn join_gpx_files(files: &Vec<String>) -> gpx::Gpx {
|
||||||
merged_gpx.metadata = Some(metadata);
|
merged_gpx.metadata = Some(metadata);
|
||||||
merged_gpx.version = gpx::GpxVersion::Gpx11;
|
merged_gpx.version = gpx::GpxVersion::Gpx11;
|
||||||
|
|
||||||
merged_gpx
|
Ok(merged_gpx)
|
||||||
}
|
}
|
||||||
fn write_gpx_to_buffer(gpx: gpx::Gpx) -> js_sys::Array {
|
fn write_gpx_to_buffer(gpx: gpx::Gpx) -> Result<js_sys::Array, Box<dyn Error>> {
|
||||||
let mut buffer = Vec::new();
|
let mut buffer = Vec::new();
|
||||||
gpx::write(&gpx, &mut buffer).unwrap();
|
gpx::write(&gpx, &mut buffer)?;
|
||||||
|
|
||||||
let uint8arr = js_sys::Uint8Array::new(&unsafe { js_sys::Uint8Array::view(&buffer) }.into());
|
let uint8arr = js_sys::Uint8Array::new(&unsafe { js_sys::Uint8Array::view(&buffer) }.into());
|
||||||
let array = js_sys::Array::new();
|
let array = js_sys::Array::new();
|
||||||
array.push(&uint8arr.buffer());
|
array.push(&uint8arr.buffer());
|
||||||
|
|
||||||
array
|
Ok(array)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn merge(files: &Vec<String>) -> Blob {
|
pub fn merge(files: &Vec<String>) -> Result<Blob, Box<dyn Error>> {
|
||||||
let merged: gpx::Gpx = join_gpx_files(files);
|
let merged: gpx::Gpx = join_gpx_files(files)?;
|
||||||
let out_vec = write_gpx_to_buffer(merged);
|
let out_vec = write_gpx_to_buffer(merged)?;
|
||||||
|
let result = Blob::new_with_u8_array_sequence(&out_vec).map_err(|e| e.as_string().unwrap() )?;
|
||||||
|
|
||||||
Blob::new_with_u8_array_sequence(&out_vec).unwrap()
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
extern {
|
||||||
|
pub fn alert(s: &str);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue