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

52
Cargo.lock generated
View File

@@ -224,9 +224,9 @@ dependencies = [
[[package]] [[package]]
name = "async-compression" name = "async-compression"
version = "0.4.31" version = "0.4.32"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9611ec0b6acea03372540509035db2f7f1e9f04da5d27728436fa994033c00a0" checksum = "5a89bce6054c720275ac2432fbba080a66a2106a44a1b804553930ca6909f4e0"
dependencies = [ dependencies = [
"compression-codecs", "compression-codecs",
"compression-core", "compression-core",
@@ -482,9 +482,9 @@ dependencies = [
[[package]] [[package]]
name = "aws-lc-sys" name = "aws-lc-sys"
version = "0.32.0" version = "0.32.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee74396bee4da70c2e27cf94762714c911725efe69d9e2672f998512a67a4ce4" checksum = "1ba2e2516bdf37af57fc6ff047855f54abad0066e5c4fdaaeb76dabb2e05bcf5"
dependencies = [ dependencies = [
"bindgen 0.72.1", "bindgen 0.72.1",
"cc", "cc",
@@ -910,9 +910,9 @@ dependencies = [
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.2.38" version = "1.2.39"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80f41ae168f955c12fb8960b057d70d0ca153fb83182b57d86380443527be7e9" checksum = "e1354349954c6fc9cb0deab020f27f783cf0b604e8bb754dc4658ecf0d29c35f"
dependencies = [ dependencies = [
"find-msvc-tools", "find-msvc-tools",
"jobserver", "jobserver",
@@ -1129,7 +1129,7 @@ dependencies = [
[[package]] [[package]]
name = "collections" name = "collections"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#0891a7142db60b9c78247d9034b292c9d9b96dca" source = "git+https://github.com/zed-industries/zed#ead38fd1bec5aa5db2ed8462cb804fe525963bca"
dependencies = [ dependencies = [
"indexmap", "indexmap",
"rustc-hash 2.1.1", "rustc-hash 2.1.1",
@@ -1185,9 +1185,9 @@ dependencies = [
[[package]] [[package]]
name = "compression-codecs" name = "compression-codecs"
version = "0.4.30" version = "0.4.31"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "485abf41ac0c8047c07c87c72c8fb3eb5197f6e9d7ded615dfd1a00ae00a0f64" checksum = "ef8a506ec4b81c460798f572caead636d57d3d7e940f998160f52bd254bf2d23"
dependencies = [ dependencies = [
"compression-core", "compression-core",
"deflate64", "deflate64",
@@ -1570,7 +1570,7 @@ dependencies = [
[[package]] [[package]]
name = "derive_refineable" name = "derive_refineable"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#0891a7142db60b9c78247d9034b292c9d9b96dca" source = "git+https://github.com/zed-industries/zed#ead38fd1bec5aa5db2ed8462cb804fe525963bca"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -2506,7 +2506,7 @@ dependencies = [
[[package]] [[package]]
name = "gpui" name = "gpui"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#0891a7142db60b9c78247d9034b292c9d9b96dca" source = "git+https://github.com/zed-industries/zed#ead38fd1bec5aa5db2ed8462cb804fe525963bca"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"as-raw-xcb-connection", "as-raw-xcb-connection",
@@ -2600,7 +2600,7 @@ dependencies = [
[[package]] [[package]]
name = "gpui_macros" name = "gpui_macros"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#0891a7142db60b9c78247d9034b292c9d9b96dca" source = "git+https://github.com/zed-industries/zed#ead38fd1bec5aa5db2ed8462cb804fe525963bca"
dependencies = [ dependencies = [
"heck 0.5.0", "heck 0.5.0",
"proc-macro2", "proc-macro2",
@@ -2612,7 +2612,7 @@ dependencies = [
[[package]] [[package]]
name = "gpui_tokio" name = "gpui_tokio"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#0891a7142db60b9c78247d9034b292c9d9b96dca" source = "git+https://github.com/zed-industries/zed#ead38fd1bec5aa5db2ed8462cb804fe525963bca"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"gpui", "gpui",
@@ -2832,7 +2832,7 @@ dependencies = [
[[package]] [[package]]
name = "http_client" name = "http_client"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#0891a7142db60b9c78247d9034b292c9d9b96dca" source = "git+https://github.com/zed-industries/zed#ead38fd1bec5aa5db2ed8462cb804fe525963bca"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bytes", "bytes",
@@ -2852,7 +2852,7 @@ dependencies = [
[[package]] [[package]]
name = "http_client_tls" name = "http_client_tls"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#0891a7142db60b9c78247d9034b292c9d9b96dca" source = "git+https://github.com/zed-industries/zed#ead38fd1bec5aa5db2ed8462cb804fe525963bca"
dependencies = [ dependencies = [
"rustls", "rustls",
"rustls-platform-verifier", "rustls-platform-verifier",
@@ -3657,7 +3657,7 @@ dependencies = [
[[package]] [[package]]
name = "media" name = "media"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#0891a7142db60b9c78247d9034b292c9d9b96dca" source = "git+https://github.com/zed-industries/zed#ead38fd1bec5aa5db2ed8462cb804fe525963bca"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bindgen 0.71.1", "bindgen 0.71.1",
@@ -4500,7 +4500,7 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
[[package]] [[package]]
name = "perf" name = "perf"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#0891a7142db60b9c78247d9034b292c9d9b96dca" source = "git+https://github.com/zed-industries/zed#ead38fd1bec5aa5db2ed8462cb804fe525963bca"
dependencies = [ dependencies = [
"collections", "collections",
"serde", "serde",
@@ -5108,7 +5108,7 @@ dependencies = [
[[package]] [[package]]
name = "refineable" name = "refineable"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#0891a7142db60b9c78247d9034b292c9d9b96dca" source = "git+https://github.com/zed-industries/zed#ead38fd1bec5aa5db2ed8462cb804fe525963bca"
dependencies = [ dependencies = [
"derive_refineable", "derive_refineable",
"workspace-hack", "workspace-hack",
@@ -5262,7 +5262,7 @@ dependencies = [
[[package]] [[package]]
name = "reqwest_client" name = "reqwest_client"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#0891a7142db60b9c78247d9034b292c9d9b96dca" source = "git+https://github.com/zed-industries/zed#ead38fd1bec5aa5db2ed8462cb804fe525963bca"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bytes", "bytes",
@@ -5317,7 +5317,7 @@ dependencies = [
[[package]] [[package]]
name = "rope" name = "rope"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#0891a7142db60b9c78247d9034b292c9d9b96dca" source = "git+https://github.com/zed-industries/zed#ead38fd1bec5aa5db2ed8462cb804fe525963bca"
dependencies = [ dependencies = [
"arrayvec", "arrayvec",
"log", "log",
@@ -5812,7 +5812,7 @@ checksum = "0f7d95a54511e0c7be3f51e8867aa8cf35148d7b9445d44de2f943e2b206e749"
[[package]] [[package]]
name = "semantic_version" name = "semantic_version"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#0891a7142db60b9c78247d9034b292c9d9b96dca" source = "git+https://github.com/zed-industries/zed#ead38fd1bec5aa5db2ed8462cb804fe525963bca"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"serde", "serde",
@@ -6264,7 +6264,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]] [[package]]
name = "sum_tree" name = "sum_tree"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#0891a7142db60b9c78247d9034b292c9d9b96dca" source = "git+https://github.com/zed-industries/zed#ead38fd1bec5aa5db2ed8462cb804fe525963bca"
dependencies = [ dependencies = [
"arrayvec", "arrayvec",
"log", "log",
@@ -6788,9 +6788,9 @@ dependencies = [
[[package]] [[package]]
name = "tokio-rustls" name = "tokio-rustls"
version = "0.26.3" version = "0.26.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05f63835928ca123f1bef57abbcd23bb2ba0ac9ae1235f1e65bda0d06e7786bd" checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61"
dependencies = [ dependencies = [
"rustls", "rustls",
"tokio", "tokio",
@@ -7310,7 +7310,7 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
[[package]] [[package]]
name = "util" name = "util"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#0891a7142db60b9c78247d9034b292c9d9b96dca" source = "git+https://github.com/zed-industries/zed#ead38fd1bec5aa5db2ed8462cb804fe525963bca"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-fs", "async-fs",
@@ -7345,7 +7345,7 @@ dependencies = [
[[package]] [[package]]
name = "util_macros" name = "util_macros"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#0891a7142db60b9c78247d9034b292c9d9b96dca" source = "git+https://github.com/zed-industries/zed#ead38fd1bec5aa5db2ed8462cb804fe525963bca"
dependencies = [ dependencies = [
"perf", "perf",
"quote", "quote",

View File

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

View File

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