diff --git a/TODO.md b/TODO.md index 86d3ad9..d8d3211 100644 --- a/TODO.md +++ b/TODO.md @@ -1,4 +1,3 @@ -- [Login] Proper key storage - [NDB] Handle PRE's - [UX] Render non-ascii chars with better font - [egui-video] Handle mobile DPI for video player \ No newline at end of file diff --git a/src/route/mod.rs b/src/route/mod.rs index e51b79b..034ed28 100644 --- a/src/route/mod.rs +++ b/src/route/mod.rs @@ -3,7 +3,7 @@ use crate::services::ffmpeg_loader::FfmpegLoader; use crate::widgets::PlaceholderRect; use anyhow::{anyhow, bail}; use egui::load::SizedTexture; -use egui::{Context, Id, Image, ImageSource, TextureHandle, Ui, Vec2}; +use egui::{vec2, Context, Id, Image, ImageSource, TextureHandle, Ui, Vec2}; use egui_video::ffmpeg_rs_raw::Transcoder; use ehttp::Response; use enostr::EventClientMessage; @@ -195,24 +195,24 @@ pub fn image_from_cache<'a>( ui: &Ui, url: &str, size: Option, -) -> Image<'a> { +) -> Option> { + if url.len() == 0 { + return None; + } let cache_key = if let Some(s) = size { format!("{}:{}", url, s) } else { url.to_string() }; - if url.len() == 0 { - return Image::from_bytes(cache_key, LOGO_BYTES); - } if let Some(promise) = img_cache.map().get(&cache_key) { match promise.poll() { - Poll::Ready(Ok(t)) => Image::new(SizedTexture::from_handle(t)), - _ => Image::from_bytes(url.to_string(), LOGO_BYTES), + Poll::Ready(Ok(t)) => Some(Image::new(SizedTexture::from_handle(t))), + _ => None, } } else { let fetch = fetch_img(img_cache, ui.ctx(), url, size); img_cache.map_mut().insert(cache_key.clone(), fetch); - Image::from_bytes(cache_key, LOGO_BYTES) + None } } @@ -229,7 +229,11 @@ fn fetch_img( Promise::spawn_thread("load_from_disk", move || { info!("Loading image from disk: {}", dst_path.display()); match FfmpegLoader::new().load_image(dst_path, size) { - Ok(img) => Ok(ctx.load_texture(&name, img, Default::default())), + Ok(img) => { + ctx.request_repaint(); + ctx.forget_image(&name); + Ok(ctx.load_texture(&name, img, Default::default())) + } Err(e) => Err(notedeck::Error::Generic(e.to_string())), } }) @@ -248,6 +252,7 @@ fn fetch_img( match FfmpegLoader::new().load_image(dst_path, size) { Ok(img) => { ctx.request_repaint(); + ctx.forget_image(&name); Ok(ctx.load_texture(&name, img, Default::default())) } Err(e) => Err(notedeck::Error::Generic(e.to_string())), diff --git a/src/route/profile.rs b/src/route/profile.rs index 19a1dfa..81aa88e 100644 --- a/src/route/profile.rs +++ b/src/route/profile.rs @@ -35,14 +35,16 @@ impl NostrWidget for ProfilePage { ui.spacing_mut().item_spacing.y = 8.0; if let Some(banner) = profile.map(|p| p.banner()).flatten() { - image_from_cache( + if let Some(img) = image_from_cache( &mut services.ctx.img_cache, ui, banner, Some(vec2(ui.available_width(), 360.0)), - ) - .rounding(ROUNDING_DEFAULT) - .ui(ui); + ) { + img.rounding(ROUNDING_DEFAULT).ui(ui); + } else { + PlaceholderRect.ui(ui); + } } else { ui.add(PlaceholderRect); } diff --git a/src/widgets/avatar.rs b/src/widgets/avatar.rs index 6b5cd4c..32a805f 100644 --- a/src/widgets/avatar.rs +++ b/src/widgets/avatar.rs @@ -54,8 +54,11 @@ impl Avatar { if !ui.is_rect_visible(ui.cursor()) { return Self::placeholder(ui, size_v); } - match &self.image { - Some(img) => image_from_cache(img_cache, ui, img, Some(size)) + match self + .image + .and_then(|i| image_from_cache(img_cache, ui, &i, Some(size))) + { + Some(img) => img .rounding(Rounding::same(size_v)) .sense(Sense::click()) .ui(ui), diff --git a/src/widgets/header.rs b/src/widgets/header.rs index ef26e90..8edad29 100644 --- a/src/widgets/header.rs +++ b/src/widgets/header.rs @@ -28,7 +28,7 @@ impl Header { Layout::left_to_right(Align::Center), |ui| { ui.style_mut().spacing.item_spacing.x = 16.; - if Image::from_bytes("logo.svg", logo_bytes) + if Image::from_bytes("header_logo.svg", logo_bytes) .max_height(24.) .sense(Sense::click()) .ui(ui) diff --git a/src/widgets/stream_tile.rs b/src/widgets/stream_tile.rs index c65dc94..9347011 100644 --- a/src/widgets/stream_tile.rs +++ b/src/widgets/stream_tile.rs @@ -33,10 +33,12 @@ impl<'a> StreamEvent<'a> { let (response, painter) = ui.allocate_painter(Vec2::new(w, h), Sense::click()); let cover = if ui.is_rect_visible(response.rect) { - self.event.image().map(|p| { - image_from_cache(services.ctx.img_cache, ui, p, Some(Vec2::new(w, h))) - .rounding(ROUNDING_DEFAULT) - }) + self.event + .image() + .and_then(|p| { + image_from_cache(services.ctx.img_cache, ui, p, Some(Vec2::new(w, h))) + }) + .map(|i| i.rounding(ROUNDING_DEFAULT)) } else { None };