summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorColin Reeder <colin@vpzom.click>2020-06-06 17:26:42 -0600
committerColin Reeder <colin@vpzom.click>2020-06-06 17:26:42 -0600
commit0590093217c3228f403f9fbfe4909869df013044 (patch)
treee00b1a053af928d5fb5ad7768689c6e36190bd35
parentb62c324da86c411df33e497bef7733306687d82a (diff)
Community pages
-rw-r--r--src/routes/mod.rs155
1 files changed, 122 insertions, 33 deletions
diff --git a/src/routes/mod.rs b/src/routes/mod.rs
index 39e87a0..a635504 100644
--- a/src/routes/mod.rs
+++ b/src/routes/mod.rs
@@ -19,6 +19,10 @@ fn get_cookie_map<'a>(src: Option<&'a str>) -> Result<CookieMap<'a>, ginger::Par
}
}
+fn get_cookie_map_for_req<'a>(req: &'a hyper::Request<hyper::Body>) -> Result<CookieMap<'a>, crate::Error> {
+ get_cookie_map(req.headers().get(hyper::header::COOKIE).map(|x| x.to_str()).transpose()?).map_err(Into::into)
+}
+
fn with_auth(mut new_req: hyper::Request<hyper::Body>, cookies: &CookieMap<'_>) -> Result<hyper::Request<hyper::Body>, hyper::header::InvalidHeaderValue> {
let token = cookies.get("hitideToken").map(|c| c.value);
if let Some(token) = token {
@@ -37,10 +41,28 @@ struct RespMinimalAuthorInfo<'a> {
host: &'a str,
}
+#[derive(Deserialize, Debug)]
+struct RespPostListPost<'a> {
+ id: i64,
+ title: &'a str,
+ href: &'a str,
+ author: Option<RespMinimalAuthorInfo<'a>>,
+ created: &'a str,
+ community: RespMinimalCommunityInfo<'a>,
+}
+
pub fn route_root() -> crate::RouteNode<()> {
crate::RouteNode::new()
.with_handler_async("GET", page_home)
.with_child(
+ "communities",
+ crate::RouteNode::new()
+ .with_child_parse::<i64, _>(
+ crate::RouteNode::new()
+ .with_handler_async("GET", page_community)
+ )
+ )
+ .with_child(
"login",
crate::RouteNode::new()
.with_handler_async("GET", page_login)
@@ -72,8 +94,38 @@ fn HTPage<Children: render::Render>(children: Children) {
}
}
+#[render::component]
+fn PostItem<'post>(post: &'post RespPostListPost<'post>, in_community: bool) {
+ render::rsx! {
+ <li>
+ <a href={post.href}>
+ {post.title}
+ </a>
+ <br />
+ {"Submitted by "}<UserLink user={post.author.as_ref()} />
+ {
+ if !in_community {
+ Some(render::rsx! {
+ <>{" to "}<CommunityLink community={&post.community} /></>
+ })
+ } else {
+ None
+ }
+ }
+ </li>
+ }
+}
+
+#[derive(Deserialize, Debug)]
+struct RespMinimalCommunityInfo<'a> {
+ id: i64,
+ name: &'a str,
+ local: bool,
+ host: &'a str,
+}
+
struct UserLink<'user> {
- user: Option<RespMinimalAuthorInfo<'user>>,
+ user: Option<&'user RespMinimalAuthorInfo<'user>>,
}
impl<'user> render::Render for UserLink<'user> {
@@ -98,6 +150,28 @@ impl<'user> render::Render for UserLink<'user> {
}
}
+struct CommunityLink<'community> {
+ community: &'community RespMinimalCommunityInfo<'community>,
+}
+impl<'community> render::Render for CommunityLink<'community> {
+ fn render_into<W: std::fmt::Write>(self, writer: &mut W) -> std::fmt::Result {
+ let community = &self.community;
+
+ let href = format!("/communities/{}", community.id);
+ (render::rsx! {
+ <a href={&href}>
+ {
+ (if community.local {
+ community.name.into()
+ } else {
+ Cow::Owned(format!("{}@{}", community.name, community.host))
+ }).as_ref()
+ }
+ </a>
+ }).render_into(writer)
+ }
+}
+
fn html_response(html: String) -> hyper::Response<hyper::Body> {
let mut res = hyper::Response::new(html.into());
res.headers_mut().insert(hyper::header::CONTENT_TYPE, hyper::header::HeaderValue::from_static("text/html"));
@@ -162,27 +236,7 @@ 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> {
- #[derive(Deserialize, Debug)]
- struct RespMinimalCommunityInfo<'a> {
- id: i64,
- name: &'a str,
- local: bool,
- host: &'a str,
- }
-
- #[derive(Deserialize, Debug)]
- struct RespPostListPost<'a> {
- id: i64,
- title: &'a str,
- href: &'a str,
- author: Option<RespMinimalAuthorInfo<'a>>,
- created: &'a str,
- community: RespMinimalCommunityInfo<'a>,
- }
-
- let cookies = get_cookie_map(req.headers().get(hyper::header::COOKIE).map(|x| x.to_str()).transpose()?)?;
-
- println!("{:?}", cookies);
+ let cookies = get_cookie_map_for_req(&req)?;
let api_res = res_to_error(ctx.http_client.request(
with_auth(
@@ -195,21 +249,56 @@ async fn page_home(_: (), ctx: Arc<crate::RouteContext>, req: hyper::Request<hyp
let api_res = hyper::body::to_bytes(api_res.into_body()).await?;
let api_res: Vec<RespPostListPost<'_>> = serde_json::from_slice(&api_res)?;
- println!("{:?}", api_res);
+ Ok(html_response(render::html! {
+ <HTPage>
+ <ul>
+ {api_res.iter().map(|post| {
+ PostItem { post, in_community: false }
+ }).collect::<Vec<_>>()}
+ </ul>
+ </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;
+
+ let cookies = get_cookie_map_for_req(&req)?;
+
+ let community_info_api_res = res_to_error(
+ ctx.http_client.request(
+ with_auth(
+ hyper::Request::get(format!("{}/api/unstable/communities/{}", ctx.backend_host, community_id))
+ .body(Default::default())?,
+ &cookies,
+ )?
+ ).await?
+ ).await?;
+ let community_info_api_res = hyper::body::to_bytes(community_info_api_res.into_body()).await?;
+
+ let community_info: RespMinimalCommunityInfo = {
+ serde_json::from_slice(&community_info_api_res)?
+ };
+
+ let posts_api_res = res_to_error(
+ ctx.http_client.request(
+ with_auth(
+ hyper::Request::get(format!("{}/api/unstable/communities/{}/posts", ctx.backend_host, community_id))
+ .body(Default::default())?,
+ &cookies,
+ )?
+ ).await?
+ ).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)?;
Ok(html_response(render::html! {
<HTPage>
+ <h1>{community_info.name}</h1>
<ul>
- {api_res.into_iter().map(|post| {
- render::rsx! {
- <li>
- <a href={post.href}>
- {post.title}
- </a>
- <br />
- {"Submitted by "}<UserLink user={post.author} />
- </li>
- }
+ {posts.iter().map(|post| {
+ PostItem { post, in_community: true }
}).collect::<Vec<_>>()}
</ul>
</HTPage>