diff options
Diffstat (limited to 'src/view')
-rw-r--r-- | src/view/address.rs | 4 | ||||
-rw-r--r-- | src/view/birthday.rs | 11 | ||||
-rw-r--r-- | src/view/input_objects/address.rs | 151 | ||||
-rw-r--r-- | src/view/input_objects/mod.rs | 106 | ||||
-rw-r--r-- | src/view/input_objects/name.rs | 118 | ||||
-rw-r--r-- | src/view/input_objects/telephone.rs | 162 | ||||
-rw-r--r-- | src/view/input_objects/utility.rs | 39 | ||||
-rw-r--r-- | src/view/main.rs | 16 | ||||
-rw-r--r-- | src/view/mod.rs | 5 | ||||
-rw-r--r-- | src/view/name.rs | 4 | ||||
-rw-r--r-- | src/view/photo.rs | 10 | ||||
-rw-r--r-- | src/view/telephone.rs | 4 |
12 files changed, 17 insertions, 613 deletions
diff --git a/src/view/address.rs b/src/view/address.rs index 4d3eae7..e26de04 100644 --- a/src/view/address.rs +++ b/src/view/address.rs @@ -1,7 +1,7 @@ use yew::prelude::*; use vcard::properties; -use super::input_objects::address::*; -use super::input_objects::VCardPropertyInputObject; +use crate::viewmodel::address::*; +use crate::viewmodel::VCardPropertyInputObject; use super::VCardPropertyInputComponent; pub struct AddressView { diff --git a/src/view/birthday.rs b/src/view/birthday.rs deleted file mode 100644 index d4b9356..0000000 --- a/src/view/birthday.rs +++ /dev/null @@ -1,11 +0,0 @@ -use yew::prelude::*; -use vcard::properties; -use vcard::parameters; -use vcard::values::{self, text}; - -#[derive(Clone)] -pub struct Birthday { - pub year: u16, - pub month: u8, - pub day: u8, -}
\ No newline at end of file diff --git a/src/view/input_objects/address.rs b/src/view/input_objects/address.rs deleted file mode 100644 index 3975200..0000000 --- a/src/view/input_objects/address.rs +++ /dev/null @@ -1,151 +0,0 @@ -use vcard::properties; -use vcard::parameters; -use vcard::values::{self, text}; -use std::collections::HashSet; -use super::*; -use super::super::address::*; - -#[derive(Clone)] -pub struct Address { - pub post_office_box: String, - pub extension: String, - pub street: String, - pub locality: String, - pub region: String, - pub code: String, - pub country: String, - pub work: bool, - pub home: bool, -} - -impl VCardPropertyInputObject<properties::Address, AddressView> for Address { - fn new() -> Self { - Self { - post_office_box: String::new(), - extension: String::new(), - street: String::new(), - locality: String::new(), - region: String::new(), - code: String::new(), - country: String::new(), - work: false, - home: false, - } - } - fn get_input_fields(&self, link: &ComponentLink<AddressView>) -> Vec<VCardPropertyInputField> { - vec![ - VCardPropertyInputField::Text{ - label: "Post Office Box".to_string(), - id: Some("post_office_box".to_string()), - placeholder: None, - oninput: link.callback(|e: InputData| Msg::UpdatePostOfficeBox(e.value)), - value: self.post_office_box.clone(), - }, - VCardPropertyInputField::Text{ - label: "Extension".to_string(), - id: Some("extension".to_string()), - placeholder: None, - oninput: link.callback(|e: InputData| Msg::UpdateExtension(e.value)), - value: self.extension.clone(), - }, - VCardPropertyInputField::Text{ - label: "Street".to_string(), - id: Some("street".to_string()), - placeholder: None, - oninput: link.callback(|e: InputData| Msg::UpdateStreet(e.value)), - value: self.street.clone(), - }, - VCardPropertyInputField::Text{ - label: "Locality".to_string(), - id: Some("locality".to_string()), - placeholder: None, - oninput: link.callback(|e: InputData| Msg::UpdateLocality(e.value)), - value: self.locality.clone(), - }, - VCardPropertyInputField::Text{ - label: "Region".to_string(), - id: Some("region".to_string()), - placeholder: None, - oninput: link.callback(|e: InputData| Msg::UpdateRegion(e.value)), - value: self.region.clone(), - }, - VCardPropertyInputField::Text{ - label: "Code".to_string(), - id: Some("code".to_string()), - placeholder: None, - oninput: link.callback(|e: InputData| Msg::UpdateCode(e.value)), - value: self.code.clone(), - }, - VCardPropertyInputField::Text{ - label: "Country".to_string(), - id: Some("country".to_string()), - placeholder: None, - oninput: link.callback(|e: InputData| Msg::UpdateCountry(e.value)), - value: self.country.clone(), - }, - VCardPropertyInputField::CheckBox{ - label: "Work".to_string(), - id: Some("work".to_string()), - onclick: link.callback(|_: MouseEvent| Msg::ToggleWork), - value: self.work, - }, - VCardPropertyInputField::CheckBox{ - label: "Home".to_string(), - id: Some("home".to_string()), - onclick: link.callback(|_: MouseEvent| Msg::ToggleHome), - value: self.home, - }, - ] - } - fn to_vcard_property(&self) -> Result<properties::Address, VCardPropertyInputError> { - let address_value = values::address_value::AddressValue::from_components( - match self.post_office_box.is_empty() { - true => None, - false => Some(text::Component::from_str(&self.post_office_box).unwrap()), - }, - match self.extension.is_empty() { - true => None, - false => Some(text::Component::from_str(&self.extension).unwrap()), - }, - match self.street.is_empty() { - true => None, - false => Some(text::Component::from_str(&self.street).unwrap()), - }, - match self.locality.is_empty() { - true => None, - false => Some(text::Component::from_str(&self.locality).unwrap()), - }, - match self.region.is_empty() { - true => None, - false => Some(text::Component::from_str(&self.region).unwrap()), - }, - match self.code.is_empty() { - true => None, - false => Some(text::Component::from_str(&self.code).unwrap()), - }, - match self.country.is_empty() { - true => None, - false => Some(text::Component::from_str(&self.country).unwrap()), - }, - ); - - let mut address = properties::Address::from_address_value(address_value); - - let type_values = { - let mut type_values = HashSet::new(); - - if self.work { - type_values.insert(values::type_value::TypeValue::Work); - } - if self.home { - type_values.insert(values::type_value::TypeValue::Home); - } - - vcard::Set::from_hash_set(type_values).unwrap() - }; - - address.typ = Some(parameters::typ::Type::from_type_values(type_values)); - - Ok(address) - } -}
\ No newline at end of file diff --git a/src/view/input_objects/mod.rs b/src/view/input_objects/mod.rs deleted file mode 100644 index 7c0fdff..0000000 --- a/src/view/input_objects/mod.rs +++ /dev/null @@ -1,106 +0,0 @@ -use vcard::properties; -use yew::prelude::*; -use super::VCardPropertyInputComponent; - -pub mod address; -pub mod birthday; -pub mod name; -pub mod photo; -pub mod telephone; -pub mod utility; - -pub trait VCardPropertyInputObject<P: properties::Property, C: VCardPropertyInputComponent<P, Self>> - where Self: Sized -{ - fn new() -> Self; - fn get_input_fields(&self, link: &ComponentLink<C>) -> Vec<VCardPropertyInputField>; - fn render(&self, link: &ComponentLink<C>) -> Html { - html!{ - <div class="columns is-mobile is-multiline"> - { - for self.get_input_fields(link).iter().map(|field| - field.render() - ) - } - </div> - } - } - fn to_vcard_property(&self) -> Result<P, VCardPropertyInputError>; -} - -#[derive(Debug)] -pub struct VCardPropertyInputError { - msg: String, -} - -pub enum VCardPropertyInputField { - Text { - label: String, - id: Option<String>, - placeholder: Option<String>, - oninput: Callback<InputData>, - value: String, - }, - CheckBox { - label: String, - id: Option<String>, - onclick: Callback<MouseEvent>, - value: bool, - }, -} - -impl VCardPropertyInputField { - pub fn render(&self) -> Html { - match self { - Self::Text { - label, - id, - placeholder, - oninput, - value: _, - } => Self::text_field_input(label, id, placeholder, oninput), - Self::CheckBox { - label, - id, - onclick, - value, - } => Self::checkbox_field_input(label, id, value, onclick), - } - } - fn text_field_input(label: &str, id: &Option<String>, placeholder: &Option<String>, oninput: &Callback<InputData>) -> Html { - html!{ - <div class="field column - is-one-fifth-widescreen - is-one-quarter-desktop - is-one-third-tablet - is-half-mobile" > - <label class="label">{ label }</label> - <div class="control"> - <input id=id.as_ref().unwrap_or(&"".to_string()) - type="text" - placeholder=placeholder.as_ref().unwrap_or(&"".to_string()) - oninput=oninput - /> - </div> - </div> - } - } - fn checkbox_field_input(label: &str, id: &Option<String>, checked: &bool, onclick: &Callback<MouseEvent>) -> Html { - html!{ - <div class="field column - is-one-fifth-widescreen - is-one-quarter-desktop - is-one-third-tablet - is-half-mobile" > - <label class="checkbox"> - <input id=id.as_ref().unwrap_or(&"".to_string()) - type="checkbox" - checked=*checked - onclick=onclick - /> - { label } - </label> - </div> - } - } -}
\ No newline at end of file diff --git a/src/view/input_objects/name.rs b/src/view/input_objects/name.rs deleted file mode 100644 index 0fe9e64..0000000 --- a/src/view/input_objects/name.rs +++ /dev/null @@ -1,118 +0,0 @@ -use vcard::properties; -use vcard::values::{self, text}; -use super::*; -use super::super::name::*; - -#[derive(Clone)] -pub struct Name { - pub prefix: String, - pub first_name: String, - pub middle_name: String, - pub last_name: String, - pub suffix: String, -} - -impl VCardPropertyInputObject<properties::Name, NameView> for Name { - fn new() -> Self { - Self { - prefix: String::new(), - first_name: String::new(), - middle_name: String::new(), - last_name: String::new(), - suffix: String::new(), - } - } - fn get_input_fields(&self, link: &ComponentLink<NameView>) -> std::vec::Vec<VCardPropertyInputField> { - vec![ - VCardPropertyInputField::Text{ - label: "Prefix".to_string(), - id: Some("prefix".to_string()), - placeholder: Some("Sir".to_string()), - oninput: link.callback(|e: InputData| Msg::UpdatePrefix(e.value)), - value: self.prefix.clone(), - }, - VCardPropertyInputField::Text{ - label: "First Name".to_string(), - id: Some("first_name".to_string()), - placeholder: Some("Arthur".to_string()), - oninput: link.callback(|e: InputData| Msg::UpdateFirstName(e.value)), - value: self.first_name.clone(), - }, - VCardPropertyInputField::Text{ - label: "Middle Name".to_string(), - id: Some("middle_name".to_string()), - placeholder: Some("Charles".to_string()), - oninput: link.callback(|e: InputData| Msg::UpdateMiddleName(e.value)), - value: self.middle_name.clone(), - }, - VCardPropertyInputField::Text{ - label: "Last Name".to_string(), - id: Some("last_name".to_string()), - placeholder: Some("Clarke".to_string()), - oninput: link.callback(|e: InputData| Msg::UpdateLastName(e.value)), - value: self.last_name.clone(), - }, - VCardPropertyInputField::Text{ - label: "Suffix".to_string(), - id: Some("suffix".to_string()), - placeholder: Some("CBE FRAS".to_string()), - oninput: link.callback(|e: InputData| Msg::UpdateSuffix(e.value)), - value: self.suffix.clone(), - }, - ] - } - fn to_vcard_property(&self) -> std::result::Result<properties::Name, VCardPropertyInputError> { - let name_value = values::name_value::NameValue::from_components( - match self.last_name.is_empty() { - true => None, - false => Some(text::Component::from_str(&self.last_name).unwrap()), - }, - match self.first_name.is_empty() { - true => None, - false => Some(text::Component::from_str(&self.first_name).unwrap()), - }, - match self.middle_name.is_empty() { - true => None, - false => Some(text::Component::from_str(&self.middle_name).unwrap()), - }, - match self.prefix.is_empty() { - true => None, - false => Some(text::Component::from_str(&self.prefix).unwrap()), - }, - match self.suffix.is_empty() { - true => None, - false => Some(text::Component::from_str(&self.suffix).unwrap()), - }, - ); - - Ok(properties::Name::from_name_value(name_value)) - } -} - -impl Name { - pub fn formatted_name(&self) -> String { - let mut formatted_name = String::new(); - - if !self.prefix.is_empty() { - formatted_name.push_str(&self.prefix); - } - if !self.first_name.is_empty() { - formatted_name.push_str(" "); - formatted_name.push_str(&self.first_name); - } - if !self.middle_name.is_empty() { - formatted_name.push_str(" "); - formatted_name.push_str(&self.middle_name); - } - if !self.last_name.is_empty() { - formatted_name.push_str(" "); - formatted_name.push_str(&self.last_name); - } - if !self.suffix.is_empty() { - formatted_name.push_str(", "); - formatted_name.push_str(&self.suffix); - } - - formatted_name - } -}
\ No newline at end of file diff --git a/src/view/input_objects/telephone.rs b/src/view/input_objects/telephone.rs deleted file mode 100644 index d7f7194..0000000 --- a/src/view/input_objects/telephone.rs +++ /dev/null @@ -1,162 +0,0 @@ -use vcard::properties; -use vcard::parameters; -use vcard::values; -use std::collections::HashSet; -use super::*; -use super::super::telephone::*; - -#[derive(Clone)] -pub struct Telephone { - pub number: String, - pub extension: String, - pub work: bool, - pub home: bool, - pub text: bool, - pub voice: bool, - pub fax: bool, - pub cell: bool, - pub video: bool, - pub pager: bool, - pub text_phone: bool, -} - -impl VCardPropertyInputObject<properties::Telephone, TelephoneView> for Telephone { - fn new() -> Self { - Self { - number: String::new(), - extension: String::new(), - work: false, - home: false, - text: false, - voice: false, - fax: false, - cell: false, - video: false, - pager: false, - text_phone: false, - } - } - fn get_input_fields(&self, link: &ComponentLink<TelephoneView>) -> Vec<VCardPropertyInputField> { - vec![ - VCardPropertyInputField::Text{ - label: "Number".to_string(), - id: Some("number".to_string()), - placeholder: None, - oninput: link.callback(|e: InputData| Msg::UpdateNumber(e.value)), - value: self.number.clone(), - }, - VCardPropertyInputField::Text{ - label: "Extension".to_string(), - id: Some("extension".to_string()), - placeholder: None, - oninput: link.callback(|e: InputData| Msg::UpdateExtension(e.value)), - value: self.extension.clone(), - }, - VCardPropertyInputField::CheckBox{ - label: "Work".to_string(), - id: Some("work".to_string()), - onclick: link.callback(|_: MouseEvent| Msg::ToggleWork), - value: self.work, - }, - VCardPropertyInputField::CheckBox{ - label: "Home".to_string(), - id: Some("home".to_string()), - onclick: link.callback(|_: MouseEvent| Msg::ToggleHome), - value: self.home, - }, - VCardPropertyInputField::CheckBox{ - label: "Text".to_string(), - id: Some("text".to_string()), - onclick: link.callback(|_: MouseEvent| Msg::ToggleText), - value: self.text, - }, - VCardPropertyInputField::CheckBox{ - label: "Voice".to_string(), - id: Some("voice".to_string()), - onclick: link.callback(|_: MouseEvent| Msg::ToggleVoice), - value: self.voice, - }, - VCardPropertyInputField::CheckBox{ - label: "Fax".to_string(), - id: Some("fax".to_string()), - onclick: link.callback(|_: MouseEvent| Msg::ToggleFax), - value: self.fax, - }, - VCardPropertyInputField::CheckBox{ - label: "Cell".to_string(), - id: Some("cell".to_string()), - onclick: link.callback(|_: MouseEvent| Msg::ToggleCell), - value: self.cell, - }, - VCardPropertyInputField::CheckBox{ - label: "Video".to_string(), - id: Some("video".to_string()), - onclick: link.callback(|_: MouseEvent| Msg::ToggleVideo), - value: self.video, - }, - VCardPropertyInputField::CheckBox{ - label: "Pager".to_string(), - id: Some("pager".to_string()), - onclick: link.callback(|_: MouseEvent| Msg::TogglePager), - value: self.pager, - }, - VCardPropertyInputField::CheckBox{ - label: "Text Phone".to_string(), - id: Some("text_phone".to_string()), - onclick: link.callback(|_: MouseEvent| Msg::ToggleTextPhone), - value: self.text_phone, - }, - ] - } - fn to_vcard_property(&self) -> Result<properties::Telephone, VCardPropertyInputError> { - let mut telephone = properties::Telephone::from_telephone_value( - values::telephone_value::TelephoneValue::from_telephone_number_str( - self.number.clone(), - match self.extension.is_empty() { - true => None::<&str>, - false => Some(&self.extension), - }, - ).unwrap() - ); - - let type_values = { - let mut type_values = HashSet::new(); - - if self.work { - type_values.insert(values::type_value::TypeValueWithTelephoneType::Work); - } - if self.home { - type_values.insert(values::type_value::TypeValueWithTelephoneType::Home); - } - if self.text { - type_values.insert(values::type_value::TypeValueWithTelephoneType::Text); - } - if self.voice { - type_values.insert(values::type_value::TypeValueWithTelephoneType::Voice); - } - if self.fax { - type_values.insert(values::type_value::TypeValueWithTelephoneType::Fax); - } - if self.cell { - type_values.insert(values::type_value::TypeValueWithTelephoneType::Cell); - } - if self.video { - type_values.insert(values::type_value::TypeValueWithTelephoneType::Video); - } - if self.pager { - type_values.insert(values::type_value::TypeValueWithTelephoneType::Pager); - } - if self.text_phone { - type_values.insert(values::type_value::TypeValueWithTelephoneType::TextPhone); - } - - vcard::Set::from_hash_set(type_values).unwrap() - }; - - if let properties::Telephone::TelephoneValue { ref mut typ, .. } = telephone { - *typ = Some(parameters::typ::TypeWithTelType::from_type_values(type_values)); - } - - Ok(telephone) - } -}
\ No newline at end of file diff --git a/src/view/input_objects/utility.rs b/src/view/input_objects/utility.rs deleted file mode 100644 index a296c1e..0000000 --- a/src/view/input_objects/utility.rs +++ /dev/null @@ -1,39 +0,0 @@ -#[derive(Clone)] -pub struct Download { - pub file_name: String, - pub content: String, - pub mime_type: MimeType, -} - -impl Download { - pub fn as_data_link(&self) -> String { - let data = base64::encode(&*self.content); - let uri_component: String = js_sys::encode_uri_component(&data).into(); - - format!("data:{};base64,{}", self.mime_type.as_text(), uri_component) - } -} - -#[derive(Clone, Copy)] -pub enum MimeType { - PDF, - VCard, - SVG, -} - -impl MimeType { - pub fn as_text(&self) -> &str { - match self { - MimeType::PDF => "application/pdf", - MimeType::VCard => "text/vcard", - MimeType::SVG => "image/svg+xml", - } - } -} - -#[derive(Clone, Copy)] -pub enum DownloadOption { - PDF, - VCard, - QrCode, -}
\ No newline at end of file diff --git a/src/view/main.rs b/src/view/main.rs index e1753b4..684db84 100644 --- a/src/view/main.rs +++ b/src/view/main.rs @@ -8,11 +8,11 @@ use qrcodegen::QrCode; use qrcodegen::QrCodeEcc; use yew::prelude::*; use vcard::{VCard, VCardError}; -use super::input_objects::utility::*; -use super::input_objects::name::Name; -use super::input_objects::address::Address; -use super::input_objects::telephone::Telephone; -use super::input_objects::VCardPropertyInputObject; +use crate::viewmodel::utility::*; +use crate::viewmodel::name::Name; +use crate::viewmodel::address::Address; +use crate::viewmodel::telephone::Telephone; +use crate::viewmodel::VCardPropertyInputObject; pub struct MainView { @@ -312,7 +312,11 @@ impl MainView { doc.set_title("BCard test"); doc.set_minimal_conformance(); - doc.set_margins(10); + + let mut decorator = genpdf::SimplePageDecorator::new(); + decorator.set_margins(10); + doc.set_page_decorator(decorator); + doc.set_line_spacing(1.25); doc.push( diff --git a/src/view/mod.rs b/src/view/mod.rs index b46accf..b47612a 100644 --- a/src/view/mod.rs +++ b/src/view/mod.rs @@ -1,11 +1,8 @@ use yew::prelude::*; -use input_objects::*; -pub mod input_objects; +use crate::viewmodel::*; pub mod main; pub mod name; -pub mod photo; -pub mod birthday; pub mod address; pub mod telephone; diff --git a/src/view/name.rs b/src/view/name.rs index 4ac78a4..f76fd2e 100644 --- a/src/view/name.rs +++ b/src/view/name.rs @@ -1,7 +1,7 @@ use yew::prelude::*; use vcard::properties; -use super::input_objects::name::*; -use super::input_objects::VCardPropertyInputObject; +use crate::viewmodel::name::*; +use crate::viewmodel::VCardPropertyInputObject; use super::VCardPropertyInputComponent; pub struct NameView { diff --git a/src/view/photo.rs b/src/view/photo.rs deleted file mode 100644 index 1c2d088..0000000 --- a/src/view/photo.rs +++ /dev/null @@ -1,10 +0,0 @@ -use yew::prelude::*; -use vcard::properties; -use vcard::parameters; -use vcard::values::{self, text}; - -#[derive(Clone)] -pub struct Photo { - pub base64_image: String, -} - diff --git a/src/view/telephone.rs b/src/view/telephone.rs index 516552e..808ebfa 100644 --- a/src/view/telephone.rs +++ b/src/view/telephone.rs @@ -1,7 +1,7 @@ use yew::prelude::*; use vcard::properties; -use super::input_objects::telephone::*; -use super::input_objects::VCardPropertyInputObject; +use crate::viewmodel::telephone::*; +use crate::viewmodel::VCardPropertyInputObject; use super::VCardPropertyInputComponent; pub struct TelephoneView { |