feat: emoji edit + pronoun

Signed-off-by: Zomatree <me@zomatree.live>
This commit is contained in:
Zomatree
2026-06-24 14:01:42 +01:00
parent 094384824b
commit c0cf3a9f60
7 changed files with 71 additions and 13 deletions

View File

@@ -4,7 +4,7 @@ use iso8601_timestamp::Timestamp;
use revolt_config::config; use revolt_config::config;
use ulid::Ulid; use ulid::Ulid;
use crate::{Database, PartialChannel, PartialMember, PartialRole, PartialServer, User}; use crate::{Database, PartialChannel, PartialMember, PartialRole, PartialServer, User, PartialEmoji};
use revolt_models::v0; use revolt_models::v0;
use revolt_permissions::OverrideField; use revolt_permissions::OverrideField;
use revolt_result::Result; use revolt_result::Result;
@@ -130,6 +130,11 @@ auto_derived!(
emoji: String, emoji: String,
name: String, name: String,
}, },
EmojiUpdate {
emoji: String,
before: PartialEmoji,
after: PartialEmoji,
},
EmojiDelete { EmojiDelete {
emoji: String, emoji: String,
name: String, name: String,
@@ -250,6 +255,7 @@ impl AuditLogEntry {
AuditLogEntryAction::WebhookCreate { .. } => {} AuditLogEntryAction::WebhookCreate { .. } => {}
AuditLogEntryAction::WebhookDelete { .. } => {} AuditLogEntryAction::WebhookDelete { .. } => {}
AuditLogEntryAction::EmojiCreate { .. } => {} AuditLogEntryAction::EmojiCreate { .. } => {}
AuditLogEntryAction::EmojiUpdate { .. } => {}
AuditLogEntryAction::EmojiDelete { .. } => {} AuditLogEntryAction::EmojiDelete { .. } => {}
}; };
} }

View File

@@ -16,7 +16,7 @@ static PERMISSIBLE_EMOJIS: Lazy<HashSet<String>> = Lazy::new(|| {
.collect() .collect()
}); });
auto_derived!( auto_derived_partial!(
/// Emoji /// Emoji
pub struct Emoji { pub struct Emoji {
/// Unique Id /// Unique Id
@@ -34,20 +34,17 @@ auto_derived!(
/// Whether the emoji is marked as nsfw /// Whether the emoji is marked as nsfw
#[serde(skip_serializing_if = "crate::if_false", default)] #[serde(skip_serializing_if = "crate::if_false", default)]
pub nsfw: bool, pub nsfw: bool,
} },
"PartialEmoji"
);
auto_derived!(
/// Parent Id of the emoji /// Parent Id of the emoji
#[serde(tag = "type")] #[serde(tag = "type")]
pub enum EmojiParent { pub enum EmojiParent {
Server { id: String }, Server { id: String },
Detached, Detached,
} }
/// Partial representation of an emoji
pub struct PartialEmoji {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
}
); );
#[allow(clippy::disallowed_methods)] #[allow(clippy::disallowed_methods)]
@@ -112,4 +109,18 @@ impl Emoji {
Ok(PERMISSIBLE_EMOJIS.contains(&sanitized_emoji)) Ok(PERMISSIBLE_EMOJIS.contains(&sanitized_emoji))
} }
} }
/// Generates a PartialEmoji containing the data which has changed in an update
pub fn generate_diff(&self, partial: &PartialEmoji) -> PartialEmoji {
let mut before = PartialEmoji::default();
generate_diff!(
self, before, partial, remove,
(
name,
)
);
before
}
} }

View File

@@ -255,6 +255,7 @@ impl Member {
(FieldsMember::Nickname) nickname, (FieldsMember::Nickname) nickname,
(FieldsMember::Avatar) avatar, (FieldsMember::Avatar) avatar,
(FieldsMember::Timeout) timeout, (FieldsMember::Timeout) timeout,
(FieldsMember::Pronouns) pronouns,
((default) FieldsMember::Roles) roles, ((default) FieldsMember::Roles) roles,
((default) FieldsMember::CanPublish) can_publish, ((default) FieldsMember::CanPublish) can_publish,
((default) FieldsMember::CanReceive) can_receive, ((default) FieldsMember::CanReceive) can_receive,

View File

@@ -414,6 +414,7 @@ impl Role {
(FieldsRole::Colour) colour, (FieldsRole::Colour) colour,
hoist, hoist,
rank, rank,
(FieldsRole::Icon) icon,
) )
); );

