update message
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
+82
-39
@@ -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,
|
||||||
media,
|
val.rumor.kind,
|
||||||
created_at: val.rumor.created_at,
|
&val.rumor.content,
|
||||||
mentions,
|
&val.rumor.tags,
|
||||||
replies_to,
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
created_at,
|
||||||
|
mentions,
|
||||||
|
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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user