mirror of
https://github.com/chatmail/core.git
synced 2026-05-04 22:06:29 +03:00
feat: Show broadcast channels in their own, proper "Channel" chat (#6901)
Part of #6884 ---- - [x] Add new chat type `InBroadcastChannel` and `OutBroadcastChannel` for incoming / outgoing channels, where the former is similar to a `Mailinglist` and the latter is similar to a `Broadcast` (which is removed) - Consideration for naming: `InChannel`/`OutChannel` (without "broadcast") would be shorter, but less greppable because we already have a lot of occurences of `channel` in the code. Consistently calling them `BcChannel`/`bc_channel` in the code would be both short and greppable, but a bit arcane when reading it at first. Opinions are welcome; if I hear none, I'll keep with `BroadcastChannel`. - [x] api: Add create_broadcast_channel(), deprecate create_broadcast_list() (or `create_channel()` / `create_bc_channel()` if we decide to switch) - Adjust code comments to match the new behavior. - [x] Ask Desktop developers what they use `is_broadcast` field for, and whether it should be true for both outgoing & incoming channels (or look it up myself) - I added `is_out_broadcast_channel`, and deprecated `is_broadcast`, for now - [x] When the user changes the broadcast channel name, immediately show this change on receiving devices - [x] Allow to change brodacast channel avatar, and immediately apply it on the receiving device - [x] Make it possible to block InBroadcastChannel - [x] Make it possible to set the avatar of an OutgoingChannel, and apply it on the receiving side - [x] DECIDE whether we still want to use the broadcast icon as the default icon or whether we want to use the letter-in-a-circle - We decided to use the letter-in-a-circle for now, because it's easier to implement, and I need to stay in the time plan - [x] chat.rs: Return an error if the user tries to modify a `InBroadcastChannel` - [x] Add automated regression tests - [x] Grep for `broadcast` and see whether there is any other work I need to do - [x] Bug: Don't show `~` in front of the sender's same in broadcast lists ---- Note that I removed the following guard: ```rust if !new_chat_contacts.contains(&ContactId::SELF) { warn!( context, "Received group avatar update for group chat {} we are not a member of.", chat.id ); } else if !new_chat_contacts.contains(&from_id) { warn!( context, "Contact {from_id} attempts to modify group chat {} avatar without being a member.", chat.id, ); } else [...] ``` i.e. with this change, non-members will be able to modify the avatar. Things were slightly easier this way, and I think that this is in line with non-members being able to modify the group name and memberlist (they need to know the Group-Chat-Id, anyway), but I can also change it back.
This commit is contained in:
@@ -1179,7 +1179,7 @@ impl Contact {
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
/// Adds blocked mailinglists as contacts
|
||||
/// Adds blocked mailinglists and broadcast channels as pseudo-contacts
|
||||
/// to allow unblocking them as if they are contacts
|
||||
/// (this way, only one unblock-ffi is needed and only one set of ui-functions,
|
||||
/// from the users perspective,
|
||||
@@ -1188,15 +1188,20 @@ impl Contact {
|
||||
context
|
||||
.sql
|
||||
.transaction(move |transaction| {
|
||||
let mut stmt = transaction
|
||||
.prepare("SELECT name, grpid FROM chats WHERE type=? AND blocked=?")?;
|
||||
let rows = stmt.query_map((Chattype::Mailinglist, Blocked::Yes), |row| {
|
||||
let name: String = row.get(0)?;
|
||||
let grpid: String = row.get(1)?;
|
||||
Ok((name, grpid))
|
||||
})?;
|
||||
let mut stmt = transaction.prepare(
|
||||
"SELECT name, grpid, type FROM chats WHERE (type=? OR type=?) AND blocked=?",
|
||||
)?;
|
||||
let rows = stmt.query_map(
|
||||
(Chattype::Mailinglist, Chattype::InBroadcast, Blocked::Yes),
|
||||
|row| {
|
||||
let name: String = row.get(0)?;
|
||||
let grpid: String = row.get(1)?;
|
||||
let typ: Chattype = row.get(2)?;
|
||||
Ok((name, grpid, typ))
|
||||
},
|
||||
)?;
|
||||
let blocked_mailinglists = rows.collect::<std::result::Result<Vec<_>, _>>()?;
|
||||
for (name, grpid) in blocked_mailinglists {
|
||||
for (name, grpid, typ) in blocked_mailinglists {
|
||||
let count = transaction.query_row(
|
||||
"SELECT COUNT(id) FROM contacts WHERE addr=?",
|
||||
[&grpid],
|
||||
@@ -1209,10 +1214,17 @@ impl Contact {
|
||||
transaction.execute("INSERT INTO contacts (addr) VALUES (?)", [&grpid])?;
|
||||
}
|
||||
|
||||
let fingerprint = if typ == Chattype::InBroadcast {
|
||||
// Set some fingerprint so that is_pgp_contact() returns true,
|
||||
// and the contact isn't marked with a letter icon.
|
||||
"Blocked_broadcast"
|
||||
} else {
|
||||
""
|
||||
};
|
||||
// Always do an update in case the blocking is reset or name is changed.
|
||||
transaction.execute(
|
||||
"UPDATE contacts SET name=?, origin=?, blocked=1 WHERE addr=?",
|
||||
(&name, Origin::MailinglistAddress, &grpid),
|
||||
"UPDATE contacts SET name=?, origin=?, blocked=1, fingerprint=? WHERE addr=?",
|
||||
(&name, Origin::MailinglistAddress, fingerprint, &grpid),
|
||||
)?;
|
||||
}
|
||||
Ok(())
|
||||
|
||||
Reference in New Issue
Block a user