chore: improve render message (#84)
* . * refactor upload button * refactor * dispatch action on mention clicked * add profile modal * . * . * . * improve rich_text * improve handle url * make registry simpler * refactor * . * clean up
This commit is contained in:
@@ -7,8 +7,6 @@ publish.workspace = true
|
||||
[dependencies]
|
||||
common = { path = "../common" }
|
||||
global = { path = "../global" }
|
||||
identity = { path = "../identity" }
|
||||
settings = { path = "../settings" }
|
||||
|
||||
rust-i18n.workspace = true
|
||||
i18n.workspace = true
|
||||
|
||||
@@ -9,7 +9,6 @@ use global::nostr_client;
|
||||
use gpui::{
|
||||
App, AppContext, Context, Entity, EventEmitter, Global, Subscription, Task, WeakEntity, Window,
|
||||
};
|
||||
use identity::Identity;
|
||||
use itertools::Itertools;
|
||||
use nostr_sdk::prelude::*;
|
||||
use room::RoomKind;
|
||||
@@ -142,11 +141,11 @@ impl Registry {
|
||||
.unwrap_or(Profile::new(public_key.to_owned(), Metadata::default()))
|
||||
}
|
||||
|
||||
pub fn get_group_person(&self, public_keys: &[PublicKey], cx: &App) -> Vec<Option<Profile>> {
|
||||
pub fn get_group_person(&self, public_keys: &[PublicKey], cx: &App) -> Vec<Profile> {
|
||||
let mut profiles = vec![];
|
||||
|
||||
for public_key in public_keys.iter() {
|
||||
let profile = self.persons.get(public_key).map(|e| e.read(cx)).cloned();
|
||||
let profile = self.get_person(public_key, cx);
|
||||
profiles.push(profile);
|
||||
}
|
||||
|
||||
@@ -315,11 +314,19 @@ impl Registry {
|
||||
let is_ongoing = client.database().count(filter).await.unwrap_or(1) >= 1;
|
||||
|
||||
if is_ongoing {
|
||||
rooms.insert(Room::new(&event).kind(RoomKind::Ongoing));
|
||||
rooms.insert(
|
||||
Room::new(&event)
|
||||
.kind(RoomKind::Ongoing)
|
||||
.rearrange_by(public_key),
|
||||
);
|
||||
} else if is_trust {
|
||||
rooms.insert(Room::new(&event).kind(RoomKind::Trusted));
|
||||
rooms.insert(
|
||||
Room::new(&event)
|
||||
.kind(RoomKind::Trusted)
|
||||
.rearrange_by(public_key),
|
||||
);
|
||||
} else {
|
||||
rooms.insert(Room::new(&event));
|
||||
rooms.insert(Room::new(&event).rearrange_by(public_key));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -388,14 +395,16 @@ impl Registry {
|
||||
///
|
||||
/// If the room doesn't exist, it will be created.
|
||||
/// Updates room ordering based on the most recent messages.
|
||||
pub fn event_to_message(&mut self, event: Event, window: &mut Window, cx: &mut Context<Self>) {
|
||||
pub fn event_to_message(
|
||||
&mut self,
|
||||
identity: PublicKey,
|
||||
event: Event,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let id = room_hash(&event);
|
||||
let author = event.pubkey;
|
||||
|
||||
let Some(identity) = Identity::read_global(cx).public_key() else {
|
||||
return;
|
||||
};
|
||||
|
||||
if let Some(room) = self.rooms.iter().find(|room| room.read(cx).id == id) {
|
||||
// Update room
|
||||
room.update(cx, |this, cx| {
|
||||
@@ -415,15 +424,16 @@ impl Registry {
|
||||
// Re-sort the rooms registry by their created at
|
||||
self.sort(cx);
|
||||
} else {
|
||||
let room = Room::new(&event).kind(RoomKind::Unknown);
|
||||
let kind = room.kind;
|
||||
let room = Room::new(&event)
|
||||
.kind(RoomKind::Unknown)
|
||||
.rearrange_by(identity);
|
||||
|
||||
// Push the new room to the front of the list
|
||||
self.add_room(cx.new(|_| room), cx);
|
||||
|
||||
// Notify the UI about the new room
|
||||
cx.defer_in(window, move |_this, _window, cx| {
|
||||
cx.emit(RoomEmitter::Request(kind));
|
||||
cx.emit(RoomEmitter::Request(RoomKind::Unknown));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ use std::rc::Rc;
|
||||
use chrono::{Local, TimeZone};
|
||||
use gpui::SharedString;
|
||||
use nostr_sdk::prelude::*;
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
|
||||
use crate::room::SendError;
|
||||
|
||||
@@ -24,11 +23,11 @@ pub struct Message {
|
||||
/// When the message was created
|
||||
pub created_at: Timestamp,
|
||||
/// List of mentioned public keys in the message
|
||||
pub mentions: SmallVec<[PublicKey; 2]>,
|
||||
pub mentions: Vec<PublicKey>,
|
||||
/// List of EventIds this message is replying to
|
||||
pub replies_to: Option<SmallVec<[EventId; 1]>>,
|
||||
pub replies_to: Option<Vec<EventId>>,
|
||||
/// Any errors that occurred while sending this message
|
||||
pub errors: Option<SmallVec<[SendError; 1]>>,
|
||||
pub errors: Option<Vec<SendError>>,
|
||||
}
|
||||
|
||||
/// Builder pattern implementation for constructing Message objects.
|
||||
@@ -38,9 +37,9 @@ pub struct MessageBuilder {
|
||||
author: PublicKey,
|
||||
content: Option<SharedString>,
|
||||
created_at: Option<Timestamp>,
|
||||
mentions: SmallVec<[PublicKey; 2]>,
|
||||
replies_to: Option<SmallVec<[EventId; 1]>>,
|
||||
errors: Option<SmallVec<[SendError; 1]>>,
|
||||
mentions: Vec<PublicKey>,
|
||||
replies_to: Option<Vec<EventId>>,
|
||||
errors: Option<Vec<SendError>>,
|
||||
}
|
||||
|
||||
impl MessageBuilder {
|
||||
@@ -51,7 +50,7 @@ impl MessageBuilder {
|
||||
author,
|
||||
content: None,
|
||||
created_at: None,
|
||||
mentions: smallvec![],
|
||||
mentions: vec![],
|
||||
replies_to: None,
|
||||
errors: None,
|
||||
}
|
||||
@@ -86,7 +85,7 @@ impl MessageBuilder {
|
||||
|
||||
/// Sets a single message this is replying to
|
||||
pub fn reply_to(mut self, reply_to: EventId) -> Self {
|
||||
self.replies_to = Some(smallvec![reply_to]);
|
||||
self.replies_to = Some(vec![reply_to]);
|
||||
self
|
||||
}
|
||||
|
||||
@@ -95,7 +94,7 @@ impl MessageBuilder {
|
||||
where
|
||||
I: IntoIterator<Item = EventId>,
|
||||
{
|
||||
let replies: SmallVec<[EventId; 1]> = replies_to.into_iter().collect();
|
||||
let replies: Vec<EventId> = replies_to.into_iter().collect();
|
||||
if !replies.is_empty() {
|
||||
self.replies_to = Some(replies);
|
||||
}
|
||||
|
||||
@@ -5,10 +5,8 @@ use chrono::{Local, TimeZone};
|
||||
use common::display::DisplayProfile;
|
||||
use global::nostr_client;
|
||||
use gpui::{App, AppContext, Context, EventEmitter, SharedString, Task, Window};
|
||||
use identity::Identity;
|
||||
use itertools::Itertools;
|
||||
use nostr_sdk::prelude::*;
|
||||
use settings::AppSettings;
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use crate::message::Message;
|
||||
@@ -26,7 +24,7 @@ pub struct Incoming(pub Message);
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct SendError {
|
||||
pub profile: Profile,
|
||||
pub message: String,
|
||||
pub message: SharedString,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Hash, Debug, PartialEq, Eq, PartialOrd, Ord, Default)]
|
||||
@@ -126,6 +124,27 @@ impl Room {
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the rearrange_by field of the room and returns the modified room
|
||||
///
|
||||
/// This is a builder-style method that allows chaining room modifications.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `rearrange_by` - The PublicKey to set for rearranging the member list
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// The modified Room instance with the new member list after rearrangement
|
||||
pub fn rearrange_by(mut self, rearrange_by: PublicKey) -> Self {
|
||||
let (not_match, matches): (Vec<PublicKey>, Vec<PublicKey>) = self
|
||||
.members
|
||||
.into_iter()
|
||||
.partition(|key| key != &rearrange_by);
|
||||
self.members = not_match.into();
|
||||
self.members.extend(matches);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the room kind to ongoing
|
||||
///
|
||||
/// # Arguments
|
||||
@@ -240,14 +259,13 @@ impl Room {
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `proxy` - Whether to use the proxy for the avatar URL
|
||||
/// * `cx` - The application context
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A SharedString containing the image path or URL
|
||||
pub fn display_image(&self, cx: &App) -> SharedString {
|
||||
let proxy = AppSettings::get_global(cx).settings.proxy_user_avatars;
|
||||
|
||||
pub fn display_image(&self, proxy: bool, cx: &App) -> SharedString {
|
||||
if let Some(picture) = self.picture.as_ref() {
|
||||
picture.clone()
|
||||
} else if !self.is_group() {
|
||||
@@ -262,18 +280,7 @@ impl Room {
|
||||
/// First member is always different from the current user.
|
||||
pub(crate) fn first_member(&self, cx: &App) -> Profile {
|
||||
let registry = Registry::read_global(cx);
|
||||
|
||||
if let Some(identity) = Identity::read_global(cx).public_key().as_ref() {
|
||||
self.members
|
||||
.iter()
|
||||
.filter(|&pubkey| pubkey != identity)
|
||||
.collect::<Vec<_>>()
|
||||
.first()
|
||||
.map(|public_key| registry.get_person(public_key, cx))
|
||||
.unwrap_or(registry.get_person(identity, cx))
|
||||
} else {
|
||||
registry.get_person(&self.members[0], cx)
|
||||
}
|
||||
registry.get_person(&self.members[0], cx)
|
||||
}
|
||||
|
||||
/// Merge the names of the first two members of the room.
|
||||
@@ -474,11 +481,10 @@ impl Room {
|
||||
/// or `None` if no account is found.
|
||||
pub fn create_temp_message(
|
||||
&self,
|
||||
public_key: PublicKey,
|
||||
content: &str,
|
||||
replies: Option<&Vec<Message>>,
|
||||
cx: &App,
|
||||
) -> Option<Message> {
|
||||
let public_key = Identity::read_global(cx).public_key()?;
|
||||
let builder = EventBuilder::private_msg_rumor(public_key, content);
|
||||
|
||||
// Add event reference if it's present (replying to another event)
|
||||
@@ -549,6 +555,7 @@ impl Room {
|
||||
&self,
|
||||
content: &str,
|
||||
replies: Option<&Vec<Message>>,
|
||||
backup: bool,
|
||||
cx: &App,
|
||||
) -> Task<Result<Vec<SendError>, Error>> {
|
||||
let content = content.to_owned();
|
||||
@@ -556,7 +563,6 @@ impl Room {
|
||||
let subject = self.subject.clone();
|
||||
let picture = self.picture.clone();
|
||||
let public_keys = self.members.clone();
|
||||
let backup = AppSettings::get_global(cx).settings.backup_messages;
|
||||
|
||||
cx.background_spawn(async move {
|
||||
let client = nostr_client();
|
||||
@@ -615,7 +621,7 @@ impl Room {
|
||||
let profile = Profile::new(*receiver, metadata);
|
||||
let report = SendError {
|
||||
profile,
|
||||
message: e.to_string(),
|
||||
message: e.to_string().into(),
|
||||
};
|
||||
|
||||
reports.push(report);
|
||||
@@ -636,7 +642,7 @@ impl Room {
|
||||
let profile = Profile::new(*current_user, metadata);
|
||||
let report = SendError {
|
||||
profile,
|
||||
message: e.to_string(),
|
||||
message: e.to_string().into(),
|
||||
};
|
||||
reports.push(report);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user