diff options
author | Colin Reeder <colin@vpzom.click> | 2020-06-06 17:58:32 -0600 |
---|---|---|
committer | Colin Reeder <colin@vpzom.click> | 2020-06-06 17:58:32 -0600 |
commit | f36adf75f755647eed1fe35ab9d32f8fdce31623 (patch) | |
tree | 9c7763f9d3f2942033572395519de844618e0f62 | |
parent | 0590093217c3228f403f9fbfe4909869df013044 (diff) |
Fetch login state
-rw-r--r-- | src/routes/mod.rs | 68 |
1 files changed, 62 insertions, 6 deletions
diff --git a/src/routes/mod.rs b/src/routes/mod.rs index a635504..abb730f 100644 --- a/src/routes/mod.rs +++ b/src/routes/mod.rs @@ -34,6 +34,43 @@ fn with_auth(mut new_req: hyper::Request<hyper::Body>, cookies: &CookieMap<'_>) } #[derive(Deserialize, Debug)] +struct RespLoginInfoUser { + id: i64, +} + +#[derive(Deserialize, Debug)] +struct RespLoginInfo { + user: RespLoginInfoUser, +} + +#[derive(Debug)] +struct PageBaseData { + login: Option<RespLoginInfo>, +} + +async fn fetch_base_data(backend_host: &str, http_client: &crate::HttpClient, cookies: &CookieMap<'_>) -> Result<PageBaseData, crate::Error> { + let login = { + let api_res = http_client.request( + with_auth( + hyper::Request::get(format!("{}/api/unstable/logins/~current", backend_host)) + .body(Default::default())?, + &cookies, + )? + ).await?; + + if api_res.status() == hyper::StatusCode::UNAUTHORIZED { + Ok(None) + } else { + let api_res = res_to_error(api_res).await?; + let api_res = hyper::body::to_bytes(api_res.into_body()).await?; + serde_json::from_slice(&api_res) + } + }?; + + Ok(PageBaseData { login }) +} + +#[derive(Deserialize, Debug)] struct RespMinimalAuthorInfo<'a> { id: i64, username: &'a str, @@ -75,7 +112,7 @@ pub fn route_root() -> crate::RouteNode<()> { } #[render::component] -fn HTPage<Children: render::Render>(children: Children) { +fn HTPage<'base_data, Children: render::Render>(base_data: &'base_data PageBaseData, children: Children) { render::rsx! { <> <render::html::HTML5Doctype /> @@ -84,7 +121,16 @@ fn HTPage<Children: render::Render>(children: Children) { <header class={"mainHeader"}> <div>{"lotide"}</div> <div> - <a href={"/login"}>{"Login"}</a> + { + match base_data.login { + Some(_) => None, + None => { + Some(render::rsx! { + <a href={"/login"}>{"Login"}</a> + }) + } + } + } </div> </header> {children} @@ -178,9 +224,13 @@ fn html_response(html: String) -> hyper::Response<hyper::Body> { res } -async fn page_login(_: (), _ctx: Arc<crate::RouteContext>, _req: hyper::Request<hyper::Body>) -> Result<hyper::Response<hyper::Body>, crate::Error> { +async fn page_login(_: (), ctx: Arc<crate::RouteContext>, req: hyper::Request<hyper::Body>) -> Result<hyper::Response<hyper::Body>, crate::Error> { + let cookies = get_cookie_map_for_req(&req)?; + + let base_data = fetch_base_data(&ctx.backend_host, &ctx.http_client, &cookies).await?; + Ok(html_response(render::html! { - <HTPage> + <HTPage base_data={&base_data}> <form method={"POST"} action={"/login/submit"}> <p> <input r#type={"text"} name={"username"} /> @@ -238,6 +288,8 @@ async fn handler_login_submit(_: (), ctx: Arc<crate::RouteContext>, req: hyper:: async fn page_home(_: (), ctx: Arc<crate::RouteContext>, req: hyper::Request<hyper::Body>) -> Result<hyper::Response<hyper::Body>, crate::Error> { let cookies = get_cookie_map_for_req(&req)?; + let base_data = fetch_base_data(&ctx.backend_host, &ctx.http_client, &cookies).await?; + let api_res = res_to_error(ctx.http_client.request( with_auth( hyper::Request::get(format!("{}/api/unstable/users/me/following:posts", ctx.backend_host)) @@ -250,7 +302,7 @@ async fn page_home(_: (), ctx: Arc<crate::RouteContext>, req: hyper::Request<hyp let api_res: Vec<RespPostListPost<'_>> = serde_json::from_slice(&api_res)?; Ok(html_response(render::html! { - <HTPage> + <HTPage base_data={&base_data}> <ul> {api_res.iter().map(|post| { PostItem { post, in_community: false } @@ -265,6 +317,10 @@ async fn page_community(params: (i64,), ctx: Arc<crate::RouteContext>, req: hype let cookies = get_cookie_map_for_req(&req)?; + // TODO parallelize requests + + let base_data = fetch_base_data(&ctx.backend_host, &ctx.http_client, &cookies).await?; + let community_info_api_res = res_to_error( ctx.http_client.request( with_auth( @@ -294,7 +350,7 @@ async fn page_community(params: (i64,), ctx: Arc<crate::RouteContext>, req: hype let posts: Vec<RespPostListPost<'_>> = serde_json::from_slice(&posts_api_res)?; Ok(html_response(render::html! { - <HTPage> + <HTPage base_data={&base_data}> <h1>{community_info.name}</h1> <ul> {posts.iter().map(|post| { |