wip: refactor

This commit is contained in:
2025-01-08 17:30:06 +07:00
parent 2d254c3a28
commit 80506b72d9
6 changed files with 145 additions and 105 deletions

View File

@@ -107,7 +107,8 @@ async fn main() {
subscription_id, subscription_id,
} = message } = message
{ {
if event.kind == Kind::GiftWrap { match event.kind {
Kind::GiftWrap => {
match client.unwrap_gift_wrap(&event).await { match client.unwrap_gift_wrap(&event).await {
Ok(UnwrappedGift { mut rumor, sender }) => { Ok(UnwrappedGift { mut rumor, sender }) => {
// Request metadata // Request metadata
@@ -136,7 +137,8 @@ async fn main() {
// Send event back to channel // Send event back to channel
if subscription_id == new_message { if subscription_id == new_message {
if let Err(e) = signal_tx.send(Signal::Event(ev)).await { if let Err(e) = signal_tx.send(Signal::Event(ev)).await
{
println!("Send error: {}", e) println!("Send error: {}", e)
} }
} }
@@ -144,11 +146,24 @@ async fn main() {
} }
Err(e) => println!("Unwrap error: {}", e), Err(e) => println!("Unwrap error: {}", e),
} }
} else if event.kind == Kind::Metadata { }
Kind::ContactList => {
let public_keys: Vec<PublicKey> =
event.tags.public_keys().copied().collect();
for public_key in public_keys.into_iter() {
if let Err(e) = mta_tx.send(public_key).await {
println!("Send error: {}", e)
};
}
}
Kind::Metadata => {
if let Err(e) = signal_tx.send(Signal::Metadata(event.pubkey)).await { if let Err(e) = signal_tx.send(Signal::Metadata(event.pubkey)).await {
println!("Send error: {}", e) println!("Send error: {}", e)
} }
} }
_ => {}
}
} else if let RelayMessage::EndOfStoredEvents(subscription_id) = message { } else if let RelayMessage::EndOfStoredEvents(subscription_id) = message {
if subscription_id == all_messages { if subscription_id == all_messages {
if let Err(e) = signal_tx.send(Signal::Eose).await { if let Err(e) = signal_tx.send(Signal::Eose).await {
@@ -283,8 +298,8 @@ async fn main() {
}) })
.await; .await;
_ = async_cx.update_global::<ChatRegistry, _>(|state, _cx| { _ = async_cx.update_global::<ChatRegistry, _>(|state, cx| {
state.new_message(event, metadata) state.new_message(event, metadata, cx)
}); });
} }
} }

View File

@@ -1,6 +1,6 @@
use crate::get_client; use crate::get_client;
use crate::utils::get_room_id; use crate::utils::get_room_id;
use gpui::{AppContext, Context, Global, Model, SharedString}; use gpui::{AppContext, Context, Global, Model, SharedString, WeakModel};
use itertools::Itertools; use itertools::Itertools;
use nostr_sdk::prelude::*; use nostr_sdk::prelude::*;
use rnglib::{Language, RNG}; use rnglib::{Language, RNG};
@@ -76,10 +76,11 @@ impl Message {
} }
} }
type Messages = RwLock<HashMap<SharedString, Arc<RwLock<Vec<Message>>>>>;
pub struct ChatRegistry { pub struct ChatRegistry {
pub messages: RwLock<HashMap<SharedString, Arc<RwLock<Vec<Message>>>>>, messages: Model<Messages>,
pub rooms: Model<Vec<Event>>, rooms: Model<Vec<Event>>,
pub is_initialized: bool,
} }
impl Global for ChatRegistry {} impl Global for ChatRegistry {}
@@ -87,13 +88,9 @@ impl Global for ChatRegistry {}
impl ChatRegistry { impl ChatRegistry {
pub fn set_global(cx: &mut AppContext) { pub fn set_global(cx: &mut AppContext) {
let rooms = cx.new_model(|_| Vec::new()); let rooms = cx.new_model(|_| Vec::new());
let messages = RwLock::new(HashMap::new()); let messages = cx.new_model(|_| RwLock::new(HashMap::new()));
cx.set_global(Self { cx.set_global(Self { messages, rooms });
messages,
rooms,
is_initialized: false,
});
} }
pub fn init(&mut self, cx: &mut AppContext) { pub fn init(&mut self, cx: &mut AppContext) {
@@ -143,31 +140,36 @@ impl ChatRegistry {
model.extend(events); model.extend(events);
cx.notify(); cx.notify();
}); });
state.is_initialized = true;
}); });
} }
}) })
.detach(); .detach();
} }
pub fn new_message(&mut self, event: Event, metadata: Option<Metadata>) { pub fn new_message(&mut self, event: Event, metadata: Option<Metadata>, cx: &mut AppContext) {
// Get room id // Get room id
let room_id = SharedString::from(get_room_id(&event.pubkey, &event.tags)); let room_id = SharedString::from(get_room_id(&event.pubkey, &event.tags));
// Create message // Create message
let message = Message::new(event, metadata); let message = Message::new(event, metadata);
self.messages self.messages.update(cx, |this, cx| {
.write() this.write()
.unwrap() .unwrap()
.entry(room_id) .entry(room_id)
.or_insert(Arc::new(RwLock::new(Vec::new()))) .or_insert(Arc::new(RwLock::new(Vec::new())))
.write() .write()
.unwrap() .unwrap()
.push(message) .push(message);
cx.notify();
});
} }
pub fn get_messages(&self, id: &SharedString) -> Option<Arc<RwLock<Vec<Message>>>> { pub fn messages(&self) -> WeakModel<Messages> {
self.messages.read().unwrap().get(id).cloned() self.messages.downgrade()
}
pub fn rooms(&self) -> WeakModel<Vec<Event>> {
self.rooms.downgrade()
} }
} }

