~vpzom/hitide

e3896eb0d47b60498ec51992bb934e28ef4b862e — Colin Reeder 10 days ago 7b7d614 + 8271286
Merge branch 'paginate-all-the-things'
3 files changed, 198 insertions(+), 71 deletions(-)

M res/lang/en.ftl
M src/routes/communities.rs
M src/routes/mod.rs
M res/lang/en.ftl => res/lang/en.ftl +4 -0
@@ 19,6 19,10 @@ comment_delete_question = Delete this comment?
comment_reply_image_prompt = Attach Image (optional):
comment_submit = Post Comment
communities = Communities
communities_all_view = See All
communities_local_more = More Local Communities
communities_remote_more = More Remote Communities
communities_page_next = View More
community_add_moderator = Add Moderator
community_create = Create Community
community_create_submit = Create

M src/routes/communities.rs => src/routes/communities.rs +181 -58
@@ 2,7 2,7 @@ use crate::components::{
    CommunityLink, Content, HTPage, HTPageAdvanced, MaybeFillInput, MaybeFillTextArea, PostItem,
};
use crate::resp_types::{
    JustContentHTML, JustStringID, RespCommunityInfoMaybeYour, RespMinimalAuthorInfo,
    JustContentHTML, JustStringID, RespCommunityInfoMaybeYour, RespList, RespMinimalAuthorInfo,
    RespMinimalCommunityInfo, RespPostListPost, RespYourFollow,
};
use crate::routes::{


@@ 24,19 24,81 @@ async fn page_communities(
    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(
                hyper::Request::get(format!("{}/api/unstable/communities", ctx.backend_host,))
                    .body(Default::default())?,
    #[derive(Deserialize)]
    struct Query<'a> {
        local: Option<bool>,
        page: Option<Cow<'a, str>>,
    }

    let query: Query = serde_urlencoded::from_str(req.uri().query().unwrap_or(""))?;

    let page_param = if let Some(page) = query.page {
        Cow::Owned(format!("&page={}", page))
    } else {
        Cow::Borrowed("")
    };

    let remote_communities_api_res = if query.local == Some(true) {
        None
    } else {
        Some(
            hyper::body::to_bytes(
                res_to_error(
                    ctx.http_client
                        .request(
                            hyper::Request::get(format!(
                                "{}/api/unstable/communities?local=false&limit=2{}",
                                ctx.backend_host, page_param
                            ))
                            .body(Default::default())?,
                        )
                        .await?,
                )
                .await?
                .into_body(),
            )
            .await?,
    )
    .await?;
    let api_res = hyper::body::to_bytes(api_res.into_body()).await?;
    let communities: Vec<RespMinimalCommunityInfo> = serde_json::from_slice(&api_res)?;

    let title = lang.tr("communities", None);
        )
    };
    let remote_communities: Option<RespList<RespMinimalCommunityInfo>> = remote_communities_api_res
        .map(|value| serde_json::from_slice(&value))
        .transpose()?;

    let local_communities_api_res = if query.local == Some(false) {
        None
    } else {
        Some(
            hyper::body::to_bytes(
                res_to_error(
                    ctx.http_client
                        .request(
                            hyper::Request::get(format!(
                                "{}/api/unstable/communities?local=true{}",
                                ctx.backend_host, page_param
                            ))
                            .body(Default::default())?,
                        )
                        .await?,
                )
                .await?
                .into_body(),
            )
            .await?,
        )
    };
    let local_communities: Option<RespList<RespMinimalCommunityInfo>> = local_communities_api_res
        .map(|value| serde_json::from_slice(&value))
        .transpose()?;

    let title = if let Some(local) = query.local {
        if local {
            lang.tr("communities_local_more", None)
        } else {
            lang.tr("communities_remote_more", None)
        }
    } else {
        lang.tr("communities", None)
    };

    Ok(html_response(render::html! {
        <HTPage


@@ 45,51 107,112 @@ async fn page_communities(
            title={&title}
        >
            <h1>{title.as_ref()}</h1>
            <div>
                <h2>{lang.tr("local", None)}</h2>
                {
                    if base_data.login.is_some() {
                        Some(render::rsx! { <a href={"/new_community"}>{lang.tr("community_create", None)}</a> })
                    } else {
                        None
                    }
            {
                if query.local.is_some() {
                    Some(render::rsx! {
                        <a href={"/communities"}>{lang.tr("communities_all_view", None)}</a>
                    })
                } else {
                    None
                }
                <ul>
                    {
                        communities.iter()
                            .filter(|x| x.local)
                            .map(|community| {
                                render::rsx! {
                                    <li><CommunityLink community={&community} /></li>
            }
            {
                if let Some(local_communities) = &local_communities {
                    Some(render::rsx! {
                        <div>
                            {
                                if query.local.is_none() {
                                    Some(render::rsx! {
                                        <h2>{lang.tr("local", None)}</h2>
                                    })
                                } else {
                                    None
                                }
                            })
                            .collect::<Vec<_>>()
                    }
                </ul>
            </div>
            <div>
                <h2>{lang.tr("remote", None)}</h2>
                <form method={"GET"} action={"/lookup"}>
                    <label>
                        {lang.tr("add_by_remote_id", None)}{" "}
                        <input r#type={"text"} name={"query"} placeholder={"group@example.com"} />
                    </label>
                    {" "}
                    <button r#type={"submit"}>{lang.tr("fetch", None)}</button>
                </form>
                <ul>
                    {
                        communities.iter()
                            .filter(|x| !x.local)
                            .map(|community| {
                                render::rsx! {
                                    <li><CommunityLink community={&community} /></li>
                            }
                            {
                                if base_data.login.is_some() {
                                    Some(render::rsx! { <a href={"/new_community"}>{lang.tr("community_create", None)}</a> })
                                } else {
                                    None
                                }
                            })
                            .collect::<Vec<_>>()
                    }
                </ul>
            </div>
                            }
                            <ul>
                                {
                                    local_communities.items.iter()
                                        .map(|community| {
                                            render::rsx! {
                                                <li><CommunityLink community={&community} /></li>
                                            }
                                        })
                                        .collect::<Vec<_>>()
                                }
                            </ul>
                            {
                                if let Some(next_page) = &local_communities.next_page {
                                    Some(render::rsx! {
                                        <a href={format!("/communities?local=true&page={}", next_page)}>
                                            {lang.tr("communities_page_next", None)}
                                        </a>
                                    })
                                } else {
                                    None
                                }
                            }
                        </div>
                    })
                } else {
                    None
                }
            }
            {
                if let Some(remote_communities) = &remote_communities {
                    Some(render::rsx! {
                        <div>
                            {
                                if query.local.is_none() {
                                    Some(render::rsx! {
                                        <h2>{lang.tr("remote", None)}</h2>
                                    })
                                } else {
                                    None
                                }
                            }
                            <form method={"GET"} action={"/lookup"}>
                                <label>
                                    {lang.tr("add_by_remote_id", None)}{" "}
                                    <input r#type={"text"} name={"query"} placeholder={"group@example.com"} />
                                </label>
                                {" "}
                                <button r#type={"submit"}>{lang.tr("fetch", None)}</button>
                            </form>
                            <ul>
                                {
                                    remote_communities.items.iter()
                                        .map(|community| {
                                            render::rsx! {
                                                <li><CommunityLink community={&community} /></li>
                                            }
                                        })
                                        .collect::<Vec<_>>()
                                }
                            </ul>
                            {
                                if let Some(next_page) = &remote_communities.next_page {
                                    Some(render::rsx! {
                                        <a href={format!("/communities?local=false&page={}", next_page)}>
                                            {lang.tr("communities_page_next", None)}
                                        </a>
                                    })
                                } else {
                                    None
                                }
                            }
                        </div>
                    })
                } else {
                    None
                }
            }
        </HTPage>
    }))
}


@@ 150,7 273,7 @@ async fn page_community(
        ctx.http_client
            .request(for_client(
                hyper::Request::get(format!(
                    "{}/api/unstable/communities/{}/posts?sort={}&sort_sticky={}",
                    "{}/api/unstable/posts?community={}&sort={}&sort_sticky={}",
                    ctx.backend_host,
                    community_id,
                    query.sort.as_str(),


@@ 165,7 288,7 @@ async fn page_community(
    .await?;
    let posts_api_res = hyper::body::to_bytes(posts_api_res.into_body()).await?;

    let posts: Vec<RespPostListPost<'_>> = serde_json::from_slice(&posts_api_res)?;
    let posts: RespList<RespPostListPost<'_>> = serde_json::from_slice(&posts_api_res)?;

    let new_post_url = format!("/communities/{}/new_post", community_id);



@@ 276,14 399,14 @@ async fn page_community(
                }
            </div>
            {
                if posts.is_empty() {
                if posts.items.is_empty() {
                    Some(render::rsx! { <p>{lang.tr("nothing", None)}</p> })
                } else {
                    None
                }
            }
            <ul>
                {posts.iter().map(|post| {
                {posts.items.iter().map(|post| {
                    PostItem { post, in_community: true, no_user: false, lang: &lang }
                }).collect::<Vec<_>>()}
            </ul>

M src/routes/mod.rs => src/routes/mod.rs +13 -13
@@ 1392,7 1392,7 @@ async fn page_user(
    )
    .await?;
    let things = hyper::body::to_bytes(things.into_body()).await?;
    let things: Vec<RespThingInfo> = serde_json::from_slice(&things)?;
    let things: RespList<RespThingInfo> = serde_json::from_slice(&things)?;

    let title = user.as_ref().username.as_ref();



@@ 1487,7 1487,7 @@ async fn page_user(
            }
            <Content src={&user.description()} />
            {
                if things.is_empty() {
                if things.items.is_empty() {
                    Some(render::rsx! { <p>{lang.tr("nothing", None)}</p> })
                } else {
                    None


@@ 1495,7 1495,7 @@ async fn page_user(
            }
            <ul>
                {
                    things.iter().map(|thing| {
                    things.items.iter().map(|thing| {
                        ThingItem { thing, lang: &lang }
                    })
                    .collect::<Vec<_>>()


@@ 1806,7 1806,7 @@ async fn page_home(
        ctx.http_client
            .request(for_client(
                hyper::Request::get(format!(
                    "{}/api/unstable/users/~me/following:posts",
                    "{}/api/unstable/posts?in_your_follows=true&include_your=true",
                    ctx.backend_host
                ))
                .body(Default::default())?,


@@ 1818,12 1818,12 @@ async fn page_home(
    .await?;

    let api_res = hyper::body::to_bytes(api_res.into_body()).await?;
    let api_res: Vec<RespPostListPost<'_>> = serde_json::from_slice(&api_res)?;
    let api_res: RespList<RespPostListPost<'_>> = serde_json::from_slice(&api_res)?;

    Ok(html_response(render::html! {
        <HTPage base_data={&base_data} lang={&lang} title={"lotide"}>
            {
                if api_res.is_empty() {
                if api_res.items.is_empty() {
                    Some(render::rsx! {
                        <p>
                            {lang.tr("nothing", None)}


@@ 1838,7 1838,7 @@ async fn page_home(
                }
            }
            <ul>
                {api_res.iter().map(|post| {
                {api_res.items.iter().map(|post| {
                    PostItem { post, in_community: false, no_user: false, lang: &lang }
                }).collect::<Vec<_>>()}
            </ul>


@@ 1883,13 1883,13 @@ async fn page_all_inner(
    .await?;

    let api_res = hyper::body::to_bytes(api_res.into_body()).await?;
    let api_res: Vec<RespPostListPost<'_>> = serde_json::from_slice(&api_res)?;
    let api_res: RespList<RespPostListPost<'_>> = serde_json::from_slice(&api_res)?;

    Ok(html_response(render::html! {
        <HTPage base_data={&base_data} lang={&lang} title={"lotide"}>
            <h1>{lang.tr("all_title", None)}</h1>
            {
                if api_res.is_empty() {
                if api_res.items.is_empty() {
                    Some(render::rsx! {
                        <p>
                            {lang.tr("nothing_yet", None)}


@@ 1900,7 1900,7 @@ async fn page_all_inner(
                }
            }
            <ul>
                {api_res.iter().map(|post| {
                {api_res.items.iter().map(|post| {
                    PostItem { post, in_community: false, no_user: false, lang: &lang }
                }).collect::<Vec<_>>()}
            </ul>


@@ 1936,13 1936,13 @@ async fn page_local(
    .await?;

    let api_res = hyper::body::to_bytes(api_res.into_body()).await?;
    let api_res: Vec<RespPostListPost<'_>> = serde_json::from_slice(&api_res)?;
    let api_res: RespList<RespPostListPost<'_>> = serde_json::from_slice(&api_res)?;

    Ok(html_response(render::html! {
        <HTPage base_data={&base_data} lang={&lang} title={"lotide"}>
            <h1>{lang.tr("local_title", None)}</h1>
            {
                if api_res.is_empty() {
                if api_res.items.is_empty() {
                    Some(render::rsx! {
                        <p>
                            {lang.tr("nothing_yet", None)}


@@ 1953,7 1953,7 @@ async fn page_local(
                }
            }
            <ul>
                {api_res.iter().map(|post| {
                {api_res.items.iter().map(|post| {
                    PostItem { post, in_community: false, no_user: false, lang: &lang }
                }).collect::<Vec<_>>()}
            </ul>