diff --git a/src/database/entities/channel.rs b/src/database/entities/channel.rs index 1f66d5199e0eb024280193377b4929557c817a50..37736dc54656482da49f38d3ec5b552c0a7e2199 100644 --- a/src/database/entities/channel.rs +++ b/src/database/entities/channel.rs @@ -1,4 +1,6 @@ use serde::{Deserialize, Serialize}; +use crate::{database::get_collection, util::result::{Error, Result}}; +use mongodb::bson::to_document; /*#[derive(Serialize, Deserialize, Debug, Clone)] pub struct LastMessage { @@ -33,6 +35,11 @@ pub struct Channel { #[derive(Serialize, Deserialize, Debug)] #[serde(tag = "type")] pub enum Channel { + SavedMessages { + #[serde(rename = "_id")] + id: String, + user: String + }, DirectMessage { #[serde(rename = "_id")] id: String, @@ -48,3 +55,18 @@ pub enum Channel { recipients: Vec<String>, } } + +impl Channel { + pub async fn save(&self) -> Result<()> { + get_collection("channels") + .insert_one( + to_document(&self) + .map_err(|_| Error::DatabaseError { operation: "to_bson", with: "channel" })?, + None + ) + .await + .map_err(|_| Error::DatabaseError { operation: "insert_one", with: "channel" })?; + + Ok(()) + } +} diff --git a/src/database/entities/user.rs b/src/database/entities/user.rs index 722c1bf56e095b86e38075522ce6a7bb1f567302..b55a8f88739e6cad9fbdf581cf9d594fc866b736 100644 --- a/src/database/entities/user.rs +++ b/src/database/entities/user.rs @@ -7,6 +7,7 @@ use rocket::request::{self, FromRequest, Outcome, Request}; #[derive(Serialize, Deserialize, Debug)] pub struct Relationship { + #[serde(rename = "_id")] pub id: String, pub status: u8, } diff --git a/src/database/guards/reference.rs b/src/database/guards/reference.rs index 1f9a36ec0105cce6d47179cb5c2d520aa819064d..a4282a1287878f52848f3135ecb1749c916538f7 100644 --- a/src/database/guards/reference.rs +++ b/src/database/guards/reference.rs @@ -10,7 +10,7 @@ use validator::Validate; #[derive(Validate, Serialize, Deserialize)] pub struct Ref { #[validate(length(min = 26, max = 26))] - id: String, + pub id: String, } impl Ref { diff --git a/src/database/permissions/mod.rs b/src/database/permissions/mod.rs index 3b0f4382561fc43f90f00d8dc043fadef14bea31..899aea7b62f1b31b9f97c81da4555e44bc9b1528 100644 --- a/src/database/permissions/mod.rs +++ b/src/database/permissions/mod.rs @@ -18,8 +18,8 @@ bitfield! { pub get_invite, _: 29; } -impl_op_ex!(+ |a: &UserPermission, b: &UserPermission| -> u32 { *a + *b }); -impl_op_ex!(+ |a: &u32, b: &UserPermission| -> u32 { *a + *b }); +impl_op_ex!(+ |a: &UserPermission, b: &UserPermission| -> u32 { *a as u32 | *b as u32 }); +impl_op_ex_commutative!(+ |a: &u32, b: &UserPermission| -> u32 { *a | *b as u32 }); pub async fn temp_calc_perm(_user: &User, _target: &User) -> UserPermissions<[u32; 1]> { // if friends; Access + Message + Invite diff --git a/src/routes/users/fetch_dms.rs b/src/routes/users/fetch_dms.rs index beeb5e75a988c86a6894b108deced83a35e6d6ff..2eda25e263ef027c81f2af7450a3f72fb454852b 100644 --- a/src/routes/users/fetch_dms.rs +++ b/src/routes/users/fetch_dms.rs @@ -26,13 +26,10 @@ pub async fn req(user: User) -> Result<JsonValue> { .await .map_err(|_| Error::DatabaseError { operation: "find", with: "channels" })?; - let mut channels: Vec<Channel> = vec![]; + let mut channels = vec![]; while let Some(result) = cursor.next().await { if let Ok(doc) = result { - channels.push( - from_bson(Bson::Document(doc)) - .map_err(|_| Error::DatabaseError { operation: "from_bson", with: "channel" })? - ); + channels.push(doc); } } diff --git a/src/routes/users/mod.rs b/src/routes/users/mod.rs index 7b92a3f98fa30cc71ba22b97960aaf57ea205c0e..fd5b017e53a9ce1de27011dfaeb35beb0eb8df2f 100644 --- a/src/routes/users/mod.rs +++ b/src/routes/users/mod.rs @@ -2,10 +2,12 @@ use rocket::Route; mod fetch_user; mod fetch_dms; +mod open_dm; pub fn routes() -> Vec<Route> { routes! [ fetch_user::req, - fetch_dms::req + fetch_dms::req, + open_dm::req, ] } diff --git a/src/routes/users/open_dm.rs b/src/routes/users/open_dm.rs new file mode 100644 index 0000000000000000000000000000000000000000..32f7496fcef22c9f00e5043b75f051d8d7bfd99a --- /dev/null +++ b/src/routes/users/open_dm.rs @@ -0,0 +1,53 @@ +use crate::database::entities::{Channel, User}; +use crate::database::guards::reference::Ref; +use crate::util::result::{Error, Result}; +use crate::database::get_collection; +use rocket_contrib::json::JsonValue; +use mongodb::bson::doc; +use ulid::Ulid; + +#[get("/<target>/dm")] +pub async fn req(user: User, target: Ref) -> Result<JsonValue> { + let query = if user.id == target.id { + doc! { + "type": "SavedMessages", + "user": &user.id + } + } else { + doc! { + "type": "DirectMessage", + "recipients": { + "$all": [ &user.id, &target.id ] + } + } + }; + + let existing_channel = get_collection("channels") + .find_one(query, None) + .await + .map_err(|_| Error::DatabaseError { operation: "find_one", with: "channel" })?; + + if let Some(doc) = existing_channel { + Ok(json!(doc)) + } else { + let id = Ulid::new().to_string(); + let channel = if user.id == target.id { + Channel::SavedMessages { + id, + user: user.id + } + } else { + Channel::DirectMessage { + id, + active: false, + recipients: vec! [ + user.id, + target.id + ] + } + }; + + channel.save().await?; + Ok(json!(channel)) + } +}