use crate::{ error::{Error, OptionExt}, extensions::{ProfileExt, SubmissionExt}, images::{BannerImage, IconImage}, pagination::{ submission::{draft_page, main_page, Cache}, PageSource, }, views::ProfileView, State, }; use hyaenidae_profiles::store::{File, Profile}; use hyaenidae_toolkit::{BannerColor, Button, FileInput, TextInput, Tile}; use uuid::Uuid; const ACCEPT_TYPES: &str = "image/png,image/webp,image/jpeg,image/gif,.png,.webp,.jpg,.jpeg,.gif"; pub struct ViewProfileState { cache: Cache, profile_id: Uuid, submissions: Vec, previous_id: Option, next_id: Option, reset: bool, path: String, drafts: bool, is_self: bool, is_follow_requested: bool, is_followed: bool, is_blocked: bool, viewer_exists: bool, } pub struct EditProfileState { pub(crate) profile: Profile, icon: Option, banner: Option, display_name_value: Option, display_name_error: Option, description_value: Option, description_error: Option, pub(crate) icon_error: Option, pub(crate) banner_error: Option, login_required_value: Option, pub(crate) login_required_error: Option, } impl ViewProfileState { fn unwrap_profile(&self) -> &Profile { self.cache.profile_map.get(&self.profile_id).unwrap() } pub(crate) fn profile<'a>(&'a self) -> ProfileView<'a> { let profile = self.cache.profile_map.get(&self.profile_id).unwrap(); let icon = if let Some(icon) = profile.icon() { self.cache.file_map.get(&icon) } else { None }; let banner = if let Some(banner) = profile.banner() { self.cache.file_map.get(&banner) } else { None }; ProfileView { profile, icon, banner, } } pub(crate) fn submissions(&self) -> Vec { self.submissions .iter() .filter_map(move |submission_id| { let submission = self.cache.submission_map.get(&submission_id)?; let author = self.cache.profile_map.get(&submission.profile_id())?; let file_id = submission.files().get(0)?; let file = self.cache.file_map.get(&file_id)?; let key = file.pictrs_key()?; let tile = Tile::new(IconImage::new(key, submission.title())) .title(submission.title()) .description( &author .display_name() .map(|dn| dn.to_owned()) .unwrap_or(format!("@{}@{}", author.handle(), author.domain())), ) .link(&submission.view_path()); if submission.files().len() > 1 { Some(tile.banner( &format!("+{}", submission.files().len() - 1), BannerColor::White, )) } else { Some(tile) } }) .collect() } pub(crate) fn buttons(&self, dark: bool) -> Vec