diff --git a/src/settings.rs b/src/settings.rs index 0b199707..343306d1 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -23,6 +23,7 @@ pub const DEFAULT_SET_USER_AGENT: bool = false; pub const DEFAULT_OVERRIDE_DPI: Option = None; pub const DEFAULT_REACTIONS: bool = true; pub const DEFAULT_REPOSTS: bool = true; +pub const DEFAULT_SHOW_FIRST_MENTION: bool = true; pub const DEFAULT_LOAD_AVATARS: bool = true; pub const DEFAULT_CHECK_NIP05: bool = true; pub const DEFAULT_DIRECT_MESSAGES: bool = true; @@ -47,6 +48,7 @@ pub struct Settings { pub override_dpi: Option, pub reactions: bool, pub reposts: bool, + pub show_first_mention: bool, pub load_avatars: bool, pub check_nip05: bool, pub direct_messages: bool, @@ -74,6 +76,7 @@ impl Default for Settings { override_dpi: DEFAULT_OVERRIDE_DPI, reactions: DEFAULT_REACTIONS, reposts: DEFAULT_REPOSTS, + show_first_mention: DEFAULT_SHOW_FIRST_MENTION, load_avatars: DEFAULT_LOAD_AVATARS, check_nip05: DEFAULT_CHECK_NIP05, direct_messages: DEFAULT_DIRECT_MESSAGES, @@ -154,6 +157,7 @@ impl Settings { } "reactions" => settings.reactions = numstr_to_bool(row.1), "reposts" => settings.reposts = numstr_to_bool(row.1), + "show_first_mention" => settings.show_first_mention = numstr_to_bool(row.1), "load_avatars" => settings.load_avatars = numstr_to_bool(row.1), "check_nip05" => settings.check_nip05 = numstr_to_bool(row.1), "direct_messages" => settings.direct_messages = numstr_to_bool(row.1), @@ -199,6 +203,7 @@ impl Settings { ('set_user_agent', ?),\ ('reactions', ?),\ ('reposts', ?),\ + ('show_first_mention', ?),\ ('load_avatars', ?),\ ('check_nip05', ?),\ ('direct_messages', ?),\ @@ -222,6 +227,7 @@ impl Settings { bool_to_numstr(self.set_user_agent), bool_to_numstr(self.reactions), bool_to_numstr(self.reposts), + bool_to_numstr(self.show_first_mention), bool_to_numstr(self.load_avatars), bool_to_numstr(self.check_nip05), bool_to_numstr(self.direct_messages), diff --git a/src/ui/feed/note/content.rs b/src/ui/feed/note/content.rs index ad0905ab..9cd5b509 100644 --- a/src/ui/feed/note/content.rs +++ b/src/ui/feed/note/content.rs @@ -1,13 +1,14 @@ use super::{GossipUi, Page}; use crate::feed::FeedKind; use crate::globals::GLOBALS; -use eframe::egui; +use eframe::egui::{self, Context}; use egui::{RichText, Ui}; use linkify::{LinkFinder, LinkKind}; use nostr_types::{Event, IdHex, Tag}; pub(super) fn render_content( app: &mut GossipUi, + ctx: &Context, ui: &mut Ui, tag_re: ®ex::Regex, event: &Event, @@ -40,14 +41,27 @@ pub(super) fn render_content( }; } Tag::Event { id, .. } => { - let idhex: IdHex = (*id).into(); - let nam = format!("#{}", GossipUi::hex_id_short(&idhex)); - if ui.link(&nam).clicked() { - app.set_page(Page::Feed(FeedKind::Thread { - id: *id, - referenced_by: event.id, - })); - }; + let mut render_as_link = true; + if app.settings.show_first_mention && pos == 0 { + // try to find the mentioned note in our cache + let maybe_event = GLOBALS.events.get(id); + if let Some(event) = maybe_event { + if let Some(note_data) = super::NoteData::new(event) { + super::render_repost(app, ui, ctx, note_data); + render_as_link = false; + } + } + } + if render_as_link { + let idhex: IdHex = (*id).into(); + let nam = format!("#{}", GossipUi::hex_id_short(&idhex)); + if ui.link(&nam).clicked() { + app.set_page(Page::Feed(FeedKind::Thread { + id: *id, + referenced_by: event.id, + })); + }; + } } Tag::Hashtag(s) => { if ui.link(format!("#{}", s)).clicked() { diff --git a/src/ui/feed/note/mod.rs b/src/ui/feed/note/mod.rs index fdbfdd3e..dafcc76a 100644 --- a/src/ui/feed/note/mod.rs +++ b/src/ui/feed/note/mod.rs @@ -17,7 +17,7 @@ use std::sync::atomic::Ordering; mod content; -struct NoteData { +pub(super) struct NoteData { event: Event, delegation: EventDelegation, author: DbPerson, @@ -414,14 +414,7 @@ fn render_note_inner( } else if event.kind == EventKind::Repost { if let Ok(inner_event) = serde_json::from_str::(&content) { if let Some(inner_note_data) = NoteData::new(inner_event) { - ui.vertical(|ui| { - thin_repost_separator(ui); - ui.add_space(4.0); - ui.horizontal_wrapped(|ui| { - render_note_inner(app, ctx, ui, inner_note_data, false, false); - }); - thin_repost_separator(ui); - }); + render_repost(app, ui, ctx, inner_note_data); } else { ui.label("REPOSTED EVENT IS NOT RELEVANT"); } @@ -429,6 +422,7 @@ fn render_note_inner( // render like a kind-1 event with a mention content::render_content( app, + ctx, ui, &tag_re, &event, @@ -437,7 +431,15 @@ fn render_note_inner( ); } } else { - content::render_content(app, ui, &tag_re, &event, deletion.is_some(), &content); + content::render_content( + app, + ctx, + ui, + &tag_re, + &event, + deletion.is_some(), + &content, + ); } }); @@ -574,3 +576,15 @@ fn thin_separator(ui: &mut Ui, stroke: Stroke) { ui.add(Separator::default().spacing(0.0)); ui.reset_style(); } + +pub(super) fn render_repost(app: &mut GossipUi, ui: &mut Ui, ctx: &Context, repost_data: NoteData) { + ui.vertical(|ui| { + thin_repost_separator(ui); + ui.add_space(4.0); + ui.horizontal_wrapped(|ui| { + // FIXME: don't do this recursively + render_note_inner(app, ctx, ui, repost_data, false, false); + }); + thin_repost_separator(ui); + }); +} diff --git a/src/ui/settings.rs b/src/ui/settings.rs index 121d4530..eaeb7cfc 100644 --- a/src/ui/settings.rs +++ b/src/ui/settings.rs @@ -99,6 +99,11 @@ pub(super) fn update(app: &mut GossipUi, ctx: &Context, _frame: &mut eframe::Fra "Enable reposts (show)", ); + ui.checkbox( + &mut app.settings.show_first_mention, + "Enable first mention (show)", + ); + ui.checkbox( &mut app.settings.direct_messages, "Show Direct Messages",