diff --git a/src/imex/transfer.rs b/src/imex/transfer.rs index b0741285c..67808b511 100644 --- a/src/imex/transfer.rs +++ b/src/imex/transfer.rs @@ -94,12 +94,7 @@ impl BackupProvider { biased; res = Self::prepare_inner(context, dir) => { match res { - Ok(slf) => { - // TODO: maybe this is the wrong place to log this - // TODO: Also needs to log progress somehow. - info!(context, "Waiting for remote to connect"); - Ok(slf) - }, + Ok(slf) => Ok(slf), Err(err) => { error!(context, "Failed to set up second device setup: {:#}", err); Err(err) @@ -153,6 +148,7 @@ impl BackupProvider { context.emit_event(SendProgress::CollectionCreated.into()); let provider = Provider::builder(db).auth_token(token).spawn()?; context.emit_event(SendProgress::ProviderListening.into()); + info!(context, "Waiting for remote to connect"); let ticket = provider.ticket(hash); Ok((provider, ticket)) } diff --git a/src/qr.rs b/src/qr.rs index 3d4bc5a6f..a5567d92b 100644 --- a/src/qr.rs +++ b/src/qr.rs @@ -167,9 +167,9 @@ pub async fn check_qr(context: &Context, qr: &str) -> Result { /// /// TODO: Refactor this so all variants have a correct [`Display`] and transform `check_qr` /// into [`FromStr`]. -pub fn format_backup(qr: Qr) -> Result { +pub fn format_backup(qr: &Qr) -> Result { match qr { - Qr::Backup { ticket } => Ok(format!("{DCBACKUP_SCHEME}{ticket}")), + Qr::Backup { ref ticket } => Ok(format!("{DCBACKUP_SCHEME}{ticket}")), _ => Err(anyhow!("Not a backup QR code")), } } diff --git a/src/qr_code_generator.rs b/src/qr_code_generator.rs index 7f43cb2c2..c6f384cf5 100644 --- a/src/qr_code_generator.rs +++ b/src/qr_code_generator.rs @@ -12,7 +12,8 @@ use crate::{ contact::{Contact, ContactId}, context::Context, qr::{Qr, DCBACKUP_SCHEME}, - securejoin, stock_str, + securejoin, + stock_str::{self, backup_transfer_qr}, }; pub async fn get_securejoin_qr_svg(context: &Context, chat_id: Option) -> Result { @@ -61,10 +62,10 @@ pub async fn generate_backup_qr(context: &Context, qr: Qr) -> Result { }; let content = format!("{DCBACKUP_SCHEME}{ticket}"); let (avatar, displayname, _addr, color) = self_info(context).await?; - let description = "Scan to setup second device"; // TODO: translation! + let description = backup_transfer_qr(context).await?; inner_generate_secure_join_qr_code( - description, + &description, &content, &color, avatar, @@ -297,6 +298,7 @@ mod tests { use testdir::testdir; use crate::imex::BackupProvider; + use crate::qr::format_backup; use crate::test_utils::TestContextManager; use super::*; @@ -322,6 +324,7 @@ mod tests { let provider = BackupProvider::prepare(&ctx, &dir).await.unwrap(); let qr = provider.qr(); + println!("{}", format_backup(&qr).unwrap()); let rendered = generate_backup_qr(&ctx, qr).await.unwrap(); tokio::fs::write(dir.join("qr.svg"), &rendered) .await diff --git a/src/stock_str.rs b/src/stock_str.rs index f91b5a783..8b3b6162f 100644 --- a/src/stock_str.rs +++ b/src/stock_str.rs @@ -404,6 +404,9 @@ pub enum StockMessage { #[strum(props(fallback = "Chat protection disabled by %1$s."))] ProtectionDisabledBy = 161, + + #[strum(props(fallback = "Scan to set up second device for %1$s"))] + BackupTransferQr = 162, } impl StockMessage { @@ -740,14 +743,14 @@ pub(crate) async fn setup_contact_qr_description( display_name: &str, addr: &str, ) -> String { - let name = &if display_name == addr { + let name = if display_name == addr { addr.to_owned() } else { format!("{display_name} ({addr})") }; translated(context, StockMessage::SetupContactQRDescription) .await - .replace1(name) + .replace1(&name) } /// Stock string: `Scan to join %1$s`. @@ -1239,6 +1242,18 @@ pub(crate) async fn aeap_explanation_and_link( .replace2(new_addr) } +pub(crate) async fn backup_transfer_qr(context: &Context) -> Result { + let contact = Contact::get_by_id(context, ContactId::SELF).await?; + let addr = contact.get_addr(); + let full_name = match context.get_config(Config::Displayname).await? { + Some(name) if name != addr => format!("{name} ({addr})"), + _ => addr.to_string(), + }; + Ok(translated(context, StockMessage::BackupTransferQr) + .await + .replace1(&full_name)) +} + impl Context { /// Set the stock string for the [StockMessage]. ///