diff --git a/crates/api/src/comment_report.rs b/crates/api/src/comment_report.rs index 2b73500da..7bbbd6890 100644 --- a/crates/api/src/comment_report.rs +++ b/crates/api/src/comment_report.rs @@ -155,12 +155,14 @@ impl Perform for ListCommentReports { let person_id = local_user_view.person.id; let community_id = data.community_id; + let unresolved_only = data.unresolved_only; let page = data.page; let limit = data.limit; let comment_reports = blocking(context.pool(), move |conn| { CommentReportQueryBuilder::create(conn, person_id) .community_id(community_id) + .unresolved_only(unresolved_only) .page(page) .limit(limit) .list() diff --git a/crates/api/src/post_report.rs b/crates/api/src/post_report.rs index b1f46a4bd..aad21bdbf 100644 --- a/crates/api/src/post_report.rs +++ b/crates/api/src/post_report.rs @@ -158,12 +158,14 @@ impl Perform for ListPostReports { let person_id = local_user_view.person.id; let community_id = data.community_id; + let unresolved_only = data.unresolved_only; let page = data.page; let limit = data.limit; let post_reports = blocking(context.pool(), move |conn| { PostReportQueryBuilder::create(conn, person_id) .community_id(community_id) + .unresolved_only(unresolved_only) .page(page) .limit(limit) .list() diff --git a/crates/api_common/src/comment.rs b/crates/api_common/src/comment.rs index 109b0ff6d..555640580 100644 --- a/crates/api_common/src/comment.rs +++ b/crates/api_common/src/comment.rs @@ -102,6 +102,8 @@ pub struct ResolveCommentReport { pub struct ListCommentReports { pub page: Option, pub limit: Option, + /// Only shows the unresolved reports + pub unresolved_only: Option, /// if no community is given, it returns reports for all communities moderated by the auth user pub community_id: Option, pub auth: String, diff --git a/crates/api_common/src/post.rs b/crates/api_common/src/post.rs index e7987d59d..3926ed8c7 100644 --- a/crates/api_common/src/post.rs +++ b/crates/api_common/src/post.rs @@ -135,6 +135,8 @@ pub struct ResolvePostReport { pub struct ListPostReports { pub page: Option, pub limit: Option, + /// Only shows the unresolved reports + pub unresolved_only: Option, /// if no community is given, it returns reports for all communities moderated by the auth user pub community_id: Option, pub auth: String, diff --git a/crates/db_views/src/comment_report_view.rs b/crates/db_views/src/comment_report_view.rs index f0dbb4b53..bdfc2c5ca 100644 --- a/crates/db_views/src/comment_report_view.rs +++ b/crates/db_views/src/comment_report_view.rs @@ -1,11 +1,19 @@ use diesel::{result::Error, *}; -use lemmy_db_queries::{limit_and_offset, MaybeOptional, ToSafe, ViewToVec}; +use lemmy_db_queries::{ + aggregates::comment_aggregates::CommentAggregates, + limit_and_offset, + MaybeOptional, + ToSafe, + ViewToVec, +}; use lemmy_db_schema::{ schema::{ comment, + comment_aggregates, comment_report, community, community_moderator, + community_person_ban, person, person_alias_1, person_alias_2, @@ -14,7 +22,7 @@ use lemmy_db_schema::{ source::{ comment::Comment, comment_report::CommentReport, - community::{Community, CommunitySafe}, + community::{Community, CommunityPersonBan, CommunitySafe}, person::{Person, PersonAlias1, PersonAlias2, PersonSafe, PersonSafeAlias1, PersonSafeAlias2}, post::Post, }, @@ -32,6 +40,8 @@ pub struct CommentReportView { pub community: CommunitySafe, pub creator: PersonSafe, pub comment_creator: PersonSafeAlias1, + pub counts: CommentAggregates, + pub creator_banned_from_community: bool, // Left Join to CommunityPersonBan pub resolver: Option, } @@ -42,6 +52,8 @@ type CommentReportViewTuple = ( CommunitySafe, PersonSafe, PersonSafeAlias1, + CommentAggregates, + Option, Option, ); @@ -50,27 +62,48 @@ impl CommentReportView { /// /// * `report_id` - the report id to obtain pub fn read(conn: &PgConnection, report_id: CommentReportId) -> Result { - let (comment_report, comment, post, community, creator, comment_creator, resolver) = - comment_report::table - .find(report_id) - .inner_join(comment::table) - .inner_join(post::table.on(comment::post_id.eq(post::id))) - .inner_join(community::table.on(post::community_id.eq(community::id))) - .inner_join(person::table.on(comment_report::creator_id.eq(person::id))) - .inner_join(person_alias_1::table.on(post::creator_id.eq(person_alias_1::id))) - .left_join( - person_alias_2::table.on(comment_report::resolver_id.eq(person_alias_2::id.nullable())), - ) - .select(( - comment_report::all_columns, - comment::all_columns, - post::all_columns, - Community::safe_columns_tuple(), - Person::safe_columns_tuple(), - PersonAlias1::safe_columns_tuple(), - PersonAlias2::safe_columns_tuple().nullable(), - )) - .first::(conn)?; + let ( + comment_report, + comment, + post, + community, + creator, + comment_creator, + counts, + creator_banned_from_community, + resolver, + ) = comment_report::table + .find(report_id) + .inner_join(comment::table) + .inner_join(post::table.on(comment::post_id.eq(post::id))) + .inner_join(community::table.on(post::community_id.eq(community::id))) + .inner_join(person::table.on(comment_report::creator_id.eq(person::id))) + .inner_join(person_alias_1::table.on(post::creator_id.eq(person_alias_1::id))) + .inner_join( + comment_aggregates::table.on(comment_report::comment_id.eq(comment_aggregates::comment_id)), + ) + .left_join( + community_person_ban::table.on( + community::id + .eq(community_person_ban::community_id) + .and(community_person_ban::person_id.eq(comment::creator_id)), + ), + ) + .left_join( + person_alias_2::table.on(comment_report::resolver_id.eq(person_alias_2::id.nullable())), + ) + .select(( + comment_report::all_columns, + comment::all_columns, + post::all_columns, + Community::safe_columns_tuple(), + Person::safe_columns_tuple(), + PersonAlias1::safe_columns_tuple(), + comment_aggregates::all_columns, + community_person_ban::all_columns.nullable(), + PersonAlias2::safe_columns_tuple().nullable(), + )) + .first::(conn)?; Ok(Self { comment_report, @@ -79,6 +112,8 @@ impl CommentReportView { community, creator, comment_creator, + counts, + creator_banned_from_community: creator_banned_from_community.is_some(), resolver, }) } @@ -124,7 +159,7 @@ pub struct CommentReportQueryBuilder<'a> { community_id: Option, page: Option, limit: Option, - resolved: bool, + unresolved_only: Option, } impl<'a> CommentReportQueryBuilder<'a> { @@ -135,7 +170,7 @@ impl<'a> CommentReportQueryBuilder<'a> { community_id: None, page: None, limit: None, - resolved: false, + unresolved_only: Some(true), } } @@ -154,8 +189,8 @@ impl<'a> CommentReportQueryBuilder<'a> { self } - pub fn resolved(mut self, resolved: bool) -> Self { - self.resolved = resolved; + pub fn unresolved_only>(mut self, unresolved_only: T) -> Self { + self.unresolved_only = unresolved_only.get_optional(); self } @@ -174,6 +209,16 @@ impl<'a> CommentReportQueryBuilder<'a> { .and(community_moderator::person_id.eq(self.my_person_id)), ), ) + .inner_join( + comment_aggregates::table.on(comment_report::comment_id.eq(comment_aggregates::comment_id)), + ) + .left_join( + community_person_ban::table.on( + community::id + .eq(community_person_ban::community_id) + .and(community_person_ban::person_id.eq(comment::creator_id)), + ), + ) .left_join( person_alias_2::table.on(comment_report::resolver_id.eq(person_alias_2::id.nullable())), ) @@ -184,6 +229,8 @@ impl<'a> CommentReportQueryBuilder<'a> { Community::safe_columns_tuple(), Person::safe_columns_tuple(), PersonAlias1::safe_columns_tuple(), + comment_aggregates::all_columns, + community_person_ban::all_columns.nullable(), PersonAlias2::safe_columns_tuple().nullable(), )) .into_boxed(); @@ -192,7 +239,9 @@ impl<'a> CommentReportQueryBuilder<'a> { query = query.filter(post::community_id.eq(community_id)); } - query = query.filter(comment_report::resolved.eq(self.resolved)); + if self.unresolved_only.unwrap_or(false) { + query = query.filter(comment_report::resolved.eq(false)); + } let (limit, offset) = limit_and_offset(self.page, self.limit); @@ -218,7 +267,9 @@ impl ViewToVec for CommentReportView { community: a.3.to_owned(), creator: a.4.to_owned(), comment_creator: a.5.to_owned(), - resolver: a.6.to_owned(), + counts: a.6.to_owned(), + creator_banned_from_community: a.7.is_some(), + resolver: a.8.to_owned(), }) .collect::>() } @@ -227,7 +278,13 @@ impl ViewToVec for CommentReportView { #[cfg(test)] mod tests { use crate::comment_report_view::{CommentReportQueryBuilder, CommentReportView}; - use lemmy_db_queries::{establish_unpooled_connection, Crud, Joinable, Reportable}; + use lemmy_db_queries::{ + aggregates::comment_aggregates::CommentAggregates, + establish_unpooled_connection, + Crud, + Joinable, + Reportable, + }; use lemmy_db_schema::source::{comment::*, comment_report::*, community::*, person::*, post::*}; use serial_test::serial; @@ -312,11 +369,13 @@ mod tests { let inserted_jessica_report = CommentReport::report(&conn, &jessica_report_form).unwrap(); + let agg = CommentAggregates::read(&conn, inserted_comment.id).unwrap(); + let read_jessica_report_view = CommentReportView::read(&conn, inserted_jessica_report.id).unwrap(); let expected_jessica_report_view = CommentReportView { comment_report: inserted_jessica_report.to_owned(), - comment: inserted_comment, + comment: inserted_comment.to_owned(), post: inserted_post, community: CommunitySafe { id: inserted_community.id, @@ -371,6 +430,15 @@ mod tests { shared_inbox_url: None, matrix_user_id: None, }, + creator_banned_from_community: false, + counts: CommentAggregates { + id: agg.id, + comment_id: inserted_comment.id, + score: 0, + upvotes: 0, + downvotes: 0, + published: agg.published, + }, resolver: None, }; diff --git a/crates/db_views/src/post_report_view.rs b/crates/db_views/src/post_report_view.rs index 36bee024b..40cfb45fc 100644 --- a/crates/db_views/src/post_report_view.rs +++ b/crates/db_views/src/post_report_view.rs @@ -1,17 +1,25 @@ use diesel::{result::Error, *}; -use lemmy_db_queries::{limit_and_offset, MaybeOptional, ToSafe, ViewToVec}; +use lemmy_db_queries::{ + aggregates::post_aggregates::PostAggregates, + limit_and_offset, + MaybeOptional, + ToSafe, + ViewToVec, +}; use lemmy_db_schema::{ schema::{ community, community_moderator, + community_person_ban, person, person_alias_1, person_alias_2, post, + post_aggregates, post_report, }, source::{ - community::{Community, CommunitySafe}, + community::{Community, CommunityPersonBan, CommunitySafe}, person::{Person, PersonAlias1, PersonAlias2, PersonSafe, PersonSafeAlias1, PersonSafeAlias2}, post::Post, post_report::PostReport, @@ -29,6 +37,8 @@ pub struct PostReportView { pub community: CommunitySafe, pub creator: PersonSafe, pub post_creator: PersonSafeAlias1, + pub creator_banned_from_community: bool, + pub counts: PostAggregates, pub resolver: Option, } @@ -38,6 +48,8 @@ type PostReportViewTuple = ( CommunitySafe, PersonSafe, PersonSafeAlias1, + Option, + PostAggregates, Option, ); @@ -46,12 +58,29 @@ impl PostReportView { /// /// * `report_id` - the report id to obtain pub fn read(conn: &PgConnection, report_id: PostReportId) -> Result { - let (post_report, post, community, creator, post_creator, resolver) = post_report::table + let ( + post_report, + post, + community, + creator, + post_creator, + creator_banned_from_community, + counts, + resolver, + ) = post_report::table .find(report_id) .inner_join(post::table) .inner_join(community::table.on(post::community_id.eq(community::id))) .inner_join(person::table.on(post_report::creator_id.eq(person::id))) .inner_join(person_alias_1::table.on(post::creator_id.eq(person_alias_1::id))) + .left_join( + community_person_ban::table.on( + post::community_id + .eq(community_person_ban::community_id) + .and(community_person_ban::person_id.eq(post::creator_id)), + ), + ) + .inner_join(post_aggregates::table.on(post_report::post_id.eq(post_aggregates::post_id))) .left_join( person_alias_2::table.on(post_report::resolver_id.eq(person_alias_2::id.nullable())), ) @@ -61,6 +90,8 @@ impl PostReportView { Community::safe_columns_tuple(), Person::safe_columns_tuple(), PersonAlias1::safe_columns_tuple(), + community_person_ban::all_columns.nullable(), + post_aggregates::all_columns, PersonAlias2::safe_columns_tuple().nullable(), )) .first::(conn)?; @@ -71,6 +102,8 @@ impl PostReportView { community, creator, post_creator, + creator_banned_from_community: creator_banned_from_community.is_some(), + counts, resolver, }) } @@ -113,7 +146,7 @@ pub struct PostReportQueryBuilder<'a> { community_id: Option, page: Option, limit: Option, - resolved: bool, + unresolved_only: Option, } impl<'a> PostReportQueryBuilder<'a> { @@ -124,7 +157,7 @@ impl<'a> PostReportQueryBuilder<'a> { community_id: None, page: None, limit: None, - resolved: false, + unresolved_only: Some(true), } } @@ -143,8 +176,8 @@ impl<'a> PostReportQueryBuilder<'a> { self } - pub fn resolved(mut self, resolved: bool) -> Self { - self.resolved = resolved; + pub fn unresolved_only>(mut self, unresolved_only: T) -> Self { + self.unresolved_only = unresolved_only.get_optional(); self } @@ -162,6 +195,14 @@ impl<'a> PostReportQueryBuilder<'a> { .and(community_moderator::person_id.eq(self.my_person_id)), ), ) + .left_join( + community_person_ban::table.on( + post::community_id + .eq(community_person_ban::community_id) + .and(community_person_ban::person_id.eq(post::creator_id)), + ), + ) + .inner_join(post_aggregates::table.on(post_report::post_id.eq(post_aggregates::post_id))) .left_join( person_alias_2::table.on(post_report::resolver_id.eq(person_alias_2::id.nullable())), ) @@ -171,6 +212,8 @@ impl<'a> PostReportQueryBuilder<'a> { Community::safe_columns_tuple(), Person::safe_columns_tuple(), PersonAlias1::safe_columns_tuple(), + community_person_ban::all_columns.nullable(), + post_aggregates::all_columns, PersonAlias2::safe_columns_tuple().nullable(), )) .into_boxed(); @@ -179,7 +222,9 @@ impl<'a> PostReportQueryBuilder<'a> { query = query.filter(post::community_id.eq(community_id)); } - query = query.filter(post_report::resolved.eq(self.resolved)); + if self.unresolved_only.unwrap_or(false) { + query = query.filter(post_report::resolved.eq(false)); + } let (limit, offset) = limit_and_offset(self.page, self.limit); @@ -204,7 +249,9 @@ impl ViewToVec for PostReportView { community: a.2.to_owned(), creator: a.3.to_owned(), post_creator: a.4.to_owned(), - resolver: a.5.to_owned(), + creator_banned_from_community: a.5.is_some(), + counts: a.6.to_owned(), + resolver: a.7.to_owned(), }) .collect::>() } @@ -213,7 +260,13 @@ impl ViewToVec for PostReportView { #[cfg(test)] mod tests { use crate::post_report_view::{PostReportQueryBuilder, PostReportView}; - use lemmy_db_queries::{establish_unpooled_connection, Crud, Joinable, Reportable}; + use lemmy_db_queries::{ + aggregates::post_aggregates::PostAggregates, + establish_unpooled_connection, + Crud, + Joinable, + Reportable, + }; use lemmy_db_schema::source::{ community::*, person::*, @@ -298,10 +351,12 @@ mod tests { let inserted_jessica_report = PostReport::report(&conn, &jessica_report_form).unwrap(); + let agg = PostAggregates::read(&conn, inserted_post.id).unwrap(); + let read_jessica_report_view = PostReportView::read(&conn, inserted_jessica_report.id).unwrap(); let expected_jessica_report_view = PostReportView { post_report: inserted_jessica_report.to_owned(), - post: inserted_post, + post: inserted_post.to_owned(), community: CommunitySafe { id: inserted_community.id, name: inserted_community.name, @@ -355,6 +410,19 @@ mod tests { shared_inbox_url: None, matrix_user_id: None, }, + creator_banned_from_community: false, + counts: PostAggregates { + id: agg.id, + post_id: inserted_post.id, + comments: 0, + score: 0, + upvotes: 0, + downvotes: 0, + stickied: false, + published: agg.published, + newest_comment_time_necro: inserted_post.published, + newest_comment_time: inserted_post.published, + }, resolver: None, };