]> Untitled Git - lemmy.git/commitdiff
Merge branch 'main' into feature/mark_post_as_read
authorDessalines <tyhou13@gmx.com>
Mon, 26 Apr 2021 14:44:19 +0000 (10:44 -0400)
committerDessalines <tyhou13@gmx.com>
Mon, 26 Apr 2021 14:44:19 +0000 (10:44 -0400)
1  2 
crates/api/src/local_user.rs
crates/api/src/site.rs
crates/api_common/src/lib.rs
crates/api_common/src/person.rs
crates/api_crud/src/comment/read.rs
crates/api_crud/src/post/read.rs
crates/api_crud/src/user/read.rs
crates/db_views/src/post_view.rs
crates/routes/src/feeds.rs

index c0ca8e32e8f460ca0364999495345d02ca92ec18,e36e86b4c976212da820d094859340245757ceb6..7fb4b83f9f4874dc77176ba151470a61f9b6209d
@@@ -16,6 -16,7 +16,7 @@@ use lemmy_api_common::
  use lemmy_db_queries::{
    diesel_option_overwrite,
    diesel_option_overwrite_to_url,
+   from_opt_str_to_opt_enum,
    source::{
      comment::Comment_,
      local_user::LocalUser_,
@@@ -68,7 -69,6 +69,6 @@@ use lemmy_websocket::
    LemmyContext,
    UserOperation,
  };
- use std::str::FromStr;
  
  #[async_trait::async_trait(?Send)]
  impl Perform for Login {
@@@ -240,7 -240,6 +240,7 @@@ impl Perform for SaveUserSettings 
        default_listing_type,
        lang: data.lang.to_owned(),
        show_avatars: data.show_avatars,
 +      show_read_posts: data.show_read_posts,
        send_notifications_to_email: data.send_notifications_to_email,
      };
  
@@@ -398,7 -397,7 +398,7 @@@ impl Perform for BanPerson 
      }
  
      // Remove their data if that's desired
