commit 293262d5536b911bc096c619fbb01e8a69361296
parent 4db688f55d8e60573c402281943beb3ceb5ce2a0
Author: William Casarin <jb55@jb55.com>
Date: Fri, 23 Jan 2026 15:23:59 -0800
columns: auto-hide toolbar+header when scrolling
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: William Casarin <jb55@jb55.com>
Diffstat:
4 files changed, 75 insertions(+), 8 deletions(-)
diff --git a/crates/notedeck_columns/src/actionbar.rs b/crates/notedeck_columns/src/actionbar.rs
@@ -69,7 +69,21 @@ fn execute_note_action(
match action {
NoteAction::Scroll(ref scroll_info) => {
- tracing::trace!("timeline scroll {scroll_info:?}")
+ tracing::trace!("timeline scroll {scroll_info:?}");
+
+ // Update toolbar visibility based on scroll velocity
+ let toolbar_visible_id = egui::Id::new("toolbar_visible");
+ let velocity_threshold = 50.0; // pixels per second
+
+ // velocity.y > 0 means scrolling up (content moving down) - show toolbar
+ // velocity.y < 0 means scrolling down (content moving up) - hide toolbar
+ if scroll_info.velocity.y > velocity_threshold {
+ ui.ctx()
+ .data_mut(|d| d.insert_temp(toolbar_visible_id, true));
+ } else if scroll_info.velocity.y < -velocity_threshold {
+ ui.ctx()
+ .data_mut(|d| d.insert_temp(toolbar_visible_id, false));
+ }
}
NoteAction::Reply(note_id) => {
diff --git a/crates/notedeck_columns/src/app.rs b/crates/notedeck_columns/src/app.rs
@@ -632,6 +632,42 @@ fn circle_icon(ui: &mut egui::Ui, openness: f32, response: &egui::Response) {
}
*/
+/// Logic that handles toolbar visibility
+fn toolbar_visibility_height(skb_rect: Option<egui::Rect>, ui: &mut egui::Ui) -> f32 {
+ // Auto-hide toolbar when scrolling down
+ let toolbar_visible_id = egui::Id::new("toolbar_visible");
+
+ // Detect scroll direction using egui input state
+ let scroll_delta = ui.ctx().input(|i| i.smooth_scroll_delta.y);
+ let velocity_threshold = 1.0;
+
+ // Update toolbar visibility based on scroll direction
+ if scroll_delta > velocity_threshold {
+ // Scrolling up (content moving down) - show toolbar
+ ui.ctx()
+ .data_mut(|d| d.insert_temp(toolbar_visible_id, true));
+ } else if scroll_delta < -velocity_threshold {
+ // Scrolling down (content moving up) - hide toolbar
+ ui.ctx()
+ .data_mut(|d| d.insert_temp(toolbar_visible_id, false));
+ }
+
+ let toolbar_visible = ui
+ .ctx()
+ .data(|d| d.get_temp::<bool>(toolbar_visible_id))
+ .unwrap_or(true); // Default to visible
+
+ let toolbar_anim = ui
+ .ctx()
+ .animate_bool_responsive(toolbar_visible_id.with("anim"), toolbar_visible);
+
+ if skb_rect.is_none() {
+ Damus::toolbar_height() * toolbar_anim
+ } else {
+ 0.0
+ }
+}
+
#[profiling::function]
fn render_damus_mobile(
app: &mut Damus,
@@ -648,12 +684,8 @@ fn render_damus_mobile(
ui.ctx().screen_rect(),
notedeck::SoftKeyboardContext::platform(ui.ctx()),
);
- let toolbar_height = if skb_rect.is_none() {
- Damus::toolbar_height()
- } else {
- 0.0
- };
+ let toolbar_height = toolbar_visibility_height(skb_rect, ui);
StripBuilder::new(ui)
.size(Size::remainder()) // top cell
.size(Size::exact(toolbar_height)) // bottom cell
diff --git a/crates/notedeck_columns/src/ui/column/header.rs b/crates/notedeck_columns/src/ui/column/header.rs
@@ -61,9 +61,29 @@ impl<'a> NavTitle<'a> {
}
pub fn show(&mut self, ui: &mut egui::Ui) -> Option<RenderNavAction> {
- notedeck_ui::padding(8.0, ui, |ui| {
+ // On mobile, animate navbar visibility in sync with the toolbar
+ // (toolbar_visible is set in render_damus_mobile based on scroll direction)
+ let toolbar_visible_id = egui::Id::new("toolbar_visible");
+ let toolbar_visible = ui
+ .ctx()
+ .data(|d| d.get_temp::<bool>(toolbar_visible_id))
+ .unwrap_or(true);
+ let navbar_anim = ui
+ .ctx()
+ .animate_bool_responsive(toolbar_visible_id.with("anim"), toolbar_visible);
+
+ // Skip rendering if almost completely hidden
+ if navbar_anim < 0.01 {
+ return None;
+ }
+
+ let base_height = 48.0;
+ let animated_height = base_height * navbar_anim;
+ let animated_padding = 8.0 * navbar_anim;
+
+ notedeck_ui::padding(animated_padding, ui, |ui| {
let mut rect = ui.available_rect_before_wrap();
- rect.set_height(48.0);
+ rect.set_height(animated_height);
let mut child_ui = ui.new_child(
UiBuilder::new()
diff --git a/shell.nix b/shell.nix
@@ -14,6 +14,7 @@ mkShell ({
#cargo-edit
#cargo-watch
rustup
+ gdb
libiconv
pkg-config
cmake