View File

@@ -1536,6 +1536,15 @@ impl From<crate::AuditLogEntryAction> for AuditLogEntryAction {
crate::AuditLogEntryAction::EmojiCreate { emoji, name } => { crate::AuditLogEntryAction::EmojiCreate { emoji, name } => {
AuditLogEntryAction::EmojiCreate { emoji, name } AuditLogEntryAction::EmojiCreate { emoji, name }
} }
crate::AuditLogEntryAction::EmojiUpdate {
emoji,
before,
after,
} => AuditLogEntryAction::EmojiUpdate {
emoji,
before: before.into(),
after: after.into(),
},
crate::AuditLogEntryAction::EmojiDelete { emoji, name } => { crate::AuditLogEntryAction::EmojiDelete { emoji, name } => {
AuditLogEntryAction::EmojiDelete { emoji, name } AuditLogEntryAction::EmojiDelete { emoji, name }
} }
@@ -1665,3 +1674,9 @@ impl From<WebPushSubscription> for crate::WebPushSubscription {
} }
} }
} }
impl From<crate::PartialEmoji> for PartialEmoji {
fn from(value: crate::PartialEmoji) -> Self {
PartialEmoji { name: value.name }
}
}

View File

@@ -1,4 +1,4 @@
use crate::v0::{Member, PartialChannel, PartialMember, PartialRole, PartialServer, User}; use crate::v0::{Member, PartialChannel, PartialEmoji, PartialMember, PartialRole, PartialServer, User};
use revolt_permissions::Override; use revolt_permissions::Override;
auto_derived!( auto_derived!(
@@ -117,6 +117,11 @@ auto_derived!(
emoji: String, emoji: String,
name: String, name: String,
}, },
EmojiUpdate {
emoji: String,
before: PartialEmoji,
after: PartialEmoji,
},
EmojiDelete { EmojiDelete {
emoji: String, emoji: String,
name: String, name: String,

View File

@@ -1,6 +1,6 @@
use revolt_database::{ use revolt_database::{
util::{permissions::DatabasePermissionQuery, reference::Reference}, util::{permissions::DatabasePermissionQuery, reference::Reference},
Database, EmojiParent, PartialEmoji, User, AuditLogEntryAction, Database, EmojiParent, PartialEmoji, User,
}; };
use revolt_models::v0; use revolt_models::v0;
use revolt_permissions::{calculate_server_permissions, ChannelPermission}; use revolt_permissions::{calculate_server_permissions, ChannelPermission};
@@ -8,6 +8,8 @@ use revolt_result::{create_error, Result};
use rocket::{serde::json::Json, State}; use rocket::{serde::json::Json, State};
use validator::Validate; use validator::Validate;
use crate::util::audit_log_reason::AuditLogReason;
/// # Edit Emoji /// # Edit Emoji
/// ///
/// Edit an emoji by its id. /// Edit an emoji by its id.
@@ -16,6 +18,7 @@ use validator::Validate;
pub async fn edit_emoji( pub async fn edit_emoji(
db: &State<Database>, db: &State<Database>,
user: User, user: User,
reason: AuditLogReason,
emoji_id: Reference<'_>, emoji_id: Reference<'_>,
data: Json<v0::DataEditEmoji>, data: Json<v0::DataEditEmoji>,
) -> Result<Json<v0::Emoji>> { ) -> Result<Json<v0::Emoji>> {
@@ -44,8 +47,24 @@ pub async fn edit_emoji(
return Ok(Json(emoji.into())); return Ok(Json(emoji.into()));
} }
let partial = PartialEmoji { name: data.name }; let partial = PartialEmoji {
emoji.update(db, partial).await?; name: data.name,
..Default::default()
};
let before = emoji.generate_diff(&partial);
emoji.update(db, partial.clone()).await?;
if let EmojiParent::Server { id: server_id } = emoji.parent.clone() {
AuditLogEntryAction::EmojiUpdate {
emoji: emoji.id.clone(),
before,
after: partial,
}
.insert(db, server_id, reason, user.id, Some(emoji.creator_id.clone()))
.await;
};
Ok(Json(emoji.into())) Ok(Json(emoji.into()))
} }