2021-01-22 05:47:47 +00:00
|
|
|
use crate::{
|
|
|
|
admin::Admin, extensions::ProfileExt, middleware::UserProfile,
|
|
|
|
notifications::total_for_profile, State,
|
|
|
|
};
|
2021-01-15 05:51:17 +00:00
|
|
|
use actix_web::{
|
|
|
|
dev::Payload,
|
|
|
|
web::{Data, Query},
|
|
|
|
FromRequest, HttpRequest,
|
|
|
|
};
|
|
|
|
use futures::future::LocalBoxFuture;
|
2021-01-10 01:49:33 +00:00
|
|
|
use hyaenidae_accounts::LogoutState;
|
|
|
|
use hyaenidae_toolkit::Button;
|
|
|
|
|
|
|
|
impl FromRequest for NavState {
|
|
|
|
type Config = ();
|
|
|
|
type Error = actix_web::Error;
|
|
|
|
type Future = LocalBoxFuture<'static, Result<Self, Self::Error>>;
|
|
|
|
|
|
|
|
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
|
2021-01-22 05:47:47 +00:00
|
|
|
let profile = Option::<UserProfile>::extract(req);
|
2021-01-10 01:49:33 +00:00
|
|
|
let logout = Option::<LogoutState>::extract(req);
|
2021-01-11 04:09:47 +00:00
|
|
|
let query = Option::<Query<Vec<(String, String)>>>::extract(req);
|
2021-01-14 04:46:34 +00:00
|
|
|
let admin = Option::<Admin>::extract(req);
|
2021-01-11 04:09:47 +00:00
|
|
|
let path = req.uri().path().to_owned();
|
2021-01-15 05:51:17 +00:00
|
|
|
let state = Data::<State>::extract(req);
|
2021-01-10 01:49:33 +00:00
|
|
|
|
|
|
|
Box::pin(async move {
|
2021-01-22 05:47:47 +00:00
|
|
|
let profile = profile.await?.map(|p| p.0);
|
2021-01-10 01:49:33 +00:00
|
|
|
let logout = logout.await?;
|
2021-01-11 04:09:47 +00:00
|
|
|
let query = query.await?;
|
2021-01-14 04:46:34 +00:00
|
|
|
let admin = admin.await?;
|
2021-01-15 05:51:17 +00:00
|
|
|
let state = state.await?;
|
2021-01-10 01:49:33 +00:00
|
|
|
|
2021-01-25 02:05:45 +00:00
|
|
|
let mut is_open = false;
|
|
|
|
let href = if let Some(query) = query {
|
2021-01-11 04:09:47 +00:00
|
|
|
let query = query
|
|
|
|
.into_inner()
|
|
|
|
.into_iter()
|
|
|
|
.filter_map(|(key, value)| {
|
|
|
|
if key == "show_nav" {
|
|
|
|
is_open = true;
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
Some(format!("{}={}", key, value))
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.collect::<Vec<String>>()
|
|
|
|
.join("&");
|
|
|
|
|
|
|
|
let query = if is_open {
|
|
|
|
query
|
|
|
|
} else {
|
|
|
|
format!("{}&show_nav=true", query)
|
|
|
|
};
|
|
|
|
|
2021-01-25 02:05:45 +00:00
|
|
|
format!("{}?{}", path, query)
|
|
|
|
} else {
|
|
|
|
format!("{}?show_nav=true", path)
|
|
|
|
};
|
|
|
|
|
|
|
|
let dark = true;
|
|
|
|
let mut nav = vec![];
|
|
|
|
let mut narrow_nav = vec![];
|
|
|
|
let mut site_nav = vec![];
|
|
|
|
let mut account_nav = vec![];
|
|
|
|
|
|
|
|
let nav_button = Button::secondary("Nav").href(&href).class("nav-link");
|
|
|
|
|
|
|
|
if let Some(logout_state) = logout {
|
|
|
|
let new_submission = Button::primary("New Submission").href("/submissions/create");
|
|
|
|
nav.push(new_submission.clone());
|
|
|
|
site_nav.push(new_submission.clone());
|
|
|
|
narrow_nav.push(new_submission);
|
|
|
|
|
|
|
|
let browse_button = Button::secondary("Browse").href("/browse");
|
|
|
|
nav.push(browse_button.clone());
|
|
|
|
site_nav.push(browse_button);
|
|
|
|
|
|
|
|
narrow_nav.push(nav_button);
|
|
|
|
|
|
|
|
let profile_button = if let Some(profile) = profile.as_ref() {
|
|
|
|
Button::secondary("Profile").href(&profile.view_path())
|
|
|
|
} else {
|
|
|
|
Button::secondary("Switch Profile").href("/profiles/change")
|
|
|
|
};
|
|
|
|
nav.push(profile_button.clone());
|
|
|
|
site_nav.push(profile_button);
|
|
|
|
|
|
|
|
if let Some(profile) = profile.as_ref() {
|
|
|
|
if let Ok(count) = total_for_profile(profile.id(), &state).await {
|
|
|
|
if count > 0 {
|
|
|
|
let notif_button =
|
|
|
|
Button::secondary("Notifications").href("/notifications");
|
|
|
|
nav.push(notif_button.clone());
|
|
|
|
site_nav.push(notif_button);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let account_button = Button::secondary("Account").href("/session/account");
|
|
|
|
nav.push(account_button.clone());
|
|
|
|
account_nav.push(account_button);
|
|
|
|
|
|
|
|
if admin.is_some() {
|
|
|
|
let admin_button = Button::secondary("Admin").href("/admin");
|
|
|
|
nav.push(admin_button.clone());
|
|
|
|
site_nav.push(admin_button);
|
|
|
|
}
|
|
|
|
let logout_button = logout_state.button(Button::primary_outline("Logout"));
|
|
|
|
nav.push(logout_button.clone());
|
|
|
|
account_nav.push(logout_button.clone());
|
2021-01-11 04:09:47 +00:00
|
|
|
} else {
|
2021-01-25 02:05:45 +00:00
|
|
|
narrow_nav.push(nav_button);
|
|
|
|
let login_button = Button::primary_outline("Login").href("/session/auth/login");
|
|
|
|
nav.push(login_button.clone());
|
|
|
|
account_nav.push(login_button);
|
|
|
|
|
|
|
|
let register_button =
|
|
|
|
Button::primary_outline("Register").href("/session/auth/register");
|
|
|
|
nav.push(register_button.clone());
|
|
|
|
account_nav.push(register_button);
|
2021-01-11 04:09:47 +00:00
|
|
|
}
|
2021-01-25 02:05:45 +00:00
|
|
|
|
|
|
|
Ok(NavState {
|
|
|
|
buttons: nav,
|
|
|
|
narrow_buttons: narrow_nav,
|
|
|
|
site_buttons: site_nav,
|
|
|
|
account_buttons: account_nav,
|
|
|
|
href,
|
|
|
|
is_open,
|
|
|
|
dark,
|
|
|
|
})
|
2021-01-10 01:49:33 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct NavState {
|
2021-01-22 05:47:47 +00:00
|
|
|
pub(crate) buttons: Vec<Button>,
|
2021-01-25 02:05:45 +00:00
|
|
|
pub(crate) narrow_buttons: Vec<Button>,
|
|
|
|
pub(crate) site_buttons: Vec<Button>,
|
|
|
|
pub(crate) account_buttons: Vec<Button>,
|
2021-01-11 04:09:47 +00:00
|
|
|
href: String,
|
|
|
|
is_open: bool,
|
|
|
|
dark: bool,
|
2021-01-10 01:49:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl NavState {
|
2021-01-11 04:09:47 +00:00
|
|
|
pub(crate) fn href(&self) -> &str {
|
|
|
|
&self.href
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn class_string(&self) -> &str {
|
|
|
|
if self.is_open {
|
|
|
|
"nav-open"
|
|
|
|
} else {
|
|
|
|
"nav-closed"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn dark(&self) -> bool {
|
|
|
|
self.dark
|
|
|
|
}
|
2021-01-10 01:49:33 +00:00
|
|
|
}
|