use gossip memory instead of sqlite

This commit is contained in:
2026-03-18 08:59:56 +07:00
parent 40e7ca368b
commit 64836b6dc5
6 changed files with 55 additions and 132 deletions

View File

@@ -13,6 +13,7 @@ use state::{NostrRegistry, TIMEOUT};
use crate::NewMessage;
const NO_RELAY: &str = "User hasn't set up any messaging relays yet.";
const NO_DEKEY: &str = "User hasn't set up a decoupled encryption key yet.";
const USER_NO_DEKEY: &str = "You haven't set up a decoupled encryption key or it's not available.";
@@ -354,17 +355,7 @@ impl Room {
pub fn connect(&self, cx: &App) -> Task<Result<(), Error>> {
let nostr = NostrRegistry::global(cx);
let client = nostr.read(cx).client();
let signer = nostr.read(cx).signer();
let sender = signer.public_key();
// Get all members, excluding the sender
let members: Vec<PublicKey> = self
.members
.iter()
.filter(|public_key| Some(**public_key) != sender)
.copied()
.collect();
let members = self.members();
cx.background_spawn(async move {
let opts = SubscribeAutoCloseOptions::default()
@@ -510,9 +501,16 @@ impl Room {
// Process each member
for member in members {
let relays = member.messaging_relays();
let announcement = member.announcement();
let public_key = member.public_key();
// Skip members with no relays
if relays.is_empty() {
reports.push(SendReport::new(public_key).error(NO_RELAY));
continue;
}
// Handle encryption signer requirements
if signer_kind.encryption() {
if announcement.is_none() {
@@ -548,7 +546,8 @@ impl Room {
SignerKind::User => (member.public_key(), user_signer.clone()),
};
match send_gift_wrap(&client, &signer, &receiver, &rumor, public_key).await {
match send_gift_wrap(&client, &signer, relays, &receiver, &rumor, public_key).await
{
Ok((report, _)) => {
reports.push(report);
sents += 1;
@@ -562,9 +561,11 @@ impl Room {
// Send backup to current user if needed
if backup && sents >= 1 {
let public_key = sender.public_key();
let relays = sender.messaging_relays();
let signer = encryption_signer.as_ref().unwrap_or(&user_signer);
match send_gift_wrap(&client, signer, &public_key, &rumor, public_key).await {
match send_gift_wrap(&client, signer, relays, &public_key, &rumor, public_key).await
{
Ok((report, _)) => reports.push(report),
Err(report) => reports.push(report),
}
@@ -579,6 +580,7 @@ impl Room {
async fn send_gift_wrap<T>(
client: &Client,
signer: &T,
to: &[RelayUrl],
receiver: &PublicKey,
rumor: &UnsignedEvent,
public_key: PublicKey,
@@ -588,9 +590,15 @@ where
{
match EventBuilder::gift_wrap(signer, receiver, rumor.clone(), []).await {
Ok(event) => {
// Connect to each relay before sending
for url in to.iter() {
client.add_relay(url).and_connect().await.ok();
}
// Send the event to each relay
match client
.send_event(&event)
.to_nip17()
.to(to)
.ack_policy(AckPolicy::none())
.await
{

View File

@@ -465,14 +465,6 @@ impl ChatPanel {
}
}
/// Check if a message is pending
fn sent_pending(&self, id: &EventId, cx: &App) -> bool {
self.reports_by_id
.read(cx)
.get(id)
.is_some_and(|reports| reports.iter().all(|r| r.pending()))
}
/// Check if a message has any reports
fn has_reports(&self, id: &EventId, cx: &App) -> bool {
self.reports_by_id.read(cx).get(id).is_some()
@@ -802,8 +794,6 @@ impl ChatPanel {
let replies = message.replies_to.as_slice();
let has_replies = !replies.is_empty();
let sent_pending = self.sent_pending(&id, cx);
let has_reports = self.has_reports(&id, cx);
// Hide avatar setting
@@ -851,9 +841,6 @@ impl ChatPanel {
.child(author.name()),
)
.child(message.created_at.to_human_time())
.when(sent_pending, |this| {
this.child(SharedString::from("• Sending..."))
})
.when(has_reports, |this| {
this.child(deferred(self.render_sent_reports(&id, cx)))
}),

View File

@@ -11,7 +11,7 @@ nostr.workspace = true
nostr-sdk.workspace = true
nostr-lmdb.workspace = true
nostr-memory.workspace = true
nostr-gossip-sqlite.workspace = true
nostr-gossip-memory.workspace = true
nostr-connect.workspace = true
nostr-blossom.workspace = true

View File

@@ -6,7 +6,7 @@ use anyhow::{Context as AnyhowContext, Error, anyhow};
use common::config_dir;
use gpui::{App, AppContext, Context, Entity, EventEmitter, Global, SharedString, Task, Window};
use nostr_connect::prelude::*;
use nostr_gossip_sqlite::prelude::*;
use nostr_gossip_memory::prelude::*;
use nostr_lmdb::prelude::*;
use nostr_memory::prelude::*;
use nostr_sdk::prelude::*;
@@ -114,17 +114,16 @@ impl NostrRegistry {
// Construct the nostr npubs entity
let npubs = cx.new(|_| vec![]);
// Construct the nostr gossip instance
let gossip = cx.foreground_executor().block_on(async move {
NostrGossipSqlite::open(config_dir().join("gossip"))
.await
.expect("Failed to initialize gossip instance")
});
// Construct the nostr client builder
let mut builder = ClientBuilder::default()
.signer(signer.clone())
.gossip(gossip)
.gossip(NostrGossipMemory::unbounded())
.gossip_config(
GossipConfig::default()
.no_background_refresh()
.sync_idle_timeout(Duration::from_secs(TIMEOUT))
.sync_initial_timeout(Duration::from_millis(600)),
)
.automatic_authentication(false)
.verify_subscriptions(false)
.connect_timeout(Duration::from_secs(10))
@@ -198,7 +197,10 @@ impl NostrRegistry {
}
// Connect to all added relays
client.connect().await;
client
.connect()
.and_wait(Duration::from_secs(TIMEOUT))
.await;
Ok(())
});