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 {