summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorColin Reeder <colin@vpzom.click>2020-07-07 23:55:43 -0600
committerColin Reeder <colin@vpzom.click>2020-07-07 23:55:43 -0600
commitad306994f663550731f0c6a519f645b0d22cbc0a (patch)
tree4de1bd0a9e573702d00a08c2868ab41c10257774
parente993e8615558507c49ee239cf5b60704ff77e1b5 (diff)
Disable action buttons when already performed (#47)
-rw-r--r--src/components/mod.rs15
-rw-r--r--src/resp_types.rs18
-rw-r--r--src/routes/communities.rs22
-rw-r--r--src/routes/posts.rs14
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 {