diff --git a/db/1.sqlite b/db/1.sqlite index 14805d3..189b6e1 100644 Binary files a/db/1.sqlite and b/db/1.sqlite differ diff --git a/db/auth.sqlite b/db/auth.sqlite index c436baa..cd1d46d 100644 Binary files a/db/auth.sqlite and b/db/auth.sqlite differ diff --git a/src/chat/extractor.rs b/src/chat/extractor.rs index dc3e5d7..4041c4a 100644 --- a/src/chat/extractor.rs +++ b/src/chat/extractor.rs @@ -5,8 +5,11 @@ use axum::{ http::StatusCode, Json, }; +use chrono::NaiveDateTime; use serde::Deserialize; + + #[derive(Deserialize, Debug)] pub struct CreateConversationValues{ //pub creator_id: i32, // already in token ? @@ -75,4 +78,29 @@ where S: Send + Sync, Ok(SendMessagePayload(payload)) } -} \ No newline at end of file +} + + +#[derive(Deserialize, Debug)] +pub struct GetMessagesValues{ + pub conv_id: u32, + pub timestamp :Option, +} + +pub struct GetMessagesPayload(pub GetMessagesValues); + +impl FromRequest for GetMessagesPayload +where S: Send + Sync, +{ + type Rejection = (StatusCode, String); + + async fn from_request(req: Request, state: &S) -> Result { + let Json(payload) = Json::::from_request(req, state) + .await + .map_err(|err| (StatusCode::BAD_REQUEST, format!("Invalid body: {}", err)))?; + + Ok(GetMessagesPayload(payload)) + + } +} + diff --git a/src/chat/handlers.rs b/src/chat/handlers.rs index 8e4bab4..f75c061 100644 --- a/src/chat/handlers.rs +++ b/src/chat/handlers.rs @@ -5,10 +5,12 @@ use axum::{ }, http::StatusCode, response::{sse::KeepAlive, IntoResponse} }; +use chrono::NaiveDateTime; use rusqlite::params; +use serde::Serialize; use crate::chat::extractor::{ -AddUserConversationPayload, CreateConversationPayload, SendMessagePayload +AddUserConversationPayload, CreateConversationPayload, GetMessagesPayload, SendMessagePayload }; use crate::utils::db_pool::{AppState}; use crate::utils::auth::AuthClaims; @@ -126,4 +128,58 @@ pub async fn send_message( Ok(_) => (StatusCode::NOT_FOUND, "not able to add the message, conversation may not exist".to_string() ), Err(err) => (StatusCode::INTERNAL_SERVER_ERROR, format!("Error when adding the message : {err}")), } +} + + + #[derive(Debug, Serialize)] + struct Message { + id: i32, + sender_id: i32, + content: String, + sent_at: String, + } + + +pub async fn get_message( + State(state): State, + AuthClaims {user_id, hotel_id,username}: AuthClaims, + GetMessagesPayload(payload):GetMessagesPayload +) -> Result { + + let pool = state.hotel_pools.get_pool(hotel_id); + + let conn = pool.get() + .map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Pool error".to_string()))?; + + let from_time = match payload.timestamp.as_deref() { + Some("0") | None => "1970-01-01 00:00:00", // default to epoch + Some(ts) => ts, + }; + + let mut stmt = conn.prepare( + "SELECT id, sender_id, content, sent_at + FROM message + WHERE conversation_id = ?1 + AND sent_at > ?2 + ORDER BY sent_at DESC + LIMIT 50" + ).map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Prepare failed".to_string()))?; + + + let messages = stmt.query_map( + params![payload.conv_id, from_time], + |row| { + Ok(Message { + id: row.get(0)?, + sender_id: row.get(1)?, + content: row.get(2)?, + sent_at: row.get(3)?, + }) + } + ).map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Query failed".to_string()))? + .collect::, _>>() + .map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Collect failed".to_string()))?; + + Ok((StatusCode::OK, serde_json::to_string(&messages).unwrap())) + } \ No newline at end of file diff --git a/src/chat/routes.rs b/src/chat/routes.rs index 534dfb0..ca3f7af 100644 --- a/src/chat/routes.rs +++ b/src/chat/routes.rs @@ -1,12 +1,13 @@ use axum::{ Router, routing::put, - routing::post + routing::post, + routing::get, }; use crate::utils::db_pool::AppState; use crate::chat::handlers::{ - create_conversation,add_user_to_conv,send_message + create_conversation,add_user_to_conv,send_message,get_message }; @@ -19,5 +20,6 @@ pub fn chat_routes() -> Router { .route("/create_conversation", post (create_conversation)) .route("/add_users_conv", put(add_user_to_conv)) .route("/send_message", post(send_message)) + .route("/get_message", get(get_message)) } \ No newline at end of file