.
Some checks failed
Rust / build (ubuntu-latest, stable) (push) Failing after 1m30s
Rust / build (ubuntu-latest, stable) (pull_request) Failing after 1m15s

This commit is contained in:
2026-02-07 20:52:17 +07:00
parent 253d04f988
commit 031883c278
10 changed files with 393 additions and 745 deletions

View File

@@ -11,7 +11,7 @@ use nostr_sdk::prelude::*;
use person::{Person, PersonRegistry};
use state::{tracker, NostrRegistry};
use crate::NewMessage;
use crate::{ChatRegistry, NewMessage};
const SEND_RETRY: usize = 10;
@@ -99,16 +99,20 @@ pub enum RoomKind {
Ongoing,
}
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct Room {
/// Conversation ID
pub id: u64,
/// The timestamp of the last message in the room
pub created_at: Timestamp,
/// Subject of the room
pub subject: Option<SharedString>,
/// All members of the room
pub members: Vec<PublicKey>,
pub(super) members: Vec<PublicKey>,
/// Kind
pub kind: RoomKind,
}
@@ -145,11 +149,7 @@ impl From<&UnsignedEvent> for Room {
fn from(val: &UnsignedEvent) -> Self {
let id = val.uniq_id();
let created_at = val.created_at;
// Get the members from the event's tags and event's pubkey
let members = val.extract_public_keys();
// Get subject from tags
let subject = val
.tags
.find(TagKind::Subject)
@@ -165,6 +165,12 @@ impl From<&UnsignedEvent> for Room {
}
}
impl From<UnsignedEvent> for Room {
fn from(val: UnsignedEvent) -> Self {
Room::from(&val)
}
}
impl Room {
/// Constructs a new room with the given receiver and tags.
pub fn new<T>(author: PublicKey, receivers: T) -> Self
@@ -172,16 +178,30 @@ impl Room {
T: IntoIterator<Item = PublicKey>,
{
let tags = Tags::from_list(receivers.into_iter().map(Tag::public_key).collect());
// Construct an unsigned event for a direct message
//
// WARNING: never sign this event
let mut event = EventBuilder::new(Kind::PrivateDirectMessage, "")
.tags(tags)
.build(author);
// Generate event ID
// Ensure that the ID is set
event.ensure_id();
Room::from(&event)
}
/// Organizes the members of the room by moving the target member to the end.
///
/// Always call this function to ensure the current user is at the end of the list.
pub fn organize(mut self, target: &PublicKey) -> Self {
if let Some(index) = self.members.iter().position(|member| member == target) {
let member = self.members.remove(index);
self.members.push(member);
}
self
}
/// Sets the kind of the room and returns the modified room
pub fn kind(mut self, kind: RoomKind) -> Self {
self.kind = kind;
@@ -275,9 +295,21 @@ impl Room {
}
}
/// Emits a new message signal to the current room
pub fn emit_message(&self, message: NewMessage, cx: &mut Context<Self>) {
/// Push a new message to the current room
pub fn push_message(&mut self, message: NewMessage, cx: &mut Context<Self>) {
let created_at = message.rumor.created_at;
let new_message = created_at > self.created_at;
// Emit the incoming message event
cx.emit(RoomEvent::Incoming(message));
if new_message {
self.set_created_at(created_at, cx);
// Sort chats after emitting a new message
ChatRegistry::global(cx).update(cx, |this, cx| {
this.sort(cx);
});
}
}
/// Emits a signal to reload the current room's messages.