From 2ad3450004a32dac311922e3d70f0884a660c41b Mon Sep 17 00:00:00 2001 From: Piotr Juszczyk <74842304+pijuszczyk@users.noreply.github.com> Date: Tue, 8 Aug 2023 11:40:28 +0200 Subject: [PATCH] Allow filtering posts and comments by whether they were liked/disliked - fixes #3401 (#3523) * Allow filtering posts and comments by whether they were liked/disliked * Switch to 2 args - liked_only, disliked_only - taking bools * Make liked_only and disliked_only Option * Fix unrelated is_profile_view compilation error --- crates/api_common/src/comment.rs | 2 ++ crates/api_common/src/post.rs | 2 ++ crates/apub/src/api/list_comments.rs | 9 +++++++ crates/apub/src/api/list_posts.rs | 8 +++++++ crates/db_views/src/comment_view.rs | 35 ++++++++++++++++++++++++++++ crates/db_views/src/post_view.rs | 30 ++++++++++++++++++++++++ crates/utils/src/error.rs | 1 + 7 files changed, 87 insertions(+) diff --git a/crates/api_common/src/comment.rs b/crates/api_common/src/comment.rs index 1b0df39d..ec9ca132 100644 --- a/crates/api_common/src/comment.rs +++ b/crates/api_common/src/comment.rs @@ -126,6 +126,8 @@ pub struct GetComments { pub post_id: Option, pub parent_id: Option, pub saved_only: Option, + pub liked_only: Option, + pub disliked_only: Option, pub auth: Option>, } diff --git a/crates/api_common/src/post.rs b/crates/api_common/src/post.rs index 01a7db9c..e511d279 100644 --- a/crates/api_common/src/post.rs +++ b/crates/api_common/src/post.rs @@ -75,6 +75,8 @@ pub struct GetPosts { pub community_id: Option, pub community_name: Option, pub saved_only: Option, + pub liked_only: Option, + pub disliked_only: Option, pub moderator_view: Option, pub auth: Option>, } diff --git a/crates/apub/src/api/list_comments.rs b/crates/apub/src/api/list_comments.rs index f07ce3da..3954df58 100644 --- a/crates/apub/src/api/list_comments.rs +++ b/crates/apub/src/api/list_comments.rs @@ -35,6 +35,13 @@ pub async fn list_comments( let sort = data.sort; let max_depth = data.max_depth; let saved_only = data.saved_only; + + let liked_only = data.liked_only; + let disliked_only = data.disliked_only; + if liked_only.unwrap_or_default() && disliked_only.unwrap_or_default() { + return Err(LemmyError::from(LemmyErrorType::ContradictingFilters)); + } + let page = data.page; let limit = data.limit; let parent_id = data.parent_id; @@ -59,6 +66,8 @@ pub async fn list_comments( sort, max_depth, saved_only, + liked_only, + disliked_only, community_id, parent_path: parent_path_cloned, post_id, diff --git a/crates/apub/src/api/list_posts.rs b/crates/apub/src/api/list_posts.rs index 2635e149..d7138df3 100644 --- a/crates/apub/src/api/list_posts.rs +++ b/crates/apub/src/api/list_posts.rs @@ -36,6 +36,12 @@ pub async fn list_posts( }; let saved_only = data.saved_only; + let liked_only = data.liked_only; + let disliked_only = data.disliked_only; + if liked_only.unwrap_or_default() && disliked_only.unwrap_or_default() { + return Err(LemmyError::from(LemmyErrorType::ContradictingFilters)); + } + let moderator_view = data.moderator_view; let listing_type = Some(listing_type_with_default( @@ -50,6 +56,8 @@ pub async fn list_posts( sort, community_id, saved_only, + liked_only, + disliked_only, moderator_view, page, limit, diff --git a/crates/db_views/src/comment_view.rs b/crates/db_views/src/comment_view.rs index 45ab82bd..506efb32 100644 --- a/crates/db_views/src/comment_view.rs +++ b/crates/db_views/src/comment_view.rs @@ -195,6 +195,12 @@ fn queries<'a>() -> Queries< query = query.filter(comment_saved::comment_id.is_not_null()); } + if options.liked_only.unwrap_or_default() { + query = query.filter(comment_like::score.eq(1)); + } else if options.disliked_only.unwrap_or_default() { + query = query.filter(comment_like::score.eq(-1)); + } + let is_creator = options.creator_id == options.local_user.map(|l| l.person.id); // only show deleted comments to creator if !is_creator { @@ -309,6 +315,8 @@ pub struct CommentQuery<'a> { pub local_user: Option<&'a LocalUserView>, pub search_term: Option, pub saved_only: Option, + pub liked_only: Option, + pub disliked_only: Option, pub is_profile_view: bool, pub page: Option, pub limit: Option, @@ -608,6 +616,33 @@ mod tests { // Make sure block set the creator blocked assert!(read_comment_from_blocked_person.creator_blocked); + let read_liked_comment_views = CommentQuery { + local_user: (Some(&data.local_user_view)), + liked_only: (Some(true)), + ..Default::default() + } + .list(pool) + .await + .unwrap(); + + assert_eq!( + expected_comment_view_with_person, + read_liked_comment_views[0] + ); + + assert_eq!(1, read_liked_comment_views.len()); + + let read_disliked_comment_views: Vec = CommentQuery { + local_user: (Some(&data.local_user_view)), + disliked_only: (Some(true)), + ..Default::default() + } + .list(pool) + .await + .unwrap(); + + assert!(read_disliked_comment_views.is_empty()); + cleanup(data, pool).await; } diff --git a/crates/db_views/src/post_view.rs b/crates/db_views/src/post_view.rs index 0f844a49..a832e111 100644 --- a/crates/db_views/src/post_view.rs +++ b/crates/db_views/src/post_view.rs @@ -313,6 +313,12 @@ fn queries<'a>() -> Queries< } } + if options.liked_only.unwrap_or_default() { + query = query.filter(post_like::score.eq(1)); + } else if options.disliked_only.unwrap_or_default() { + query = query.filter(post_like::score.eq(-1)); + } + if options.local_user.is_some() { // Filter out the rows with missing languages query = query.filter(local_user_language::language_id.is_not_null()); @@ -426,6 +432,8 @@ pub struct PostQuery<'a> { pub search_term: Option, pub url_search: Option, pub saved_only: Option, + pub liked_only: Option, + pub disliked_only: Option, pub moderator_view: Option, pub is_profile_view: bool, pub page: Option, @@ -796,6 +804,28 @@ mod tests { assert_eq!(expected_post_with_upvote, read_post_listing[0]); + let read_liked_post_listing = PostQuery { + community_id: (Some(data.inserted_community.id)), + local_user: (Some(&data.local_user_view)), + liked_only: (Some(true)), + ..Default::default() + } + .list(pool) + .await + .unwrap(); + assert_eq!(read_post_listing, read_liked_post_listing); + + let read_disliked_post_listing = PostQuery { + community_id: (Some(data.inserted_community.id)), + local_user: (Some(&data.local_user_view)), + disliked_only: (Some(true)), + ..Default::default() + } + .list(pool) + .await + .unwrap(); + assert!(read_disliked_post_listing.is_empty()); + let like_removed = PostLike::remove(pool, data.local_user_view.person.id, data.inserted_post.id) .await diff --git a/crates/utils/src/error.rs b/crates/utils/src/error.rs index c6e6ad01..9ddd3b29 100644 --- a/crates/utils/src/error.rs +++ b/crates/utils/src/error.rs @@ -207,6 +207,7 @@ pub enum LemmyErrorType { CouldntCreateAudioCaptcha, InvalidUrlScheme, CouldntSendWebmention, + ContradictingFilters, Unknown(String), } -- 2.44.1