use crate::{ error::Error, extensions::SubmissionExt, images::IconImage, middleware::UserProfile, nav::NavState, pagination::{ submission::{home_page, Cache}, PageSource, }, profiles::SubmissionPage, State, }; use actix_web::{web, HttpRequest, HttpResponse}; use hyaenidae_accounts::User; use hyaenidae_toolkit::{BannerColor, Button, Tile}; use uuid::Uuid; pub(crate) async fn home( req: HttpRequest, page: Option>, user: Option, profile: Option, nav_state: NavState, state: web::Data, ) -> Result { let profile = profile.map(|p| p.0); if user.is_some() && profile.is_none() { return Ok(crate::profiles::to_change_profile_page()); } let viewer = profile.map(|p| p.id()); let view = ViewHomeState::build( req.path().to_owned(), viewer, page.map(|q| q.into_inner().into()), &state, ) .await?; crate::rendered(HttpResponse::Ok(), |cursor| { crate::templates::index(cursor, &view, &nav_state) }) } pub struct ViewHomeState { cache: Cache, submissions: Vec, previous_id: Option, next_id: Option, reset: bool, path: String, } impl ViewHomeState { async fn build( path: String, viewer: Option, source: Option, state: &State, ) -> Result { let store = state.profiles.clone(); let state = actix_web::web::block(move || { let mut cache = Cache::new(); let page = home_page(viewer, &store, &mut cache, source); Ok(ViewHomeState { cache, submissions: page.items, next_id: page.next, previous_id: page.prev, reset: page.reset, path, }) }) .await?; Ok(state) } 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 nav(&self, dark: bool) -> Vec