notedeck

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

commit 5a241d730e3d83f8057e211485edfde2f3c96e54
parent 80982059fc213edca90271d4bd70271d91b768c3
Author: William Casarin <jb55@jb55.com>
Date:   Tue, 17 Dec 2024 11:53:09 -0800

mentions: open profile page when clicking a user mention

Fixes: https://github.com/damus-io/notedeck/issues/588
Changelog-Added: Clicking a mention now opens profile page
Signed-off-by: William Casarin <jb55@jb55.com>

Diffstat:
Mcrates/notedeck_columns/src/ui/mention.rs | 29++++++++++++++++++++++++-----
Mcrates/notedeck_columns/src/ui/note/contents.rs | 27+++++++++++++++++++++------
2 files changed, 45 insertions(+), 11 deletions(-)

diff --git a/crates/notedeck_columns/src/ui/mention.rs b/crates/notedeck_columns/src/ui/mention.rs @@ -1,4 +1,7 @@ +use crate::actionbar::NoteAction; use crate::ui; +use egui::Sense; +use enostr::Pubkey; use nostrdb::{Ndb, Transaction}; use notedeck::ImageCache; @@ -39,10 +42,8 @@ impl<'a> Mention<'a> { self.size = size; self } -} -impl egui::Widget for Mention<'_> { - fn ui(self, ui: &mut egui::Ui) -> egui::Response { + pub fn show(self, ui: &mut egui::Ui) -> egui::InnerResponse<Option<NoteAction>> { mention_ui( self.ndb, self.img_cache, @@ -55,6 +56,12 @@ impl egui::Widget for Mention<'_> { } } +impl egui::Widget for Mention<'_> { + fn ui(self, ui: &mut egui::Ui) -> egui::Response { + self.show(ui).response + } +} + fn mention_ui( ndb: &Ndb, img_cache: &mut ImageCache, @@ -63,7 +70,7 @@ fn mention_ui( ui: &mut egui::Ui, size: f32, selectable: bool, -) -> egui::Response { +) -> egui::InnerResponse<Option<NoteAction>> { #[cfg(feature = "profiling")] puffin::profile_function!(); @@ -81,15 +88,27 @@ fn mention_ui( let resp = ui.add( egui::Label::new(egui::RichText::new(name).color(link_color).size(size)) + .sense(Sense::click()) .selectable(selectable), ); + let note_action = if resp.clicked() { + ui::show_pointer(ui); + Some(NoteAction::OpenProfile(Pubkey::new(*pk))) + } else if resp.hovered() { + ui::show_pointer(ui); + None + } else { + None + }; + if let Some(rec) = profile.as_ref() { resp.on_hover_ui_at_pointer(|ui| { ui.set_max_width(300.0); ui.add(ui::ProfilePreview::new(rec, img_cache)); }); } + + note_action }) - .response } diff --git a/crates/notedeck_columns/src/ui/note/contents.rs b/crates/notedeck_columns/src/ui/note/contents.rs @@ -1,8 +1,10 @@ use crate::actionbar::NoteAction; use crate::images::ImageType; -use crate::ui; -use crate::ui::note::{NoteOptions, NoteResponse}; -use crate::ui::ProfilePic; +use crate::ui::{ + self, + note::{NoteOptions, NoteResponse}, + ProfilePic, +}; use egui::{Color32, Hyperlink, Image, RichText}; use nostrdb::{BlockType, Mention, Ndb, Note, NoteKey, Transaction}; use tracing::warn; @@ -143,6 +145,7 @@ fn render_note_contents( let selectable = options.has_selectable_text(); let mut images: Vec<String> = vec![]; + let mut note_action: Option<NoteAction> = None; let mut inline_note: Option<(&[u8; 32], &str)> = None; let hide_media = options.has_hide_media(); let link_color = ui.visuals().hyperlink_color; @@ -162,11 +165,21 @@ fn render_note_contents( match block.blocktype() { BlockType::MentionBech32 => match block.as_mention().unwrap() { Mention::Profile(profile) => { - ui.add(ui::Mention::new(ndb, img_cache, txn, profile.pubkey())); + let act = ui::Mention::new(ndb, img_cache, txn, profile.pubkey()) + .show(ui) + .inner; + if act.is_some() { + note_action = act; + } } Mention::Pubkey(npub) => { - ui.add(ui::Mention::new(ndb, img_cache, txn, npub.pubkey())); + let act = ui::Mention::new(ndb, img_cache, txn, npub.pubkey()) + .show(ui) + .inner; + if act.is_some() { + note_action = act; + } } Mention::Note(note) if options.has_note_previews() => { @@ -215,7 +228,7 @@ fn render_note_contents( } }); - let note_action = if let Some((id, _block_str)) = inline_note { + let preview_note_action = if let Some((id, _block_str)) = inline_note { render_note_preview(ui, ndb, note_cache, img_cache, txn, id, note_key).action } else { None @@ -228,6 +241,8 @@ fn render_note_contents( ui.add_space(2.0); } + let note_action = preview_note_action.or(note_action); + NoteResponse::new(response.response).with_action(note_action) }