]> Untitled Git - lemmy.git/blobdiff - crates/websocket/src/send.rs
First pass at adding comment trees. (#2362)
[lemmy.git] / crates / websocket / src / send.rs
index ccb29879e5d42bf9992adc6d263a7562bccba9df..f518f4c15322ae6ef1bce7a6609a407fde4707c9 100644 (file)
@@ -4,38 +4,29 @@ use crate::{
   OperationType,
 };
 use lemmy_api_common::{
-  blocking,
   comment::CommentResponse,
   community::CommunityResponse,
   person::PrivateMessageResponse,
   post::PostResponse,
+  utils::{blocking, check_person_block, get_user_lang, send_email_to_user},
 };
 use lemmy_db_schema::{
   newtypes::{CommentId, CommunityId, LocalUserId, PersonId, PostId, PrivateMessageId},
   source::{
     comment::Comment,
+    comment_reply::{CommentReply, CommentReplyForm},
     person::Person,
     person_mention::{PersonMention, PersonMentionForm},
     post::Post,
   },
   traits::{Crud, DeleteableOrRemoveable},
+  SubscribedType,
 };
-use lemmy_db_views::{
-  comment_view::CommentView,
-  local_user_view::LocalUserView,
-  post_view::PostView,
-  private_message_view::PrivateMessageView,
-};
-use lemmy_db_views_actor::community_view::CommunityView;
-use lemmy_utils::{
-  email::send_email,
-  settings::structs::Settings,
-  utils::MentionData,
-  ConnectionId,
-  LemmyError,
-};
-use tracing::error;
+use lemmy_db_views::structs::{CommentView, LocalUserView, PostView, PrivateMessageView};
+use lemmy_db_views_actor::structs::CommunityView;
+use lemmy_utils::{error::LemmyError, utils::MentionData, ConnectionId};
 
+#[tracing::instrument(skip_all)]
 pub async fn send_post_ws_message<OP: ToString + Send + OperationType + 'static>(
   post_id: PostId,
   op: OP,
@@ -61,6 +52,7 @@ pub async fn send_post_ws_message<OP: ToString + Send + OperationType + 'static>
 
 // TODO: in many call sites in apub crate, we are setting an empty vec for recipient_ids,
 //       we should get the actual recipient actors from somewhere
+#[tracing::instrument(skip_all)]
 pub async fn send_comment_ws_message_simple<OP: ToString + Send + OperationType + 'static>(
   comment_id: CommentId,
   op: OP,
@@ -69,6 +61,7 @@ pub async fn send_comment_ws_message_simple<OP: ToString + Send + OperationType
   send_comment_ws_message(comment_id, op, None, None, None, vec![], context).await
 }
 
+#[tracing::instrument(skip_all)]
 pub async fn send_comment_ws_message<OP: ToString + Send + OperationType + 'static>(
   comment_id: CommentId,
   op: OP,
@@ -107,6 +100,7 @@ pub async fn send_comment_ws_message<OP: ToString + Send + OperationType + 'stat
   Ok(res)
 }
 
+#[tracing::instrument(skip_all)]
 pub async fn send_community_ws_message<OP: ToString + Send + OperationType + 'static>(
   community_id: CommunityId,
   op: OP,
@@ -123,7 +117,7 @@ pub async fn send_community_ws_message<OP: ToString + Send + OperationType + 'st
 
   // Strip out the person id and subscribed when sending to others
   let mut res_mut = res.clone();
-  res_mut.community_view.subscribed = false;
+  res_mut.community_view.subscribed = SubscribedType::NotSubscribed;
 
   context.chat_server().do_send(SendCommunityRoomMessage {
     op,
@@ -135,6 +129,7 @@ pub async fn send_community_ws_message<OP: ToString + Send + OperationType + 'st
   Ok(res)
 }
 
+#[tracing::instrument(skip_all)]
 pub async fn send_pm_ws_message<OP: ToString + Send + OperationType + 'static>(
   private_message_id: PrivateMessageId,
   op: OP,
@@ -173,6 +168,7 @@ pub async fn send_pm_ws_message<OP: ToString + Send + OperationType + 'static>(
   Ok(res)
 }
 
