action.rs (4161B)
1 use crate::{Images, MediaCacheType, TexturedImage}; 2 use poll_promise::Promise; 3 4 /// Tracks where media was on the screen so that 5 /// we can do fun animations when opening the 6 /// Media Viewer 7 #[derive(Debug, Clone)] 8 pub struct MediaInfo { 9 /// The original screen position where it 10 /// was rendered from. This is not where 11 /// it should be rendered in the scene. 12 pub original_position: egui::Rect, 13 pub url: String, 14 } 15 16 /// Contains various information for when a user 17 /// clicks a piece of media. It contains the current 18 /// location on screen for each piece of media. 19 /// 20 /// Viewers can use this to smoothly transition from 21 /// the timeline to the viewer 22 #[derive(Debug, Clone, Default)] 23 pub struct ViewMediaInfo { 24 pub clicked_index: usize, 25 pub medias: Vec<MediaInfo>, 26 } 27 28 impl ViewMediaInfo { 29 pub fn clicked_media(&self) -> &MediaInfo { 30 &self.medias[self.clicked_index] 31 } 32 } 33 34 /// Actions generated by media ui interactions 35 pub enum MediaAction { 36 /// An image was clicked on in a carousel, we have 37 /// the opportunity to open into a fullscreen media viewer 38 /// with a list of url values 39 ViewMedias(ViewMediaInfo), 40 41 FetchImage { 42 url: String, 43 cache_type: MediaCacheType, 44 no_pfp_promise: Promise<Option<Result<TexturedImage, crate::Error>>>, 45 }, 46 DoneLoading { 47 url: String, 48 cache_type: MediaCacheType, 49 }, 50 } 51 52 impl std::fmt::Debug for MediaAction { 53 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 54 match self { 55 Self::ViewMedias(ViewMediaInfo { 56 clicked_index, 57 medias, 58 }) => f 59 .debug_struct("ViewMedias") 60 .field("clicked_index", clicked_index) 61 .field("media", medias) 62 .finish(), 63 Self::FetchImage { 64 url, 65 cache_type, 66 no_pfp_promise, 67 } => f 68 .debug_struct("FetchNoPfpImage") 69 .field("url", url) 70 .field("cache_type", cache_type) 71 .field("no_pfp_promise ready", &no_pfp_promise.ready().is_some()) 72 .finish(), 73 Self::DoneLoading { url, cache_type } => f 74 .debug_struct("DoneLoading") 75 .field("url", url) 76 .field("cache_type", cache_type) 77 .finish(), 78 } 79 } 80 } 81 82 impl MediaAction { 83 /// Handle view media actions 84 pub fn on_view_media(&self, handler: impl FnOnce(&ViewMediaInfo)) { 85 if let MediaAction::ViewMedias(view_medias) = self { 86 handler(view_medias) 87 } 88 } 89 90 /// Default processing logic for Media Actions. We don't handle ViewMedias here since 91 /// this may be app specific ? 92 pub fn process_default_media_actions(self, images: &mut Images) { 93 match self { 94 MediaAction::ViewMedias(_urls) => { 95 // NOTE(jb55): don't assume we want to show a fullscreen 96 // media viewer we can use on_view_media for that. We 97 // also don't want to have a notedeck_ui dependency in 98 // the notedeck lib (MediaViewerState) 99 // 100 // In general our notedeck crate should be pretty 101 // agnostic to functionallity in general unless it low 102 // level like image rendering. 103 // 104 //mview_state.set_urls(urls); 105 } 106 107 MediaAction::FetchImage { 108 url, 109 cache_type, 110 no_pfp_promise: promise, 111 } => { 112 images 113 .get_cache_mut(cache_type) 114 .textures_cache 115 .insert_pending(&url, promise); 116 } 117 MediaAction::DoneLoading { url, cache_type } => { 118 let cache = match cache_type { 119 MediaCacheType::Image => &mut images.static_imgs, 120 MediaCacheType::Gif => &mut images.gifs, 121 }; 122 123 cache.textures_cache.move_to_loaded(&url); 124 } 125 } 126 } 127 }