Flexible routing

Another massive refactor to change the way routing works. Now any
column can route anywhere.

Also things are generally just much better and more modular via the
new struct split borrowing technique.

I didn't even try to split this into smaller commits for my sanity.

Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
William Casarin
2024-09-11 19:43:41 -07:00
parent b4a8cddc48
commit 36c0971fd9
27 changed files with 973 additions and 963 deletions

View File

@@ -1,55 +1,49 @@
use crate::{
actionbar::BarResult, column::Columns, imgcache::ImageCache, notecache::NoteCache,
thread::Threads, timeline::TimelineSource, ui, unknowns::UnknownIds,
actionbar::BarAction, imgcache::ImageCache, notecache::NoteCache, thread::Threads, ui,
};
use enostr::RelayPool;
use nostrdb::{Ndb, NoteKey, Transaction};
use tracing::{error, warn};
pub struct ThreadView<'a> {
column: usize,
columns: &'a mut Columns,
threads: &'a mut Threads,
ndb: &'a Ndb,
pool: &'a mut RelayPool,
note_cache: &'a mut NoteCache,
img_cache: &'a mut ImageCache,
unknown_ids: &'a mut UnknownIds,
selected_note_id: &'a [u8; 32],
textmode: bool,
id_source: egui::Id,
}
impl<'a> ThreadView<'a> {
#[allow(clippy::too_many_arguments)]
pub fn new(
column: usize,
columns: &'a mut Columns,
threads: &'a mut Threads,
ndb: &'a Ndb,
note_cache: &'a mut NoteCache,
img_cache: &'a mut ImageCache,
unknown_ids: &'a mut UnknownIds,
pool: &'a mut RelayPool,
textmode: bool,
selected_note_id: &'a [u8; 32],
textmode: bool,
) -> Self {
let id_source = egui::Id::new("threadscroll_threadview");
ThreadView {
column,
columns,
threads,
ndb,
note_cache,
img_cache,
textmode,
selected_note_id,
unknown_ids,
pool,
textmode,
id_source,
}
}
pub fn ui(&mut self, ui: &mut egui::Ui) -> Option<BarResult> {
pub fn id_source(mut self, id: egui::Id) -> Self {
self.id_source = id;
self
}
pub fn ui(&mut self, ui: &mut egui::Ui) -> Option<BarAction> {
let txn = Transaction::new(self.ndb).expect("txn");
let mut result: Option<BarResult> = None;
let mut action: Option<BarAction> = None;
let selected_note_key = if let Ok(key) = self
.ndb
@@ -62,21 +56,13 @@ impl<'a> ThreadView<'a> {
return None;
};
let scroll_id = {
egui::Id::new((
"threadscroll",
self.columns.column(self.column).view_id(),
selected_note_key,
))
};
ui.label(
egui::RichText::new("Threads ALPHA! It's not done. Things will be broken.")
.color(egui::Color32::RED),
);
egui::ScrollArea::vertical()
.id_source(scroll_id)
.id_source(self.id_source)
.animated(false)
.auto_shrink([false, false])
.scroll_bar_visibility(egui::scroll_area::ScrollBarVisibility::AlwaysVisible)
@@ -99,36 +85,27 @@ impl<'a> ThreadView<'a> {
.map_or_else(|| self.selected_note_id, |nr| nr.id)
};
let thread = self.threads.thread_mut(self.ndb, &txn, root_id).get_ptr();
// TODO(jb55): skip poll if ThreadResult is fresh?
// poll for new notes and insert them into our existing notes
if let Err(e) = TimelineSource::Thread(root_id).poll_notes_into_view(
&txn,
self.ndb,
self.columns,
self.threads,
self.unknown_ids,
self.note_cache,
) {
if let Err(e) = thread.poll_notes_into_view(&txn, self.ndb) {
error!("Thread::poll_notes_into_view: {e}");
}
let (len, list) = {
let thread = self.threads.thread_mut(self.ndb, &txn, root_id).get_ptr();
let len = thread.view().notes.len();
let len = thread.view.notes.len();
(len, &mut thread.view.list)
};
list.clone()
.borrow_mut()
.ui_custom_layout(ui, len, |ui, start_index| {
thread.view().list.clone().borrow_mut().ui_custom_layout(
ui,
len,
|ui, start_index| {
ui.spacing_mut().item_spacing.y = 0.0;
ui.spacing_mut().item_spacing.x = 4.0;
let ind = len - 1 - start_index;
let note_key = {
let thread = self.threads.thread_mut(self.ndb, &txn, root_id).get_ptr();
thread.view.notes[ind].key
};
let note_key = thread.view().notes[ind].key;
let note = if let Ok(note) = self.ndb.get_note_by_key(&txn, note_key) {
note
@@ -138,25 +115,14 @@ impl<'a> ThreadView<'a> {
};
ui::padding(8.0, ui, |ui| {
let resp =
if let Some(bar_action) =
ui::NoteView::new(self.ndb, self.note_cache, self.img_cache, &note)
.note_previews(!self.textmode)
.textmode(self.textmode)
.show(ui);
if let Some(action) = resp.action {
let br = action.execute(
self.ndb,
self.columns.column_mut(self.column),
self.threads,
self.note_cache,
self.pool,
note.id(),
&txn,
);
if br.is_some() {
result = br;
}
.show(ui)
.action
{
action = Some(bar_action);
}
});
@@ -164,9 +130,10 @@ impl<'a> ThreadView<'a> {
//ui.add(egui::Separator::default().spacing(0.0));
1
});
},
);
});
result
action
}
}