From 5a03734b6767fed04c0913384584d8f59dc597ea Mon Sep 17 00:00:00 2001 From: jelemux Date: Tue, 24 Nov 2020 21:58:51 +0100 Subject: add traits for viewmodel and view --- src/view/mod.rs | 388 +++----------------------------------------------------- 1 file changed, 18 insertions(+), 370 deletions(-) (limited to 'src/view/mod.rs') diff --git a/src/view/mod.rs b/src/view/mod.rs index d34eb39..b46accf 100644 --- a/src/view/mod.rs +++ b/src/view/mod.rs @@ -1,262 +1,26 @@ -use crate::view::telephone::{TelephoneView,Telephone}; -use std::collections::HashSet; -use name::{NameView,Name}; -use address::{AddressView,Address,AddressType}; -use genpdf::Element as _; -use genpdf::{elements, style, fonts}; -use qrcodegen::QrCode; -use qrcodegen::QrCodeEcc; use yew::prelude::*; -use vcard::{VCard, VCardError}; - - -mod name; -mod photo; -mod birthday; -mod address; -mod telephone; - -#[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, -} - -pub struct MainView { - link: ComponentLink, - error: Vec, - name: Name, - work_address: Address, - home_address: Address, - telephone: Telephone, - download: Option, - selected_option: DownloadOption, -} - -pub enum Msg { - UpdateName(Name), - UpdateHomeAddress(Address), - UpdateWorkAddress(Address), - UpdateTelephone(Telephone), - Generate(DownloadOption), - Nope, -} - -impl Component for MainView { - type Message = Msg; - type Properties = (); - - fn create(_props: Self::Properties, link: ComponentLink) -> Self { - MainView { - link, - error: vec![], - name: Name::new(), - work_address: Address::new_with_type(AddressType::Work), - home_address: Address::new_with_type(AddressType::Home), - telephone: Telephone::new(), - download: None, - selected_option: DownloadOption::VCard - } - } - - fn update(&mut self, msg: Self::Message) -> ShouldRender { - self.error.clear(); - match msg { - Msg::UpdateName(value) => { - self.name = value; - self.link.send_message(Msg::Generate(self.selected_option)); - }, - Msg::UpdateHomeAddress(value) => { - self.home_address = value; - self.link.send_message(Msg::Generate(self.selected_option)); - }, - Msg::UpdateWorkAddress(value) => { - self.work_address = value; - self.link.send_message(Msg::Generate(self.selected_option)); - }, - Msg::UpdateTelephone(value) => { - self.telephone = value; - self.link.send_message(Msg::Generate(self.selected_option)); - }, - Msg::Generate(option) => { - self.selected_option = option; - - let vcard_content = match self.generate_vcard() { - Ok(vcard) => Some(vcard.to_string()), - Err(VCardError::FormatError(err)) => { - self.error.push(err.to_string()); - None - } - Err(VCardError::EmptyFormatName) => { - self.error.push(String::from("At least one of the name fields should be filled out.")); - None - } - }; - - match option { - DownloadOption::VCard => { - if vcard_content.is_some() { - self.download = Some( - Download { - file_name: format!("{}.vcs", self.name.formatted_name()), - content: vcard_content.unwrap().to_string(), - mime_type: MimeType::VCard, - } - ) - } - } - DownloadOption::QrCode => { - if vcard_content.is_some() { - match QrCode::encode_text(vcard_content.as_ref().unwrap(), QrCodeEcc::Low) { - Ok(qr) => self.download = Some( - Download { - file_name: format!("QR-Code VCard {}.svg", self.name.formatted_name()), - content: qr.to_svg_string(4), - mime_type: MimeType::SVG, - } - ), - Err(_) => self.error.push(String::from("Sorry, VCard is too long!")), - }; - } - } - DownloadOption::PDF => { - match self.generate_pdf() { - Ok(pdf) => self.download = Some( - Download { - file_name: format!("Visitenkarten {}.pdf", self.name.formatted_name()), - content: pdf, - mime_type: MimeType::PDF, - } - ), - Err(_) => self.error.push(String::from("Unexpected error while generating the PDF. Please contact me about it.")), - } - } - } - } - Msg::Nope => return false, - }; - if self.error.len() > 0 { - self.download = None; - } - true - } - - fn change(&mut self, _props: Self::Properties) -> ShouldRender { - false - } - - fn view(&self) -> Html { - - let download_options = self.link.callback(|e: ChangeData| - match e { - ChangeData::Select(v) => match v.value().as_str() { - "vcard" => Msg::Generate(DownloadOption::VCard), - "pdf" => Msg::Generate(DownloadOption::PDF), - "qrcode" => Msg::Generate(DownloadOption::QrCode), - _ => Msg::Nope, - }, - _ => Msg::Nope, - } - ); - - html!{ - <> -
-
-
-
-

{ "A Generator for vCards" }

-

{ "Supports generating vCards (.vcf), print-ready PDF business cards and QR Codes" }

-
-
-
- -
-
- - { self.render_errors() } - - - - - - - - - -
-
- -
- - { self.render_download() } -
- -
- { self.render_preview() } -
- -
-
-
- - - - } - } -} - -impl MainView { +use input_objects::*; +pub mod input_objects; + +pub mod main; +pub mod name; +pub mod photo; +pub mod birthday; +pub mod address; +pub mod telephone; + +pub trait VCardPropertyInputComponent: Component + where P: vcard::properties::Property, + T: VCardPropertyInputObject +{ + fn get_input_object(&self) -> T; + fn get_title(&self) -> String; + fn get_errors(&self) -> Vec; fn render_errors(&self) -> Html { html!{ <> { - for self.error.iter().map(|err| + for self.get_errors().iter().map(|err| html!{
{ err } @@ -267,120 +31,4 @@ impl MainView { } } - fn render_download(&self) -> Html { - if self.download.is_some() { - let download = self.download.as_ref().unwrap(); - - html!{ - - { "Download" } - - } - } else { - html!{} - } - } - fn render_preview(&self) -> Html { - if self.download.is_some() { - let download = self.download.as_ref().unwrap(); - - match download.mime_type { - MimeType::PDF => html!{ -