138 lines
3.6 KiB
Rust
138 lines
3.6 KiB
Rust
|
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::{Button, Tile};
|
||
|
use uuid::Uuid;
|
||
|
|
||
|
pub(crate) async fn home(
|
||
|
req: HttpRequest,
|
||
|
page: Option<web::Query<SubmissionPage>>,
|
||
|
user: Option<User>,
|
||
|
profile: Option<UserProfile>,
|
||
|
nav_state: NavState,
|
||
|
state: web::Data<State>,
|
||
|
) -> Result<HttpResponse, Error> {
|
||
|
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<Uuid>,
|
||
|
previous_id: Option<Uuid>,
|
||
|
next_id: Option<Uuid>,
|
||
|
reset: bool,
|
||
|
path: String,
|
||
|
}
|
||
|
|
||
|
impl ViewHomeState {
|
||
|
async fn build(
|
||
|
path: String,
|
||
|
viewer: Option<Uuid>,
|
||
|
source: Option<PageSource>,
|
||
|
state: &State,
|
||
|
) -> Result<Self, Error> {
|
||
|
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<Tile> {
|
||
|
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());
|
||
|
|
||
|
Some(tile)
|
||
|
})
|
||
|
.collect()
|
||
|
}
|
||
|
|
||
|
pub(crate) fn nav(&self, dark: bool) -> Vec<Button> {
|
||
|
let mut nav = vec![];
|
||
|
|
||
|
if let Some(prev) = self.previous_id {
|
||
|
nav.push(
|
||
|
Button::secondary("Previous")
|
||
|
.href(&format!("{}?min={}", self.path, prev))
|
||
|
.dark(dark),
|
||
|
);
|
||
|
}
|
||
|
|
||
|
if let Some(next) = self.next_id {
|
||
|
nav.push(
|
||
|
Button::secondary("Next")
|
||
|
.href(&format!("{}?max={}", self.path, next))
|
||
|
.dark(dark),
|
||
|
);
|
||
|
}
|
||
|
|
||
|
if self.reset {
|
||
|
nav.push(Button::secondary("Reset").href(&self.path).dark(dark));
|
||
|
}
|
||
|
|
||
|
nav
|
||
|
}
|
||
|
}
|