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<bool>

* Fix unrelated is_profile_view compilation error
This commit is contained in:
Piotr Juszczyk 2023-08-08 11:40:28 +02:00 committed by GitHub
parent f9c2ba1cfa
commit 2ad3450004
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 87 additions and 0 deletions

View File

@ -126,6 +126,8 @@ pub struct GetComments {
pub post_id: Option<PostId>, pub post_id: Option<PostId>,
pub parent_id: Option<CommentId>, pub parent_id: Option<CommentId>,
pub saved_only: Option<bool>, pub saved_only: Option<bool>,
pub liked_only: Option<bool>,
pub disliked_only: Option<bool>,
pub auth: Option<Sensitive<String>>, pub auth: Option<Sensitive<String>>,
} }

View File

@ -75,6 +75,8 @@ pub struct GetPosts {
pub community_id: Option<CommunityId>, pub community_id: Option<CommunityId>,
pub community_name: Option<String>, pub community_name: Option<String>,
pub saved_only: Option<bool>, pub saved_only: Option<bool>,
pub liked_only: Option<bool>,
pub disliked_only: Option<bool>,
pub moderator_view: Option<bool>, pub moderator_view: Option<bool>,
pub auth: Option<Sensitive<String>>, pub auth: Option<Sensitive<String>>,
} }

View File

@ -35,6 +35,13 @@ pub async fn list_comments(
let sort = data.sort; let sort = data.sort;
let max_depth = data.max_depth; let max_depth = data.max_depth;
let saved_only = data.saved_only; 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 page = data.page;
let limit = data.limit; let limit = data.limit;
let parent_id = data.parent_id; let parent_id = data.parent_id;
@ -59,6 +66,8 @@ pub async fn list_comments(
sort, sort,
max_depth, max_depth,
saved_only, saved_only,
liked_only,
disliked_only,
community_id, community_id,
parent_path: parent_path_cloned, parent_path: parent_path_cloned,
post_id, post_id,

View File

@ -36,6 +36,12 @@ pub async fn list_posts(
}; };
let saved_only = data.saved_only; 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 moderator_view = data.moderator_view;
let listing_type = Some(listing_type_with_default( let listing_type = Some(listing_type_with_default(
@ -50,6 +56,8 @@ pub async fn list_posts(
sort, sort,
community_id, community_id,
saved_only, saved_only,
liked_only,
disliked_only,
moderator_view, moderator_view,
page, page,
limit, limit,

View File

@ -195,6 +195,12 @@ fn queries<'a>() -> Queries<
query = query.filter(comment_saved::comment_id.is_not_null()); 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); let is_creator = options.creator_id == options.local_user.map(|l| l.person.id);
// only show deleted comments to creator // only show deleted comments to creator
if !is_creator { if !is_creator {
@ -309,6 +315,8 @@ pub struct CommentQuery<'a> {
pub local_user: Option<&'a LocalUserView>, pub local_user: Option<&'a LocalUserView>,
pub search_term: Option<String>, pub search_term: Option<String>,
pub saved_only: Option<bool>, pub saved_only: Option<bool>,
pub liked_only: Option<bool>,
pub disliked_only: Option<bool>,
pub is_profile_view: bool, pub is_profile_view: bool,
pub page: Option<i64>, pub page: Option<i64>,
pub limit: Option<i64>, pub limit: Option<i64>,
@ -608,6 +616,33 @@ mod tests {
// Make sure block set the creator blocked // Make sure block set the creator blocked
assert!(read_comment_from_blocked_person.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<CommentView> = 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; cleanup(data, pool).await;
} }

View File

@ -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() { if options.local_user.is_some() {
// Filter out the rows with missing languages // Filter out the rows with missing languages
query = query.filter(local_user_language::language_id.is_not_null()); query = query.filter(local_user_language::language_id.is_not_null());
@ -426,6 +432,8 @@ pub struct PostQuery<'a> {
pub search_term: Option<String>, pub search_term: Option<String>,
pub url_search: Option<String>, pub url_search: Option<String>,
pub saved_only: Option<bool>, pub saved_only: Option<bool>,
pub liked_only: Option<bool>,
pub disliked_only: Option<bool>,
pub moderator_view: Option<bool>, pub moderator_view: Option<bool>,
pub is_profile_view: bool, pub is_profile_view: bool,
pub page: Option<i64>, pub page: Option<i64>,
@ -796,6 +804,28 @@ mod tests {
assert_eq!(expected_post_with_upvote, read_post_listing[0]); 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 = let like_removed =
PostLike::remove(pool, data.local_user_view.person.id, data.inserted_post.id) PostLike::remove(pool, data.local_user_view.person.id, data.inserted_post.id)
.await .await

View File

@ -207,6 +207,7 @@ pub enum LemmyErrorType {
CouldntCreateAudioCaptcha, CouldntCreateAudioCaptcha,
InvalidUrlScheme, InvalidUrlScheme,
CouldntSendWebmention, CouldntSendWebmention,
ContradictingFilters,
Unknown(String), Unknown(String),
} }