From 0acff8a58837366beae38f9ddfe1c65db86926a0 Mon Sep 17 00:00:00 2001 From: Colin Reeder Date: Sun, 17 Mar 2024 10:11:05 -0600 Subject: [PATCH] Add UI for site-blocking posts --- Cargo.lock | 5 +- Cargo.toml | 1 + res/lang/en.ftl | 5 ++ src/routes/posts.rs | 125 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 134 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index be75543..1421965 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -489,6 +489,7 @@ dependencies = [ "lazy_static", "log", "multer", + "percent-encoding", "render", "serde", "serde_derive", @@ -906,9 +907,9 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "phf" diff --git a/Cargo.toml b/Cargo.toml index d5c94dc..b1bea60 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,6 +37,7 @@ env_logger = "0.8" config = { version = "0.11.0", default-features = false, features = ["ini"] } url = { version = "2.2.2", features = ["serde"] } intl-memoizer = "0.5.1" +percent-encoding = "2.3.1" [build-dependencies] fluent-syntax = "0.11.0" diff --git a/res/lang/en.ftl b/res/lang/en.ftl index 0d8d775..a58b746 100644 --- a/res/lang/en.ftl +++ b/res/lang/en.ftl @@ -153,6 +153,9 @@ post_new_missing_content_type = Missing Content-Type for image upload post_new_image_prompt = Image: post_not_approved = This post has not been approved by the community. post_rejected = This post has been rejected by the community. +post_site_block_title = Block Post from Site +post_site_block_question = Block this post from the site? +post_site_block_question_description = This will remove the local copy of this post and prevent it from being refetched. post_submitted = Submitted { $part_time } post_submitted_by = Submitted { $part_time } by { $part_user } post_submitted_by_to = Submitted { $part_time } by { $part_user } to { $part_community } @@ -177,6 +180,8 @@ score = { $score } { $score -> sensitive = Sensitive Content signup_email_address_prompt = Email Address (optional): signup_not_allowed = User registration is disabled on this server +site_block = block from site +site_block_yes = Yes, block sort = Sort: sort_hot = hot sort_new = new diff --git a/src/routes/posts.rs b/src/routes/posts.rs index e53ece1..fa11bdb 100644 --- a/src/routes/posts.rs +++ b/src/routes/posts.rs @@ -297,6 +297,15 @@ async fn page_post_inner( None } } + { + if !post.local && base_data.is_site_admin() { + Some(render::rsx! { + {lang.tr(&lang::SITE_BLOCK)} + }) + } else { + None + } + } { if post.local { None @@ -475,6 +484,110 @@ async fn handler_post_delete_confirm( .body("Successfully deleted.".into())?) } +async fn page_post_site_block( + params: (i64,), + ctx: Arc, + req: hyper::Request, +) -> Result, crate::Error> { + let (post_id,) = params; + + let lang = crate::get_lang_for_req(&req); + let cookies = get_cookie_map_for_req(&req)?; + + let base_data = + fetch_base_data(&ctx.backend_host, &ctx.http_client, req.headers(), &cookies).await?; + + let api_res = res_to_error( + ctx.http_client + .request(for_client( + hyper::Request::get(format!( + "{}/api/unstable/posts/{}", + ctx.backend_host, post_id + )) + .body(Default::default())?, + req.headers(), + &cookies, + )?) + .await?, + ) + .await?; + let api_res = hyper::body::to_bytes(api_res.into_body()).await?; + + let post: RespPostInfo = serde_json::from_slice(&api_res)?; + + Ok(html_response(render::html! { + +

{post.as_ref().as_ref().title.as_ref()}

+

{lang.tr(&lang::post_site_block_question())}

+

{lang.tr(&lang::post_site_block_question_description())}

+
+ {lang.tr(&lang::no_cancel())} + {" "} + +
+
+ })) +} + +async fn handler_post_site_block_confirm( + params: (i64,), + ctx: Arc, + req: hyper::Request, +) -> Result, crate::Error> { + let (post_id,) = params; + + let cookies = get_cookie_map_for_req(&req)?; + + let api_res_get = res_to_error( + ctx.http_client + .request(for_client( + hyper::Request::get(format!( + "{}/api/unstable/posts/{}", + ctx.backend_host, post_id + )) + .body(Default::default())?, + req.headers(), + &cookies, + )?) + .await?, + ) + .await?; + let api_res_get = hyper::body::to_bytes(api_res_get.into_body()).await?; + let post: RespPostInfo = serde_json::from_slice(&api_res_get)?; + + if let Some(remote_url) = &post.as_ref().as_ref().remote_url { + res_to_error( + ctx.http_client + .request(for_client( + hyper::Request::put(format!( + "{}/api/unstable/objects:blocks/{}", + ctx.backend_host, + percent_encoding::utf8_percent_encode( + &remote_url, + percent_encoding::NON_ALPHANUMERIC + ), + )) + .body("".into())?, + req.headers(), + &cookies, + )?) + .await?, + ) + .await?; + + Ok(hyper::Response::builder() + .status(hyper::StatusCode::SEE_OTHER) + .header(hyper::header::LOCATION, "/") + .body("Successfully blocked from site.".into())?) + } else { + Err(crate::Error::UserError({ + let mut res = hyper::Response::new("Not a remote post".into()); + *res.status_mut() = hyper::StatusCode::BAD_REQUEST; + res + })) + } +} + async fn page_post_flag( params: (i64,), ctx: Arc, @@ -1026,6 +1139,18 @@ pub fn route_posts() -> crate::RouteNode<()> { .with_handler_async(hyper::Method::POST, handler_post_delete_confirm), ), ) + .with_child( + "site_block", + crate::RouteNode::new() + .with_handler_async(hyper::Method::GET, page_post_site_block) + .with_child( + "confirm", + crate::RouteNode::new().with_handler_async( + hyper::Method::POST, + handler_post_site_block_confirm, + ), + ), + ) .with_child( "flag", crate::RouteNode::new() -- 2.45.2