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 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_permissions::OverrideField;
use revolt_result::Result;
@@ -130,6 +130,11 @@ auto_derived!(
emoji: String,
name: String,
},
EmojiUpdate {
emoji: String,
before: PartialEmoji,
after: PartialEmoji,
},
EmojiDelete {
emoji: String,
name: String,
@@ -250,6 +255,7 @@ impl AuditLogEntry {
AuditLogEntryAction::WebhookCreate { .. } => {}
AuditLogEntryAction::WebhookDelete { .. } => {}
AuditLogEntryAction::EmojiCreate { .. } => {}
AuditLogEntryAction::EmojiUpdate { .. } => {}
AuditLogEntryAction::EmojiDelete { .. } => {}
};
}

View File

@@ -16,7 +16,7 @@ static PERMISSIBLE_EMOJIS: Lazy<HashSet<String>> = Lazy::new(|| {
.collect()
});
auto_derived!(
auto_derived_partial!(
/// Emoji
pub struct Emoji {
/// Unique Id
@@ -34,20 +34,17 @@ auto_derived!(
/// Whether the emoji is marked as nsfw
#[serde(skip_serializing_if = "crate::if_false", default)]
pub nsfw: bool,
}
},
"PartialEmoji"
);
auto_derived!(
/// Parent Id of the emoji
#[serde(tag = "type")]
pub enum EmojiParent {
Server { id: String },
Detached,
}
/// Partial representation of an emoji
pub struct PartialEmoji {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
}
);
#[allow(clippy::disallowed_methods)]
@@ -112,4 +109,18 @@ impl 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::Avatar) avatar,
(FieldsMember::Timeout) timeout,
(FieldsMember::Pronouns) pronouns,
((default) FieldsMember::Roles) roles,
((default) FieldsMember::CanPublish) can_publish,
((default) FieldsMember::CanReceive) can_receive,

View File

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

View File

@@ -1536,6 +1536,15 @@ impl From<crate::AuditLogEntryAction> for AuditLogEntryAction {
crate::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 } => {
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;
auto_derived!(
@@ -117,6 +117,11 @@ auto_derived!(
emoji: String,
name: String,
},
EmojiUpdate {
emoji: String,
before: PartialEmoji,
after: PartialEmoji,
},
EmojiDelete {
emoji: String,
name: String,

View File

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