From 96bf73cb573223e90d81e9b627787667d7a5bacc Mon Sep 17 00:00:00 2001 From: Zomatree Date: Mon, 22 Jul 2024 00:09:27 +0100 Subject: [PATCH] fix: send pin system messages --- .../database/src/models/messages/model.rs | 9 ++++ crates/core/database/src/util/bridge/v0.rs | 2 + crates/core/models/src/v0/messages.rs | 4 +- .../delta/src/routes/channels/message_pin.rs | 38 +++++++++++++- .../src/routes/channels/message_unpin.rs | 52 ++++++++++++++----- 5 files changed, 89 insertions(+), 16 deletions(-) diff --git a/crates/core/database/src/models/messages/model.rs b/crates/core/database/src/models/messages/model.rs index 5f3969cd..2b9ff3d1 100644 --- a/crates/core/database/src/models/messages/model.rs +++ b/crates/core/database/src/models/messages/model.rs @@ -101,6 +101,10 @@ auto_derived!( ChannelIconChanged { by: String }, #[serde(rename = "channel_ownership_changed")] ChannelOwnershipChanged { from: String, to: String }, + #[serde(rename = "message_pinned")] + MessagePinned { id: String, by: String }, + #[serde(rename = "message_unpinned")] + MessageUnpinned { id: String, by: String }, } /// Name and / or avatar override information @@ -525,6 +529,11 @@ impl Message { /// Update message data pub async fn update(&mut self, db: &Database, partial: PartialMessage, remove: Vec) -> Result<()> { self.apply_options(partial.clone()); + + for field in &remove { + self.remove_field(field); + } + db.update_message(&self.id, &partial, remove.clone()).await?; EventV1::MessageUpdate { diff --git a/crates/core/database/src/util/bridge/v0.rs b/crates/core/database/src/util/bridge/v0.rs index 16e589d7..da1e8f11 100644 --- a/crates/core/database/src/util/bridge/v0.rs +++ b/crates/core/database/src/util/bridge/v0.rs @@ -533,6 +533,8 @@ impl From for SystemMessage { crate::SystemMessage::UserKicked { id } => Self::UserKicked { id }, crate::SystemMessage::UserLeft { id } => Self::UserLeft { id }, crate::SystemMessage::UserRemove { id, by } => Self::UserRemove { id, by }, + crate::SystemMessage::MessagePinned { id, by } => Self::MessagePinned { id, by }, + crate::SystemMessage::MessageUnpinned { id, by } => Self::MessageUnpinned { id, by }, } } } diff --git a/crates/core/models/src/v0/messages.rs b/crates/core/models/src/v0/messages.rs index 5e3c47af..5101d8e1 100644 --- a/crates/core/models/src/v0/messages.rs +++ b/crates/core/models/src/v0/messages.rs @@ -131,9 +131,9 @@ auto_derived!( #[serde(rename = "channel_ownership_changed")] ChannelOwnershipChanged { from: String, to: String }, #[serde(rename = "message_pinned")] - MessagePinned { id: String }, + MessagePinned { id: String, by: String }, #[serde(rename = "message_unpinned")] - MessageUnpinned { id: String }, + MessageUnpinned { id: String, by: String }, } /// Name and / or avatar override information diff --git a/crates/delta/src/routes/channels/message_pin.rs b/crates/delta/src/routes/channels/message_pin.rs index 3a5e347d..ef5bf598 100644 --- a/crates/delta/src/routes/channels/message_pin.rs +++ b/crates/delta/src/routes/channels/message_pin.rs @@ -1,6 +1,7 @@ use revolt_database::{ - util::{permissions::DatabasePermissionQuery, reference::Reference}, Database, PartialMessage, User + util::{permissions::DatabasePermissionQuery, reference::Reference}, Database, PartialMessage, SystemMessage, User }; +use revolt_models::v0::MessageAuthor; use revolt_permissions::{calculate_channel_permissions, ChannelPermission}; use revolt_result::{create_error, Result}; use rocket::State; @@ -35,6 +36,23 @@ pub async fn message_pin( ..Default::default() }, vec![]).await?; + SystemMessage::MessagePinned { + id: message.id.clone(), + by: user.id.clone() + } + .into_message(channel.id()) + .send( + db, + MessageAuthor::System { + username: &user.username, + avatar: user.avatar.as_ref().map(|file| file.id.as_ref()) + }, + None, + None, + &channel, + false + ).await?; + Ok(EmptyResponse) } @@ -42,7 +60,7 @@ pub async fn message_pin( mod test { use crate::{rocket, util::test::TestHarness}; use revolt_database::{events::client::EventV1, util::{idempotency::IdempotencyKey, reference::Reference}, Member, Message, Server}; - use revolt_models::v0; + use revolt_models::v0::{self, SystemMessage}; use rocket::http::{Header, Status}; #[rocket::async_test] @@ -97,6 +115,22 @@ mod test { assert_eq!(response.status(), Status::NoContent); drop(response); + harness.wait_for_event(&channel.id(), |event| { + match event { + EventV1::Message(message) => { + match &message.system { + Some(SystemMessage::MessagePinned { by, .. }) => { + assert_eq!(by, &user.id); + + true + }, + _ => false + } + }, + _ => false + } + }).await; + harness.wait_for_event(&channel.id(), |event| { match event { EventV1::MessageUpdate { id, channel: channel_id, data, .. } => { diff --git a/crates/delta/src/routes/channels/message_unpin.rs b/crates/delta/src/routes/channels/message_unpin.rs index 1edf9e46..96f33dcb 100644 --- a/crates/delta/src/routes/channels/message_unpin.rs +++ b/crates/delta/src/routes/channels/message_unpin.rs @@ -1,6 +1,7 @@ use revolt_database::{ - util::{permissions::DatabasePermissionQuery, reference::Reference}, Database, FieldsMessage, PartialMessage, User + util::{permissions::DatabasePermissionQuery, reference::Reference}, Database, FieldsMessage, PartialMessage, SystemMessage, User }; +use revolt_models::v0::MessageAuthor; use revolt_permissions::{calculate_channel_permissions, ChannelPermission}; use revolt_result::{create_error, Result}; use rocket::State; @@ -30,10 +31,24 @@ pub async fn message_unpin( return Err(create_error!(NotPinned)) } - message.update(db, PartialMessage { - pinned: Some(false), - ..Default::default() - }, vec![FieldsMessage::Pinned]).await?; + message.update(db, PartialMessage::default(), vec![FieldsMessage::Pinned]).await?; + + SystemMessage::MessageUnpinned { + id: message.id.clone(), + by: user.id.clone() + } + .into_message(channel.id()) + .send( + db, + MessageAuthor::System { + username: &user.username, + avatar: user.avatar.as_ref().map(|file| file.id.as_ref()) + }, + None, + None, + &channel, + false + ).await?; Ok(EmptyResponse) } @@ -42,7 +57,7 @@ pub async fn message_unpin( mod test { use crate::{rocket, util::test::TestHarness}; use revolt_database::{events::client::EventV1, util::{idempotency::IdempotencyKey, reference::Reference}, Member, Message, PartialMessage, Server}; - use revolt_models::v0; + use revolt_models::v0::{self, FieldsMessage, SystemMessage}; use rocket::http::{Header, Status}; #[rocket::async_test] @@ -65,7 +80,7 @@ mod test { Member::create(&harness.db, &server, &user, Some(channels.clone())).await.expect("Failed to create member"); let member = Reference::from_unchecked(user.id.clone()).as_member(&harness.db, &server.id).await.expect("Failed to get member"); - let mut message = Message::create_from_api( + let message = Message::create_from_api( &harness.db, channel.clone(), v0::DataMessageSend { @@ -110,12 +125,25 @@ mod test { harness.wait_for_event(&channel.id(), |event| { match event { - EventV1::MessageUpdate { id, data, .. } => { - if id != &message.id { - return false - }; + EventV1::Message(message) => { + match &message.system { + Some(SystemMessage::MessageUnpinned { by, .. }) => { + assert_eq!(by, &user.id); - assert_eq!(data.pinned, Some(false)); + true + }, + _ => false + } + }, + _ => false + } + }).await; + + harness.wait_for_event(&channel.id(), |event| { + match event { + EventV1::MessageUpdate { id, clear, .. } => { + assert_eq!(&message.id, id); + assert_eq!(clear, &[FieldsMessage::Pinned]); true },