diff --git a/crates/notedeck/src/imgcache.rs b/crates/notedeck/src/imgcache.rs index 88e49b0..ab3f5e3 100644 --- a/crates/notedeck/src/imgcache.rs +++ b/crates/notedeck/src/imgcache.rs @@ -89,7 +89,7 @@ impl TexturesCache { entry.replace_entry_with(|_, v| { let TextureStateInternal::Loading(textured) = v else { - return None; + return Some(v); }; Some(TextureStateInternal::Loaded(textured)) diff --git a/crates/notedeck_columns/src/ui/note/post.rs b/crates/notedeck_columns/src/ui/note/post.rs index 8e15ea9..4d6f23c 100644 --- a/crates/notedeck_columns/src/ui/note/post.rs +++ b/crates/notedeck_columns/src/ui/note/post.rs @@ -342,6 +342,13 @@ impl<'a, 'd> PostView<'a, 'd> { } pub fn ui(&mut self, txn: &Transaction, ui: &mut egui::Ui) -> PostResponse { + ScrollArea::vertical() + .id_salt(PostView::scroll_id()) + .show(ui, |ui| self.ui_no_scroll(txn, ui)) + .inner + } + + pub fn ui_no_scroll(&mut self, txn: &Transaction, ui: &mut egui::Ui) -> PostResponse { while let Some(selected_file) = get_next_selected_file() { match selected_file { Ok(selected_media) => { @@ -358,13 +365,6 @@ impl<'a, 'd> PostView<'a, 'd> { } } - ScrollArea::vertical() - .id_salt(PostView::scroll_id()) - .show(ui, |ui| self.ui_no_scroll(txn, ui)) - .inner - } - - pub fn ui_no_scroll(&mut self, txn: &Transaction, ui: &mut egui::Ui) -> PostResponse { let focused = self.focused(ui); let stroke = if focused { ui.visuals().selection.stroke @@ -410,7 +410,7 @@ impl<'a, 'd> PostView<'a, 'd> { self.note_context, txn, id.bytes(), - nostrdb::NoteKey::new(0), + None, self.note_options, self.jobs, ) diff --git a/crates/notedeck_ui/src/note/contents.rs b/crates/notedeck_ui/src/note/contents.rs index 7472bcd..e75ac84 100644 --- a/crates/notedeck_ui/src/note/contents.rs +++ b/crates/notedeck_ui/src/note/contents.rs @@ -4,7 +4,7 @@ use crate::{ secondary_label, }; use egui::{Color32, Hyperlink, Label, RichText}; -use nostrdb::{BlockType, Mention, Note, NoteKey, Transaction}; +use nostrdb::{BlockType, Mention, Note, Transaction}; use notedeck::Localization; use notedeck::{ time_format, update_imeta_blurhashes, IsFollowing, NoteCache, NoteContext, NotedeckTextStyle, @@ -16,6 +16,7 @@ pub struct NoteContents<'a, 'd> { note_context: &'a mut NoteContext<'d>, txn: &'a Transaction, note: &'a Note<'a>, + parent: Option<&'a Note<'a>>, options: NoteOptions, pub action: Option, jobs: &'a mut JobsCache, @@ -27,6 +28,7 @@ impl<'a, 'd> NoteContents<'a, 'd> { note_context: &'a mut NoteContext<'d>, txn: &'a Transaction, note: &'a Note, + parent: Option<&'a Note>, options: NoteOptions, jobs: &'a mut JobsCache, ) -> Self { @@ -34,6 +36,7 @@ impl<'a, 'd> NoteContents<'a, 'd> { note_context, txn, note, + parent, options, action: None, jobs, @@ -48,6 +51,7 @@ impl egui::Widget for &mut NoteContents<'_, '_> { self.note_context, self.txn, self.note, + self.parent, self.options, self.jobs, ); @@ -83,7 +87,7 @@ pub fn render_note_preview( note_context: &mut NoteContext, txn: &Transaction, id: &[u8; 32], - parent: NoteKey, + parent: Option<&Note>, note_options: NoteOptions, jobs: &mut JobsCache, ) -> NoteResponse { @@ -114,10 +118,12 @@ pub fn render_note_preview( */ }; - NoteView::new(note_context, ¬e, note_options, jobs) - .preview_style() - .parent(parent) - .show(ui) + let mut view = NoteView::new(note_context, ¬e, note_options, jobs).preview_style(); + if let Some(parent) = parent { + view = view.parent(parent); + } + + view.show(ui) } /// Render note contents and surrounding info (client name, full date timestamp) @@ -126,10 +132,12 @@ fn render_note_contents( note_context: &mut NoteContext, txn: &Transaction, note: &Note, + parent: Option<&Note>, options: NoteOptions, jobs: &mut JobsCache, ) -> NoteResponse { - let response = render_undecorated_note_contents(ui, note_context, txn, note, options, jobs); + let response = + render_undecorated_note_contents(ui, note_context, txn, note, parent, options, jobs); ui.horizontal_wrapped(|ui| { note_bottom_metadata_ui( @@ -170,6 +178,7 @@ fn render_undecorated_note_contents<'a>( note_context: &mut NoteContext, txn: &Transaction, note: &'a Note, + parent: Option<&'a Note>, options: NoteOptions, jobs: &mut JobsCache, ) -> NoteResponse { @@ -357,7 +366,7 @@ fn render_undecorated_note_contents<'a>( }); let preview_note_action = inline_note.and_then(|(id, _)| { - render_note_preview(ui, note_context, txn, id, note_key, options, jobs) + render_note_preview(ui, note_context, txn, id, Some(note), options, jobs) .action .map(|a| match a { NoteAction::Note { note_id, .. } => NoteAction::Note { @@ -382,12 +391,19 @@ fn render_undecorated_note_contents<'a>( .pubkey .bytes(); - let trusted_media = is_self - || note_context - .accounts - .get_selected_account() - .is_following(note.pubkey()) - == IsFollowing::Yes; + let trusted_media = { + let is_followed = |pk| { + matches!( + note_context + .accounts + .get_selected_account() + .is_following(pk), + IsFollowing::Yes + ) + }; + + is_self || is_followed(note.pubkey()) || parent.is_some_and(|p| is_followed(p.pubkey())) + }; media_action = image_carousel( ui, diff --git a/crates/notedeck_ui/src/note/mod.rs b/crates/notedeck_ui/src/note/mod.rs index 7c85e86..81537dd 100644 --- a/crates/notedeck_ui/src/note/mod.rs +++ b/crates/notedeck_ui/src/note/mod.rs @@ -32,7 +32,7 @@ use notedeck::{ pub struct NoteView<'a, 'd> { note_context: &'a mut NoteContext<'d>, - parent: Option, + parent: Option<&'a Note<'a>>, note: &'a nostrdb::Note<'a>, flags: NoteOptions, jobs: &'a mut JobsCache, @@ -85,7 +85,7 @@ impl<'a, 'd> NoteView<'a, 'd> { flags: NoteOptions, jobs: &'a mut JobsCache, ) -> Self { - let parent: Option = None; + let parent: Option<&Note> = None; Self { note_context, @@ -209,7 +209,7 @@ impl<'a, 'd> NoteView<'a, 'd> { } #[inline] - pub fn parent(mut self, parent: NoteKey) -> Self { + pub fn parent(mut self, parent: &'a Note<'a>) -> Self { self.parent = Some(parent); self } @@ -255,6 +255,7 @@ impl<'a, 'd> NoteView<'a, 'd> { self.note_context, txn, self.note, + self.parent, self.flags, self.jobs, )); @@ -425,8 +426,14 @@ impl<'a, 'd> NoteView<'a, 'd> { }); } - let mut contents = - NoteContents::new(self.note_context, txn, self.note, self.flags, self.jobs); + let mut contents = NoteContents::new( + self.note_context, + txn, + self.note, + self.parent, + self.flags, + self.jobs, + ); ui.add(&mut contents); @@ -519,8 +526,14 @@ impl<'a, 'd> NoteView<'a, 'd> { }); } - let mut contents = - NoteContents::new(self.note_context, txn, self.note, self.flags, self.jobs); + let mut contents = NoteContents::new( + self.note_context, + txn, + self.note, + self.parent, + self.flags, + self.jobs, + ); ui.add(&mut contents); note_action = contents.action.or(note_action); @@ -564,7 +577,12 @@ impl<'a, 'd> NoteView<'a, 'd> { .ndb .get_profile_by_pubkey(txn, self.note.pubkey()); - let hitbox_id = note_hitbox_id(note_key, self.options(), self.parent); + let hitbox_id = note_hitbox_id( + note_key, + self.options(), + self.parent + .map(|n| n.key().expect("todo: support non-db notes")), + ); let maybe_hitbox = maybe_note_hitbox(ui, hitbox_id); // wide design