From 1cf520254da7b121368b0f75ac4c3c0d978b4f3d Mon Sep 17 00:00:00 2001 From: Dessalines Date: Wed, 16 Dec 2020 17:16:48 -0500 Subject: [PATCH] Adding private message view. --- lemmy_api/src/user.rs | 8 +- .../src/activities/receive/private_message.rs | 13 +- lemmy_db/src/lib.rs | 1 - lemmy_db/src/private_message_view.rs | 138 ------------------ lemmy_db/src/source/private_message.rs | 3 +- lemmy_db/src/views/mod.rs | 1 + lemmy_db/src/views/private_message_view.rs | 130 +++++++++++++++++ lemmy_structs/src/user.rs | 20 ++- 8 files changed, 154 insertions(+), 160 deletions(-) delete mode 100644 lemmy_db/src/private_message_view.rs create mode 100644 lemmy_db/src/views/private_message_view.rs diff --git a/lemmy_api/src/user.rs b/lemmy_api/src/user.rs index c47a5e1ce..327a1a426 100644 --- a/lemmy_api/src/user.rs +++ b/lemmy_api/src/user.rs @@ -19,7 +19,6 @@ use lemmy_db::{ diesel_option_overwrite, naive_now, post_report::PostReportView, - private_message_view::*, source::{ comment::*, community::*, @@ -38,6 +37,7 @@ use lemmy_db::{ community_moderator_view::CommunityModeratorView, }, post_view::PostQueryBuilder, + private_message_view::{PrivateMessageQueryBuilder, PrivateMessageView}, site_view::SiteView, user_mention_view::{UserMentionQueryBuilder, UserMentionView}, user_view::{UserViewDangerous, UserViewSafe}, @@ -1146,7 +1146,7 @@ impl Perform for EditPrivateMessage { PrivateMessageView::read(conn, edit_id) }) .await??; - let recipient_id = message.recipient_id; + let recipient_id = message.recipient.id; let res = PrivateMessageResponse { message }; @@ -1209,7 +1209,7 @@ impl Perform for DeletePrivateMessage { PrivateMessageView::read(conn, edit_id) }) .await??; - let recipient_id = message.recipient_id; + let recipient_id = message.recipient.id; let res = PrivateMessageResponse { message }; @@ -1265,7 +1265,7 @@ impl Perform for MarkPrivateMessageAsRead { PrivateMessageView::read(conn, edit_id) }) .await??; - let recipient_id = message.recipient_id; + let recipient_id = message.recipient.id; let res = PrivateMessageResponse { message }; diff --git a/lemmy_apub/src/activities/receive/private_message.rs b/lemmy_apub/src/activities/receive/private_message.rs index 25d4c26c5..15cde53f2 100644 --- a/lemmy_apub/src/activities/receive/private_message.rs +++ b/lemmy_apub/src/activities/receive/private_message.rs @@ -13,7 +13,10 @@ use activitystreams::{ public, }; use anyhow::{anyhow, Context}; -use lemmy_db::{private_message_view::PrivateMessageView, source::private_message::PrivateMessage}; +use lemmy_db::{ + source::private_message::PrivateMessage, + views::private_message_view::PrivateMessageView, +}; use lemmy_structs::{blocking, user::PrivateMessageResponse}; use lemmy_utils::{location_info, LemmyError}; use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperation}; @@ -46,7 +49,7 @@ pub(crate) async fn receive_create_private_message( let res = PrivateMessageResponse { message }; - let recipient_id = res.message.recipient_id; + let recipient_id = res.message.recipient.id; context.chat_server().do_send(SendUserRoomMessage { op: UserOperation::CreatePrivateMessage, @@ -84,7 +87,7 @@ pub(crate) async fn receive_update_private_message( let res = PrivateMessageResponse { message }; - let recipient_id = res.message.recipient_id; + let recipient_id = res.message.recipient.id; context.chat_server().do_send(SendUserRoomMessage { op: UserOperation::EditPrivateMessage, @@ -115,7 +118,7 @@ pub(crate) async fn receive_delete_private_message( .await??; let res = PrivateMessageResponse { message }; - let recipient_id = res.message.recipient_id; + let recipient_id = res.message.recipient.id; context.chat_server().do_send(SendUserRoomMessage { op: UserOperation::EditPrivateMessage, response: res, @@ -150,7 +153,7 @@ pub(crate) async fn receive_undo_delete_private_message( .await??; let res = PrivateMessageResponse { message }; - let recipient_id = res.message.recipient_id; + let recipient_id = res.message.recipient.id; context.chat_server().do_send(SendUserRoomMessage { op: UserOperation::EditPrivateMessage, response: res, diff --git a/lemmy_db/src/lib.rs b/lemmy_db/src/lib.rs index 8906f32c4..6b026f95d 100644 --- a/lemmy_db/src/lib.rs +++ b/lemmy_db/src/lib.rs @@ -13,7 +13,6 @@ use std::{env, env::VarError}; pub mod comment_report; pub mod post_report; -pub mod private_message_view; pub mod aggregates; pub mod schema; diff --git a/lemmy_db/src/private_message_view.rs b/lemmy_db/src/private_message_view.rs deleted file mode 100644 index 68f7df42c..000000000 --- a/lemmy_db/src/private_message_view.rs +++ /dev/null @@ -1,138 +0,0 @@ -use crate::{limit_and_offset, MaybeOptional}; -use diesel::{pg::Pg, result::Error, *}; -use serde::Serialize; - -// The faked schema since diesel doesn't do views -table! { - private_message_view (id) { - id -> Int4, - creator_id -> Int4, - recipient_id -> Int4, - content -> Text, - deleted -> Bool, - read -> Bool, - published -> Timestamp, - updated -> Nullable, - ap_id -> Text, - local -> Bool, - creator_name -> Varchar, - creator_preferred_username -> Nullable, - creator_avatar -> Nullable, - creator_actor_id -> Text, - creator_local -> Bool, - recipient_name -> Varchar, - recipient_preferred_username -> Nullable, - recipient_avatar -> Nullable, - recipient_actor_id -> Text, - recipient_local -> Bool, - } -} - -#[derive(Queryable, Identifiable, PartialEq, Debug, Serialize, QueryableByName, Clone)] -#[table_name = "private_message_view"] -pub struct PrivateMessageView { - pub id: i32, - pub creator_id: i32, - pub recipient_id: i32, - pub content: String, - pub deleted: bool, - pub read: bool, - pub published: chrono::NaiveDateTime, - pub updated: Option, - pub ap_id: String, - pub local: bool, - pub creator_name: String, - pub creator_preferred_username: Option, - pub creator_avatar: Option, - pub creator_actor_id: String, - pub creator_local: bool, - pub recipient_name: String, - pub recipient_preferred_username: Option, - pub recipient_avatar: Option, - pub recipient_actor_id: String, - pub recipient_local: bool, -} - -pub struct PrivateMessageQueryBuilder<'a> { - conn: &'a PgConnection, - query: super::private_message_view::private_message_view::BoxedQuery<'a, Pg>, - for_recipient_id: i32, - unread_only: bool, - page: Option, - limit: Option, -} - -impl<'a> PrivateMessageQueryBuilder<'a> { - pub fn create(conn: &'a PgConnection, for_recipient_id: i32) -> Self { - use super::private_message_view::private_message_view::dsl::*; - - let query = private_message_view.into_boxed(); - - PrivateMessageQueryBuilder { - conn, - query, - for_recipient_id, - unread_only: false, - page: None, - limit: None, - } - } - - pub fn unread_only(mut self, unread_only: bool) -> Self { - self.unread_only = unread_only; - self - } - - pub fn page>(mut self, page: T) -> Self { - self.page = page.get_optional(); - self - } - - pub fn limit>(mut self, limit: T) -> Self { - self.limit = limit.get_optional(); - self - } - - pub fn list(self) -> Result, Error> { - use super::private_message_view::private_message_view::dsl::*; - - let mut query = self.query.filter(deleted.eq(false)); - - // If its unread, I only want the ones to me - if self.unread_only { - query = query - .filter(read.eq(false)) - .filter(recipient_id.eq(self.for_recipient_id)); - } - // Otherwise, I want the ALL view to show both sent and received - else { - query = query.filter( - recipient_id - .eq(self.for_recipient_id) - .or(creator_id.eq(self.for_recipient_id)), - ) - } - - let (limit, offset) = limit_and_offset(self.page, self.limit); - - query - .limit(limit) - .offset(offset) - .order_by(published.desc()) - .load::(self.conn) - } -} - -impl PrivateMessageView { - pub fn read(conn: &PgConnection, from_private_message_id: i32) -> Result { - use super::private_message_view::private_message_view::dsl::*; - - let mut query = private_message_view.into_boxed(); - - query = query - .filter(id.eq(from_private_message_id)) - .order_by(published.desc()); - - query.first::(conn) - } -} diff --git a/lemmy_db/src/source/private_message.rs b/lemmy_db/src/source/private_message.rs index 47bb78fbb..f474cf9ac 100644 --- a/lemmy_db/src/source/private_message.rs +++ b/lemmy_db/src/source/private_message.rs @@ -1,7 +1,8 @@ use crate::{naive_now, schema::private_message, ApubObject, Crud}; use diesel::{dsl::*, result::Error, *}; +use serde::Serialize; -#[derive(Queryable, Identifiable, PartialEq, Debug)] +#[derive(Clone, Queryable, Associations, Identifiable, PartialEq, Debug, Serialize)] #[table_name = "private_message"] pub struct PrivateMessage { pub id: i32, diff --git a/lemmy_db/src/views/mod.rs b/lemmy_db/src/views/mod.rs index 28323fca2..ee9a82f5b 100644 --- a/lemmy_db/src/views/mod.rs +++ b/lemmy_db/src/views/mod.rs @@ -2,6 +2,7 @@ pub mod comment_view; pub mod community; pub mod moderator; pub mod post_view; +pub mod private_message_view; pub mod site_view; pub mod user_mention_view; pub mod user_view; diff --git a/lemmy_db/src/views/private_message_view.rs b/lemmy_db/src/views/private_message_view.rs new file mode 100644 index 000000000..43d960a8a --- /dev/null +++ b/lemmy_db/src/views/private_message_view.rs @@ -0,0 +1,130 @@ +use crate::{ + limit_and_offset, + schema::{private_message, user_, user_alias_1}, + source::{ + private_message::PrivateMessage, + user::{UserAlias1, UserSafe, UserSafeAlias1, User_}, + }, + views::ViewToVec, + MaybeOptional, + ToSafe, +}; +use diesel::{result::Error, *}; +use serde::Serialize; + +#[derive(Debug, PartialEq, Serialize, Clone)] +pub struct PrivateMessageView { + pub private_message: PrivateMessage, + pub creator: UserSafe, + pub recipient: UserSafeAlias1, +} + +type PrivateMessageViewTuple = (PrivateMessage, UserSafe, UserSafeAlias1); + +impl PrivateMessageView { + pub fn read(conn: &PgConnection, private_message_id: i32) -> Result { + let (private_message, creator, recipient) = private_message::table + .find(private_message_id) + .inner_join(user_::table.on(private_message::creator_id.eq(user_::id))) + .inner_join(user_alias_1::table.on(private_message::recipient_id.eq(user_alias_1::id))) + .order_by(private_message::published.desc()) + .select(( + private_message::all_columns, + User_::safe_columns_tuple(), + UserAlias1::safe_columns_tuple(), + )) + .first::(conn)?; + + Ok(PrivateMessageView { + private_message, + creator, + recipient, + }) + } +} + +pub struct PrivateMessageQueryBuilder<'a> { + conn: &'a PgConnection, + recipient_id: i32, + unread_only: bool, + page: Option, + limit: Option, +} + +impl<'a> PrivateMessageQueryBuilder<'a> { + pub fn create(conn: &'a PgConnection, recipient_id: i32) -> Self { + PrivateMessageQueryBuilder { + conn, + recipient_id, + unread_only: false, + page: None, + limit: None, + } + } + + pub fn unread_only(mut self, unread_only: bool) -> Self { + self.unread_only = unread_only; + self + } + + pub fn page>(mut self, page: T) -> Self { + self.page = page.get_optional(); + self + } + + pub fn limit>(mut self, limit: T) -> Self { + self.limit = limit.get_optional(); + self + } + + pub fn list(self) -> Result, Error> { + let mut query = private_message::table + .inner_join(user_::table.on(private_message::creator_id.eq(user_::id))) + .inner_join(user_alias_1::table.on(private_message::recipient_id.eq(user_alias_1::id))) + .select(( + private_message::all_columns, + User_::safe_columns_tuple(), + UserAlias1::safe_columns_tuple(), + )) + .into_boxed(); + + // If its unread, I only want the ones to me + if self.unread_only { + query = query + .filter(private_message::read.eq(false)) + .filter(private_message::recipient_id.eq(self.recipient_id)); + } + // Otherwise, I want the ALL view to show both sent and received + else { + query = query.filter( + private_message::recipient_id + .eq(self.recipient_id) + .or(private_message::creator_id.eq(self.recipient_id)), + ) + } + + let (limit, offset) = limit_and_offset(self.page, self.limit); + + let res = query + .filter(private_message::deleted.eq(false)) + .limit(limit) + .offset(offset) + .order_by(private_message::published.desc()) + .load::(self.conn)?; + + Ok(PrivateMessageView::to_vec(res)) + } +} + +impl ViewToVec for PrivateMessageView { + type DbTuple = PrivateMessageViewTuple; + fn to_vec(pm: Vec) -> Vec { + pm.iter() + .map(|a| Self { + private_message: a.0.to_owned(), + creator: a.1.to_owned(), + recipient: a.2.to_owned(), + }) + .collect::>() + } +} diff --git a/lemmy_structs/src/user.rs b/lemmy_structs/src/user.rs index 1bd320cd0..f73d63f99 100644 --- a/lemmy_structs/src/user.rs +++ b/lemmy_structs/src/user.rs @@ -1,15 +1,13 @@ -use lemmy_db::{ - private_message_view::PrivateMessageView, - views::{ - comment_view::CommentView, - community::{ - community_follower_view::CommunityFollowerView, - community_moderator_view::CommunityModeratorView, - }, - post_view::PostView, - user_mention_view::UserMentionView, - user_view::{UserViewDangerous, UserViewSafe}, +use lemmy_db::views::{ + comment_view::CommentView, + community::{ + community_follower_view::CommunityFollowerView, + community_moderator_view::CommunityModeratorView, }, + post_view::PostView, + private_message_view::PrivateMessageView, + user_mention_view::UserMentionView, + user_view::{UserViewDangerous, UserViewSafe}, }; use serde::{Deserialize, Serialize};