Repository: LemmyNet/lemmy (language: rust)

Issue:
Full reports federation
### Requirements

- [X] Is this a feature request? For questions or discussions use https://lemmy.ml/c/lemmy_support
- [X] Did you check to see if this issue already exists?
- [X] Is this only a feature request? Do not put multiple feature requests in one issue.
- [X] Is this a backend issue? Use the [lemmy-ui](https://github.com/LemmyNet/lemmy-ui) repo for UI / frontend issues.
- [X] Do you agree to follow the rules in our [Code of Conduct](https://join-lemmy.org/docs/code_of_conduct.html)?

### Is your proposal related to a problem?

Reports are only partially federated, especially regarding remote moderators (who are on a different instance from the community). These mods wont receive all reports as they are not forwarded. Also when resolving a report, this action isnt federated to other instances.
Rename `when_` fields to `published`
Some of the modlog items have timestamps stored in fields called `when_`. This should be changed to `published` to be consistent with other tables. A simple search and replace should be enough.


Discussion / hints:
related:
- #3781
- #4436
This seems like an important issue, could it get added to a Milestone?
Up to @Nutomic I spose.


Fix patch:
diff --git a/crates/api_common/src/build_response.rs b/crates/api_common/src/build_response.rs
index 3a73b42f18..66a184284d 100644
--- a/crates/api_common/src/build_response.rs
+++ b/crates/api_common/src/build_response.rs
@@ -101,7 +101,6 @@ pub async fn send_local_notifs(
   local_user_view: Option<&LocalUserView>,
 ) -> LemmyResult<Vec<LocalUserId>> {
   let mut recipient_ids = Vec::new();
-  let inbox_link = format!("{}/inbox", context.settings().get_protocol_and_hostname());
 
   let (comment_opt, post, community) = match post_or_comment_id {
     PostOrCommentId::Post(post_id) => {
@@ -141,6 +140,16 @@ pub async fn send_local_notifs(
     }
   };
 
+  let inbox_link = format!("{}/inbox", context.settings().get_protocol_and_hostname());
+  let comment_link = |comment: &Comment| {
+    format!(
+      "{}/post/{}/{}",
+      context.settings().get_protocol_and_hostname(),
+      post.id,
+      comment.id
+    )
+  };
+
   // Send the local mentions
   for mention in mentions
     .iter()
@@ -156,7 +165,7 @@ pub async fn send_local_notifs(
       recipient_ids.push(mention_user_view.local_user.id);
 
       // Make the correct reply form depending on whether its a post or comment mention
-      let comment_content_or_post_body = if let Some(comment) = &comment_opt {
+      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,
@@ -168,7 +177,7 @@ pub async fn send_local_notifs(
         PersonCommentMention::create(&mut context.pool(), &person_comment_mention_form)
           .await
           .ok();
-        comment.content.clone()
+        (comment_link(comment), comment.content.clone())
       } else {
         let person_post_mention_form = PersonPostMentionInsertForm {
           recipient_id: mention_user_view.person.id,
@@ -180,7 +189,12 @@ pub async fn send_local_notifs(
         PersonPostMention::create(&mut context.pool(), &person_post_mention_form)
           .await
           .ok();
-        post.body.clone().unwrap_or_default()
+        let post_link = format!(
+          "{}/post/{}",
+          context.settings().get_protocol_and_hostname(),
+          post.id,
+        );
+        (post_link, post.body.clone().unwrap_or_default())
       };
 
       // Send an email to those local users that have notifications on
@@ -190,7 +204,7 @@ pub async fn send_local_notifs(
         send_email_to_user(
           &mention_user_view,
           &lang.notification_mentioned_by_subject(&person.name),
-          &lang.notification_mentioned_by_body(&content, &inbox_link, &person.name),
+          &lang.notification_mentioned_by_body(&link, &content, &inbox_link, &person.name),
           context.settings(),
         )
         .await
@@ -243,7 +257,14 @@ pub async fn send_local_notifs(
               send_email_to_user(
                 &parent_user_view,
                 &lang.notification_comment_reply_subject(&person.name),
-                &lang.notification_comment_reply_body(&content, &inbox_link, &person.name),
+                &lang.notification_comment_reply_body(
+                  comment_link(comment),
+                  &content,
+                  &inbox_link,
+                  &parent_comment.content,
+                  &post.name,
+                  &person.name,
+                ),
                 context.settings(),
               )
               .await
@@ -289,7 +310,13 @@ pub async fn send_local_notifs(
               send_email_to_user(
                 &parent_user_view,
                 &lang.notification_post_reply_subject(&person.name),
-                &lang.notification_post_reply_body(&content, &inbox_link, &person.name),
+                &lang.notification_post_reply_body(
+                  comment_link(comment),
+                  &content,
+                  &inbox_link,
+                  &post.name,
+                  &person.name,
+                ),
                 context.settings(),
               )
               .await
diff --git a/crates/utils/build.rs b/crates/utils/build.rs
index b336f8c560..f40ac456a7 100644
--- a/crates/utils/build.rs
+++ b/crates/utils/build.rs
@@ -1,11 +1,28 @@
+use std::fs::read_dir;
+
 fn main() -> Result<(), Box<dyn std::error::Error>> {
-  rosetta_build::config()
-    .source("en", "translations/email/en.json")
-    .source("fi", "translations/email/fi.json")
-    .source("ko", "translations/email/ko.json")
-    .source("pt", "translations/email/pt.json")
-    .fallback("en")
-    .generate()?;
+  let mut config = rosetta_build::config();
+
+  for path in read_dir("translations/email/")? {
+    let path = path?.path();
+    if let Some(name) = path.file_name() {
+      let lang = name.to_string_lossy().to_string().replace(".json", "");
+      // Rosetta doesnt support these language variants.
+      if lang.contains('_') {
+        continue;
+      }
+
+      let path = path.to_string_lossy();
+      rosetta_build::config()
+        .source(&lang, path.clone())
+        .fallback(&lang)
+        .generate()?;
+
+      config = config.source(lang, path);
+    }
+  }
+
+  config.fallback("en").generate()?;
 
   Ok(())
 }
diff --git a/crates/utils/translations b/crates/utils/translations
index 70a2384b59..e8a175a0a7 160000
--- a/crates/utils/translations
+++ b/crates/utils/translations
@@ -1,1 +1,1 @@
-Subproject commit 70a2384b595c17dfe2096419cd1b381f638ced9a
+Subproject commit e8a175a0a79f7bc268874e40b051cc2f036eab75


Test patch: