use crate::components::{CommunityLink, HTPage, MaybeFillInput, MaybeFillTextArea, PostItem};
use crate::resp_types::{
JustContentHTML, RespCommunityInfoMaybeYour, RespMinimalCommunityInfo, RespPostListPost,
RespYourFollow,
};
use crate::routes::{
fetch_base_data, for_client, get_cookie_map_for_headers, get_cookie_map_for_req, html_response,
res_to_error, CookieMap,
};
use serde_derive::Deserialize;
use std::collections::HashMap;
use std::sync::Arc;
async fn page_communities(
_: (),
ctx: Arc<crate::RouteContext>,
req: hyper::Request<hyper::Body>,
) -> Result<hyper::Response<hyper::Body>, crate::Error> {
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 api_res = res_to_error(
ctx.http_client
.request(
hyper::Request::get(format!("{}/api/unstable/communities", ctx.backend_host,))
.body(Default::default())?,
)
.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);
Ok(html_response(render::html! {
<HTPage base_data={&base_data} lang={&lang} 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
}
}
<ul>
{
communities.iter()
.filter(|x| x.local)
.map(|community| {
render::rsx! {
<li><CommunityLink community={&community} /></li>
}
})
.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>
}
})
.collect::<Vec<_>>()
}
</ul>
</div>
</HTPage>
}))
}
async fn page_community(
params: (i64,),
ctx: Arc<crate::RouteContext>,
req: hyper::Request<hyper::Body>,
) -> Result<hyper::Response<hyper::Body>, crate::Error> {
let (community_id,) = params;
fn default_sort() -> crate::SortType {
crate::SortType::Hot
}
#[derive(Deserialize)]
struct Query {
#[serde(default = "default_sort")]
sort: crate::SortType,
}
let query: Query = serde_urlencoded::from_str(req.uri().query().unwrap_or(""))?;
let lang = crate::get_lang_for_req(&req);
let cookies = get_cookie_map_for_req(&req)?;
// TODO parallelize requests
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 posts_api_res = res_to_error(
ctx.http_client
.request(for_client(
hyper::Request::get(format!(
"{}/api/unstable/communities/{}/posts?sort={}",
ctx.backend_host,
community_id,
query.sort.as_str(),
))
.body(Default::default())?,
req.headers(),
&cookies,
)?)
.await?,
)
.await?;