mirror of
https://github.com/LemmyNet/lemmy.git
synced 2025-09-02 11:13:51 +00:00
This reverts commit 76fbb29079
.
This commit is contained in:
parent
0d149dd613
commit
3922f0f325
26 changed files with 420 additions and 393 deletions
|
@ -69,5 +69,8 @@ pub async fn distinguish_comment(
|
|||
)
|
||||
.await?;
|
||||
|
||||
Ok(Json(CommentResponse { comment_view }))
|
||||
Ok(Json(CommentResponse {
|
||||
comment_view,
|
||||
recipient_ids: Vec::new(),
|
||||
}))
|
||||
}
|
||||
|
|
|
@ -8,9 +8,10 @@ use lemmy_api_utils::{
|
|||
utils::{check_bot_account, check_community_user_action, check_local_vote_mode},
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
newtypes::PostOrCommentId,
|
||||
newtypes::{LocalUserId, PostOrCommentId},
|
||||
source::{
|
||||
comment::{CommentActions, CommentLikeForm},
|
||||
comment_reply::CommentReply,
|
||||
person::PersonActions,
|
||||
},
|
||||
traits::Likeable,
|
||||
|
@ -34,6 +35,8 @@ pub async fn like_comment(
|
|||
let comment_id = data.comment_id;
|
||||
let my_person_id = local_user_view.person.id;
|
||||
|
||||
let mut recipient_ids = Vec::<LocalUserId>::new();
|
||||
|
||||
check_local_vote_mode(
|
||||
data.score,
|
||||
PostOrCommentId::Comment(comment_id),
|
||||
|
@ -60,6 +63,16 @@ pub async fn like_comment(
|
|||
)
|
||||
.await?;
|
||||
|
||||
// Add parent poster or commenter to recipients
|
||||
let comment_reply = CommentReply::read_by_comment(&mut context.pool(), comment_id).await;
|
||||
if let Ok(Some(reply)) = comment_reply {
|
||||
let recipient_id = reply.recipient_id;
|
||||
if let Ok(local_recipient) = LocalUserView::read_person(&mut context.pool(), recipient_id).await
|
||||
{
|
||||
recipient_ids.push(local_recipient.local_user.id);
|
||||
}
|
||||
}
|
||||
|
||||
let mut like_form = CommentLikeForm::new(my_person_id, data.comment_id, data.score);
|
||||
|
||||
// Remove any likes first
|
||||
|
@ -106,6 +119,7 @@ pub async fn like_comment(
|
|||
context.deref(),
|
||||
comment_id,
|
||||
Some(local_user_view),
|
||||
recipient_ids,
|
||||
local_instance_id,
|
||||
)
|
||||
.await?,
|
||||
|
|
|
@ -34,5 +34,8 @@ pub async fn save_comment(
|
|||
)
|
||||
.await?;
|
||||
|
||||
Ok(Json(CommentResponse { comment_view }))
|
||||
Ok(Json(CommentResponse {
|
||||
comment_view,
|
||||
recipient_ids: Vec::new(),
|
||||
}))
|
||||
}
|
||||
|
|
|
@ -7,4 +7,3 @@ pub mod lock;
|
|||
pub mod mark_many_read;
|
||||
pub mod mark_read;
|
||||
pub mod save;
|
||||
pub mod update_notifications;
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
use activitypub_federation::config::Data;
|
||||
use actix_web::web::Json;
|
||||
use lemmy_api_utils::context::LemmyContext;
|
||||
use lemmy_db_schema::source::post::PostActions;
|
||||
use lemmy_db_views_local_user::LocalUserView;
|
||||
use lemmy_db_views_post::api::UpdatePostNotifications;
|
||||
use lemmy_db_views_site::api::SuccessResponse;
|
||||
use lemmy_utils::error::LemmyResult;
|
||||
|
||||
pub async fn update_post_notifications(
|
||||
data: Json<UpdatePostNotifications>,
|
||||
context: Data<LemmyContext>,
|
||||
local_user_view: LocalUserView,
|
||||
) -> LemmyResult<Json<SuccessResponse>> {
|
||||
PostActions::update_notification_state(
|
||||
data.post_id,
|
||||
local_user_view.person.id,
|
||||
data.new_state,
|
||||
&mut context.pool(),
|
||||
)
|
||||
.await?;
|
||||
Ok(Json(SuccessResponse::default()))
|
||||
}
|
|
@ -19,6 +19,7 @@ use lemmy_api_utils::{
|
|||
};
|
||||
use lemmy_db_schema::{
|
||||
impls::actor_language::validate_post_language,
|
||||
newtypes::PostOrCommentId,
|
||||
source::{
|
||||
comment::{Comment, CommentActions, CommentInsertForm, CommentLikeForm},
|
||||
comment_reply::{CommentReply, CommentReplyUpdateForm},
|
||||
|
@ -32,7 +33,7 @@ use lemmy_db_views_post::PostView;
|
|||
use lemmy_db_views_site::SiteView;
|
||||
use lemmy_utils::{
|
||||
error::{LemmyErrorType, LemmyResult},
|
||||
utils::validation::is_valid_body_field,
|
||||
utils::{mention::scrape_text_for_mentions, validation::is_valid_body_field},
|
||||
};
|
||||
|
||||
pub async fn create_comment(
|
||||
|
@ -112,14 +113,19 @@ pub async fn create_comment(
|
|||
Comment::create(&mut context.pool(), &comment_form, parent_path.as_ref()).await?;
|
||||
plugin_hook_after("after_create_local_comment", &inserted_comment)?;
|
||||
|
||||
let inserted_comment_id = inserted_comment.id;
|
||||
|
||||
// Scan the comment for user mentions, add those rows
|
||||
let mentions = scrape_text_for_mentions(&content);
|
||||
let do_send_email = !local_site.disable_email_notifications;
|
||||
send_local_notifs(
|
||||
&post,
|
||||
Some(&inserted_comment),
|
||||
let recipient_ids = send_local_notifs(
|
||||
mentions,
|
||||
PostOrCommentId::Comment(inserted_comment_id),
|
||||
&local_user_view.person,
|
||||
&post_view.community,
|
||||
do_send_email,
|
||||
&context,
|
||||
Some(&local_user_view),
|
||||
local_instance_id,
|
||||
)
|
||||
.await?;
|
||||
|
||||
|
@ -179,6 +185,7 @@ pub async fn create_comment(
|
|||
&context,
|
||||
inserted_comment.id,
|
||||
Some(local_user_view),
|
||||
recipient_ids,
|
||||
local_instance_id,
|
||||
)
|
||||
.await?,
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
use activitypub_federation::config::Data;
|
||||
use actix_web::web::Json;
|
||||
use lemmy_api_utils::{
|
||||
build_response::build_comment_response,
|
||||
build_response::{build_comment_response, send_local_notifs},
|
||||
context::LemmyContext,
|
||||
send_activity::{ActivityChannel, SendActivityData},
|
||||
utils::check_community_user_action,
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
newtypes::PostOrCommentId,
|
||||
source::comment::{Comment, CommentUpdateForm},
|
||||
traits::Crud,
|
||||
};
|
||||
|
@ -61,6 +62,16 @@ pub async fn delete_comment(
|
|||
)
|
||||
.await?;
|
||||
|
||||
let recipient_ids = send_local_notifs(
|
||||
vec![],
|
||||
PostOrCommentId::Comment(comment_id),
|
||||
&local_user_view.person,
|
||||
false,
|
||||
&context,
|
||||
Some(&local_user_view),
|
||||
local_instance_id,
|
||||
)
|
||||
.await?;
|
||||
let updated_comment_id = updated_comment.id;
|
||||
|
||||
ActivityChannel::submit_activity(
|
||||
|
@ -77,6 +88,7 @@ pub async fn delete_comment(
|
|||
&context,
|
||||
updated_comment_id,
|
||||
Some(local_user_view),
|
||||
recipient_ids,
|
||||
local_instance_id,
|
||||
)
|
||||
.await?,
|
||||
|
|
|
@ -21,6 +21,13 @@ pub async fn get_comment(
|
|||
check_private_instance(&local_user_view, &local_site)?;
|
||||
|
||||
Ok(Json(
|
||||
build_comment_response(&context, data.id, local_user_view, local_instance_id).await?,
|
||||
build_comment_response(
|
||||
&context,
|
||||
data.id,
|
||||
local_user_view,
|
||||
vec![],
|
||||
local_instance_id,
|
||||
)
|
||||
.await?,
|
||||
))
|
||||
}
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
use activitypub_federation::config::Data;
|
||||
use actix_web::web::Json;
|
||||
use lemmy_api_utils::{
|
||||
build_response::build_comment_response,
|
||||
build_response::{build_comment_response, send_local_notifs},
|
||||
context::LemmyContext,
|
||||
send_activity::{ActivityChannel, SendActivityData},
|
||||
utils::check_community_mod_action,
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
newtypes::PostOrCommentId,
|
||||
source::{
|
||||
comment::{Comment, CommentUpdateForm},
|
||||
comment_report::CommentReport,
|
||||
|
@ -83,6 +84,16 @@ pub async fn remove_comment(
|
|||
};
|
||||
ModRemoveComment::create(&mut context.pool(), &form).await?;
|
||||
|
||||
let recipient_ids = send_local_notifs(
|
||||
vec![],
|
||||
PostOrCommentId::Comment(comment_id),
|
||||
&local_user_view.person,
|
||||
false,
|
||||
&context,
|
||||
Some(&local_user_view),
|
||||
local_instance_id,
|
||||
)
|
||||
.await?;
|
||||
let updated_comment_id = updated_comment.id;
|
||||
|
||||
ActivityChannel::submit_activity(
|
||||
|
@ -100,6 +111,7 @@ pub async fn remove_comment(
|
|||
&context,
|
||||
updated_comment_id,
|
||||
Some(local_user_view),
|
||||
recipient_ids,
|
||||
local_instance_id,
|
||||
)
|
||||
.await?,
|
||||
|
|
|
@ -10,6 +10,7 @@ use lemmy_api_utils::{
|
|||
};
|
||||
use lemmy_db_schema::{
|
||||
impls::actor_language::validate_post_language,
|
||||
newtypes::PostOrCommentId,
|
||||
source::comment::{Comment, CommentUpdateForm},
|
||||
traits::Crud,
|
||||
};
|
||||
|
@ -20,7 +21,7 @@ use lemmy_db_views_comment::{
|
|||
use lemmy_db_views_local_user::LocalUserView;
|
||||
use lemmy_utils::{
|
||||
error::{LemmyErrorType, LemmyResult},
|
||||
utils::validation::is_valid_body_field,
|
||||
utils::{mention::scrape_text_for_mentions, validation::is_valid_body_field},
|
||||
};
|
||||
|
||||
pub async fn update_comment(
|
||||
|
@ -78,13 +79,16 @@ pub async fn update_comment(
|
|||
plugin_hook_after("after_update_local_comment", &updated_comment)?;
|
||||
|
||||
// Do the mentions / recipients
|
||||
send_local_notifs(
|
||||
&orig_comment.post,
|
||||
Some(&updated_comment),
|
||||
let updated_comment_content = updated_comment.content.clone();
|
||||
let mentions = scrape_text_for_mentions(&updated_comment_content);
|
||||
let recipient_ids = send_local_notifs(
|
||||
mentions,
|
||||
PostOrCommentId::Comment(comment_id),
|
||||
&local_user_view.person,
|
||||
&orig_comment.community,
|
||||
false,
|
||||
&context,
|
||||
Some(&local_user_view),
|
||||
local_instance_id,
|
||||
)
|
||||
.await?;
|
||||
|
||||
|
@ -98,6 +102,7 @@ pub async fn update_comment(
|
|||
&context,
|
||||
updated_comment.id,
|
||||
Some(local_user_view),
|
||||
recipient_ids,
|
||||
local_instance_id,
|
||||
)
|
||||
.await?,
|
||||
|
|
|
@ -21,6 +21,7 @@ use lemmy_api_utils::{
|
|||
};
|
||||
use lemmy_db_schema::{
|
||||
impls::actor_language::validate_post_language,
|
||||
newtypes::PostOrCommentId,
|
||||
source::post::{Post, PostActions, PostInsertForm, PostLikeForm, PostReadForm},
|
||||
traits::{Crud, Likeable, Readable},
|
||||
utils::diesel_url_create,
|
||||
|
@ -33,6 +34,7 @@ use lemmy_db_views_site::SiteView;
|
|||
use lemmy_utils::{
|
||||
error::LemmyResult,
|
||||
utils::{
|
||||
mention::scrape_text_for_mentions,
|
||||
slurs::check_slurs,
|
||||
validation::{
|
||||
is_url_blocked,
|
||||
|
@ -167,18 +169,22 @@ pub async fn create_post(
|
|||
// They like their own post by default
|
||||
let person_id = local_user_view.person.id;
|
||||
let post_id = inserted_post.id;
|
||||
let local_instance_id = local_user_view.person.instance_id;
|
||||
let like_form = PostLikeForm::new(post_id, person_id, 1);
|
||||
|
||||
PostActions::like(&mut context.pool(), &like_form).await?;
|
||||
|
||||
// Scan the post body for user mentions, add those rows
|
||||
let mentions = scrape_text_for_mentions(&inserted_post.body.clone().unwrap_or_default());
|
||||
let do_send_email = !local_site.disable_email_notifications;
|
||||
send_local_notifs(
|
||||
&inserted_post,
|
||||
None,
|
||||
mentions,
|
||||
PostOrCommentId::Post(inserted_post.id),
|
||||
&local_user_view.person,
|
||||
community,
|
||||
do_send_email,
|
||||
&context,
|
||||
Some(&local_user_view),
|
||||
local_instance_id,
|
||||
)
|
||||
.await?;
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ use lemmy_api_utils::{
|
|||
};
|
||||
use lemmy_db_schema::{
|
||||
impls::actor_language::validate_post_language,
|
||||
newtypes::PostOrCommentId,
|
||||
source::{
|
||||
community::Community,
|
||||
post::{Post, PostUpdateForm},
|
||||
|
@ -37,6 +38,7 @@ use lemmy_db_views_site::SiteView;
|
|||
use lemmy_utils::{
|
||||
error::{LemmyErrorType, LemmyResult},
|
||||
utils::{
|
||||
mention::scrape_text_for_mentions,
|
||||
slurs::check_slurs,
|
||||
validation::{
|
||||
is_url_blocked,
|
||||
|
@ -161,13 +163,16 @@ pub async fn update_post(
|
|||
let updated_post = Post::update(&mut context.pool(), post_id, &post_form).await?;
|
||||
plugin_hook_after("after_update_local_post", &post_form)?;
|
||||
|
||||
// Scan the post body for user mentions, add those rows
|
||||
let mentions = scrape_text_for_mentions(&updated_post.body.clone().unwrap_or_default());
|
||||
send_local_notifs(
|
||||
&updated_post,
|
||||
None,
|
||||
mentions,
|
||||
PostOrCommentId::Post(updated_post.id),
|
||||
&local_user_view.person,
|
||||
&orig_post.community,
|
||||
false,
|
||||
&context,
|
||||
Some(&local_user_view),
|
||||
local_instance_id,
|
||||
)
|
||||
.await?;
|
||||
|
||||
|
|
|
@ -1,36 +1,38 @@
|
|||
use crate::{context::LemmyContext, utils::is_mod_or_admin};
|
||||
use crate::{
|
||||
context::LemmyContext,
|
||||
utils::{check_person_instance_community_block, is_mod_or_admin},
|
||||
};
|
||||
use actix_web::web::Json;
|
||||
use lemmy_db_schema::{
|
||||
newtypes::{CommentId, CommunityId, InstanceId, PersonId, PostId},
|
||||
newtypes::{CommentId, CommunityId, InstanceId, LocalUserId, PostId, PostOrCommentId},
|
||||
source::{
|
||||
actor_language::CommunityLanguage,
|
||||
comment::Comment,
|
||||
comment_reply::{CommentReply, CommentReplyInsertForm},
|
||||
community::{Community, CommunityActions},
|
||||
instance::InstanceActions,
|
||||
person::{Person, PersonActions},
|
||||
community::Community,
|
||||
person::Person,
|
||||
person_comment_mention::{PersonCommentMention, PersonCommentMentionInsertForm},
|
||||
person_post_mention::{PersonPostMention, PersonPostMentionInsertForm},
|
||||
post::{Post, PostActions},
|
||||
post::Post,
|
||||
},
|
||||
traits::{Blockable, Crud},
|
||||
traits::Crud,
|
||||
};
|
||||
use lemmy_db_schema_file::enums::PostNotifications;
|
||||
use lemmy_db_views_comment::{api::CommentResponse, CommentView};
|
||||
use lemmy_db_views_community::{api::CommunityResponse, CommunityView};
|
||||
use lemmy_db_views_local_user::LocalUserView;
|
||||
use lemmy_db_views_post::{api::PostResponse, PostView};
|
||||
use lemmy_email::notifications::{send_mention_email, send_reply_email};
|
||||
use lemmy_utils::{
|
||||
error::{LemmyErrorType, LemmyResult},
|
||||
utils::mention::scrape_text_for_mentions,
|
||||
use lemmy_email::notifications::{
|
||||
send_comment_reply_email,
|
||||
send_mention_email,
|
||||
send_post_reply_email,
|
||||
};
|
||||
use url::Url;
|
||||
use lemmy_utils::{error::LemmyResult, utils::mention::MentionData};
|
||||
|
||||
pub async fn build_comment_response(
|
||||
context: &LemmyContext,
|
||||
comment_id: CommentId,
|
||||
local_user_view: Option<LocalUserView>,
|
||||
recipient_ids: Vec<LocalUserId>,
|
||||
local_instance_id: InstanceId,
|
||||
) -> LemmyResult<CommentResponse> {
|
||||
let local_user = local_user_view.map(|l| l.local_user);
|
||||
|
@ -41,7 +43,10 @@ pub async fn build_comment_response(
|
|||
local_instance_id,
|
||||
)
|
||||
.await?;
|
||||
Ok(CommentResponse { comment_view })
|
||||
Ok(CommentResponse {
|
||||
comment_view,
|
||||
recipient_ids,
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn build_community_response(
|
||||
|
@ -89,223 +94,220 @@ pub async fn build_post_response(
|
|||
Ok(Json(PostResponse { post_view }))
|
||||
}
|
||||
|
||||
/// Scans the post/comment content for mentions, then sends notifications via db and email
|
||||
/// to mentioned users and parent creator.
|
||||
// TODO: this function is a mess and should be split up to handle email separately
|
||||
pub async fn send_local_notifs(
|
||||
post: &Post,
|
||||
comment_opt: Option<&Comment>,
|
||||
mentions: Vec<MentionData>,
|
||||
post_or_comment_id: PostOrCommentId,
|
||||
person: &Person,
|
||||
community: &Community,
|
||||
do_send_email: bool,
|
||||
context: &LemmyContext,
|
||||
) -> LemmyResult<()> {
|
||||
let parent_creator =
|
||||
notify_parent_creator(person, post, comment_opt, community, do_send_email, context).await?;
|
||||
local_user_view: Option<&LocalUserView>,
|
||||
local_instance_id: InstanceId,
|
||||
) -> LemmyResult<Vec<LocalUserId>> {
|
||||
let mut recipient_ids = Vec::new();
|
||||
|
||||
send_local_mentions(
|
||||
post,
|
||||
comment_opt,
|
||||
person,
|
||||
parent_creator,
|
||||
community,
|
||||
do_send_email,
|
||||
context,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn notify_parent_creator(
|
||||
person: &Person,
|
||||
post: &Post,
|
||||
comment_opt: Option<&Comment>,
|
||||
community: &Community,
|
||||
do_send_email: bool,
|
||||
context: &LemmyContext,
|
||||
) -> LemmyResult<Option<PersonId>> {
|
||||
let Some(comment) = comment_opt else {
|
||||
return Ok(None);
|
||||
let (comment_opt, post, community) = match post_or_comment_id {
|
||||
PostOrCommentId::Post(post_id) => {
|
||||
let post_view = PostView::read(
|
||||
&mut context.pool(),
|
||||
post_id,
|
||||
local_user_view.map(|view| &view.local_user),
|
||||
local_instance_id,
|
||||
false,
|
||||
)
|
||||
.await?;
|
||||
(None, post_view.post, post_view.community)
|
||||
}
|
||||
PostOrCommentId::Comment(comment_id) => {
|
||||
// When called from api code, we have local user view and can read with CommentView
|
||||
// to reduce db queries. But when receiving a federated comment the user view is None,
|
||||
// which means that comments inside private communities cant be read. As a workaround
|
||||
// we need to read the items manually to bypass this check.
|
||||
if let Some(local_user_view) = local_user_view {
|
||||
// Read the comment view to get extra info
|
||||
let comment_view = CommentView::read(
|
||||
&mut context.pool(),
|
||||
comment_id,
|
||||
Some(&local_user_view.local_user),
|
||||
local_instance_id,
|
||||
)
|
||||
.await?;
|
||||
(
|
||||
Some(comment_view.comment),
|
||||
comment_view.post,
|
||||
comment_view.community,
|
||||
)
|
||||
} else {
|
||||
let comment = Comment::read(&mut context.pool(), comment_id).await?;
|
||||
let post = Post::read(&mut context.pool(), comment.post_id).await?;
|
||||
let community = Community::read(&mut context.pool(), post.community_id).await?;
|
||||
(Some(comment), post, community)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Get the parent data
|
||||
let (parent_creator_id, parent_comment) =
|
||||
// Send the local mentions
|
||||
for mention in mentions
|
||||
.iter()
|
||||
.filter(|m| m.is_local(&context.settings().hostname) && m.name.ne(&person.name))
|
||||
{
|
||||
let mention_name = mention.name.clone();
|
||||
let user_view = LocalUserView::read_from_name(&mut context.pool(), &mention_name).await;
|
||||
if let Ok(mention_user_view) = user_view {
|
||||
// TODO
|
||||
// At some point, make it so you can't tag the parent creator either
|
||||
// Potential duplication of notifications, one for reply and the other for mention, is handled
|
||||
// below by checking recipient ids
|
||||
recipient_ids.push(mention_user_view.local_user.id);
|
||||
|
||||
// Make the correct reply form depending on whether its a post or comment mention
|
||||
let (link, comment_content_or_post_body) = if let Some(comment) = &comment_opt {
|
||||
let person_comment_mention_form = PersonCommentMentionInsertForm {
|
||||
recipient_id: mention_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
|
||||
PersonCommentMention::create(&mut context.pool(), &person_comment_mention_form)
|
||||
.await
|
||||
.ok();
|
||||
(
|
||||
comment.local_url(context.settings())?,
|
||||
comment.content.clone(),
|
||||
)
|
||||
} else {
|
||||
let person_post_mention_form = PersonPostMentionInsertForm {
|
||||
recipient_id: mention_user_view.person.id,
|
||||
post_id: post.id,
|
||||
read: None,
|
||||
};
|
||||
|
||||
// Allow this to fail softly, since edits might re-update or replace it
|
||||
PersonPostMention::create(&mut context.pool(), &person_post_mention_form)
|
||||
.await
|
||||
.ok();
|
||||
(
|
||||
post.local_url(context.settings())?,
|
||||
post.body.clone().unwrap_or_default(),
|
||||
)
|
||||
};
|
||||
|
||||
// Send an email to those local users that have notifications on
|
||||
if do_send_email {
|
||||
send_mention_email(
|
||||
&mention_user_view,
|
||||
&comment_content_or_post_body,
|
||||
person,
|
||||
link.into(),
|
||||
context.settings(),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Send comment_reply to the parent commenter / poster
|
||||
if let Some(comment) = &comment_opt {
|
||||
if let Some(parent_comment_id) = comment.parent_comment_id() {
|
||||
let parent_comment = Comment::read(&mut context.pool(), parent_comment_id).await?;
|
||||
(parent_comment.creator_id, Some(parent_comment))
|
||||
} else {
|
||||
(post.creator_id, None)
|
||||
};
|
||||
|
||||
// Dont send notification to yourself
|
||||
if parent_creator_id == person.id {
|
||||
return Ok(None);
|
||||
}
|
||||
// Get the parent commenter local_user
|
||||
let parent_creator_id = parent_comment.creator_id;
|
||||
|
||||
let is_blocked = check_notifications_allowed(
|
||||
parent_creator_id,
|
||||
// Only block from the community's instance_id
|
||||
community.instance_id,
|
||||
post,
|
||||
context,
|
||||
)
|
||||
.await
|
||||
.is_err();
|
||||
if is_blocked {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let Ok(user_view) = LocalUserView::read_person(&mut context.pool(), parent_creator_id).await
|
||||
else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
let comment_reply_form = CommentReplyInsertForm {
|
||||
recipient_id: 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
|
||||
CommentReply::create(&mut context.pool(), &comment_reply_form)
|
||||
.await
|
||||
.ok();
|
||||
|
||||
if do_send_email {
|
||||
send_reply_email(
|
||||
&user_view,
|
||||
comment,
|
||||
person,
|
||||
&parent_comment,
|
||||
post,
|
||||
context.settings(),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
Ok(Some(user_view.person.id))
|
||||
}
|
||||
|
||||
async fn send_local_mentions(
|
||||
post: &Post,
|
||||
comment_opt: Option<&Comment>,
|
||||
person: &Person,
|
||||
parent_creator_id: Option<PersonId>,
|
||||
community: &Community,
|
||||
do_send_email: bool,
|
||||
context: &LemmyContext,
|
||||
) -> LemmyResult<()> {
|
||||
let content = if let Some(comment) = comment_opt {
|
||||
&comment.content
|
||||
} else {
|
||||
&post.body.clone().unwrap_or_default()
|
||||
};
|
||||
let mentions = scrape_text_for_mentions(content)
|
||||
.into_iter()
|
||||
.filter(|m| m.is_local(&context.settings().hostname) && m.name.ne(&person.name));
|
||||
for mention in mentions {
|
||||
// Ignore error if user is remote
|
||||
let Ok(user_view) = LocalUserView::read_from_name(&mut context.pool(), &mention.name).await
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
|
||||
// Dont send any mention notification to parent creator nor to yourself
|
||||
if Some(user_view.person.id) == parent_creator_id || user_view.person.id == person.id {
|
||||
continue;
|
||||
}
|
||||
|
||||
let is_blocked = check_notifications_allowed(
|
||||
user_view.person.id,
|
||||
// Only block from the community's instance_id
|
||||
community.instance_id,
|
||||
post,
|
||||
context,
|
||||
)
|
||||
.await
|
||||
.is_err();
|
||||
if is_blocked {
|
||||
continue;
|
||||
};
|
||||
|
||||
let (link, comment_content_or_post_body) =
|
||||
insert_post_or_comment_mention(&user_view, post, comment_opt, context).await?;
|
||||
|
||||
// Send an email to those local users that have notifications on
|
||||
if do_send_email {
|
||||
send_mention_email(
|
||||
&user_view,
|
||||
&comment_content_or_post_body,
|
||||
person,
|
||||
link.into(),
|
||||
context.settings(),
|
||||
let check_blocks = check_person_instance_community_block(
|
||||
person.id,
|
||||
parent_creator_id,
|
||||
// Only block from the community's instance_id
|
||||
community.instance_id,
|
||||
community.id,
|
||||
&mut context.pool(),
|
||||
)
|
||||
.await;
|
||||
.await
|
||||
.is_err();
|
||||
|
||||
// Don't send a notif to yourself
|
||||
if parent_comment.creator_id != person.id && !check_blocks {
|
||||
let user_view = LocalUserView::read_person(&mut context.pool(), parent_creator_id).await;
|
||||
if let Ok(parent_user_view) = user_view {
|
||||
// Don't duplicate notif if already mentioned by checking recipient ids
|
||||
if !recipient_ids.contains(&parent_user_view.local_user.id) {
|
||||
recipient_ids.push(parent_user_view.local_user.id);
|
||||
|
||||
let comment_reply_form = CommentReplyInsertForm {
|
||||
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
|
||||
CommentReply::create(&mut context.pool(), &comment_reply_form)
|
||||
.await
|
||||
.ok();
|
||||
|
||||
if do_send_email {
|
||||
send_comment_reply_email(
|
||||
&parent_user_view,
|
||||
comment,
|
||||
person,
|
||||
&parent_comment,
|
||||
&post,
|
||||
context.settings(),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Use the post creator to check blocks
|
||||
let check_blocks = check_person_instance_community_block(
|
||||
person.id,
|
||||
post.creator_id,
|
||||
// Only block from the community's instance_id
|
||||
community.instance_id,
|
||||
community.id,
|
||||
&mut context.pool(),
|
||||
)
|
||||
.await
|
||||
.is_err();
|
||||
|
||||
if post.creator_id != person.id && !check_blocks {
|
||||
let creator_id = post.creator_id;
|
||||
let parent_user = LocalUserView::read_person(&mut context.pool(), creator_id).await;
|
||||
if let Ok(parent_user_view) = parent_user {
|
||||
if !recipient_ids.contains(&parent_user_view.local_user.id) {
|
||||
recipient_ids.push(parent_user_view.local_user.id);
|
||||
|
||||
let comment_reply_form = CommentReplyInsertForm {
|
||||
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
|
||||
CommentReply::create(&mut context.pool(), &comment_reply_form)
|
||||
.await
|
||||
.ok();
|
||||
|
||||
if do_send_email {
|
||||
send_post_reply_email(
|
||||
&parent_user_view,
|
||||
comment,
|
||||
person,
|
||||
&post,
|
||||
context.settings(),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Make the correct reply form depending on whether its a post or comment mention
|
||||
async fn insert_post_or_comment_mention(
|
||||
mention_user_view: &LocalUserView,
|
||||
post: &Post,
|
||||
comment_opt: Option<&Comment>,
|
||||
context: &LemmyContext,
|
||||
) -> LemmyResult<(Url, String)> {
|
||||
if let Some(comment) = &comment_opt {
|
||||
let person_comment_mention_form = PersonCommentMentionInsertForm {
|
||||
recipient_id: mention_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
|
||||
PersonCommentMention::create(&mut context.pool(), &person_comment_mention_form)
|
||||
.await
|
||||
.ok();
|
||||
Ok((
|
||||
comment.local_url(context.settings())?,
|
||||
comment.content.clone(),
|
||||
))
|
||||
} else {
|
||||
let person_post_mention_form = PersonPostMentionInsertForm {
|
||||
recipient_id: mention_user_view.person.id,
|
||||
post_id: post.id,
|
||||
read: None,
|
||||
};
|
||||
|
||||
// Allow this to fail softly, since edits might re-update or replace it
|
||||
PersonPostMention::create(&mut context.pool(), &person_post_mention_form)
|
||||
.await
|
||||
.ok();
|
||||
Ok((
|
||||
post.local_url(context.settings())?,
|
||||
post.body.clone().unwrap_or_default(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn check_notifications_allowed(
|
||||
potential_blocker_id: PersonId,
|
||||
community_instance_id: InstanceId,
|
||||
post: &Post,
|
||||
context: &LemmyContext,
|
||||
) -> LemmyResult<()> {
|
||||
let pool = &mut context.pool();
|
||||
PersonActions::read_block(pool, potential_blocker_id, post.creator_id).await?;
|
||||
InstanceActions::read_block(pool, potential_blocker_id, community_instance_id).await?;
|
||||
CommunityActions::read_block(pool, potential_blocker_id, post.community_id).await?;
|
||||
let post_notifications = PostActions::read(pool, post.id, potential_blocker_id)
|
||||
.await
|
||||
.ok()
|
||||
.and_then(|a| a.notifications)
|
||||
.unwrap_or_default();
|
||||
if post_notifications == PostNotifications::Mute {
|
||||
// The specific error type is irrelevant
|
||||
return Err(LemmyErrorType::NotFound.into());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
Ok(recipient_ids)
|
||||
}
|
||||
|
|
|
@ -24,13 +24,13 @@ use lemmy_db_schema::{
|
|||
ModRemovePostForm,
|
||||
},
|
||||
oauth_account::OAuthAccount,
|
||||
person::{Person, PersonUpdateForm},
|
||||
person::{Person, PersonActions, PersonUpdateForm},
|
||||
post::{Post, PostActions, PostReadCommentsForm},
|
||||
private_message::PrivateMessage,
|
||||
registration_application::RegistrationApplication,
|
||||
site::Site,
|
||||
},
|
||||
traits::{Crud, Likeable, ReadComments},
|
||||
traits::{Blockable, Crud, Likeable, ReadComments},
|
||||
utils::DbPool,
|
||||
};
|
||||
use lemmy_db_schema_file::enums::{FederationMode, RegistrationMode};
|
||||
|
@ -321,6 +321,19 @@ pub fn check_comment_deleted_or_removed(comment: &Comment) -> LemmyResult<()> {
|
|||
}
|
||||
}
|
||||
|
||||
pub async fn check_person_instance_community_block(
|
||||
my_id: PersonId,
|
||||
potential_blocker_id: PersonId,
|
||||
community_instance_id: InstanceId,
|
||||
community_id: CommunityId,
|
||||
pool: &mut DbPool<'_>,
|
||||
) -> LemmyResult<()> {
|
||||
PersonActions::read_block(pool, potential_blocker_id, my_id).await?;
|
||||
InstanceActions::read_block(pool, potential_blocker_id, community_instance_id).await?;
|
||||
CommunityActions::read_block(pool, potential_blocker_id, community_id).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn check_local_vote_mode(
|
||||
score: i16,
|
||||
post_or_comment_id: PostOrCommentId,
|
||||
|
|
|
@ -27,7 +27,7 @@ use lemmy_apub_objects::{
|
|||
},
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
newtypes::PersonId,
|
||||
newtypes::{PersonId, PostOrCommentId},
|
||||
source::{
|
||||
activity::ActivitySendTargets,
|
||||
comment::{Comment, CommentActions, CommentLikeForm},
|
||||
|
@ -38,7 +38,10 @@ use lemmy_db_schema::{
|
|||
traits::{Crud, Likeable},
|
||||
};
|
||||
use lemmy_db_views_site::SiteView;
|
||||
use lemmy_utils::error::{LemmyError, LemmyResult};
|
||||
use lemmy_utils::{
|
||||
error::{LemmyError, LemmyResult},
|
||||
utils::mention::scrape_text_for_mentions,
|
||||
};
|
||||
use serde_json::{from_value, to_value};
|
||||
use url::Url;
|
||||
|
||||
|
@ -134,12 +137,12 @@ impl ActivityHandler for CreateOrUpdateNote {
|
|||
// Need to do this check here instead of Note::from_json because we need the person who
|
||||
// send the activity, not the comment author.
|
||||
let existing_comment = self.object.id.dereference_local(context).await.ok();
|
||||
let (post, _) = self.object.get_parents(context).await?;
|
||||
if let (Some(distinguished), Some(existing_comment)) =
|
||||
(self.object.distinguished, existing_comment)
|
||||
{
|
||||
if distinguished != existing_comment.distinguished {
|
||||
let creator = self.actor.dereference(context).await?;
|
||||
let (post, _) = self.object.get_parents(context).await?;
|
||||
check_is_mod_or_admin(
|
||||
&mut context.pool(),
|
||||
creator.id,
|
||||
|
@ -169,14 +172,17 @@ impl ActivityHandler for CreateOrUpdateNote {
|
|||
// anyway.
|
||||
// TODO: for compatibility with other projects, it would be much better to read this from cc or
|
||||
// tags
|
||||
let community = Community::read(&mut context.pool(), post.community_id).await?;
|
||||
let mentions = scrape_text_for_mentions(&comment.content);
|
||||
// TODO: this fails in local community comment as CommentView::read() returns nothing
|
||||
// without passing LocalUser
|
||||
send_local_notifs(
|
||||
&post.0,
|
||||
Some(&comment.0),
|
||||
mentions,
|
||||
PostOrCommentId::Comment(comment.id),
|
||||
&actor,
|
||||
&community,
|
||||
do_send_email,
|
||||
context,
|
||||
None,
|
||||
local_instance_id,
|
||||
)
|
||||
.await?;
|
||||
Ok(())
|
||||
|
|
|
@ -21,7 +21,7 @@ use lemmy_apub_objects::{
|
|||
},
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
newtypes::PersonId,
|
||||
newtypes::{PersonId, PostOrCommentId},
|
||||
source::{
|
||||
activity::ActivitySendTargets,
|
||||
community::Community,
|
||||
|
@ -31,7 +31,10 @@ use lemmy_db_schema::{
|
|||
traits::{Crud, Likeable},
|
||||
};
|
||||
use lemmy_db_views_site::SiteView;
|
||||
use lemmy_utils::error::{LemmyError, LemmyResult};
|
||||
use lemmy_utils::{
|
||||
error::{LemmyError, LemmyResult},
|
||||
utils::mention::scrape_text_for_mentions,
|
||||
};
|
||||
use url::Url;
|
||||
|
||||
impl CreateOrUpdatePage {
|
||||
|
@ -107,6 +110,7 @@ impl ActivityHandler for CreateOrUpdatePage {
|
|||
|
||||
async fn receive(self, context: &Data<LemmyContext>) -> LemmyResult<()> {
|
||||
let site_view = SiteView::read_local(&mut context.pool()).await?;
|
||||
let local_instance_id = site_view.site.instance_id;
|
||||
|
||||
let post = ApubPost::from_json(self.object, context).await?;
|
||||
|
||||
|
@ -121,8 +125,18 @@ impl ActivityHandler for CreateOrUpdatePage {
|
|||
self.kind == CreateOrUpdateType::Create && !site_view.local_site.disable_email_notifications;
|
||||
let actor = self.actor.dereference(context).await?;
|
||||
|
||||
let community = Community::read(&mut context.pool(), post.community_id).await?;
|
||||
send_local_notifs(&post.0, None, &actor, &community, do_send_email, context).await?;
|
||||
// Send the post body mentions
|
||||
let mentions = scrape_text_for_mentions(&post.body.clone().unwrap_or_default());
|
||||
send_local_notifs(
|
||||
mentions,
|
||||
PostOrCommentId::Post(post.id),
|
||||
&actor,
|
||||
do_send_email,
|
||||
context,
|
||||
None,
|
||||
local_instance_id,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ use crate::{
|
|||
SITEMAP_LIMIT,
|
||||
},
|
||||
};
|
||||
use ::url::Url;
|
||||
use chrono::{DateTime, Utc};
|
||||
use diesel::{
|
||||
dsl::{count, insert_into, not, update},
|
||||
|
@ -38,15 +39,11 @@ use diesel::{
|
|||
QueryDsl,
|
||||
};
|
||||
use diesel_async::RunQueryDsl;
|
||||
use lemmy_db_schema_file::{
|
||||
enums::PostNotifications,
|
||||
schema::{community, person, post, post_actions},
|
||||
};
|
||||
use lemmy_db_schema_file::schema::{community, person, post, post_actions};
|
||||
use lemmy_utils::{
|
||||
error::{LemmyErrorExt, LemmyErrorExt2, LemmyErrorType, LemmyResult},
|
||||
settings::structs::Settings,
|
||||
};
|
||||
use url::Url;
|
||||
|
||||
impl Crud for Post {
|
||||
type InsertForm = PostInsertForm;
|
||||
|
@ -542,7 +539,9 @@ impl PostActions {
|
|||
.map(|post_id| (PostReadForm::new(*post_id, person_id)))
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
}
|
||||
|
||||
impl PostActions {
|
||||
pub async fn read(
|
||||
pool: &mut DbPool<'_>,
|
||||
post_id: PostId,
|
||||
|
@ -568,29 +567,6 @@ impl PostActions {
|
|||
.ok_or(LemmyErrorType::CouldntParsePaginationToken)?;
|
||||
Self::read(pool, PostId(*post_id), PersonId(*person_id)).await
|
||||
}
|
||||
|
||||
pub async fn update_notification_state(
|
||||
post_id: PostId,
|
||||
person_id: PersonId,
|
||||
new_state: PostNotifications,
|
||||
pool: &mut DbPool<'_>,
|
||||
) -> LemmyResult<PostActions> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
let form = (
|
||||
post_actions::person_id.eq(person_id),
|
||||
post_actions::post_id.eq(post_id),
|
||||
post_actions::notifications.eq(new_state),
|
||||
);
|
||||
|
||||
insert_into(post_actions::table)
|
||||
.values(form.clone())
|
||||
.on_conflict((post_actions::person_id, post_actions::post_id))
|
||||
.do_update()
|
||||
.set(form)
|
||||
.get_result::<Self>(conn)
|
||||
.await
|
||||
.with_lemmy_type(LemmyErrorType::NotFound)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use crate::newtypes::{CommunityId, DbUrl, LanguageId, PersonId, PostId};
|
||||
use chrono::{DateTime, Utc};
|
||||
use lemmy_db_schema_file::enums::PostNotifications;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::skip_serializing_none;
|
||||
#[cfg(feature = "full")]
|
||||
|
@ -202,7 +201,6 @@ pub struct PostActions {
|
|||
pub like_score: Option<i16>,
|
||||
/// When the post was hidden.
|
||||
pub hidden_at: Option<DateTime<Utc>>,
|
||||
pub notifications: Option<PostNotifications>,
|
||||
}
|
||||
|
||||
#[derive(Clone, derive_new::new)]
|
||||
|
|
|
@ -226,22 +226,3 @@ pub enum VoteShow {
|
|||
ShowForOthers,
|
||||
Hide,
|
||||
}
|
||||
|
||||
#[derive(
|
||||
EnumString, Display, Debug, Serialize, Deserialize, Default, Clone, Copy, PartialEq, Eq, Hash,
|
||||
)]
|
||||
#[cfg_attr(feature = "full", derive(DbEnum))]
|
||||
#[cfg_attr(
|
||||
feature = "full",
|
||||
ExistingTypePath = "crate::schema::sql_types::PostNotificationsModeEnum"
|
||||
)]
|
||||
#[cfg_attr(feature = "full", DbValueStyle = "verbatim")]
|
||||
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
|
||||
#[cfg_attr(feature = "ts-rs", ts(export))]
|
||||
/// Lets you show votes for others only, show all votes, or hide all votes.
|
||||
pub enum PostNotifications {
|
||||
#[default]
|
||||
RepliesAndMentions,
|
||||
AllComments,
|
||||
Mute,
|
||||
}
|
||||
|
|
|
@ -33,10 +33,6 @@ pub mod sql_types {
|
|||
#[diesel(postgres_type(name = "post_listing_mode_enum"))]
|
||||
pub struct PostListingModeEnum;
|
||||
|
||||
#[derive(diesel::query_builder::QueryId, diesel::sql_types::SqlType)]
|
||||
#[diesel(postgres_type(name = "post_notifications_mode_enum"))]
|
||||
pub struct PostNotificationsModeEnum;
|
||||
|
||||
#[derive(diesel::query_builder::QueryId, diesel::sql_types::SqlType)]
|
||||
#[diesel(postgres_type(name = "post_sort_type_enum"))]
|
||||
pub struct PostSortTypeEnum;
|
||||
|
@ -938,9 +934,6 @@ diesel::table! {
|
|||
}
|
||||
|
||||
diesel::table! {
|
||||
use diesel::sql_types::*;
|
||||
use super::sql_types::PostNotificationsModeEnum;
|
||||
|
||||
post_actions (person_id, post_id) {
|
||||
post_id -> Int4,
|
||||
person_id -> Int4,
|
||||
|
@ -951,7 +944,6 @@ diesel::table! {
|
|||
liked_at -> Nullable<Timestamptz>,
|
||||
like_score -> Nullable<Int2>,
|
||||
hidden_at -> Nullable<Timestamptz>,
|
||||
notifications -> Nullable<PostNotificationsModeEnum>,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
use crate::{CommentSlimView, CommentView};
|
||||
use lemmy_db_schema::newtypes::{CommentId, CommunityId, LanguageId, PaginationCursor, PostId};
|
||||
use lemmy_db_schema::newtypes::{
|
||||
CommentId,
|
||||
CommunityId,
|
||||
LanguageId,
|
||||
LocalUserId,
|
||||
PaginationCursor,
|
||||
PostId,
|
||||
};
|
||||
use lemmy_db_schema_file::enums::{CommentSortType, ListingType};
|
||||
use lemmy_db_views_vote::VoteView;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -12,6 +19,7 @@ use serde_with::skip_serializing_none;
|
|||
/// A comment response.
|
||||
pub struct CommentResponse {
|
||||
pub comment_view: CommentView,
|
||||
pub recipient_ids: Vec<LocalUserId>,
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
|
|
|
@ -12,7 +12,7 @@ use lemmy_db_schema::{
|
|||
},
|
||||
PostFeatureType,
|
||||
};
|
||||
use lemmy_db_schema_file::enums::{ListingType, PostNotifications, PostSortType};
|
||||
use lemmy_db_schema_file::enums::{ListingType, PostSortType};
|
||||
use lemmy_db_views_community::CommunityView;
|
||||
use lemmy_db_views_vote::VoteView;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -93,15 +93,6 @@ pub struct FeaturePost {
|
|||
pub feature_type: PostFeatureType,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, Copy, Default, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
|
||||
#[cfg_attr(feature = "ts-rs", ts(optional_fields, export))]
|
||||
/// Disable reply notifications for a post and all comments inside it
|
||||
pub struct UpdatePostNotifications {
|
||||
pub post_id: PostId,
|
||||
pub new_state: PostNotifications,
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
|
||||
|
|
|
@ -30,42 +30,57 @@ pub async fn send_mention_email(
|
|||
.await
|
||||
}
|
||||
|
||||
pub async fn send_reply_email(
|
||||
pub async fn send_comment_reply_email(
|
||||
parent_user_view: &LocalUserView,
|
||||
comment: &Comment,
|
||||
person: &Person,
|
||||
parent_comment: &Option<Comment>,
|
||||
parent_comment: &Comment,
|
||||
post: &Post,
|
||||
settings: &Settings,
|
||||
) -> LemmyResult<()> {
|
||||
let inbox_link = inbox_link(settings);
|
||||
let lang = user_language(parent_user_view);
|
||||
let content = markdown_to_html(&comment.content);
|
||||
let (subject, body) = if let Some(parent_comment) = parent_comment {
|
||||
(
|
||||
lang.notification_comment_reply_subject(&person.name),
|
||||
lang.notification_comment_reply_body(
|
||||
comment.local_url(settings)?,
|
||||
&content,
|
||||
&inbox_link,
|
||||
&parent_comment.content,
|
||||
&post.name,
|
||||
&person.name,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
(
|
||||
lang.notification_post_reply_subject(&person.name),
|
||||
lang.notification_post_reply_body(
|
||||
comment.local_url(settings)?,
|
||||
&content,
|
||||
&inbox_link,
|
||||
&post.name,
|
||||
&person.name,
|
||||
),
|
||||
)
|
||||
};
|
||||
send_email_to_user(parent_user_view, &subject, &body, settings).await;
|
||||
send_email_to_user(
|
||||
parent_user_view,
|
||||
&lang.notification_comment_reply_subject(&person.name),
|
||||
&lang.notification_comment_reply_body(
|
||||
comment.local_url(settings)?,
|
||||
&content,
|
||||
&inbox_link,
|
||||
&parent_comment.content,
|
||||
&post.name,
|
||||
&person.name,
|
||||
),
|
||||
settings,
|
||||
)
|
||||
.await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn send_post_reply_email(
|
||||
parent_user_view: &LocalUserView,
|
||||
comment: &Comment,
|
||||
person: &Person,
|
||||
post: &Post,
|
||||
settings: &Settings,
|
||||
) -> LemmyResult<()> {
|
||||
let inbox_link = inbox_link(settings);
|
||||
let lang = user_language(parent_user_view);
|
||||
let content = markdown_to_html(&comment.content);
|
||||
send_email_to_user(
|
||||
parent_user_view,
|
||||
&lang.notification_post_reply_subject(&person.name),
|
||||
&lang.notification_post_reply_body(
|
||||
comment.local_url(settings)?,
|
||||
&content,
|
||||
&inbox_link,
|
||||
&post.name,
|
||||
&person.name,
|
||||
),
|
||||
settings,
|
||||
)
|
||||
.await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
ALTER TABLE post_actions
|
||||
DROP COLUMN notifications;
|
||||
|
||||
DROP TYPE post_notifications_mode_enum;
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
CREATE TYPE post_notifications_mode_enum AS enum (
|
||||
'RepliesAndMentions',
|
||||
'AllComments',
|
||||
'Mute'
|
||||
);
|
||||
|
||||
ALTER TABLE post_actions
|
||||
ADD COLUMN notifications post_notifications_mode_enum;
|
||||
|
|
@ -67,7 +67,6 @@ use lemmy_api::{
|
|||
mark_many_read::mark_posts_as_read,
|
||||
mark_read::mark_post_as_read,
|
||||
save::save_post,
|
||||
update_notifications::update_post_notifications,
|
||||
},
|
||||
private_message::mark_read::mark_pm_as_read,
|
||||
reports::{
|
||||
|
@ -295,11 +294,7 @@ pub fn config(cfg: &mut ServiceConfig, rate_limit: &RateLimit) {
|
|||
.route("/like/list", get().to(list_post_likes))
|
||||
.route("/save", put().to(save_post))
|
||||
.route("/report", post().to(create_post_report))
|
||||
.route("/report/resolve", put().to(resolve_post_report))
|
||||
.route(
|
||||
"/disable_notifications",
|
||||
post().to(update_post_notifications),
|
||||
),
|
||||
.route("/report/resolve", put().to(resolve_post_report)),
|
||||
)
|
||||
// Comment
|
||||
.service(
|
||||
|
|
Loading…
Reference in a new issue