Compare commits

...
Author SHA1 Message Date
stoat-release[bot] 786a232f81 chore(deps): update rust crate aes-gcm to 0.11.0 2026-07-07 13:37:20 +00:00
Zomatree 0b53db9921 fix: voice system messages and call notifs by fetching participant list (#846)
Signed-off-by: Zomatree <me@zomatree.live>
2026-07-06 22:37:27 -07:00
Zomatree 21daf3aec6 fix: allow removing channel slowmode (#836)
Signed-off-by: Zomatree <me@zomatree.live>
2026-07-02 19:23:52 -07:00
Tom 59f6e012f8 feat: replace tenor with gifbox (#844)
Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com>
2026-07-02 19:20:18 -07:00
Zomatree a22378c35c fix(docs): update react version (#842)
Signed-off-by: Zomatree <me@zomatree.live>
2026-06-27 04:24:00 +01:00
Zomatree 164be6a2da Revert "chore(deps): update dependency gh to v2.95.0" (#840)
Signed-off-by: Zomatree <me@zomatree.live>
2026-06-25 18:57:12 +01:00
11 changed files with 239 additions and 172 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
node = "25.4.0" node = "25.4.0"
pnpm = "10.28.1" pnpm = "10.28.1"
gh = "2.95.0" gh = "2.25.0"
rust = "1.92.0" rust = "1.92.0"
"cargo:cargo-nextest" = "0.9.122" "cargo:cargo-nextest" = "0.9.122"
Generated
+68 -38
View File
@@ -19,12 +19,12 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
[[package]] [[package]]
name = "aead" name = "aead"
version = "0.5.2" version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" checksum = "1973cfbc1a2daf9cf550e74e1f088c28e7f7d8c1e1418fb6c9dc5184b7e84c99"
dependencies = [ dependencies = [
"crypto-common 0.1.7", "crypto-common 0.2.2",
"generic-array 0.14.7", "inout 0.2.2",
] ]
[[package]] [[package]]
@@ -34,19 +34,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"cipher", "cipher 0.4.4",
"cpufeatures 0.2.17", "cpufeatures 0.2.17",
] ]
[[package]] [[package]]
name = "aes-gcm" name = "aes"
version = "0.10.3" version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" checksum = "f1fc76eaeac4c9164506c466d4ffdd8ec9d0c5bf57ee97177c4d8eceb3a0e138"
dependencies = [
"cipher 0.5.2",
"cpubits",
"cpufeatures 0.3.0",
]
[[package]]
name = "aes-gcm"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fdf011db2e21ce0d575593d749db5554b47fed37aff429e4dc50bc91ac93a028"
dependencies = [ dependencies = [
"aead", "aead",
"aes", "aes 0.9.1",
"cipher", "cipher 0.5.2",
"ctr", "ctr",
"ghash", "ghash",
"subtle", "subtle",
@@ -1445,7 +1456,7 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6"
dependencies = [ dependencies = [
"cipher", "cipher 0.4.4",
] ]
[[package]] [[package]]
@@ -1520,7 +1531,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
dependencies = [ dependencies = [
"crypto-common 0.1.7", "crypto-common 0.1.7",
"inout", "inout 0.1.4",
]
[[package]]
name = "cipher"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8cf2a2c93cd704877c0858356ed03480ff301ee950b43f1cbe4573b088bfa6c"
dependencies = [
"block-buffer 0.12.1",
"crypto-common 0.2.2",
"inout 0.2.2",
] ]
[[package]] [[package]]
@@ -1723,6 +1745,12 @@ dependencies = [
"libm", "libm",
] ]
[[package]]
name = "cpubits"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15b85f9c39137c3a891689859392b1bd49812121d0d61c9caf00d46ed5ce06ae"
[[package]] [[package]]
name = "cpufeatures" name = "cpufeatures"
version = "0.2.17" version = "0.2.17"
@@ -1840,7 +1868,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
dependencies = [ dependencies = [
"generic-array 0.14.7", "generic-array 0.14.7",
"rand_core 0.6.4",
"typenum", "typenum",
] ]
@@ -1850,7 +1877,9 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453"
dependencies = [ dependencies = [
"getrandom 0.4.3",
"hybrid-array", "hybrid-array",
"rand_core 0.10.1",
] ]
[[package]] [[package]]
@@ -1884,11 +1913,11 @@ checksum = "49fb0c6640b4507ebd99ff67677009e381ba5eee1d14df78de4a3d16eb123c39"
[[package]] [[package]]
name = "ctr" name = "ctr"
version = "0.9.2" version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" checksum = "baaca1c4b237092596f64d571e9db6ce4109c4ef9742e27590f1709594461f21"
dependencies = [ dependencies = [
"cipher", "cipher 0.5.2",
] ]
[[package]] [[package]]
@@ -2294,7 +2323,7 @@ version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffdd80ce8ce993de27e9f063a444a4d53ce8e8db4c1f00cc03af5ad5a9867a1e" checksum = "ffdd80ce8ce993de27e9f063a444a4d53ce8e8db4c1f00cc03af5ad5a9867a1e"
dependencies = [ dependencies = [
"cipher", "cipher 0.4.4",
] ]
[[package]] [[package]]
@@ -3188,11 +3217,10 @@ dependencies = [
[[package]] [[package]]
name = "ghash" name = "ghash"
version = "0.5.1" version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" checksum = "2eecf2d5dc9b66b732b97707a0210906b1d30523eb773193ab777c0c84b3e8d5"
dependencies = [ dependencies = [
"opaque-debug",
"polyval", "polyval",
] ]
@@ -4053,6 +4081,15 @@ dependencies = [
"generic-array 0.14.7", "generic-array 0.14.7",
] ]
[[package]]
name = "inout"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4250ce6452e92010fdf7268ccc5d14faa80bb12fc741938534c58f16804e03c7"
dependencies = [
"hybrid-array",
]
[[package]] [[package]]
name = "instant" name = "instant"
version = "0.1.13" version = "0.1.13"
@@ -5626,12 +5663,6 @@ dependencies = [
"portable-atomic", "portable-atomic",
] ]
[[package]]
name = "opaque-debug"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
[[package]] [[package]]
name = "openssl" name = "openssl"
version = "0.10.81" version = "0.10.81"
@@ -6257,7 +6288,7 @@ version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e847e2c91a18bfa887dd028ec33f2fe6f25db77db3619024764914affe8b69a6" checksum = "e847e2c91a18bfa887dd028ec33f2fe6f25db77db3619024764914affe8b69a6"
dependencies = [ dependencies = [
"aes", "aes 0.8.4",
"cbc", "cbc",
"der 0.7.10", "der 0.7.10",
"pbkdf2", "pbkdf2",
@@ -6334,13 +6365,12 @@ dependencies = [
[[package]] [[package]]
name = "polyval" name = "polyval"
version = "0.6.2" version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" checksum = "7dfc63250416fea14f5749b90725916a6c903f599d51cb635aa7a52bfd03eede"
dependencies = [ dependencies = [
"cfg-if", "cpubits",
"cpufeatures 0.2.17", "cpufeatures 0.3.0",
"opaque-debug",
"universal-hash", "universal-hash",
] ]
@@ -6903,7 +6933,7 @@ version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62c64daa8e9438b84aaae55010a93f396f8e60e3911590fcba770d04643fc1dd" checksum = "62c64daa8e9438b84aaae55010a93f396f8e60e3911590fcba770d04643fc1dd"
dependencies = [ dependencies = [
"cipher", "cipher 0.4.4",
] ]
[[package]] [[package]]
@@ -8212,7 +8242,7 @@ version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213"
dependencies = [ dependencies = [
"cipher", "cipher 0.4.4",
] ]
[[package]] [[package]]
@@ -9946,12 +9976,12 @@ checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
[[package]] [[package]]
name = "universal-hash" name = "universal-hash"
version = "0.5.1" version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" checksum = "f4987bdc12753382e0bec4a65c50738ffaabc998b9cdd1f952fb5f39b0048a96"
dependencies = [ dependencies = [
"crypto-common 0.1.7", "crypto-common 0.2.2",
"subtle", "ctutils",
] ]
[[package]] [[package]]
+1 -1
View File
@@ -177,7 +177,7 @@ revolt_optional_struct = "0.2.0"
unicode-segmentation = "1.10.1" unicode-segmentation = "1.10.1"
querystring = "1.1.0" querystring = "1.1.0"
tempfile = "3.12.0" tempfile = "3.12.0"
aes-gcm = "0.10.3" aes-gcm = "0.11.0"
auto_ops = "0.3.0" auto_ops = "0.3.0"
url = "2.2.2" url = "2.2.2"
impl_ops = "0.1.1" impl_ops = "0.1.1"
@@ -161,6 +161,7 @@ auto_derived!(
Icon, Icon,
DefaultPermissions, DefaultPermissions,
Voice, Voice,
Slowmode,
} }
); );
@@ -554,6 +555,12 @@ impl Channel {
} }
_ => {} _ => {}
}, },
FieldsChannel::Slowmode => match self {
Self::TextChannel { slowmode, .. } => {
slowmode.take();
}
_ => {}
}
} }
} }
@@ -777,6 +784,7 @@ impl IntoDocumentPath for FieldsChannel {
FieldsChannel::Icon => "icon", FieldsChannel::Icon => "icon",
FieldsChannel::DefaultPermissions => "default_permissions", FieldsChannel::DefaultPermissions => "default_permissions",
FieldsChannel::Voice => "voice", FieldsChannel::Voice => "voice",
FieldsChannel::Slowmode => "slowmode",
}) })
} }
} }
@@ -319,6 +319,7 @@ impl From<FieldsChannel> for crate::FieldsChannel {
FieldsChannel::Icon => crate::FieldsChannel::Icon, FieldsChannel::Icon => crate::FieldsChannel::Icon,
FieldsChannel::DefaultPermissions => crate::FieldsChannel::DefaultPermissions, FieldsChannel::DefaultPermissions => crate::FieldsChannel::DefaultPermissions,
FieldsChannel::Voice => crate::FieldsChannel::Voice, FieldsChannel::Voice => crate::FieldsChannel::Voice,
FieldsChannel::Slowmode => crate::FieldsChannel::Slowmode,
} }
} }
} }
@@ -330,6 +331,7 @@ impl From<crate::FieldsChannel> for FieldsChannel {
crate::FieldsChannel::Icon => FieldsChannel::Icon, crate::FieldsChannel::Icon => FieldsChannel::Icon,
crate::FieldsChannel::DefaultPermissions => FieldsChannel::DefaultPermissions, crate::FieldsChannel::DefaultPermissions => FieldsChannel::DefaultPermissions,
crate::FieldsChannel::Voice => FieldsChannel::Voice, crate::FieldsChannel::Voice => FieldsChannel::Voice,
crate::FieldsChannel::Slowmode => FieldsChannel::Slowmode,
} }
} }
} }
@@ -159,4 +159,17 @@ impl VoiceClient {
.await .await
.to_internal_error() .to_internal_error()
} }
pub async fn get_room_participants(
&self,
node: &str,
channel_id: &str,
) -> Result<Vec<ParticipantInfo>> {
let room = self.get_node(node)?;
room.client
.list_participants(channel_id)
.await
.to_internal_error()
}
} }
+1
View File
@@ -164,6 +164,7 @@ auto_derived!(
Icon, Icon,
DefaultPermissions, DefaultPermissions,
Voice, Voice,
Slowmode,
} }
/// New webhook information /// New webhook information
+91 -92
View File
@@ -1,19 +1,15 @@
use livekit_api::{access_token::TokenVerifier, webhooks::WebhookReceiver}; use livekit_api::{access_token::TokenVerifier, webhooks::WebhookReceiver};
use livekit_protocol::TrackType; use livekit_protocol::TrackType;
use revolt_database::{ use revolt_database::{
events::client::EventV1, AMQP, Database, PartialMessage, SystemMessage, events::client::EventV1, iso8601_timestamp::{Duration, Timestamp}, util::reference::Reference, voice::{
iso8601_timestamp::{Duration, Timestamp}, RoomMetadata, UserVoiceChannel, VoiceClient, create_voice_state, delete_channel_voice_state, delete_voice_state, get_call_notification_recipients, get_user_moved_from_voice, get_user_moved_to_voice, get_voice_channel_members, set_channel_call_started_system_message, take_channel_call_started_system_message, update_voice_state_tracks
util::reference::Reference, }
voice::{
create_voice_state, delete_channel_voice_state, delete_voice_state,
get_user_moved_from_voice, get_user_moved_to_voice, update_voice_state_tracks,
RoomMetadata, UserVoiceChannel, VoiceClient,
},
Database, AMQP,
}; };
use revolt_models::v0;
use revolt_result::{Result, ToRevoltError}; use revolt_result::{Result, ToRevoltError};
use rocket::{post, State}; use rocket::{post, State};
use rocket_empty::EmptyResponse; use rocket_empty::EmptyResponse;
use ulid::Ulid;
use crate::guard::AuthHeader; use crate::guard::AuthHeader;
@@ -21,12 +17,12 @@ use crate::guard::AuthHeader;
pub async fn ingress( pub async fn ingress(
db: &State<Database>, db: &State<Database>,
voice_client: &State<VoiceClient>, voice_client: &State<VoiceClient>,
_amqp: &State<AMQP>, amqp: &State<AMQP>,
node: &str, node: &str,
auth_header: AuthHeader<'_>, auth_header: AuthHeader<'_>,
body: &str, body: &str,
) -> Result<EmptyResponse> { ) -> Result<EmptyResponse> {
log::debug!("received event: {body:?}"); log::debug!("received event: {body}");
let config = revolt_config::config().await; let config = revolt_config::config().await;
@@ -63,16 +59,18 @@ pub async fn ingress(
let channel_id = channel_id.to_internal_error()?; let channel_id = channel_id.to_internal_error()?;
let user_id = user_id.to_internal_error()?; let user_id = user_id.to_internal_error()?;
let server_id = room_metadata.to_internal_error()?.server; let server_id = room_metadata.to_internal_error()?.server;
let channel = UserVoiceChannel { let voice_channel = UserVoiceChannel {
id: channel_id.clone(), id: channel_id.clone(),
server_id: server_id.clone(), server_id: server_id.clone(),
}; };
let channel = Reference::from_unchecked(channel_id).as_channel(db).await?;
let joined_at = Timestamp::UNIX_EPOCH let joined_at = Timestamp::UNIX_EPOCH
.checked_add(Duration::seconds(event.created_at)) .checked_add(Duration::seconds(event.created_at))
.unwrap(); .unwrap();
let voice_state = create_voice_state(&channel, user_id, joined_at).await?; let voice_state = create_voice_state(&voice_channel, user_id, joined_at).await?;
// Only publish one event when a user is moved from one channel to another. // Only publish one event when a user is moved from one channel to another.
if let Some(moved_from) = get_user_moved_to_voice(channel_id, user_id).await? { if let Some(moved_from) = get_user_moved_to_voice(channel_id, user_id).await? {
@@ -93,63 +91,66 @@ pub async fn ingress(
.await; .await;
}; };
// TODO: fix `num_participants` being incorrect sometimes see (#457) let participants = voice_client.get_room_participants(node, channel_id).await?;
// First user who joined - send call started system message.
// if event.room.as_ref().unwrap().num_participants == 1 {
// let user = Reference::from_unchecked(user_id).as_user(db).await?;
// let message_id = if participants.len() == 1 {
// Ulid::from_datetime(DateTime::from_timestamp_secs(event.created_at).unwrap()) let user = Reference::from_unchecked(user_id).as_user(db).await?;
// .to_string(); let message_id = Ulid::from_datetime(
Timestamp::UNIX_EPOCH
.checked_add(Duration::seconds(event.created_at))
.unwrap()
.into(),
)
.to_string();
// let mut call_started_message = SystemMessage::CallStarted { let mut call_started_message = SystemMessage::CallStarted {
// by: user_id.to_string(), by: user_id.to_string(),
// finished_at: None, finished_at: None,
// } }
// .into_message(channel.id().to_string()); .into_message(channel_id.clone());
// call_started_message.id = message_id; call_started_message.id = message_id;
// set_channel_call_started_system_message(channel.id(), &call_started_message.id) set_channel_call_started_system_message(channel_id, &call_started_message.id)
// .await?; .await?;
// call_started_message call_started_message
// .send( .send(
// db, db,
// Some(amqp), Some(amqp),
// v0::MessageAuthor::System { v0::MessageAuthor::System {
// username: &user.username, username: &user.username,
// avatar: user.avatar.as_ref().map(|file| file.id.as_ref()), avatar: user.avatar.as_ref().map(|file| file.id.as_ref()),
// }, },
// None, None,
// None, None,
// &channel, &channel,
// false, false,
// ) )
// .await?; .await?;
// let recipients = get_call_notification_recipients(&channel_id, &user_id).await?; let recipients = get_call_notification_recipients(channel_id, user_id).await?;
// let now = joined_at.format_short().to_string(); let now = joined_at.format_short().to_string();
// if let Err(e) = amqp if let Err(e) = amqp
// .dm_call_updated(&user.id, channel.id(), Some(&now), false, recipients) .dm_call_updated(&user.id, channel_id, Some(&now), false, recipients)
// .await .await
// { {
// revolt_config::capture_error(&e); revolt_config::capture_error(&e);
// } }
// } }
} }
// User left a channel // User left a channel
"participant_left" => { "participant_left" => {
let channel_id = channel_id.to_internal_error()?; let channel_id = channel_id.to_internal_error()?;
let user_id = user_id.to_internal_error()?; let user_id = user_id.to_internal_error()?;
let server_id = room_metadata.to_internal_error()?.server; let server_id = room_metadata.to_internal_error()?.server;
let channel = UserVoiceChannel { let voice_channel = UserVoiceChannel {
id: channel_id.clone(), id: channel_id.clone(),
server_id: server_id.clone(), server_id: server_id.clone(),
}; };
delete_voice_state(&channel, user_id).await?; delete_voice_state(&voice_channel, user_id).await?;
// Dont send leave event when a user is moved // Dont send leave event when a user is moved
if get_user_moved_from_voice(channel_id, user_id) if get_user_moved_from_voice(channel_id, user_id)
@@ -164,49 +165,47 @@ pub async fn ingress(
.await; .await;
}; };
// See above for why this is commented out
// // Update CallStarted system message if everyone has left with the end time // // Update CallStarted system message if everyone has left with the end time
// let members = get_voice_channel_members(channel_id).await?; let members = get_voice_channel_members(&voice_channel).await?;
// if members.is_none_or(|m| m.is_empty()) { if members.is_none_or(|m| m.is_empty()) {
// // The channel is empty so send out an "end" message for ringing // The channel is empty so send out an "end" message for ringing
// if let Err(e) = amqp if let Err(e) = amqp
// .dm_call_updated(user_id, channel_id, None, true, None) .dm_call_updated(user_id, channel_id, None, true, None)
// .await .await
// { {
// revolt_config::capture_internal_error!(&e); revolt_config::capture_internal_error!(&e);
// } }
// if let Some(system_message_id) = if let Some(system_message_id) =
// take_channel_call_started_system_message(channel_id).await? take_channel_call_started_system_message(channel_id).await?
// { {
// // Could have been deleted // Could have been deleted
// if let Ok(mut message) = Reference::from_unchecked(&system_message_id) if let Ok(mut message) = Reference::from_unchecked(&system_message_id)
// .as_message(db) .as_message(db)
// .await .await
// { {
// if let Some(SystemMessage::CallStarted { finished_at, .. }) = if let Some(SystemMessage::CallStarted { finished_at, .. }) =
// &mut message.system &mut message.system
// { {
// *finished_at = Some(Timestamp::now_utc()); *finished_at = Some(Timestamp::now_utc());
// message message
// .update( .update(
// db, db,
// PartialMessage { PartialMessage {
// system: message.system.clone(), system: message.system.clone(),
// ..Default::default() ..Default::default()
// }, },
// Vec::new(), Vec::new(),
// ) )
// .await?; .await?;
// } else { } else {
// log::error!("Broken State: Call started message ID ({}) does not contain a CallStarted system message.", &message.id) log::error!("Broken State: Call started message ID ({}) does not contain a CallStarted system message.", &message.id)
// } }
// }; };
// }; };
// } }
} }
// Audio/video track was started/stopped/unmuted/muted // Audio/video track was started/stopped/unmuted/muted
"track_published" | "track_unpublished" | "track_unmuted" | "track_muted" => { "track_published" | "track_unpublished" | "track_unmuted" | "track_muted" => {
@@ -221,6 +221,9 @@ pub async fn edit(
v0::FieldsChannel::Voice => { v0::FieldsChannel::Voice => {
voice.take(); voice.take();
} }
v0::FieldsChannel::Slowmode => {
slowmode.take();
}
_ => {} _ => {}
} }
} }
+49 -38
View File
@@ -10,7 +10,7 @@ use tokio::sync::RwLock;
pub mod types; pub mod types;
const TENOR_API_BASE_URL: &str = "https://tenor.googleapis.com/v2"; const TENOR_API_BASE_URL: &str = "https://compat.gifbox.me/v2";
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
pub enum TenorError { pub enum TenorError {
@@ -59,7 +59,11 @@ impl Tenor {
} }
} }
pub async fn request<T: DeserializeOwned>(&self, path: &str, query: &[Option<(&str, &str)>]) -> Result<Arc<T>, TenorError> { pub async fn request<T: DeserializeOwned>(
&self,
path: &str,
query: &[Option<(&str, &str)>],
) -> Result<Arc<T>, TenorError> {
let response = self let response = self
.client .client
.get(format!("{TENOR_API_BASE_URL}{path}")) .get(format!("{TENOR_API_BASE_URL}{path}"))
@@ -95,24 +99,27 @@ impl Tenor {
} }
} }
let res = self.coalescion.execute(unique_key.clone(), || async move { let res = self
self.request::<types::PaginatedMediaResponse>( .coalescion
"/search", .execute(unique_key.clone(), || async move {
&[ self.request::<types::PaginatedMediaResponse>(
Some(("key", &self.key)), "/search",
Some(("q", query)), &[
Some(("client_key", "Gifbox")), Some(("key", &self.key)),
Some(("media_filter", "webm,tinywebm")), Some(("q", query)),
Some(("locale", locale)), Some(("client_key", "Gifbox")),
Some(("contentfilter", "high")), Some(("media_filter", "webm,tinywebm")),
Some(("limit", &limit.to_string())), Some(("locale", locale)),
position.is_empty().then_some(("pos", position)), Some(("contentfilter", "high")),
is_category.then_some(("component", "categories")) Some(("limit", &limit.to_string())),
] position.is_empty().then_some(("pos", position)),
).await is_category.then_some(("component", "categories")),
}) ],
.await )
.unwrap(); .await
})
.await
.unwrap();
if let Ok(resp) = &*res { if let Ok(resp) = &*res {
self.cache.write().await.insert(unique_key, resp.clone()); self.cache.write().await.insert(unique_key, resp.clone());
@@ -143,8 +150,9 @@ impl Tenor {
Some(("client_key", "Gifbox")), Some(("client_key", "Gifbox")),
Some(("locale", locale)), Some(("locale", locale)),
Some(("contentfilter", "high")), Some(("contentfilter", "high")),
] ],
).await )
.await
}) })
.await .await
.unwrap(); .unwrap();
@@ -173,22 +181,25 @@ impl Tenor {
} }
} }
let res = self.coalescion.execute(unique_key.clone(), || async move { let res = self
self.request::<types::PaginatedMediaResponse>( .coalescion
"/featured", .execute(unique_key.clone(), || async move {
&[ self.request::<types::PaginatedMediaResponse>(
Some(("key", &self.key)), "/featured",
Some(("client_key", "Gifbox")), &[
Some(("media_filter", "webm,tinywebm")), Some(("key", &self.key)),
Some(("locale", locale)), Some(("client_key", "Gifbox")),
Some(("contentfilter", "high")), Some(("media_filter", "webm,tinywebm")),
Some(("limit", &limit.to_string())), Some(("locale", locale)),
position.is_empty().then_some(("pos", position)), Some(("contentfilter", "high")),
] Some(("limit", &limit.to_string())),
).await position.is_empty().then_some(("pos", position)),
}) ],
.await )
.unwrap(); .await
})
.await
.unwrap();
if let Ok(resp) = &*res { if let Ok(resp) = &*res {
self.featured.write().await.insert(unique_key, resp.clone()); self.featured.write().await.insert(unique_key, resp.clone());
+2 -2
View File
@@ -22,8 +22,8 @@
"@scalar/docusaurus": "^0.7.21", "@scalar/docusaurus": "^0.7.21",
"clsx": "^2.0.0", "clsx": "^2.0.0",
"prism-react-renderer": "^2.3.0", "prism-react-renderer": "^2.3.0",
"react": "^19.0.0", "react": "^19.2.7",
"react-dom": "^19.0.0" "react-dom": "^19.2.7"
}, },
"devDependencies": { "devDependencies": {
"@docusaurus/module-type-aliases": "3.9.2", "@docusaurus/module-type-aliases": "3.9.2",