From 0660151a8b641fa0a23dde2598132029970f7ae4 Mon Sep 17 00:00:00 2001 From: jelemux Date: Thu, 11 Feb 2021 12:07:22 +0100 Subject: refactoring - reduced code size by about a third --- src/model/mod.rs | 240 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 240 insertions(+) create mode 100644 src/model/mod.rs (limited to 'src/model/mod.rs') diff --git a/src/model/mod.rs b/src/model/mod.rs new file mode 100644 index 0000000..45c91f1 --- /dev/null +++ b/src/model/mod.rs @@ -0,0 +1,240 @@ +use crate::model::utility::File; +use crate::view::property_group::*; +use wasm_bindgen::closure::Closure; +use wasm_bindgen::JsCast; +use web_sys::FileReader; +use yew::prelude::*; +use yew::services::ConsoleService; + +pub mod address; +pub mod dates; +pub mod name; +pub mod organizational; +pub mod telephone; +pub mod utility; +pub mod vcard; + +/// Trait for types that represent the data of a vcard property used inside of a `VCardPropertyInputComponent`. +pub trait VCardPropertyInputObject: Clone + PartialEq +where + Self: Sized, +{ + /// Function for creating a new (and empty) `VCardPropertyInputObject`. + fn new() -> Self; + /// Getter function for the title of the component + fn get_title(&self) -> String; + /// Converts each field of the `VCardPropertyInputObject` to a VCardPropertyInputField and returns them as a vector. + fn get_input_fields( + &self, + link: &ComponentLink>, + ) -> Vec; + fn update( + &mut self, + props: InputProps, + msg: as yew::Component>::Message, + ) -> bool; + /// Returns a `Html` representation of the `VCardPropertyInputObject`. + fn render(&self, link: &ComponentLink>) -> Html { + html! { +
+ { + for self.get_input_fields(link).iter().map(|field| + field.render() + ) + } +
+ } + } + /// Convenience function for checking if the `VCardPropertyInputObject` is empty. + fn is_empty(&self) -> bool; +} + +/// Type for saving error messages. +/// +/// More of a placeholder for something better later on. +#[derive(Debug, Clone, PartialEq)] +pub struct Error { + pub msg: String, +} + +/// Type that represents the visiual appearance of an input field. +pub enum VCardPropertyInputField { + Text { + label: String, + id: Option, + placeholder: Option, + oninput: Callback, + value: String, + typ: String, + }, + File { + label: String, + name: String, + callback: Callback>, + value: Option, + }, + CheckBox { + label: String, + id: Option, + onclick: Callback, + value: bool, + }, +} + +impl VCardPropertyInputField { + /// Returns a `Html` representation of the `VCardPropertyInputField`. + pub fn render(&self) -> Html { + match self { + Self::Text { + label, + id, + placeholder, + oninput, + value: _, + typ, + } => Self::text_field_input(label, id, placeholder, oninput, typ), + Self::File { + label, + name, + callback, + value, + } => Self::file_field_input(label, name, callback, value), + Self::CheckBox { + label, + id, + onclick, + value, + } => Self::checkbox_field_input(label, id, value, onclick), + } + } + /// Returns an `Html` representation of a text input field with the given parameters. + fn text_field_input( + label: &str, + id: &Option, + placeholder: &Option, + oninput: &Callback, + typ: &str, + ) -> Html { + html! { +
+ +
+ +
+
+ } + } + /// Returns an `Html` representation of a file input field with the given parameters. + fn file_field_input( + label: &str, + name: &str, + callback: &Callback>, + file: &Option, + ) -> Html { + let callback = callback.clone(); + let onchange = Callback::<()>::default(); + let onchange = onchange.reform(move |c: ChangeData| { + if let ChangeData::Files(files) = c { + match files.item(0) { + Some(file) => { + let file_reader = FileReader::new().unwrap(); + match file_reader.read_as_data_url(&file) { + Ok(_) => (), + Err(_) => ConsoleService::warn("Error: Couldn't get file as data url."), + }; + + let callback = callback.clone(); + let onload = Closure::wrap(Box::new(move |event: Event| { + let file_reader: FileReader = + event.target().unwrap().dyn_into().unwrap(); + let data_url: Option = + file_reader.result().unwrap().as_string(); + match data_url { + Some(content) => callback.emit(Some(File { + name: file.name(), + content, + })), + None => { + ConsoleService::warn("Couldn't get data url as string."); + callback.emit(None); + } + }; + }) as Box); + + file_reader.set_onload(Some(onload.as_ref().unchecked_ref())); + onload.forget(); + } + None => callback.emit(None), + } + } else { + callback.emit(None); + } + }); + html! { +
+ +
+ +
+
+ } + } + /// Returns an `Html` representation of a checkbox input field with the given parameters. + fn checkbox_field_input( + label: &str, + id: &Option, + checked: &bool, + onclick: &Callback, + ) -> Html { + html! { +
+ +
+ } + } +} -- cgit v1.2.3