chore: internal changes

This commit is contained in:
2025-02-25 15:22:24 +07:00
parent 1c4806bd92
commit 111ab3b082
11 changed files with 275 additions and 323 deletions

View File

@@ -1,4 +1,4 @@
use anyhow::anyhow;
use anyhow::{anyhow, Error};
use common::{
constants::{ALL_MESSAGES_SUB_ID, NEW_MESSAGE_SUB_ID},
profile::NostrProfile,
@@ -29,46 +29,37 @@ impl Account {
pub fn login(signer: Arc<dyn NostrSigner>, cx: &AsyncApp) -> Task<Result<(), anyhow::Error>> {
let client = get_client();
let (tx, rx) = oneshot::channel::<Option<NostrProfile>>();
cx.background_spawn(async move {
let task: Task<Result<NostrProfile, anyhow::Error>> = cx.background_spawn(async move {
// Update nostr signer
_ = client.set_signer(signer).await;
// Verify nostr signer and get public key
let result = async {
let signer = client.signer().await?;
let public_key = signer.get_public_key().await?;
let metadata = client
.fetch_metadata(public_key, Duration::from_secs(2))
.await
.ok()
.unwrap_or_default();
let signer = client.signer().await?;
let public_key = signer.get_public_key().await?;
let metadata = client
.fetch_metadata(public_key, Duration::from_secs(2))
.await
.unwrap_or_default();
Ok::<_, anyhow::Error>(NostrProfile::new(public_key, metadata))
}
.await;
tx.send(result.ok()).ok();
})
.detach();
Ok(NostrProfile::new(public_key, metadata))
});
cx.spawn(|cx| async move {
if let Ok(Some(profile)) = rx.await {
cx.update(|cx| {
let this = cx.new(|cx| {
let this = Account { profile };
// Run initial sync data for this account
if let Some(task) = this.sync(cx) {
task.detach();
}
// Return
this
});
match task.await {
Ok(profile) => {
cx.update(|cx| {
let this = cx.new(|cx| {
let this = Self { profile };
// Run initial sync data for this account
this.sync(cx);
this
});
Self::set_global(this, cx)
})
} else {
Err(anyhow!("Login failed"))
Self::set_global(this, cx)
})
}
Err(e) => Err(anyhow!("Login failed: {}", e)),
}
})
}
@@ -77,41 +68,81 @@ impl Account {
&self.profile
}
fn sync(&self, cx: &mut Context<Self>) -> Option<Task<()>> {
pub fn verify_inbox_relays(&self, cx: &App) -> Task<Result<Vec<String>, Error>> {
let client = get_client();
let public_key = self.profile.public_key();
let task = cx.background_spawn(async move {
// Set the default options for this task
cx.background_spawn(async move {
let filter = Filter::new()
.kind(Kind::InboxRelays)
.author(public_key)
.limit(1);
let events = client.database().query(filter).await?;
if let Some(event) = events.first_owned() {
let relays = event
.tags
.filter_standardized(TagKind::Relay)
.filter_map(|t| match t {
TagStandard::Relay(url) => Some(url.to_string()),
_ => None,
})
.collect::<Vec<_>>();
Ok(relays)
} else {
Err(anyhow!("Not found"))
}
})
}
fn sync(&self, cx: &mut Context<Self>) {
let client = get_client();
let public_key = self.profile.public_key();
cx.background_spawn(async move {
let opts = SubscribeAutoCloseOptions::default().exit_policy(ReqExitPolicy::ExitOnEOSE);
// Create a filter to get contact list
// Get contact list
let contact_list = Filter::new()
.kind(Kind::ContactList)
.author(public_key)
.limit(1);
if let Err(e) = client.subscribe(contact_list, Some(opts)).await {
log::error!("Failed to subscribe to contact list: {}", e);
log::error!("Failed to get contact list: {}", e);
}
// Create a filter to continuously receive new user's data.
let data = Filter::new()
.kinds(vec![Kind::Metadata, Kind::InboxRelays, Kind::RelayList])
.author(public_key)
.since(Timestamp::now());
if let Err(e) = client.subscribe(data, None).await {
log::error!("Failed to subscribe to user data: {}", e);
}
// Create a filter for getting all gift wrapped events send to current user
let msg = Filter::new().kind(Kind::GiftWrap).pubkey(public_key);
let id = SubscriptionId::new(ALL_MESSAGES_SUB_ID);
let filter = Filter::new().kind(Kind::GiftWrap).pubkey(public_key);
let sub_id = SubscriptionId::new(ALL_MESSAGES_SUB_ID);
if let Err(e) = client.subscribe_with_id(id, msg.clone(), Some(opts)).await {
if let Err(e) = client
.subscribe_with_id(sub_id, filter.clone(), Some(opts))
.await
{
log::error!("Failed to subscribe to all messages: {}", e);
}
// Create a filter to continuously receive new messages.
let new_msg = msg.limit(0);
let id = SubscriptionId::new(NEW_MESSAGE_SUB_ID);
let new_filter = filter.limit(0);
let sub_id = SubscriptionId::new(NEW_MESSAGE_SUB_ID);
if let Err(e) = client.subscribe_with_id(id, new_msg, None).await {
if let Err(e) = client.subscribe_with_id(sub_id, new_filter, None).await {
log::error!("Failed to subscribe to new messages: {}", e);
}
});
Some(task)
})
.detach();
}
}