update message

This commit is contained in:
2026-09-15 19:16:10 +07:00
parent 1877e0082c
commit 9fcfb9f0bf
2 changed files with 83 additions and 39 deletions
+1
View File
@@ -21,6 +21,7 @@ mod room;
pub use message::*; pub use message::*;
pub use room::*; pub use room::*;
pub use state::FileAttachment;
/// A static keypair used only for signing locally-cached rumor events. /// A static keypair used only for signing locally-cached rumor events.
static LOCAL_KEYS: LazyLock<Keys> = LazyLock::new(Keys::generate); static LOCAL_KEYS: LazyLock<Keys> = LazyLock::new(Keys::generate);
+79 -36
View File
@@ -4,6 +4,9 @@ use std::ops::Range;
use common::{EventExt, NostrParser, extract_and_remove_media_urls}; use common::{EventExt, NostrParser, extract_and_remove_media_urls};
use gpui::{SharedString, SharedUri}; use gpui::{SharedString, SharedUri};
use nostr_sdk::prelude::*; use nostr_sdk::prelude::*;
use state::FileAttachment;
pub const KIND_FILE_MESSAGE: Kind = Kind::Custom(15);
/// Rendered message. /// Rendered message.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@@ -21,61 +24,90 @@ pub struct Message {
pub mentions: Vec<Mention>, pub mentions: Vec<Mention>,
/// List of event of the message this message is a reply to /// List of event of the message this message is a reply to
pub replies_to: Vec<EventId>, pub replies_to: Vec<EventId>,
/// Encrypted file attachment
pub file: Option<FileAttachment>,
} }
impl From<&Event> for Message { impl From<&Event> for Message {
fn from(val: &Event) -> Self { fn from(val: &Event) -> Self {
let mentions = extract_mentions(&val.content); from_parts(
let replies_to = extract_reply_ids(&val.tags); val.id,
let (media, string) = extract_and_remove_media_urls(&val.content); val.pubkey,
val.created_at,
Self { val.kind,
id: val.id, &val.content,
author: val.pubkey, &val.tags,
content: string, )
media,
created_at: val.created_at,
mentions,
replies_to,
}
} }
} }
impl From<&UnsignedEvent> for Message { impl From<&UnsignedEvent> for Message {
fn from(val: &UnsignedEvent) -> Self { fn from(val: &UnsignedEvent) -> Self {
let mentions = extract_mentions(&val.content); from_parts(
let replies_to = extract_reply_ids(&val.tags);
let (media, string) = extract_and_remove_media_urls(&val.content);
Self {
// Event ID must be known // Event ID must be known
id: val.id.unwrap(), val.id.unwrap(),
author: val.pubkey, val.pubkey,
content: string, val.created_at,
media, val.kind,
created_at: val.created_at, &val.content,
mentions, &val.tags,
replies_to, )
}
} }
} }
impl From<&NewMessage> for Message { impl From<&NewMessage> for Message {
fn from(val: &NewMessage) -> Self { fn from(val: &NewMessage) -> Self {
let mentions = extract_mentions(&val.rumor.content); from_parts(
let replies_to = extract_reply_ids(&val.rumor.tags);
let (media, string) = extract_and_remove_media_urls(&val.rumor.content);
Self {
// Event ID must be known // Event ID must be known
id: val.rumor.id.unwrap(), val.rumor.id.unwrap(),
author: val.rumor.pubkey, val.rumor.pubkey,
content: string, val.rumor.created_at,
val.rumor.kind,
&val.rumor.content,
&val.rumor.tags,
)
}
}
fn from_parts(
id: EventId,
author: PublicKey,
created_at: Timestamp,
kind: Kind,
content: &str,
tags: &Tags,
) -> Message {
let file = if kind == KIND_FILE_MESSAGE {
FileAttachment::from_tags(content, tags)
} else {
None
};
let has_file = file.is_some();
let replies_to = extract_reply_ids(tags);
// For file messages `.content` is the encrypted blob URL, not text or media
let mentions = if has_file {
Vec::new()
} else {
extract_mentions(content)
};
let (media, content) = if has_file {
(Vec::new(), String::new())
} else {
extract_and_remove_media_urls(content)
};
Message {
id,
author,
content,
media, media,
created_at: val.rumor.created_at, created_at,
mentions, mentions,
replies_to, replies_to,
} file,
} }
} }
@@ -105,6 +137,17 @@ impl Hash for Message {
} }
} }
impl Message {
/// Single-line representation for reply previews, notifications and copy.
pub fn preview(&self) -> SharedString {
if let Some(file) = &self.file {
return format!("[File] {}", file.display_name()).into();
}
self.content.clone().into()
}
}
/// New message. /// New message.
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct NewMessage { pub struct NewMessage {