hyaenidae/server/src/views.rs

190 lines
5.1 KiB
Rust
Raw Normal View History

use crate::{
error::{Error, OptionExt},
extensions::{ProfileExt, SubmissionExt},
images::{BannerImage, IconImage, ThumbnailImage},
};
use hyaenidae_profiles::store::{File, Profile, Submission};
use hyaenidae_toolkit::{IndicatorColor, Thumbnail, Tile};
use uuid::Uuid;
pub struct OwnedProfileView {
pub(crate) profile: Profile,
pub(crate) icon: Option<File>,
pub(crate) banner: Option<File>,
}
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<File>,
pub(crate) current_file: Option<Uuid>,
}
pub struct SubmissionView<'a> {
pub(crate) author: &'a Profile,
pub(crate) author_icon: Option<&'a File>,
pub(crate) submission: &'a Submission,
pub(crate) files: Vec<&'a File>,
}
impl<'a> SubmissionView<'a> {
pub(crate) fn profile(&self) -> ProfileView<'a> {
ProfileView {
profile: self.author,
icon: self.author_icon,
banner: None,
}
}
pub(crate) fn thumbnail(&self) -> Option<Thumbnail> {
let file = self.files.get(0)?;
let key = file.pictrs_key()?;
let image = ThumbnailImage::new(key, &self.submission.title_text());
2021-01-24 20:50:16 +00:00
let thumb = Thumbnail::new(image, &self.submission.view_path())
.title(&self.submission.title_text())
.author(&self.author.name(), &self.author.view_path());
if self.files.len() > 1 {
Some(thumb.indicator(&format!("+{}", self.files.len() - 1), IndicatorColor::White))
} else {
Some(thumb)
}
}
}
impl OwnedSubmissionView {
pub(crate) fn tiles(&self) -> Vec<Tile> {
self.files
.iter()
.enumerate()
.filter_map(|(index, file)| {
let key = file.pictrs_key()?;
let alt = format!("file {}", 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) -> hyaenidae_toolkit::Profile {
ProfileView {
profile: &self.profile,
icon: self.icon.as_ref(),
banner: self.banner.as_ref(),
}
.heading()
}
pub(crate) fn icon(&self) -> hyaenidae_toolkit::Icon {
ProfileView {
profile: &self.profile,
icon: self.icon.as_ref(),
banner: self.banner.as_ref(),
}
.icon()
}
pub(crate) fn from_id(
profile_id: Uuid,
store: &hyaenidae_profiles::store::Store,
) -> Result<Self, Error> {
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) -> 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(icon) = self.icon_key() {
heading.icon_image(IconImage::new(
icon,
&format!("{}'s icon", self.profile.name()),
))
} else {
heading
};
if let Some(banner) = self.banner_key() {
heading.banner_image(BannerImage::new(
banner,
&format!("{}'s banner", self.profile.name()),
))
} else {
heading
}
}
pub(crate) fn icon(&self) -> hyaenidae_toolkit::Icon {
let icon = hyaenidae_toolkit::Icon::new(self.profile.view_path());
if let Some(key) = self.icon_key() {
icon.image(IconImage::new(
key,
&format!("{}'s icon", self.profile.name()),
))
} else {
icon
}
}
fn icon_key(&self) -> Option<&str> {
self.icon.and_then(|icon| icon.pictrs_key())
}
fn banner_key(&self) -> Option<&str> {
self.banner.and_then(|banner| banner.pictrs_key())
}
}