feat(image_carousel): navigate media with arrow left/right keys
This commit is contained in:
@@ -1,12 +1,13 @@
|
||||
use std::{collections::HashMap, path::Path};
|
||||
|
||||
use egui::{
|
||||
Button, Color32, Context, CornerRadius, FontId, Image, Response, Sense, TextureHandle, Window,
|
||||
Button, Color32, Context, CornerRadius, FontId, Image, Response, RichText, Sense,
|
||||
TextureHandle, Window,
|
||||
};
|
||||
use notedeck::{
|
||||
fonts::get_font_size, note::MediaAction, show_one_error_message, supported_mime_hosted_at_url,
|
||||
GifState, GifStateMap, Images, JobPool, MediaCache, MediaCacheType, NotedeckTextStyle,
|
||||
TexturedImage, TexturesCache, UrlMimes,
|
||||
ui::is_narrow, GifState, GifStateMap, Images, JobPool, MediaCache, MediaCacheType,
|
||||
NotedeckTextStyle, TexturedImage, TexturesCache, UrlMimes,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
@@ -29,7 +30,8 @@ pub(crate) fn image_carousel(
|
||||
) -> Option<MediaAction> {
|
||||
// let's make sure everything is within our area
|
||||
|
||||
let height = 360.0;
|
||||
let height = if is_narrow(ui.ctx()) { 90.0 } else { 360.0 };
|
||||
|
||||
let width = ui.available_width();
|
||||
|
||||
let show_popup = ui.ctx().memory(|mem| {
|
||||
@@ -55,8 +57,9 @@ pub(crate) fn image_carousel(
|
||||
};
|
||||
let mut action = None;
|
||||
|
||||
//let has_touch_screen = ui.ctx().input(|i| i.has_touch_screen());
|
||||
let media_urls = &medias.iter().map(|m| m.url.to_string()).collect::<Vec<_>>();
|
||||
|
||||
//let has_touch_screen = ui.ctx().input(|i| i.has_touch_screen());
|
||||
ui.add_sized([width, height], |ui: &mut egui::Ui| {
|
||||
egui::ScrollArea::horizontal()
|
||||
.drag_to_scroll(false)
|
||||
@@ -96,16 +99,13 @@ pub(crate) fn image_carousel(
|
||||
height,
|
||||
carousel_id,
|
||||
) {
|
||||
let cur_action = cur_action.to_media_action(
|
||||
action = cur_action.to_media_action(
|
||||
ui.ctx(),
|
||||
url,
|
||||
media_type,
|
||||
cache,
|
||||
ImageType::Content,
|
||||
);
|
||||
if let Some(cur_action) = cur_action {
|
||||
action = Some(cur_action);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -116,7 +116,14 @@ pub(crate) fn image_carousel(
|
||||
|
||||
if show_popup {
|
||||
if let Some((image_url, cache_type)) = current_image {
|
||||
show_full_screen_media(ui, &image_url, cache_type, img_cache, carousel_id);
|
||||
show_full_screen_media(
|
||||
ui,
|
||||
&media_urls,
|
||||
&image_url,
|
||||
cache_type,
|
||||
img_cache,
|
||||
carousel_id,
|
||||
);
|
||||
}
|
||||
}
|
||||
action
|
||||
@@ -170,6 +177,7 @@ impl MediaUIAction {
|
||||
|
||||
fn show_full_screen_media(
|
||||
ui: &mut egui::Ui,
|
||||
media_urls: &[String],
|
||||
image_url: &str,
|
||||
cache_type: MediaCacheType,
|
||||
img_cache: &mut Images,
|
||||
@@ -196,6 +204,7 @@ fn show_full_screen_media(
|
||||
|
||||
render_full_screen_media(
|
||||
ui,
|
||||
&media_urls,
|
||||
textured_image,
|
||||
cur_state.gifs,
|
||||
image_url,
|
||||
@@ -310,6 +319,7 @@ fn get_obfuscated<'a>(
|
||||
|
||||
fn render_full_screen_media(
|
||||
ui: &mut egui::Ui,
|
||||
media_urls: &[String],
|
||||
renderable_media: &mut TexturedImage,
|
||||
gifs: &mut HashMap<String, GifState>,
|
||||
image_url: &str,
|
||||
@@ -324,6 +334,51 @@ fn render_full_screen_media(
|
||||
});
|
||||
}
|
||||
|
||||
if media_urls.len() > 1 {
|
||||
if ui.input(|i| i.key_pressed(egui::Key::ArrowRight)) {
|
||||
ui.ctx().memory_mut(|mem| {
|
||||
let curr = media_urls.iter().position(|m| m == image_url).unwrap_or(0) as i32;
|
||||
|
||||
let next: i32 = if curr + 1 >= media_urls.len() as i32 {
|
||||
0
|
||||
} else {
|
||||
curr + 1
|
||||
};
|
||||
let next_url = media_urls.get(next as usize).cloned();
|
||||
|
||||
mem.data.insert_temp(
|
||||
carousel_id.with("current_image"),
|
||||
(
|
||||
next_url.unwrap_or_else(|| image_url.to_owned()),
|
||||
MediaCacheType::Image,
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
if ui.input(|i| i.key_pressed(egui::Key::ArrowLeft)) {
|
||||
ui.ctx().memory_mut(|mem| {
|
||||
let curr = media_urls.iter().position(|m| m == image_url).unwrap_or(0) as i32;
|
||||
|
||||
let next: i32 = if curr - 1 < 0 {
|
||||
media_urls.len() as i32 - 1
|
||||
} else {
|
||||
curr - 1
|
||||
};
|
||||
|
||||
let next_url = media_urls.get(next as usize).cloned();
|
||||
|
||||
mem.data.insert_temp(
|
||||
carousel_id.with("current_image"),
|
||||
(
|
||||
next_url.unwrap_or_else(|| image_url.to_owned()),
|
||||
MediaCacheType::Image,
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// background
|
||||
ui.painter()
|
||||
.rect_filled(screen_rect, 0.0, Color32::from_black_alpha(230));
|
||||
@@ -454,6 +509,18 @@ fn render_full_screen_media(
|
||||
});
|
||||
}
|
||||
|
||||
if media_urls.len() > 1 {
|
||||
let color = ui.style().visuals.noninteractive().fg_stroke.color;
|
||||
|
||||
let curr = media_urls.iter().position(|m| m == image_url).unwrap_or(0) + 1;
|
||||
|
||||
let text = format!("{}/{}", curr, media_urls.len());
|
||||
|
||||
println!("Rendering media: {text}");
|
||||
|
||||
ui.label(RichText::new(text).size(10.0).color(color));
|
||||
}
|
||||
|
||||
copy_link(image_url, response);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user