diff options
Diffstat (limited to 'src/view/main.rs')
-rw-r--r-- | src/view/main.rs | 281 |
1 files changed, 186 insertions, 95 deletions
diff --git a/src/view/main.rs b/src/view/main.rs index e926504..b1c0dda 100644 --- a/src/view/main.rs +++ b/src/view/main.rs @@ -1,6 +1,8 @@ +use yew::services::ConsoleService; +use yewtil::ptr::Irc; +use crate::viewmodel::vcard::VCardData; use crate::viewmodel::Error; use crate::view::telephone::{self,TelephoneView}; -use std::collections::HashSet; use super::WeakComponentLink; use super::name::{self,NameView}; use super::address::{self,AddressView}; @@ -9,13 +11,15 @@ use genpdf::{elements, style, fonts}; use qrcodegen::QrCode; use qrcodegen::QrCodeEcc; use yew::prelude::*; -use vobject::Vcard; +use yewtil::ptr::Mrc; use vobject::vcard::VcardBuilder; use vobject::parameters; +use chrono::prelude::*; use crate::viewmodel::name::Name; use crate::viewmodel::address::Address; use crate::viewmodel::telephone::Telephone; use crate::viewmodel::utility::*; +use boolinator::Boolinator; pub struct MainView { @@ -23,7 +27,7 @@ pub struct MainView { error: Option<Error>, download: Option<Download>, selected_option: DownloadOption, - vcard_builder: VcardBuilder, + vcard_data: Mrc<VCardData>, name_links: Vec<WeakComponentLink<NameView>>, address_links: Vec<WeakComponentLink<AddressView>>, @@ -40,10 +44,9 @@ pub enum Msg { ChangeDownloadOption(DownloadOption), Generate, - GeneratedFormattedName(String), - GeneratedName(Name), - GeneratedAddress(Address), - GeneratedTelephone(Telephone), + GeneratedName(Irc<Name>), + GeneratedAddress(Irc<Address>), + GeneratedTelephone(Irc<Telephone>), GenerationComplete, Nope, @@ -59,7 +62,7 @@ impl Component for MainView { error: None, download: None, selected_option: DownloadOption::VCard, - vcard_builder: VcardBuilder::new(), + vcard_data: Mrc::new(VCardData::new()), name_links: vec![WeakComponentLink::default()], address_links: vec![WeakComponentLink::default()], @@ -126,26 +129,14 @@ impl Component for MainView { shouldrender = true; }, - Msg::GeneratedFormattedName(formatted_name) => { - - self.answer_count += 1; - - self.vcard_builder = self.vcard_builder.with_fullname(formatted_name); - - shouldrender = true; - }, Msg::GeneratedName(name) => { self.answer_count += 1; - self.vcard_builder = self.vcard_builder.with_name( - parameters!(), - name.last_name.is_empty().then(|| name.last_name), - name.first_name.is_empty().then(|| name.first_name), - name.middle_name.is_empty().then(|| name.middle_name), - name.prefix.is_empty().then(|| name.prefix), - name.suffix.is_empty().then(|| name.suffix) - ); + match self.vcard_data.get_mut() { + Some(vcard_data) => vcard_data.add_name(name), + None => ConsoleService::info("Error in GeneratedName: Couldn't get mutable borrow of VCardData"), + }; shouldrender = true; @@ -154,9 +145,10 @@ impl Component for MainView { self.answer_count += 1; - self.vcard_builder = self.vcard_builder.with_adr( - parameters!(), - ); + match self.vcard_data.get_mut() { + Some(vcard_data) => vcard_data.add_address(address), + None => ConsoleService::info("Error in GeneratedAddress: Couldn't get mutable borrow of VCardData"), + }; shouldrender = true; }, @@ -164,31 +156,10 @@ impl Component for MainView { self.answer_count += 1; - match telephone { - Ok(telephone) => { - match self.vcard { - Some(vcard) => { - match vcard.telephones { - Some(telephones) => { - telephones.insert(telephone); - }, - None => { - let telephones = { - let mut telephones = HashSet::new(); - telephones.insert(telephone); - - telephones - }; - - vcard.telephones = Some(vcard::Set::from_hash_set(telephones).unwrap()); - } - }; - }, - None => (), - }; - }, - Err(_) => (), - } + match self.vcard_data.get_mut() { + Some(vcard_data) => vcard_data.add_telephone(telephone), + None => ConsoleService::info("Error in GeneratedTelephone: Couldn't get mutable borrow of VCardData"), + }; shouldrender = true; }, @@ -196,43 +167,167 @@ impl Component for MainView { self.answer_count = 0; - match self.vcard.clone() { - Some(vcard) => { - match self.selected_option { - DownloadOption::VCard => { - self.download = Some( - Download { - file_name: String::from("VCard.vcs"), - content: vcard.to_string(), - mime_type: MimeType::VCard, - } - ); - }, - DownloadOption::QrCode => { - match QrCode::encode_text(&vcard.to_string(), QrCodeEcc::Low) { - Ok(qr) => self.download = Some( - Download { - file_name: String::from("QR-Code VCard.svg"), - content: qr.to_svg_string(4), - mime_type: MimeType::SVG, - } - ), - Err(_) => self.error = Some( - Error{ - msg: String::from("Sorry, VCard is too long!"), - } - ), - }; - }, - _ => (), - }; - - self.vcard = None; - shouldrender = true; + let vcard_data = match self.vcard_data.irc().try_unwrap() { + Ok(data) => data, + Err(err) => { + ConsoleService::error(&format!("Error when unwrapping VCardData: {:?}", err)); + VCardData::new() }, - None => shouldrender = false, // what TODO here? + }; + + let mut builder = VcardBuilder::new(); + + for name in vcard_data.names { + + builder = builder + .with_fullname( + name.generate_fn() + ) + .with_name( + parameters!(), + name.last_name.is_empty().as_some(name.last_name.clone()), + name.first_name.is_empty().as_some(name.first_name.clone()), + name.middle_name.is_empty().as_some(name.middle_name.clone()), + name.prefix.is_empty().as_some(name.prefix.clone()), + name.suffix.is_empty().as_some(name.suffix.clone()) + ); + } + + for address in vcard_data.addresses { + let mut types = String::new(); + if address.work { + types.push_str("WORK"); + } + if address.home { + if types.is_empty() { + types.push(','); + } + types.push_str("HOME") + } + + builder = builder.with_adr( + parameters!("TYPE" => types), + address.post_office_box.is_empty().as_some(address.post_office_box.clone()), + address.extension.is_empty().as_some(address.extension.clone()), + address.street.is_empty().as_some(address.street.clone()), + address.locality.is_empty().as_some(address.locality.clone()), + address.region.is_empty().as_some(address.region.clone()), + address.code.is_empty().as_some(address.code.clone()), + address.country.is_empty().as_some(address.country.clone()), + ); } + for telephone in vcard_data.telephones { + let mut types = String::new(); + if telephone.work { + types.push_str("WORK"); + } + if telephone.home { + if types.is_empty() { + types.push(','); + } + types.push_str("HOME") + } + if telephone.text { + if types.is_empty() { + types.push(','); + } + types.push_str("TEXT") + } + if telephone.voice { + if types.is_empty() { + types.push(','); + } + types.push_str("VOICE") + } + if telephone.fax { + if types.is_empty() { + types.push(','); + } + types.push_str("FAX") + } + if telephone.cell { + if types.is_empty() { + types.push(','); + } + types.push_str("CELL") + } + if telephone.video { + if types.is_empty() { + types.push(','); + } + types.push_str("VIDEO") + } + if telephone.pager { + if types.is_empty() { + types.push(','); + } + types.push_str("PAGER") + } + if telephone.text_phone { + if types.is_empty() { + types.push(','); + } + types.push_str("TEXTPHONE") + } + + builder = builder.with_tel( + parameters!("TYPE" => types), + telephone.number.clone(), + ); + } + + + let rev = Local::now(); + + match builder + .with_version("4.0".to_string()) + .with_rev(format!("{}", rev)) + .build() { + Ok(vcard) => { + match self.selected_option { + DownloadOption::VCard => { + self.download = Some( + Download { + file_name: String::from("VCard.vcs"), + content: vobject::write_component(&vcard), + mime_type: MimeType::VCard, + } + ); + }, + DownloadOption::QrCode => { + match QrCode::encode_text(&vobject::write_component(&vcard), QrCodeEcc::Low) { + Ok(qr) => self.download = Some( + Download { + file_name: String::from("QR-Code VCard.svg"), + content: qr.to_svg_string(4), + mime_type: MimeType::SVG, + } + ), + Err(_) => self.error = Some( + Error{ + msg: String::from("Sorry, VCard is too long!"), + } + ), + }; + }, + _ => (), + }; + }, + Err(err) => self.error = Some( + Error{ + msg: err.to_string(), + } + ), + }; + + match self.vcard_data.get_mut() { + Some(vcard_data) => *vcard_data = VCardData::new(), + None => ConsoleService::info("Couldn't reset VCardData"), + }; + + shouldrender = true; + }, Msg::Nope => shouldrender = false, }; @@ -286,12 +381,8 @@ impl Component for MainView { for self.name_links.iter().map(|link| html!{ <NameView weak_link=link - generated_fn=self.link.callback( - |fmn: Result<properties::FormattedName,()>| - Msg::GeneratedFormattedName(fmn) - ) - generated_name=self.link.callback( - |n: Result<properties::Name,()>| + generated=self.link.callback( + |n: Irc<Name>| Msg::GeneratedName(n) ) /> @@ -304,7 +395,7 @@ impl Component for MainView { html!{ <AddressView weak_link=link generated=self.link.callback( - |a: Result<properties::Address,()>| + |a: Irc<Address>| Msg::GeneratedAddress(a) ) /> @@ -317,7 +408,7 @@ impl Component for MainView { html!{ <TelephoneView weak_link=link generated=self.link.callback( - |t: Result<properties::Telephone,()>| + |t: Irc<Telephone>| Msg::GeneratedTelephone(t) ) /> @@ -326,7 +417,7 @@ impl Component for MainView { } <div class="block level-left"> - <button onclick=self.link.callback(|_| Msg::Generate) class="button is-primary level-item" /> + <button onclick=self.link.callback(|_| Msg::Generate) class="button is-primary level-item">{ "Generate" }</button> <div class="select level-item"> <select id="download_options" onchange=download_options> |