summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorColin Reeder <colin@vpzom.click>2020-08-02 21:20:16 -0600
committerColin Reeder <colin@vpzom.click>2020-08-02 21:20:16 -0600
commitc03de98fbb1f4769e3d9917ba87d6041d9c91dfe (patch)
tree8f80ee8fdbe06092c3cde1878e6ec56fafe7b09f
parent30eb3636cc7ccc968f4244eef7c39a4cf0a317ff (diff)
Add UI for personal notes
-rw-r--r--res/lang/en.ftl4
-rw-r--r--res/lang/eo.ftl4
-rw-r--r--src/resp_types.rs6
-rw-r--r--src/routes/mod.rs133
4 files changed, 142 insertions, 5 deletions
diff --git a/res/lang/en.ftl b/res/lang/en.ftl
index 26f4462..ab31313 100644
--- a/res/lang/en.ftl
+++ b/res/lang/en.ftl
@@ -61,6 +61,7 @@ remote = Remote
reply = reply
reply_submit = Reply
reply_to = Reply to
+save = Save
score = { $score } likes
sort = Sort:
sort_hot = hot
@@ -119,3 +120,6 @@ username_prompt = Username:
view_at_source = View at Source
view_more_comments = View More Comments
your_comment = your comment
+your_note = Personal Note
+your_note_add = Add Personal Note
+your_note_edit = Edit Personal Note
diff --git a/res/lang/eo.ftl b/res/lang/eo.ftl
index 47bfc91..1629cc7 100644
--- a/res/lang/eo.ftl
+++ b/res/lang/eo.ftl
@@ -61,6 +61,7 @@ remote = Fora
reply = respondi
reply_submit = Respondi
reply_to = Respondo al
+save = Konservi
score = { $score } ŝatantoj
sort = Ordigi:
sort_hot = furora
@@ -119,3 +120,6 @@ username_prompt = Uzantnomo:
view_at_source = Vidi ĉe Fonto
view_more_comments = Vidi Pli da Komentoj
your_comment = via komento
+your_note = Propra Noto
+your_note_add = Aldoni Propra Noto
+your_note_edit = Redakti Propra Noto
diff --git a/src/resp_types.rs b/src/resp_types.rs
index 96b1626..d2ec489 100644
--- a/src/resp_types.rs
+++ b/src/resp_types.rs
@@ -137,6 +137,7 @@ pub struct RespUserInfo<'a> {
#[serde(flatten)]
pub base: RespMinimalAuthorInfo<'a>,
pub description: Cow<'a, str>,
+ pub your_note: Option<JustContentText<'a>>,
}
impl<'a> AsRef<RespMinimalAuthorInfo<'a>> for RespUserInfo<'a> {
@@ -228,6 +229,11 @@ pub struct JustUser<'a> {
}
#[derive(Deserialize, Debug)]
+pub struct JustContentText<'a> {
+ pub content_text: Cow<'a, str>,
+}
+
+#[derive(Deserialize, Debug)]
pub struct JustContentHTML<'a> {
pub content_html: Cow<'a, str>,
}
diff --git a/src/routes/mod.rs b/src/routes/mod.rs
index 355d992..0c8969f 100644
--- a/src/routes/mod.rs
+++ b/src/routes/mod.rs
@@ -1087,13 +1087,21 @@ async fn page_user(
let user = res_to_error(
ctx.http_client
- .request(
+ .request(for_client(
hyper::Request::get(format!(
- "{}/api/unstable/users/{}",
- ctx.backend_host, user_id
+ "{}/api/unstable/users/{}{}",
+ ctx.backend_host,
+ user_id,
+ if base_data.login.is_some() {
+ "?include_your=true"
+ } else {
+ ""
+ },
))
.body(Default::default())?,
- )
+ req.headers(),
+ &cookies,
+ )?)
.await?,
)
.await?;
@@ -1120,7 +1128,7 @@ async fn page_user(
Ok(html_response(render::html! {
<HTPage base_data={&base_data} lang={&lang} title>
<h1>{title}</h1>
- <div><em>{format!("@{}@{}", user.as_ref().username, user.as_ref().host)}</em></div>
+ <p><em>{format!("@{}@{}", user.as_ref().username, user.as_ref().host)}</em></p>
{
if user.as_ref().local {
None
@@ -1136,6 +1144,29 @@ async fn page_user(
}
}
{
+ if let Some(your_note) = &user.your_note {
+ Some(render::rsx! {
+ <div>
+ {lang.tr("your_note", None)}{" ("}<a href={format!("/users/{}/your_note/edit", user_id)}>{lang.tr("edit", None)}</a>{"):"}
+ <pre>{your_note.content_text.as_ref()}</pre>
+ </div>
+ })
+ } else {
+ None
+ }
+ }
+ {
+ if user.your_note.is_none() && base_data.login.is_some() {
+ Some(render::rsx! {
+ <div>
+ <a href={format!("/users/{}/your_note/edit", user_id)}>{lang.tr("your_note_add", None)}</a>
+ </div>
+ })
+ } else {
+ None
+ }
+ }
+ {
if let Some(login) = &base_data.login {
if login.user.id == user_id {
Some(render::rsx! { <a href={format!("/users/{}/edit", user_id)}>{lang.tr("edit", None)}</a> })
@@ -1262,6 +1293,88 @@ async fn handler_user_edit_submit(
.body("Successfully created.".into())?)
}
+async fn page_user_your_note_edit(
+ params: (i64,),
+ ctx: Arc<crate::RouteContext>,
+ req: hyper::Request<hyper::Body>,
+) -> Result<hyper::Response<hyper::Body>, crate::Error> {
+ let (user_id,) = params;
+
+ 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 user = res_to_error(
+ ctx.http_client
+ .request(for_client(
+ hyper::Request::get(format!(
+ "{}/api/unstable/users/{}?include_your=true",
+ ctx.backend_host, user_id,
+ ))
+ .body(Default::default())?,
+ req.headers(),
+ &cookies,
+ )?)
+ .await?,
+ )
+ .await?;
+ let user = hyper::body::to_bytes(user.into_body()).await?;
+ let user: RespUserInfo<'_> = serde_json::from_slice(&user)?;
+
+ let title = lang.tr("your_note_edit", None);
+
+ Ok(html_response(render::html! {
+ <HTPage base_data={&base_data} lang={&lang} title={&title}>
+ <h1>{title.as_ref()}</h1>
+ <form method={"POST"} action={format!("/users/{}/your_note/edit/submit", user_id)}>
+ <div>
+ <textarea name={"content_text"} autofocus={""}>
+ {user.your_note.map(|x| x.content_text)}
+ </textarea>
+ </div>
+ <button type={"submit"}>{lang.tr("save", None)}</button>
+ </form>
+ </HTPage>
+ }))
+}
+
+async fn handler_user_your_note_edit_submit(
+ params: (i64,),
+ ctx: Arc<crate::RouteContext>,
+ req: hyper::Request<hyper::Body>,
+) -> Result<hyper::Response<hyper::Body>, crate::Error> {
+ let (user_id,) = params;
+
+ let (req_parts, body) = req.into_parts();
+
+ let cookies = get_cookie_map_for_headers(&req_parts.headers)?;
+
+ let body = hyper::body::to_bytes(body).await?;
+ let body: serde_json::Value = serde_urlencoded::from_bytes(&body)?;
+
+ res_to_error(
+ ctx.http_client
+ .request(for_client(
+ hyper::Request::put(format!(
+ "{}/api/unstable/users/{}/your_note",
+ ctx.backend_host, user_id
+ ))
+ .body(serde_json::to_vec(&body)?.into())?,
+ &req_parts.headers,
+ &cookies,
+ )?)
+ .await?,
+ )
+ .await?;
+
+ Ok(hyper::Response::builder()
+ .status(hyper::StatusCode::SEE_OTHER)
+ .header(hyper::header::LOCATION, format!("/users/{}", user_id))
+ .body("Successfully created.".into())?)
+}
+
async fn page_home(
_: (),
ctx: Arc<crate::RouteContext>,
@@ -1474,6 +1587,16 @@ pub fn route_root() -> crate::RouteNode<()> {
crate::RouteNode::new()
.with_handler_async("POST", handler_user_edit_submit),
),
+ )
+ .with_child(
+ "your_note/edit",
+ crate::RouteNode::new()
+ .with_handler_async("GET", page_user_your_note_edit)
+ .with_child(
+ "submit",
+ crate::RouteNode::new()
+ .with_handler_async("POST", handler_user_your_note_edit_submit),
+ ),
),
),
)