Adding private message view.

This commit is contained in:
Dessalines 2020-12-16 17:16:48 -05:00
parent 313f0467c8
commit 1cf520254d
8 changed files with 154 additions and 160 deletions

View file

@ -19,7 +19,6 @@ use lemmy_db::{
diesel_option_overwrite, diesel_option_overwrite,
naive_now, naive_now,
post_report::PostReportView, post_report::PostReportView,
private_message_view::*,
source::{ source::{
comment::*, comment::*,
community::*, community::*,
@ -38,6 +37,7 @@ use lemmy_db::{
community_moderator_view::CommunityModeratorView, community_moderator_view::CommunityModeratorView,
}, },
post_view::PostQueryBuilder, post_view::PostQueryBuilder,
private_message_view::{PrivateMessageQueryBuilder, PrivateMessageView},
site_view::SiteView, site_view::SiteView,
user_mention_view::{UserMentionQueryBuilder, UserMentionView}, user_mention_view::{UserMentionQueryBuilder, UserMentionView},
user_view::{UserViewDangerous, UserViewSafe}, user_view::{UserViewDangerous, UserViewSafe},
@ -1146,7 +1146,7 @@ impl Perform for EditPrivateMessage {
PrivateMessageView::read(conn, edit_id) PrivateMessageView::read(conn, edit_id)
}) })
.await??; .await??;
let recipient_id = message.recipient_id; let recipient_id = message.recipient.id;
let res = PrivateMessageResponse { message }; let res = PrivateMessageResponse { message };
@ -1209,7 +1209,7 @@ impl Perform for DeletePrivateMessage {
PrivateMessageView::read(conn, edit_id) PrivateMessageView::read(conn, edit_id)
}) })
.await??; .await??;
let recipient_id = message.recipient_id; let recipient_id = message.recipient.id;
let res = PrivateMessageResponse { message }; let res = PrivateMessageResponse { message };
@ -1265,7 +1265,7 @@ impl Perform for MarkPrivateMessageAsRead {
PrivateMessageView::read(conn, edit_id) PrivateMessageView::read(conn, edit_id)
}) })
.await??; .await??;
let recipient_id = message.recipient_id; let recipient_id = message.recipient.id;
let res = PrivateMessageResponse { message }; let res = PrivateMessageResponse { message };

View file

