summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorColin Reeder <colin@vpzom.click>2020-09-16 19:02:25 -0600
committerColin Reeder <colin@vpzom.click>2020-09-16 19:02:25 -0600
commit5a0cd2b9310417536603ad8f051d9fa8b3e65e69 (patch)
tree7e3270fc41f8cfef7085111be6f742630005673d
parent464ab3c600345227176a598c10181f7b142aa197 (diff)
Add UI for adding community moderators
-rw-r--r--res/lang/en.ftl4
-rw-r--r--src/routes/communities.rs149
2 files changed, 151 insertions, 2 deletions
diff --git a/res/lang/en.ftl b/res/lang/en.ftl
index 95a8d36..da13d7f 100644
--- a/res/lang/en.ftl
+++ b/res/lang/en.ftl
@@ -5,6 +5,7 @@ about_text1 = lotide is an attempt to build a federated forum. Users can create
about_text2 = For more information or to view the source code, check out the
about_sourcehut = SourceHut page
about_versions = This instance is running hitide { $hitide_version } on { $backend_name } { $backend_version }.
+add = Add
add_by_remote_id = Add by ID:
all = All
all_title = The Whole Known Network
@@ -15,6 +16,7 @@ comment_delete_title = Delete Comment
comment_delete_question = Delete this comment?
comment_submit = Post Comment
communities = Communities
+community_add_moderator = Add Moderator
community_create = Create Community
community_create_submit = Create
community_edit = Customize Community
@@ -37,6 +39,7 @@ login = Login
login_signup_link = create a new account
lookup_nothing = Nothing found.
lookup_title = Lookup
+moderators = Moderators
name_prompt = Name:
no_cancel = No, cancel
nothing = Looks like there's nothing here.
@@ -116,6 +119,7 @@ user_edit_description_prompt = Profile Description:
user_edit_not_you = You can only edit your own profile.
user_edit_submit = Save
user_edit_title = Edit Profile
+user_id_prompt = User ID:
user_remote_note = This is a remote user, information on this page may be incomplete.
username_prompt = Username:
view_at_source = View at Source
diff --git a/src/routes/communities.rs b/src/routes/communities.rs
index fc2bb07..fc2bb8d 100644
--- a/src/routes/communities.rs
+++ b/src/routes/communities.rs
@@ -1,7 +1,7 @@
use crate::components::{CommunityLink, HTPage, MaybeFillInput, MaybeFillTextArea, PostItem};
use crate::resp_types::{
- JustContentHTML, RespCommunityInfoMaybeYour, RespMinimalCommunityInfo, RespPostListPost,
- RespYourFollow,
+ JustContentHTML, RespCommunityInfoMaybeYour, RespMinimalAuthorInfo, RespMinimalCommunityInfo,
+ RespPostListPost, RespYourFollow,
};
use crate::routes::{
fetch_base_data, for_client, get_cookie_map_for_headers, get_cookie_map_for_req, html_response,
@@ -229,6 +229,7 @@ async fn page_community(
}
}
<p>{community_info.description.as_ref()}</p>
+ <p><a href={format!("/communities/{}/moderators", community_id)}>{lang.tr("moderators", None)}</a></p>
</div>
<div class={"sortOptions"}>
<span>{lang.tr("sort", None)}</span>
@@ -415,6 +416,140 @@ async fn handler_community_follow(
.body("Successfully followed".into())?)
}
+async fn page_community_moderators(
+ params: (i64,),
+ ctx: Arc<crate::RouteContext>,
+ req: hyper::Request<hyper::Body>,
+) -> Result<hyper::Response<hyper::Body>, crate::Error> {
+ let (community_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 community_info_api_res = res_to_error(
+ ctx.http_client
+ .request(for_client(
+ hyper::Request::get(format!(
+ "{}/api/unstable/communities/{}{}",
+ ctx.backend_host,
+ community_id,
+ if base_data.login.is_some() {
+ "?include_your=true"
+ } else {
+ ""
+ },
+ ))
+ .body(Default::default())?,
+ req.headers(),
+ &cookies,
+ )?)
+ .await?,
+ )
+ .await?;
+ let community_info_api_res = hyper::body::to_bytes(community_info_api_res.into_body()).await?;
+ let community_info: RespCommunityInfoMaybeYour =
+ { serde_json::from_slice(&community_info_api_res)? };
+
+ let api_res = res_to_error(
+ ctx.http_client
+ .request(for_client(
+ hyper::Request::get(format!(
+ "{}/api/unstable/communities/{}/moderators",
+ ctx.backend_host, community_id,
+ ))
+ .body(Default::default())?,
+ req.headers(),
+ &cookies,
+ )?)
+ .await?,
+ )
+ .await?;
+ let api_res = hyper::body::to_bytes(api_res.into_body()).await?;
+ let api_res: Vec<RespMinimalAuthorInfo> = serde_json::from_slice(&api_res)?;
+
+ let title = lang.tr("moderators", None);
+
+ Ok(html_response(render::html! {
+ <HTPage base_data={&base_data} lang={&lang} title={&title}>
+ <h1>{title.as_ref()}</h1>
+ <ul>
+ {
+ api_res.iter().map(|user| {
+ render::rsx! {
+ <li><a href={format!("/users/{}", user.id)}>{user.username.as_ref()}</a></li>
+ }
+ })
+ .collect::<Vec<_>>()
+ }
+ </ul>
+ {
+ if community_info.you_are_moderator == Some(true) {
+ Some(render::rsx! {
+ <div>
+ <h2>{lang.tr("community_add_moderator", None)}</h2>
+ <form method={"POST"} action={format!("/communities/{}/moderators/add", community_id)}>
+ <label>
+ {lang.tr("user_id_prompt", None)}{" "}
+ <input type={"number"} name={"user"} />
+ </label>
+ {" "}
+ <button type={"submit"}>{lang.tr("add", None)}</button>
+ </form>
+ </div>
+ })
+ } else {
+ None
+ }
+ }
+ </HTPage>
+ }))
+}
+
+async fn handler_community_moderators_add(
+ params: (i64,),
+ ctx: Arc<crate::RouteContext>,
+ req: hyper::Request<hyper::Body>,
+) -> Result<hyper::Response<hyper::Body>, crate::Error> {
+ let (community_id,) = params;
+
+ let (req_parts, body) = req.into_parts();
+
+ let cookies = get_cookie_map_for_headers(&req_parts.headers)?;
+
+ #[derive(Deserialize)]
+ struct ModeratorsAddParams {
+ user: i64,
+ }
+
+ let body = hyper::body::to_bytes(body).await?;
+ let body: ModeratorsAddParams = serde_urlencoded::from_bytes(&body)?;
+
+ res_to_error(
+ ctx.http_client
+ .request(for_client(
+ hyper::Request::put(format!(
+ "{}/api/unstable/communities/{}/moderators/{}",
+ ctx.backend_host, community_id, body.user,
+ ))
+ .body(Default::default())?,
+ &req_parts.headers,
+ &cookies,
+ )?)
+ .await?,
+ )
+ .await?;
+
+ Ok(hyper::Response::builder()
+ .status(hyper::StatusCode::SEE_OTHER)
+ .header(
+ hyper::header::LOCATION,
+ format!("/communities/{}/moderators", community_id),
+ )
+ .body("Successfully added.".into())?)
+}
+
async fn handler_community_post_approve(
params: (i64, i64),
ctx: Arc<crate::RouteContext>,
@@ -726,6 +861,16 @@ pub fn route_communities() -> crate::RouteNode<()> {
crate::RouteNode::new().with_handler_async("POST", handler_community_follow),
)
.with_child(
+ "moderators",
+ crate::RouteNode::new()
+ .with_handler_async("GET", page_community_moderators)
+ .with_child(
+ "add",
+ crate::RouteNode::new()
+ .with_handler_async("POST", handler_community_moderators_add),
+ ),
+ )
+ .with_child(
"posts",
crate::RouteNode::new().with_child_parse::<i64, _>(
crate::RouteNode::new()