refactor: Refactor chat request and response
Signed-off-by: Awiteb <a@4rs.nl>
This commit is contained in:
parent
d1ca5c0a48
commit
476bffb37b
2 changed files with 81 additions and 31 deletions
|
@ -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::<bool>::None)),
|
||||
)
|
||||
.one(self)
|
||||
.await?
|
||||
.map(IntoActiveModel::into_active_model)
|
||||
{
|
||||
user.delete(self).await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<ServerEvent<Unsigned>> {
|
||||
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<ServerEvent<Unsigned>> {
|
||||
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 {
|
||||
|
|
Loading…
Reference in a new issue