mirror of
https://github.com/stoatchat/stoatchat.git
synced 2026-07-14 05:26:59 +00:00
feat: add role icon support (#724)
Signed-off-by: ispik <ispik@ispik.dev>
This commit is contained in:
@@ -70,6 +70,7 @@ auto_derived!(
|
||||
LegacyGroupIcon,
|
||||
ChannelIcon,
|
||||
ServerIcon,
|
||||
RoleIcon,
|
||||
}
|
||||
|
||||
/// Information about what the file was used for
|
||||
@@ -239,4 +240,23 @@ impl File {
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Use a file for a role icon
|
||||
pub async fn use_role_icon(
|
||||
db: &Database,
|
||||
id: &str,
|
||||
parent: &str,
|
||||
uploader_id: &str,
|
||||
) -> Result<File> {
|
||||
db.find_and_use_attachment(
|
||||
id,
|
||||
"icons",
|
||||
FileUsedFor {
|
||||
id: parent.to_owned(),
|
||||
object_type: FileUsedForType::RoleIcon,
|
||||
},
|
||||
uploader_id.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,6 +86,9 @@ auto_derived_partial!(
|
||||
/// Ranking of this role
|
||||
#[serde(default)]
|
||||
pub rank: i64,
|
||||
/// Custom icon attachment
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub icon: Option<File>,
|
||||
},
|
||||
"PartialRole"
|
||||
);
|
||||
@@ -129,6 +132,7 @@ auto_derived!(
|
||||
/// Optional fields on server object
|
||||
pub enum FieldsRole {
|
||||
Colour,
|
||||
Icon,
|
||||
}
|
||||
);
|
||||
|
||||
@@ -305,6 +309,7 @@ impl Role {
|
||||
colour: self.colour,
|
||||
hoist: Some(self.hoist),
|
||||
rank: Some(self.rank),
|
||||
icon: self.icon,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,6 +323,7 @@ impl Role {
|
||||
colour: None,
|
||||
hoist: false,
|
||||
permissions: Default::default(),
|
||||
icon: None,
|
||||
};
|
||||
|
||||
db.insert_role(&server.id, &role).await?;
|
||||
@@ -367,6 +373,7 @@ impl Role {
|
||||
pub fn remove_field(&mut self, field: &FieldsRole) {
|
||||
match field {
|
||||
FieldsRole::Colour => self.colour = None,
|
||||
FieldsRole::Icon => self.icon = None,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -172,6 +172,7 @@ impl IntoDocumentPath for FieldsRole {
|
||||
fn as_path(&self) -> Option<&'static str> {
|
||||
Some(match self {
|
||||
FieldsRole::Colour => "colour",
|
||||
FieldsRole::Icon => "icon",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ impl From<crate::Channel> for Channel {
|
||||
role_permissions,
|
||||
nsfw,
|
||||
voice,
|
||||
slowmode
|
||||
slowmode,
|
||||
} => Channel::TextChannel {
|
||||
id,
|
||||
server,
|
||||
@@ -202,7 +202,7 @@ impl From<crate::Channel> for Channel {
|
||||
role_permissions,
|
||||
nsfw,
|
||||
voice: voice.map(|voice| voice.into()),
|
||||
slowmode
|
||||
slowmode,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -256,7 +256,7 @@ impl From<Channel> for crate::Channel {
|
||||
role_permissions,
|
||||
nsfw,
|
||||
voice,
|
||||
slowmode
|
||||
slowmode,
|
||||
} => crate::Channel::TextChannel {
|
||||
id,
|
||||
server,
|
||||
@@ -268,7 +268,7 @@ impl From<Channel> for crate::Channel {
|
||||
role_permissions,
|
||||
nsfw,
|
||||
voice: voice.map(|voice| voice.into()),
|
||||
slowmode
|
||||
slowmode,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -307,7 +307,7 @@ impl From<PartialChannel> for crate::PartialChannel {
|
||||
default_permissions: value.default_permissions,
|
||||
last_message_id: value.last_message_id,
|
||||
voice: value.voice.map(|voice| voice.into()),
|
||||
slowmode: value.slowmode
|
||||
slowmode: value.slowmode,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -926,6 +926,7 @@ impl From<crate::Role> for Role {
|
||||
colour: value.colour,
|
||||
hoist: value.hoist,
|
||||
rank: value.rank,
|
||||
icon: value.icon.map(|f| f.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -939,6 +940,7 @@ impl From<Role> for crate::Role {
|
||||
colour: value.colour,
|
||||
hoist: value.hoist,
|
||||
rank: value.rank,
|
||||
icon: value.icon.map(|f| f.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -952,6 +954,7 @@ impl From<crate::PartialRole> for PartialRole {
|
||||
colour: value.colour,
|
||||
hoist: value.hoist,
|
||||
rank: value.rank,
|
||||
icon: value.icon.map(|f| f.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -965,6 +968,7 @@ impl From<PartialRole> for crate::PartialRole {
|
||||
colour: value.colour,
|
||||
hoist: value.hoist,
|
||||
rank: value.rank,
|
||||
icon: value.icon.map(|f| f.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -973,6 +977,7 @@ impl From<crate::FieldsRole> for FieldsRole {
|
||||
fn from(value: crate::FieldsRole) -> Self {
|
||||
match value {
|
||||
crate::FieldsRole::Colour => FieldsRole::Colour,
|
||||
crate::FieldsRole::Icon => FieldsRole::Icon,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -981,6 +986,7 @@ impl From<FieldsRole> for crate::FieldsRole {
|
||||
fn from(value: FieldsRole) -> Self {
|
||||
match value {
|
||||
FieldsRole::Colour => crate::FieldsRole::Colour,
|
||||
FieldsRole::Icon => crate::FieldsRole::Icon,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,6 +106,9 @@ auto_derived_partial!(
|
||||
/// Ranking of this role
|
||||
#[cfg_attr(feature = "serde", serde(default))]
|
||||
pub rank: i64,
|
||||
/// Role icon
|
||||
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
|
||||
pub icon: Option<File>,
|
||||
},
|
||||
"PartialRole"
|
||||
);
|
||||
@@ -123,6 +126,7 @@ auto_derived!(
|
||||
/// Optional fields on server object
|
||||
pub enum FieldsRole {
|
||||
Colour,
|
||||
Icon,
|
||||
}
|
||||
|
||||
/// Channel category
|
||||
@@ -278,6 +282,11 @@ auto_derived!(
|
||||
///
|
||||
/// **Removed** - no effect, use the edit server role positions route
|
||||
pub rank: Option<i64>,
|
||||
/// Role icon
|
||||
///
|
||||
/// Provide an Autumn attachment Id.
|
||||
#[cfg_attr(feature = "validator", validate(length(min = 1, max = 128)))]
|
||||
pub icon: Option<String>,
|
||||
/// Fields to remove from role object
|
||||
#[cfg_attr(feature = "serde", serde(default))]
|
||||
pub remove: Vec<FieldsRole>,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use revolt_database::{
|
||||
util::{permissions::DatabasePermissionQuery, reference::Reference},
|
||||
voice::{sync_voice_permissions, VoiceClient},
|
||||
Database, PartialRole, User
|
||||
Database, File, PartialRole, User,
|
||||
};
|
||||
use revolt_models::v0;
|
||||
use revolt_permissions::{calculate_server_permissions, ChannelPermission};
|
||||
@@ -47,14 +47,27 @@ pub async fn edit(
|
||||
name,
|
||||
colour,
|
||||
hoist,
|
||||
icon,
|
||||
remove,
|
||||
..
|
||||
} = data;
|
||||
|
||||
if remove.contains(&v0::FieldsRole::Icon) {
|
||||
if let Some(existing_icon) = &role.icon {
|
||||
db.mark_attachment_as_deleted(&existing_icon.id).await?;
|
||||
}
|
||||
}
|
||||
|
||||
let mut final_icon = None;
|
||||
if let Some(icon_id) = icon {
|
||||
final_icon = Some(File::use_role_icon(db, &icon_id, &role_id, &user.id).await?);
|
||||
}
|
||||
|
||||
let partial = PartialRole {
|
||||
name,
|
||||
colour,
|
||||
hoist,
|
||||
icon: final_icon,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
@@ -69,8 +82,9 @@ pub async fn edit(
|
||||
for channel_id in &server.channels {
|
||||
let channel = Reference::from_unchecked(channel_id).as_channel(db).await?;
|
||||
|
||||
sync_voice_permissions(db, voice_client, &channel, Some(&server), Some(&role_id)).await?;
|
||||
};
|
||||
sync_voice_permissions(db, voice_client, &channel, Some(&server), Some(&role_id))
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(Json(role.into()))
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user