Merge remote-tracking branch 'origin/main' into chore/utoipa

This commit is contained in:
Zomatree
2025-11-17 23:11:21 +00:00
parent 43c94b68b0
commit d198796fde
155 changed files with 34536 additions and 846 deletions

View File

@@ -18,7 +18,7 @@ macro_rules! auto_derived {
$(
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "utoipa", derive(ToSchema))]
#[derive(Debug, Clone, Eq, PartialEq)]
#[derive(Debug, Clone, PartialEq)]
$item
)+
};
@@ -27,8 +27,8 @@ macro_rules! auto_derived {
#[cfg(feature = "partials")]
macro_rules! auto_derived_partial {
( $item:item, $name:expr ) => {
#[derive(OptionalStruct, Debug, Clone, Eq, PartialEq, Serialize, Deserialize, ToSchema)]
#[optional_derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, ToSchema, Default)]
#[derive(OptionalStruct, Debug, Clone, PartialEq, Serialize, Deserialize, ToSchema)]
#[optional_derive(Debug, Clone, PartialEq, Serialize, Deserialize, ToSchema, Default)]
#[optional_name = $name]
#[opt_skip_serializing_none]
#[opt_some_priority]
@@ -39,7 +39,7 @@ macro_rules! auto_derived_partial {
#[cfg(not(feature = "partials"))]
macro_rules! auto_derived_partial {
( $item:item, $name:expr ) => {
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, ToSchema)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ToSchema)]
$item
};
}

View File

@@ -1,4 +1,5 @@
use super::File;
#![allow(deprecated)]
use super::{File, UserVoiceState};
use revolt_permissions::{Override, OverrideField};
use std::collections::{HashMap, HashSet};
@@ -107,44 +108,21 @@ auto_derived!(
serde(skip_serializing_if = "crate::if_false", default)
)]
nsfw: bool,
/// Voice Information for when this channel is also a voice channel
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
voice: Option<VoiceInformation>,
},
/// Voice channel belonging to a server
VoiceChannel {
/// Unique Id
#[cfg_attr(feature = "serde", serde(rename = "_id"))]
id: String,
/// Id of the server this channel belongs to
server: String,
}
/// Display name of the channel
name: String,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
/// Channel description
description: Option<String>,
/// Custom icon attachment
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
icon: Option<File>,
/// Default permissions assigned to users in this channel
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
default_permissions: Option<OverrideField>,
/// Permissions assigned based on role to this channel
#[cfg_attr(
feature = "serde",
serde(
default = "HashMap::<String, OverrideField>::new",
skip_serializing_if = "HashMap::<String, OverrideField>::is_empty"
)
)]
role_permissions: HashMap<String, OverrideField>,
/// Whether this channel is marked as not safe for work
#[cfg_attr(
feature = "serde",
serde(skip_serializing_if = "crate::if_false", default)
)]
nsfw: bool,
},
/// Voice information for a channel
#[derive(Default)]
#[cfg_attr(feature = "validator", derive(validator::Validate))]
pub struct VoiceInformation {
/// Maximium amount of users allowed in the voice channel at once
#[cfg_attr(feature = "validator", validate(range(min = 1)))]
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
pub max_users: Option<usize>,
}
/// Partial representation of a channel
@@ -170,6 +148,8 @@ auto_derived!(
pub default_permissions: Option<OverrideField>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
pub last_message_id: Option<String>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
pub voice: Option<VoiceInformation>,
}
/// Optional fields on channel object
@@ -177,6 +157,7 @@ auto_derived!(
Description,
Icon,
DefaultPermissions,
Voice,
}
/// New webhook information
@@ -205,6 +186,9 @@ auto_derived!(
/// Whether this channel is archived
pub archived: Option<bool>,
/// Voice Information for voice channels
pub voice: Option<VoiceInformation>,
/// Fields to remove from channel
#[cfg_attr(feature = "serde", serde(default))]
pub remove: Vec<FieldsChannel>,
@@ -260,6 +244,10 @@ auto_derived!(
/// Whether this channel is age restricted
#[serde(skip_serializing_if = "Option::is_none")]
pub nsfw: Option<bool>,
/// Voice Information for when this channel is also a voice channel
#[serde(skip_serializing_if = "Option::is_none")]
pub voice: Option<VoiceInformation>,
}
/// New default permissions
@@ -270,7 +258,7 @@ auto_derived!(
permissions: u64,
},
Field {
/// Allow / deny values to set for members in this `TextChannel` or `VoiceChannel`
/// Allow / deny values to set for members in this server channel
permissions: Override,
},
}
@@ -290,9 +278,32 @@ auto_derived!(
}
/// Voice server token response
pub struct LegacyCreateVoiceUserResponse {
pub struct CreateVoiceUserResponse {
/// Token for authenticating with the voice server
token: String,
pub token: String,
/// Url of the livekit server to connect to
pub url: String,
}
/// Voice state for a channel
pub struct ChannelVoiceState {
pub id: String,
/// The states of the users who are connected to the channel
pub participants: Vec<UserVoiceState>,
}
/// Join a voice channel
pub struct DataJoinCall {
/// Name of the node to join
pub node: Option<String>,
/// Whether to force disconnect any other existing voice connections
///
/// Useful for disconnecting on another device and joining on a new.
pub force_disconnect: Option<bool>,
/// Users which should be notified of the call starting
///
/// Only used when the user is the first one connected.
pub recipients: Option<Vec<String>>,
}
);
@@ -303,8 +314,7 @@ impl Channel {
Channel::DirectMessage { id, .. }
| Channel::Group { id, .. }
| Channel::SavedMessages { id, .. }
| Channel::TextChannel { id, .. }
| Channel::VoiceChannel { id, .. } => id,
| Channel::TextChannel { id, .. } => id,
}
}
@@ -316,9 +326,7 @@ impl Channel {
match self {
Channel::DirectMessage { .. } => None,
Channel::SavedMessages { .. } => Some("Saved Messages"),
Channel::TextChannel { name, .. }
| Channel::Group { name, .. }
| Channel::VoiceChannel { name, .. } => Some(name),
Channel::TextChannel { name, .. } | Channel::Group { name, .. } => Some(name),
}
}
}

