From 476bffb37b8ed2256512b017f6a5eba2740f5d81 Mon Sep 17 00:00:00 2001
From: Awiteb
Date: Sun, 28 Jul 2024 12:03:57 +0300
Subject: [PATCH] refactor: Refactor chat request and response
Signed-off-by: Awiteb
---
.../oxidetalis/src/database/incoming_chat.rs | 42 +++++++++--
.../src/websocket/handlers/chat_request.rs | 70 ++++++++++++-------
2 files changed, 81 insertions(+), 31 deletions(-)
diff --git a/crates/oxidetalis/src/database/incoming_chat.rs b/crates/oxidetalis/src/database/incoming_chat.rs
index 17f7a88..60a3308 100644
--- a/crates/oxidetalis/src/database/incoming_chat.rs
+++ b/crates/oxidetalis/src/database/incoming_chat.rs
@@ -25,11 +25,18 @@ use crate::errors::ServerResult;
/// Extension trait for the `incoming_chat` table.
pub trait IncomingChatExt {
- /// Save the chat request in the recipient table
+ /// Save the incoming chat request
async fn save_in_chat_request(
&self,
- requester: &PublicKey,
- recipient: &UserModel,
+ chat_request_recipient: &UserModel,
+ chat_request_sender: &PublicKey,
+ ) -> ServerResult<()>;
+
+ /// Remove incoming chat request
+ async fn remove_in_chat_request(
+ &self,
+ chat_request_recipient: &UserModel,
+ chat_request_sender: &PublicKey,
) -> ServerResult<()>;
}
@@ -37,12 +44,12 @@ impl IncomingChatExt for DatabaseConnection {
#[logcall::logcall]
async fn save_in_chat_request(
&self,
- sender: &PublicKey,
- recipient: &UserModel,
+ chat_request_recipient: &UserModel,
+ chat_request_sender: &PublicKey,
) -> ServerResult<()> {
IncomingChatEntity::insert(IncomingChatActiveModel {
- recipient_id: Set(recipient.id),
- sender: Set(*sender),
+ recipient_id: Set(chat_request_recipient.id),
+ sender: Set(*chat_request_sender),
received_timestamp: Set(Utc::now()),
..Default::default()
})
@@ -59,4 +66,25 @@ impl IncomingChatExt for DatabaseConnection {
.await?;
Ok(())
}
+
+ async fn remove_in_chat_request(
+ &self,
+ chat_request_recipient: &UserModel,
+ chat_request_sender: &PublicKey,
+ ) -> ServerResult<()> {
+ if let Some(user) = chat_request_recipient
+ .find_related(IncomingChatEntity)
+ .filter(
+ IncomingChatColumn::Sender
+ .eq(chat_request_sender)
+ .and(IncomingChatColumn::AcceptedResponse.eq(Option::::None)),
+ )
+ .one(self)
+ .await?
+ .map(IntoActiveModel::into_active_model)
+ {
+ user.delete(self).await?;
+ }
+ Ok(())
+ }
}
diff --git a/crates/oxidetalis/src/websocket/handlers/chat_request.rs b/crates/oxidetalis/src/websocket/handlers/chat_request.rs
index 77d6ade..448f481 100644
--- a/crates/oxidetalis/src/websocket/handlers/chat_request.rs
+++ b/crates/oxidetalis/src/websocket/handlers/chat_request.rs
@@ -33,44 +33,58 @@ use crate::{
#[logcall::logcall]
pub async fn handle_chat_request(
db: &DatabaseConnection,
- from: Option<&UserModel>,
- to_public_key: &PublicKey,
+ chat_request_sender: Option<&UserModel>,
+ chat_request_recipient: &PublicKey,
) -> Option> {
- let Some(from_user) = from else {
+ let Some(chat_request_sender) = chat_request_sender else {
return Some(WsError::RegistredUserEvent.into());
};
- let Some(to_user) = try_ws!(Some db.get_user_by_pubk(to_public_key).await) else {
+ let Some(chat_request_recipient) =
+ try_ws!(Some db.get_user_by_pubk(chat_request_recipient).await)
+ else {
return Some(WsError::UserNotFound.into());
};
- if from_user.id == to_user.id {
+ if chat_request_sender.id == chat_request_recipient.id {
return Some(WsError::CannotSendChatRequestToSelf.into());
}
- if try_ws!(Some db.get_chat_request_to(from_user, to_public_key).await).is_some() {
+ if try_ws!(Some db.get_chat_request_to(chat_request_sender, &chat_request_recipient.public_key).await).is_some() {
return Some(WsError::AlreadySendChatRequest.into());
}
- if try_ws!(Some db.is_blacklisted(&to_user, &from_user.public_key).await) {
+ if try_ws!(Some db.is_blacklisted(&chat_request_recipient, &chat_request_sender.public_key).await)
+ {
return Some(WsError::RecipientBlacklist.into());
}
// To ignore the error if the requester added the recipient to the whitelist
// table before send a request to them
- if let Err(ServerError::Internal(_)) = db.add_to_whitelist(from_user, to_public_key).await {
+ if let Err(ServerError::Internal(_)) = db
+ .add_to_whitelist(chat_request_sender, &chat_request_recipient.public_key)
+ .await
+ {
return Some(WsError::InternalServerError.into());
}
- if try_ws!(Some db.is_whitelisted(&to_user, &from_user.public_key).await) {
+ if try_ws!(Some db.is_whitelisted(&chat_request_recipient, &chat_request_sender.public_key).await)
+ {
return Some(WsError::AlreadyInRecipientWhitelist.into());
}
- try_ws!(Some db.save_out_chat_request(from_user, to_public_key).await);
- if let Some(conn_id) = ONLINE_USERS.is_online(to_public_key).await {
+ try_ws!(Some db.save_out_chat_request(chat_request_sender, &chat_request_recipient.public_key).await);
+
+ if let Some(conn_id) = ONLINE_USERS
+ .is_online(&chat_request_recipient.public_key)
+ .await
+ {
ONLINE_USERS
- .send(&conn_id, ServerEvent::chat_request(&from_user.public_key))
+ .send(
+ &conn_id,
+ ServerEvent::chat_request(&chat_request_sender.public_key),
+ )
.await;
} else {
- try_ws!(Some db.save_in_chat_request(&from_user.public_key, &to_user).await);
+ try_ws!(Some db.save_in_chat_request(&chat_request_recipient, &chat_request_sender.public_key).await);
}
None
}
@@ -78,22 +92,25 @@ pub async fn handle_chat_request(
#[logcall::logcall]
pub async fn handle_chat_response(
db: &DatabaseConnection,
- recipient: Option<&UserModel>,
- sender_public_key: &PublicKey,
+ response_sender: Option<&UserModel>,
+ response_recipient: &PublicKey,
accepted: bool,
) -> Option> {
- let Some(recipient_user) = recipient else {
+ let Some(response_sender) = response_sender else {
return Some(WsError::RegistredUserEvent.into());
};
- let Some(sender_user) = try_ws!(Some db.get_user_by_pubk(sender_public_key).await) else {
+
+ let Some(response_recipient) = try_ws!(Some db.get_user_by_pubk(response_recipient).await)
+ else {
return Some(WsError::UserNotFound.into());
};
- if recipient_user.id == sender_user.id {
+
+ if response_sender.id == response_recipient.id {
return Some(WsError::CannotRespondToOwnChatRequest.into());
}
if try_ws!(Some
- db.get_chat_request_to(&sender_user, &recipient_user.public_key)
+ db.get_chat_request_to(&response_recipient, &response_sender.public_key)
.await
)
.is_none()
@@ -104,21 +121,26 @@ pub async fn handle_chat_response(
// We don't need to handle the case where the sender is blacklisted or
// whitelisted already, just add it if it is not already there
let _ = if accepted {
- db.add_to_whitelist(recipient_user, sender_public_key).await
+ db.add_to_whitelist(response_sender, &response_recipient.public_key)
+ .await
} else {
- db.add_to_blacklist(recipient_user, sender_public_key).await
+ db.add_to_blacklist(response_sender, &response_recipient.public_key)
+ .await
};
try_ws!(Some
- db.remove_out_chat_request(&sender_user, &recipient_user.public_key)
+ db.remove_out_chat_request(&response_recipient, &response_sender.public_key)
.await
);
+ try_ws!(Some
+ db.remove_in_chat_request(response_sender, &response_recipient.public_key).await
+ );
- if let Some(conn_id) = ONLINE_USERS.is_online(sender_public_key).await {
+ if let Some(conn_id) = ONLINE_USERS.is_online(&response_recipient.public_key).await {
ONLINE_USERS
.send(
&conn_id,
- ServerEvent::chat_request_response(recipient_user.public_key, accepted),
+ ServerEvent::chat_request_response(response_sender.public_key, accepted),
)
.await;
} else {