98 lines
2.6 KiB
Rust
98 lines
2.6 KiB
Rust
|
use crate::db::{db_get_comments, db_new_comment};
|
||
|
use crate::jwt::validate_token;
|
||
|
use crate::ServerState;
|
||
|
|
||
|
use actix_web::get;
|
||
|
use actix_web::web::{Data, Query};
|
||
|
use actix_web::{post, web::Json, HttpResponse, Responder, Result};
|
||
|
use log::info;
|
||
|
use serde::{Deserialize, Serialize};
|
||
|
|
||
|
#[derive(Debug, Serialize, Deserialize)]
|
||
|
pub struct NewComment {
|
||
|
pub parent_post_id: i64,
|
||
|
pub parent_comment_id: Option<i64>,
|
||
|
pub user_token: String,
|
||
|
pub content: String,
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, Serialize, Deserialize, Clone, sqlx::FromRow)]
|
||
|
pub struct Comment {
|
||
|
pub id: i64,
|
||
|
pub parent_post_id: i64,
|
||
|
pub parent_comment_id: Option<i64>,
|
||
|
pub author_user_id: i64,
|
||
|
pub upvotes: i64,
|
||
|
pub downvotes: i64,
|
||
|
pub content: String,
|
||
|
pub created_at: chrono::NaiveDateTime,
|
||
|
pub updated_at: chrono::NaiveDateTime,
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, Serialize, Deserialize)]
|
||
|
pub struct CommentQueryParams {
|
||
|
post_id: i64,
|
||
|
limit: Option<i64>,
|
||
|
offset: Option<i64>,
|
||
|
}
|
||
|
|
||
|
#[get("/comments")]
|
||
|
pub async fn get_comments(
|
||
|
commentiflter: Query<CommentQueryParams>,
|
||
|
state: Data<ServerState>,
|
||
|
) -> Result<impl Responder> {
|
||
|
let post_id = commentiflter.post_id;
|
||
|
let limit = commentiflter.limit.unwrap_or(10);
|
||
|
let offset = commentiflter.offset.unwrap_or(0);
|
||
|
|
||
|
info!(
|
||
|
"Getting comments for post {} with limit {} and offset {}",
|
||
|
post_id, limit, offset
|
||
|
);
|
||
|
|
||
|
let comments = db_get_comments(&state.pool, post_id, limit, offset).await;
|
||
|
|
||
|
Ok(HttpResponse::Ok().json(comments))
|
||
|
}
|
||
|
|
||
|
#[post("/comments")]
|
||
|
pub async fn new_comment(
|
||
|
data: Json<NewComment>,
|
||
|
state: Data<ServerState>,
|
||
|
) -> Result<impl Responder> {
|
||
|
let user_claims = validate_token(&data.user_token);
|
||
|
|
||
|
// Bail if the token is invalid
|
||
|
if let Err(e) = user_claims {
|
||
|
info!("Error validating token: {}", e);
|
||
|
return Ok(HttpResponse::BadRequest().json("Error"));
|
||
|
}
|
||
|
|
||
|
let claims = user_claims.unwrap();
|
||
|
info!("User {:?} created a new comment", &claims.sub);
|
||
|
|
||
|
let content = data.content.clone();
|
||
|
let username = claims.sub.clone();
|
||
|
|
||
|
// This one is avoidable if we just store the user id in the token
|
||
|
let userid = sqlx::query!("SELECT id FROM users WHERE username = $1", username)
|
||
|
.fetch_one(&state.pool)
|
||
|
.await
|
||
|
.unwrap()
|
||
|
.id;
|
||
|
|
||
|
let success = db_new_comment(
|
||
|
&state.pool,
|
||
|
data.parent_post_id,
|
||
|
data.parent_comment_id,
|
||
|
userid,
|
||
|
&content,
|
||
|
)
|
||
|
.await;
|
||
|
|
||
|
match success {
|
||
|
true => Ok(HttpResponse::Ok().json("Success")),
|
||
|
false => Ok(HttpResponse::BadRequest().json("Error")),
|
||
|
}
|
||
|
}
|