This commit is contained in:
2026-07-29 17:14:55 +07:00
parent 5945251a60
commit 480039c6c5
3 changed files with 23 additions and 44 deletions

View File

@@ -1,4 +1,4 @@
use std::collections::{BTreeMap, BTreeSet, HashSet}; use std::collections::{BTreeMap, HashSet};
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
pub use actions::*; pub use actions::*;
@@ -53,8 +53,8 @@ pub struct ChatPanel {
/// Message list state /// Message list state
list_state: ListState, list_state: ListState,
/// All messages /// All messages (sorted by created_at)
messages: BTreeSet<Message>, messages: Vec<Message>,
/// Mapping message ids to their rendered texts /// Mapping message ids to their rendered texts
rendered_texts_by_id: BTreeMap<EventId, RenderedText>, rendered_texts_by_id: BTreeMap<EventId, RenderedText>,
@@ -98,7 +98,7 @@ impl ChatPanel {
let reports_by_id = Arc::new(RwLock::new(BTreeMap::new())); let reports_by_id = Arc::new(RwLock::new(BTreeMap::new()));
// Define list of messages // Define list of messages
let messages = BTreeSet::default(); let messages = Vec::new();
let list_state = ListState::new(messages.len(), ListAlignment::Bottom, px(1024.)); let list_state = ListState::new(messages.len(), ListAlignment::Bottom, px(1024.));
// Get room id and name // Get room id and name
@@ -424,9 +424,10 @@ impl ChatPanel {
E: Into<Message>, E: Into<Message>,
{ {
let old_len = self.messages.len(); let old_len = self.messages.len();
let msg: Message = m.into();
// Extend the messages list with the new events if let Err(pos) = self.messages.binary_search(&msg) {
if self.messages.insert(m.into()) { self.messages.insert(pos, msg);
self.list_state.splice(old_len..old_len, 1); self.list_state.splice(old_len..old_len, 1);
if scroll { if scroll {
@@ -778,10 +779,8 @@ impl ChatPanel {
return true; return true;
} }
let mut iter = self.messages.iter(); if let Some(previous) = self.messages.get(ix - 1)
&& let Some(current) = self.messages.get(ix)
if let Some(previous) = iter.nth(ix - 1)
&& let Some(current) = iter.next()
{ {
if current.author != previous.author { if current.author != previous.author {
return true; return true;
@@ -804,7 +803,7 @@ impl ChatPanel {
window: &mut Window, window: &mut Window,
cx: &mut Context<Self>, cx: &mut Context<Self>,
) -> AnyElement { ) -> AnyElement {
if let Some(message) = self.messages.iter().nth(ix) { if let Some(message) = self.messages.get(ix) {
let persons = PersonRegistry::global(cx); let persons = PersonRegistry::global(cx);
let show_author = self.is_group_start(ix); let show_author = self.is_group_start(ix);
let text = self let text = self

View File

@@ -220,27 +220,6 @@ impl Workspace {
}), }),
); );
subscriptions.push(
// Observe the chat registry.
// Deferred via spawn to avoid potential re-entrancy if
// cx.observe fires synchronously during a chat.update.
cx.observe(&chat, move |this, chat, cx| {
let ids = this.panel_ids(cx);
let chat = chat.downgrade();
cx.spawn(async move |this, cx| -> anyhow::Result<()> {
if let Some(chat) = chat.upgrade() {
this.update(cx, |_this, cx| {
chat.update(cx, |chat, cx| {
chat.refresh_rooms(&ids, cx);
});
})?;
}
Ok(())
})
.detach();
}),
);
cx.defer_in(window, |this, window, cx| { cx.defer_in(window, |this, window, cx| {
let dock = this.dock.downgrade(); let dock = this.dock.downgrade();
let greeter = Arc::new(greeter::init(window, cx)); let greeter = Arc::new(greeter::init(window, cx));
@@ -277,17 +256,6 @@ impl Workspace {
} }
} }
/// Get all panel ids
fn panel_ids(&self, cx: &App) -> Vec<u64> {
self.dock
.read(cx)
.items
.panel_ids(cx)
.into_iter()
.filter_map(|panel| panel.parse::<u64>().ok())
.collect()
}
/// Handle command events /// Handle command events
fn on_command(&mut self, command: &Command, window: &mut Window, cx: &mut Context<Self>) { fn on_command(&mut self, command: &Command, window: &mut Window, cx: &mut Context<Self>) {
match command { match command {

View File

@@ -31,8 +31,20 @@ pub fn run() -> Result<(), JsValue> {
#[cfg(target_family = "wasm")] #[cfg(target_family = "wasm")]
gpui_platform::web_init(); gpui_platform::web_init();
#[cfg(not(target_family = "wasm"))]
let app = gpui_platform::application();
#[cfg(target_family = "wasm")]
let app = {
let app = gpui_platform::single_threaded_web();
gpui_platform::application().run(|cx| { // Temporary fix: intentionally leak the `Rc<AppCell>` to keep the application alive
struct WasmApplication(std::rc::Rc<AppCell>);
let wasm_app = unsafe { std::mem::transmute::<Application, WasmApplication>(app) };
std::mem::forget(wasm_app.0.clone());
unsafe { std::mem::transmute::<WasmApplication, Application>(wasm_app) }
};
app.run(|cx| {
// Open the root window // Open the root window
cx.open_window(WindowOptions::default(), |window, cx| { cx.open_window(WindowOptions::default(), |window, cx| {
// Initialize components // Initialize components