chore: fix duplicate reply (#169)

* prevent duplicate reply

* .
This commit is contained in:
reya
2025-09-27 08:02:16 +07:00
committed by GitHub
parent 98ce928f0c
commit 338a947b57
3 changed files with 53 additions and 53 deletions

View File

@@ -1,4 +1,4 @@
use std::collections::HashMap;
use std::collections::{HashMap, HashSet};
use common::display::{RenderedProfile, RenderedTimestamp};
use common::nip96::nip96_upload;
@@ -61,7 +61,7 @@ pub struct Chat {
// New Message
input: Entity<InputState>,
replies_to: Entity<Vec<EventId>>,
replies_to: Entity<HashSet<EventId>>,
// Media Attachment
attachments: Entity<Vec<Url>>,
@@ -79,7 +79,7 @@ pub struct Chat {
impl Chat {
pub fn new(room: Entity<Room>, window: &mut Window, cx: &mut Context<Self>) -> Self {
let attachments = cx.new(|_| vec![]);
let replies_to = cx.new(|_| vec![]);
let replies_to = cx.new(|_| HashSet::new());
let relays = cx.new(|_| {
let this: HashMap<PublicKey, Vec<RelayUrl>> = HashMap::new();
@@ -315,7 +315,7 @@ impl Chat {
let backup = AppSettings::get_backup_messages(cx);
// Get replies_to if it's present
let replies = self.replies_to.read(cx).clone();
let replies = self.replies_to.read(cx).iter().copied().collect_vec();
// Get the current room entity
let room = self.room.read(cx);
@@ -503,7 +503,7 @@ impl Chat {
fn reply_to(&mut self, id: &EventId, cx: &mut Context<Self>) {
if let Some(text) = self.message(id) {
self.replies_to.update(cx, |this, cx| {
this.push(text.id);
this.insert(text.id);
cx.notify();
});
}
@@ -511,16 +511,14 @@ impl Chat {
fn remove_reply(&mut self, id: &EventId, cx: &mut Context<Self>) {
self.replies_to.update(cx, |this, cx| {
if let Some(ix) = this.iter().position(|this| this == id) {
this.remove(ix);
cx.notify();
}
this.remove(id);
cx.notify();
});
}
fn remove_all_replies(&mut self, cx: &mut Context<Self>) {
self.replies_to.update(cx, |this, cx| {
*this = vec![];
this.clear();
cx.notify();
});
}

View File

@@ -21,20 +21,26 @@ impl Message {
pub fn system() -> Self {
Self::System(Timestamp::default())
}
fn timestamp(&self) -> &Timestamp {
match self {
Message::User(msg) => &msg.created_at,
Message::Warning(_, ts) => ts,
Message::System(ts) => ts,
}
}
}
impl Ord for Message {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
match (self, other) {
(Message::User(a), Message::User(b)) => a.cmp(b),
(Message::System(a), Message::System(b)) => a.cmp(b),
(Message::User(a), Message::System(b)) => a.created_at.cmp(b),
(Message::System(a), Message::User(b)) => a.cmp(&b.created_at),
(Message::Warning(_, a), Message::Warning(_, b)) => a.cmp(b),
(Message::Warning(_, a), Message::User(b)) => a.cmp(&b.created_at),
(Message::User(a), Message::Warning(_, b)) => a.created_at.cmp(b),
(Message::Warning(_, a), Message::System(b)) => a.cmp(b),
(Message::System(a), Message::Warning(_, b)) => a.cmp(b),
// System always comes first
(Message::System(_), Message::System(_)) => self.timestamp().cmp(other.timestamp()),
(Message::System(_), _) => std::cmp::Ordering::Less,
(_, Message::System(_)) => std::cmp::Ordering::Greater,
// For non-system messages, compare by timestamp
_ => self.timestamp().cmp(other.timestamp()),
}
}
}
@@ -151,18 +157,14 @@ fn extract_reply_ids(inner: &Tags) -> Vec<EventId> {
let mut replies_to = vec![];
for tag in inner.filter(TagKind::e()) {
if let Some(content) = tag.content() {
if let Ok(id) = EventId::from_hex(content) {
replies_to.push(id);
}
if let Some(id) = tag.content().and_then(|id| EventId::parse(id).ok()) {
replies_to.push(id);
}
}
for tag in inner.filter(TagKind::q()) {
if let Some(content) = tag.content() {
if let Ok(id) = EventId::from_hex(content) {
replies_to.push(id);
}
if let Some(id) = tag.content().and_then(|id| EventId::parse(id).ok()) {
replies_to.push(id);
}
}