forked from jmug/stoatchat
feat: silent messages and message flags
This commit is contained in:
@@ -4,8 +4,8 @@ use indexmap::{IndexMap, IndexSet};
|
|||||||
use iso8601_timestamp::Timestamp;
|
use iso8601_timestamp::Timestamp;
|
||||||
use revolt_config::{config, FeaturesLimits};
|
use revolt_config::{config, FeaturesLimits};
|
||||||
use revolt_models::v0::{
|
use revolt_models::v0::{
|
||||||
self, BulkMessageResponse, DataMessageSend, Embed, MessageAuthor, MessageSort, MessageWebhook,
|
self, BulkMessageResponse, DataMessageSend, Embed, MessageAuthor, MessageFlags, MessageSort,
|
||||||
PushNotification, ReplyIntent, SendableEmbed, Text, RE_MENTION,
|
MessageWebhook, PushNotification, ReplyIntent, SendableEmbed, Text, RE_MENTION,
|
||||||
};
|
};
|
||||||
use revolt_permissions::{ChannelPermission, PermissionValue};
|
use revolt_permissions::{ChannelPermission, PermissionValue};
|
||||||
use revolt_result::Result;
|
use revolt_result::Result;
|
||||||
@@ -65,6 +65,10 @@ auto_derived_partial!(
|
|||||||
/// Name and / or avatar overrides for this message
|
/// Name and / or avatar overrides for this message
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub masquerade: Option<Masquerade>,
|
pub masquerade: Option<Masquerade>,
|
||||||
|
|
||||||
|
/// Bitfield of message flags
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub flags: Option<i32>,
|
||||||
},
|
},
|
||||||
"PartialMessage"
|
"PartialMessage"
|
||||||
);
|
);
|
||||||
@@ -200,6 +204,7 @@ impl Default for Message {
|
|||||||
reactions: Default::default(),
|
reactions: Default::default(),
|
||||||
interactions: Default::default(),
|
interactions: Default::default(),
|
||||||
masquerade: None,
|
masquerade: None,
|
||||||
|
flags: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -241,6 +246,13 @@ impl Message {
|
|||||||
return Err(create_error!(EmptyMessage));
|
return Err(create_error!(EmptyMessage));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure flags are either not set or have permissible values
|
||||||
|
if let Some(flags) = &data.flags {
|
||||||
|
if flags != &0 && flags != &1 {
|
||||||
|
return Err(create_error!(InvalidProperty));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure restrict_reactions is not specified without reactions list
|
// Ensure restrict_reactions is not specified without reactions list
|
||||||
if let Some(interactions) = &data.interactions {
|
if let Some(interactions) = &data.interactions {
|
||||||
if interactions.restrict_reactions {
|
if interactions.restrict_reactions {
|
||||||
@@ -274,6 +286,7 @@ impl Message {
|
|||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
author: author_id,
|
author: author_id,
|
||||||
webhook: webhook.map(|w| w.into()),
|
webhook: webhook.map(|w| w.into()),
|
||||||
|
flags: data.flags.map(|v| v as i32),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -438,24 +451,26 @@ impl Message {
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
// Push out Web Push notifications
|
if !self.has_suppressed_notifications() {
|
||||||
crate::tasks::web_push::queue(
|
// Push out Web Push notifications
|
||||||
{
|
crate::tasks::web_push::queue(
|
||||||
match channel {
|
{
|
||||||
Channel::DirectMessage { recipients, .. }
|
match channel {
|
||||||
| Channel::Group { recipients, .. } => recipients.clone(),
|
Channel::DirectMessage { recipients, .. }
|
||||||
Channel::TextChannel { .. } => self.mentions.clone().unwrap_or_default(),
|
| Channel::Group { recipients, .. } => recipients.clone(),
|
||||||
_ => vec![],
|
Channel::TextChannel { .. } => self.mentions.clone().unwrap_or_default(),
|
||||||
}
|
_ => vec![],
|
||||||
},
|
}
|
||||||
PushNotification::from(
|
},
|
||||||
self.clone().into_model(None, None),
|
PushNotification::from(
|
||||||
Some(author),
|
self.clone().into_model(None, None),
|
||||||
&channel.id(),
|
Some(author),
|
||||||
|
&channel.id(),
|
||||||
|
)
|
||||||
|
.await,
|
||||||
)
|
)
|
||||||
.await,
|
.await;
|
||||||
)
|
}
|
||||||
.await;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -487,6 +502,16 @@ impl Message {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Whether this message has suppressed notifications
|
||||||
|
pub fn has_suppressed_notifications(&self) -> bool {
|
||||||
|
if let Some(flags) = self.flags {
|
||||||
|
flags & MessageFlags::SupressNotifications as i32
|
||||||
|
== MessageFlags::SupressNotifications as i32
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Update message data
|
/// Update message data
|
||||||
pub async fn update(&mut self, db: &Database, partial: PartialMessage) -> Result<()> {
|
pub async fn update(&mut self, db: &Database, partial: PartialMessage) -> Result<()> {
|
||||||
self.apply_options(partial.clone());
|
self.apply_options(partial.clone());
|
||||||
|
|||||||
@@ -470,7 +470,7 @@ impl crate::Message {
|
|||||||
member,
|
member,
|
||||||
webhook: self.webhook,
|
webhook: self.webhook,
|
||||||
content: self.content,
|
content: self.content,
|
||||||
system: self.system.map(|system| system.into()),
|
system: self.system.map(Into::into),
|
||||||
attachments: self
|
attachments: self
|
||||||
.attachments
|
.attachments
|
||||||
.map(|v| v.into_iter().map(|f| f.into()).collect()),
|
.map(|v| v.into_iter().map(|f| f.into()).collect()),
|
||||||
@@ -480,7 +480,8 @@ impl crate::Message {
|
|||||||
replies: self.replies,
|
replies: self.replies,
|
||||||
reactions: self.reactions,
|
reactions: self.reactions,
|
||||||
interactions: self.interactions.into(),
|
interactions: self.interactions.into(),
|
||||||
masquerade: self.masquerade.map(|masq| masq.into()),
|
masquerade: self.masquerade.map(Into::into),
|
||||||
|
flags: self.flags.map(|flags| flags as u32).unwrap_or_default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -496,7 +497,7 @@ impl From<crate::PartialMessage> for PartialMessage {
|
|||||||
member: None,
|
member: None,
|
||||||
webhook: value.webhook,
|
webhook: value.webhook,
|
||||||
content: value.content,
|
content: value.content,
|
||||||
system: value.system.map(|system| system.into()),
|
system: value.system.map(Into::into),
|
||||||
attachments: value
|
attachments: value
|
||||||
.attachments
|
.attachments
|
||||||
.map(|v| v.into_iter().map(|f| f.into()).collect()),
|
.map(|v| v.into_iter().map(|f| f.into()).collect()),
|
||||||
@@ -505,8 +506,9 @@ impl From<crate::PartialMessage> for PartialMessage {
|
|||||||
mentions: value.mentions,
|
mentions: value.mentions,
|
||||||
replies: value.replies,
|
replies: value.replies,
|
||||||
reactions: value.reactions,
|
reactions: value.reactions,
|
||||||
interactions: value.interactions.map(|interactions| interactions.into()),
|
interactions: value.interactions.map(Into::into),
|
||||||
masquerade: value.masquerade.map(|masq| masq.into()),
|
masquerade: value.masquerade.map(Into::into),
|
||||||
|
flags: value.flags.map(|flags| flags as u32),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,6 +70,15 @@ auto_derived_partial!(
|
|||||||
/// Name and / or avatar overrides for this message
|
/// Name and / or avatar overrides for this message
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub masquerade: Option<Masquerade>,
|
pub masquerade: Option<Masquerade>,
|
||||||
|
|
||||||
|
/// Bitfield of message flags
|
||||||
|
///
|
||||||
|
/// https://docs.rs/revolt-models/latest/revolt_models/v0/enum.MessageFlags.html
|
||||||
|
#[cfg_attr(
|
||||||
|
feature = "serde",
|
||||||
|
serde(skip_serializing_if = "crate::if_zero_u32", default)
|
||||||
|
)]
|
||||||
|
pub flags: u32,
|
||||||
},
|
},
|
||||||
"PartialMessage"
|
"PartialMessage"
|
||||||
);
|
);
|
||||||
@@ -247,6 +256,11 @@ auto_derived!(
|
|||||||
pub masquerade: Option<Masquerade>,
|
pub masquerade: Option<Masquerade>,
|
||||||
/// Information about how this message should be interacted with
|
/// Information about how this message should be interacted with
|
||||||
pub interactions: Option<Interactions>,
|
pub interactions: Option<Interactions>,
|
||||||
|
|
||||||
|
/// Bitfield of message flags
|
||||||
|
///
|
||||||
|
/// https://docs.rs/revolt-models/latest/revolt_models/v0/enum.MessageFlags.html
|
||||||
|
pub flags: Option<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Options for querying messages
|
/// Options for querying messages
|
||||||
@@ -334,6 +348,13 @@ auto_derived!(
|
|||||||
/// Remove all reactions
|
/// Remove all reactions
|
||||||
pub remove_all: Option<bool>,
|
pub remove_all: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Message flag bitfield
|
||||||
|
#[repr(u32)]
|
||||||
|
pub enum MessageFlags {
|
||||||
|
/// Message will not send push / desktop notifications
|
||||||
|
SupressNotifications = 1,
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Message Author Abstraction
|
/// Message Author Abstraction
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ auto_derived_partial!(
|
|||||||
pub relations: Vec<Relationship>,
|
pub relations: Vec<Relationship>,
|
||||||
|
|
||||||
/// Bitfield of user badges
|
/// Bitfield of user badges
|
||||||
|
///
|
||||||
|
/// https://docs.rs/revolt-models/latest/revolt_models/v0/enum.UserBadges.html
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "serde",
|
feature = "serde",
|
||||||
serde(skip_serializing_if = "crate::if_zero_u32", default)
|
serde(skip_serializing_if = "crate::if_zero_u32", default)
|
||||||
@@ -52,6 +54,8 @@ auto_derived_partial!(
|
|||||||
pub status: Option<UserStatus>,
|
pub status: Option<UserStatus>,
|
||||||
|
|
||||||
/// Enum of user flags
|
/// Enum of user flags
|
||||||
|
///
|
||||||
|
/// https://docs.rs/revolt-models/latest/revolt_models/v0/enum.UserFlags.html
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "serde",
|
feature = "serde",
|
||||||
serde(skip_serializing_if = "crate::if_zero_u32", default)
|
serde(skip_serializing_if = "crate::if_zero_u32", default)
|
||||||
|
|||||||
Reference in New Issue
Block a user