-     if data.remove_data {
+     if data.remove_data.unwrap_or(false) {
        // Posts
        blocking(context.pool(), move |conn: &'_ _| {
          Post::update_removed_for_creator(conn, banned_person_id, None, true)
@@@ -463,7 -462,7 +463,7 @@@ impl Perform for GetReplies 
      let data: &GetReplies = &self;
      let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
  
-     let sort = SortType::from_str(&data.sort)?;
+     let sort: Option<SortType> = from_opt_str_to_opt_enum(&data.sort);
  
      let page = data.page;
      let limit = data.limit;
  
      let replies = blocking(context.pool(), move |conn| {
        CommentQueryBuilder::create(conn)
-         .sort(&sort)
+         .sort(sort)
          .unread_only(unread_only)
          .recipient_id(person_id)
          .show_bot_accounts(show_bot_accounts)
@@@ -500,7 -499,7 +500,7 @@@ impl Perform for GetPersonMentions 
      let data: &GetPersonMentions = &self;
      let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
  
-     let sort = SortType::from_str(&data.sort)?;
+     let sort: Option<SortType> = from_opt_str_to_opt_enum(&data.sort);
  
      let page = data.page;
      let limit = data.limit;
        PersonMentionQueryBuilder::create(conn)
          .recipient_id(person_id)
          .my_person_id(person_id)
-         .sort(&sort)
+         .sort(sort)
          .unread_only(unread_only)
          .page(page)
          .limit(limit)
diff --combined crates/api/src/site.rs
index fa8dd5e4c76e9cd0bb00fbd02455287780c86b39,c55ac6645d202f4f45fc7d628a37e168e6dd445c..dab4583041ef455141d350679c4461adcd3f7da7
@@@ -9,12 -9,18 +9,16 @@@ use lemmy_api_common::
    get_local_user_view_from_jwt_opt,
    is_admin,
    site::*,
--  user_show_bot_accounts,
--  user_show_nsfw,
-   user_show_read_posts,
  };
  use lemmy_apub::fetcher::search::search_by_apub_id;
- use lemmy_db_queries::{source::site::Site_, Crud, SearchType, SortType};
+ use lemmy_db_queries::{
+   from_opt_str_to_opt_enum,
+   source::site::Site_,
+   Crud,
+   ListingType,
+   SearchType,
+   SortType,
+ };
  use lemmy_db_schema::source::{moderator::*, site::Site};
  use lemmy_db_views::{
    comment_view::CommentQueryBuilder,
@@@ -46,7 -52,6 +50,6 @@@ use lemmy_utils::
  };
  use lemmy_websocket::LemmyContext;
  use log::debug;
- use std::str::FromStr;
  
  #[async_trait::async_trait(?Send)]
  impl Perform for GetModlog {
@@@ -140,14 -145,11 +143,16 @@@ impl Perform for Search 
  
      let local_user_view = get_local_user_view_from_jwt_opt(&data.auth, context.pool()).await?;
  
--    let show_nsfw = user_show_nsfw(&local_user_view);
--    let show_bot_accounts = user_show_bot_accounts(&local_user_view);
-     let show_read_posts = user_show_read_posts(&local_user_view);
++    let show_nsfw = local_user_view.as_ref().map(|t| t.local_user.show_nsfw);
++    let show_bot_accounts = local_user_view
++      .as_ref()
++      .map(|t| t.local_user.show_bot_accounts);
++    let show_read_posts = local_user_view
++      .as_ref()
++      .map(|t| t.local_user.show_read_posts);
  
      let person_id = local_user_view.map(|u| u.person.id);
  
-     let type_ = SearchType::from_str(&data.type_)?;
      let mut posts = Vec::new();
      let mut comments = Vec::new();
      let mut communities = Vec::new();
      let q = data.q.to_owned();
      let page = data.page;
      let limit = data.limit;
-     let sort = SortType::from_str(&data.sort)?;
+     let sort: Option<SortType> = from_opt_str_to_opt_enum(&data.sort);
+     let listing_type: Option<ListingType> = from_opt_str_to_opt_enum(&data.listing_type);
+     let search_type: SearchType = from_opt_str_to_opt_enum(&data.type_).unwrap_or(SearchType::All);
      let community_id = data.community_id;
      let community_name = data.community_name.to_owned();
-     match type_ {
+     let creator_id = data.creator_id;
+     match search_type {
        SearchType::Posts => {
          posts = blocking(context.pool(), move |conn| {
            PostQueryBuilder::create(conn)
-             .sort(&sort)
+             .sort(sort)
              .show_nsfw(show_nsfw)
              .show_bot_accounts(show_bot_accounts)
 +            .show_read_posts(show_read_posts)
+             .listing_type(listing_type)
              .community_id(community_id)
              .community_name(community_name)
+             .creator_id(creator_id)
              .my_person_id(person_id)
              .search_term(q)
              .page(page)
        SearchType::Comments => {
          comments = blocking(context.pool(), move |conn| {
            CommentQueryBuilder::create(&conn)
-             .sort(&sort)
+             .sort(sort)
+             .listing_type(listing_type)
              .search_term(q)
              .show_bot_accounts(show_bot_accounts)
+             .community_id(community_id)
+             .community_name(community_name)
+             .creator_id(creator_id)
              .my_person_id(person_id)
              .page(page)
              .limit(limit)
        SearchType::Communities => {
          communities = blocking(context.pool(), move |conn| {
            CommunityQueryBuilder::create(conn)
-             .sort(&sort)
+             .sort(sort)
+             .listing_type(listing_type)
              .search_term(q)
              .my_person_id(person_id)
              .page(page)
        SearchType::Users => {
          users = blocking(context.pool(), move |conn| {
            PersonQueryBuilder::create(conn)
-             .sort(&sort)
+             .sort(sort)
              .search_term(q)
              .page(page)
              .limit(limit)
          .await??;
        }
        SearchType::All => {
+         // If the community or creator is included, dont search communities or users
+         let community_or_creator_included =
+           data.community_id.is_some() || data.community_name.is_some() || data.creator_id.is_some();
          posts = blocking(context.pool(), move |conn| {
            PostQueryBuilder::create(conn)
-             .sort(&sort)
+             .sort(sort)
              .show_nsfw(show_nsfw)
              .show_bot_accounts(show_bot_accounts)
 +            .show_read_posts(show_read_posts)
+             .listing_type(listing_type)
              .community_id(community_id)
              .community_name(community_name)
+             .creator_id(creator_id)
              .my_person_id(person_id)
              .search_term(q)
              .page(page)
          .await??;
  
          let q = data.q.to_owned();
-         let sort = SortType::from_str(&data.sort)?;
+         let community_name = data.community_name.to_owned();
  
          comments = blocking(context.pool(), move |conn| {
            CommentQueryBuilder::create(conn)
-             .sort(&sort)
+             .sort(sort)
+             .listing_type(listing_type)
              .search_term(q)
              .show_bot_accounts(show_bot_accounts)
+             .community_id(community_id)
+             .community_name(community_name)
+             .creator_id(creator_id)
              .my_person_id(person_id)
              .page(page)
              .limit(limit)
          .await??;
  
          let q = data.q.to_owned();
-         let sort = SortType::from_str(&data.sort)?;
  
-         communities = blocking(context.pool(), move |conn| {
-           CommunityQueryBuilder::create(conn)
-             .sort(&sort)
-             .search_term(q)
-             .my_person_id(person_id)
-             .page(page)
-             .limit(limit)
-             .list()
-         })
-         .await??;
+         communities = if community_or_creator_included {
+           vec![]
+         } else {
+           blocking(context.pool(), move |conn| {
+             CommunityQueryBuilder::create(conn)
+               .sort(sort)
+               .listing_type(listing_type)
+               .search_term(q)
+               .my_person_id(person_id)
+               .page(page)
+               .limit(limit)
+               .list()
+           })
+           .await??
+         };
  
          let q = data.q.to_owned();
-         let sort = SortType::from_str(&data.sort)?;
  
-         users = blocking(context.pool(), move |conn| {
-           PersonQueryBuilder::create(conn)
-             .sort(&sort)
-             .search_term(q)
-             .page(page)
-             .limit(limit)
-             .list()
-         })
-         .await??;
+         users = if community_or_creator_included {
+           vec![]
+         } else {
+           blocking(context.pool(), move |conn| {
+             PersonQueryBuilder::create(conn)
+               .sort(sort)
+               .search_term(q)
+               .page(page)
+               .limit(limit)
+               .list()
+           })
+           .await??
+         };
        }
        SearchType::Url => {
          posts = blocking(context.pool(), move |conn| {
            PostQueryBuilder::create(conn)
-             .sort(&sort)
+             .sort(sort)
              .show_nsfw(show_nsfw)
              .show_bot_accounts(show_bot_accounts)
 +            .show_read_posts(show_read_posts)
+             .listing_type(listing_type)
              .my_person_id(person_id)
              .community_id(community_id)
              .community_name(community_name)
+             .creator_id(creator_id)
              .url_search(q)
              .page(page)
              .limit(limit)
  
      // Return the jwt
      Ok(SearchResponse {
-       type_: data.type_.to_owned(),
+       type_: search_type.to_string(),
        comments,
        posts,
        communities,
index 47f4752dd489acaafe3c0f82831fb4f87501d7e0,1a644b7d4d775745de63bb1d14fe1c604b9e54cb..f2b41be50c8c027e619b4c93d4e7ac95bec07a67
@@@ -14,7 -14,6 +14,7 @@@ use lemmy_db_queries::
    },
    Crud,
    DbPool,
 +  Readable,
  };
  use lemmy_db_schema::{
    source::{
@@@ -22,7 -21,7 +22,7 @@@
      community::{Community, CommunityModerator},
      person::Person,
      person_mention::{PersonMention, PersonMentionForm},
 -    post::Post,
 +    post::{Post, PostRead, PostReadForm},
      site::Site,
    },
    CommunityId,
@@@ -237,50 -236,28 +237,26 @@@ pub fn is_admin(local_user_view: &Local
    Ok(())
  }
  
--/// A helper method for showing the bot account
--pub fn user_show_bot_accounts(local_user_view: &Option<LocalUserView>) -> bool {
--  match local_user_view {
--    Some(uv) => uv.to_owned().local_user.show_bot_accounts,
--    None => true,
--  }
--}
--
--/// A helper method for showing nsfw
--pub fn user_show_nsfw(local_user_view: &Option<LocalUserView>) -> bool {
--  match &local_user_view {
--    Some(uv) => uv.local_user.show_nsfw,
--    None => false,
-   }
- }
- /// A helper method for showing read posts
- pub fn user_show_read_posts(local_user_view: &Option<LocalUserView>) -> bool {
-   match local_user_view {
-     Some(uv) => uv.to_owned().local_user.show_read_posts,
-     None => true,
--  }
--}
--
  pub async fn get_post(post_id: PostId, pool: &DbPool) -> Result<Post, LemmyError> {
    blocking(pool, move |conn| Post::read(conn, post_id))
      .await?
      .map_err(|_| ApiError::err("couldnt_find_post").into())
  }
  
 +pub async fn mark_post_as_read(
 +  person_id: PersonId,
 +  post_id: PostId,
 +  pool: &DbPool,
 +) -> Result<PostRead, LemmyError> {
 +  let post_read_form = PostReadForm { post_id, person_id };
 +
 +  blocking(pool, move |conn| {
 +    PostRead::mark_as_read(conn, &post_read_form)
 +  })
 +  .await?
 +  .map_err(|_| ApiError::err("couldnt_mark_post_as_read").into())
 +}
 +
  pub async fn get_local_user_view_from_jwt(
    jwt: &str,
    pool: &DbPool,
index f8fbe5d0d1812d749f0e262c8f844d0bc1d6bf83,8349f2a1f869fe1aff74d4e26e8fed77e67cdca3..12cc5deeb60efefd458d9564f2982bb80dbc1b77
@@@ -21,10 -21,10 +21,10 @@@ use lemmy_db_schema::{CommunityId, Pers
  #[derive(Deserialize)]
  pub struct Register {
    pub username: String,
-   pub email: Option<String>,
    pub password: String,
    pub password_verify: String,
    pub show_nsfw: bool,
+   pub email: Option<String>,
    pub captcha_uuid: Option<String>,
    pub captcha_answer: Option<String>,
  }
@@@ -62,7 -62,6 +62,7 @@@ pub struct SaveUserSettings 
    pub send_notifications_to_email: Option<bool>,
    pub bot_account: Option<bool>,
    pub show_bot_accounts: Option<bool>,
 +  pub show_read_posts: Option<bool>,
    pub auth: String,
  }
  
@@@ -81,13 -80,13 +81,13 @@@ pub struct LoginResponse 
  
  #[derive(Deserialize)]
  pub struct GetPersonDetails {
-   pub person_id: Option<PersonId>,
+   pub person_id: Option<PersonId>, // One of these two are required
    pub username: Option<String>,
-   pub sort: String,
+   pub sort: Option<String>,
    pub page: Option<i64>,
    pub limit: Option<i64>,
    pub community_id: Option<CommunityId>,
-   pub saved_only: bool,
+   pub saved_only: Option<bool>,
    pub auth: Option<String>,
  }
  
@@@ -131,7 -130,7 +131,7 @@@ pub struct AddAdminResponse 
  pub struct BanPerson {
    pub person_id: PersonId,
    pub ban: bool,
-   pub remove_data: bool,
+   pub remove_data: Option<bool>,
    pub reason: Option<String>,
    pub expires: Option<i64>,
    pub auth: String,
@@@ -145,19 -144,19 +145,19 @@@ pub struct BanPersonResponse 
  
  #[derive(Deserialize)]
  pub struct GetReplies {
-   pub sort: String,
+   pub sort: Option<String>,
    pub page: Option<i64>,
    pub limit: Option<i64>,
-   pub unread_only: bool,
+   pub unread_only: Option<bool>,
    pub auth: String,
  }
  
  #[derive(Deserialize)]
  pub struct GetPersonMentions {
-   pub sort: String,
+   pub sort: Option<String>,
    pub page: Option<i64>,
    pub limit: Option<i64>,
-   pub unread_only: bool,
+   pub unread_only: Option<bool>,
    pub auth: String,
  }
  
@@@ -224,7 -223,7 +224,7 @@@ pub struct MarkPrivateMessageAsRead 
  
  #[derive(Deserialize)]
  pub struct GetPrivateMessages {
-   pub unread_only: bool,
+   pub unread_only: Option<bool>,
    pub page: Option<i64>,
    pub limit: Option<i64>,
    pub auth: String,
index 4d144382089688aa2b1a2eeb137941b4dad884b1,f82b97481844eab8c314ebb2dd339662b87fa906..12ccbd5a1a6b6b6b7427d66ac3c44d7072673da9
@@@ -1,16 -1,15 +1,10 @@@
  use crate::PerformCrud;
  use actix_web::web::Data;
--use lemmy_api_common::{
--  blocking,
--  comment::*,
--  get_local_user_view_from_jwt_opt,
--  user_show_bot_accounts,
--};
- use lemmy_db_queries::{ListingType, SortType};
++use lemmy_api_common::{blocking, comment::*, get_local_user_view_from_jwt_opt};
+ use lemmy_db_queries::{from_opt_str_to_opt_enum, ListingType, SortType};
  use lemmy_db_views::comment_view::CommentQueryBuilder;
  use lemmy_utils::{ApiError, ConnectionId, LemmyError};
  use lemmy_websocket::LemmyContext;
- use std::str::FromStr;
  
  #[async_trait::async_trait(?Send)]
  impl PerformCrud for GetComments {
      let data: &GetComments = &self;
      let local_user_view = get_local_user_view_from_jwt_opt(&data.auth, context.pool()).await?;
  
--    let show_bot_accounts = user_show_bot_accounts(&local_user_view);
++    let show_bot_accounts = local_user_view
++      .as_ref()
++      .map(|t| t.local_user.show_bot_accounts);
      let person_id = local_user_view.map(|u| u.person.id);
  
-     let type_ = ListingType::from_str(&data.type_)?;
-     let sort = SortType::from_str(&data.sort)?;
+     let sort: Option<SortType> = from_opt_str_to_opt_enum(&data.sort);
+     let listing_type: Option<ListingType> = from_opt_str_to_opt_enum(&data.type_);
  
      let community_id = data.community_id;
      let community_name = data.community_name.to_owned();
@@@ -37,8 -36,8 +33,8 @@@
      let limit = data.limit;
      let comments = blocking(context.pool(), move |conn| {
        CommentQueryBuilder::create(conn)
-         .listing_type(type_)
-         .sort(&sort)
+         .listing_type(listing_type)
+         .sort(sort)
          .saved_only(saved_only)
          .community_id(community_id)
          .community_name(community_name)
index d44f029a0973b07a801fe88969fe4e0707d3b158,14c6cad5f453d1ccd1e9d6433d50c78d0fc6315a..d49764bba269783b09970ad4425aee4eeb09be50
@@@ -1,15 -1,13 +1,7 @@@
  use crate::PerformCrud;
  use actix_web::web::Data;
--use lemmy_api_common::{
--  blocking,
--  get_local_user_view_from_jwt_opt,
-   mark_post_as_read,
--  post::*,
--  user_show_bot_accounts,
--  user_show_nsfw,
-   user_show_read_posts,
--};
- use lemmy_db_queries::{ListingType, SortType};
++use lemmy_api_common::{blocking, get_local_user_view_from_jwt_opt, mark_post_as_read, post::*};
+ use lemmy_db_queries::{from_opt_str_to_opt_enum, ListingType, SortType};
  use lemmy_db_views::{
    comment_view::CommentQueryBuilder,
    post_view::{PostQueryBuilder, PostView},
@@@ -20,7 -18,6 +12,6 @@@ use lemmy_db_views_actor::
  };
  use lemmy_utils::{ApiError, ConnectionId, LemmyError};
  use lemmy_websocket::{messages::GetPostUsersOnline, LemmyContext};
- use std::str::FromStr;
  
  #[async_trait::async_trait(?Send)]
  impl PerformCrud for GetPost {
@@@ -34,8 -31,8 +25,9 @@@
      let data: &GetPost = &self;
      let local_user_view = get_local_user_view_from_jwt_opt(&data.auth, context.pool()).await?;
  
--    let show_bot_accounts = user_show_bot_accounts(&local_user_view);
--
++    let show_bot_accounts = local_user_view
++      .as_ref()
++      .map(|t| t.local_user.show_bot_accounts);
      let person_id = local_user_view.map(|u| u.person.id);
  
      let id = data.id;
      .await?
      .map_err(|_| ApiError::err("couldnt_find_post"))?;
  
 +    // Mark the post as read
 +    if let Some(person_id) = person_id {
 +      mark_post_as_read(person_id, id, context.pool()).await?;
 +    }
 +
      let id = data.id;
      let comments = blocking(context.pool(), move |conn| {
        CommentQueryBuilder::create(conn)
@@@ -105,12 -97,11 +97,16 @@@ impl PerformCrud for GetPosts 
  
      let person_id = local_user_view.to_owned().map(|l| l.person.id);
  
--    let show_nsfw = user_show_nsfw(&local_user_view);
--    let show_bot_accounts = user_show_bot_accounts(&local_user_view);
-     let show_read_posts = user_show_read_posts(&local_user_view);
++    let show_nsfw = local_user_view.as_ref().map(|t| t.local_user.show_nsfw);
++    let show_bot_accounts = local_user_view
++      .as_ref()
++      .map(|t| t.local_user.show_bot_accounts);
++    let show_read_posts = local_user_view
++      .as_ref()
++      .map(|t| t.local_user.show_read_posts);
  
-     let type_ = ListingType::from_str(&data.type_)?;
-     let sort = SortType::from_str(&data.sort)?;
+     let sort: Option<SortType> = from_opt_str_to_opt_enum(&data.sort);
+     let listing_type: Option<ListingType> = from_opt_str_to_opt_enum(&data.type_);
  
      let page = data.page;
      let limit = data.limit;
  
      let posts = blocking(context.pool(), move |conn| {
        PostQueryBuilder::create(conn)
-         .listing_type(&type_)
-         .sort(&sort)
+         .listing_type(listing_type)
+         .sort(sort)
          .show_nsfw(show_nsfw)
          .show_bot_accounts(show_bot_accounts)
 +        .show_read_posts(show_read_posts)
          .community_id(community_id)
          .community_name(community_name)
          .saved_only(saved_only)
index e0e3808c17ced23885055b17c034fe1caae0fbf2,39431128aee3d70846a5278ff5bb2425b9d84907..132bdd78f4e32d633332f098b97fac9b081aea14
@@@ -1,14 -1,13 +1,7 @@@
  use crate::PerformCrud;
  use actix_web::web::Data;
--use lemmy_api_common::{
--  blocking,
--  get_local_user_view_from_jwt_opt,
--  person::*,
--  user_show_bot_accounts,
--  user_show_nsfw,
-   user_show_read_posts,
--};
- use lemmy_db_queries::{source::person::Person_, SortType};
++use lemmy_api_common::{blocking, get_local_user_view_from_jwt_opt, person::*};
+ use lemmy_db_queries::{from_opt_str_to_opt_enum, source::person::Person_, SortType};
  use lemmy_db_schema::source::person::*;
  use lemmy_db_views::{comment_view::CommentQueryBuilder, post_view::PostQueryBuilder};
  use lemmy_db_views_actor::{
@@@ -18,7 -17,6 +11,6 @@@
  };
  use lemmy_utils::{ApiError, ConnectionId, LemmyError};
  use lemmy_websocket::LemmyContext;
- use std::str::FromStr;
  
  #[async_trait::async_trait(?Send)]
  impl PerformCrud for GetPersonDetails {
      let data: &GetPersonDetails = &self;
      let local_user_view = get_local_user_view_from_jwt_opt(&data.auth, context.pool()).await?;
  
--    let show_nsfw = user_show_nsfw(&local_user_view);
--    let show_bot_accounts = user_show_bot_accounts(&local_user_view);
-     let show_read_posts = user_show_read_posts(&local_user_view);
++    let show_nsfw = local_user_view.as_ref().map(|t| t.local_user.show_nsfw);
++    let show_bot_accounts = local_user_view
++      .as_ref()
++      .map(|t| t.local_user.show_bot_accounts);
++    let show_read_posts = local_user_view
++      .as_ref()
++      .map(|t| t.local_user.show_read_posts);
  
-     let sort = SortType::from_str(&data.sort)?;
+     let sort: Option<SortType> = from_opt_str_to_opt_enum(&data.sort);
  
      let username = data
        .username
  
      let (posts, comments) = blocking(context.pool(), move |conn| {
        let mut posts_query = PostQueryBuilder::create(conn)
-         .sort(&sort)
+         .sort(sort)
          .show_nsfw(show_nsfw)
          .show_bot_accounts(show_bot_accounts)
 +        .show_read_posts(show_read_posts)
          .saved_only(saved_only)
          .community_id(community_id)
          .my_person_id(person_id)
@@@ -84,7 -80,7 +80,7 @@@
        let mut comments_query = CommentQueryBuilder::create(conn)
          .my_person_id(person_id)
          .show_bot_accounts(show_bot_accounts)
-         .sort(&sort)
+         .sort(sort)
          .saved_only(saved_only)
          .community_id(community_id)
          .page(page)
@@@ -92,7 -88,7 +88,7 @@@
  
        // If its saved only, you don't care what creator it was
        // Or, if its not saved, then you only want it for that specific creator
-       if !saved_only {
+       if !saved_only.unwrap_or(false) {
          posts_query = posts_query.creator_id(person_details_id);
          comments_query = comments_query.creator_id(person_details_id);
        }
index 8a533412f7da77abfbbf2925dcf0afcac427c11e,fb8f073365ad49b5c8e496e971ae99759966a530..1d8ea80e607720a0e4b2492b79eacb1de16be9ba
@@@ -155,18 -155,18 +155,18 @@@ impl PostView 
  
  pub struct PostQueryBuilder<'a> {
    conn: &'a PgConnection,
-   listing_type: &'a ListingType,
-   sort: &'a SortType,
+   listing_type: Option<ListingType>,
+   sort: Option<SortType>,
    creator_id: Option<PersonId>,
    community_id: Option<CommunityId>,
    community_name: Option<String>,
    my_person_id: Option<PersonId>,
    search_term: Option<String>,
    url_search: Option<String>,
-   show_nsfw: bool,
-   show_bot_accounts: bool,
-   show_read_posts: bool,
-   saved_only: bool,
+   show_nsfw: Option<bool>,
+   show_bot_accounts: Option<bool>,
++  show_read_posts: Option<bool>,
+   saved_only: Option<bool>,
 -  unread_only: Option<bool>,
    page: Option<i64>,
    limit: Option<i64>,
  }
@@@ -175,30 -175,30 +175,30 @@@ impl<'a> PostQueryBuilder<'a> 
    pub fn create(conn: &'a PgConnection) -> Self {
      PostQueryBuilder {
        conn,
-       listing_type: &ListingType::All,
-       sort: &SortType::Hot,
+       listing_type: None,
+       sort: None,
        creator_id: None,
        community_id: None,
        community_name: None,
        my_person_id: None,
        search_term: None,
        url_search: None,
-       show_nsfw: true,
-       show_bot_accounts: true,
-       show_read_posts: true,
-       saved_only: false,
+       show_nsfw: None,
+       show_bot_accounts: None,
++      show_read_posts: None,
+       saved_only: None,
 -      unread_only: None,
        page: None,
        limit: None,
      }
    }
  
-   pub fn listing_type(mut self, listing_type: &'a ListingType) -> Self {
-     self.listing_type = listing_type;
+   pub fn listing_type<T: MaybeOptional<ListingType>>(mut self, listing_type: T) -> Self {
+     self.listing_type = listing_type.get_optional();
      self
    }
  
-   pub fn sort(mut self, sort: &'a SortType) -> Self {
-     self.sort = sort;
+   pub fn sort<T: MaybeOptional<SortType>>(mut self, sort: T) -> Self {
+     self.sort = sort.get_optional();
      self
    }
  
      self
    }
  
-   pub fn show_nsfw(mut self, show_nsfw: bool) -> Self {
-     self.show_nsfw = show_nsfw;
+   pub fn show_nsfw<T: MaybeOptional<bool>>(mut self, show_nsfw: T) -> Self {
+     self.show_nsfw = show_nsfw.get_optional();
      self
    }
  
-   pub fn show_bot_accounts(mut self, show_bot_accounts: bool) -> Self {
-     self.show_bot_accounts = show_bot_accounts;
+   pub fn show_bot_accounts<T: MaybeOptional<bool>>(mut self, show_bot_accounts: T) -> Self {
+     self.show_bot_accounts = show_bot_accounts.get_optional();
      self
    }
  
-   pub fn show_read_posts(mut self, show_read_posts: bool) -> Self {
-     self.show_read_posts = show_read_posts;
++  pub fn show_read_posts<T: MaybeOptional<bool>>(mut self, show_read_posts: T) -> Self {
++    self.show_read_posts = show_read_posts.get_optional();
 +    self
 +  }
 +
-   pub fn saved_only(mut self, saved_only: bool) -> Self {
-     self.saved_only = saved_only;
+   pub fn saved_only<T: MaybeOptional<bool>>(mut self, saved_only: T) -> Self {
+     self.saved_only = saved_only.get_optional();
      self
    }
  
        ))
        .into_boxed();
  
-     query = match self.listing_type {
-       ListingType::Subscribed => query.filter(community_follower::person_id.is_not_null()), // TODO could be this: and(community_follower::person_id.eq(person_id_join)),
-       ListingType::Local => query.filter(community::local.eq(true)),
-       _ => query,
-     };
+     if let Some(listing_type) = self.listing_type {
+       query = match listing_type {
+         ListingType::Subscribed => query.filter(community_follower::person_id.is_not_null()),
+         ListingType::Local => query.filter(community::local.eq(true)),
+         _ => query,
+       };
+     }
  
      if let Some(community_id) = self.community_id {
        query = query
        query = query.filter(post::creator_id.eq(creator_id));
      }
  
-     if !self.show_nsfw {
+     if !self.show_nsfw.unwrap_or(true) {
        query = query
          .filter(post::nsfw.eq(false))
          .filter(community::nsfw.eq(false));
      };
  
-     if !self.show_bot_accounts {
+     if !self.show_bot_accounts.unwrap_or(true) {
        query = query.filter(person::bot_account.eq(false));
      };
  
-     if self.saved_only {
 -    if self.saved_only.unwrap_or(false) {
--      query = query.filter(post_saved::id.is_not_null());
++    if !self.show_read_posts.unwrap_or(true) {
++      query = query.filter(post_read::id.is_null());
      };
  
-     if !self.show_read_posts {
-       query = query.filter(post_read::id.is_null());
 -    if self.unread_only.unwrap_or(false) {
 -      query = query.filter(post_read::id.is_not_null());
++    if self.saved_only.unwrap_or(false) {
++      query = query.filter(post_saved::id.is_not_null());
      };
  
-     query = match self.sort {
+     query = match self.sort.unwrap_or(SortType::Hot) {
        SortType::Active => query
          .then_order_by(
            hot_rank(
@@@ -526,8 -523,8 +528,8 @@@ mod tests 
      };
  
      let read_post_listings_with_person = PostQueryBuilder::create(&conn)
-       .listing_type(&ListingType::Community)
-       .sort(&SortType::New)
+       .listing_type(ListingType::Community)
+       .sort(SortType::New)
        .show_bot_accounts(false)
        .community_id(inserted_community.id)
        .my_person_id(inserted_person.id)
        .unwrap();
  
      let read_post_listings_no_person = PostQueryBuilder::create(&conn)
-       .listing_type(&ListingType::Community)
-       .sort(&SortType::New)
+       .listing_type(ListingType::Community)
+       .sort(SortType::New)
        .community_id(inserted_community.id)
        .list()
        .unwrap();
index 2ed586737f3e9e688d3eb36119a09af08bd37ebe,a4f6a45a06c9c60502670094b7c34bb0791e4f63..06b9ac13aef395940803d911cb0e3691029b0f12
@@@ -90,11 -90,10 +90,10 @@@ async fn get_feed_data
  ) -> Result<HttpResponse, LemmyError> {
    let site_view = blocking(context.pool(), move |conn| SiteView::read(&conn)).await??;
  
-   let listing_type_ = listing_type.clone();
    let posts = blocking(context.pool(), move |conn| {
      PostQueryBuilder::create(&conn)
-       .listing_type(&listing_type_)
-       .sort(&sort_type)
+       .listing_type(listing_type)
+       .sort(sort_type)
        .list()
    })
    .await??;
@@@ -174,8 -173,8 +173,8 @@@ fn get_feed_user
    let person = Person::find_by_name(&conn, &user_name)?;
  
    let posts = PostQueryBuilder::create(&conn)
-     .listing_type(&ListingType::All)
-     .sort(sort_type)
+     .listing_type(ListingType::All)
+     .sort(*sort_type)
      .creator_id(person.id)
      .list()?;
  
@@@ -200,8 -199,8 +199,8 @@@ fn get_feed_community
    let community = Community::read_from_name(&conn, &community_name)?;
  
    let posts = PostQueryBuilder::create(&conn)
-     .listing_type(&ListingType::All)
-     .sort(sort_type)
+     .listing_type(ListingType::All)
+     .sort(*sort_type)
      .community_id(community.id)
      .list()?;
  
@@@ -231,14 -230,12 +230,14 @@@ fn get_feed_front
    let local_user = LocalUser::read(&conn, local_user_id)?;
    let person_id = local_user.person_id;
    let show_bot_accounts = local_user.show_bot_accounts;
 +  let show_read_posts = local_user.show_read_posts;
  
    let posts = PostQueryBuilder::create(&conn)
-     .listing_type(&ListingType::Subscribed)
+     .listing_type(ListingType::Subscribed)
      .my_person_id(person_id)
      .show_bot_accounts(show_bot_accounts)
-     .sort(sort_type)
 +    .show_read_posts(show_read_posts)
+     .sort(*sort_type)
      .list()?;
  
    let items = create_post_items(posts)?;
@@@ -270,13 -267,13 +269,13 @@@ fn get_feed_inbox(conn: &PgConnection, 
      .recipient_id(person_id)
      .my_person_id(person_id)
      .show_bot_accounts(show_bot_accounts)
-     .sort(&sort)
+     .sort(sort)
      .list()?;
  
    let mentions = PersonMentionQueryBuilder::create(&conn)
      .recipient_id(person_id)
      .my_person_id(person_id)
-     .sort(&sort)
+     .sort(sort)
      .list()?;
  
    let items = create_reply_and_mention_items(replies, mentions)?;