111 lines
5.2 KiB
Rust
111 lines
5.2 KiB
Rust
use axum::{extract::{Path, Query, State}, Json};
|
|
use api_types::requests::{PaginationQuery, SearchQuery};
|
|
use application::use_cases::feed::{get_home_feed, get_public_feed, get_followers, get_following, get_user_feed, get_by_tag};
|
|
use domain::models::feed::PageParams;
|
|
use crate::{errors::ApiError, extractors::{AuthUser, OptionalAuthUser}, handlers::auth::to_user_response, state::AppState};
|
|
use application::use_cases::profile::get_user_by_username;
|
|
|
|
pub async fn home_feed(State(s): State<AppState>, AuthUser(uid): AuthUser, Query(q): Query<PaginationQuery>) -> Result<Json<serde_json::Value>, ApiError> {
|
|
let page = PageParams { page: q.page(), per_page: q.per_page() };
|
|
let result = get_home_feed(&*s.feed, &*s.follows, &uid, page).await?;
|
|
Ok(Json(serde_json::json!({ "items": result.items.iter().map(|e| e.thought.id.as_uuid()).collect::<Vec<_>>(), "total": result.total, "page": result.page })))
|
|
}
|
|
|
|
pub async fn public_feed(State(s): State<AppState>, OptionalAuthUser(viewer): OptionalAuthUser, Query(q): Query<PaginationQuery>) -> Result<Json<serde_json::Value>, ApiError> {
|
|
let page = PageParams { page: q.page(), per_page: q.per_page() };
|
|
let result = get_public_feed(&*s.feed, viewer.as_ref(), page).await?;
|
|
Ok(Json(serde_json::json!({ "items": result.items.iter().map(|e| e.thought.id.as_uuid()).collect::<Vec<_>>(), "total": result.total, "page": result.page })))
|
|
}
|
|
|
|
pub async fn search_handler(
|
|
State(s): State<AppState>,
|
|
OptionalAuthUser(viewer): OptionalAuthUser,
|
|
Query(q): Query<SearchQuery>,
|
|
) -> Result<Json<serde_json::Value>, ApiError> {
|
|
let page = PageParams { page: q.page.unwrap_or(1), per_page: q.per_page.unwrap_or(20) };
|
|
let query = q.q.trim().to_string();
|
|
|
|
let (thoughts_result, users_result) = tokio::join!(
|
|
s.search.search_thoughts(&query, &page, viewer.as_ref()),
|
|
s.search.search_users(&query, &page),
|
|
);
|
|
|
|
let thoughts = thoughts_result?.items.into_iter().map(|e| serde_json::json!({
|
|
"id": e.thought.id.as_uuid(),
|
|
"content": e.thought.content.as_str(),
|
|
"author": to_user_response(&e.author),
|
|
"like_count": e.like_count,
|
|
"boost_count": e.boost_count,
|
|
"reply_count": e.reply_count,
|
|
"created_at": e.thought.created_at,
|
|
})).collect::<Vec<_>>();
|
|
|
|
let users = users_result?.items.into_iter().map(|u| to_user_response(&u)).collect::<Vec<_>>();
|
|
|
|
Ok(Json(serde_json::json!({
|
|
"query": query,
|
|
"thoughts": thoughts,
|
|
"users": users,
|
|
})))
|
|
}
|
|
|
|
pub async fn get_following_handler(State(s): State<AppState>, Path(username): Path<String>, Query(q): Query<PaginationQuery>) -> Result<Json<serde_json::Value>, ApiError> {
|
|
let user = get_user_by_username(&*s.users, &username).await?;
|
|
let page = PageParams { page: q.page(), per_page: q.per_page() };
|
|
let result = get_following(&*s.follows, &user.id, page).await?;
|
|
Ok(Json(serde_json::json!({ "total": result.total, "items": result.items.iter().map(to_user_response).collect::<Vec<_>>() })))
|
|
}
|
|
|
|
pub async fn get_followers_handler(State(s): State<AppState>, Path(username): Path<String>, Query(q): Query<PaginationQuery>) -> Result<Json<serde_json::Value>, ApiError> {
|
|
let user = get_user_by_username(&*s.users, &username).await?;
|
|
let page = PageParams { page: q.page(), per_page: q.per_page() };
|
|
let result = get_followers(&*s.follows, &user.id, page).await?;
|
|
Ok(Json(serde_json::json!({ "total": result.total, "items": result.items.iter().map(to_user_response).collect::<Vec<_>>() })))
|
|
}
|
|
|
|
pub async fn user_thoughts_handler(
|
|
State(s): State<AppState>,
|
|
Path(username): Path<String>,
|
|
Query(q): Query<PaginationQuery>,
|
|
) -> Result<Json<serde_json::Value>, ApiError> {
|
|
let user = get_user_by_username(&*s.users, &username).await?;
|
|
let page = PageParams { page: q.page(), per_page: q.per_page() };
|
|
let result = get_user_feed(&*s.thoughts, &user.id, page).await?;
|
|
Ok(Json(serde_json::json!({
|
|
"total": result.total,
|
|
"page": result.page,
|
|
"per_page": result.per_page,
|
|
"items": result.items.iter().map(|e| serde_json::json!({
|
|
"id": e.thought.id.as_uuid(),
|
|
"content": e.thought.content.as_str(),
|
|
"visibility": e.thought.visibility.as_str(),
|
|
"like_count": e.like_count,
|
|
"boost_count": e.boost_count,
|
|
"reply_count": e.reply_count,
|
|
"created_at": e.thought.created_at,
|
|
"updated_at": e.thought.updated_at,
|
|
})).collect::<Vec<_>>()
|
|
})))
|
|
}
|
|
|
|
pub async fn tag_thoughts_handler(
|
|
State(s): State<AppState>,
|
|
Path(tag_name): Path<String>,
|
|
Query(q): Query<PaginationQuery>,
|
|
) -> Result<Json<serde_json::Value>, ApiError> {
|
|
let page = PageParams { page: q.page(), per_page: q.per_page() };
|
|
let result = get_by_tag(&*s.tags, &tag_name, page).await?;
|
|
Ok(Json(serde_json::json!({
|
|
"tag": tag_name,
|
|
"total": result.total,
|
|
"page": result.page,
|
|
"per_page": result.per_page,
|
|
"items": result.items.iter().map(|t| serde_json::json!({
|
|
"id": t.id.as_uuid(),
|
|
"content": t.content.as_str(),
|
|
"visibility": t.visibility.as_str(),
|
|
"created_at": t.created_at,
|
|
})).collect::<Vec<_>>()
|
|
})))
|
|
}
|