wip: refactor
This commit is contained in:
60
crates/app/src/states/account.rs
Normal file
60
crates/app/src/states/account.rs
Normal file
@@ -0,0 +1,60 @@
|
||||
use async_utility::task::spawn;
|
||||
use gpui::*;
|
||||
use nostr_sdk::prelude::*;
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::{constants::SUBSCRIPTION_ID, get_client};
|
||||
|
||||
pub struct AccountState {
|
||||
pub in_use: Option<PublicKey>,
|
||||
}
|
||||
|
||||
impl Global for AccountState {}
|
||||
|
||||
impl AccountState {
|
||||
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 {
|
||||
let client = get_client();
|
||||
|
||||
// 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);
|
||||
|
||||
// Create a filter for getting new message
|
||||
let new_message = Filter::new()
|
||||
.kind(Kind::GiftWrap)
|
||||
.pubkey(public_key)
|
||||
.limit(0);
|
||||
|
||||
spawn(async move {
|
||||
if client
|
||||
.subscribe(vec![all_messages], Some(opts))
|
||||
.await
|
||||
.is_ok()
|
||||
{
|
||||
// Subscribe for new message
|
||||
_ = client
|
||||
.subscribe_with_id(subscription_id, vec![new_message], None)
|
||||
.await
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
||||
fn new() -> Self {
|
||||
Self { in_use: None }
|
||||
}
|
||||
}
|
||||
@@ -1,2 +1,2 @@
|
||||
pub mod account;
|
||||
pub mod room;
|
||||
pub mod user;
|
||||
|
||||
@@ -1,35 +1,103 @@
|
||||
use components::theme::ActiveTheme;
|
||||
use gpui::*;
|
||||
use nostr_sdk::prelude::*;
|
||||
use prelude::FluentBuilder;
|
||||
|
||||
use crate::get_client;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct RoomLastMessage {
|
||||
pub content: Option<String>,
|
||||
pub time: Timestamp,
|
||||
#[allow(dead_code)]
|
||||
struct RoomLastMessage {
|
||||
content: Option<String>,
|
||||
time: Timestamp,
|
||||
}
|
||||
|
||||
#[derive(Clone, IntoElement)]
|
||||
pub struct Room {
|
||||
members: Vec<PublicKey>,
|
||||
last_message: Option<RoomLastMessage>,
|
||||
#[allow(dead_code)]
|
||||
public_key: PublicKey,
|
||||
metadata: Model<Option<Metadata>>,
|
||||
#[allow(dead_code)]
|
||||
last_message: RoomLastMessage,
|
||||
}
|
||||
|
||||
impl Room {
|
||||
pub fn new(members: Vec<PublicKey>, last_message: Option<RoomLastMessage>) -> Self {
|
||||
pub fn new(event: Event, cx: &mut WindowContext) -> Self {
|
||||
let public_key = event.pubkey;
|
||||
|
||||
let last_message = RoomLastMessage {
|
||||
content: Some(event.content),
|
||||
time: event.created_at,
|
||||
};
|
||||
|
||||
let metadata = cx.new_model(|_| None);
|
||||
let async_metadata = metadata.clone();
|
||||
|
||||
let mut async_cx = cx.to_async();
|
||||
|
||||
cx.foreground_executor()
|
||||
.spawn(async move {
|
||||
let client = get_client();
|
||||
|
||||
let query = async_cx
|
||||
.background_executor()
|
||||
.spawn(async move { client.database().metadata(public_key).await })
|
||||
.await;
|
||||
|
||||
if let Ok(metadata) = query {
|
||||
_ = async_cx.update_model(&async_metadata, |a, b| {
|
||||
*a = metadata;
|
||||
b.notify();
|
||||
});
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
|
||||
Self {
|
||||
members,
|
||||
public_key,
|
||||
metadata,
|
||||
last_message,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RenderOnce for Room {
|
||||
fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
|
||||
div().child("TODO")
|
||||
fn render(self, cx: &mut WindowContext) -> impl IntoElement {
|
||||
let mut content = div();
|
||||
|
||||
if let Some(metadata) = self.metadata.read(cx).as_ref() {
|
||||
content = content
|
||||
.flex()
|
||||
.items_center()
|
||||
.gap_2()
|
||||
.text_sm()
|
||||
.when_some(metadata.picture.clone(), |div, picture| {
|
||||
div.flex_shrink_0().child(
|
||||
img(picture)
|
||||
.size_6()
|
||||
.rounded_full()
|
||||
.object_fit(ObjectFit::Cover),
|
||||
)
|
||||
})
|
||||
.when_some(metadata.display_name.clone(), |div, display_name| {
|
||||
div.child(display_name)
|
||||
})
|
||||
} else {
|
||||
content = content
|
||||
.flex()
|
||||
.items_center()
|
||||
.gap_2()
|
||||
.text_sm()
|
||||
.child(
|
||||
div()
|
||||
.flex_shrink_0()
|
||||
.size_6()
|
||||
.rounded_full()
|
||||
.bg(cx.theme().muted),
|
||||
)
|
||||
.child("Anon")
|
||||
}
|
||||
|
||||
div().child(content)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Rooms {
|
||||
pub rooms: Vec<Room>,
|
||||
}
|
||||
|
||||
impl Global for Rooms {}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
use gpui::*;
|
||||
use nostr_sdk::prelude::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct UserState {
|
||||
pub current_user: Option<PublicKey>,
|
||||
}
|
||||
|
||||
impl Global for UserState {}
|
||||
|
||||
impl UserState {
|
||||
pub fn set_global(cx: &mut AppContext) {
|
||||
cx.set_global(Self::new());
|
||||
}
|
||||
|
||||
fn new() -> Self {
|
||||
Self { current_user: None }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user