~vpzom/hitide

ad306994f663550731f0c6a519f645b0d22cbc0a — Colin Reeder 1 year, 2 months ago e993e86
Disable action buttons when already performed (#47)
4 files changed, 57 insertions(+), 12 deletions(-)

M src/components/mod.rs
M src/resp_types.rs
M src/routes/communities.rs
M src/routes/posts.rs
M src/components/mod.rs => src/components/mod.rs +14 -1
@@ 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>
        }
    }
}

M src/resp_types.rs => src/resp_types.rs +18 -0
@@ 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
    }
}

M src/routes/communities.rs => src/routes/communities.rs +15 -7
@@ 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>

M src/routes/posts.rs => src/routes/posts.rs +10 -4
@@ 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 {