chore: fix crash when failing to parse message (#202)

* clean up

* .

* fix rich text component

* clean up
This commit is contained in:
reya
2025-11-03 19:04:16 +07:00
committed by GitHub
parent 4ebe590f8a
commit a4067d2c00
12 changed files with 200 additions and 366 deletions

View File

@@ -22,7 +22,7 @@ use person::PersonRegistry;
use settings::AppSettings;
use smallvec::{smallvec, SmallVec};
use smol::fs;
use states::{app_state, SignerKind, QUERY_TIMEOUT};
use states::{app_state, SignerKind};
use theme::ActiveTheme;
use ui::avatar::Avatar;
use ui::button::{Button, ButtonVariants};
@@ -45,9 +45,6 @@ mod emoji;
mod subject;
mod text;
const NIP17_WARN: &str = "has not set up Messaging Relays, they cannot receive your message.";
const EMPTY_WARN: &str = "Something is wrong. Coop cannot display this message";
pub fn init(room: Entity<Room>, window: &mut Window, cx: &mut App) -> Entity<ChatPanel> {
cx.new(|cx| ChatPanel::new(room, window, cx))
}
@@ -77,7 +74,7 @@ pub struct ChatPanel {
image_cache: Entity<RetainAllImageCache>,
_subscriptions: SmallVec<[Subscription; 3]>,
_tasks: SmallVec<[Task<()>; 3]>,
_tasks: SmallVec<[Task<()>; 2]>,
}
impl ChatPanel {
@@ -99,21 +96,11 @@ impl ChatPanel {
let list_state = ListState::new(messages.len(), ListAlignment::Bottom, px(1024.));
let connect = room.read(cx).connect(cx);
let verify_connections = room.read(cx).verify_connections(cx);
let get_messages = room.read(cx).get_messages(cx);
let mut subscriptions = smallvec![];
let mut tasks = smallvec![];
tasks.push(
// Get messaging relays and encryption keys announcement for all members
cx.background_spawn(async move {
if let Err(e) = connect.await {
log::error!("Failed to initialize room: {e}");
}
}),
);
tasks.push(
// Load all messages belonging to this room
cx.spawn_in(window, async move |this, cx| {
@@ -134,35 +121,11 @@ impl ChatPanel {
);
tasks.push(
// Connect and verify all members messaging relays
cx.spawn_in(window, async move |this, cx| {
// Wait for 5 seconds before connecting and verifying
cx.background_executor()
.timer(Duration::from_secs(QUERY_TIMEOUT))
.await;
let result = verify_connections.await;
this.update_in(cx, |this, window, cx| {
match result {
Ok(data) => {
let persons = PersonRegistry::global(cx);
for (public_key, status) in data.into_iter() {
if !status {
let profile = persons.read(cx).get_person(&public_key, cx);
let name = profile.display_name();
this.insert_warning(format!("{NIP17_WARN} {name}"), cx);
}
}
}
Err(e) => {
window.push_notification(e.to_string(), cx);
}
};
})
.ok();
// Get messaging relays and encryption keys announcement for each member
cx.background_spawn(async move {
if let Err(e) = connect.await {
log::error!("Failed to initialize room: {}", e);
}
}),
);
@@ -663,6 +626,33 @@ impl ChatPanel {
}
fn render_message(
&mut self,
ix: usize,
window: &mut Window,
cx: &mut Context<Self>,
) -> AnyElement {
if let Some(message) = self.messages.get_index(ix) {
match message {
Message::User(rendered) => {
let text = self
.rendered_texts_by_id
.entry(rendered.id)
.or_insert_with(|| RenderedText::new(&rendered.content, cx))
.element(ix.into(), window, cx);
self.render_text_message(ix, rendered, text, cx)
}
Message::Warning(content, _timestamp) => {
self.render_warning(ix, SharedString::from(content), cx)
}
Message::System(_timestamp) => self.render_announcement(ix, cx),
}
} else {
self.render_warning(ix, SharedString::from("Message not found"), cx)
}
}
fn render_text_message(
&self,
ix: usize,
message: &RenderedMessage,
@@ -1358,26 +1348,9 @@ impl Render for ChatPanel {
.child(
list(
self.list_state.clone(),
cx.processor(move |this, ix: usize, window, cx| {
if let Some(message) = this.messages.get_index(ix) {
match message {
Message::User(rendered) => {
let text = this
.rendered_texts_by_id
.entry(rendered.id)
.or_insert_with(|| RenderedText::new(&rendered.content, cx))
.element(ix.into(), window, cx);
this.render_message(ix, rendered, text, cx)
}
Message::Warning(content, _timestamp) => {
this.render_warning(ix, SharedString::from(content), cx)
}
Message::System(_timestamp) => this.render_announcement(ix, cx),
}
} else {
this.render_warning(ix, SharedString::from(EMPTY_WARN), cx)
}
cx.processor(|this, ix, window, cx| {
// Get and render message by index
this.render_message(ix, window, cx)
}),
)
.flex_1(),