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 quasi_router::Document;
15 use sqlx::PgPool;
16
17 use super::item::set_embed_headers;
18
19 #[tracing::instrument(skip_all, name = "embed::tip_button")]
20 /// GET /embed/u/{username}/tip
21 pub(super) async fn tip_button(
22 State(db): State<PgPool>,
23 State(config): State<Config>,
24 Path(username): Path<String>,
25 ) -> Result<Response> {
26 let username = Username::new(&username).map_err(|_| AppError::NotFound)?;
27 let user = db::users::get_user_by_username(&db, &username)
28 .await?
29 .ok_or(AppError::NotFound)?;
30
31 if user.is_suspended() || user.is_deactivated() || !user.tips_enabled {
32 return Err(AppError::NotFound);
33 }
34
35 let display_name = user
36 .display_name
37 .as_deref()
38 .unwrap_or(&user.username)
39 .to_string();
40 let tip_url = format!("{}/u/{}/tip", config.host_url, user.username);
41
42 let view = embeds::TipView {
43 display_name,
44 username: user.username.to_string(),
45 tip_url,
46 avatar_url: user.avatar_url,
47 };
48 let mut response = Html(embeds::document(
49 &embeds::tip_button(&view).documented(Document::default().classed("embed-tip")),
50 ))
51 .into_response();
52 set_embed_headers(&mut response);
53 Ok(response)
54 }
55