Notify user about new replies

This commit is contained in:
silverpill 2021-10-15 00:27:39 +00:00
parent 43256fa4b1
commit bc65186f00
4 changed files with 64 additions and 2 deletions

View file

@ -25,15 +25,20 @@ impl ApiNotification {
notification.sender,
instance_url,
);
let status = notification.post.map(|post| {
Status::from_post(post, instance_url)
});
let event_type_mastodon = match notification.event_type {
EventType::Follow => "follow",
EventType::FollowRequest => "follow_request",
EventType::Reply => "reply",
};
Self {
id: notification.id.to_string(),
event_type: event_type_mastodon.to_string(),
created_at: notification.created_at,
account,
status: None,
status,
}
}
}

View file

@ -4,6 +4,7 @@ use tokio_postgres::GenericClient;
use uuid::Uuid;
use crate::errors::DatabaseError;
use crate::models::posts::types::DbPost;
use super::types::{EventType, Notification};
pub async fn create_notification(
@ -26,16 +27,51 @@ pub async fn create_notification(
Ok(())
}
pub async fn create_reply_notification(
db_client: &impl GenericClient,
reply: &DbPost,
) -> Result<(), DatabaseError> {
let event_type: i16 = EventType::Reply.into();
db_client.execute(
"
INSERT INTO notification (
sender_id,
recipient_id,
post_id,
event_type
)
SELECT $1, post.author_id, $2, $3
FROM post WHERE id = $4
",
&[
&reply.author_id,
&reply.id,
&event_type,
&reply.in_reply_to_id,
],
).await?;
Ok(())
}
pub async fn get_notifications(
db_client: &impl GenericClient,
recipient_id: &Uuid,
) -> Result<Vec<Notification>, DatabaseError> {
let rows = db_client.query(
"
SELECT notification, sender
SELECT
notification, sender, post, post_author,
ARRAY(
SELECT media_attachment
FROM media_attachment WHERE post_id = post.id
) AS attachments
FROM notification
JOIN actor_profile AS sender
ON notification.sender_id = sender.id
LEFT JOIN post
ON notification.post_id = post.id
LEFT JOIN actor_profile AS post_author
ON post.author_id = post_author.id
WHERE recipient_id = $1
",
&[&recipient_id],

View file

@ -6,6 +6,8 @@ use tokio_postgres::Row;
use uuid::Uuid;
use crate::errors::{ConversionError, DatabaseError};
use crate::models::attachments::types::DbMediaAttachment;
use crate::models::posts::types::{DbPost, Post};
use crate::models::profiles::types::DbActorProfile;
#[allow(dead_code)]
@ -22,12 +24,16 @@ struct DbNotification {
pub enum EventType {
Follow,
FollowRequest,
Reply,
}
impl From<EventType> for i16 {
fn from(value: EventType) -> i16 {
match value {
EventType::Follow => 1,
EventType::FollowRequest => 2,
EventType::Reply => 3,
}
}
}
@ -38,6 +44,8 @@ impl TryFrom<i16> for EventType {
fn try_from(value: i16) -> Result<Self, Self::Error> {
let event_type = match value {
1 => Self::Follow,
2 => Self::FollowRequest,
3 => Self::Reply,
_ => return Err(ConversionError),
};
Ok(event_type)
@ -47,6 +55,7 @@ impl TryFrom<i16> for EventType {
pub struct Notification {
pub id: i32,
pub sender: DbActorProfile,
pub post: Option<Post>,
pub event_type: EventType,
pub created_at: DateTime<Utc>,
}
@ -58,9 +67,19 @@ impl TryFrom<&Row> for Notification {
fn try_from(row: &Row) -> Result<Self, Self::Error> {
let db_notification: DbNotification = row.try_get("notification")?;
let db_sender: DbActorProfile = row.try_get("sender")?;
let maybe_db_post: Option<DbPost> = row.try_get("post")?;
let maybe_post = match maybe_db_post {
Some(db_post) => {
let db_post_author: DbActorProfile = row.try_get("post_author")?;
let db_attachments: Vec<DbMediaAttachment> = row.try_get("attachments")?;
Some(Post::new(db_post, db_post_author, db_attachments))
},
None => None,
};
let notification = Self {
id: db_notification.id,
sender: db_sender,
post: maybe_post,
event_type: EventType::try_from(db_notification.event_type)?,
created_at: db_notification.created_at,
};

View file

@ -11,6 +11,7 @@ use crate::models::cleanup::{
find_orphaned_ipfs_objects,
DeletionQueue,
};
use crate::models::notifications::queries::create_reply_notification;
use crate::models::profiles::queries::update_post_count;
use super::types::{DbPost, Post, PostCreateData};
@ -125,6 +126,7 @@ pub async fn create_post(
let author = update_post_count(&transaction, &db_post.author_id, 1).await?;
if let Some(in_reply_to_id) = &db_post.in_reply_to_id {
update_reply_count(&transaction, in_reply_to_id, 1).await?;
create_reply_notification(&transaction, &db_post).await?;
}
transaction.commit().await?;