Adding private message view.
This commit is contained in:
parent
313f0467c8
commit
1cf520254d
8 changed files with 154 additions and 160 deletions
|
@ -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 };
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
130
lemmy_db/src/views/private_message_view.rs
Normal file
130
lemmy_db/src/views/private_message_view.rs
Normal 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>>()
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,15 +1,13 @@
|
||||||
use lemmy_db::{
|
use lemmy_db::views::{
|
||||||
private_message_view::PrivateMessageView,
|
comment_view::CommentView,
|
||||||
views::{
|
community::{
|
||||||
comment_view::CommentView,
|
community_follower_view::CommunityFollowerView,
|
||||||
community::{
|
community_moderator_view::CommunityModeratorView,
|
||||||
community_follower_view::CommunityFollowerView,
|
|
||||||
community_moderator_view::CommunityModeratorView,
|
|
||||||
},
|
|
||||||
post_view::PostView,
|
|
||||||
user_mention_view::UserMentionView,
|
|
||||||
user_view::{UserViewDangerous, UserViewSafe},
|
|
||||||
},
|
},
|
||||||
|
post_view::PostView,
|
||||||
|
private_message_view::PrivateMessageView,
|
||||||
|
user_mention_view::UserMentionView,
|
||||||
|
user_view::{UserViewDangerous, UserViewSafe},
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue