soundfx-bot/src/event_handlers.rs
2023-12-18 21:54:34 +00:00

222 lines
11 KiB
Rust

use poise::serenity_prelude::{
model::channel::Channel, ActionRowComponent, Activity, Context, CreateActionRow, FullEvent,
Interaction,
};
#[cfg(feature = "metrics")]
use crate::metrics::GREET_COUNTER;
use crate::{
cmds::search::SoundPager,
models::{
guild_data::{AllowGreet, CtxGuildData},
join_sound::JoinSoundCtx,
sound::Sound,
},
utils::{join_channel, play_audio, play_from_query},
Data, Error,
};
pub async fn listener(ctx: &Context, event: &FullEvent, data: &Data) -> Result<(), Error> {
match event {
FullEvent::Ready { .. } => {
ctx.set_activity(Activity::watching("for /play")).await;
}
FullEvent::VoiceStateUpdate { old, new, .. } => {
if let Some(past_state) = old {
if let (Some(guild_id), None) = (past_state.guild_id, new.channel_id) {
if let Some(channel_id) = past_state.channel_id {
if let Some(Channel::Guild(channel)) =
channel_id.to_channel_cached(&ctx.cache)
{
if channel.members(&ctx).await.map(|m| m.len()).unwrap_or(0) <= 1 {
let songbird = songbird::get(ctx).await.unwrap();
let _ = songbird.remove(guild_id).await;
}
}
}
}
} else if let (Some(guild_id), Some(user_channel)) = (new.guild_id, new.channel_id) {
if let Some(guild) = ctx.cache.guild(guild_id) {
let guild_data_opt = data.guild_data(guild.id).await;
if let Ok(guild_data) = guild_data_opt {
let volume;
let allowed_greets;
{
let read = guild_data.read().await;
volume = read.volume;
allowed_greets = read.allow_greets;
}
if allowed_greets != AllowGreet::Disabled {
if let Some(join_id) = data
.join_sound(
new.user_id,
new.guild_id,
allowed_greets == AllowGreet::GuildOnly,
)
.await
{
let mut sound = sqlx::query_as_unchecked!(
Sound,
"
SELECT name, id, public, server_id, uploader_id
FROM sounds
WHERE id = ?",
join_id
)
.fetch_one(&data.database)
.await
.unwrap();
let (handler, _) = join_channel(&ctx, guild, user_channel).await;
#[cfg(feature = "metrics")]
GREET_COUNTER.inc();
play_audio(
&mut sound,
volume,
&mut handler.lock().await,
&data.database,
false,
)
.await
.unwrap();
}
}
}
}
}
}
FullEvent::InteractionCreate { interaction } => match interaction {
Interaction::MessageComponent(component) => {
if let Some(guild_id) = component.guild_id {
if let Ok(()) = SoundPager::handle_interaction(ctx, &data, component).await {
} else {
let mode = component.data.custom_id.as_str();
match mode {
"#stop" => {
component
.create_interaction_response(ctx, |r| {
r.kind(InteractionResponseType::DeferredUpdateMessage)
})
.await
.unwrap();
let songbird = songbird::get(ctx).await.unwrap();
let call_opt = songbird.get(guild_id);
if let Some(call) = call_opt {
let mut lock = call.lock().await;
lock.stop();
}
}
"#loop" | "#queue" | "#instant" => {
component
.create_interaction_response(ctx, |r| {
r.kind(InteractionResponseType::UpdateMessage)
.interaction_response_data(|d| {
let mut c = vec![];
for action_row in &component.message.components {
let mut a: CreateActionRow = Default::default();
// These are always buttons
for component in &action_row.components {
match component {
ActionRowComponent::Button(button) => {
a.create_button(|b| {
if let Some(label) =
&button.label
{
b.label(label);
}
if let Some(emoji) =
&button.emoji
{
b.emoji(emoji.clone());
}
if let Some(custom_id) =
&button.custom_id
{
if custom_id
.starts_with('#')
{
b.custom_id(custom_id)
.disabled(
custom_id
== "#mode"
|| custom_id
== mode,
);
} else {
b.custom_id(format!(
"{}{}",
custom_id
.split('#')
.next()
.unwrap(),
mode
));
}
}
b.style(button.style);
b
});
}
_ => {}
}
}
c.push(a);
}
d.set_components(c)
})
})
.await
.unwrap();
}
id_mode => {
component
.create_interaction_response(ctx, |r| {
r.kind(InteractionResponseType::DeferredUpdateMessage)
})
.await
.unwrap();
let mut it = id_mode.split('#');
let id = it.next().unwrap();
let mode = it.next().unwrap_or("instant");
play_from_query(
&ctx,
&data,
guild_id.to_guild_cached(&ctx).unwrap(),
component.user.id,
None,
id.split('#').next().unwrap(),
mode == "loop",
)
.await;
}
}
}
}
}
_ => {}
},
_ => {}
}
Ok(())
}