notedeck

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

actionbar.rs (4833B)


      1 use crate::{
      2     column::Columns,
      3     muted::MuteFun,
      4     note::NoteRef,
      5     notecache::NoteCache,
      6     notes_holder::{NotesHolder, NotesHolderStorage},
      7     profile::Profile,
      8     route::{Route, Router},
      9     thread::Thread,
     10 };
     11 use enostr::{NoteId, Pubkey, RelayPool};
     12 use nostrdb::{Ndb, Transaction};
     13 
     14 #[derive(Debug, Eq, PartialEq, Copy, Clone)]
     15 pub enum NoteAction {
     16     Reply(NoteId),
     17     Quote(NoteId),
     18     OpenThread(NoteId),
     19     OpenProfile(Pubkey),
     20 }
     21 
     22 pub struct NewNotes {
     23     pub id: [u8; 32],
     24     pub notes: Vec<NoteRef>,
     25 }
     26 
     27 pub enum NotesHolderResult {
     28     NewNotes(NewNotes),
     29 }
     30 
     31 /// open_thread is called when a note is selected and we need to navigate
     32 /// to a thread It is responsible for managing the subscription and
     33 /// making sure the thread is up to date. In a sense, it's a model for
     34 /// the thread view. We don't have a concept of model/view/controller etc
     35 /// in egui, but this is the closest thing to that.
     36 #[allow(clippy::too_many_arguments)]
     37 fn open_thread(
     38     ndb: &Ndb,
     39     txn: &Transaction,
     40     router: &mut Router<Route>,
     41     note_cache: &mut NoteCache,
     42     pool: &mut RelayPool,
     43     threads: &mut NotesHolderStorage<Thread>,
     44     selected_note: &[u8; 32],
     45     is_muted: &MuteFun,
     46 ) -> Option<NotesHolderResult> {
     47     router.route_to(Route::thread(NoteId::new(selected_note.to_owned())));
     48 
     49     let root_id = crate::note::root_note_id_from_selected_id(ndb, note_cache, txn, selected_note);
     50     Thread::open(ndb, note_cache, txn, pool, threads, root_id, is_muted)
     51 }
     52 
     53 impl NoteAction {
     54     #[allow(clippy::too_many_arguments)]
     55     pub fn execute(
     56         self,
     57         ndb: &Ndb,
     58         router: &mut Router<Route>,
     59         threads: &mut NotesHolderStorage<Thread>,
     60         profiles: &mut NotesHolderStorage<Profile>,
     61         note_cache: &mut NoteCache,
     62         pool: &mut RelayPool,
     63         txn: &Transaction,
     64         is_muted: &MuteFun,
     65     ) -> Option<NotesHolderResult> {
     66         match self {
     67             NoteAction::Reply(note_id) => {
     68                 router.route_to(Route::reply(note_id));
     69                 None
     70             }
     71 
     72             NoteAction::OpenThread(note_id) => open_thread(
     73                 ndb,
     74                 txn,
     75                 router,
     76                 note_cache,
     77                 pool,
     78                 threads,
     79                 note_id.bytes(),
     80                 is_muted,
     81             ),
     82 
     83             NoteAction::OpenProfile(pubkey) => {
     84                 router.route_to(Route::profile(pubkey));
     85                 Profile::open(
     86                     ndb,
     87                     note_cache,
     88                     txn,
     89                     pool,
     90                     profiles,
     91                     pubkey.bytes(),
     92                     is_muted,
     93                 )
     94             }
     95 
     96             NoteAction::Quote(note_id) => {
     97                 router.route_to(Route::quote(note_id));
     98                 None
     99             }
    100         }
    101     }
    102 
    103     /// Execute the NoteAction and process the NotesHolderResult
    104     #[allow(clippy::too_many_arguments)]
    105     pub fn execute_and_process_result(
    106         self,
    107         ndb: &Ndb,
    108         columns: &mut Columns,
    109         col: usize,
    110         threads: &mut NotesHolderStorage<Thread>,
    111         profiles: &mut NotesHolderStorage<Profile>,
    112         note_cache: &mut NoteCache,
    113         pool: &mut RelayPool,
    114         txn: &Transaction,
    115         is_muted: &MuteFun,
    116     ) {
    117         let router = columns.column_mut(col).router_mut();
    118         if let Some(br) = self.execute(
    119             ndb, router, threads, profiles, note_cache, pool, txn, is_muted,
    120         ) {
    121             br.process(ndb, note_cache, txn, threads, is_muted);
    122         }
    123     }
    124 }
    125 
    126 impl NotesHolderResult {
    127     pub fn new_notes(notes: Vec<NoteRef>, id: [u8; 32]) -> Self {
    128         NotesHolderResult::NewNotes(NewNotes::new(notes, id))
    129     }
    130 
    131     pub fn process<N: NotesHolder>(
    132         &self,
    133         ndb: &Ndb,
    134         note_cache: &mut NoteCache,
    135         txn: &Transaction,
    136         storage: &mut NotesHolderStorage<N>,
    137         is_muted: &MuteFun,
    138     ) {
    139         match self {
    140             // update the thread for next render if we have new notes
    141             NotesHolderResult::NewNotes(new_notes) => {
    142                 let holder = storage
    143                     .notes_holder_mutated(ndb, note_cache, txn, &new_notes.id, is_muted)
    144                     .get_ptr();
    145                 new_notes.process(holder);
    146             }
    147         }
    148     }
    149 }
    150 
    151 impl NewNotes {
    152     pub fn new(notes: Vec<NoteRef>, id: [u8; 32]) -> Self {
    153         NewNotes { notes, id }
    154     }
    155 
    156     /// Simple helper for processing a NewThreadNotes result. It simply
    157     /// inserts/merges the notes into the thread cache
    158     pub fn process<N: NotesHolder>(&self, thread: &mut N) {
    159         // threads are chronological, ie reversed from reverse-chronological, the default.
    160         let reversed = true;
    161         thread.get_view().insert(&self.notes, reversed);
    162     }
    163 }