From 2f90b55309daaf553fd5facb53466152cb285e32 Mon Sep 17 00:00:00 2001 From: Hocuri Date: Thu, 20 Nov 2025 22:13:04 +0100 Subject: [PATCH] feat: Stock string for joining a channel (#7480) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a stock string `%1$s invited you to join this channel.\n\nWaiting for the device of %2$s to reply…`, which is shown when a user starts to join a channel. I did _not_ add an equivalent to `%1$s replied, waiting for being added to the group…`, which is shown when vg-auth-required was received. I don't think that this would add any information that's interesting to the user, other than 'something is happening, hang on'. And the more text on the screen, the less likely that anyone reads it. But if others think differently, we can also add it. With this PR, joining a channel looks like this: ``` Msg#2003: info (Contact#Contact#Info): Messages are end-to-end encrypted. [NOTICED][INFO] Msg#2004: info (Contact#Contact#Info): Alice invited you to join this channel. Waiting for the device of Alice to reply… [NOTICED][INFO] Msg#2007🔒: (Contact#Contact#2001): You joined the channel. [FRESH][INFO] ``` --- deltachat-ffi/deltachat.h | 12 +++++++++++- deltachat-rpc-client/tests/test_securejoin.py | 2 +- deltachat-rpc-client/tests/test_something.py | 2 +- src/securejoin/bob.rs | 5 ++--- src/stock_str.rs | 19 +++++++++++++++++++ .../golden/test_broadcast_joining_golden_bob | 4 +++- test-data/golden/test_sync_broadcast_bob | 4 +++- 7 files changed, 40 insertions(+), 8 deletions(-) diff --git a/deltachat-ffi/deltachat.h b/deltachat-ffi/deltachat.h index dd887a306..117cb6ef8 100644 --- a/deltachat-ffi/deltachat.h +++ b/deltachat-ffi/deltachat.h @@ -7756,7 +7756,17 @@ void dc_event_unref(dc_event_t* event); /// Subtitle for channel join qrcode svg image generated by the core. /// /// `%1$s` will be replaced with the channel name. -#define DC_STR_SECURE_JOIN_CHANNEL_QR_DESC 201 +#define DC_STR_SECURE_JOIN_CHANNEL_QR_DESC 201 + +/// "You joined the channel." +#define DC_STR_MSG_YOU_JOINED_CHANNEL 202 + +/// "%1$s invited you to join this channel. Waiting for the device of %2$s to reply…" +/// +/// Added as an info-message directly after scanning a QR code for joining a broadcast channel. +/// +/// `%1$s` and `%2$s` will both be replaced by the name of the inviter. +#define DC_STR_SECURE_JOIN_CHANNEL_STARTED 203 /// "Proxy Enabled" /// diff --git a/deltachat-rpc-client/tests/test_securejoin.py b/deltachat-rpc-client/tests/test_securejoin.py index e2d6e1cef..ab1c6f746 100644 --- a/deltachat-rpc-client/tests/test_securejoin.py +++ b/deltachat-rpc-client/tests/test_securejoin.py @@ -164,7 +164,7 @@ def test_qr_securejoin_broadcast(acfactory, all_devices_online): if please_wait_info_msg: first_msg = chat_msgs.pop(0).get_snapshot() - assert first_msg.text == "Establishing connection, please wait…" + assert "invited you to join this channel" in first_msg.text assert first_msg.is_info member_added_msg = chat_msgs.pop(0).get_snapshot() diff --git a/deltachat-rpc-client/tests/test_something.py b/deltachat-rpc-client/tests/test_something.py index 6db131f6e..2edc9f80f 100644 --- a/deltachat-rpc-client/tests/test_something.py +++ b/deltachat-rpc-client/tests/test_something.py @@ -874,7 +874,7 @@ def test_leave_broadcast(acfactory, all_devices_online): if please_wait_info_msg: first_msg = chat_msgs.pop(0).get_snapshot() - assert first_msg.text == "Establishing connection, please wait…" + assert "invited you to join this channel" in first_msg.text assert first_msg.is_info member_added_msg = chat_msgs.pop(0).get_snapshot() diff --git a/src/securejoin/bob.rs b/src/securejoin/bob.rs index 8ed5aa97d..7318d1e7a 100644 --- a/src/securejoin/bob.rs +++ b/src/securejoin/bob.rs @@ -144,10 +144,9 @@ pub(super) async fn start_protocol(context: &Context, invite: QrInvite) -> Resul } // If we were not in the broadcast channel before, show a 'please wait' info message. - // Since we don't have any specific stock string for this, - // use the generic `Establishing connection, please wait…` if !is_contact_in_chat(context, joining_chat_id, ContactId::SELF).await? { - let msg = stock_str::securejoin_wait(context).await; + let msg = + stock_str::secure_join_broadcast_started(context, invite.contact_id()).await; chat::add_info_msg(context, joining_chat_id, &msg).await?; } Ok(joining_chat_id) diff --git a/src/stock_str.rs b/src/stock_str.rs index 6d073869a..e4922a735 100644 --- a/src/stock_str.rs +++ b/src/stock_str.rs @@ -429,6 +429,10 @@ https://delta.chat/donate"))] #[strum(props(fallback = "You joined the channel."))] MsgYouJoinedBroadcast = 202, + #[strum(props(fallback = "%1$s invited you to join this channel.\n\n\ + Waiting for the device of %2$s to reply…"))] + SecureJoinBroadcastStarted = 203, + #[strum(props( fallback = "The attachment contains anonymous usage statistics, which helps us improve Delta Chat. Thank you!" ))] @@ -737,6 +741,21 @@ pub(crate) async fn msg_you_joined_broadcast(context: &Context) -> String { translated(context, StockMessage::MsgYouJoinedBroadcast).await } +/// Stock string: `%1$s invited you to join this channel. Waiting for the device of %2$s to reply…`. +pub(crate) async fn secure_join_broadcast_started( + context: &Context, + inviter_contact_id: ContactId, +) -> String { + if let Ok(contact) = Contact::get_by_id(context, inviter_contact_id).await { + translated(context, StockMessage::SecureJoinBroadcastStarted) + .await + .replace1(contact.get_display_name()) + .replace2(contact.get_display_name()) + } else { + format!("secure_join_started: unknown contact {inviter_contact_id}") + } +} + /// Stock string: `You reacted %1$s to "%2$s"` or `%1$s reacted %2$s to "%3$s"`. pub(crate) async fn msg_reacted( context: &Context, diff --git a/test-data/golden/test_broadcast_joining_golden_bob b/test-data/golden/test_broadcast_joining_golden_bob index 93ef5ab6a..0bc27cffe 100644 --- a/test-data/golden/test_broadcast_joining_golden_bob +++ b/test-data/golden/test_broadcast_joining_golden_bob @@ -1,6 +1,8 @@ InBroadcast#Chat#2002: My Channel [2 member(s)] Icon: e9b6c7a78aa2e4f415644f55a553e73.png -------------------------------------------------------------------------------- Msg#2003: info (Contact#Contact#Info): Messages are end-to-end encrypted. [NOTICED][INFO] -Msg#2004: info (Contact#Contact#Info): Establishing connection, please wait… [NOTICED][INFO] +Msg#2004: info (Contact#Contact#Info): Alice invited you to join this channel. + +Waiting for the device of Alice to reply… [NOTICED][INFO] Msg#2007🔒: (Contact#Contact#2001): You joined the channel. [FRESH][INFO] -------------------------------------------------------------------------------- diff --git a/test-data/golden/test_sync_broadcast_bob b/test-data/golden/test_sync_broadcast_bob index fa8c862ee..c62396083 100644 --- a/test-data/golden/test_sync_broadcast_bob +++ b/test-data/golden/test_sync_broadcast_bob @@ -1,7 +1,9 @@ InBroadcast#Chat#2002: Channel [1 member(s)] -------------------------------------------------------------------------------- Msg#2003: info (Contact#Contact#Info): Messages are end-to-end encrypted. [NOTICED][INFO] -Msg#2004: info (Contact#Contact#Info): Establishing connection, please wait… [NOTICED][INFO] +Msg#2004: info (Contact#Contact#Info): alice@example.org invited you to join this channel. + +Waiting for the device of alice@example.org to reply… [NOTICED][INFO] Msg#2008🔒: (Contact#Contact#2001): You joined the channel. [FRESH][INFO] Msg#2010🔒: (Contact#Contact#2001): hi [FRESH] Msg#2011🔒: (Contact#Contact#2001): Member Me removed by alice@example.org. [FRESH][INFO]