notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

commit cb7dadee44cc3423bdef373ae0324c87ef504fc7
parent 74f63f49caceccaf2983026166675d3f0ec71fe4
Author: William Casarin <jb55@jb55.com>
Date:   Tue,  4 Nov 2025 14:41:25 -0800

ui: note metadata stats

Signed-off-by: William Casarin <jb55@jb55.com>

Diffstat:
Mcrates/notedeck_ui/src/note/mod.rs | 87++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 75 insertions(+), 12 deletions(-)

diff --git a/crates/notedeck_ui/src/note/mod.rs b/crates/notedeck_ui/src/note/mod.rs @@ -452,15 +452,30 @@ impl<'a, 'd> NoteView<'a, 'd> { // question: WTF? question 2: WHY? ui.allocate_space(egui::vec2(0.0, 0.0)); + let counts = self + .note_context + .ndb + .get_note_metadata(txn, self.note.id()) + .ok() + .and_then(|md| { + md.into_iter().find_map(|e| { + if let nostrdb::NoteMetadataEntryVariant::Counts(ce) = e { + Some(ce) + } else { + None + } + }) + }); + render_note_actionbar( ui, + counts, get_zapper( self.note_context.accounts, self.note_context.global_wallet, self.note_context.zaps, ), - self.note.id(), - self.note.pubkey(), + self.note, self.note_context.accounts.selected_account_pubkey(), note_key, self.note_context.i18n, @@ -539,17 +554,32 @@ impl<'a, 'd> NoteView<'a, 'd> { note_action = contents.action.or(note_action); if self.options().contains(NoteOptions::ActionBar) { + let counts = self + .note_context + .ndb + .get_note_metadata(txn, self.note.id()) + .ok() + .and_then(|md| { + md.into_iter().find_map(|e| { + if let nostrdb::NoteMetadataEntryVariant::Counts(ce) = e { + Some(ce) + } else { + None + } + }) + }); + note_action = ui .horizontal_wrapped(|ui| { render_note_actionbar( ui, + counts, get_zapper( self.note_context.accounts, self.note_context.global_wallet, self.note_context.zaps, ), - self.note.id(), - self.note.pubkey(), + self.note, self.note_context.accounts.selected_account_pubkey(), note_key, self.note_context.i18n, @@ -862,48 +892,81 @@ fn is_root_note(note: &Note) -> bool { #[profiling::function] fn render_note_actionbar( ui: &mut egui::Ui, + counts: Option<nostrdb::CountsEntry<'_>>, zapper: Option<Zapper<'_>>, - note_id: &[u8; 32], - note_pubkey: &[u8; 32], + note: &Note, current_user_pubkey: &Pubkey, note_key: NoteKey, i18n: &mut Localization, ) -> Option<NoteAction> { let mut action = None; + let spacing = 24.0; + ui.spacing_mut().item_spacing.x = 2.0; ui.set_min_height(26.0); - ui.spacing_mut().item_spacing.x = 24.0; let reply_resp = reply_button(ui, i18n, note_key).on_hover_cursor(egui::CursorIcon::PointingHand); + if let Some(c) = &counts { + let count = if is_root_note(note) { + c.thread_replies() + } else { + c.direct_replies() as u32 + }; + + if count > 0 { + ui.weak(format!("{}", count)); + } + } + + ui.add_space(spacing); + let filled = ui .ctx() - .data(|d| d.get_temp(reaction_sent_id(current_user_pubkey, note_id))) + .data(|d| d.get_temp(reaction_sent_id(current_user_pubkey, note.id()))) == Some(true); let like_resp = like_button(ui, i18n, note_key, filled).on_hover_cursor(egui::CursorIcon::PointingHand); + if let Some(c) = &counts { + let count = c.reactions(); + if count > 0 { + ui.weak(format!("{}", count)); + } + } + + ui.add_space(spacing); + let quote_resp = quote_repost_button(ui, i18n, note_key).on_hover_cursor(egui::CursorIcon::PointingHand); + if let Some(c) = &counts { + let count = c.quotes() + c.reposts(); + if count > 0 { + ui.weak(format!("{}", count)); + } + } + + ui.add_space(spacing); + if reply_resp.clicked() { - action = Some(NoteAction::Reply(NoteId::new(*note_id))); + action = Some(NoteAction::Reply(NoteId::new(*note.id()))); } if like_resp.clicked() { action = Some(NoteAction::React(ReactAction::new( - NoteId::new(*note_id), + NoteId::new(*note.id()), "🤙🏻", ))); } if quote_resp.clicked() { - action = Some(NoteAction::Repost(NoteId::new(*note_id))); + action = Some(NoteAction::Repost(NoteId::new(*note.id()))); } - action = zap_actionbar_button(ui, note_id, note_pubkey, zapper, i18n).or(action); + action = zap_actionbar_button(ui, note.id(), note.pubkey(), zapper, i18n).or(action); action }