diff --git a/crates/service/web/storyteller_web/src/http_server/endpoints/comments/edit_comment_handler.rs b/crates/service/web/storyteller_web/src/http_server/endpoints/comments/edit_comment_handler.rs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/crates/service/web/storyteller_web/src/http_server/endpoints/comments/list_comments_handler.rs b/crates/service/web/storyteller_web/src/http_server/endpoints/comments/list_comments_handler.rs index e69de29bb2..15e1484cad 100644 --- a/crates/service/web/storyteller_web/src/http_server/endpoints/comments/list_comments_handler.rs +++ b/crates/service/web/storyteller_web/src/http_server/endpoints/comments/list_comments_handler.rs @@ -0,0 +1,137 @@ +// NB: Incrementally getting rid of build warnings... +#![forbid(unused_imports)] +#![forbid(unused_mut)] +#![forbid(unused_variables)] + +use actix_web::error::ResponseError; +use actix_web::http::StatusCode; +use actix_web::web::Path; +use actix_web::{web, HttpResponse, HttpRequest}; +use chrono::{DateTime, Utc}; +use crate::http_server::web_utils::response_error_helpers::to_simple_json_error; +use crate::server_state::ServerState; +use enums::by_table::comments::comment_entity_type::CommentEntityType; +use log::warn; +use mysql_queries::queries::comments::list_comments_for_entity::list_comments_for_entity; +use std::fmt; +use std::sync::Arc; +use mysql_queries::queries::comments::comment_entity_token::CommentEntityToken; +use tokens::tokens::comments::CommentToken; +use tokens::users::user::UserToken; + +/// For the URL PathInfo +#[derive(Deserialize)] +pub struct ListCommentsPathInfo { + entity_type: CommentEntityType, + entity_token: String, +} + +#[derive(Serialize)] +pub struct ListCommentsSuccessResponse { + pub success: bool, + pub comments: Vec, +} + +#[derive(Serialize)] +pub struct Comment { + pub token: CommentToken, + + pub user_token: UserToken, + pub username: String, + pub user_display_name: String, + pub user_gravatar_hash: String, + + pub comment_markdown: String, + pub comment_rendered_html: String, + + //pub mod_fields: CommentForListModFields, + + pub created_at: DateTime, + pub updated_at: DateTime, + pub maybe_edited_at: Option>, +} + +// TODO +//pub struct CommentForListModFields { +// pub creator_ip_address: String, +// pub editor_ip_address: String, +// pub maybe_user_deleted_at: Option>, +// pub maybe_mod_deleted_at: Option>, +// pub maybe_object_owner_deleted_at: Option>, +//} + +#[derive(Debug)] +pub enum ListCommentsError { + ServerError, +} + +impl ResponseError for ListCommentsError { + fn status_code(&self) -> StatusCode { + match *self { + ListCommentsError::ServerError=> StatusCode::INTERNAL_SERVER_ERROR, + } + } + + fn error_response(&self) -> HttpResponse { + let error_reason = match self { + ListCommentsError::ServerError => "server error".to_string(), + }; + + to_simple_json_error(&error_reason, self.status_code()) + } +} + +// NB: Not using derive_more::Display since Clion doesn't understand it. +impl fmt::Display for ListCommentsError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?}", self) + } +} + +pub async fn list_comments_handler( + _http_request: HttpRequest, + path: Path, + server_state: web::Data> +) -> Result +{ + let entity_token = CommentEntityToken::from_entity_type_and_token( + path.entity_type, &path.entity_token); + + let query_results = list_comments_for_entity( + entity_token, + &server_state.mysql_pool, + ).await; + + let comments = match query_results { + Ok(results) => results, + Err(e) => { + warn!("Query error: {:?}", e); + return Err(ListCommentsError::ServerError); + } + }; + + let response = ListCommentsSuccessResponse { + success: true, + comments: comments.into_iter() + .map(|comment| Comment { + token: comment.token, + user_token: comment.user_token, + username: comment.username, + user_display_name: comment.user_display_name, + user_gravatar_hash: comment.user_gravatar_hash, + comment_markdown: comment.comment_markdown, + comment_rendered_html: comment.comment_rendered_html, + created_at: comment.created_at, + updated_at: comment.updated_at, + maybe_edited_at: comment.maybe_edited_at, + }) + .collect(), + }; + + let body = serde_json::to_string(&response) + .map_err(|_e| ListCommentsError::ServerError)?; + + Ok(HttpResponse::Ok() + .content_type("application/json") + .body(body)) +} diff --git a/crates/service/web/storyteller_web/src/http_server/endpoints/comments/mod.rs b/crates/service/web/storyteller_web/src/http_server/endpoints/comments/mod.rs index 752004d915..1d30b8c6d5 100644 --- a/crates/service/web/storyteller_web/src/http_server/endpoints/comments/mod.rs +++ b/crates/service/web/storyteller_web/src/http_server/endpoints/comments/mod.rs @@ -1,4 +1,3 @@ pub mod create_comment_handler; pub mod delete_comment_handler; -pub mod edit_comment_handler; -pub mod list_comments_handler; \ No newline at end of file +pub mod list_comments_handler; diff --git a/crates/service/web/storyteller_web/src/routes.rs b/crates/service/web/storyteller_web/src/routes.rs index 43bc2fc6b1..84318c9ef5 100644 --- a/crates/service/web/storyteller_web/src/routes.rs +++ b/crates/service/web/storyteller_web/src/routes.rs @@ -3,6 +3,7 @@ use actix_service::ServiceFactory; use actix_web::dev::{ServiceRequest, ServiceResponse}; use actix_web::error::Error; use actix_web::{App, web, HttpResponse}; +use actix_helpers::route_builder::RouteBuilder; use billing_component::default_routes::add_suggested_stripe_billing_routes; use crate::http_server::endpoints::api_tokens::create_api_token::create_api_token_handler; use crate::http_server::endpoints::api_tokens::delete_api_token::delete_api_token_handler; @@ -106,6 +107,9 @@ use crate::http_server::endpoints::subscriptions::unsubscribe_reason::set_unsubs use users_component::default_routes::add_suggested_api_v1_account_creation_and_session_routes; use users_component::endpoints::edit_profile_handler::edit_profile_handler; use users_component::endpoints::get_profile_handler::get_profile_handler; +use crate::http_server::endpoints::comments::create_comment_handler::create_comment_handler; +use crate::http_server::endpoints::comments::delete_comment_handler::delete_comment_handler; +use crate::http_server::endpoints::comments::list_comments_handler::list_comments_handler; pub fn add_routes (app: App) -> App where @@ -137,7 +141,16 @@ pub fn add_routes (app: App) -> App app = add_user_rating_routes(app); /* /v1/user_rating/... */ app = add_subscription_routes(app); /* /v1/subscriptions/... */ - // From components + // ==================== Comments ==================== + + let mut app = RouteBuilder::from_app(app) + .add_get("/v1/comments/{entity_type}/entity_token", list_comments_handler) + .add_post("/v1/comments/new", create_comment_handler) + .add_post("/v1/comments/{comment_token}/delete", delete_comment_handler) + .into_app(); + + // ==================== COMPONENTS ==================== + app = add_suggested_api_v1_account_creation_and_session_routes(app); // /create_account, /session, /login, /logout app = add_suggested_stripe_billing_routes(app); // /stripe, billing, webhooks, etc.