diff options
-rw-r--r-- | src/model/property_groups/communication.rs | 71 | ||||
-rw-r--r-- | src/model/property_groups/mod.rs | 1 | ||||
-rw-r--r-- | src/model/vcard.rs | 4 | ||||
-rw-r--r-- | src/view/main.rs | 79 |
4 files changed, 149 insertions, 6 deletions
diff --git a/src/model/property_groups/communication.rs b/src/model/property_groups/communication.rs new file mode 100644 index 0000000..82fce2a --- /dev/null +++ b/src/model/property_groups/communication.rs @@ -0,0 +1,71 @@ +use crate::model::input_fields::VCardPropertyInputField; +use crate::model::*; + +#[derive(Clone, Debug, PartialEq)] +pub struct Communication { + pub email_address: String, + pub impp: String, +} + +#[derive(Clone, PartialEq)] +pub enum CommunicationMsg { + UpdateEmailAddress(String), + UpdateImpp(String), + + Generate, +} + +impl VCardPropertyInputGroupObject<CommunicationMsg> for Communication { + fn new() -> Self { + Self { + email_address: String::new(), + impp: String::new(), + } + } + fn get_title(&self) -> String { + String::from("Communication") + } + fn get_input_fields( + &self, + link: &yew::html::Scope<PropertyGroupInputComponent<Self, CommunicationMsg>>, + ) -> Vec<VCardPropertyInputField> { + vec![ + VCardPropertyInputField::Text { + label: "Email Address".to_string(), + id: Some("email_address".to_string()), + placeholder: None, + oninput: link + .callback(|e: InputData| CommunicationMsg::UpdateEmailAddress(e.value)), + value: self.email_address.clone(), + typ: String::from("email"), + }, + VCardPropertyInputField::Text { + label: "Instant Messaging URI".to_string(), + id: Some("impp".to_string()), + placeholder: None, + oninput: link.callback(|e: InputData| CommunicationMsg::UpdateImpp(e.value)), + value: self.impp.clone(), + typ: String::from("text"), + }, + ] + } + fn update( + &mut self, + props: InputProps<Self, CommunicationMsg>, + msg: <PropertyGroupInputComponent<Self, CommunicationMsg> as yew::Component>::Message, + ) -> bool { + match msg { + CommunicationMsg::UpdateEmailAddress(a) => self.email_address = a, + CommunicationMsg::UpdateImpp(i) => self.impp = i, + + CommunicationMsg::Generate => { + props.generated.emit(self.clone()); + } + }; + + true + } + fn is_empty(&self) -> bool { + self.email_address.is_empty() && self.impp.is_empty() + } +} diff --git a/src/model/property_groups/mod.rs b/src/model/property_groups/mod.rs index 3bfc9f3..ec4e87f 100644 --- a/src/model/property_groups/mod.rs +++ b/src/model/property_groups/mod.rs @@ -1,4 +1,5 @@ pub mod address; +pub mod communication; pub mod name; pub mod organizational; pub mod other_identification; diff --git a/src/model/vcard.rs b/src/model/vcard.rs index 24a47ff..4670fe7 100644 --- a/src/model/vcard.rs +++ b/src/model/vcard.rs @@ -1,4 +1,5 @@ use crate::model::property_groups::address::Address; +use crate::model::property_groups::communication::Communication; use crate::model::property_groups::name::Name; use crate::model::property_groups::organizational::Organizational; use crate::model::property_groups::other_identification::OtherIdentification; @@ -10,6 +11,7 @@ pub struct VCardData { pub names: Vec<Name>, pub addresses: Vec<Address>, pub telephones: Vec<Telephone>, + pub communications: Vec<Communication>, pub other_identifications: Vec<OtherIdentification>, pub organizationals: Vec<Organizational>, } @@ -28,6 +30,7 @@ impl VCardData { names: Vec::new(), addresses: Vec::new(), telephones: Vec::new(), + communications: Vec::new(), other_identifications: Vec::new(), organizationals: Vec::new(), } @@ -35,6 +38,7 @@ impl VCardData { make_vec_adder_fn!( fn add_name names => name: Name ); make_vec_adder_fn!( fn add_address addresses => address: Address ); make_vec_adder_fn!( fn add_telephone telephones => telephone: Telephone ); + make_vec_adder_fn!( fn add_communication communications => communication: Communication ); make_vec_adder_fn!( fn add_other_identification other_identifications => other_identification: OtherIdentification ); make_vec_adder_fn!( fn add_organizational organizationals => organizational: Organizational ); } diff --git a/src/view/main.rs b/src/view/main.rs index dd32e33..9ce032a 100644 --- a/src/view/main.rs +++ b/src/view/main.rs @@ -1,4 +1,5 @@ use crate::model::property_groups::address::*; +use crate::model::property_groups::communication::*; use crate::model::property_groups::name::*; use crate::model::property_groups::organizational::*; use crate::model::property_groups::other_identification::*; @@ -28,6 +29,7 @@ type OtherIdentificationView = PropertyGroupInputComponent<OtherIdentification, OtherIdentificationMsg>; type OrganizationalView = PropertyGroupInputComponent<Organizational, OrganizationalMsg>; type TelephoneView = PropertyGroupInputComponent<Telephone, TelephoneMsg>; +type CommunicationView = PropertyGroupInputComponent<Communication, CommunicationMsg>; pub struct MainView { link: ComponentLink<Self>, @@ -39,6 +41,7 @@ pub struct MainView { name_links: Vec<WeakComponentLink<NameView>>, address_links: Vec<WeakComponentLink<AddressView>>, telephone_links: Vec<WeakComponentLink<TelephoneView>>, + communcation_links: Vec<WeakComponentLink<CommunicationView>>, other_identifications_links: Vec<WeakComponentLink<OtherIdentificationView>>, organizational_links: Vec<WeakComponentLink<OrganizationalView>>, @@ -56,6 +59,8 @@ pub enum Msg { DelOtherIdentification(usize), AddOrganizational, DelOrganizational(usize), + AddCommunication, + DelCommunication(usize), ChangeDownloadOption(DownloadOption), @@ -65,6 +70,7 @@ pub enum Msg { GeneratedAddress(Address), GeneratedTelephone(Telephone), GeneratedOrganizational(Organizational), + GeneratedCommunication(Communication), GenerationComplete, Nope, @@ -85,6 +91,7 @@ impl Component for MainView { name_links: vec![WeakComponentLink::default()], address_links: vec![WeakComponentLink::default()], telephone_links: vec![WeakComponentLink::default()], + communcation_links: vec![WeakComponentLink::default()], other_identifications_links: vec![WeakComponentLink::default()], organizational_links: vec![WeakComponentLink::default()], answer_count: 0, @@ -136,6 +143,14 @@ impl Component for MainView { self.organizational_links.remove(idx); true } + Msg::AddCommunication => { + self.communcation_links.push(WeakComponentLink::default()); + true + } + Msg::DelCommunication(idx) => { + self.communcation_links.remove(idx); + true + } Msg::ChangeDownloadOption(option) => { self.selected_option = option; false @@ -159,15 +174,20 @@ impl Component for MainView { telephone_link.send_message(TelephoneMsg::Generate); } - for dates_link in self.other_identifications_links.iter() { - let dates_link = dates_link.borrow().clone().unwrap(); - dates_link.send_message(OtherIdentificationMsg::Generate) + for other_identifications_link in self.other_identifications_links.iter() { + let other_identifications_link = other_identifications_link.borrow().clone().unwrap(); + other_identifications_link.send_message(OtherIdentificationMsg::Generate) } - for organizational_links in self.organizational_links.iter() { - let organizational_link = organizational_links.borrow().clone().unwrap(); + for organizational_link in self.organizational_links.iter() { + let organizational_link = organizational_link.borrow().clone().unwrap(); organizational_link.send_message(OrganizationalMsg::Generate) } + + for communcation_link in self.communcation_links.iter() { + let communcation_link = communcation_link.borrow().clone().unwrap(); + communcation_link.send_message(CommunicationMsg::Generate) + } } /* DownloadOption::PDF => { @@ -235,6 +255,18 @@ impl Component for MainView { true } + Msg::GeneratedCommunication(communication) => { + self.answer_count += 1; + + match self.vcard_data.get_mut() { + Some(vcard_data) => vcard_data.add_communication(communication), + None => ConsoleService::info( + "Error in GeneratedCommunication: Couldn't get mutable borrow of VCardData", + ), + }; + + true + } Msg::GeneratedOrganizational(organizational) => { self.answer_count += 1; @@ -363,6 +395,15 @@ impl Component for MainView { } } + for communication in vcard_data.communications { + if !communication.email_address.is_empty() { + builder = builder.with_email(communication.email_address.clone()); + } + if !communication.impp.is_empty() { + builder = builder.with_impp(communication.impp.clone()); + } + } + for other_identification in vcard_data.other_identifications { if !other_identification.nickname.is_empty() { builder = @@ -469,7 +510,7 @@ impl Component for MainView { true } - Msg::Nope => false + Msg::Nope => false, }; if self.answer_count >= self.get_subcomponent_count() { @@ -617,6 +658,31 @@ impl Component for MainView { <div class="level"> <div class="level-left"> <div class="level-item"> + <h2 class="subtitle is-2">{ "Communication" }</h2> + </div> + <div class="level-item"> + <button onclick=self.link.callback(|_| Msg::AddCommunication) class="button">{ "Add more" }</button> + </div> + </div> + </div> + + { + for self.communcation_links.iter().enumerate().map(move |(idx, link)| + html!{ + <CommunicationView weak_link=link + generated=self.link.callback( + |c: Communication| + Msg::GeneratedCommunication(c) + ) + delete=self.link.callback(move |_| Msg::DelCommunication(idx)) + /> + } + ) + } + + <div class="level"> + <div class="level-left"> + <div class="level-item"> <h2 class="subtitle is-2">{ "Organisations" }</h2> </div> <div class="level-item"> @@ -801,5 +867,6 @@ impl MainView { + self.telephone_links.len() + self.other_identifications_links.len() + self.organizational_links.len() + + self.communcation_links.len() } } |