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