diff --git a/crates/app/src/public/html/profile/settings.lisp b/crates/app/src/public/html/profile/settings.lisp index 8c67bdd..50c0c60 100644 --- a/crates/app/src/public/html/profile/settings.lisp +++ b/crates/app/src/public/html/profile/settings.lisp @@ -1364,6 +1364,11 @@ \"{{ profile.settings.auto_unlist }}\", \"checkbox\", ], + [ + [\"all_timeline_hide_answers\", 'Hide posts answering questions from the \"All\" timeline'], + \"{{ profile.settings.all_timeline_hide_answers }}\", + \"checkbox\", + ], [[], \"Questions\", \"title\"], [ [ diff --git a/crates/app/src/routes/api/v1/communities/posts.rs b/crates/app/src/routes/api/v1/communities/posts.rs index 7bf4bf3..9e35fd9 100644 --- a/crates/app/src/routes/api/v1/communities/posts.rs +++ b/crates/app/src/routes/api/v1/communities/posts.rs @@ -792,7 +792,10 @@ pub async fn all_request( None => return Json(Error::NotAllowed.into()), }; - match data.get_latest_posts(12, props.page).await { + match data + .get_latest_posts(12, props.page, &Some(user.clone())) + .await + { Ok(posts) => { let ignore_users = crate::ignore_users_gen!(user!, #data); Json(ApiReturn { diff --git a/crates/app/src/routes/pages/misc.rs b/crates/app/src/routes/pages/misc.rs index 8b76292..8d0d8be 100644 --- a/crates/app/src/routes/pages/misc.rs +++ b/crates/app/src/routes/pages/misc.rs @@ -636,7 +636,9 @@ pub async fn swiss_army_timeline_request( } else { // everything else match req.tl { - DefaultTimelineChoice::AllPosts => data.0.get_latest_posts(12, req.page).await, + DefaultTimelineChoice::AllPosts => { + data.0.get_latest_posts(12, req.page, &user).await + } DefaultTimelineChoice::PopularPosts => { data.0.get_popular_posts(12, req.page, 604_800_000).await } diff --git a/crates/core/src/database/posts.rs b/crates/core/src/database/posts.rs index 4390f26..e52490a 100644 --- a/crates/core/src/database/posts.rs +++ b/crates/core/src/database/posts.rs @@ -1319,7 +1319,18 @@ impl DataManager { /// # Arguments /// * `batch` - the limit of posts in each page /// * `page` - the page number - pub async fn get_latest_posts(&self, batch: usize, page: usize) -> Result> { + pub async fn get_latest_posts( + &self, + batch: usize, + page: usize, + as_user: &Option, + ) -> Result> { + let hide_answers: bool = if let Some(user) = as_user { + user.settings.all_timeline_hide_answers + } else { + false + }; + let conn = match self.0.connect().await { Ok(c) => c, Err(e) => return Err(Error::DatabaseConnection(e.to_string())), @@ -1327,7 +1338,14 @@ impl DataManager { let res = query_rows!( &conn, - "SELECT * FROM posts WHERE replying_to = 0 AND NOT context LIKE '%\"is_nsfw\":true%' ORDER BY created DESC LIMIT $1 OFFSET $2", + &format!( + "SELECT * FROM posts WHERE replying_to = 0 AND NOT context LIKE '%\"is_nsfw\":true%'{} ORDER BY created DESC LIMIT $1 OFFSET $2", + if hide_answers { + " AND context::jsonb->>'answering' = '0'" + } else { + "" + } + ), &[&(batch as i64), &((page * batch) as i64)], |x| { Self::get_post_from_row(x) } ); diff --git a/crates/core/src/database/stacks.rs b/crates/core/src/database/stacks.rs index 47f5e53..a42c4a0 100644 --- a/crates/core/src/database/stacks.rs +++ b/crates/core/src/database/stacks.rs @@ -59,7 +59,7 @@ impl DataManager { match stack.sort { StackSort::Created => { self.fill_posts_with_community( - self.get_latest_posts(batch, page).await?, + self.get_latest_posts(batch, page, &user).await?, as_user_id, &ignore_users, user, diff --git a/crates/core/src/model/auth.rs b/crates/core/src/model/auth.rs index 5ff9c49..ff910f5 100644 --- a/crates/core/src/model/auth.rs +++ b/crates/core/src/model/auth.rs @@ -240,6 +240,9 @@ pub struct UserSettings { /// Automatically unlist posts from timelines. #[serde(default)] pub auto_unlist: bool, + /// Hide posts that are answering a question on the "All" timeline. + #[serde(default)] + pub all_timeline_hide_answers: bool, } fn mime_avif() -> String {