.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
|
||||
use anyhow::Result;
|
||||
@@ -502,32 +502,7 @@ impl CommunityPanel {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut index: HashMap<EventId, usize> = self
|
||||
.rows
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(ix, message)| (message.id, ix))
|
||||
.collect();
|
||||
|
||||
let mut added = Vec::new();
|
||||
|
||||
for message in messages {
|
||||
match index.get(&message.id).copied() {
|
||||
Some(ix) => self.rows[ix] = message,
|
||||
None => {
|
||||
index.insert(message.id, self.rows.len() + added.len());
|
||||
added.push(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !added.is_empty() {
|
||||
let at = self.item_count();
|
||||
let count = added.len();
|
||||
self.rows.extend(added);
|
||||
self.list_state.splice(at..at, count);
|
||||
}
|
||||
|
||||
self.merge(messages);
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
@@ -537,22 +512,42 @@ impl CommunityPanel {
|
||||
return;
|
||||
}
|
||||
|
||||
let known: HashSet<EventId> = self.rows.iter().map(|message| message.id).collect();
|
||||
let added: Vec<ChatMessage> = timeline
|
||||
.messages
|
||||
.into_iter()
|
||||
.filter(|message| !known.contains(&message.id))
|
||||
self.has_more = timeline.has_more;
|
||||
self.merge(timeline.messages);
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
/// Fold read rows into what is on screen, keeping the list in time order.
|
||||
fn merge(&mut self, messages: Vec<ChatMessage>) {
|
||||
let mut shown: HashMap<EventId, usize> = self
|
||||
.rows
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(ix, message)| (message.id, ix))
|
||||
.collect();
|
||||
|
||||
self.has_more = timeline.has_more;
|
||||
let mut fresh = Vec::new();
|
||||
|
||||
if !added.is_empty() {
|
||||
let count = added.len();
|
||||
self.rows.splice(0..0, added);
|
||||
self.list_state.splice(1..1, count);
|
||||
for message in messages {
|
||||
match shown.get(&message.id).copied() {
|
||||
Some(ix) => self.rows[ix] = message,
|
||||
None => fresh.push(message),
|
||||
}
|
||||
}
|
||||
|
||||
cx.notify();
|
||||
for message in fresh {
|
||||
if shown.contains_key(&message.id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let at = self
|
||||
.rows
|
||||
.partition_point(|row| (row.at_ms, row.id) <= (message.at_ms, message.id));
|
||||
|
||||
shown.insert(message.id, at);
|
||||
self.rows.insert(at, message);
|
||||
self.list_state.splice(at + 1..at + 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
fn send(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
@@ -567,9 +562,6 @@ impl CommunityPanel {
|
||||
return;
|
||||
};
|
||||
|
||||
// A rotation that excluded us moved the write plane out of reach, and the
|
||||
// community refuses to seal a message nobody could read. The notice above
|
||||
// the list is what says why.
|
||||
if let Some(notice) = self.notice(cx).filter(|notice| !notice.writable()) {
|
||||
window.push_notification(Notification::error(notice.to_string()).autohide(false), cx);
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user