diff --git a/crates/core/database/src/events/client.rs b/crates/core/database/src/events/client.rs index a0b3eef9..90c83469 100644 --- a/crates/core/database/src/events/client.rs +++ b/crates/core/database/src/events/client.rs @@ -2,10 +2,7 @@ use authifier::AuthifierEvent; use serde::{Deserialize, Serialize}; use revolt_models::v0::{ - AppendMessage, Channel, ChannelUnread, Emoji, FieldsChannel, FieldsMember, FieldsRole, - FieldsServer, FieldsUser, FieldsWebhook, Member, MemberCompositeKey, Message, PartialChannel, - PartialMember, PartialMessage, PartialRole, PartialServer, PartialUser, PartialWebhook, - RemovalIntention, Report, Server, User, UserSettings, Webhook, + AppendMessage, Channel, ChannelUnread, Emoji, FieldsChannel, FieldsMember, FieldsMessage, FieldsRole, FieldsServer, FieldsUser, FieldsWebhook, Member, MemberCompositeKey, Message, PartialChannel, PartialMember, PartialMessage, PartialRole, PartialServer, PartialUser, PartialWebhook, RemovalIntention, Report, Server, User, UserSettings, Webhook }; use revolt_result::Error; @@ -92,6 +89,7 @@ pub enum EventV1 { id: String, channel: String, data: PartialMessage, + clear: Vec, }, /// Append information to existing message diff --git a/crates/core/database/src/models/messages/model.rs b/crates/core/database/src/models/messages/model.rs index 25b6c625..5f3969cd 100644 --- a/crates/core/database/src/models/messages/model.rs +++ b/crates/core/database/src/models/messages/model.rs @@ -4,8 +4,7 @@ use indexmap::{IndexMap, IndexSet}; use iso8601_timestamp::Timestamp; use revolt_config::{config, FeaturesLimits}; use revolt_models::v0::{ - self, BulkMessageResponse, DataMessageSend, Embed, MessageAuthor, MessageFlags, MessageSort, - MessageWebhook, PushNotification, ReplyIntent, SendableEmbed, Text, RE_MENTION, + self, BulkMessageResponse, DataMessageSend, Embed, MessageAuthor, MessageFlags, MessageSort, MessageWebhook, PushNotification, ReplyIntent, SendableEmbed, Text, RE_MENTION }; use revolt_permissions::{ChannelPermission, PermissionValue}; use revolt_result::Result; @@ -188,6 +187,11 @@ auto_derived!( #[serde(flatten)] pub time_period: MessageTimePeriod, } + + /// Optional fields on message + pub enum FieldsMessage { + Pinned + } ); #[allow(clippy::derivable_impls)] @@ -519,14 +523,15 @@ impl Message { } /// Update message data - pub async fn update(&mut self, db: &Database, partial: PartialMessage) -> Result<()> { + pub async fn update(&mut self, db: &Database, partial: PartialMessage, remove: Vec) -> Result<()> { self.apply_options(partial.clone()); - db.update_message(&self.id, &partial).await?; + db.update_message(&self.id, &partial, remove.clone()).await?; EventV1::MessageUpdate { id: self.id.clone(), channel: self.channel.clone(), data: partial.into(), + clear: remove.into_iter().map(|field| field.into()).collect() } .p(self.channel.clone()) .await; @@ -808,6 +813,12 @@ impl Message { // Write to database db.clear_reaction(&self.id, emoji).await } + + pub fn remove_field(&mut self, field: &FieldsMessage) { + match field { + FieldsMessage::Pinned => self.pinned = None + } + } } impl SystemMessage { diff --git a/crates/core/database/src/models/messages/ops.rs b/crates/core/database/src/models/messages/ops.rs index c89caf9b..b10022b4 100644 --- a/crates/core/database/src/models/messages/ops.rs +++ b/crates/core/database/src/models/messages/ops.rs @@ -1,6 +1,6 @@ use revolt_result::Result; -use crate::{AppendMessage, Message, MessageQuery, PartialMessage}; +use crate::{AppendMessage, FieldsMessage, Message, MessageQuery, PartialMessage}; mod mongodb; mod reference; @@ -20,7 +20,7 @@ pub trait AbstractMessages: Sync + Send { async fn fetch_messages_by_id(&self, ids: &[String]) -> Result>; /// Update a given message with new information - async fn update_message(&self, id: &str, message: &PartialMessage) -> Result<()>; + async fn update_message(&self, id: &str, message: &PartialMessage, remove: Vec) -> Result<()>; /// Append information to a given message async fn append_message(&self, id: &str, append: &AppendMessage) -> Result<()>; diff --git a/crates/core/database/src/models/messages/ops/mongodb.rs b/crates/core/database/src/models/messages/ops/mongodb.rs index faaeca36..f10420e3 100644 --- a/crates/core/database/src/models/messages/ops/mongodb.rs +++ b/crates/core/database/src/models/messages/ops/mongodb.rs @@ -5,7 +5,7 @@ use revolt_models::v0::MessageSort; use revolt_result::Result; use crate::{ - AppendMessage, DocumentId, Message, MessageQuery, MessageTimePeriod, MongoDb, PartialMessage, + AppendMessage, DocumentId, FieldsMessage, IntoDocumentPath, Message, MessageQuery, MessageTimePeriod, MongoDb, PartialMessage }; use super::AbstractMessages; @@ -182,8 +182,16 @@ impl AbstractMessages for MongoDb { } /// Update a given message with new information - async fn update_message(&self, id: &str, message: &PartialMessage) -> Result<()> { - query!(self, update_one_by_id, COL, id, message, vec![], None).map(|_| ()) + async fn update_message(&self, id: &str, message: &PartialMessage, remove: Vec) -> Result<()> { + query!( + self, + update_one_by_id, + COL, + id, + message, + remove.iter().map(|x| x as &dyn IntoDocumentPath).collect(), + None + ).map(|_| ()) } /// Append information to a given message @@ -301,6 +309,14 @@ impl AbstractMessages for MongoDb { } } +impl IntoDocumentPath for FieldsMessage { + fn as_path(&self) -> Option<&'static str> { + Some(match self { + FieldsMessage::Pinned => "pinned" + }) + } +} + impl MongoDb { pub async fn delete_bulk_messages(&self, projection: Document) -> Result<()> { let mut for_attachments = projection.clone(); diff --git a/crates/core/database/src/models/messages/ops/reference.rs b/crates/core/database/src/models/messages/ops/reference.rs index 636cadb0..ae5b43f0 100644 --- a/crates/core/database/src/models/messages/ops/reference.rs +++ b/crates/core/database/src/models/messages/ops/reference.rs @@ -2,7 +2,7 @@ use futures::future::try_join_all; use indexmap::IndexSet; use revolt_result::Result; -use crate::{AppendMessage, Message, MessageQuery, PartialMessage, ReferenceDb}; +use crate::{AppendMessage, FieldsMessage, Message, MessageQuery, PartialMessage, ReferenceDb}; use super::AbstractMessages; @@ -189,10 +189,15 @@ impl AbstractMessages for ReferenceDb { } /// Update a given message with new information - async fn update_message(&self, id: &str, message: &PartialMessage) -> Result<()> { + async fn update_message(&self, id: &str, message: &PartialMessage, remove: Vec) -> Result<()> { let mut messages = self.messages.lock().await; if let Some(message_data) = messages.get_mut(id) { message_data.apply_options(message.to_owned()); + + for field in remove { + #[allow(clippy::disallowed_methods)] + message_data.remove_field(&field); + } Ok(()) } else { Err(create_error!(NotFound)) diff --git a/crates/core/database/src/util/bridge/v0.rs b/crates/core/database/src/util/bridge/v0.rs index 814fae2c..16e589d7 100644 --- a/crates/core/database/src/util/bridge/v0.rs +++ b/crates/core/database/src/util/bridge/v0.rs @@ -1322,3 +1322,18 @@ impl From for crate::BotInformation { } } } + +impl From for FieldsMessage { + fn from(value: crate::FieldsMessage) -> Self { + match value { + crate::FieldsMessage::Pinned => FieldsMessage::Pinned, + } + } +} +impl From for crate::FieldsMessage { + fn from(value: FieldsMessage) -> Self { + match value { + FieldsMessage::Pinned => crate::FieldsMessage::Pinned, + } + } +} \ No newline at end of file diff --git a/crates/core/models/src/v0/messages.rs b/crates/core/models/src/v0/messages.rs index 2abf5bf1..5e3c47af 100644 --- a/crates/core/models/src/v0/messages.rs +++ b/crates/core/models/src/v0/messages.rs @@ -364,6 +364,11 @@ auto_derived!( /// Message will not send push / desktop notifications SuppressNotifications = 1, } + + /// Optional fields on message + pub enum FieldsMessage { + Pinned + } ); /// Message Author Abstraction diff --git a/crates/delta/src/routes/channels/message_clear_reactions.rs b/crates/delta/src/routes/channels/message_clear_reactions.rs index 2dffc3fa..3142ed6b 100644 --- a/crates/delta/src/routes/channels/message_clear_reactions.rs +++ b/crates/delta/src/routes/channels/message_clear_reactions.rs @@ -37,6 +37,7 @@ pub async fn clear_reactions( reactions: Some(Default::default()), ..Default::default() }, + vec![] ) .await .map(|_| EmptyResponse) diff --git a/crates/delta/src/routes/channels/message_edit.rs b/crates/delta/src/routes/channels/message_edit.rs index 507ce03f..5a77cb92 100644 --- a/crates/delta/src/routes/channels/message_edit.rs +++ b/crates/delta/src/routes/channels/message_edit.rs @@ -83,7 +83,7 @@ pub async fn edit( partial.embeds = Some(new_embeds); - message.update(db, partial).await?; + message.update(db, partial, vec![]).await?; // Queue up a task for processing embeds if the we have sufficient permissions if permissions.has_channel_permission(ChannelPermission::SendEmbeds) { diff --git a/crates/delta/src/routes/channels/message_pin.rs b/crates/delta/src/routes/channels/message_pin.rs index 8163556a..80dc19fe 100644 --- a/crates/delta/src/routes/channels/message_pin.rs +++ b/crates/delta/src/routes/channels/message_pin.rs @@ -33,7 +33,7 @@ pub async fn message_pin( message.update(db, PartialMessage { pinned: Some(true), ..Default::default() - }).await?; + }, vec![]).await?; Ok(EmptyResponse) } diff --git a/crates/delta/src/routes/channels/message_unpin.rs b/crates/delta/src/routes/channels/message_unpin.rs index 4271d62e..13e91971 100644 --- a/crates/delta/src/routes/channels/message_unpin.rs +++ b/crates/delta/src/routes/channels/message_unpin.rs @@ -33,7 +33,7 @@ pub async fn message_unpin( message.update(db, PartialMessage { pinned: Some(false), ..Default::default() - }).await?; + }, vec![FieldsMessage::Pinned]).await?; Ok(EmptyResponse) }