From 5b2be6f9dfa38fb5d5444b9d1646600e14b5c555 Mon Sep 17 00:00:00 2001 From: Dessalines Date: Sat, 24 Apr 2021 18:26:50 -0400 Subject: [PATCH] Add show_read_posts filter. Fixes #1561 --- crates/api/src/local_user.rs | 1 + crates/api/src/post.rs | 7 ++++++ crates/api/src/site.rs | 5 ++++ crates/api_common/src/lib.rs | 25 ++++++++++++++++++- crates/api_common/src/person.rs | 1 + crates/api_crud/src/post/create.rs | 17 ++++++++++--- crates/api_crud/src/post/read.rs | 9 +++++++ crates/api_crud/src/user/create.rs | 1 + crates/api_crud/src/user/read.rs | 3 +++ crates/db_queries/src/source/local_user.rs | 2 ++ crates/db_queries/src/source/post.rs | 3 +++ crates/db_schema/src/schema.rs | 1 + crates/db_schema/src/source/local_user.rs | 3 +++ crates/db_views/src/post_view.rs | 14 +++++++---- crates/routes/src/feeds.rs | 2 ++ .../down.sql | 1 + .../up.sql | 1 + 17 files changed, 87 insertions(+), 9 deletions(-) create mode 100644 migrations/2021-04-24-174047_add_show_read_post_setting/down.sql create mode 100644 migrations/2021-04-24-174047_add_show_read_post_setting/up.sql diff --git a/crates/api/src/local_user.rs b/crates/api/src/local_user.rs index b273b5820..c0ca8e32e 100644 --- a/crates/api/src/local_user.rs +++ b/crates/api/src/local_user.rs @@ -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, }; diff --git a/crates/api/src/post.rs b/crates/api/src/post.rs index 34c9c4116..f0e4d91fa 100644 --- a/crates/api/src/post.rs +++ b/crates/api/src/post.rs @@ -6,6 +6,7 @@ use lemmy_api_common::{ check_downvotes_enabled, get_local_user_view_from_jwt, is_mod_or_admin, + mark_post_as_read, post::*, }; use lemmy_apub::{ApubLikeableType, ApubObjectType}; @@ -69,6 +70,9 @@ impl Perform for CreatePostLike { .await?; } + // Mark the post as read + mark_post_as_read(person_id, post_id, context.pool()).await?; + let post_id = data.post_id; let person_id = local_user_view.person.id; let post_view = blocking(context.pool(), move |conn| { @@ -269,6 +273,9 @@ impl Perform for SavePost { }) .await??; + // Mark the post as read + mark_post_as_read(person_id, post_id, context.pool()).await?; + Ok(PostResponse { post_view }) } } diff --git a/crates/api/src/site.rs b/crates/api/src/site.rs index aae400ca7..fa8dd5e4c 100644 --- a/crates/api/src/site.rs +++ b/crates/api/src/site.rs @@ -11,6 +11,7 @@ use lemmy_api_common::{ 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}; @@ -141,6 +142,7 @@ impl Perform for Search { 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 person_id = local_user_view.map(|u| u.person.id); @@ -166,6 +168,7 @@ impl Perform for Search { .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) .my_person_id(person_id) @@ -218,6 +221,7 @@ impl Perform for Search { .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) .my_person_id(person_id) @@ -276,6 +280,7 @@ impl Perform for Search { .sort(&sort) .show_nsfw(show_nsfw) .show_bot_accounts(show_bot_accounts) + .show_read_posts(show_read_posts) .my_person_id(person_id) .community_id(community_id) .community_name(community_name) diff --git a/crates/api_common/src/lib.rs b/crates/api_common/src/lib.rs index 1a644b7d4..47f4752dd 100644 --- a/crates/api_common/src/lib.rs +++ b/crates/api_common/src/lib.rs @@ -14,6 +14,7 @@ use lemmy_db_queries::{ }, Crud, DbPool, + Readable, }; use lemmy_db_schema::{ source::{ @@ -21,7 +22,7 @@ use lemmy_db_schema::{ community::{Community, CommunityModerator}, person::Person, person_mention::{PersonMention, PersonMentionForm}, - post::Post, + post::{Post, PostRead, PostReadForm}, site::Site, }, CommunityId, @@ -252,12 +253,34 @@ pub fn user_show_nsfw(local_user_view: &Option) -> bool { } } +/// A helper method for showing read posts +pub fn user_show_read_posts(local_user_view: &Option) -> 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 { 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 { + 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, diff --git a/crates/api_common/src/person.rs b/crates/api_common/src/person.rs index 5473a4820..f8fbe5d0d 100644 --- a/crates/api_common/src/person.rs +++ b/crates/api_common/src/person.rs @@ -62,6 +62,7 @@ pub struct SaveUserSettings { pub send_notifications_to_email: Option, pub bot_account: Option, pub show_bot_accounts: Option, + pub show_read_posts: Option, pub auth: String, } diff --git a/crates/api_crud/src/post/create.rs b/crates/api_crud/src/post/create.rs index 3a2311a76..835518a14 100644 --- a/crates/api_crud/src/post/create.rs +++ b/crates/api_crud/src/post/create.rs @@ -1,6 +1,12 @@ use crate::PerformCrud; use actix_web::web::Data; -use lemmy_api_common::{blocking, check_community_ban, get_local_user_view_from_jwt, post::*}; +use lemmy_api_common::{ + blocking, + check_community_ban, + get_local_user_view_from_jwt, + mark_post_as_read, + post::*, +}; use lemmy_apub::{generate_apub_endpoint, ApubLikeableType, ApubObjectType, EndpointType}; use lemmy_db_queries::{source::post::Post_, Crud, Likeable}; use lemmy_db_schema::source::post::*; @@ -81,9 +87,11 @@ impl PerformCrud for CreatePost { .await?; // They like their own post by default + let person_id = local_user_view.person.id; + let post_id = inserted_post.id; let like_form = PostLikeForm { - post_id: inserted_post.id, - person_id: local_user_view.person.id, + post_id, + person_id, score: 1, }; @@ -92,6 +100,9 @@ impl PerformCrud for CreatePost { return Err(ApiError::err("couldnt_like_post").into()); } + // Mark the post as read + mark_post_as_read(person_id, post_id, context.pool()).await?; + updated_post .send_like(&local_user_view.person, context) .await?; diff --git a/crates/api_crud/src/post/read.rs b/crates/api_crud/src/post/read.rs index d2231d24b..d44f029a0 100644 --- a/crates/api_crud/src/post/read.rs +++ b/crates/api_crud/src/post/read.rs @@ -3,9 +3,11 @@ 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_db_views::{ @@ -43,6 +45,11 @@ impl PerformCrud for GetPost { .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) @@ -100,6 +107,7 @@ impl PerformCrud for GetPosts { 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 type_ = ListingType::from_str(&data.type_)?; let sort = SortType::from_str(&data.sort)?; @@ -116,6 +124,7 @@ impl PerformCrud for GetPosts { .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) diff --git a/crates/api_crud/src/user/create.rs b/crates/api_crud/src/user/create.rs index 097555561..d7aae65f0 100644 --- a/crates/api_crud/src/user/create.rs +++ b/crates/api_crud/src/user/create.rs @@ -130,6 +130,7 @@ impl PerformCrud for Register { lang: Some("browser".into()), show_avatars: Some(true), show_scores: Some(true), + show_read_posts: Some(true), send_notifications_to_email: Some(false), }; diff --git a/crates/api_crud/src/user/read.rs b/crates/api_crud/src/user/read.rs index 24ac2f61e..e0e3808c1 100644 --- a/crates/api_crud/src/user/read.rs +++ b/crates/api_crud/src/user/read.rs @@ -6,6 +6,7 @@ use lemmy_api_common::{ person::*, user_show_bot_accounts, user_show_nsfw, + user_show_read_posts, }; use lemmy_db_queries::{source::person::Person_, SortType}; use lemmy_db_schema::source::person::*; @@ -33,6 +34,7 @@ impl PerformCrud for GetPersonDetails { 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 sort = SortType::from_str(&data.sort)?; @@ -72,6 +74,7 @@ impl PerformCrud for GetPersonDetails { .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) diff --git a/crates/db_queries/src/source/local_user.rs b/crates/db_queries/src/source/local_user.rs index 43a5c7727..2cd347e5c 100644 --- a/crates/db_queries/src/source/local_user.rs +++ b/crates/db_queries/src/source/local_user.rs @@ -26,6 +26,7 @@ mod safe_settings_type { validator_time, show_bot_accounts, show_scores, + show_read_posts, ); impl ToSafeSettings for LocalUser { @@ -47,6 +48,7 @@ mod safe_settings_type { validator_time, show_bot_accounts, show_scores, + show_read_posts, ) } } diff --git a/crates/db_queries/src/source/post.rs b/crates/db_queries/src/source/post.rs index 0205dc954..9f2d2f9b3 100644 --- a/crates/db_queries/src/source/post.rs +++ b/crates/db_queries/src/source/post.rs @@ -243,6 +243,9 @@ impl Readable for PostRead { use lemmy_db_schema::schema::post_read::dsl::*; insert_into(post_read) .values(post_read_form) + .on_conflict((post_id, person_id)) + .do_update() + .set(post_read_form) .get_result::(conn) } diff --git a/crates/db_schema/src/schema.rs b/crates/db_schema/src/schema.rs index a70083981..4a52b310d 100644 --- a/crates/db_schema/src/schema.rs +++ b/crates/db_schema/src/schema.rs @@ -155,6 +155,7 @@ table! { validator_time -> Timestamp, show_bot_accounts -> Bool, show_scores -> Bool, + show_read_posts -> Bool, } } diff --git a/crates/db_schema/src/source/local_user.rs b/crates/db_schema/src/source/local_user.rs index 64afb49a4..77e0c0ceb 100644 --- a/crates/db_schema/src/source/local_user.rs +++ b/crates/db_schema/src/source/local_user.rs @@ -18,6 +18,7 @@ pub struct LocalUser { pub validator_time: chrono::NaiveDateTime, pub show_bot_accounts: bool, pub show_scores: bool, + pub show_read_posts: bool, } // TODO redo these, check table defaults @@ -36,6 +37,7 @@ pub struct LocalUserForm { pub send_notifications_to_email: Option, pub show_bot_accounts: Option, pub show_scores: Option, + pub show_read_posts: Option, } /// A local user view that removes password encrypted @@ -55,4 +57,5 @@ pub struct LocalUserSettings { pub validator_time: chrono::NaiveDateTime, pub show_bot_accounts: bool, pub show_scores: bool, + pub show_read_posts: bool, } diff --git a/crates/db_views/src/post_view.rs b/crates/db_views/src/post_view.rs index 8248bfd29..8a533412f 100644 --- a/crates/db_views/src/post_view.rs +++ b/crates/db_views/src/post_view.rs @@ -165,8 +165,8 @@ pub struct PostQueryBuilder<'a> { url_search: Option, show_nsfw: bool, show_bot_accounts: bool, + show_read_posts: bool, saved_only: bool, - unread_only: bool, page: Option, limit: Option, } @@ -185,8 +185,8 @@ impl<'a> PostQueryBuilder<'a> { url_search: None, show_nsfw: true, show_bot_accounts: true, + show_read_posts: true, saved_only: false, - unread_only: false, page: None, limit: None, } @@ -242,6 +242,11 @@ impl<'a> PostQueryBuilder<'a> { self } + pub fn show_read_posts(mut self, show_read_posts: bool) -> Self { + self.show_read_posts = show_read_posts; + self + } + pub fn saved_only(mut self, saved_only: bool) -> Self { self.saved_only = saved_only; self @@ -362,13 +367,12 @@ impl<'a> PostQueryBuilder<'a> { query = query.filter(person::bot_account.eq(false)); }; - // TODO These two might be wrong if self.saved_only { query = query.filter(post_saved::id.is_not_null()); }; - if self.unread_only { - query = query.filter(post_read::id.is_not_null()); + if !self.show_read_posts { + query = query.filter(post_read::id.is_null()); }; query = match self.sort { diff --git a/crates/routes/src/feeds.rs b/crates/routes/src/feeds.rs index 21263fd61..2ed586737 100644 --- a/crates/routes/src/feeds.rs +++ b/crates/routes/src/feeds.rs @@ -231,11 +231,13 @@ 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) .my_person_id(person_id) .show_bot_accounts(show_bot_accounts) + .show_read_posts(show_read_posts) .sort(sort_type) .list()?; diff --git a/migrations/2021-04-24-174047_add_show_read_post_setting/down.sql b/migrations/2021-04-24-174047_add_show_read_post_setting/down.sql new file mode 100644 index 000000000..2aa275147 --- /dev/null +++ b/migrations/2021-04-24-174047_add_show_read_post_setting/down.sql @@ -0,0 +1 @@ +alter table local_user drop column show_read_posts; diff --git a/migrations/2021-04-24-174047_add_show_read_post_setting/up.sql b/migrations/2021-04-24-174047_add_show_read_post_setting/up.sql new file mode 100644 index 000000000..74b5398c3 --- /dev/null +++ b/migrations/2021-04-24-174047_add_show_read_post_setting/up.sql @@ -0,0 +1 @@ +alter table local_user add column show_read_posts boolean default true not null;