@@ -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();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user