feat: Chat request implementation #14
3 changed files with 34 additions and 37 deletions
|
@ -35,13 +35,15 @@
|
||||||
/// [`Err`]: std::result::Result::Err
|
/// [`Err`]: std::result::Result::Err
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! try_ws {
|
macro_rules! try_ws {
|
||||||
($result_expr:expr) => {
|
(Some $result_expr:expr) => {
|
||||||
match $result_expr {
|
match $result_expr {
|
||||||
Ok(val) => val,
|
Ok(val) => val,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
log::error!("{err}");
|
log::error!("{err}");
|
||||||
return $crate::websocket::ServerEvent::<$crate::websocket::Unsigned>::from(
|
return Some(
|
||||||
|
$crate::websocket::ServerEvent::<$crate::websocket::Unsigned>::from(
|
||||||
$crate::websocket::errors::WsError::from(err),
|
$crate::websocket::errors::WsError::from(err),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,45 +35,42 @@ pub async fn handle_chat_request(
|
||||||
db: &DatabaseConnection,
|
db: &DatabaseConnection,
|
||||||
from: Option<&UserModel>,
|
from: Option<&UserModel>,
|
||||||
to_public_key: &PublicKey,
|
to_public_key: &PublicKey,
|
||||||
) -> ServerEvent<Unsigned> {
|
) -> Option<ServerEvent<Unsigned>> {
|
||||||
let Some(from_user) = from else {
|
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 {
|
let Some(to_user) = try_ws!(Some db.get_user_by_pubk(to_public_key).await) else {
|
||||||
return WsError::UserNotFound.into();
|
return Some(WsError::UserNotFound.into());
|
||||||
};
|
};
|
||||||
if from_user.id == to_user.id {
|
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
|
// 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");
|
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) {
|
if try_ws!(Some db.have_chat_request_to(from_user, to_public_key).await).is_some() {
|
||||||
return ServerEvent::message(
|
return Some(WsError::AlreadySendChatRequest.into());
|
||||||
"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.");
|
|
||||||
}
|
}
|
||||||
awiteb marked this conversation as resolved
|
|||||||
|
|
||||||
try_ws!(db.add_to_whitelist(from_user, to_public_key).await);
|
if try_ws!(Some db.is_blacklisted(&to_user, &from_public_key).await) {
|
||||||
|
return Some(WsError::RecipientBlacklist.into());
|
||||||
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.",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
if let Some(conn_id) = ONLINE_USERS.is_online(to_public_key).await {
|
||||||
ONLINE_USERS
|
ONLINE_USERS
|
||||||
.send(&conn_id, ServerEvent::chat_request(&from_public_key))
|
.send(&conn_id, ServerEvent::chat_request(&from_public_key))
|
||||||
.await;
|
.await;
|
||||||
} else {
|
} 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(
|
pub async fn handle_chat_response(
|
||||||
|
@ -81,28 +78,28 @@ pub async fn handle_chat_response(
|
||||||
recipient: Option<&UserModel>,
|
recipient: Option<&UserModel>,
|
||||||
sender_public_key: &PublicKey,
|
sender_public_key: &PublicKey,
|
||||||
accepted: bool,
|
accepted: bool,
|
||||||
) -> ServerEvent<Unsigned> {
|
) -> Option<ServerEvent<Unsigned>> {
|
||||||
let Some(recipient_user) = recipient else {
|
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 {
|
let Some(sender_user) = try_ws!(Some db.get_user_by_pubk(sender_public_key).await) else {
|
||||||
return WsError::UserNotFound.into();
|
return Some(WsError::UserNotFound.into());
|
||||||
};
|
};
|
||||||
if recipient_user.id == sender_user.id {
|
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
|
// FIXME: When change the entity public key to a PublicKey type, change this
|
||||||
let recipient_public_key =
|
let recipient_public_key =
|
||||||
PublicKey::from_str(&recipient_user.public_key).expect("Is valid 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)
|
db.have_chat_request_to(&sender_user, &recipient_public_key)
|
||||||
.await
|
.await
|
||||||
)
|
)
|
||||||
.is_none()
|
.is_none()
|
||||||
{
|
{
|
||||||
return WsError::NoChatRequestFromRecipient.into();
|
return Some(WsError::NoChatRequestFromRecipient.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(conn_id) = ONLINE_USERS.is_online(sender_public_key).await {
|
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
|
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)
|
db.remove_out_chat_request(&sender_user, &recipient_public_key)
|
||||||
.await
|
.await
|
||||||
);
|
);
|
||||||
|
|
||||||
ServerEvent::message("Chat request response sent successfully.")
|
None
|
||||||
}
|
}
|
||||||
|
|
|
@ -216,11 +216,9 @@ async fn handle_events(
|
||||||
ONLINE_USERS.update_pong(conn_id).await;
|
ONLINE_USERS.update_pong(conn_id).await;
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
ClientEventType::ChatRequest { to } => {
|
ClientEventType::ChatRequest { to } => handlers::handle_chat_request(db, user, to).await,
|
||||||
Some(handlers::handle_chat_request(db, user, to).await)
|
|
||||||
}
|
|
||||||
ClientEventType::ChatRequestResponse { to, accepted } => {
|
ClientEventType::ChatRequestResponse { to, accepted } => {
|
||||||
Some(handlers::handle_chat_response(db, user, to, *accepted).await)
|
handlers::handle_chat_response(db, user, to, *accepted).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue
Maybe would be better to move this to
WsError
easier to manage errorsthere are also others below this
Right, this should be an error, not a message. I don't know how is this happened
I'll remove
Message
event it is actually useless. 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.