1 use crate::structs::CommentReplyView;
8 NullableExpressionMethods,
11 use diesel_async::RunQueryDsl;
12 use lemmy_db_schema::{
13 aggregates::structs::CommentAggregates,
15 newtypes::{CommentReplyId, PersonId},
31 comment_reply::CommentReply,
32 community::{Community, CommunityFollower},
37 utils::{get_conn, limit_and_offset, DbConn, DbPool, ListFn, Queries, ReadFn},
42 type CommentReplyViewTuple = (
57 fn queries<'a>() -> Queries<
58 impl ReadFn<'a, CommentReplyView, (CommentReplyId, Option<PersonId>)>,
59 impl ListFn<'a, CommentReplyView, CommentReplyQuery>,
61 let all_joins = |query: comment_reply::BoxedQuery<'a, Pg>, my_person_id: Option<PersonId>| {
62 // The left join below will return None in this case
63 let person_id_join = my_person_id.unwrap_or(PersonId(-1));
66 .inner_join(comment::table)
67 .inner_join(person::table.on(comment::creator_id.eq(person::id)))
68 .inner_join(post::table.on(comment::post_id.eq(post::id)))
69 .inner_join(community::table.on(post::community_id.eq(community::id)))
70 .inner_join(aliases::person1)
71 .inner_join(comment_aggregates::table.on(comment::id.eq(comment_aggregates::comment_id)))
73 community_person_ban::table.on(
75 .eq(community_person_ban::community_id)
76 .and(community_person_ban::person_id.eq(comment::creator_id)),
80 community_follower::table.on(
82 .eq(community_follower::community_id)
83 .and(community_follower::person_id.eq(person_id_join)),
87 comment_saved::table.on(
89 .eq(comment_saved::comment_id)
90 .and(comment_saved::person_id.eq(person_id_join)),
94 person_block::table.on(
96 .eq(person_block::target_id)
97 .and(person_block::person_id.eq(person_id_join)),
101 comment_like::table.on(
103 .eq(comment_like::comment_id)
104 .and(comment_like::person_id.eq(person_id_join)),
108 comment_reply::all_columns,
109 comment::all_columns,
112 community::all_columns,
113 aliases::person1.fields(person::all_columns),
114 comment_aggregates::all_columns,
115 community_person_ban::id.nullable().is_not_null(),
116 CommunityFollower::select_subscribed_type(),
117 comment_saved::id.nullable().is_not_null(),
118 person_block::id.nullable().is_not_null(),
119 comment_like::score.nullable(),
124 move |mut conn: DbConn<'a>,
125 (comment_reply_id, my_person_id): (CommentReplyId, Option<PersonId>)| async move {
127 comment_reply::table.find(comment_reply_id).into_boxed(),
130 .first::<CommentReplyViewTuple>(&mut conn)
134 let list = move |mut conn: DbConn<'a>, options: CommentReplyQuery| async move {
135 let mut query = all_joins(comment_reply::table.into_boxed(), options.my_person_id);
137 if let Some(recipient_id) = options.recipient_id {
138 query = query.filter(comment_reply::recipient_id.eq(recipient_id));
141 if options.unread_only {
142 query = query.filter(comment_reply::read.eq(false));
145 if !options.show_bot_accounts {
146 query = query.filter(person::bot_account.eq(false));
149 query = match options.sort.unwrap_or(CommentSortType::New) {
150 CommentSortType::Hot => query.then_order_by(comment_aggregates::hot_rank.desc()),
151 CommentSortType::Controversial => {
152 query.then_order_by(comment_aggregates::controversy_rank.desc())
154 CommentSortType::New => query.then_order_by(comment_reply::published.desc()),
155 CommentSortType::Old => query.then_order_by(comment_reply::published.asc()),
156 CommentSortType::Top => query.order_by(comment_aggregates::score.desc()),
159 let (limit, offset) = limit_and_offset(options.page, options.limit)?;
164 .load::<CommentReplyViewTuple>(&mut conn)
168 Queries::new(read, list)
171 impl CommentReplyView {
173 pool: &mut DbPool<'_>,
174 comment_reply_id: CommentReplyId,
175 my_person_id: Option<PersonId>,
176 ) -> Result<Self, Error> {
177 queries().read(pool, (comment_reply_id, my_person_id)).await
180 /// Gets the number of unread replies
181 pub async fn get_unread_replies(
182 pool: &mut DbPool<'_>,
183 my_person_id: PersonId,
184 ) -> Result<i64, Error> {
185 use diesel::dsl::count;
187 let conn = &mut get_conn(pool).await?;
190 .inner_join(comment::table)
191 .filter(comment_reply::recipient_id.eq(my_person_id))
192 .filter(comment_reply::read.eq(false))
193 .filter(comment::deleted.eq(false))
194 .filter(comment::removed.eq(false))
195 .select(count(comment_reply::id))
202 pub struct CommentReplyQuery {
203 pub my_person_id: Option<PersonId>,
204 pub recipient_id: Option<PersonId>,
205 pub sort: Option<CommentSortType>,
206 pub unread_only: bool,
207 pub show_bot_accounts: bool,
208 pub page: Option<i64>,
209 pub limit: Option<i64>,
212 impl CommentReplyQuery {
213 pub async fn list(self, pool: &mut DbPool<'_>) -> Result<Vec<CommentReplyView>, Error> {
214 queries().list(pool, self).await
218 impl JoinView for CommentReplyView {
219 type JoinTuple = CommentReplyViewTuple;
220 fn from_tuple(a: Self::JoinTuple) -> Self {
229 creator_banned_from_community: a.7,
232 creator_blocked: a.10,