From 02744444346fd0ad535e00f1dd6fb1cfbe37dba6 Mon Sep 17 00:00:00 2001
From: Awiteb
Date: Sun, 28 Jul 2024 10:36:05 +0300
Subject: [PATCH 1/7] refactor: Rename `in_chat_requests` table to
`incoming_chat`
Signed-off-by: Awiteb
---
.../{in_chat_requests.rs => incoming_chat.rs} | 19 ++++++--------
crates/oxidetalis/src/database/mod.rs | 4 +--
.../src/websocket/handlers/chat_request.rs | 2 +-
...ming_chat_requests.rs => incoming_chat.rs} | 4 +--
crates/oxidetalis_entities/src/lib.rs | 2 +-
crates/oxidetalis_entities/src/prelude.rs | 10 +++----
crates/oxidetalis_entities/src/users.rs | 8 +++---
...table.rs => create_incoming_chat_table.rs} | 26 +++++++++----------
crates/oxidetalis_migrations/src/lib.rs | 4 +--
9 files changed, 38 insertions(+), 41 deletions(-)
rename crates/oxidetalis/src/database/{in_chat_requests.rs => incoming_chat.rs} (77%)
rename crates/oxidetalis_entities/src/{incoming_chat_requests.rs => incoming_chat.rs} (96%)
rename crates/oxidetalis_migrations/src/{create_incoming_chat_requests_table.rs => create_incoming_chat_table.rs} (78%)
diff --git a/crates/oxidetalis/src/database/in_chat_requests.rs b/crates/oxidetalis/src/database/incoming_chat.rs
similarity index 77%
rename from crates/oxidetalis/src/database/in_chat_requests.rs
rename to crates/oxidetalis/src/database/incoming_chat.rs
index 10c150a..2a6dbba 100644
--- a/crates/oxidetalis/src/database/in_chat_requests.rs
+++ b/crates/oxidetalis/src/database/incoming_chat.rs
@@ -14,7 +14,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-//! Database extension for the `in_chat_requests` table.
+//! Database extension for the `incoming_chat` table.
use chrono::Utc;
use oxidetalis_core::types::PublicKey;
@@ -23,8 +23,8 @@ use sea_orm::{sea_query::OnConflict, DatabaseConnection};
use crate::errors::ServerResult;
-/// Extension trait for the `in_chat_requests` table.
-pub trait InChatRequestsExt {
+/// Extension trait for the `incoming_chat` table.
+pub trait IncomingChatExt {
/// Save the chat request in the recipient table
async fn save_in_chat_request(
&self,
@@ -33,26 +33,23 @@ pub trait InChatRequestsExt {
) -> ServerResult<()>;
}
-impl InChatRequestsExt for DatabaseConnection {
+impl IncomingChatExt for DatabaseConnection {
#[logcall::logcall]
async fn save_in_chat_request(
&self,
sender: &PublicKey,
recipient: &UserModel,
) -> ServerResult<()> {
- InChatRequestsEntity::insert(InChatRequestsActiveModel {
+ IncomingChatEntity::insert(IncomingChatActiveModel {
recipient_id: Set(recipient.id),
sender: Set(*sender),
in_on: Set(Utc::now()),
..Default::default()
})
.on_conflict(
- OnConflict::columns([
- InChatRequestsColumn::RecipientId,
- InChatRequestsColumn::Sender,
- ])
- .do_nothing()
- .to_owned(),
+ OnConflict::columns([IncomingChatColumn::RecipientId, IncomingChatColumn::Sender])
+ .do_nothing()
+ .to_owned(),
)
.exec(self)
.await?;
diff --git a/crates/oxidetalis/src/database/mod.rs b/crates/oxidetalis/src/database/mod.rs
index 8d51890..ec51210 100644
--- a/crates/oxidetalis/src/database/mod.rs
+++ b/crates/oxidetalis/src/database/mod.rs
@@ -16,12 +16,12 @@
//! Database trait extensions.
-mod in_chat_requests;
+mod incoming_chat;
mod out_chat_requests;
mod user;
mod user_status;
-pub use in_chat_requests::*;
+pub use incoming_chat::*;
pub use out_chat_requests::*;
pub use user::*;
pub use user_status::*;
diff --git a/crates/oxidetalis/src/websocket/handlers/chat_request.rs b/crates/oxidetalis/src/websocket/handlers/chat_request.rs
index 222137a..77d6ade 100644
--- a/crates/oxidetalis/src/websocket/handlers/chat_request.rs
+++ b/crates/oxidetalis/src/websocket/handlers/chat_request.rs
@@ -20,7 +20,7 @@ use oxidetalis_core::types::PublicKey;
use oxidetalis_entities::prelude::*;
use sea_orm::DatabaseConnection;
-use crate::database::InChatRequestsExt;
+use crate::database::IncomingChatExt;
use crate::errors::ServerError;
use crate::extensions::OnlineUsersExt;
use crate::{
diff --git a/crates/oxidetalis_entities/src/incoming_chat_requests.rs b/crates/oxidetalis_entities/src/incoming_chat.rs
similarity index 96%
rename from crates/oxidetalis_entities/src/incoming_chat_requests.rs
rename to crates/oxidetalis_entities/src/incoming_chat.rs
index ed6ff3c..e93fd8a 100644
--- a/crates/oxidetalis_entities/src/incoming_chat_requests.rs
+++ b/crates/oxidetalis_entities/src/incoming_chat.rs
@@ -19,7 +19,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
-//! Entity for `in_chat_requests` table
+//! Entity for `incoming_chat` table
use chrono::Utc;
use oxidetalis_core::types::PublicKey;
@@ -28,7 +28,7 @@ use sea_orm::entity::prelude::*;
use crate::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
-#[sea_orm(table_name = "in_chat_requests")]
+#[sea_orm(table_name = "incoming_chat")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: UserId,
diff --git a/crates/oxidetalis_entities/src/lib.rs b/crates/oxidetalis_entities/src/lib.rs
index ba83d45..2df1d8e 100644
--- a/crates/oxidetalis_entities/src/lib.rs
+++ b/crates/oxidetalis_entities/src/lib.rs
@@ -21,7 +21,7 @@
#![doc = include_str!("../README.md")]
-pub mod incoming_chat_requests;
+pub mod incoming_chat;
pub mod outgoing_chat_requests;
pub mod prelude;
pub mod users;
diff --git a/crates/oxidetalis_entities/src/prelude.rs b/crates/oxidetalis_entities/src/prelude.rs
index 4bdd679..a4e5d64 100644
--- a/crates/oxidetalis_entities/src/prelude.rs
+++ b/crates/oxidetalis_entities/src/prelude.rs
@@ -40,11 +40,11 @@ pub use sea_orm::{
/// User ID type
pub type UserId = i64;
-pub use super::incoming_chat_requests::{
- ActiveModel as InChatRequestsActiveModel,
- Column as InChatRequestsColumn,
- Entity as InChatRequestsEntity,
- Model as InChatRequestsModel,
+pub use super::incoming_chat::{
+ ActiveModel as IncomingChatActiveModel,
+ Column as IncomingChatColumn,
+ Entity as IncomingChatEntity,
+ Model as IncomingChatModel,
};
pub use super::outgoing_chat_requests::{
ActiveModel as OutChatRequestsActiveModel,
diff --git a/crates/oxidetalis_entities/src/users.rs b/crates/oxidetalis_entities/src/users.rs
index 8489585..b3a0f81 100644
--- a/crates/oxidetalis_entities/src/users.rs
+++ b/crates/oxidetalis_entities/src/users.rs
@@ -39,17 +39,17 @@ pub struct Model {
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
- #[sea_orm(has_many = "InChatRequestsEntity")]
- InChatRequests,
+ #[sea_orm(has_many = "IncomingChatEntity")]
+ IncomingChat,
#[sea_orm(has_many = "OutChatRequestsEntity")]
OutChatRequests,
#[sea_orm(has_many = "UsersStatusEntity")]
UsersStatus,
}
-impl Related for Entity {
+impl Related for Entity {
fn to() -> RelationDef {
- Relation::InChatRequests.def()
+ Relation::IncomingChat.def()
}
}
diff --git a/crates/oxidetalis_migrations/src/create_incoming_chat_requests_table.rs b/crates/oxidetalis_migrations/src/create_incoming_chat_table.rs
similarity index 78%
rename from crates/oxidetalis_migrations/src/create_incoming_chat_requests_table.rs
rename to crates/oxidetalis_migrations/src/create_incoming_chat_table.rs
index 3cd6fed..0dc03f5 100644
--- a/crates/oxidetalis_migrations/src/create_incoming_chat_requests_table.rs
+++ b/crates/oxidetalis_migrations/src/create_incoming_chat_table.rs
@@ -19,8 +19,8 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
-//! Migration to create the `in_chat_requests` table, a table for incoming chat
-//! requests from other users
+//! Migration to create the `incoming_chat` table, a table for incoming chat
+//! requests and responses from other users
use sea_orm_migration::prelude::*;
@@ -35,31 +35,31 @@ impl MigrationTrait for Migration {
manager
.create_table(
Table::create()
- .table(InChatRequests::Table)
+ .table(IncomingChat::Table)
.if_not_exists()
.col(
- ColumnDef::new(InChatRequests::Id)
+ ColumnDef::new(IncomingChat::Id)
.big_integer()
.not_null()
.auto_increment()
.primary_key(),
)
.col(
- ColumnDef::new(InChatRequests::RecipientId)
+ ColumnDef::new(IncomingChat::RecipientId)
.big_integer()
.not_null(),
)
.foreign_key(
ForeignKey::create()
- .name("fk-in_chat_requests-users")
- .from(InChatRequests::Table, InChatRequests::RecipientId)
+ .name("fk-incoming_chat-users")
+ .from(IncomingChat::Table, IncomingChat::RecipientId)
.to(Users::Table, Users::Id)
.on_update(ForeignKeyAction::NoAction)
.on_delete(ForeignKeyAction::Cascade),
)
- .col(ColumnDef::new(InChatRequests::Sender).binary().not_null())
+ .col(ColumnDef::new(IncomingChat::Sender).binary().not_null())
.col(
- ColumnDef::new(InChatRequests::InOn)
+ ColumnDef::new(IncomingChat::InOn)
.timestamp_with_time_zone()
.not_null(),
)
@@ -71,9 +71,9 @@ impl MigrationTrait for Migration {
Index::create()
.if_not_exists()
.name("sep_request")
- .table(InChatRequests::Table)
- .col(InChatRequests::RecipientId)
- .col(InChatRequests::Sender)
+ .table(IncomingChat::Table)
+ .col(IncomingChat::RecipientId)
+ .col(IncomingChat::Sender)
.unique()
.to_owned(),
)
@@ -82,7 +82,7 @@ impl MigrationTrait for Migration {
}
#[derive(DeriveIden)]
-enum InChatRequests {
+enum IncomingChat {
Table,
Id,
RecipientId,
diff --git a/crates/oxidetalis_migrations/src/lib.rs b/crates/oxidetalis_migrations/src/lib.rs
index b36dd83..56603d3 100644
--- a/crates/oxidetalis_migrations/src/lib.rs
+++ b/crates/oxidetalis_migrations/src/lib.rs
@@ -24,7 +24,7 @@
use sea_orm_migration::prelude::*;
pub use sea_orm_migration::MigratorTrait;
-mod create_incoming_chat_requests_table;
+mod create_incoming_chat_table;
mod create_outgoing_chat_requests_table;
mod create_users_status;
mod create_users_table;
@@ -36,7 +36,7 @@ impl MigratorTrait for Migrator {
fn migrations() -> Vec> {
vec![
Box::new(create_users_table::Migration),
- Box::new(create_incoming_chat_requests_table::Migration),
+ Box::new(create_incoming_chat_table::Migration),
Box::new(create_outgoing_chat_requests_table::Migration),
Box::new(create_users_status::Migration),
]
--
2.45.2
From f0383296dee88533581e1453a59a6e612231a1ec Mon Sep 17 00:00:00 2001
From: Awiteb
Date: Sun, 28 Jul 2024 10:40:04 +0300
Subject: [PATCH 2/7] change: Rename `UserId` to `IdCol` and make it private
Signed-off-by: Awiteb
---
crates/oxidetalis_entities/src/incoming_chat.rs | 4 ++--
crates/oxidetalis_entities/src/outgoing_chat_requests.rs | 4 ++--
crates/oxidetalis_entities/src/prelude.rs | 2 +-
crates/oxidetalis_entities/src/users.rs | 2 +-
crates/oxidetalis_entities/src/users_status.rs | 4 ++--
5 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/crates/oxidetalis_entities/src/incoming_chat.rs b/crates/oxidetalis_entities/src/incoming_chat.rs
index e93fd8a..709bb1a 100644
--- a/crates/oxidetalis_entities/src/incoming_chat.rs
+++ b/crates/oxidetalis_entities/src/incoming_chat.rs
@@ -31,8 +31,8 @@ use crate::prelude::*;
#[sea_orm(table_name = "incoming_chat")]
pub struct Model {
#[sea_orm(primary_key)]
- pub id: UserId,
- pub recipient_id: UserId,
+ pub id: IdCol,
+ pub recipient_id: IdCol,
/// Public key of the sender
pub sender: PublicKey,
/// The timestamp of the request, when it was received
diff --git a/crates/oxidetalis_entities/src/outgoing_chat_requests.rs b/crates/oxidetalis_entities/src/outgoing_chat_requests.rs
index 2f5642c..8e00c3b 100644
--- a/crates/oxidetalis_entities/src/outgoing_chat_requests.rs
+++ b/crates/oxidetalis_entities/src/outgoing_chat_requests.rs
@@ -31,8 +31,8 @@ use crate::prelude::*;
#[sea_orm(table_name = "out_chat_requests")]
pub struct Model {
#[sea_orm(primary_key)]
- pub id: UserId,
- pub sender_id: UserId,
+ pub id: IdCol,
+ pub sender_id: IdCol,
/// Public key of the recipient
pub recipient: PublicKey,
/// The timestamp of the request, when it was sent
diff --git a/crates/oxidetalis_entities/src/prelude.rs b/crates/oxidetalis_entities/src/prelude.rs
index a4e5d64..d5cb22f 100644
--- a/crates/oxidetalis_entities/src/prelude.rs
+++ b/crates/oxidetalis_entities/src/prelude.rs
@@ -38,7 +38,7 @@ pub use sea_orm::{
};
/// User ID type
-pub type UserId = i64;
+pub(crate) type IdCol = i64;
pub use super::incoming_chat::{
ActiveModel as IncomingChatActiveModel,
diff --git a/crates/oxidetalis_entities/src/users.rs b/crates/oxidetalis_entities/src/users.rs
index b3a0f81..1c59bb6 100644
--- a/crates/oxidetalis_entities/src/users.rs
+++ b/crates/oxidetalis_entities/src/users.rs
@@ -31,7 +31,7 @@ use crate::prelude::*;
#[sea_orm(table_name = "users")]
pub struct Model {
#[sea_orm(primary_key)]
- pub id: UserId,
+ pub id: IdCol,
pub public_key: PublicKey,
pub last_logout: chrono::DateTime,
pub is_admin: bool,
diff --git a/crates/oxidetalis_entities/src/users_status.rs b/crates/oxidetalis_entities/src/users_status.rs
index 2f66883..0559a6e 100644
--- a/crates/oxidetalis_entities/src/users_status.rs
+++ b/crates/oxidetalis_entities/src/users_status.rs
@@ -40,8 +40,8 @@ pub enum AccessStatus {
#[sea_orm(table_name = "users_status")]
pub struct Model {
#[sea_orm(primary_key)]
- pub id: UserId,
- pub user_id: UserId,
+ pub id: IdCol,
+ pub user_id: IdCol,
pub target: PublicKey,
pub status: AccessStatus,
pub updated_at: chrono::DateTime,
--
2.45.2
From c8693eeb3ec11ca5fc11621b201c22e314e79b96 Mon Sep 17 00:00:00 2001
From: Awiteb
Date: Sun, 28 Jul 2024 10:55:04 +0300
Subject: [PATCH 3/7] feat: Add `accepted_response` col to `incoming_chat`
table
Signed-off-by: Awiteb
---
crates/oxidetalis/src/database/incoming_chat.rs | 10 +++++++---
crates/oxidetalis_entities/src/incoming_chat.rs | 11 +++++++----
.../src/create_incoming_chat_table.rs | 9 +++++++++
3 files changed, 23 insertions(+), 7 deletions(-)
diff --git a/crates/oxidetalis/src/database/incoming_chat.rs b/crates/oxidetalis/src/database/incoming_chat.rs
index 2a6dbba..e562199 100644
--- a/crates/oxidetalis/src/database/incoming_chat.rs
+++ b/crates/oxidetalis/src/database/incoming_chat.rs
@@ -47,9 +47,13 @@ impl IncomingChatExt for DatabaseConnection {
..Default::default()
})
.on_conflict(
- OnConflict::columns([IncomingChatColumn::RecipientId, IncomingChatColumn::Sender])
- .do_nothing()
- .to_owned(),
+ OnConflict::columns([
+ IncomingChatColumn::RecipientId,
+ IncomingChatColumn::Sender,
+ IncomingChatColumn::AcceptedResponse,
+ ])
+ .do_nothing()
+ .to_owned(),
)
.exec(self)
.await?;
diff --git a/crates/oxidetalis_entities/src/incoming_chat.rs b/crates/oxidetalis_entities/src/incoming_chat.rs
index 709bb1a..c44393d 100644
--- a/crates/oxidetalis_entities/src/incoming_chat.rs
+++ b/crates/oxidetalis_entities/src/incoming_chat.rs
@@ -31,12 +31,15 @@ use crate::prelude::*;
#[sea_orm(table_name = "incoming_chat")]
pub struct Model {
#[sea_orm(primary_key)]
- pub id: IdCol,
- pub recipient_id: IdCol,
+ pub id: IdCol,
+ pub recipient_id: IdCol,
/// Public key of the sender
- pub sender: PublicKey,
+ pub sender: PublicKey,
+ /// Whether the chat response accepted or not.
+ /// This will be `None` if it is chat request, otherwise `bool`
+ pub accepted_response: Option,
/// The timestamp of the request, when it was received
- pub in_on: chrono::DateTime,
+ pub in_on: chrono::DateTime,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
diff --git a/crates/oxidetalis_migrations/src/create_incoming_chat_table.rs b/crates/oxidetalis_migrations/src/create_incoming_chat_table.rs
index 0dc03f5..87b7083 100644
--- a/crates/oxidetalis_migrations/src/create_incoming_chat_table.rs
+++ b/crates/oxidetalis_migrations/src/create_incoming_chat_table.rs
@@ -58,6 +58,12 @@ impl MigrationTrait for Migration {
.on_delete(ForeignKeyAction::Cascade),
)
.col(ColumnDef::new(IncomingChat::Sender).binary().not_null())
+ .col(
+ ColumnDef::new(IncomingChat::AcceptedResponse)
+ .boolean()
+ .null()
+ .default(Option::::None),
+ )
.col(
ColumnDef::new(IncomingChat::InOn)
.timestamp_with_time_zone()
@@ -74,6 +80,7 @@ impl MigrationTrait for Migration {
.table(IncomingChat::Table)
.col(IncomingChat::RecipientId)
.col(IncomingChat::Sender)
+ .col(IncomingChat::AcceptedResponse)
.unique()
.to_owned(),
)
@@ -88,5 +95,7 @@ enum IncomingChat {
RecipientId,
/// Public key of the sender
Sender,
+ /// Whether the chat response accepted or not
+ AcceptedResponse,
InOn,
}
--
2.45.2
From d1ca5c0a481afe1e8d270d9eb0c9aa48908434c6 Mon Sep 17 00:00:00 2001
From: Awiteb
Date: Sun, 28 Jul 2024 11:07:00 +0300
Subject: [PATCH 4/7] change: Rename `in_on` col of `incoming_chat` table to
`received_timestamp`
Signed-off-by: Awiteb
---
crates/oxidetalis/src/database/incoming_chat.rs | 2 +-
crates/oxidetalis_entities/src/incoming_chat.rs | 10 +++++-----
.../src/create_incoming_chat_table.rs | 4 ++--
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/crates/oxidetalis/src/database/incoming_chat.rs b/crates/oxidetalis/src/database/incoming_chat.rs
index e562199..17f7a88 100644
--- a/crates/oxidetalis/src/database/incoming_chat.rs
+++ b/crates/oxidetalis/src/database/incoming_chat.rs
@@ -43,7 +43,7 @@ impl IncomingChatExt for DatabaseConnection {
IncomingChatEntity::insert(IncomingChatActiveModel {
recipient_id: Set(recipient.id),
sender: Set(*sender),
- in_on: Set(Utc::now()),
+ received_timestamp: Set(Utc::now()),
..Default::default()
})
.on_conflict(
diff --git a/crates/oxidetalis_entities/src/incoming_chat.rs b/crates/oxidetalis_entities/src/incoming_chat.rs
index c44393d..ed2d810 100644
--- a/crates/oxidetalis_entities/src/incoming_chat.rs
+++ b/crates/oxidetalis_entities/src/incoming_chat.rs
@@ -31,15 +31,15 @@ use crate::prelude::*;
#[sea_orm(table_name = "incoming_chat")]
pub struct Model {
#[sea_orm(primary_key)]
- pub id: IdCol,
- pub recipient_id: IdCol,
+ pub id: IdCol,
+ pub recipient_id: IdCol,
/// Public key of the sender
- pub sender: PublicKey,
+ pub sender: PublicKey,
/// Whether the chat response accepted or not.
/// This will be `None` if it is chat request, otherwise `bool`
- pub accepted_response: Option,
+ pub accepted_response: Option,
/// The timestamp of the request, when it was received
- pub in_on: chrono::DateTime,
+ pub received_timestamp: chrono::DateTime,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
diff --git a/crates/oxidetalis_migrations/src/create_incoming_chat_table.rs b/crates/oxidetalis_migrations/src/create_incoming_chat_table.rs
index 87b7083..cdab495 100644
--- a/crates/oxidetalis_migrations/src/create_incoming_chat_table.rs
+++ b/crates/oxidetalis_migrations/src/create_incoming_chat_table.rs
@@ -65,7 +65,7 @@ impl MigrationTrait for Migration {
.default(Option::::None),
)
.col(
- ColumnDef::new(IncomingChat::InOn)
+ ColumnDef::new(IncomingChat::ReceivedTimestamp)
.timestamp_with_time_zone()
.not_null(),
)
@@ -97,5 +97,5 @@ enum IncomingChat {
Sender,
/// Whether the chat response accepted or not
AcceptedResponse,
- InOn,
+ ReceivedTimestamp,
}
--
2.45.2
From 476bffb37b8ed2256512b017f6a5eba2740f5d81 Mon Sep 17 00:00:00 2001
From: Awiteb
Date: Sun, 28 Jul 2024 12:03:57 +0300
Subject: [PATCH 5/7] 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 {
--
2.45.2
From 1249d9c8bf2b0de2c3ab0e04a9a43a981c5f5ef4 Mon Sep 17 00:00:00 2001
From: Awiteb
Date: Mon, 29 Jul 2024 14:01:27 +0300
Subject: [PATCH 6/7] chore: Remove `remove_in_chat_request` trait function
Signed-off-by: Awiteb
---
.../oxidetalis/src/database/incoming_chat.rs | 27 -------------------
.../src/websocket/handlers/chat_request.rs | 3 ---
2 files changed, 30 deletions(-)
diff --git a/crates/oxidetalis/src/database/incoming_chat.rs b/crates/oxidetalis/src/database/incoming_chat.rs
index 60a3308..72ebaa0 100644
--- a/crates/oxidetalis/src/database/incoming_chat.rs
+++ b/crates/oxidetalis/src/database/incoming_chat.rs
@@ -32,12 +32,6 @@ pub trait IncomingChatExt {
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<()>;
}
impl IncomingChatExt for DatabaseConnection {
@@ -67,24 +61,3 @@ impl IncomingChatExt for DatabaseConnection {
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 448f481..8a9914b 100644
--- a/crates/oxidetalis/src/websocket/handlers/chat_request.rs
+++ b/crates/oxidetalis/src/websocket/handlers/chat_request.rs
@@ -132,9 +132,6 @@ pub async fn handle_chat_response(
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(&response_recipient.public_key).await {
ONLINE_USERS
--
2.45.2
From 9218f205df5e55501fd29eb99b1f4ecf82675d18 Mon Sep 17 00:00:00 2001
From: Awiteb
Date: Mon, 29 Jul 2024 14:02:58 +0300
Subject: [PATCH 7/7] feat: Send chat requests and responses when the user is
online
Signed-off-by: Awiteb
---
.../oxidetalis/src/database/incoming_chat.rs | 115 +++++++++++++++---
.../src/websocket/handlers/chat_request.rs | 5 +-
crates/oxidetalis/src/websocket/mod.rs | 57 ++++++++-
3 files changed, 154 insertions(+), 23 deletions(-)
diff --git a/crates/oxidetalis/src/database/incoming_chat.rs b/crates/oxidetalis/src/database/incoming_chat.rs
index 72ebaa0..fe0c3f5 100644
--- a/crates/oxidetalis/src/database/incoming_chat.rs
+++ b/crates/oxidetalis/src/database/incoming_chat.rs
@@ -32,6 +32,25 @@ pub trait IncomingChatExt {
chat_request_sender: &PublicKey,
) -> ServerResult<()>;
+ /// Returns all incoming chat requests for the given recipient
+ async fn get_all_chat_requests(
+ &self,
+ chat_request_recipient: &UserModel,
+ ) -> ServerResult>;
+
+ /// Save the incoming chat response
+ async fn save_in_chat_response(
+ &self,
+ chat_response_recipient: &UserModel,
+ chat_response_sender: &PublicKey,
+ accepted_response: bool,
+ ) -> ServerResult<()>;
+
+ /// Returns all incoming chat responses for the given recipient
+ async fn get_all_chat_responses(
+ &self,
+ chat_response_recipient: &UserModel,
+ ) -> ServerResult>;
}
impl IncomingChatExt for DatabaseConnection {
@@ -41,23 +60,83 @@ impl IncomingChatExt for DatabaseConnection {
chat_request_recipient: &UserModel,
chat_request_sender: &PublicKey,
) -> ServerResult<()> {
- IncomingChatEntity::insert(IncomingChatActiveModel {
- recipient_id: Set(chat_request_recipient.id),
- sender: Set(*chat_request_sender),
- received_timestamp: Set(Utc::now()),
- ..Default::default()
- })
- .on_conflict(
- OnConflict::columns([
- IncomingChatColumn::RecipientId,
- IncomingChatColumn::Sender,
- IncomingChatColumn::AcceptedResponse,
- ])
- .do_nothing()
- .to_owned(),
- )
- .exec(self)
- .await?;
- Ok(())
+ save(self, chat_request_recipient, chat_request_sender, None).await
}
+ async fn get_all_chat_requests(
+ &self,
+ chat_request_recipient: &UserModel,
+ ) -> ServerResult> {
+ get_all::(self, chat_request_recipient).await
+ }
+
+ #[logcall::logcall]
+ async fn save_in_chat_response(
+ &self,
+ chat_response_recipient: &UserModel,
+ chat_response_sender: &PublicKey,
+ accepted_response: bool,
+ ) -> ServerResult<()> {
+ save(
+ self,
+ chat_response_recipient,
+ chat_response_sender,
+ Some(accepted_response),
+ )
+ .await
+ }
+
+ async fn get_all_chat_responses(
+ &self,
+ chat_response_recipient: &UserModel,
+ ) -> ServerResult> {
+ get_all::(self, chat_response_recipient).await
+ }
+}
+
+/// Utility function to save incoming chat request or response
+async fn save(
+ db: &DatabaseConnection,
+ recipient: &UserModel,
+ sender: &PublicKey,
+ accepted_response: Option,
+) -> ServerResult<()> {
+ IncomingChatEntity::insert(IncomingChatActiveModel {
+ recipient_id: Set(recipient.id),
+ sender: Set(*sender),
+ received_timestamp: Set(Utc::now()),
+ accepted_response: Set(accepted_response),
+ ..Default::default()
+ })
+ .on_conflict(
+ OnConflict::columns([
+ IncomingChatColumn::RecipientId,
+ IncomingChatColumn::Sender,
+ IncomingChatColumn::AcceptedResponse,
+ ])
+ .do_nothing()
+ .to_owned(),
+ )
+ .exec(db)
+ .await?;
+ Ok(())
+}
+
+/// Utility function to get all incoming chat requests or responses
+async fn get_all(
+ db: &DatabaseConnection,
+ recipient: &UserModel,
+) -> ServerResult> {
+ recipient
+ .find_related(IncomingChatEntity)
+ .filter(
+ if IS_REQUEST {
+ IncomingChatColumn::AcceptedResponse.is_null()
+ } else {
+ IncomingChatColumn::AcceptedResponse.is_not_null()
+ },
+ )
+ .all(db)
+ .await
+ .map_err(Into::into)
+}
diff --git a/crates/oxidetalis/src/websocket/handlers/chat_request.rs b/crates/oxidetalis/src/websocket/handlers/chat_request.rs
index 8a9914b..7957dcf 100644
--- a/crates/oxidetalis/src/websocket/handlers/chat_request.rs
+++ b/crates/oxidetalis/src/websocket/handlers/chat_request.rs
@@ -141,8 +141,9 @@ pub async fn handle_chat_response(
)
.await;
} else {
- // TODO: Create a table for chat request responses, and send them when
- // the user logs in
+ try_ws!(Some
+ db.save_in_chat_response(&response_recipient, &response_sender.public_key, accepted).await
+ );
}
None
diff --git a/crates/oxidetalis/src/websocket/mod.rs b/crates/oxidetalis/src/websocket/mod.rs
index 84b3396..20ea8bb 100644
--- a/crates/oxidetalis/src/websocket/mod.rs
+++ b/crates/oxidetalis/src/websocket/mod.rs
@@ -45,7 +45,7 @@ pub use events::*;
use uuid::Uuid;
use crate::{
- database::UserTableExt,
+ database::{IncomingChatExt, UserTableExt},
extensions::{DepotExt, OnlineUsersExt},
middlewares,
nonce::NonceCache,
@@ -145,8 +145,9 @@ async fn handle_socket(
.await;
log::info!("New user connected: ConnId(={conn_id}) PublicKey(={user_public_key})");
- // TODO: Send the incoming chat request to the user, while they are offline.
- // This after adding last_login col to the user table
+ if let Some(server_user) = &user {
+ send_chat_requests_and_responses(&db_conn, &user_shared_secret, &sender, server_user).await;
+ }
while let Some(Ok(msg)) = user_ws_receiver.next().await {
match handle_ws_msg(msg, &nonce_cache, &user_shared_secret).await {
@@ -177,6 +178,56 @@ async fn handle_socket(
user_disconnected(&db_conn, &conn_id, &user_public_key, user).await;
}
+/// Send the incoming chat requests and responses to the user while they were
+/// offline
+///
+/// ### Note
+/// The errors are ignored, if there is an issue with user connection, the user
+/// will be disconnected after this function is called.
+///
+/// Also we make sure that the user receives the chat requests and responses
+/// before we delete them from the database.
+async fn send_chat_requests_and_responses(
+ db_conn: &DatabaseConnection,
+ user_shared_secret: &[u8; 32],
+ sender: &mpsc::UnboundedSender>,
+ server_user: &UserModel,
+) {
+ let Ok(requests) = db_conn.get_all_chat_requests(server_user).await else {
+ return;
+ };
+ let Ok(responses) = db_conn.get_all_chat_responses(server_user).await else {
+ return;
+ };
+
+ for request in requests {
+ if sender
+ .unbounded_send(Ok(ServerEvent::chat_request(&request.sender)
+ .sign(user_shared_secret)
+ .as_ref()
+ .into()))
+ .is_ok()
+ {
+ let _ = request.delete(db_conn).await;
+ }
+ }
+
+ for response in responses {
+ if sender
+ .unbounded_send(Ok(ServerEvent::chat_request_response(
+ response.sender,
+ response.accepted_response.unwrap_or_default(),
+ )
+ .sign(user_shared_secret)
+ .as_ref()
+ .into()))
+ .is_ok()
+ {
+ let _ = response.delete(db_conn).await;
+ }
+ }
+}
+
/// Handle websocket msg
async fn handle_ws_msg(
msg: Message,
--
2.45.2