notedeck

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

commit a8185d9a75ce1c7b5033e4e8ec93d48b02e59867
parent 6f2aa56b9eaa7710695b0ccb87e8871e036988dd
Author: William Casarin <jb55@jb55.com>
Date:   Sun, 14 Apr 2024 16:50:51 -0700

note: don't allow nested note previews

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

Diffstat:
Msrc/ui/note/contents.rs | 25+++++++++++++++++++++----
Msrc/ui/note/mod.rs | 54+++++++++++++++++++++++++++++-------------------------
Asrc/ui/note/options.rs | 41+++++++++++++++++++++++++++++++++++++++++
3 files changed, 91 insertions(+), 29 deletions(-)

diff --git a/src/ui/note/contents.rs b/src/ui/note/contents.rs @@ -1,3 +1,4 @@ +use crate::ui::note::NoteOptions; use crate::{colors, ui, Damus}; use egui::{Color32, Hyperlink, Image, RichText}; use nostrdb::{BlockType, Mention, Note, NoteKey, Transaction}; @@ -8,6 +9,7 @@ pub struct NoteContents<'a> { txn: &'a Transaction, note: &'a Note<'a>, note_key: NoteKey, + options: NoteOptions, } impl<'a> NoteContents<'a> { @@ -16,19 +18,29 @@ impl<'a> NoteContents<'a> { txn: &'a Transaction, note: &'a Note, note_key: NoteKey, + options: ui::note::NoteOptions, ) -> Self { NoteContents { damus, txn, note, note_key, + options, } } } impl egui::Widget for NoteContents<'_> { fn ui(self, ui: &mut egui::Ui) -> egui::Response { - render_note_contents(ui, self.damus, self.txn, self.note, self.note_key).response + render_note_contents( + ui, + self.damus, + self.txn, + self.note, + self.note_key, + self.options, + ) + .response } } @@ -62,7 +74,11 @@ fn render_note_preview( */ }; - ui.add(ui::Note::new(app, &note).actionbar(false)) + ui.add( + ui::Note::new(app, &note) + .actionbar(false) + .note_previews(false), + ) } fn render_note_contents( @@ -71,6 +87,7 @@ fn render_note_contents( txn: &Transaction, note: &Note, note_key: NoteKey, + options: NoteOptions, ) -> egui::InnerResponse<()> { #[cfg(feature = "profiling")] puffin::profile_function!(); @@ -105,11 +122,11 @@ fn render_note_contents( } } - Mention::Note(note) => { + Mention::Note(note) if options.has_note_previews() => { inline_note = Some((note.id(), block.as_str())); } - Mention::Event(note) => { + Mention::Event(note) if options.has_note_previews() => { inline_note = Some((note.id(), block.as_str())); } diff --git a/src/ui/note/mod.rs b/src/ui/note/mod.rs @@ -1,24 +1,16 @@ pub mod contents; +pub mod options; + pub use contents::NoteContents; +pub use options::NoteOptions; use crate::{ui, Damus}; -use bitflags::bitflags; use egui::{Color32, Label, RichText, Sense, TextureHandle, Vec2}; -bitflags! { - // Attributes can be applied to flags types - #[repr(transparent)] - #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] - pub struct NoteFlags: u32 { - const actionbar = 0b00000001; - const note_previews = 0b00000010; - } -} - pub struct Note<'a> { app: &'a mut Damus, note: &'a nostrdb::Note<'a>, - flags: NoteFlags, + flags: NoteOptions, } impl<'a> egui::Widget for Note<'a> { @@ -33,24 +25,28 @@ impl<'a> egui::Widget for Note<'a> { impl<'a> Note<'a> { pub fn new(app: &'a mut Damus, note: &'a nostrdb::Note<'a>) -> Self { - let flags = NoteFlags::actionbar; + let flags = NoteOptions::actionbar | NoteOptions::note_previews; Note { app, note, flags } } - #[inline] - pub fn has_actionbar(&self) -> bool { - (self.flags & NoteFlags::actionbar) == NoteFlags::actionbar + pub fn actionbar(mut self, enable: bool) -> Self { + self.options_mut().set_actionbar(enable); + self } - pub fn actionbar(mut self, enable: bool) -> Self { - if enable { - self.flags = self.flags | NoteFlags::actionbar; - } else { - self.flags = self.flags & !NoteFlags::actionbar; - } + pub fn note_previews(mut self, enable: bool) -> Self { + self.options_mut().set_note_previews(enable); self } + pub fn options(&self) -> NoteOptions { + self.flags + } + + pub fn options_mut(&mut self) -> &mut NoteOptions { + &mut self.flags + } + fn textmode_ui(self, ui: &mut egui::Ui) -> egui::Response { let note_key = self.note.key().expect("todo: implement non-db notes"); let txn = self.note.txn().expect("todo: implement non-db notes"); @@ -80,7 +76,9 @@ impl<'a> Note<'a> { ) }); - ui.add(NoteContents::new(self.app, txn, self.note, note_key)); + ui.add(NoteContents::new( + self.app, txn, self.note, note_key, self.flags, + )); }); }) .response @@ -130,9 +128,15 @@ impl<'a> Note<'a> { render_reltime(ui, note_cache, true); }); - ui.add(NoteContents::new(self.app, txn, self.note, note_key)); + ui.add(NoteContents::new( + self.app, + txn, + self.note, + note_key, + self.options(), + )); - if self.has_actionbar() { + if self.options().has_actionbar() { render_note_actionbar(ui); } diff --git a/src/ui/note/options.rs b/src/ui/note/options.rs @@ -0,0 +1,41 @@ +use bitflags::bitflags; + +bitflags! { + // Attributes can be applied to flags types + #[repr(transparent)] + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub struct NoteOptions: u32 { + const actionbar = 0b00000001; + const note_previews = 0b00000010; + } +} + +impl NoteOptions { + #[inline] + pub fn has_actionbar(self) -> bool { + (self & NoteOptions::actionbar) == NoteOptions::actionbar + } + + #[inline] + pub fn has_note_previews(self) -> bool { + (self & NoteOptions::note_previews) == NoteOptions::note_previews + } + + #[inline] + pub fn set_note_previews(&mut self, enable: bool) { + if enable { + *self = *self | NoteOptions::note_previews; + } else { + *self = *self & !NoteOptions::note_previews; + } + } + + #[inline] + pub fn set_actionbar(&mut self, enable: bool) { + if enable { + *self = *self | NoteOptions::actionbar; + } else { + *self = *self & !NoteOptions::actionbar; + } + } +}