feat: Chat request implementation #14

Manually merged
awiteb merged 55 commits from awiteb/chat-request-and-response into master 2024-07-18 14:21:39 +02:00 AGit
3 changed files with 34 additions and 37 deletions
Showing only changes of commit 09f90b060f - Show all commits

View file

@ -35,13 +35,15 @@
/// [`Err`]: std::result::Result::Err
#[macro_export]
macro_rules! try_ws {
($result_expr:expr) => {
(Some $result_expr:expr) => {
match $result_expr {
Ok(val) => val,
Err(err) => {
log::error!("{err}");
return $crate::websocket::ServerEvent::<$crate::websocket::Unsigned>::from(
$crate::websocket::errors::WsError::from(err),
return Some(
$crate::websocket::ServerEvent::<$crate::websocket::Unsigned>::from(
$crate::websocket::errors::WsError::from(err),
),
);
}
}

View file

@ -35,45 +35,42 @@ pub async fn handle_chat_request(
db: &DatabaseConnection,
from: Option<&UserModel>,
to_public_key: &PublicKey,
) -> ServerEvent<Unsigned> {
) -> Option<ServerEvent<Unsigned>> {
let Some(from_user) = from else {
return WsError::RegistredUserEvent.into();
return Some(WsError::RegistredUserEvent.into());
};
let Some(to_user) = try_ws!(db.get_user_by_pubk(to_public_key).await) else {
return WsError::UserNotFound.into();
let Some(to_user) = try_ws!(Some db.get_user_by_pubk(to_public_key).await) else {
return Some(WsError::UserNotFound.into());
};
if from_user.id == to_user.id {
return WsError::CannotSendChatRequestToSelf.into();
return Some(WsError::CannotSendChatRequestToSelf.into());
}
// FIXME: When change the entity public key to a PublicKey type, change this
let from_public_key = PublicKey::from_str(&from_user.public_key).expect("Is valid public key");
if try_ws!(db.is_blacklisted(&to_user, &from_public_key).await) {
return ServerEvent::message(
"You are unable to send a chat request because you are on the recipient's blacklist.",
);
}
if try_ws!(db.have_chat_request_to(from_user, to_public_key).await).is_some() {
return ServerEvent::message("You have already sent a chat request to this user.");
if try_ws!(Some db.have_chat_request_to(from_user, to_public_key).await).is_some() {
return Some(WsError::AlreadySendChatRequest.into());
}
awiteb marked this conversation as resolved
Review

Maybe would be better to move this to WsError easier to manage errors
there are also others below this

Maybe would be better to move this to `WsError` easier to manage errors there are also others below this
Review

Right, this should be an error, not a message. I don't know how is this happened

Right, this should be an error, not a message. I don't know how is this happened
Review

I'll remove Message event it is actually useless. I don't know why I thought it was good.

I'll remove `Message` event it is actually useless. I don't know why I thought it was good.
Review

I don't know why I thought it was good.

Well, I remembered when I added it, it was a pain to add a new error (before ws_error macro) so I thought it was good for simple messages.

> I don't know why I thought it was good. Well, I remembered when I added it, it was a pain to add a new error (before `ws_error` macro) so I thought it was good for simple messages.
try_ws!(db.add_to_whitelist(from_user, to_public_key).await);
if try_ws!(db.is_whitelisted(&to_user, &from_public_key).await) {
return ServerEvent::message(
"You are already on the recipient's whitelist, so you can now chat with them.",
);
if try_ws!(Some db.is_blacklisted(&to_user, &from_public_key).await) {
return Some(WsError::RecipientBlacklist.into());
}
try_ws!(db.save_out_chat_request(from_user, to_public_key).await);
try_ws!(Some db.add_to_whitelist(from_user, to_public_key).await);
if try_ws!(Some db.is_whitelisted(&to_user, &from_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 {
ONLINE_USERS
.send(&conn_id, ServerEvent::chat_request(&from_public_key))
.await;
} else {
try_ws!(db.save_in_chat_request(&from_public_key, &to_user).await);
try_ws!(Some db.save_in_chat_request(&from_public_key, &to_user).await);
}
ServerEvent::message("Chat request sent successfully.")
None
}
pub async fn handle_chat_response(
@ -81,28 +78,28 @@ pub async fn handle_chat_response(
recipient: Option<&UserModel>,
sender_public_key: &PublicKey,
accepted: bool,
) -> ServerEvent<Unsigned> {
) -> Option<ServerEvent<Unsigned>> {
let Some(recipient_user) = recipient else {
return WsError::RegistredUserEvent.into();
return Some(WsError::RegistredUserEvent.into());
};
let Some(sender_user) = try_ws!(db.get_user_by_pubk(sender_public_key).await) else {
return WsError::UserNotFound.into();
let Some(sender_user) = try_ws!(Some db.get_user_by_pubk(sender_public_key).await) else {
return Some(WsError::UserNotFound.into());
};
if recipient_user.id == sender_user.id {
return WsError::CannotRespondToOwnChatRequest.into();
return Some(WsError::CannotRespondToOwnChatRequest.into());
}
// FIXME: When change the entity public key to a PublicKey type, change this
let recipient_public_key =
PublicKey::from_str(&recipient_user.public_key).expect("Is valid public key");
if try_ws!(
if try_ws!(Some
db.have_chat_request_to(&sender_user, &recipient_public_key)
.await
)
.is_none()
{
return WsError::NoChatRequestFromRecipient.into();
return Some(WsError::NoChatRequestFromRecipient.into());
}
if let Some(conn_id) = ONLINE_USERS.is_online(sender_public_key).await {
@ -125,10 +122,10 @@ pub async fn handle_chat_response(
db.add_to_blacklist(recipient_user, sender_public_key).await
};
try_ws!(
try_ws!(Some
db.remove_out_chat_request(&sender_user, &recipient_public_key)
.await
);
ServerEvent::message("Chat request response sent successfully.")
None
}

View file

@ -216,11 +216,9 @@ async fn handle_events(
ONLINE_USERS.update_pong(conn_id).await;
None
}
ClientEventType::ChatRequest { to } => {
Some(handlers::handle_chat_request(db, user, to).await)
}
ClientEventType::ChatRequest { to } => handlers::handle_chat_request(db, user, to).await,
ClientEventType::ChatRequestResponse { to, accepted } => {
Some(handlers::handle_chat_response(db, user, to, *accepted).await)
handlers::handle_chat_response(db, user, to, *accepted).await
}
}
}