add: user follow requests

add: nsfw questions
fix: inherit nsfw status from questions
fix: inherit community from questions
This commit is contained in:
trisua 2025-04-14 17:21:52 -04:00
parent d6c7372610
commit ad17acec98
24 changed files with 492 additions and 59 deletions

View file

@ -4,7 +4,7 @@ use crate::{
};
use axum::{Extension, Json, extract::Path, response::IntoResponse};
use axum_extra::extract::CookieJar;
use tetratto_core::model::auth::{Notification, UserBlock, UserFollow};
use tetratto_core::model::auth::{FollowResult, Notification, UserBlock, UserFollow};
/// Toggle following on the given user.
pub async fn follow_request(
@ -30,33 +30,111 @@ pub async fn follow_request(
}
} else {
// create
match data.create_userfollow(UserFollow::new(user.id, id)).await {
Ok(_) => {
if let Err(e) = data
.create_notification(Notification::new(
"Somebody has followed you!".to_string(),
format!(
"You have been followed by [@{}](/api/v1/auth/user/find/{}).",
user.username, user.id
),
id,
))
.await
{
return Json(e.into());
};
match data
.create_userfollow(UserFollow::new(user.id, id), false)
.await
{
Ok(r) => {
if r == FollowResult::Followed {
if let Err(e) = data
.create_notification(Notification::new(
"Somebody has followed you!".to_string(),
format!(
"You have been followed by [@{}](/api/v1/auth/user/find/{}).",
user.username, user.id
),
id,
))
.await
{
return Json(e.into());
};
Json(ApiReturn {
ok: true,
message: "User followed".to_string(),
payload: (),
})
Json(ApiReturn {
ok: true,
message: "User followed".to_string(),
payload: (),
})
} else {
Json(ApiReturn {
ok: true,
message: "Asked to follow user".to_string(),
payload: (),
})
}
}
Err(e) => Json(e.into()),
}
}
}
pub async fn cancel_follow_request(
jar: CookieJar,
Extension(data): Extension<State>,
Path(id): Path<usize>,
) -> impl IntoResponse {
let data = &(data.read().await).0;
let user = match get_user_from_token!(jar, data) {
Some(ua) => ua,
None => return Json(Error::NotAllowed.into()),
};
match data.delete_request(user.id, id, &user, true).await {
Ok(_) => Json(ApiReturn {
ok: true,
message: "Follow request deleted".to_string(),
payload: (),
}),
Err(e) => Json(e.into()),
}
}
pub async fn accept_follow_request(
jar: CookieJar,
Extension(data): Extension<State>,
Path(id): Path<usize>,
) -> impl IntoResponse {
let data = &(data.read().await).0;
let user = match get_user_from_token!(jar, data) {
Some(ua) => ua,
None => return Json(Error::NotAllowed.into()),
};
// delete the request
if let Err(e) = data.delete_request(id, user.id, &user, true).await {
return Json(e.into());
}
// create follow
match data
.create_userfollow(UserFollow::new(id, user.id), true)
.await
{
Ok(_) => {
if let Err(e) = data
.create_notification(Notification::new(
"Somebody has accepted your follow request!".to_string(),
format!(
"You are now following [@{}](/api/v1/auth/user/find/{}).",
user.username, user.id
),
id,
))
.await
{
return Json(e.into());
};
Json(ApiReturn {
ok: true,
message: "User follow request accepted".to_string(),
payload: (),
})
}
Err(e) => Json(e.into()),
}
}
/// Toggle blocking on the given user.
pub async fn block_request(
jar: CookieJar,

View file

@ -118,6 +118,14 @@ pub fn routes() -> Router {
.route("/auth/user/{id}/avatar", get(auth::images::avatar_request))
.route("/auth/user/{id}/banner", get(auth::images::banner_request))
.route("/auth/user/{id}/follow", post(auth::social::follow_request))
.route(
"/auth/user/{id}/follow/cancel",
post(auth::social::cancel_follow_request),
)
.route(
"/auth/user/{id}/follow/accept",
post(auth::social::accept_follow_request),
)
.route("/auth/user/{id}/block", post(auth::social::block_request))
.route(
"/auth/user/{id}/settings",

View file

@ -14,7 +14,7 @@ pub async fn delete_request(
None => return Json(Error::NotAllowed.into()),
};
match data.delete_request(id, linked_asset, &user).await {
match data.delete_request(id, linked_asset, &user, false).await {
Ok(_) => Json(ApiReturn {
ok: true,
message: "Request deleted".to_string(),