Skip to main content

max / makenotwork

1.4 KB · 55 lines History Blame Raw
1 //! User embed handlers: tip button.
2
3 use axum::{
4 extract::{Path, State},
5 response::{Html, IntoResponse, Response},
6 };
7
8 use crate::quasi::embeds;
9 use crate::{
10 config::Config,
11 db::{self, Username},
12 error::{AppError, Result},
13 };
14 use sqlx::PgPool;
15
16 use super::item::set_embed_headers;
17
18 #[tracing::instrument(skip_all, name = "embed::tip_button")]
19 /// GET /embed/u/{username}/tip
20 pub(super) async fn tip_button(
21 State(db): State<PgPool>,
22 State(config): State<Config>,
23 Path(username): Path<String>,
24 ) -> Result<Response> {
25 let username = Username::new(&username).map_err(|_| AppError::NotFound)?;
26 let user = db::users::get_user_by_username(&db, &username)
27 .await?
28 .ok_or(AppError::NotFound)?;
29
30 if user.is_suspended() || user.is_deactivated() || !user.tips_enabled {
31 return Err(AppError::NotFound);
32 }
33
34 let display_name = user
35 .display_name
36 .as_deref()
37 .unwrap_or(&user.username)
38 .to_string();
39 let tip_url = format!("{}/u/{}/tip", config.host_url, user.username);
40
41 let view = embeds::TipView {
42 display_name,
43 username: user.username.to_string(),
44 tip_url,
45 avatar_url: user.avatar_url,
46 };
47 let mut response = Html(embeds::document(
48 &embeds::tip_button(&view),
49 Some("embed-tip"),
50 ))
51 .into_response();
52 set_embed_headers(&mut response);
53 Ok(response)
54 }
55