From 6b9aac5234c65e27fffbceb6147eecddd7d4fd2e Mon Sep 17 00:00:00 2001 From: adbenitez Date: Sat, 9 Jul 2022 05:42:39 -0400 Subject: [PATCH] detect draft when scanning QR with mailto link as data --- deltachat-ffi/src/lot.rs | 18 +++++++++++++--- src/qr.rs | 45 ++++++++++++++++++++++++++++++++-------- 2 files changed, 51 insertions(+), 12 deletions(-) diff --git a/deltachat-ffi/src/lot.rs b/deltachat-ffi/src/lot.rs index 9426ef425..8d1281609 100644 --- a/deltachat-ffi/src/lot.rs +++ b/deltachat-ffi/src/lot.rs @@ -51,7 +51,13 @@ impl Lot { Qr::FprWithoutAddr { fingerprint, .. } => Some(fingerprint), Qr::Account { domain } => Some(domain), Qr::WebrtcInstance { domain, .. } => Some(domain), - Qr::Addr { .. } => None, + Qr::Addr { draft, .. } => { + if let Some(draft) = draft { + Some(draft) + } else { + None + } + } Qr::Url { url } => Some(url), Qr::Text { text } => Some(text), Qr::WithdrawVerifyContact { .. } => None, @@ -79,7 +85,13 @@ impl Lot { Some(SummaryPrefix::Username(_username)) => Meaning::Text1Username, Some(SummaryPrefix::Me(_text)) => Meaning::Text1Self, }, - Self::Qr(_qr) => Meaning::None, + Self::Qr(qr) => match qr { + Qr::Addr { draft, .. } => match draft { + None => Meaning::None, + _ => Meaning::Text1Draft, + }, + _ => Meaning::None, + }, Self::Error(_err) => Meaning::None, } } @@ -118,7 +130,7 @@ impl Lot { Qr::FprWithoutAddr { .. } => Default::default(), Qr::Account { .. } => Default::default(), Qr::WebrtcInstance { .. } => Default::default(), - Qr::Addr { contact_id } => contact_id.to_u32(), + Qr::Addr { contact_id, .. } => contact_id.to_u32(), Qr::Url { .. } => Default::default(), Qr::Text { .. } => Default::default(), Qr::WithdrawVerifyContact { contact_id, .. } => contact_id.to_u32(), diff --git a/src/qr.rs b/src/qr.rs index d3693fff8..43ae20ef4 100644 --- a/src/qr.rs +++ b/src/qr.rs @@ -61,6 +61,7 @@ pub enum Qr { }, Addr { contact_id: ContactId, + draft: Option, }, Url { url: String, @@ -451,15 +452,41 @@ pub async fn set_config_from_qr(context: &Context, qr: &str) -> Result<()> { async fn decode_mailto(context: &Context, qr: &str) -> Result { let payload = &qr[MAILTO_SCHEME.len()..]; - let addr = if let Some(query_index) = payload.find('?') { - &payload[..query_index] + let (addr, query) = if let Some(query_index) = payload.find('?') { + (&payload[..query_index], &payload[query_index+1..]) } else { - payload + (payload, "") + }; + + let param: BTreeMap<&str, &str> = query + .split('&') + .filter_map(|s| { + if let [key, value] = s.splitn(2, '=').collect::>()[..] { + Some((key, value)) + } else { + None + } + }) + .collect(); + + let subject = if let Some(subject) = param.get("subject") { + subject.to_string() + } else { + "".to_string() + }; + let draft = if let Some(body) = param.get("body") { + if subject.is_empty() { + body.to_string() + } else { + subject + "\n" + body + } + } else { + subject }; let addr = normalize_address(addr)?; let name = "".to_string(); - Qr::from_address(context, name, addr).await + Qr::from_address(context, name, addr, if draft.is_empty() { None } else { Some(draft) }).await } /// Extract address for the smtp scheme. @@ -477,7 +504,7 @@ async fn decode_smtp(context: &Context, qr: &str) -> Result { let addr = normalize_address(addr)?; let name = "".to_string(); - Qr::from_address(context, name, addr).await + Qr::from_address(context, name, addr, None).await } /// Extract address for the matmsg scheme. @@ -502,7 +529,7 @@ async fn decode_matmsg(context: &Context, qr: &str) -> Result { let addr = normalize_address(addr)?; let name = "".to_string(); - Qr::from_address(context, name, addr).await + Qr::from_address(context, name, addr, None).await } static VCARD_NAME_RE: Lazy = @@ -531,14 +558,14 @@ async fn decode_vcard(context: &Context, qr: &str) -> Result { bail!("Bad e-mail address"); }; - Qr::from_address(context, name, addr).await + Qr::from_address(context, name, addr, None).await } impl Qr { - pub async fn from_address(context: &Context, name: String, addr: String) -> Result { + pub async fn from_address(context: &Context, name: String, addr: String, draft: Option) -> Result { let (contact_id, _) = Contact::add_or_lookup(context, &name, &addr, Origin::UnhandledQrScan).await?; - Ok(Qr::Addr { contact_id }) + Ok(Qr::Addr { contact_id, draft }) } }