diff --git a/assets/styles/lemmybb.css b/assets/styles/lemmybb.css index 4fd2805..8be28bc 100644 --- a/assets/styles/lemmybb.css +++ b/assets/styles/lemmybb.css @@ -54,3 +54,17 @@ a.lastsubject { color: #ff0000; font-weight: bold; } + +#mod_log { + width: 95%; + margin: 0 auto; +} + +#mod_log th, +td { + border-bottom: 1px solid; +} + +#mod_log p { + margin-bottom: 0.5em; +} diff --git a/lemmybb-translations b/lemmybb-translations index bd9d6dc..daa75ff 160000 --- a/lemmybb-translations +++ b/lemmybb-translations @@ -1 +1 @@ -Subproject commit bd9d6dc307cabc564ab458a30b8058a8549699ce +Subproject commit daa75ffc99685aea57bfaf68005c0ed26fe410c7 diff --git a/src/api/moderation.rs b/src/api/moderation.rs index 66981be..1a7f389 100644 --- a/src/api/moderation.rs +++ b/src/api/moderation.rs @@ -1,10 +1,11 @@ -use crate::api::post; +use crate::api::{get, post}; use anyhow::Error; use lemmy_api_common::{ comment::{CommentResponse, RemoveComment}, lemmy_db_schema::newtypes::{CommentId, PostId}, post::{PostResponse, RemovePost}, sensitive::Sensitive, + site::{GetModlog, GetModlogResponse}, }; pub async fn remove_post( @@ -34,3 +35,11 @@ pub async fn remove_comment( }; post("/comment/remove", ¶ms).await } + +pub async fn get_mod_log(auth: Option>) -> Result { + let params = GetModlog { + auth, + ..Default::default() + }; + get("/modlog", ¶ms).await +} diff --git a/src/main.rs b/src/main.rs index 55a5c2a..692119a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -136,7 +136,8 @@ fn init_rocket() -> Result, Error> { node_info, api_site, remove_item, - do_remove_item + do_remove_item, + mod_log ], ) .mount("/assets", FileServer::from(relative!("assets")))) diff --git a/src/routes/moderation.rs b/src/routes/moderation.rs index 05295de..9287469 100644 --- a/src/routes/moderation.rs +++ b/src/routes/moderation.rs @@ -1,17 +1,22 @@ use crate::{ api::{ comment::get_comment, - moderation::{remove_comment, remove_post}, + moderation::{get_mod_log, remove_comment, remove_post}, post::get_post, }, error::ErrorPage, site_fairing::SiteData, + template_helpers::i18n_, utils::Context, }; use anyhow::anyhow; - +use chrono::NaiveDateTime; +use comrak::{markdown_to_html, ComrakOptions}; +use itertools::Itertools; +use lemmy_api_common::lemmy_db_schema::source::community::CommunitySafe; use rocket::{form::Form, response::Redirect, Either}; use rocket_dyn_templates::{context, Template}; +use serde::Serialize; #[get("/remove_item?&")] pub async fn remove_item( @@ -83,3 +88,77 @@ pub async fn do_remove_item<'r>( .build(); Ok(Either::Left(Template::render("message", ctx))) } + +#[get("/mod_log")] +pub async fn mod_log(site_data: SiteData) -> Result { + let mod_log = get_mod_log(site_data.auth.clone()).await?; + // TODO: consider moving this upstream + let entries: Vec> = vec![ + mod_log + .removed_posts + .into_iter() + .map(|m| { + // TODO: why is removed an option?? + let action = if m.mod_remove_post.removed.unwrap() { + "Removed" + } else { + "Restored" + }; + let message = format!("{action} post [{}]({})", m.post.name, m.post.ap_id); + ModLogEntry { + community: Some(m.community), + reason: m.mod_remove_post.reason, + when: m.mod_remove_post.when_, + message, + } + }) + .collect(), + mod_log + .removed_comments + .into_iter() + .map(|m| { + let action = if m.mod_remove_comment.removed.unwrap() { + "Removed" + } else { + "Restored" + }; + let mut content = m.comment.content.replace('\n', " "); + if content.chars().count() > 100 { + content = format!("{}...", content.chars().take(100).collect::()); + } + let message = format!("{action} comment [{}]({})", content, m.comment.ap_id); + ModLogEntry { + community: Some(m.community), + reason: m.mod_remove_comment.reason, + when: m.mod_remove_comment.when_, + message, + } + }) + .collect(), + ]; + let entries: Vec<_> = entries + .into_iter() + .flatten() + .map(|mut e| { + e.message = markdown_to_html(&e.message, &ComrakOptions::default()); + e + }) + .sorted_by_key(|e| e.when) + .rev() + .collect(); + + let ctx = Context::builder() + .title(i18n_(&site_data, "mod_log_title")) + .site_data(site_data) + .other(context! { entries }) + .build(); + Ok(Template::render("site/mod_log", ctx)) +} + +#[derive(Debug, Serialize)] +pub struct ModLogEntry { + community: Option, + reason: Option, + when: NaiveDateTime, + message: String, +} diff --git a/templates/components/header.html.hbs b/templates/components/header.html.hbs index 81c9ec0..88a7a9c 100644 --- a/templates/components/header.html.hbs +++ b/templates/components/header.html.hbs @@ -59,6 +59,12 @@