notedeck

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

commit 088704a76863f769ef789fa07005779c6086b47d
parent 10eedc0ca642b3af64a80eba47d6c374fe2716c6
Author: William Casarin <jb55@jb55.com>
Date:   Wed, 23 Jul 2025 09:07:06 -0700

Merge media swipe nav from fernando #1010

Fernando López Guevara (1):
      feat(full-screen-media): add swipe navigation

Diffstat:
Mcrates/notedeck_ui/src/note/media.rs | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 53 insertions(+), 2 deletions(-)

diff --git a/crates/notedeck_ui/src/note/media.rs b/crates/notedeck_ui/src/note/media.rs @@ -235,13 +235,32 @@ fn get_selected_index(ui: &egui::Ui, selection_id: egui::Id) -> usize { /// Checks to see if we have any left/right key presses and updates the carousel index fn update_selected_image_index(ui: &mut egui::Ui, carousel_id: egui::Id, num_urls: i32) -> usize { if num_urls > 1 { - if ui.input(|i| i.key_pressed(egui::Key::ArrowRight) || i.key_pressed(egui::Key::L)) { + let next_image = ui.data(|data| { + data.get_temp(carousel_id.with("next_image")) + .unwrap_or(false) + }); + let prev_image = ui.data(|data| { + data.get_temp(carousel_id.with("prev_image")) + .unwrap_or(false) + }); + + if next_image + || ui.input(|i| i.key_pressed(egui::Key::ArrowRight) || i.key_pressed(egui::Key::L)) + { let ind = select_next_media(ui, carousel_id, num_urls, 1); tracing::debug!("carousel selecting right {}/{}", ind + 1, num_urls); + if next_image { + ui.data_mut(|data| data.remove_temp::<bool>(carousel_id.with("next_image"))); + } ind - } else if ui.input(|i| i.key_pressed(egui::Key::ArrowLeft) || i.key_pressed(egui::Key::H)) { + } else if prev_image + || ui.input(|i| i.key_pressed(egui::Key::ArrowLeft) || i.key_pressed(egui::Key::H)) + { let ind = select_next_media(ui, carousel_id, num_urls, -1); tracing::debug!("carousel selecting left {}/{}", ind + 1, num_urls); + if prev_image { + ui.data_mut(|data| data.remove_temp::<bool>(carousel_id.with("prev_image"))); + } ind } else { get_selected_index(ui, selection_id(carousel_id)) @@ -548,9 +567,20 @@ fn render_full_screen_media( Sense::click_and_drag(), ); + let swipe_accum_id = carousel_id.with("swipe_accum"); + let mut swipe_delta = ui.ctx().memory(|mem| { + mem.data + .get_temp::<egui::Vec2>(swipe_accum_id) + .unwrap_or(egui::Vec2::ZERO) + }); + // Handle pan via drag if response.dragged() { let delta = response.drag_delta(); + swipe_delta += delta; + ui.ctx().memory_mut(|mem| { + mem.data.insert_temp(swipe_accum_id, swipe_delta); + }); pan_offset -= delta; pan_offset.x = pan_offset.x.clamp(-max_pan_x, max_pan_x); pan_offset.y = pan_offset.y.clamp(-max_pan_y, max_pan_y); @@ -568,6 +598,27 @@ fn render_full_screen_media( }); } + let swipe_threshold = 50.0; + if response.drag_stopped() { + if swipe_delta.x.abs() > swipe_threshold && swipe_delta.y.abs() < swipe_threshold { + if swipe_delta.x < 0.0 { + ui.ctx().data_mut(|data| { + keep_popup_open = true; + data.insert_temp(carousel_id.with("next_image"), true); + }); + } else if swipe_delta.x > 0.0 { + ui.ctx().data_mut(|data| { + keep_popup_open = true; + data.insert_temp(carousel_id.with("prev_image"), true); + }); + } + } + + ui.ctx().memory_mut(|mem| { + mem.data.remove::<egui::Vec2>(swipe_accum_id); + }); + } + // bottom bar if num_urls > 1 { let bottom_rect = egui::Rect::from_min_max(