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
		Add a link
		
	
		Reference in a new issue