commit 0344ea866f0ffccbfff1b870667a8a524a019540
parent 34c51536188005eca3c8d55408e07a007b517f9d
Author: kernelkind <kernelkind@gmail.com>
Date: Sun, 19 Oct 2025 19:45:49 -0400
fix(notif-indicator): more performant impl
the previous unseen notification indicator only ran once a few
seconds, but when it did it often took > 5ms because of ndb::query,
which is unacceptable.
This commit removes the ndb::query entirely and relies on the
ndb::poll_for_notes which is already being used every time there is
a new event from a relay
Signed-off-by: kernelkind <kernelkind@gmail.com>
Diffstat:
4 files changed, 18 insertions(+), 39 deletions(-)
diff --git a/crates/notedeck_columns/src/app.rs b/crates/notedeck_columns/src/app.rs
@@ -698,11 +698,7 @@ fn render_damus_mobile(
break 'brk;
}
- let unseen_notif = unseen_notification(
- app,
- app_ctx.ndb,
- app_ctx.accounts.get_selected_account().key.pubkey,
- );
+ let unseen_notif = unseen_notification(app, app_ctx.accounts, active_col);
if skb_rect.is_none() {
let resp = toolbar(ui, unseen_notif);
diff --git a/crates/notedeck_columns/src/timeline/cache.rs b/crates/notedeck_columns/src/timeline/cache.rs
@@ -258,7 +258,7 @@ impl TimelineCache {
return;
};
- tl.current_view_mut().freshness.set_fresh();
+ tl.seen_latest_notes = true;
}
}
diff --git a/crates/notedeck_columns/src/timeline/mod.rs b/crates/notedeck_columns/src/timeline/mod.rs
@@ -243,6 +243,7 @@ pub struct Timeline {
pub filter: FilterStates,
pub views: Vec<TimelineTab>,
pub selected_view: usize,
+ pub seen_latest_notes: bool,
pub subscription: TimelineSub,
pub enable_front_insert: bool,
@@ -317,6 +318,7 @@ impl Timeline {
subscription,
selected_view,
enable_front_insert,
+ seen_latest_notes: false,
}
}
@@ -489,7 +491,7 @@ impl Timeline {
if new_note_ids.is_empty() {
return Ok(());
} else {
- debug!("{} new notes! {:?}", new_note_ids.len(), new_note_ids);
+ self.seen_latest_notes = false;
}
self.insert(&new_note_ids, ndb, txn, unknown_ids, note_cache, reversed)
diff --git a/crates/notedeck_columns/src/toolbar.rs b/crates/notedeck_columns/src/toolbar.rs
@@ -1,4 +1,3 @@
-use nostrdb::Transaction;
use notedeck::AppContext;
use crate::{
@@ -10,42 +9,24 @@ use crate::{
#[profiling::function]
pub fn unseen_notification(
columns: &mut Damus,
- ndb: &nostrdb::Ndb,
- current_pk: notedeck::enostr::Pubkey,
+ accounts: ¬edeck::Accounts,
+ active_col: usize,
) -> bool {
- let Some(tl) = columns
- .timeline_cache
- .get_mut(&TimelineKind::Notifications(current_pk))
- else {
- return false;
- };
+ let top = columns.columns(accounts).column(active_col).router().top();
+ let current_pk = accounts.get_selected_account().keypair().pubkey;
- let freshness = &mut tl.current_view_mut().freshness;
- freshness.update(|timestamp_last_viewed| {
- profiling::scope!("NotesFreshness::update closure");
- let filter = {
- profiling::scope!("NotesFreshness::update filter instantiation");
- enostr::Filter::new_with_capacity(1)
- .pubkeys([current_pk.bytes()])
- .kinds(crate::timeline::kind::notification_kinds())
- .limit(1)
- .since(timestamp_last_viewed)
- .build()
- };
- let txn = Transaction::new(ndb).expect("txn");
-
- let Some(res) = {
- profiling::scope!("NoteFreshness::update Ndb::query");
- ndb.query(&txn, &[filter], 1)
- }
- .ok() else {
+ if let Route::Timeline(TimelineKind::Notifications(notif_pk)) = top {
+ if notif_pk == current_pk {
return false;
- };
+ }
+ }
- !res.is_empty()
- });
+ let notif_kind = TimelineKind::Notifications(*current_pk);
+ let Some(tl) = columns.timeline_cache.get_mut(¬if_kind) else {
+ return false;
+ };
- freshness.has_unseen()
+ !tl.seen_latest_notes
}
/// When you click the toolbar button, these actions