ui: Deduplicate reaction senders in timeline

This commit is contained in:
jonnyandrew
2023-06-22 12:42:49 +00:00
committed by GitHub
parent 3fd55c0ab1
commit 7fd5068faa
7 changed files with 49 additions and 3 deletions

1
Cargo.lock generated
View File

@@ -2944,6 +2944,7 @@ dependencies = [
"futures-util",
"imbl",
"indexmap",
"itertools",
"matrix-sdk",
"matrix-sdk-base",
"matrix-sdk-crypto",

View File

@@ -35,6 +35,7 @@ futures-core = "0.3.28"
futures-executor = "0.3.21"
futures-util = { version = "0.3.26", default-features = false, features = ["alloc"] }
http = "0.2.6"
itertools = "0.10.5"
ruma = { git = "https://github.com/ruma/ruma", rev = "cf32036df4c9daca736dcd7f0d9d65debcf9897f", features = ["client-api-c", "compat-user-id"] }
ruma-common = { git = "https://github.com/ruma/ruma", rev = "cf32036df4c9daca736dcd7f0d9d65debcf9897f" }
once_cell = "1.16.0"

View File

@@ -44,7 +44,7 @@ futures-util = { workspace = true }
hkdf = { version = "0.12.3", optional = true }
hmac = "0.12.1"
http = { workspace = true, optional = true } # feature = testing only
itertools = "0.10.5"
itertools = { workspace = true }
matrix-sdk-qrcode = { version = "0.4.0", path = "../matrix-sdk-qrcode", optional = true }
matrix-sdk-common = { version = "0.6.0", path = "../matrix-sdk-common" }
pbkdf2 = { version = "0.11.0", default-features = false }

View File

@@ -30,6 +30,7 @@ futures-core = { workspace = true }
futures-util = { workspace = true }
imbl = { version = "2.0.0", features = ["serde"] }
indexmap = "1.9.1"
itertools = { workspace = true }
matrix-sdk = { version = "0.6.2", path = "../matrix-sdk", default-features = false }
matrix-sdk-base = { version = "0.6.1", path = "../matrix-sdk-base" }
matrix-sdk-crypto = { version = "0.6.0", path = "../matrix-sdk-crypto" }

View File

@@ -16,6 +16,7 @@ use std::{fmt, ops::Deref, sync::Arc};
use imbl::{vector, Vector};
use indexmap::IndexMap;
use itertools::Itertools;
use matrix_sdk::{deserialized_responses::TimelineEvent, Result};
use ruma::{
assign,
@@ -398,9 +399,9 @@ type ReactionGroupInner = IndexMap<(Option<OwnedTransactionId>, Option<OwnedEven
pub struct ReactionGroup(pub(in crate::timeline) ReactionGroupInner);
impl ReactionGroup {
/// The senders of the reactions in this group.
/// The (deduplicated) senders of the reactions in this group.
pub fn senders(&self) -> impl Iterator<Item = &UserId> {
self.values().map(AsRef::as_ref)
self.values().unique().map(AsRef::as_ref)
}
}

View File

@@ -53,6 +53,7 @@ mod edit;
#[cfg(feature = "e2e-encryption")]
mod encryption;
mod invalid;
mod reaction_group;
mod read_receipts;
mod redaction;
mod virt;

View File

@@ -0,0 +1,41 @@
// Copyright 2023 The Matrix.org Foundation C.I.C.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use ruma::{server_name, EventId, UserId};
use crate::timeline::{
tests::{ALICE, BOB},
ReactionGroup,
};
/// The Matrix spec does not allow duplicate annotations to be created but it
/// is still possible for duplicates to be received over federation. And in
/// that case, clients are expected to treat duplicates as a single annotation.
#[test]
fn senders_are_deduplicated() {
let group = {
let mut group = ReactionGroup::default();
insert(&mut group, &ALICE, 3);
insert(&mut group, &BOB, 2);
group
};
assert_eq!(group.senders().collect::<Vec<_>>(), vec![&ALICE.to_owned(), &BOB.to_owned()]);
}
fn insert(group: &mut ReactionGroup, sender: &UserId, count: u64) {
for _ in 0..count {
let event_id = EventId::new(server_name!("dummy.server"));
group.0.insert((None, Some(event_id)), sender.to_owned());
}
}