mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-05-07 07:27:45 -04:00
ui: Deduplicate reaction senders in timeline
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -2944,6 +2944,7 @@ dependencies = [
|
||||
"futures-util",
|
||||
"imbl",
|
||||
"indexmap",
|
||||
"itertools",
|
||||
"matrix-sdk",
|
||||
"matrix-sdk-base",
|
||||
"matrix-sdk-crypto",
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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" }
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ mod edit;
|
||||
#[cfg(feature = "e2e-encryption")]
|
||||
mod encryption;
|
||||
mod invalid;
|
||||
mod reaction_group;
|
||||
mod read_receipts;
|
||||
mod redaction;
|
||||
mod virt;
|
||||
|
||||
41
crates/matrix-sdk-ui/src/timeline/tests/reaction_group.rs
Normal file
41
crates/matrix-sdk-ui/src/timeline/tests/reaction_group.rs
Normal 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());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user