wip: refactor

This commit is contained in:
2024-12-13 10:11:12 +07:00
parent 10f042acab
commit f82eaa4ac3
20 changed files with 431 additions and 231 deletions

View File

@@ -3,33 +3,36 @@ use gpui::*;
use nostr_sdk::prelude::*;
use std::time::Duration;
use crate::{constants::SUBSCRIPTION_ID, get_client};
use crate::{
constants::{ALL_MESSAGES_SUB_ID, NEW_MESSAGE_SUB_ID},
get_client,
};
pub struct AccountState {
pub in_use: Option<PublicKey>,
pub struct AccountRegistry {
public_key: Option<PublicKey>,
}
impl Global for AccountState {}
impl Global for AccountRegistry {}
impl AccountState {
impl AccountRegistry {
pub fn set_global(cx: &mut AppContext) {
cx.set_global(Self::new());
cx.observe_global::<Self>(|cx| {
let state = cx.global::<Self>();
if let Some(public_key) = state.in_use {
if let Some(public_key) = state.public_key {
let client = get_client();
let all_messages_sub_id = SubscriptionId::new(ALL_MESSAGES_SUB_ID);
let new_message_sub_id = SubscriptionId::new(NEW_MESSAGE_SUB_ID);
// Create a filter for getting all gift wrapped events send to current user
let all_messages = Filter::new().kind(Kind::GiftWrap).pubkey(public_key);
// Subscription options
let opts = SubscribeAutoCloseOptions::default().filter(
FilterOptions::WaitDurationAfterEOSE(Duration::from_secs(10)),
);
let subscription_id = SubscriptionId::new(SUBSCRIPTION_ID);
let opts = SubscribeAutoCloseOptions::default()
.filter(FilterOptions::WaitDurationAfterEOSE(Duration::from_secs(5)));
// Create a filter for getting new message
let new_message = Filter::new()
@@ -38,14 +41,15 @@ impl AccountState {
.limit(0);
spawn(async move {
// Subscribe for all messages
if client
.subscribe(vec![all_messages], Some(opts))
.subscribe_with_id(all_messages_sub_id, vec![all_messages], Some(opts))
.await
.is_ok()
{
// Subscribe for new message
_ = client
.subscribe_with_id(subscription_id, vec![new_message], None)
.subscribe_with_id(new_message_sub_id, vec![new_message], None)
.await
}
});
@@ -54,7 +58,15 @@ impl AccountState {
.detach();
}
pub fn set_user(&mut self, public_key: Option<PublicKey>) {
self.public_key = public_key
}
pub fn is_user_logged_in(&self) -> bool {
self.public_key.is_some()
}
fn new() -> Self {
Self { in_use: None }
Self { public_key: None }
}
}

View File

@@ -0,0 +1,75 @@
use gpui::*;
use itertools::Itertools;
use nostr_sdk::prelude::*;
use std::cmp::Reverse;
use crate::get_client;
pub struct ChatRegistry {
events: Model<Option<Vec<Event>>>,
}
impl Global for ChatRegistry {}
impl ChatRegistry {
pub fn set_global(cx: &mut AppContext) {
let events = cx.new_model(|_| None);
cx.set_global(Self::new(events));
}
pub fn load(&self, cx: &mut AppContext) {
let mut async_cx = cx.to_async();
let async_events = self.events.clone();
cx.foreground_executor()
.spawn(async move {
let client = get_client();
let signer = client.signer().await.unwrap();
let public_key = signer.get_public_key().await.unwrap();
let filter = Filter::new()
.kind(Kind::PrivateDirectMessage)
.pubkey(public_key);
let events = async_cx
.background_executor()
.spawn(async move {
if let Ok(events) = client.database().query(vec![filter]).await {
events
.into_iter()
.filter(|ev| ev.pubkey != public_key) // Filter messages from current user
.unique_by(|ev| ev.pubkey) // Get unique list
.sorted_by_key(|ev| Reverse(ev.created_at)) // Sort by created at
.collect::<Vec<_>>()
} else {
Vec::new()
}
})
.await;
async_cx.update_model(&async_events, |a, b| {
*a = Some(events);
b.notify();
})
})
.detach();
}
pub fn push(&self, event: Event, cx: &mut AppContext) {
cx.update_model(&self.events, |a, b| {
if let Some(events) = a {
events.push(event);
b.notify();
}
})
}
pub fn get(&self, cx: &WindowContext) -> Option<Vec<Event>> {
self.events.read(cx).clone()
}
fn new(events: Model<Option<Vec<Event>>>) -> Self {
Self { events }
}
}

View File

@@ -1 +1,3 @@
pub mod account;
pub mod chat;
pub mod signal;

View File

@@ -0,0 +1,28 @@
use gpui::*;
use nostr_sdk::prelude::*;
pub struct SignalRegistry {
public_keys: Vec<PublicKey>,
}
impl Global for SignalRegistry {}
impl SignalRegistry {
pub fn set_global(cx: &mut AppContext) {
cx.set_global(Self::new());
}
pub fn contains(&self, public_key: PublicKey) -> bool {
self.public_keys.contains(&public_key)
}
pub fn push(&mut self, public_key: PublicKey) {
self.public_keys.push(public_key);
}
fn new() -> Self {
Self {
public_keys: Vec::new(),
}
}
}