View File

@@ -15,16 +15,21 @@ auto_derived!(
pub url: String,
}
/// Voice Server Configuration
/// # Information about a livekit node
pub struct VoiceNode {
pub name: String,
pub lat: f64,
pub lon: f64,
pub public_url: String,
}
/// # Voice Server Configuration
pub struct VoiceFeature {
/// Whether voice is enabled
pub enabled: bool,
/// URL pointing to the voice API
pub url: String,
/// URL pointing to the voice WebSocket server
pub ws: String,
/// All livekit nodes
pub nodes: Vec<VoiceNode>,
}
/// Feature Configuration
pub struct RevoltFeatures {
/// hCaptcha configuration
@@ -38,7 +43,7 @@ auto_derived!(
/// Proxy service configuration
pub january: Feature,
/// Voice server configuration
pub voso: VoiceFeature,
pub livekit: VoiceFeature,
}
/// Build Information

View File

@@ -132,6 +132,8 @@ auto_derived!(
MessagePinned { id: String, by: String },
#[serde(rename = "message_unpinned")]
MessageUnpinned { id: String, by: String },
#[serde(rename = "call_started")]
CallStarted { by: String, finished_at: Option<Timestamp> },
}
/// Name and / or avatar override information
@@ -447,6 +449,7 @@ impl From<SystemMessage> for String {
}
SystemMessage::MessagePinned { .. } => "Message pinned.".to_string(),
SystemMessage::MessageUnpinned { .. } => "Message unpinned.".to_string(),
SystemMessage::CallStarted { .. } => "Call started.".to_string(),
}
}
}

View File

@@ -31,6 +31,14 @@ pub static RE_COLOUR: Lazy<Regex> = Lazy::new(|| {
Regex::new(r"(?i)^(?:[a-z ]+|var\(--[a-z\d-]+\)|rgba?\([\d, ]+\)|#[a-f0-9]+|(repeating-)?(linear|conic|radial)-gradient\(([a-z ]+|var\(--[a-z\d-]+\)|rgba?\([\d, ]+\)|#[a-f0-9]+|\d+deg)([ ]+(\d{1,3}%|0))?(,[ ]*([a-z ]+|var\(--[a-z\d-]+\)|rgba?\([\d, ]+\)|#[a-f0-9]+)([ ]+(\d{1,3}%|0))?)+\))$").unwrap()
});
fn default_true() -> bool {
true
}
fn is_true(x: &bool) -> bool {
*x
}
auto_derived_partial!(
/// Server Member
pub struct Member {
@@ -57,6 +65,13 @@ auto_derived_partial!(
/// Timestamp this member is timed out until
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
pub timeout: Option<Timestamp>,
/// Whether the member is server-wide voice muted
#[serde(skip_serializing_if = "is_true", default = "default_true")]
pub can_publish: bool,
/// Whether the member is server-wide voice deafened
#[serde(skip_serializing_if = "is_true", default = "default_true")]
pub can_receive: bool,
},
"PartialMember"
);
@@ -77,6 +92,8 @@ auto_derived!(
Avatar,
Roles,
Timeout,
CanReceive,
CanPublish,
JoinedAt,
}
@@ -125,6 +142,12 @@ auto_derived!(
pub roles: Option<Vec<String>>,
/// Timestamp this member is timed out until
pub timeout: Option<Timestamp>,
/// server-wide voice muted
pub can_publish: Option<bool>,
/// server-wide voice deafened
pub can_receive: Option<bool>,
/// voice channel to move to if already in a voice channel
pub voice_channel: Option<String>,
/// Fields to remove from channel object
#[cfg_attr(feature = "serde", serde(default))]
pub remove: Vec<FieldsMember>,

View File

@@ -1,3 +1,4 @@
use iso8601_timestamp::Timestamp;
use once_cell::sync::Lazy;
use regex::Regex;
@@ -279,6 +280,19 @@ auto_derived!(
}
);
auto_derived_partial!(
/// Voice State information for a user
pub struct UserVoiceState {
pub id: String,
pub joined_at: Timestamp,
pub is_receiving: bool,
pub is_publishing: bool,
pub screensharing: bool,
pub camera: bool,
},
"PartialUserVoiceState"
);
pub trait CheckRelationship {
fn with(&self, user: &str) -> RelationshipStatus;
}