wip: refactor
This commit is contained in:
@@ -107,47 +107,62 @@ async fn main() {
|
|||||||
subscription_id,
|
subscription_id,
|
||||||
} = message
|
} = message
|
||||||
{
|
{
|
||||||
if event.kind == Kind::GiftWrap {
|
match event.kind {
|
||||||
match client.unwrap_gift_wrap(&event).await {
|
Kind::GiftWrap => {
|
||||||
Ok(UnwrappedGift { mut rumor, sender }) => {
|
match client.unwrap_gift_wrap(&event).await {
|
||||||
// Request metadata
|
Ok(UnwrappedGift { mut rumor, sender }) => {
|
||||||
if let Err(e) = mta_tx.send(sender).await {
|
// Request metadata
|
||||||
println!("Send error: {}", e)
|
if let Err(e) = mta_tx.send(sender).await {
|
||||||
};
|
println!("Send error: {}", e)
|
||||||
|
};
|
||||||
|
|
||||||
// Compute event id if not exist
|
// Compute event id if not exist
|
||||||
rumor.ensure_id();
|
rumor.ensure_id();
|
||||||
|
|
||||||
if let Some(id) = rumor.id {
|
if let Some(id) = rumor.id {
|
||||||
let ev = Event::new(
|
let ev = Event::new(
|
||||||
id,
|
id,
|
||||||
rumor.pubkey,
|
rumor.pubkey,
|
||||||
rumor.created_at,
|
rumor.created_at,
|
||||||
rumor.kind,
|
rumor.kind,
|
||||||
rumor.tags,
|
rumor.tags,
|
||||||
rumor.content,
|
rumor.content,
|
||||||
sig,
|
sig,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Save rumor to database to further query
|
// Save rumor to database to further query
|
||||||
if let Err(e) = client.database().save_event(&ev).await {
|
if let Err(e) = client.database().save_event(&ev).await {
|
||||||
println!("Save error: {}", e);
|
println!("Save error: {}", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Err(e) => println!("Unwrap error: {}", e),
|
||||||
}
|
}
|
||||||
Err(e) => println!("Unwrap error: {}", e),
|
|
||||||
}
|
}
|
||||||
} else if event.kind == Kind::Metadata {
|
Kind::ContactList => {
|
||||||
if let Err(e) = signal_tx.send(Signal::Metadata(event.pubkey)).await {
|
let public_keys: Vec<PublicKey> =
|
||||||
println!("Send error: {}", e)
|
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 {
|
||||||
|
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 {
|
||||||
@@ -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)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -166,39 +166,42 @@ 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
|
||||||
.read()
|
.read()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.clone()
|
.clone()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|m| {
|
.map(|m| {
|
||||||
RoomMessage::new(
|
RoomMessage::new(
|
||||||
m.event.pubkey,
|
m.event.pubkey,
|
||||||
m.metadata,
|
m.metadata,
|
||||||
m.event.content,
|
m.event.content,
|
||||||
m.event.created_at,
|
m.event.created_at,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
cx.update_model(&messages, |model, cx| {
|
cx.update_model(&messages, |model, cx| {
|
||||||
model.items.extend(items);
|
model.items.extend(items);
|
||||||
model.count = model.items.len();
|
model.count = model.items.len();
|
||||||
cx.notify();
|
cx.notify();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.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 != ¤t_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();
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user