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, 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, 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, offset: Option, } #[get("/comments")] pub async fn get_comments( commentiflter: Query, state: Data, ) -> Result { 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, state: Data, ) -> Result { 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")), } }