diff --git a/src/app_ctx.rs b/src/app_ctx.rs index 86858fa..ec858b6 100644 --- a/src/app_ctx.rs +++ b/src/app_ctx.rs @@ -23,14 +23,12 @@ pub enum Msg { // App state // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -#[derive(Debug, PartialEq, Eq, Clone)] -#[derive(Default)] +#[derive(Debug, PartialEq, Eq, Clone, Default)] pub struct AppState { pub file: Option, pub exified: bool, } - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Reducer // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -45,8 +43,6 @@ impl Reducible for AppState { exified: self.exified, }, Msg::RemoveExif => { - - if let Some(Ok(details)) = &self.file { let result = remove_exif(details.clone()); diff --git a/src/components/add.rs b/src/components/add.rs index 870a294..7b25210 100644 --- a/src/components/add.rs +++ b/src/components/add.rs @@ -29,11 +29,9 @@ pub fn Add() -> Html { let task_ref = task_ref.clone(); Callback::from(move |files: FileList| { match files.item(0) { - None => { - ctx.dispatch(Msg::Update(Err(FileError::DragDropFailed( - "No file in FileList".to_string(), - )))) - } + None => ctx.dispatch(Msg::Update(Err(FileError::DragDropFailed( + "No file in FileList".to_string(), + )))), Some(file) => { let file = File::from(file); let file_name = file.name(); @@ -41,10 +39,7 @@ pub fn Add() -> Html { let ctx = ctx.clone(); let task = gloo::file::callbacks::read_as_bytes(&file, move |res| { let msg = match res { - Ok(data) => { - - get_file_details(data, file_name, file_type) - } + Ok(data) => get_file_details(data, file_name, file_type), Err(e) => Err(FileError::InvalidData(e.to_string())), }; @@ -80,9 +75,7 @@ pub fn Add() -> Html { event .data_transfer() - .and_then(|data| { - data.files() - }) + .and_then(|data| data.files()) .map(|list| { files_selected.emit(list.clone()); Some(true) @@ -98,9 +91,7 @@ pub fn Add() -> Html { event.prevent_default(); event.stop_propagation(); - let _ = event.data_transfer().map(|_| { - Some(true) - }); + let _ = event.data_transfer().map(|_| Some(true)); s.set(true); }) @@ -121,9 +112,7 @@ pub fn Add() -> Html { Callback::from(move |event: DragEvent| { event.prevent_default(); - let _ = event.data_transfer().map(|_| { - Some(true) - }); + let _ = event.data_transfer().map(|_| Some(true)); s.set(false); }) diff --git a/src/components/details.rs b/src/components/details.rs index f604681..d924aa5 100644 --- a/src/components/details.rs +++ b/src/components/details.rs @@ -3,17 +3,15 @@ use wasm_bindgen::JsValue; use web_sys::{HtmlAnchorElement, Url}; use yew::prelude::*; +use crate::app_ctx::Msg; use crate::icons::{BrokenImage, Close}; use crate::types::{AppContext, FileError}; -use crate::utils::{img_src, exified_file_name}; -use crate::app_ctx::Msg; +use crate::utils::{exified_file_name, img_src}; use yew::html; - #[function_component] pub fn Details() -> Html { - let ctx = use_context::().unwrap(); let file_details = use_memo(ctx.file.clone(), |file| file.clone().and_then(Result::ok)); @@ -22,8 +20,12 @@ pub fn Details() -> Html { let is_exified = use_memo(ctx.exified, |ex| *ex); - let has_exif = use_memo(ctx.file.clone(), |file| - file.clone().and_then(Result::ok).map(|fd| !fd.exif.is_empty()).unwrap_or(false)); + let has_exif = use_memo(ctx.file.clone(), |file| { + file.clone() + .and_then(Result::ok) + .map(|fd| !fd.exif.is_empty()) + .unwrap_or(false) + }); let on_remove = { let ctx = ctx.clone(); @@ -37,50 +39,46 @@ pub fn Details() -> Html { }; let on_save = { - let fd = file_details.clone(); - let ctx = ctx.clone(); - Callback::from(move |_: MouseEvent| { + let fd = file_details.clone(); + let ctx = ctx.clone(); + Callback::from(move |_: MouseEvent| { if let Some(fd) = &*fd { // transform Vec into JSValue (Array) - let u8_array = - js_sys::Array::of1(&js_sys::Uint8Array::from(&fd.data[..])); - let options = web_sys::BlobPropertyBag::new(); - options.set_type(&fd.file_type); + let u8_array = js_sys::Array::of1(&js_sys::Uint8Array::from(&fd.data[..])); + let options = web_sys::BlobPropertyBag::new(); + options.set_type(&fd.file_type); // get URL (blob) to download file - let result = web_sys::Blob::new_with_u8_array_sequence_and_options( - &u8_array, - &options, - ) - .and_then(|blob| web_sys::Url::create_object_url_with_blob(&blob)) - .and_then(|url| - // Create element to download file - web_sys::window() - .and_then(|w| w.document()) - // Map error needed to stay with Result<_, JSValue> - .ok_or(JsValue::from_str("no document")) - .and_then(|d| d.create_element("a")) - .map(|elem| { - let name = exified_file_name(fd); - let a: HtmlAnchorElement = HtmlAnchorElement::from(JsValue::from(elem)); - a.set_href(&url); - a.set_download(&name); - a.set_class_name("hidden"); - a.click(); - // cleanup - Url::revoke_object_url(&url).unwrap(); - document().body().unwrap().remove_child(&a).unwrap(); - // return name - name - }) - - ); - - let result = result.map_err(|e| FileError::SaveFailed( - e.as_string() - .unwrap_or("failed to save file".to_owned()) - )); - ctx.dispatch(Msg::Saved(result)); - }; + let result = + web_sys::Blob::new_with_u8_array_sequence_and_options(&u8_array, &options) + .and_then(|blob| web_sys::Url::create_object_url_with_blob(&blob)) + // Create element to download file + .and_then(|url| { + web_sys::window() + .and_then(|w| w.document()) + // Map error needed to stay with Result<_, JSValue> + .ok_or(JsValue::from_str("no document")) + .and_then(|d| d.create_element("a")) + .map(|elem| { + let name = exified_file_name(fd); + let a: HtmlAnchorElement = + HtmlAnchorElement::from(JsValue::from(elem)); + a.set_href(&url); + a.set_download(&name); + a.set_class_name("hidden"); + a.click(); + // cleanup + Url::revoke_object_url(&url).unwrap(); + document().body().unwrap().remove_child(&a).unwrap(); + // return name + name + }) + }); + + let result = result.map_err(|e| { + FileError::SaveFailed(e.as_string().unwrap_or("failed to save file".to_owned())) + }); + ctx.dispatch(Msg::Saved(result)); + }; }) }; @@ -99,8 +97,8 @@ pub fn Details() -> Html { <>
-
- + + { if let Some(fd) = &*file_details { html!{
diff --git a/src/utils.rs b/src/utils.rs index 674979a..ba097f7 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -8,8 +8,6 @@ use img_parts::{Bytes, DynImage, ImageEXIF}; use crate::types::{ExifMap, FileDetails, FileError}; pub fn img_from_bytes(data: Vec) -> Result { - - DynImage::from_bytes(data.clone().into()) .map_err(|e| FileError::InvalidData(e.to_string()))? .ok_or_else(|| FileError::InvalidData("No image data".to_string()))