local thread subscriptions

This adds local nostrdb thread subscriptions. When navigating to a
thread, we first check to see if we have any active nostrdb
subscriptions for that thread. If not, we create a new subscription. If
we do, we re-use that subscription.

This works by storing thread state in the Threads struct in the Damus
application state.

When we pop a route, we check to see if its a thread route. If it is,
then we try to unsubscribe, but only if that is the last remaining
subscriber for that thread, as there could be more than one.

Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
William Casarin
2024-07-23 14:10:00 -07:00
parent 33e5b6886b
commit a28db5d330
9 changed files with 459 additions and 165 deletions

View File

@@ -1,5 +1,7 @@
use crate::{route::Route, Damus};
use crate::{route::Route, thread::Thread, Damus};
use enostr::NoteId;
use nostrdb::Transaction;
use tracing::{info, warn};
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
pub enum BarAction {
@@ -8,7 +10,13 @@ pub enum BarAction {
}
impl BarAction {
pub fn execute(self, app: &mut Damus, timeline: usize, replying_to: &[u8; 32]) {
pub fn execute(
self,
app: &mut Damus,
timeline: usize,
replying_to: &[u8; 32],
txn: &Transaction,
) {
match self {
BarAction::Reply => {
let timeline = &mut app.timelines[timeline];
@@ -19,11 +27,44 @@ impl BarAction {
}
BarAction::OpenThread => {
let timeline = &mut app.timelines[timeline];
timeline
.routes
.push(Route::Thread(NoteId::new(replying_to.to_owned())));
timeline.navigating = true;
{
let timeline = &mut app.timelines[timeline];
timeline
.routes
.push(Route::Thread(NoteId::new(replying_to.to_owned())));
timeline.navigating = true;
}
let root_id = crate::note::root_note_id_from_selected_id(app, txn, replying_to);
let thread = app.threads.thread_mut(&app.ndb, txn, root_id);
// only start a subscription on nav and if we don't have
// an active subscription for this thread.
if thread.subscription().is_none() {
*thread.subscription_mut() = app.ndb.subscribe(Thread::filters(root_id)).ok();
match thread.subscription() {
Some(_sub) => {
thread.subscribers += 1;
info!(
"Locally subscribing to thread. {} total active subscriptions, {} on this thread",
app.ndb.subscription_count(),
thread.subscribers,
);
}
None => warn!(
"Error subscribing locally to selected note '{}''s thread",
hex::encode(replying_to)
),
}
} else {
thread.subscribers += 1;
info!(
"Re-using existing thread subscription. {} total active subscriptions, {} on this thread",
app.ndb.subscription_count(),
thread.subscribers,
)
}
}
}
}