diff options
author | Colin Reeder <colin@vpzom.click> | 2020-07-07 23:55:43 -0600 |
---|---|---|
committer | Colin Reeder <colin@vpzom.click> | 2020-07-07 23:55:43 -0600 |
commit | ad306994f663550731f0c6a519f645b0d22cbc0a (patch) | |
tree | 4de1bd0a9e573702d00a08c2868ab41c10257774 | |
parent | e993e8615558507c49ee239cf5b60704ff77e1b5 (diff) |
Disable action buttons when already performed (#47)
-rw-r--r-- | src/components/mod.rs | 15 | ||||
-rw-r--r-- | src/resp_types.rs | 18 | ||||
-rw-r--r-- | src/routes/communities.rs | 22 | ||||
-rw-r--r-- | src/routes/posts.rs | 14 |
4 files changed, 57 insertions, 12 deletions
diff --git a/src/components/mod.rs b/src/components/mod.rs index 18f227c..2ffd97c 100644 --- a/src/components/mod.rs +++ b/src/components/mod.rs @@ -21,7 +21,7 @@ pub fn Comment<'comment, 'base_data>( Some(render::rsx! { <> <form method={"POST"} action={format!("/comments/{}/like", comment.id)} style={"display: inline"}> - <button r#type={"submit"}>{"Like"}</button> + <BoolSubmitButton value={comment.your_vote.is_some()} do_text={"Like"} done_text={"Liked"} /> </form> <a href={format!("/comments/{}", comment.id)}>{"reply"}</a> </> @@ -272,3 +272,16 @@ pub fn MaybeFillTextArea<'a>(values: &'a Option<&'a serde_json::Value>, name: &' </textarea> } } + +#[render::component] +pub fn BoolSubmitButton<'a>(value: bool, do_text: &'a str, done_text: &'a str) { + if value { + render::rsx! { + <button disabled={""}>{done_text}</button> + } + } else { + render::rsx! { + <button type={"submit"}>{do_text}</button> + } + } +} diff --git a/src/resp_types.rs b/src/resp_types.rs index e8858d5..d81c6ef 100644 --- a/src/resp_types.rs +++ b/src/resp_types.rs @@ -31,6 +31,7 @@ pub struct RespPostCommentInfo<'a> { pub created: Cow<'a, str>, pub content_text: Option<Cow<'a, str>>, pub content_html: Option<Cow<'a, str>>, + pub your_vote: Option<Empty>, #[serde(borrow)] pub replies: Option<Vec<RespPostCommentInfo<'a>>>, } @@ -42,6 +43,7 @@ pub struct RespPostInfo<'a> { pub score: i64, #[serde(borrow)] pub comments: Vec<RespPostCommentInfo<'a>>, + pub your_vote: Option<Empty>, } impl<'a> AsRef<RespPostListPost<'a>> for RespPostInfo<'a> { @@ -67,3 +69,19 @@ pub struct RespLoginInfoUser { pub struct RespLoginInfo { pub user: RespLoginInfoUser, } + +#[derive(Deserialize, Debug)] +pub struct Empty {} + +#[derive(Deserialize)] +pub struct RespCommunityInfoMaybeYour<'a> { + #[serde(flatten)] + pub base: RespMinimalCommunityInfo<'a>, + pub your_follow: Option<Empty>, +} + +impl<'a> AsRef<RespMinimalCommunityInfo<'a>> for RespCommunityInfoMaybeYour<'a> { + fn as_ref(&self) -> &RespMinimalCommunityInfo<'a> { + &self.base + } +} diff --git a/src/routes/communities.rs b/src/routes/communities.rs index c407677..ce289cc 100644 --- a/src/routes/communities.rs +++ b/src/routes/communities.rs @@ -1,5 +1,5 @@ -use crate::components::{CommunityLink, HTPage, PostItem}; -use crate::resp_types::{RespMinimalCommunityInfo, RespPostListPost}; +use crate::components::{BoolSubmitButton, CommunityLink, HTPage, PostItem}; +use crate::resp_types::{RespCommunityInfoMaybeYour, RespMinimalCommunityInfo, RespPostListPost}; use crate::routes::{ fetch_base_data, get_cookie_map, get_cookie_map_for_req, html_response, res_to_error, with_auth, }; @@ -95,8 +95,14 @@ async fn page_community( ctx.http_client .request(with_auth( hyper::Request::get(format!( - "{}/api/unstable/communities/{}", - ctx.backend_host, community_id + "{}/api/unstable/communities/{}{}", + ctx.backend_host, + community_id, + if base_data.login.is_some() { + "?include_your=true" + } else { + "" + }, )) .body(Default::default())?, &cookies, @@ -106,7 +112,7 @@ async fn page_community( .await?; let community_info_api_res = hyper::body::to_bytes(community_info_api_res.into_body()).await?; - let community_info: RespMinimalCommunityInfo = + let community_info: RespCommunityInfoMaybeYour = { serde_json::from_slice(&community_info_api_res)? }; let posts_api_res = res_to_error( @@ -129,14 +135,16 @@ async fn page_community( let follow_url = format!("/communities/{}/follow", community_id); let new_post_url = format!("/communities/{}/new_post", community_id); - let title = community_info.name.as_ref(); + let title = community_info.as_ref().name.as_ref(); + + let following = community_info.your_follow.is_some(); Ok(html_response(render::html! { <HTPage base_data={&base_data} title> <h1>{title}</h1> <p> <form method={"POST"} action={&follow_url}> - <button r#type={"submit"}>{"Follow"}</button> + <BoolSubmitButton value={following} do_text={"Follow"} done_text={"Following"} /> </form> </p> <p> diff --git a/src/routes/posts.rs b/src/routes/posts.rs index 25d7089..0a41490 100644 --- a/src/routes/posts.rs +++ b/src/routes/posts.rs @@ -2,7 +2,7 @@ use super::{ fetch_base_data, get_cookie_map_for_headers, get_cookie_map_for_req, html_response, res_to_error, with_auth, }; -use crate::components::{Comment, CommunityLink, Content, HTPage, UserLink}; +use crate::components::{BoolSubmitButton, Comment, CommunityLink, Content, HTPage, UserLink}; use crate::resp_types::RespPostInfo; use crate::util::author_is_me; use std::sync::Arc; @@ -22,8 +22,14 @@ async fn page_post( ctx.http_client .request(with_auth( hyper::Request::get(format!( - "{}/api/unstable/posts/{}", - ctx.backend_host, post_id + "{}/api/unstable/posts/{}{}", + ctx.backend_host, + post_id, + if base_data.login.is_some() { + "?include_your=true" + } else { + "" + }, )) .body(Default::default())?, &cookies, @@ -47,7 +53,7 @@ async fn page_post( if base_data.login.is_some() { Some(render::rsx! { <form method={"POST"} action={format!("/posts/{}/like", post_id)}> - <button r#type={"submit"}>{"Like"}</button> + <BoolSubmitButton value={post.your_vote.is_some()} do_text={"Like"} done_text={"Liked"} /> </form> }) } else { |