+#[tracing::instrument(skip_all)]
 pub async fn send_local_notifs(
   mentions: Vec<MentionData>,
   comment: &Comment,
@@ -182,6 +178,7 @@ pub async fn send_local_notifs(
   context: &LemmyContext,
 ) -> Result<Vec<LocalUserId>, LemmyError> {
   let mut recipient_ids = Vec::new();
+  let inbox_link = format!("{}/inbox", context.settings().get_protocol_and_hostname());
 
   // Send the local mentions
   for mention in mentions
@@ -216,105 +213,108 @@ pub async fn send_local_notifs(
 
       // Send an email to those local users that have notifications on
       if do_send_email {
+        let lang = get_user_lang(&mention_user_view);
         send_email_to_user(
           &mention_user_view,
-          "Mentioned by",
-          "Person Mention",
-          &comment.content,
-          &context.settings(),
+          &lang.notification_mentioned_by_subject(&person.name),
+          &lang.notification_mentioned_by_body(&comment.content, &inbox_link, &person.name),
+          context.settings(),
         )
       }
     }
   }
 
-  // Send notifs to the parent commenter / poster
-  match comment.parent_id {
-    Some(parent_id) => {
-      let parent_comment =
-        blocking(context.pool(), move |conn| Comment::read(conn, parent_id)).await?;
-      if let Ok(parent_comment) = parent_comment {
-        // Don't send a notif to yourself
-        if parent_comment.creator_id != person.id {
-          // Get the parent commenter local_user
-          let user_view = blocking(context.pool(), move |conn| {
-            LocalUserView::read_person(conn, parent_comment.creator_id)
-          })
-          .await?;
-          if let Ok(parent_user_view) = user_view {
-            recipient_ids.push(parent_user_view.local_user.id);
-
-            if do_send_email {
-              send_email_to_user(
-                &parent_user_view,
-                "Reply from",
-                "Comment Reply",
-                &comment.content,
-                &context.settings(),
-              )
-            }
-          }
+  // Send comment_reply to the parent commenter / poster
+  if let Some(parent_comment_id) = comment.parent_comment_id() {
+    let parent_comment = blocking(context.pool(), move |conn| {
+      Comment::read(conn, parent_comment_id)
+    })
+    .await??;
+
+    // Get the parent commenter local_user
+    let parent_creator_id = parent_comment.creator_id;
+
+    // Only add to recipients if that person isn't blocked
+    let creator_blocked = check_person_block(person.id, parent_creator_id, context.pool())
+      .await
+      .is_err();
+
+    // Don't send a notif to yourself
+    if parent_comment.creator_id != person.id && !creator_blocked {
+      let user_view = blocking(context.pool(), move |conn| {
+        LocalUserView::read_person(conn, parent_creator_id)
+      })
+      .await?;
+      if let Ok(parent_user_view) = user_view {
+        recipient_ids.push(parent_user_view.local_user.id);
+
+        let comment_reply_form = CommentReplyForm {
+          recipient_id: parent_user_view.person.id,
+          comment_id: comment.id,
+          read: None,
+        };
+
+        // Allow this to fail softly, since comment edits might re-update or replace it
+        // Let the uniqueness handle this fail
+        blocking(context.pool(), move |conn| {
+          CommentReply::create(conn, &comment_reply_form)
+        })
+        .await?
+        .ok();
+
+        if do_send_email {
+          let lang = get_user_lang(&parent_user_view);
+          send_email_to_user(
+            &parent_user_view,
+            &lang.notification_comment_reply_subject(&person.name),
+            &lang.notification_comment_reply_body(&comment.content, &inbox_link, &person.name),
+            context.settings(),
+          )
         }
       }
     }
-    // Its a post
-    None => {
-      if post.creator_id != person.id {
-        let creator_id = post.creator_id;
-        let parent_user = blocking(context.pool(), move |conn| {
-          LocalUserView::read_person(conn, creator_id)
+  } else {
+    // If there's no parent, its the post creator
+    // Only add to recipients if that person isn't blocked
+    let creator_blocked = check_person_block(person.id, post.creator_id, context.pool())
+      .await
+      .is_err();
+
+    if post.creator_id != person.id && !creator_blocked {
+      let creator_id = post.creator_id;
+      let parent_user = blocking(context.pool(), move |conn| {
+        LocalUserView::read_person(conn, creator_id)
+      })
+      .await?;
+      if let Ok(parent_user_view) = parent_user {
+        recipient_ids.push(parent_user_view.local_user.id);
+
+        let comment_reply_form = CommentReplyForm {
+          recipient_id: parent_user_view.person.id,
+          comment_id: comment.id,
+          read: None,
+        };
+
+        // Allow this to fail softly, since comment edits might re-update or replace it
+        // Let the uniqueness handle this fail
+        blocking(context.pool(), move |conn| {
+          CommentReply::create(conn, &comment_reply_form)
         })
-        .await?;
-        if let Ok(parent_user_view) = parent_user {
-          recipient_ids.push(parent_user_view.local_user.id);
-
-          if do_send_email {
-            send_email_to_user(
-              &parent_user_view,
-              "Reply from",
-              "Post Reply",
-              &comment.content,
-              &context.settings(),
-            )
-          }
+        .await?
+        .ok();
+
+        if do_send_email {
+          let lang = get_user_lang(&parent_user_view);
+          send_email_to_user(
+            &parent_user_view,
+            &lang.notification_post_reply_subject(&person.name),
+            &lang.notification_post_reply_body(&comment.content, &inbox_link, &person.name),
+            context.settings(),
+          )
         }
       }
     }
-  };
-  Ok(recipient_ids)
-}
-
-pub fn send_email_to_user(
-  local_user_view: &LocalUserView,
-  subject_text: &str,
-  body_text: &str,
-  comment_content: &str,
-  settings: &Settings,
-) {
-  if local_user_view.person.banned || !local_user_view.local_user.send_notifications_to_email {
-    return;
   }
 
-  if let Some(user_email) = &local_user_view.local_user.email {
-    let subject = &format!(
-      "{} - {} {}",
-      subject_text, settings.hostname, local_user_view.person.name,
-    );
-    let html = &format!(
-      "<h1>{}</h1><br><div>{} - {}</div><br><a href={}/inbox>inbox</a>",
-      body_text,
-      local_user_view.person.name,
-      comment_content,
-      settings.get_protocol_and_hostname()
-    );
-    match send_email(
-      subject,
-      user_email,
-      &local_user_view.person.name,
-      html,
-      settings,
-    ) {
-      Ok(_o) => _o,
-      Err(e) => error!("{}", e),
-    };
-  }
+  Ok(recipient_ids)
 }