From d3e62b7cd17b448331cc7a52e647e85e7e32423d Mon Sep 17 00:00:00 2001 From: asonix Date: Mon, 1 Feb 2021 19:03:57 -0600 Subject: [PATCH] Server: Expose visibility on submission update page Make submission next/previous buttons respect visibility --- src/admin.rs | 6 +- src/pagination/submission.rs | 24 +++++++- src/submissions.rs | 83 ++++++++++++++++++++++++---- templates/browse.rs.html | 20 ++++--- templates/submissions/update.rs.html | 9 ++- translations/en-US/hyaenidae.ftl | 5 ++ 6 files changed, 120 insertions(+), 27 deletions(-) diff --git a/src/admin.rs b/src/admin.rs index c9b7656..f05444a 100644 --- a/src/admin.rs +++ b/src/admin.rs @@ -927,16 +927,14 @@ impl ReportView { } pub(crate) fn select(&self, loader: &ActixLoader) -> Select { - let select = Select::new("action") + Select::new("action") .title(&fl!(loader, "admin-report-resolve-select")) .options(&[ (&fl!(loader, "admin-report-ignore"), "Ignore"), (&fl!(loader, "admin-report-delete"), "Delete"), (&fl!(loader, "admin-report-suspend"), "Suspend"), ]) - .default_option("Ignore"); - - select + .default_option("Ignore") } pub(crate) fn input(&self, loader: &ActixLoader) -> TextInput { diff --git a/src/pagination/submission.rs b/src/pagination/submission.rs index 402d26b..95eb7f3 100644 --- a/src/pagination/submission.rs +++ b/src/pagination/submission.rs @@ -92,6 +92,7 @@ impl<'b> Pagination for BrowsePager<'b> { self.viewer, &self.store.store, self.cache, + false, )), ) } @@ -106,6 +107,7 @@ impl<'b> Pagination for BrowsePager<'b> { self.viewer, &self.store.store, self.cache, + false, )), ) } @@ -120,6 +122,7 @@ impl<'b> Pagination for BrowsePager<'b> { self.viewer, &self.store.store, self.cache, + false, )), ) } @@ -143,6 +146,7 @@ impl<'b> Pagination for DraftPager<'b> { self.viewer, &self.store.store, self.cache, + true, )), ) } @@ -157,6 +161,7 @@ impl<'b> Pagination for DraftPager<'b> { self.viewer, &self.store.store, self.cache, + true, )), ) } @@ -171,6 +176,7 @@ impl<'b> Pagination for DraftPager<'b> { self.viewer, &self.store.store, self.cache, + true, )), ) } @@ -194,6 +200,7 @@ impl<'b> Pagination for SubmissionPager<'b> { self.viewer, &self.store.store, self.cache, + true, )), ) } @@ -208,6 +215,7 @@ impl<'b> Pagination for SubmissionPager<'b> { self.viewer, &self.store.store, self.cache, + true, )), ) } @@ -222,6 +230,7 @@ impl<'b> Pagination for SubmissionPager<'b> { self.viewer, &self.store.store, self.cache, + true, )), ) } @@ -231,6 +240,7 @@ fn filter_submissions<'a>( viewer: Option, store: &'a hyaenidae_profiles::store::Store, cache: &'a mut Cache, + show_unlisted: bool, ) -> impl FnMut(Uuid) -> Option + 'a { move |submission_id| { if !cache.submission_map.contains_key(&submission_id) { @@ -241,7 +251,7 @@ fn filter_submissions<'a>( cache.profile_map.insert(profile.id(), profile); } - let opt = can_view(viewer, &submission, store, cache); + let opt = can_view(viewer, &submission, store, cache, show_unlisted); if let Some(file_id) = submission.files().get(0) { if !cache.file_map.contains_key(file_id) { @@ -256,7 +266,7 @@ fn filter_submissions<'a>( } else { let submission = cache.submission_map.get(&submission_id)?.clone(); - can_view(viewer, &submission, store, cache)?; + can_view(viewer, &submission, store, cache, show_unlisted)?; Some(submission_id) } @@ -268,8 +278,12 @@ pub(crate) fn can_view( submission: &Submission, store: &hyaenidae_profiles::store::Store, cache: &mut Cache, + show_unlisted: bool, ) -> Option<()> { if let Some(viewer) = viewer { + if viewer == submission.profile_id() { + return Some(()); + } if let Some(block) = cache.blocks.get(&submission.profile_id()) { if *block { return None; @@ -302,7 +316,7 @@ pub(crate) fn can_view( } } - if submission.is_followers_only() { + if (submission.is_unlisted() && !show_unlisted) || submission.is_followers_only() { if let Some(follow) = cache.follows.get(&submission.profile_id()) { if !*follow { return None; @@ -323,6 +337,10 @@ pub(crate) fn can_view( } } } else { + if submission.is_unlisted() && !show_unlisted { + return None; + } + let requires_login = if let Some(profile) = cache.profile_map.get(&submission.profile_id()) { profile.login_required() diff --git a/src/submissions.rs b/src/submissions.rs index b7bda9b..8971a8b 100644 --- a/src/submissions.rs +++ b/src/submissions.rs @@ -9,8 +9,8 @@ use crate::{ ActixLoader, State, }; use actix_web::{client::Client, web, HttpRequest, HttpResponse, Scope}; -use hyaenidae_profiles::store::{File, Profile, Submission}; -use hyaenidae_toolkit::{Button, FileInput, TextInput, Tile}; +use hyaenidae_profiles::store::{File, Profile, Submission, Visibility}; +use hyaenidae_toolkit::{Button, FileInput, Select, TextInput, Tile}; use i18n_embed_fl::fl; use std::collections::HashMap; use uuid::Uuid; @@ -312,6 +312,17 @@ impl SubmissionState { }) } + pub(crate) fn visibility(&self, loader: &ActixLoader) -> Select { + Select::new("visibility") + .title(&fl!(loader, "submission-visibility-select")) + .options(&[ + (&fl!(loader, "submission-visibility-followers"), "Followers"), + (&fl!(loader, "submission-visibility-unlisted"), "Unlisted"), + (&fl!(loader, "submission-visibility-public"), "Public"), + ]) + .default_option(&self.submission.visibility().to_string()) + } + pub(crate) fn title_input(&self, loader: &ActixLoader) -> TextInput { TextInput::new("title") .title(&fl!(loader, "update-submission-title-input")) @@ -690,40 +701,90 @@ fn submission_nav( } async fn adjacent_submissions( - submission_id: Uuid, - is_published: bool, + viewer: Option, + submission: &Submission, state: &State, ) -> Result<(Option, Option), Error> { + let submission_id = submission.id(); + let is_published = submission.published().is_some(); let store = state.profiles.clone(); let (next, prev) = web::block(move || { if is_published { + let inner_store = store.clone(); let prev = store .store .submissions .published_newer_than_for_profile(submission_id) .filter(|id| *id != submission_id) - .next(); + .find_map(move |id| { + let submission = inner_store.store.submissions.by_id(id).ok()??; + + crate::pagination::submission::can_view( + viewer, + &submission, + &inner_store.store, + &mut Default::default(), + true, + ) + .map(move |_| id) + }); + let next = store .store .submissions .published_older_than_for_profile(submission_id) .filter(|id| *id != submission_id) - .next(); + .find_map(move |id| { + let submission = store.store.submissions.by_id(id).ok()??; + + crate::pagination::submission::can_view( + viewer, + &submission, + &store.store, + &mut Default::default(), + true, + ) + .map(move |_| id) + }); Ok((next, prev)) as Result<_, Error> } else { + let inner_store = store.clone(); let prev = store .store .submissions .drafted_newer_than_for_profile(submission_id) .filter(|id| *id != submission_id) - .next(); + .find_map(move |id| { + let submission = inner_store.store.submissions.by_id(id).ok()??; + + crate::pagination::submission::can_view( + viewer, + &submission, + &inner_store.store, + &mut Default::default(), + true, + ) + .map(move |_| id) + }); + let next = store .store .submissions .drafted_older_than_for_profile(submission_id) .filter(|id| *id != submission_id) - .next(); + .find_map(move |id| { + let submission = store.store.submissions.by_id(id).ok()??; + + crate::pagination::submission::can_view( + viewer, + &submission, + &store.store, + &mut Default::default(), + true, + ) + .map(move |_| id) + }); Ok((next, prev)) as Result<_, Error> } @@ -762,7 +823,7 @@ async fn submission_page( } let (next_submission, previous_submission) = - adjacent_submissions(submission.id(), submission.published().is_some(), &state).await?; + adjacent_submissions(viewer, &submission, &state).await?; let (nav, current_file) = submission_nav( page.map(|p| p.into_inner()), @@ -895,7 +956,7 @@ async fn create_comment( let cache = files_for_profile(&poster, cache, &state).await?; let (next_submission, previous_submission) = - adjacent_submissions(submission.id(), submission.published().is_some(), &state).await?; + adjacent_submissions(Some(profile.id()), &submission, &state).await?; let (nav, current_file) = submission_nav( page.map(|p| p.into_inner()), @@ -932,6 +993,7 @@ async fn create_comment( struct UpdateSubmissionForm { title: String, description: String, + visibility: Option, } async fn update_submission( @@ -962,6 +1024,7 @@ async fn update_submission( submission.id(), form.title.clone(), Some(form.description.clone()), + form.visibility, )) .await; diff --git a/templates/browse.rs.html b/templates/browse.rs.html index f855aae..7554d6a 100644 --- a/templates/browse.rs.html +++ b/templates/browse.rs.html @@ -12,16 +12,18 @@ @(loader: &ActixLoader, browse_view: &ViewBrowseState, nav_state: &NavState) @:wide(loader, &fl!(loader, "site-name"), &fl!(loader, "site-description"), nav_state, {}, { -
- @:tab_group({ - @:tab(Tab::new("/browse").selected(true), { - @fl!(loader, "submissions-tab") + @if browse_view.is_logged_in() { +
+ @:tab_group({ + @:tab(Tab::new("/browse").selected(true), { + @fl!(loader, "submissions-tab") + }) + @:tab(Tab::new("/discover"), { + @fl!(loader, "profiles-tab") + }) }) - @:tab(Tab::new("/discover"), { - @fl!(loader, "profiles-tab") - }) - }) -
+
+ } @if browse_view.has_submissions() { @if browse_view.has_nav() { @:thumbnail_border({ diff --git a/templates/submissions/update.rs.html b/templates/submissions/update.rs.html index b6c5cdd..32a7ec2 100644 --- a/templates/submissions/update.rs.html +++ b/templates/submissions/update.rs.html @@ -1,7 +1,11 @@ @use crate::ActixLoader; @use crate::templates::{button_js, file_js}; @use crate::{templates::layouts::home, nav::NavState, submissions::SubmissionState}; -@use hyaenidae_toolkit::{templates::{button_group, card, card_body, card_title, file_input, text_input}, Button, Card}; +@use hyaenidae_toolkit::{templates::{button_group}, Button}; +@use hyaenidae_toolkit::{templates::{card, card_body, card_title}, Card}; +@use hyaenidae_toolkit::templates::file_input; +@use hyaenidae_toolkit::templates::select; +@use hyaenidae_toolkit::templates::text_input; @use hyaenidae_toolkit::templates::image; @use i18n_embed_fl::fl; @@ -39,6 +43,9 @@ @:card_body({ @:text_input(&state.title_input(loader).dark(nav_state.dark())) @:text_input(&state.description_input(loader).dark(nav_state.dark())) + @if !state.is_published() { + @:select(&state.visibility(loader).dark(nav_state.dark())) + } }) @:card_body({ @:button_group(&[ diff --git a/translations/en-US/hyaenidae.ftl b/translations/en-US/hyaenidae.ftl index cbc7c90..e803181 100644 --- a/translations/en-US/hyaenidae.ftl +++ b/translations/en-US/hyaenidae.ftl @@ -169,6 +169,11 @@ create-submission-heading = Select a file to post create-submission-input = Select Image create-submission-button = Next +submission-visibility-select = Visibility +submission-visibility-followers = Followers Only +submission-visibility-unlisted = Unlisted +submission-visibility-public = Public + update-submission-title = Edit Submission update-submission-subtitle = Edit information or update images update-submission-publish-title = Publish Submission