use crate::{ error::{Error, OptionExt}, extensions::{ProfileExt, SubmissionExt}, images::{BannerImage, IconImage, ThumbnailImage}, ActixLoader, }; use hyaenidae_profiles::store::{File, Profile, Submission}; use hyaenidae_toolkit::{IndicatorColor, Thumbnail, Tile}; use i18n_embed_fl::fl; use uuid::Uuid; pub struct OwnedProfileView { pub(crate) profile: Profile, pub(crate) icon: Option, pub(crate) banner: Option, } pub struct ProfileView<'a> { pub(crate) profile: &'a Profile, pub(crate) icon: Option<&'a File>, pub(crate) banner: Option<&'a File>, } pub struct OwnedSubmissionView { pub(crate) submission: Submission, pub(crate) files: Vec, pub(crate) current_file: Option, } pub struct SubmissionView<'a> { pub(crate) author: &'a Profile, pub(crate) submission: &'a Submission, pub(crate) files: Vec<&'a File>, } impl<'a> SubmissionView<'a> { pub(crate) fn thumbnail(&self) -> Option { let file = self.files.get(0)?; let key = file.pictrs_key()?; let image = ThumbnailImage::new(key, &self.submission.title_text()); let thumb = Thumbnail::new(image, &self.submission.view_path()) .title(&self.submission.title_text()) .author(&self.author.name(), &self.author.view_path()); let sensitive_color = if self.submission.is_sensitive() { Some(IndicatorColor::Red) } else { None }; if self.files.len() > 1 { Some(thumb.indicator( &format!("+{}", self.files.len() - 1), sensitive_color.unwrap_or(IndicatorColor::White), )) } else { if let Some(sensitive_color) = sensitive_color { Some(thumb.indicator("", sensitive_color)) } else { Some(thumb) } } } } impl OwnedSubmissionView { pub(crate) fn tiles(&self, loader: &ActixLoader) -> Vec { self.files .iter() .enumerate() .filter_map(|(index, file)| { let key = file.pictrs_key()?; let alt = fl!(loader, "file-num", num = (index + 1)); let tile = Tile::new(IconImage::new(key, &alt)) .link(&self.submission.file_page_link(index)); if self .current_file .map(|f_id| f_id == file.id()) .unwrap_or(false) { Some(tile.indicator("", IndicatorColor::Gray)) } else { Some(tile) } }) .collect() } } impl OwnedProfileView { pub(crate) fn heading(&self, loader: &ActixLoader) -> hyaenidae_toolkit::Profile { ProfileView { profile: &self.profile, icon: self.icon.as_ref(), banner: self.banner.as_ref(), } .heading(loader) } pub(crate) fn icon(&self, loader: &ActixLoader) -> hyaenidae_toolkit::Icon { ProfileView { profile: &self.profile, icon: self.icon.as_ref(), banner: self.banner.as_ref(), } .icon(loader) } pub(crate) fn banner_image(&self, loader: &ActixLoader) -> Option { ProfileView { profile: &self.profile, icon: self.icon.as_ref(), banner: self.banner.as_ref(), } .banner_image(loader) } pub(crate) fn from_id( profile_id: Uuid, store: &hyaenidae_profiles::store::Store, ) -> Result { let profile = store.profiles.by_id(profile_id)?.req()?; let icon = if let Some(icon) = profile.icon() { store.files.by_id(icon)? } else { None }; let banner = if let Some(banner) = profile.banner() { store.files.by_id(banner)? } else { None }; Ok(OwnedProfileView { profile, icon, banner, }) } } impl<'a> ProfileView<'a> { pub(crate) fn heading(&self, loader: &ActixLoader) -> hyaenidae_toolkit::Profile { let heading = hyaenidae_toolkit::Profile::new(self.profile.full_handle(), self.profile.view_path()); let heading = if let Some(display_name) = self.profile.display_name() { heading.display_name(display_name) } else { heading }; let heading = if let Some(description) = self.profile.description_text() { heading.description(description) } else { heading }; let heading = if let Some(img) = self.icon_image(loader) { heading.icon_image(img) } else { heading }; if let Some(img) = self.banner_image(loader) { heading.banner_image(img) } else { heading } } pub(crate) fn banner_image(&self, loader: &ActixLoader) -> Option { let banner = self.banner?; let key = banner.pictrs_key()?; Some(BannerImage::new( key, &fl!(loader, "profile-banner", profileName = self.profile.name()), )) } fn icon_image(&self, loader: &ActixLoader) -> Option { let icon = self.icon?; let key = icon.pictrs_key()?; Some(IconImage::new( key, &fl!(loader, "profile-icon", profileName = self.profile.name()), )) } pub(crate) fn icon(&self, loader: &ActixLoader) -> hyaenidae_toolkit::Icon { let icon = hyaenidae_toolkit::Icon::new(self.profile.view_path()); if let Some(img) = self.icon_image(loader) { icon.image(img) } else { icon } } }