Expose sensitive on submission page
- Don't show sensitive content to logged-out users - Add sensitive indicator on submission tiles, thumbnails - Improve mobile nav UI
This commit is contained in:
parent
2f9decc07f
commit
7ed5264bef
|
@ -23,12 +23,20 @@ picture {
|
||||||
|
|
||||||
.mobile-bar {
|
.mobile-bar {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
||||||
|
.toolkit-button {
|
||||||
|
min-width: auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile-nav {
|
.profile-nav {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
|
.mobile-bar-icon {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.bar-icon {
|
.bar-icon {
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
margin-left: 16px;
|
margin-left: 16px;
|
||||||
|
@ -45,13 +53,6 @@ picture {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.narrow-nav {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.wide-nav {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-body {
|
.nav-body {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
|
@ -307,15 +308,6 @@ picture {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 975px) {
|
|
||||||
.narrow-nav {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.wide-nav {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 700px) {
|
@media (max-width: 700px) {
|
||||||
.desktop-bar {
|
.desktop-bar {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
|
@ -117,13 +117,23 @@ impl ViewBrowseState {
|
||||||
.title(&submission.title_text())
|
.title(&submission.title_text())
|
||||||
.author(&author.name(), &author.view_path());
|
.author(&author.name(), &author.view_path());
|
||||||
|
|
||||||
|
let sensitive_color = if submission.is_sensitive() {
|
||||||
|
Some(IndicatorColor::Red)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
if submission.files().len() > 1 {
|
if submission.files().len() > 1 {
|
||||||
Some(thumb.indicator(
|
Some(thumb.indicator(
|
||||||
&format!("+{}", submission.files().len() - 1),
|
&format!("+{}", submission.files().len() - 1),
|
||||||
IndicatorColor::White,
|
sensitive_color.unwrap_or(IndicatorColor::White),
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
Some(thumb)
|
if let Some(sensitive_color) = sensitive_color {
|
||||||
|
Some(thumb.indicator("", sensitive_color))
|
||||||
|
} else {
|
||||||
|
Some(thumb)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
|
|
95
src/nav.rs
95
src/nav.rs
|
@ -1,7 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
admin::Admin,
|
admin::Admin,
|
||||||
error::Error,
|
error::Error,
|
||||||
extensions::ProfileExt,
|
|
||||||
middleware::UserProfile,
|
middleware::UserProfile,
|
||||||
notifications::total_for_profile,
|
notifications::total_for_profile,
|
||||||
views::{OwnedProfileView, ProfileView},
|
views::{OwnedProfileView, ProfileView},
|
||||||
|
@ -133,52 +132,54 @@ impl NavState {
|
||||||
Button::primary_link(&fl!(loader, "nav-submission-button")).href("/submissions/create")
|
Button::primary_link(&fl!(loader, "nav-submission-button")).href("/submissions/create")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn nav_button(&self, loader: &ActixLoader) -> Button {
|
fn mobile_submission_button(&self, loader: &ActixLoader) -> Button {
|
||||||
Button::link(&fl!(loader, "nav-text"))
|
Button::primary(&fl!(loader, "nav-submission-button")).href("/submissions/create")
|
||||||
.href(&self.href)
|
|
||||||
.class("nav-link")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn browse_button(&self, loader: &ActixLoader) -> Button {
|
pub(crate) fn browse_button(&self, loader: &ActixLoader) -> Button {
|
||||||
Button::link(&fl!(loader, "nav-browse-button")).href("/browse")
|
Button::link(&fl!(loader, "nav-browse-button")).href("/browse")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn profile_button(&self, loader: &ActixLoader) -> Button {
|
fn mobile_browse_button(&self, loader: &ActixLoader) -> Button {
|
||||||
if let Some(view) = self.profile.as_ref() {
|
Button::secondary(&fl!(loader, "nav-browse-button")).href("/browse")
|
||||||
Button::link(&fl!(loader, "nav-profile-button")).href(&view.profile.view_path())
|
|
||||||
} else {
|
|
||||||
Button::link(&fl!(loader, "nav-switch-profile-button")).href("/profiles/change")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn notifications_path(&self) -> &'static str {
|
pub(crate) fn notifications_path(&self) -> &'static str {
|
||||||
"/notifications"
|
"/notifications"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn notifications_button(&self, loader: &ActixLoader) -> Button {
|
pub(crate) fn admin_button(&self, loader: &ActixLoader) -> Button {
|
||||||
Button::link(&fl!(loader, "nav-notifications-button")).href(self.notifications_path())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn admin_button(&self, loader: &ActixLoader) -> Button {
|
|
||||||
Button::link(&fl!(loader, "nav-admin-button")).href("/admin")
|
Button::link(&fl!(loader, "nav-admin-button")).href("/admin")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn account_button(&self, loader: &ActixLoader) -> Button {
|
fn mobile_admin_button(&self, loader: &ActixLoader) -> Button {
|
||||||
Button::link(&fl!(loader, "nav-account-button")).href("/session/account")
|
Button::secondary(&fl!(loader, "nav-admin-button")).href("/admin")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn login_button(&self, loader: &ActixLoader) -> Button {
|
fn login_button(&self, loader: &ActixLoader) -> Button {
|
||||||
Button::primary_link(&fl!(loader, "nav-login-button")).href("/session/auth/login")
|
Button::primary_link(&fl!(loader, "nav-login-button")).href("/session/auth/login")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mobile_login_button(&self, loader: &ActixLoader) -> Button {
|
||||||
|
Button::primary_outline(&fl!(loader, "nav-login-button")).href("/session/auth/login")
|
||||||
|
}
|
||||||
|
|
||||||
fn register_button(&self, loader: &ActixLoader) -> Button {
|
fn register_button(&self, loader: &ActixLoader) -> Button {
|
||||||
Button::primary_link(&fl!(loader, "nav-register-button")).href("/session/auth/register")
|
Button::primary_link(&fl!(loader, "nav-register-button")).href("/session/auth/register")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mobile_register_button(&self, loader: &ActixLoader) -> Button {
|
||||||
|
Button::primary_outline(&fl!(loader, "nav-register-button")).href("/session/auth/register")
|
||||||
|
}
|
||||||
|
|
||||||
fn logout_button(&self, logout_state: &LogoutState, loader: &ActixLoader) -> Button {
|
fn logout_button(&self, logout_state: &LogoutState, loader: &ActixLoader) -> Button {
|
||||||
Button::primary_link(&fl!(loader, "nav-logout-button")).form(&logout_state.logout_path())
|
Button::primary_link(&fl!(loader, "nav-logout-button")).form(&logout_state.logout_path())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mobile_logout_button(&self, logout_state: &LogoutState, loader: &ActixLoader) -> Button {
|
||||||
|
Button::primary_outline(&fl!(loader, "nav-logout-button")).form(&logout_state.logout_path())
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn has_notifications(&self) -> bool {
|
pub(crate) fn has_notifications(&self) -> bool {
|
||||||
if let Some(count) = self.notification_count {
|
if let Some(count) = self.notification_count {
|
||||||
count > 0
|
count > 0
|
||||||
|
@ -191,16 +192,11 @@ impl NavState {
|
||||||
let mut nav = vec![];
|
let mut nav = vec![];
|
||||||
|
|
||||||
if let Some(logout_state) = &self.logout_state {
|
if let Some(logout_state) = &self.logout_state {
|
||||||
nav.push(self.submission_button(loader));
|
if self.profile.is_some() {
|
||||||
nav.push(self.browse_button(loader));
|
nav.push(self.submission_button(loader));
|
||||||
nav.push(self.profile_button(loader));
|
nav.push(self.browse_button(loader));
|
||||||
|
|
||||||
if self.has_notifications() {
|
|
||||||
nav.push(self.notifications_button(loader));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nav.push(self.account_button(loader));
|
|
||||||
|
|
||||||
if self.admin.is_some() {
|
if self.admin.is_some() {
|
||||||
nav.push(self.admin_button(loader));
|
nav.push(self.admin_button(loader));
|
||||||
}
|
}
|
||||||
|
@ -213,50 +209,25 @@ impl NavState {
|
||||||
nav
|
nav
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn narrow_buttons(&self, loader: &ActixLoader) -> Vec<Button> {
|
pub(crate) fn mobile_buttons(&self, loader: &ActixLoader) -> Vec<Button> {
|
||||||
let mut narrow_nav = vec![];
|
let mut nav = vec![];
|
||||||
|
|
||||||
if self.logout_state.is_some() {
|
if let Some(logout_state) = &self.logout_state {
|
||||||
narrow_nav.push(self.submission_button(loader));
|
if self.profile.is_some() {
|
||||||
narrow_nav.push(self.nav_button(loader));
|
nav.push(self.mobile_submission_button(loader));
|
||||||
} else {
|
nav.push(self.mobile_browse_button(loader));
|
||||||
narrow_nav.push(self.nav_button(loader));
|
|
||||||
}
|
|
||||||
|
|
||||||
narrow_nav
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn site_buttons(&self, loader: &ActixLoader) -> Vec<Button> {
|
|
||||||
let mut site_nav = vec![];
|
|
||||||
|
|
||||||
if self.logout_state.is_some() {
|
|
||||||
site_nav.push(self.submission_button(loader));
|
|
||||||
site_nav.push(self.browse_button(loader));
|
|
||||||
site_nav.push(self.profile_button(loader));
|
|
||||||
|
|
||||||
if self.has_notifications() {
|
|
||||||
site_nav.push(self.notifications_button(loader));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.admin.is_some() {
|
if self.admin.is_some() {
|
||||||
site_nav.push(self.admin_button(loader));
|
nav.push(self.mobile_admin_button(loader));
|
||||||
}
|
}
|
||||||
}
|
nav.push(self.mobile_logout_button(logout_state, loader));
|
||||||
|
|
||||||
site_nav
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn account_buttons(&self, loader: &ActixLoader) -> Vec<Button> {
|
|
||||||
let mut account_nav = vec![];
|
|
||||||
|
|
||||||
if let Some(logout_state) = &self.logout_state {
|
|
||||||
account_nav.push(self.logout_button(logout_state, loader));
|
|
||||||
} else {
|
} else {
|
||||||
account_nav.push(self.login_button(loader));
|
nav.push(self.mobile_login_button(loader));
|
||||||
account_nav.push(self.register_button(loader));
|
nav.push(self.mobile_register_button(loader));
|
||||||
}
|
}
|
||||||
|
|
||||||
account_nav
|
nav
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn class_string(&self) -> &str {
|
pub(crate) fn class_string(&self) -> &str {
|
||||||
|
|
|
@ -337,6 +337,10 @@ pub(crate) fn can_view(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if submission.is_sensitive() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
if submission.is_unlisted() && !show_unlisted {
|
if submission.is_unlisted() && !show_unlisted {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,13 +89,23 @@ impl ViewProfileState {
|
||||||
.description(&author.name())
|
.description(&author.name())
|
||||||
.link(&submission.view_path());
|
.link(&submission.view_path());
|
||||||
|
|
||||||
|
let sensitive_color = if submission.is_sensitive() {
|
||||||
|
Some(IndicatorColor::Red)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
if submission.files().len() > 1 {
|
if submission.files().len() > 1 {
|
||||||
Some(tile.indicator(
|
Some(tile.indicator(
|
||||||
&format!("+{}", submission.files().len() - 1),
|
&format!("+{}", submission.files().len() - 1),
|
||||||
IndicatorColor::White,
|
sensitive_color.unwrap_or(IndicatorColor::White),
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
Some(tile)
|
if let Some(sensitive_color) = sensitive_color {
|
||||||
|
Some(tile.indicator("", sensitive_color))
|
||||||
|
} else {
|
||||||
|
Some(tile)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
|
@ -106,6 +116,10 @@ impl ViewProfileState {
|
||||||
.href(&self.unwrap_profile().view_path())
|
.href(&self.unwrap_profile().view_path())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn account_settings_button(&self, loader: &ActixLoader) -> Button {
|
||||||
|
Button::secondary(&fl!(loader, "account-settings-button")).href("/session/account")
|
||||||
|
}
|
||||||
|
|
||||||
fn edit_profile_button(&self, loader: &ActixLoader) -> Button {
|
fn edit_profile_button(&self, loader: &ActixLoader) -> Button {
|
||||||
Button::secondary(&fl!(loader, "edit-profile-button")).href("/profiles/current")
|
Button::secondary(&fl!(loader, "edit-profile-button")).href("/profiles/current")
|
||||||
}
|
}
|
||||||
|
@ -152,10 +166,12 @@ impl ViewProfileState {
|
||||||
btns.push(self.view_profile_button(loader));
|
btns.push(self.view_profile_button(loader));
|
||||||
btns.push(self.edit_profile_button(loader));
|
btns.push(self.edit_profile_button(loader));
|
||||||
btns.push(self.switch_profile_button(loader));
|
btns.push(self.switch_profile_button(loader));
|
||||||
|
btns.push(self.account_settings_button(loader));
|
||||||
} else if self.is_self {
|
} else if self.is_self {
|
||||||
btns.push(self.view_drafts_button(loader));
|
btns.push(self.view_drafts_button(loader));
|
||||||
btns.push(self.edit_profile_button(loader));
|
btns.push(self.edit_profile_button(loader));
|
||||||
btns.push(self.switch_profile_button(loader));
|
btns.push(self.switch_profile_button(loader));
|
||||||
|
btns.push(self.account_settings_button(loader));
|
||||||
} else if self.is_follow_requested {
|
} else if self.is_follow_requested {
|
||||||
btns.push(self.cancel_request_button(loader));
|
btns.push(self.cancel_request_button(loader));
|
||||||
btns.push(self.block_button(loader));
|
btns.push(self.block_button(loader));
|
||||||
|
@ -341,6 +357,31 @@ impl EditProfileState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn view_profile_button(&self, loader: &ActixLoader) -> Button {
|
||||||
|
Button::secondary(&fl!(loader, "view-profile-button")).href(&self.profile.view_path())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn view_drafts_button(&self, loader: &ActixLoader) -> Button {
|
||||||
|
Button::secondary(&fl!(loader, "drafts-button")).href("/profiles/drafts")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn switch_profile_button(&self, loader: &ActixLoader) -> Button {
|
||||||
|
Button::secondary(&fl!(loader, "switch-profile-button")).href("/profiles/change")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn account_settings_button(&self, loader: &ActixLoader) -> Button {
|
||||||
|
Button::secondary(&fl!(loader, "account-settings-button")).href("/session/account")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn buttons(&self, loader: &ActixLoader) -> Vec<Button> {
|
||||||
|
vec![
|
||||||
|
self.view_profile_button(loader),
|
||||||
|
self.view_drafts_button(loader),
|
||||||
|
self.switch_profile_button(loader),
|
||||||
|
self.account_settings_button(loader),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn display_name(&self, loader: &ActixLoader) -> TextInput {
|
pub(crate) fn display_name(&self, loader: &ActixLoader) -> TextInput {
|
||||||
let input = TextInput::new("display_name")
|
let input = TextInput::new("display_name")
|
||||||
.title(&fl!(loader, "create-bio-display-name"))
|
.title(&fl!(loader, "create-bio-display-name"))
|
||||||
|
|
|
@ -51,6 +51,11 @@ pub(super) fn scope() -> Scope {
|
||||||
.route(web::get().to(route_to_update_page))
|
.route(web::get().to(route_to_update_page))
|
||||||
.route(web::post().to(update_visibility)),
|
.route(web::post().to(update_visibility)),
|
||||||
)
|
)
|
||||||
|
.service(
|
||||||
|
web::resource("/sensitive")
|
||||||
|
.route(web::get().to(route_to_update_page))
|
||||||
|
.route(web::post().to(update_sensitive)),
|
||||||
|
)
|
||||||
.service(
|
.service(
|
||||||
web::resource("/add-file")
|
web::resource("/add-file")
|
||||||
.route(web::get().to(route_to_update_page))
|
.route(web::get().to(route_to_update_page))
|
||||||
|
@ -287,6 +292,7 @@ pub struct SubmissionState {
|
||||||
pub(crate) publish_error: Option<String>,
|
pub(crate) publish_error: Option<String>,
|
||||||
pub(crate) delete_error: Option<String>,
|
pub(crate) delete_error: Option<String>,
|
||||||
pub(crate) visibility_error: Option<String>,
|
pub(crate) visibility_error: Option<String>,
|
||||||
|
pub(crate) sensitive_error: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SubmissionState {
|
impl SubmissionState {
|
||||||
|
@ -320,6 +326,7 @@ impl SubmissionState {
|
||||||
publish_error: None,
|
publish_error: None,
|
||||||
delete_error: None,
|
delete_error: None,
|
||||||
visibility_error: None,
|
visibility_error: None,
|
||||||
|
sensitive_error: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,6 +389,10 @@ impl SubmissionState {
|
||||||
format!("/submissions/{}/visibility", self.submission.id())
|
format!("/submissions/{}/visibility", self.submission.id())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn sensitive_path(&self) -> String {
|
||||||
|
format!("/submissions/{}/sensitive", self.submission.id())
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn update_path(&self) -> String {
|
pub(crate) fn update_path(&self) -> String {
|
||||||
format!("/submissions/{}/update", self.submission.id())
|
format!("/submissions/{}/update", self.submission.id())
|
||||||
}
|
}
|
||||||
|
@ -460,6 +471,11 @@ impl SubmissionState {
|
||||||
self.visibility_error = Some(error);
|
self.visibility_error = Some(error);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn sensitive_error(mut self, error: String) -> Self {
|
||||||
|
self.sensitive_error = Some(error);
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn files_page(
|
async fn files_page(
|
||||||
|
@ -601,6 +617,12 @@ async fn can_view(
|
||||||
submission: &Submission,
|
submission: &Submission,
|
||||||
state: &State,
|
state: &State,
|
||||||
) -> Result<Option<HttpResponse>, Error> {
|
) -> Result<Option<HttpResponse>, Error> {
|
||||||
|
if submission.is_sensitive() {
|
||||||
|
if viewer.is_none() {
|
||||||
|
return Ok(Some(crate::to_404()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if poster.login_required() && viewer.is_none() {
|
if poster.login_required() && viewer.is_none() {
|
||||||
return Ok(Some(crate::to_404()));
|
return Ok(Some(crate::to_404()));
|
||||||
}
|
}
|
||||||
|
@ -1093,8 +1115,6 @@ async fn update_visibility(
|
||||||
return Ok(crate::to_404());
|
return Ok(crate::to_404());
|
||||||
}
|
}
|
||||||
|
|
||||||
log::debug!("form: {:?}", form);
|
|
||||||
|
|
||||||
let res = state
|
let res = state
|
||||||
.profiles
|
.profiles
|
||||||
.run(UpdateSubmission::from_visibility(
|
.run(UpdateSubmission::from_visibility(
|
||||||
|
@ -1119,6 +1139,50 @@ async fn update_visibility(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, serde::Deserialize)]
|
||||||
|
struct UpdateSensitiveForm {
|
||||||
|
sensitive: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn update_sensitive(
|
||||||
|
loader: ActixLoader,
|
||||||
|
form: web::Form<UpdateSensitiveForm>,
|
||||||
|
submission: CurrentSubmission,
|
||||||
|
profile: UserProfile,
|
||||||
|
nav_state: NavState,
|
||||||
|
state: web::Data<State>,
|
||||||
|
) -> Result<HttpResponse, Error> {
|
||||||
|
let submission = submission.0;
|
||||||
|
let profile = profile.0;
|
||||||
|
|
||||||
|
let form = form.into_inner();
|
||||||
|
|
||||||
|
if profile.id() != submission.profile_id() {
|
||||||
|
return Ok(crate::to_404());
|
||||||
|
}
|
||||||
|
|
||||||
|
let res = state
|
||||||
|
.profiles
|
||||||
|
.run(UpdateSubmission::from_sensitive(
|
||||||
|
submission.id(),
|
||||||
|
form.sensitive.is_some(),
|
||||||
|
))
|
||||||
|
.await;
|
||||||
|
|
||||||
|
let error = match res {
|
||||||
|
Ok(_) => return Ok(to_update_page(submission.id())),
|
||||||
|
Err(e) => e.to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let state = SubmissionState::new(submission, &state)
|
||||||
|
.await?
|
||||||
|
.sensitive_error(error);
|
||||||
|
|
||||||
|
crate::rendered(HttpResponse::BadRequest(), |cursor| {
|
||||||
|
crate::templates::submissions::update(cursor, &loader, &state, &nav_state)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
async fn add_file(
|
async fn add_file(
|
||||||
loader: ActixLoader,
|
loader: ActixLoader,
|
||||||
req: HttpRequest,
|
req: HttpRequest,
|
||||||
|
|
19
src/views.rs
19
src/views.rs
|
@ -44,10 +44,23 @@ impl<'a> SubmissionView<'a> {
|
||||||
.title(&self.submission.title_text())
|
.title(&self.submission.title_text())
|
||||||
.author(&self.author.name(), &self.author.view_path());
|
.author(&self.author.name(), &self.author.view_path());
|
||||||
|
|
||||||
if self.files.len() > 1 {
|
let sensitive_color = if self.submission.is_sensitive() {
|
||||||
Some(thumb.indicator(&format!("+{}", self.files.len() - 1), IndicatorColor::White))
|
Some(IndicatorColor::Red)
|
||||||
} else {
|
} else {
|
||||||
Some(thumb)
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
if self.files.len() > 1 {
|
||||||
|
Some(thumb.indicator(
|
||||||
|
&format!("+{}", self.files.len() - 1),
|
||||||
|
sensitive_color.unwrap_or(IndicatorColor::White),
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
if let Some(sensitive_color) = sensitive_color {
|
||||||
|
Some(thumb.indicator("", sensitive_color))
|
||||||
|
} else {
|
||||||
|
Some(thumb)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
@use hyaenidae_toolkit::templates::bar;
|
@use hyaenidae_toolkit::templates::bar;
|
||||||
@use hyaenidae_toolkit::templates::{button, button_group};
|
@use hyaenidae_toolkit::templates::{button, button_group};
|
||||||
@use hyaenidae_toolkit::{templates::icon, Size};
|
@use hyaenidae_toolkit::{templates::icon, Size};
|
||||||
|
@use hyaenidae_toolkit::templates::icon_button;
|
||||||
@use hyaenidae_toolkit::{templates::link, Link};
|
@use hyaenidae_toolkit::{templates::link, Link};
|
||||||
@use i18n_embed_fl::fl;
|
@use i18n_embed_fl::fl;
|
||||||
|
|
||||||
|
@ -21,33 +22,38 @@
|
||||||
@:button(&nav_state.submission_button(loader))
|
@:button(&nav_state.submission_button(loader))
|
||||||
@:button(&nav_state.browse_button(loader))
|
@:button(&nav_state.browse_button(loader))
|
||||||
@if nav_state.has_notifications() {
|
@if nav_state.has_notifications() {
|
||||||
<div class="toolkit-button toolkit-button__link">
|
@:icon_button("bell", &fl!(loader, "nav-notifications-button"), nav_state.notifications_path())
|
||||||
<span><i class="fa fa-bell"></i></span>
|
|
||||||
@:link(&Link::current_tab(nav_state.notifications_path()).plain(true).class("toolkit-button--action").title("Notifications"), {
|
|
||||||
<i class="fa fa-bell"></i>
|
|
||||||
})
|
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@:icon(&profile.icon(loader).size(Size::Tiny).class("bar-icon").dark(true))
|
@:icon(&profile.icon(loader).size(Size::Tiny).class("bar-icon").dark(true))
|
||||||
</div>
|
</div>
|
||||||
} else {
|
} else {
|
||||||
<div class="narrow-nav">
|
@:button_group(&nav_state.buttons(loader))
|
||||||
@:button_group(&nav_state.narrow_buttons(loader))
|
|
||||||
</div>
|
|
||||||
<div class="wide-nav">
|
|
||||||
@:button_group(&nav_state.buttons(loader))
|
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
</nav>
|
</nav>
|
||||||
})
|
})
|
||||||
@:bar(nav_state.dark(), "mobile-bar", {
|
@:bar(nav_state.dark(), "mobile-bar", {
|
||||||
@:link(&Link::current_tab("/").plain(true), {
|
<div class="profile-nav">
|
||||||
<h2>@fl!(loader, "site-name")</h2>
|
@if let Some(profile) = nav_state.profile() {
|
||||||
})
|
@:icon(&profile.icon(loader).size(Size::Tiny).class("mobile-bar-icon").dark(true))
|
||||||
<h3 class="nav-link">
|
} else {
|
||||||
@:link(&Link::current_tab(nav_state.href()).plain(true), {
|
@:link(&Link::current_tab("/").plain(true), {
|
||||||
@fl!(loader, "nav-text")
|
<h2>@fl!(loader, "site-name")</h2>
|
||||||
})
|
})
|
||||||
</h3>
|
}
|
||||||
|
</div>
|
||||||
|
<div class="toolkit-button-group">
|
||||||
|
@if nav_state.profile().is_some() {
|
||||||
|
@:icon_button("upload", &fl!(loader, "nav-submission-button"), "/submissions/create")
|
||||||
|
@:icon_button("home", &fl!(loader, "feed-title"), "/")
|
||||||
|
}
|
||||||
|
@if nav_state.has_notifications() {
|
||||||
|
<div class="toolkit-button-group">
|
||||||
|
@:icon_button("bell", &fl!(loader, "nav-notifications-button"), nav_state.notifications_path())
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<div class="nav-link">
|
||||||
|
@:icon_button("ellipsis-v", &fl!(loader, "nav-text"), nav_state.href())
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
})
|
})
|
||||||
|
|
|
@ -29,19 +29,11 @@
|
||||||
<nav class="nav-links">
|
<nav class="nav-links">
|
||||||
@:centered(false, {
|
@:centered(false, {
|
||||||
@:card(&Card::full_width().classes(&["nav"]).dark(nav_state.dark()), {
|
@:card(&Card::full_width().classes(&["nav"]).dark(nav_state.dark()), {
|
||||||
@if !nav_state.site_buttons(loader).is_empty() {
|
|
||||||
@:card_body({
|
|
||||||
<div class="nav-heading">
|
|
||||||
<h3>@fl!(loader, "site-navigation-heading")</h3>
|
|
||||||
</div>
|
|
||||||
@:button_group(&nav_state.site_buttons(loader))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@:card_body({
|
@:card_body({
|
||||||
<div class="nav-heading">
|
<div class="nav-heading">
|
||||||
<h3>@fl!(loader, "account-navigation-heading")</h3>
|
<h3>@fl!(loader, "site-name")</h3>
|
||||||
</div>
|
</div>
|
||||||
@:button_group(&nav_state.account_buttons(loader))
|
@:button_group(&nav_state.mobile_buttons(loader))
|
||||||
})
|
})
|
||||||
@:card_body({
|
@:card_body({
|
||||||
@:button_group(&[
|
@:button_group(&[
|
||||||
|
|
|
@ -27,10 +27,7 @@
|
||||||
@fl!(loader, "profile-actions-heading")
|
@fl!(loader, "profile-actions-heading")
|
||||||
})
|
})
|
||||||
@:card_body({
|
@:card_body({
|
||||||
@:button_group(&[
|
@:button_group(&state.buttons(loader))
|
||||||
Button::secondary(&fl!(loader, "view-profile-button")).href(&state.profile.view_path()),
|
|
||||||
Button::secondary(&fl!(loader, "switch-profile-button")).href("/profiles/change"),
|
|
||||||
])
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@:card(&Card::full_width().dark(nav_state.dark()), {
|
@:card(&Card::full_width().dark(nav_state.dark()), {
|
||||||
|
|
|
@ -20,6 +20,16 @@
|
||||||
@:home(loader, &view.submission.title_text(), view.submission.description_text().unwrap_or(&fl!(loader, "view-submission-subtitle", title = view.submission.title_text())), nav_state, {
|
@:home(loader, &view.submission.title_text(), view.submission.description_text().unwrap_or(&fl!(loader, "view-submission-subtitle", title = view.submission.title_text())), nav_state, {
|
||||||
@:button_js()
|
@:button_js()
|
||||||
}, {
|
}, {
|
||||||
|
@if view.is_self {
|
||||||
|
@:card(&Card::full_width().dark(nav_state.dark()), {
|
||||||
|
@:card_title({ Edit Submission })
|
||||||
|
@:card_body({
|
||||||
|
@:button_group(&[
|
||||||
|
Button::primary(&fl!(loader, "view-submission-edit-button")).href(&view.submission.update_path()),
|
||||||
|
])
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
@:card(&Card::full_width().dark(nav_state.dark()), {
|
@:card(&Card::full_width().dark(nav_state.dark()), {
|
||||||
@:card_title({
|
@:card_title({
|
||||||
@Html(view.submission.title_text())
|
@Html(view.submission.title_text())
|
||||||
|
@ -58,16 +68,6 @@
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@if view.is_self {
|
|
||||||
@:card(&Card::full_width().dark(nav_state.dark()), {
|
|
||||||
@:card_title({ Edit Submission })
|
|
||||||
@:card_body({
|
|
||||||
@:button_group(&[
|
|
||||||
Button::primary(&fl!(loader, "view-submission-edit-button")).href(&view.submission.update_path()),
|
|
||||||
])
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@if view.profile.is_some() && view.submission.published().is_some() {
|
@if view.profile.is_some() && view.submission.published().is_some() {
|
||||||
@:card(&Card::full_width().dark(nav_state.dark()), {
|
@:card(&Card::full_width().dark(nav_state.dark()), {
|
||||||
<form method="POST" action="@view.submission.comment_path()">
|
<form method="POST" action="@view.submission.comment_path()">
|
||||||
|
|
|
@ -36,6 +36,16 @@
|
||||||
</form>
|
</form>
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@:card(&Card::full_width().dark(nav_state.dark()), {
|
||||||
|
@:card_title({
|
||||||
|
@fl!(loader, "update-submission-view-heading")
|
||||||
|
})
|
||||||
|
@:card_body({
|
||||||
|
@:button_group(&[
|
||||||
|
Button::primary(&fl!(loader, "update-submission-view-button")).href(&state.view_path()),
|
||||||
|
])
|
||||||
|
})
|
||||||
|
})
|
||||||
@if !state.is_published() {
|
@if !state.is_published() {
|
||||||
@:card(&Card::full_width().dark(nav_state.dark()), {
|
@:card(&Card::full_width().dark(nav_state.dark()), {
|
||||||
<form method="POST" action="@state.visibility_path()">
|
<form method="POST" action="@state.visibility_path()">
|
||||||
|
@ -60,6 +70,21 @@
|
||||||
</form>
|
</form>
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@:card(&Card::full_width().dark(nav_state.dark()), {
|
||||||
|
<form method="POST" action="@state.sensitive_path()">
|
||||||
|
@:card_title({
|
||||||
|
@fl!(loader, "submission-sensitive-heading")
|
||||||
|
})
|
||||||
|
@:card_body({
|
||||||
|
@:checkbox("sensitive", &fl!(loader, "submission-sensitive-checkbox"), state.submission.is_sensitive())
|
||||||
|
})
|
||||||
|
@:card_body({
|
||||||
|
@:button_group(&[
|
||||||
|
Button::primary(&fl!(loader, "submission-sensitive-button")),
|
||||||
|
])
|
||||||
|
})
|
||||||
|
</form>
|
||||||
|
})
|
||||||
@:card(&Card::full_width().dark(nav_state.dark()), {
|
@:card(&Card::full_width().dark(nav_state.dark()), {
|
||||||
<form method="POST" action="@state.update_path()">
|
<form method="POST" action="@state.update_path()">
|
||||||
@:card_title({
|
@:card_title({
|
||||||
|
@ -119,16 +144,6 @@
|
||||||
})
|
})
|
||||||
</form>
|
</form>
|
||||||
})
|
})
|
||||||
@:card(&Card::full_width().dark(nav_state.dark()), {
|
|
||||||
@:card_title({
|
|
||||||
@fl!(loader, "update-submission-view-heading")
|
|
||||||
})
|
|
||||||
@:card_body({
|
|
||||||
@:button_group(&[
|
|
||||||
Button::primary(&fl!(loader, "update-submission-view-button")).href(&state.view_path()),
|
|
||||||
])
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@:card(&Card::full_width().dark(nav_state.dark()), {
|
@:card(&Card::full_width().dark(nav_state.dark()), {
|
||||||
@:card_title({
|
@:card_title({
|
||||||
@fl!(loader, "danger-heading")
|
@fl!(loader, "danger-heading")
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
site-name = Hyaenidae
|
site-name = Hyaenidae
|
||||||
site-description = A simple website
|
site-description = A simple website
|
||||||
|
|
||||||
nav-text = Nav
|
nav-text = Navigation
|
||||||
site-navigation-heading = Site Navigation
|
|
||||||
account-navigation-heading = Account Navigation
|
|
||||||
nav-cancel = Close
|
nav-cancel = Close
|
||||||
|
|
||||||
browse-logged-out = Log into {site-name} to see what's happening
|
browse-logged-out = Log into {site-name} to see what's happening
|
||||||
|
@ -119,6 +117,7 @@ drafts-button = View Drafts
|
||||||
edit-profile-button = Edit Profile
|
edit-profile-button = Edit Profile
|
||||||
switch-profile-button = Switch Profile
|
switch-profile-button = Switch Profile
|
||||||
view-profile-button = View Profile
|
view-profile-button = View Profile
|
||||||
|
account-settings-button = Account Settings
|
||||||
|
|
||||||
profile-submissions-heading = Submissions
|
profile-submissions-heading = Submissions
|
||||||
profile-drafts-heading = Drafts
|
profile-drafts-heading = Drafts
|
||||||
|
@ -129,7 +128,6 @@ nav-profile-button = Profile
|
||||||
nav-switch-profile-button = Switch Profile
|
nav-switch-profile-button = Switch Profile
|
||||||
nav-notifications-button = Notifications
|
nav-notifications-button = Notifications
|
||||||
nav-admin-button = Admin
|
nav-admin-button = Admin
|
||||||
nav-account-button = Account
|
|
||||||
nav-login-button = Login
|
nav-login-button = Login
|
||||||
nav-register-button = Register
|
nav-register-button = Register
|
||||||
nav-logout-button = Logout
|
nav-logout-button = Logout
|
||||||
|
@ -178,6 +176,10 @@ submission-visibility-heading = Audience
|
||||||
submission-login-required = Require login to view this submission
|
submission-login-required = Require login to view this submission
|
||||||
submission-local-only = Restrict this submission to your {site-name} server
|
submission-local-only = Restrict this submission to your {site-name} server
|
||||||
|
|
||||||
|
submission-sensitive-heading = Content Rating
|
||||||
|
submission-sensitive-checkbox = Mark this submission has NSFW
|
||||||
|
submission-sensitive-button = Save
|
||||||
|
|
||||||
update-submission-title = Edit Submission
|
update-submission-title = Edit Submission
|
||||||
update-submission-subtitle = Edit information or update images
|
update-submission-subtitle = Edit information or update images
|
||||||
update-submission-publish-title = Publish Submission
|
update-submission-publish-title = Publish Submission
|
||||||
|
|
Loading…
Reference in a new issue