View File

@@ -166,10 +166,11 @@ impl RoomPanel {
pub fn subscribe(&self, cx: &mut ViewContext<Self>) { pub fn subscribe(&self, cx: &mut ViewContext<Self>) {
let room_id = self.id.clone(); let room_id = self.id.clone();
let messages = self.messages.clone(); let messages = self.messages.clone();
let state = cx.global::<ChatRegistry>().messages();
cx.observe_global::<ChatRegistry>(move |_, cx| { if let Some(state) = state.upgrade() {
let state = cx.global::<ChatRegistry>(); cx.observe(&state, move |_, model, cx| {
let new_messages = state.get_messages(&room_id); let new_messages = model.read(cx).read().unwrap().get(&room_id).cloned();
if let Some(new_messages) = new_messages { if let Some(new_messages) = new_messages {
let items: Vec<RoomMessage> = new_messages let items: Vec<RoomMessage> = new_messages
@@ -196,9 +197,11 @@ impl RoomPanel {
}) })
.detach(); .detach();
} }
}
fn send_message(&mut self, cx: &mut ViewContext<Self>) { fn send_message(&mut self, cx: &mut ViewContext<Self>) {
let owner = self.owner; let members = self.members.clone();
let members2 = members.clone();
let content = self.input.read(cx).text().to_string(); let content = self.input.read(cx).text().to_string();
let content2 = content.clone(); let content2 = content.clone();
let content3 = content2.clone(); let content3 = content2.clone();
@@ -223,20 +226,40 @@ impl RoomPanel {
// Send message to all members // Send message to all members
async_cx async_cx
.background_executor() .background_executor()
.spawn(async move { client.send_private_msg(owner, content, vec![]).await }) .spawn(async move {
for member in members.iter() {
let tags: Vec<Tag> = members
.iter()
.filter_map(|public_key| {
if public_key != member {
Some(Tag::public_key(*public_key))
} else {
None
}
})
.collect();
_ = client.send_private_msg(*member, &content, tags).await;
}
})
.detach(); .detach();
// Send a copy to yourself // Send a copy to yourself
async_cx async_cx
.background_executor() .background_executor()
.spawn(async move { .spawn(async move {
client let tags: Vec<Tag> = members2
.send_private_msg( .iter()
current_user, .filter_map(|public_key| {
content2, if public_key != &current_user {
vec![Tag::public_key(owner)], Some(Tag::public_key(*public_key))
) } else {
.await None
}
})
.collect();
_ = client.send_private_msg(current_user, content2, tags).await;
}) })
.detach(); .detach();

View File

@@ -191,7 +191,7 @@ impl ContactList {
} }
} }
pub fn _selected(&self) -> Vec<PublicKey> { pub fn selected(&self) -> Vec<PublicKey> {
self.selected.clone().into_iter().collect() self.selected.clone().into_iter().collect()
} }

View File

@@ -165,13 +165,14 @@ pub struct Inbox {
impl Inbox { impl Inbox {
pub fn new(cx: &mut ViewContext<'_, Self>) -> Self { pub fn new(cx: &mut ViewContext<'_, Self>) -> Self {
let items = cx.new_model(|_| None); let items = cx.new_model(|_| None);
let events = cx.global::<ChatRegistry>().rooms();
cx.observe_global::<ChatRegistry>(|this, cx| { if let Some(events) = events.upgrade() {
if cx.global::<ChatRegistry>().is_initialized { cx.observe(&events, |this, model, cx| {
this.load(cx) this.load(model, cx);
}
}) })
.detach(); .detach();
}
Self { Self {
items, items,
@@ -181,9 +182,8 @@ impl Inbox {
} }
} }
pub fn load(&mut self, cx: &mut ViewContext<Self>) { pub fn load(&mut self, model: Model<Vec<Event>>, cx: &mut ViewContext<Self>) {
// Get all room's events let events = model.read(cx).clone();
let events: Vec<Event> = cx.global::<ChatRegistry>().rooms.read(cx).clone();
cx.spawn(|view, mut async_cx| async move { cx.spawn(|view, mut async_cx| async move {
let client = get_client(); let client = get_client();

View File

@@ -36,7 +36,7 @@ impl Sidebar {
let inbox = cx.new_view(Inbox::new); let inbox = cx.new_view(Inbox::new);
Self { Self {
name: "Left Dock".into(), name: "Sidebar".into(),
closeable: true, closeable: true,
zoomable: true, zoomable: true,
focus_handle: cx.focus_handle(), focus_handle: cx.focus_handle(),
@@ -57,9 +57,9 @@ impl Sidebar {
.rounded(ButtonRounded::Large) .rounded(ButtonRounded::Large)
.w_full() .w_full()
.on_click({ .on_click({
let _contact_list = contact_list.clone(); let contact_list = contact_list.clone();
move |_, _cx| { move |_, cx| {
// TODO: open room let _selected = contact_list.model.read(cx).selected();
} }
}), }),
), ),