feat: allow kicking members from voice channels (#495)
This commit is contained in:
@@ -72,6 +72,7 @@ auto_derived!(
|
|||||||
CanReceive,
|
CanReceive,
|
||||||
CanPublish,
|
CanPublish,
|
||||||
JoinedAt,
|
JoinedAt,
|
||||||
|
VoiceChannel,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Member removal intention
|
/// Member removal intention
|
||||||
@@ -224,13 +225,14 @@ impl Member {
|
|||||||
|
|
||||||
pub fn remove_field(&mut self, field: &FieldsMember) {
|
pub fn remove_field(&mut self, field: &FieldsMember) {
|
||||||
match field {
|
match field {
|
||||||
FieldsMember::JoinedAt => (),
|
FieldsMember::JoinedAt => {},
|
||||||
FieldsMember::Avatar => self.avatar = None,
|
FieldsMember::Avatar => self.avatar = None,
|
||||||
FieldsMember::Nickname => self.nickname = None,
|
FieldsMember::Nickname => self.nickname = None,
|
||||||
FieldsMember::Roles => self.roles.clear(),
|
FieldsMember::Roles => self.roles.clear(),
|
||||||
FieldsMember::Timeout => self.timeout = None,
|
FieldsMember::Timeout => self.timeout = None,
|
||||||
FieldsMember::CanReceive => self.can_receive = true,
|
FieldsMember::CanReceive => self.can_receive = true,
|
||||||
FieldsMember::CanPublish => self.can_publish = true,
|
FieldsMember::CanPublish => self.can_publish = true,
|
||||||
|
FieldsMember::VoiceChannel => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -330,14 +330,15 @@ impl AbstractServerMembers for MongoDb {
|
|||||||
|
|
||||||
impl IntoDocumentPath for FieldsMember {
|
impl IntoDocumentPath for FieldsMember {
|
||||||
fn as_path(&self) -> Option<&'static str> {
|
fn as_path(&self) -> Option<&'static str> {
|
||||||
Some(match self {
|
match self {
|
||||||
FieldsMember::JoinedAt => "joined_at",
|
FieldsMember::JoinedAt => Some("joined_at"),
|
||||||
FieldsMember::Avatar => "avatar",
|
FieldsMember::Avatar => Some("avatar"),
|
||||||
FieldsMember::Nickname => "nickname",
|
FieldsMember::Nickname => Some("nickname"),
|
||||||
FieldsMember::Roles => "roles",
|
FieldsMember::Roles => Some("roles"),
|
||||||
FieldsMember::Timeout => "timeout",
|
FieldsMember::Timeout => Some("timeout"),
|
||||||
FieldsMember::CanPublish => "can_publish",
|
FieldsMember::CanPublish => Some("can_publish"),
|
||||||
FieldsMember::CanReceive => "can_receive",
|
FieldsMember::CanReceive => Some("can_receive"),
|
||||||
})
|
FieldsMember::VoiceChannel => None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -691,6 +691,7 @@ impl From<crate::FieldsMember> for FieldsMember {
|
|||||||
crate::FieldsMember::CanReceive => FieldsMember::CanReceive,
|
crate::FieldsMember::CanReceive => FieldsMember::CanReceive,
|
||||||
crate::FieldsMember::CanPublish => FieldsMember::CanPublish,
|
crate::FieldsMember::CanPublish => FieldsMember::CanPublish,
|
||||||
crate::FieldsMember::JoinedAt => FieldsMember::JoinedAt,
|
crate::FieldsMember::JoinedAt => FieldsMember::JoinedAt,
|
||||||
|
crate::FieldsMember::VoiceChannel => FieldsMember::VoiceChannel,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -705,6 +706,7 @@ impl From<FieldsMember> for crate::FieldsMember {
|
|||||||
FieldsMember::CanReceive => crate::FieldsMember::CanReceive,
|
FieldsMember::CanReceive => crate::FieldsMember::CanReceive,
|
||||||
FieldsMember::CanPublish => crate::FieldsMember::CanPublish,
|
FieldsMember::CanPublish => crate::FieldsMember::CanPublish,
|
||||||
FieldsMember::JoinedAt => crate::FieldsMember::JoinedAt,
|
FieldsMember::JoinedAt => crate::FieldsMember::JoinedAt,
|
||||||
|
FieldsMember::VoiceChannel => crate::FieldsMember::VoiceChannel,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ auto_derived!(
|
|||||||
CanReceive,
|
CanReceive,
|
||||||
CanPublish,
|
CanPublish,
|
||||||
JoinedAt,
|
JoinedAt,
|
||||||
|
VoiceChannel,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Member removal intention
|
/// Member removal intention
|
||||||
|
|||||||
@@ -98,13 +98,21 @@ pub async fn edit(
|
|||||||
permissions.throw_if_lacking_channel_permission(ChannelPermission::DeafenMembers)?;
|
permissions.throw_if_lacking_channel_permission(ChannelPermission::DeafenMembers)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let new_voice_channel = if let Some(new_channel) = &data.voice_channel {
|
if data.voice_channel.is_some() && data.remove.contains(&FieldsMember::VoiceChannel) {
|
||||||
|
return Err(create_error!(InvalidOperation))
|
||||||
|
}
|
||||||
|
|
||||||
|
if data.voice_channel.is_some() || data.remove.contains(&FieldsMember::VoiceChannel) {
|
||||||
if !voice_client.is_enabled() {
|
if !voice_client.is_enabled() {
|
||||||
return Err(create_error!(LiveKitUnavailable));
|
return Err(create_error!(LiveKitUnavailable));
|
||||||
};
|
};
|
||||||
|
|
||||||
permissions.throw_if_lacking_channel_permission(ChannelPermission::MoveMembers)?;
|
if member.id.user != user.id {
|
||||||
|
permissions.throw_if_lacking_channel_permission(ChannelPermission::MoveMembers)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let new_voice_channel = if let Some(new_channel) = &data.voice_channel {
|
||||||
// ensure the channel we are moving them to is in the server and is a voice channel
|
// ensure the channel we are moving them to is in the server and is a voice channel
|
||||||
|
|
||||||
let channel = Reference::from_unchecked(new_channel)
|
let channel = Reference::from_unchecked(new_channel)
|
||||||
@@ -116,6 +124,9 @@ pub async fn edit(
|
|||||||
Err(create_error!(UnknownChannel))?
|
Err(create_error!(UnknownChannel))?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let channel_permissions = calculate_channel_permissions(&mut query.clone().channel(&channel)).await;
|
||||||
|
channel_permissions.throw_if_lacking_channel_permission(ChannelPermission::Connect)?;
|
||||||
|
|
||||||
if get_user_voice_channel_in_server(&target_user.id, &server.id)
|
if get_user_voice_channel_in_server(&target_user.id, &server.id)
|
||||||
.await?
|
.await?
|
||||||
.is_none()
|
.is_none()
|
||||||
@@ -189,10 +200,8 @@ pub async fn edit(
|
|||||||
partial.avatar = Some(File::use_user_avatar(db, &avatar, &user.id, &user.id).await?);
|
partial.avatar = Some(File::use_user_avatar(db, &avatar, &user.id, &user.id).await?);
|
||||||
}
|
}
|
||||||
|
|
||||||
let remove_contains_voice = remove.contains(FieldsMember::CanPublish) || remove.contains(FieldsMember::CanReceive);
|
|
||||||
|
|
||||||
member
|
member
|
||||||
.update(db, partial, remove.into_iter().map(Into::into).collect())
|
.update(db, partial, remove.clone().into_iter().map(Into::into).collect())
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
if let Some(new_voice_channel) = new_voice_channel {
|
if let Some(new_voice_channel) = new_voice_channel {
|
||||||
@@ -234,7 +243,7 @@ pub async fn edit(
|
|||||||
.private(target_user.id.clone())
|
.private(target_user.id.clone())
|
||||||
.await;
|
.await;
|
||||||
};
|
};
|
||||||
} else if can_publish.is_some() || can_receive.is_some() || remove_contains_voice {
|
} else if can_publish.is_some() || can_receive.is_some() || remove.contains(FieldsMember::CanPublish) || remove.contains(FieldsMember::CanReceive) {
|
||||||
if let Some(channel) = get_user_voice_channel_in_server(&target_user.id, &server.id).await?
|
if let Some(channel) = get_user_voice_channel_in_server(&target_user.id, &server.id).await?
|
||||||
{
|
{
|
||||||
let node = get_channel_node(&channel).await?.unwrap();
|
let node = get_channel_node(&channel).await?.unwrap();
|
||||||
@@ -253,5 +262,14 @@ pub async fn edit(
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if remove.contains(&FieldsMember::VoiceChannel) {
|
||||||
|
if let Some(channel) = get_user_voice_channel_in_server(&target_user.id, &server.id).await?
|
||||||
|
{
|
||||||
|
let node = get_channel_node(&channel).await?.unwrap();
|
||||||
|
|
||||||
|
voice_client.remove_user(&node, &user.id, &channel).await?;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
Ok(Json(member.into()))
|
Ok(Json(member.into()))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user