Merge thread scroll fix by kernel

kernelkind (5):
      TMP: use new egui-nav to fix scroll offset issues
      add `scroll_offset` to `NoteAction::Note`
      add `ThreadNote::set_scroll_offset`
      set scroll offset when routing to thread
      appease clippy
This commit is contained in:
William Casarin
2025-08-04 15:08:09 -07:00
7 changed files with 49 additions and 12 deletions

2
Cargo.lock generated
View File

@@ -1554,7 +1554,7 @@ dependencies = [
[[package]] [[package]]
name = "egui_nav" name = "egui_nav"
version = "0.2.0" version = "0.2.0"
source = "git+https://github.com/damus-io/egui-nav?rev=3c67eb6298edbff36d46546897cfac33df4f04db#3c67eb6298edbff36d46546897cfac33df4f04db" source = "git+https://github.com/damus-io/egui-nav?rev=de6e2d51892478fdd516df166f866e64dedbae07#de6e2d51892478fdd516df166f866e64dedbae07"
dependencies = [ dependencies = [
"egui", "egui",
"egui_extras", "egui_extras",

View File

@@ -26,7 +26,7 @@ egui = { version = "0.31.1", features = ["serde"] }
egui-wgpu = "0.31.1" egui-wgpu = "0.31.1"
egui_extras = { version = "0.31.1", features = ["all_loaders"] } egui_extras = { version = "0.31.1", features = ["all_loaders"] }
egui-winit = { version = "0.31.1", features = ["android-game-activity", "clipboard"] } egui-winit = { version = "0.31.1", features = ["android-game-activity", "clipboard"] }
egui_nav = { git = "https://github.com/damus-io/egui-nav", rev = "3c67eb6298edbff36d46546897cfac33df4f04db" } egui_nav = { git = "https://github.com/damus-io/egui-nav", rev = "de6e2d51892478fdd516df166f866e64dedbae07" }
egui_tabs = { git = "https://github.com/damus-io/egui-tabs", rev = "6eb91740577b374a8a6658c09c9a4181299734d0" } egui_tabs = { git = "https://github.com/damus-io/egui-tabs", rev = "6eb91740577b374a8a6658c09c9a4181299734d0" }
#egui_virtual_list = "0.6.0" #egui_virtual_list = "0.6.0"
egui_virtual_list = { git = "https://github.com/jb55/hello_egui", rev = "a66b6794f5e707a2f4109633770e02b02fb722e1" } egui_virtual_list = { git = "https://github.com/jb55/hello_egui", rev = "a66b6794f5e707a2f4109633770e02b02fb722e1" }

View File

@@ -24,7 +24,11 @@ pub enum NoteAction {
Profile(Pubkey), Profile(Pubkey),
/// User has clicked a note link /// User has clicked a note link
Note { note_id: NoteId, preview: bool }, Note {
note_id: NoteId,
preview: bool,
scroll_offset: f32,
},
/// User has selected some context option /// User has selected some context option
Context(ContextSelection), Context(ContextSelection),
@@ -44,6 +48,7 @@ impl NoteAction {
NoteAction::Note { NoteAction::Note {
note_id: id, note_id: id,
preview: false, preview: false,
scroll_offset: 0.0,
} }
} }
} }

View File

@@ -81,7 +81,11 @@ fn execute_note_action(
.open(ndb, note_cache, txn, pool, &kind) .open(ndb, note_cache, txn, pool, &kind)
.map(NotesOpenResult::Timeline); .map(NotesOpenResult::Timeline);
} }
NoteAction::Note { note_id, preview } => 'ex: { NoteAction::Note {
note_id,
preview,
scroll_offset,
} => 'ex: {
let Ok(thread_selection) = ThreadSelection::from_note_id(ndb, note_cache, txn, note_id) let Ok(thread_selection) = ThreadSelection::from_note_id(ndb, note_cache, txn, note_id)
else { else {
tracing::error!("No thread selection for {}?", hex::encode(note_id.bytes())); tracing::error!("No thread selection for {}?", hex::encode(note_id.bytes()));
@@ -89,7 +93,15 @@ fn execute_note_action(
}; };
timeline_res = threads timeline_res = threads
.open(ndb, txn, pool, &thread_selection, preview, col) .open(
ndb,
txn,
pool,
&thread_selection,
preview,
col,
scroll_offset,
)
.map(NotesOpenResult::Thread); .map(NotesOpenResult::Thread);
let route = Route::Thread(thread_selection); let route = Route::Thread(thread_selection);

View File

@@ -23,6 +23,7 @@ pub struct ThreadNode {
pub prev: ParentState, pub prev: ParentState,
pub have_all_ancestors: bool, pub have_all_ancestors: bool,
pub list: VirtualList, pub list: VirtualList,
pub set_scroll_offset: Option<f32>,
} }
#[derive(Clone)] #[derive(Clone)]
@@ -132,8 +133,14 @@ impl ThreadNode {
prev: parent, prev: parent,
have_all_ancestors: false, have_all_ancestors: false,
list: VirtualList::new(), list: VirtualList::new(),
set_scroll_offset: None,
} }
} }
pub fn with_offset(mut self, offset: f32) -> Self {
self.set_scroll_offset = Some(offset);
self
}
} }
#[derive(Default)] #[derive(Default)]
@@ -147,6 +154,7 @@ pub struct Threads {
impl Threads { impl Threads {
/// Opening a thread. /// Opening a thread.
/// Similar to [[super::cache::TimelineCache::open]] /// Similar to [[super::cache::TimelineCache::open]]
#[allow(clippy::too_many_arguments)]
pub fn open( pub fn open(
&mut self, &mut self,
ndb: &mut Ndb, ndb: &mut Ndb,
@@ -155,6 +163,7 @@ impl Threads {
thread: &ThreadSelection, thread: &ThreadSelection,
new_scope: bool, new_scope: bool,
col: usize, col: usize,
scroll_offset: f32,
) -> Option<NewThreadNotes> { ) -> Option<NewThreadNotes> {
tracing::info!("Opening thread: {:?}", thread); tracing::info!("Opening thread: {:?}", thread);
let local_sub_filter = if let Some(selected) = &thread.selected_note { let local_sub_filter = if let Some(selected) = &thread.selected_note {
@@ -184,7 +193,7 @@ impl Threads {
RawEntryMut::Vacant(entry) => { RawEntryMut::Vacant(entry) => {
let id = NoteId::new(*selected_note_id); let id = NoteId::new(*selected_note_id);
let node = ThreadNode::new(ParentState::Unknown); let node = ThreadNode::new(ParentState::Unknown).with_offset(scroll_offset);
entry.insert(id, node); entry.insert(id, node);
&local_sub_filter &local_sub_filter

View File

@@ -52,17 +52,26 @@ impl<'a, 'd> ThreadView<'a, 'd> {
.auto_shrink([false, false]) .auto_shrink([false, false])
.scroll_bar_visibility(egui::scroll_area::ScrollBarVisibility::AlwaysVisible); .scroll_bar_visibility(egui::scroll_area::ScrollBarVisibility::AlwaysVisible);
let offset_id = scroll_id.with(("scroll_offset", self.selected_note_id)); if let Some(thread) = self.threads.threads.get_mut(&self.selected_note_id) {
if let Some(new_offset) = thread.set_scroll_offset.take() {
if let Some(offset) = ui.data(|i| i.get_temp::<f32>(offset_id)) { scroll_area = scroll_area.vertical_scroll_offset(new_offset);
scroll_area = scroll_area.vertical_scroll_offset(offset); }
} }
let output = scroll_area.show(ui, |ui| self.notes(ui, &txn)); let output = scroll_area.show(ui, |ui| self.notes(ui, &txn));
ui.data_mut(|d| d.insert_temp(offset_id, output.state.offset.y)); let mut resp = output.inner;
output.inner if let Some(NoteAction::Note {
note_id: _,
preview: _,
scroll_offset,
}) = &mut resp
{
*scroll_offset = output.state.offset.y;
}
resp
} }
fn notes(&mut self, ui: &mut egui::Ui, txn: &Transaction) -> Option<NoteAction> { fn notes(&mut self, ui: &mut egui::Ui, txn: &Transaction) -> Option<NoteAction> {
@@ -195,6 +204,7 @@ fn strip_note_action(action: NoteAction) -> Option<NoteAction> {
NoteAction::Note { NoteAction::Note {
note_id: _, note_id: _,
preview: false, preview: false,
scroll_offset: _,
} }
) { ) {
return None; return None;

View File

@@ -363,6 +363,7 @@ fn render_undecorated_note_contents<'a>(
NoteAction::Note { note_id, .. } => NoteAction::Note { NoteAction::Note { note_id, .. } => NoteAction::Note {
note_id, note_id,
preview: true, preview: true,
scroll_offset: 0.0,
}, },
other => other, other => other,
}) })