@ -13,7 +13,10 @@ use activitystreams::{
public, public,
}; };
use anyhow::{anyhow, Context}; 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_structs::{blocking, user::PrivateMessageResponse};
use lemmy_utils::{location_info, LemmyError}; use lemmy_utils::{location_info, LemmyError};
use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperation}; use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperation};
@ -46,7 +49,7 @@ pub(crate) async fn receive_create_private_message(
let res = PrivateMessageResponse { 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 { context.chat_server().do_send(SendUserRoomMessage {
op: UserOperation::CreatePrivateMessage, op: UserOperation::CreatePrivateMessage,
@ -84,7 +87,7 @@ pub(crate) async fn receive_update_private_message(
let res = PrivateMessageResponse { 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 { context.chat_server().do_send(SendUserRoomMessage {
op: UserOperation::EditPrivateMessage, op: UserOperation::EditPrivateMessage,
@ -115,7 +118,7 @@ pub(crate) async fn receive_delete_private_message(
.await??; .await??;
let res = PrivateMessageResponse { 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 { context.chat_server().do_send(SendUserRoomMessage {
op: UserOperation::EditPrivateMessage, op: UserOperation::EditPrivateMessage,
response: res, response: res,
@ -150,7 +153,7 @@ pub(crate) async fn receive_undo_delete_private_message(
.await??; .await??;
let res = PrivateMessageResponse { 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 { context.chat_server().do_send(SendUserRoomMessage {
op: UserOperation::EditPrivateMessage, op: UserOperation::EditPrivateMessage,
response: res, response: res,

View file

@ -13,7 +13,6 @@ use std::{env, env::VarError};
pub mod comment_report; pub mod comment_report;
pub mod post_report; pub mod post_report;
pub mod private_message_view;
pub mod aggregates; pub mod aggregates;
pub mod schema; pub mod schema;

View file

@ -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<Timestamp>,
ap_id -> Text,
local -> Bool,
creator_name -> Varchar,
creator_preferred_username -> Nullable<Varchar>,
creator_avatar -> Nullable<Text>,
creator_actor_id -> Text,
creator_local -> Bool,
recipient_name -> Varchar,
recipient_preferred_username -> Nullable<Varchar>,
recipient_avatar -> Nullable<Text>,
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<chrono::NaiveDateTime>,
pub ap_id: String,
pub local: bool,
pub creator_name: String,
pub creator_preferred_username: Option<String>,
pub creator_avatar: Option<String>,
pub creator_actor_id: String,
pub creator_local: bool,
pub recipient_name: String,
pub recipient_preferred_username: Option<String>,
pub recipient_avatar: Option<String>,
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<i64>,
limit: Option<i64>,
}
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<T: MaybeOptional<i64>>(mut self, page: T) -> Self {
self.page = page.get_optional();
self
}
pub fn limit<T: MaybeOptional<i64>>(mut self, limit: T) -> Self {
self.limit = limit.get_optional();
self
}
pub fn list(self) -> Result<Vec<PrivateMessageView>, 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::<PrivateMessageView>(self.conn)
}
}
impl PrivateMessageView {
pub fn read(conn: &PgConnection, from_private_message_id: i32) -> Result<Self, Error> {
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::<Self>(conn)
}
}

View file

@ -1,7 +1,8 @@
use crate::{naive_now, schema::private_message, ApubObject, Crud}; use crate::{naive_now, schema::private_message, ApubObject, Crud};
use diesel::{dsl::*, result::Error, *}; 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"] #[table_name = "private_message"]
pub struct PrivateMessage { pub struct PrivateMessage {
pub id: i32, pub id: i32,

View file

@ -2,6 +2,7 @@ pub mod comment_view;
pub mod community; pub mod community;
pub mod moderator; pub mod moderator;
pub mod post_view; pub mod post_view;
pub mod private_message_view;
pub mod site_view; pub mod site_view;
pub mod user_mention_view; pub mod user_mention_view;
pub mod user_view; pub mod user_view;

View file

@ -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<Self, Error> {
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::<PrivateMessageViewTuple>(conn)?;
Ok(PrivateMessageView {
private_message,
creator,
recipient,
})
}
}
pub struct PrivateMessageQueryBuilder<'a> {
conn: &'a PgConnection,
recipient_id: i32,
unread_only: bool,
page: Option<i64>,
limit: Option<i64>,
}
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<T: MaybeOptional<i64>>(mut self, page: T) -> Self {
self.page = page.get_optional();
self
}
pub fn limit<T: MaybeOptional<i64>>(mut self, limit: T) -> Self {
self.limit = limit.get_optional();
self
}
pub fn list(self) -> Result<Vec<PrivateMessageView>, 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::<PrivateMessageViewTuple>(self.conn)?;
Ok(PrivateMessageView::to_vec(res))
}
}
impl ViewToVec for PrivateMessageView {
type DbTuple = PrivateMessageViewTuple;
fn to_vec(pm: Vec<Self::DbTuple>) -> Vec<Self> {
pm.iter()
.map(|a| Self {
private_message: a.0.to_owned(),
creator: a.1.to_owned(),
recipient: a.2.to_owned(),
})
.collect::<Vec<Self>>()
}
}

View file

@ -1,15 +1,13 @@
use lemmy_db::{ use lemmy_db::views::{
private_message_view::PrivateMessageView,
views::{
comment_view::CommentView, comment_view::CommentView,
community::{ community::{
community_follower_view::CommunityFollowerView, community_follower_view::CommunityFollowerView,
community_moderator_view::CommunityModeratorView, community_moderator_view::CommunityModeratorView,
}, },
post_view::PostView, post_view::PostView,
private_message_view::PrivateMessageView,
user_mention_view::UserMentionView, user_mention_view::UserMentionView,
user_view::{UserViewDangerous, UserViewSafe}, user_view::{UserViewDangerous, UserViewSafe},
},
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};