Refactor code for improved readability and consistency across various command files

- Adjusted formatting and indentation in `rename.rs`, `suggestion.rs`, `tempvoc.rs`, `ticket.rs`, `ticket_member.rs`, and `tickets.rs` for better clarity.
- Consolidated `if` statements and method calls for cleaner code in `suggestion.rs`, `tempvoc.rs`, and `ticket.rs`.
- Updated the `LOGS_PER_PAGE` constant in `viewlogs.rs` to increase the number of logs displayed per page.
- Removed unused `handle_boostembed` function from `logs_service.rs`.
- Added new modules in `mod.rs` for better organization of command files.
- Enhanced the `handle_show_pics` function in `showpics.rs` for improved member filtering.
- Updated the `handle_message` function in `message_event.rs` to streamline command handling.
This commit is contained in:
Puechberty Arthur
2026-04-10 03:48:38 +02:00
parent 572cfa17b2
commit bc623a7736
16 changed files with 831 additions and 210 deletions
+635 -6
View File
@@ -1,9 +1,638 @@
use crate::commands::logs_service; use serenity::builder::{
CreateActionRow, CreateButton, CreateEmbed, CreateInputText, CreateInteractionResponse,
CreateInteractionResponseMessage, CreateMessage, CreateModal,
};
use serenity::model::application::{
ActionRowComponent, ButtonStyle, ComponentInteraction, InputTextStyle, ModalInteraction,
};
use serenity::model::prelude::*; use serenity::model::prelude::*;
use serenity::prelude::*; use serenity::prelude::*;
use crate::commands::common::{parse_channel_id, send_embed, theme_color};
use crate::commands::logs_service;
use crate::db::DbPoolKey;
const BOOSTEMBED_MENU: &str = "boostembed:settings";
#[derive(Clone)]
struct BoostEmbedSettings {
enabled: bool,
title: Option<String>,
description: Option<String>,
color: Option<i32>,
boost_channel_id: Option<i64>,
boost_channel_enabled: bool,
}
fn default_settings() -> BoostEmbedSettings {
BoostEmbedSettings {
enabled: true,
title: None,
description: None,
color: None,
boost_channel_id: None,
boost_channel_enabled: false,
}
}
fn parse_owner_id(custom_id: &str) -> Option<(String, u64)> {
let mut parts = custom_id.rsplitn(2, ':');
let owner = parts.next()?.parse::<u64>().ok()?;
let action = parts.next()?.to_string();
Some((action, owner))
}
fn modal_value(modal: &ModalInteraction, wanted_id: &str) -> Option<String> {
for row in &modal.data.components {
for component in &row.components {
if let ActionRowComponent::InputText(input) = component {
if input.custom_id == wanted_id {
return input.value.clone();
}
}
}
}
None
}
async fn pool(ctx: &Context) -> Option<sqlx::PgPool> {
let data = ctx.data.read().await;
data.get::<DbPoolKey>().cloned()
}
async fn ensure_boost_embed_row(pool: &sqlx::PgPool, bot_id: UserId, guild_id: GuildId) {
let _ = sqlx::query(
r#"
INSERT INTO bot_boost_embed (bot_id, guild_id, enabled, title, description, color)
VALUES ($1, $2, TRUE, NULL, NULL, NULL)
ON CONFLICT (bot_id, guild_id)
DO NOTHING;
"#,
)
.bind(bot_id.get() as i64)
.bind(guild_id.get() as i64)
.execute(pool)
.await;
}
async fn set_boost_embed_enabled(
pool: &sqlx::PgPool,
bot_id: UserId,
guild_id: GuildId,
enabled: bool,
) {
let _ = sqlx::query(
r#"
INSERT INTO bot_boost_embed (bot_id, guild_id, enabled)
VALUES ($1, $2, $3)
ON CONFLICT (bot_id, guild_id)
DO UPDATE SET enabled = EXCLUDED.enabled, updated_at = NOW();
"#,
)
.bind(bot_id.get() as i64)
.bind(guild_id.get() as i64)
.bind(enabled)
.execute(pool)
.await;
}
async fn set_boost_log_channel(
pool: &sqlx::PgPool,
bot_id: UserId,
guild_id: GuildId,
channel_id: Option<ChannelId>,
enabled: bool,
) {
let _ = sqlx::query(
r#"
INSERT INTO bot_log_channels (bot_id, guild_id, log_type, channel_id, enabled)
VALUES ($1, $2, 'boost', $3, $4)
ON CONFLICT (bot_id, guild_id, log_type)
DO UPDATE SET channel_id = EXCLUDED.channel_id, enabled = EXCLUDED.enabled, updated_at = NOW();
"#,
)
.bind(bot_id.get() as i64)
.bind(guild_id.get() as i64)
.bind(channel_id.map(|c| c.get() as i64))
.bind(enabled)
.execute(pool)
.await;
}
async fn read_settings(pool: &sqlx::PgPool, bot_id: UserId, guild_id: GuildId) -> BoostEmbedSettings {
let row = sqlx::query_as::<_, (bool, Option<String>, Option<String>, Option<i32>)>(
r#"
SELECT enabled, title, description, color
FROM bot_boost_embed
WHERE bot_id = $1 AND guild_id = $2
LIMIT 1;
"#,
)
.bind(bot_id.get() as i64)
.bind(guild_id.get() as i64)
.fetch_optional(pool)
.await
.ok()
.flatten();
let channel_row = sqlx::query_as::<_, (Option<i64>, bool)>(
r#"
SELECT channel_id, enabled
FROM bot_log_channels
WHERE bot_id = $1 AND guild_id = $2 AND log_type = 'boost'
LIMIT 1;
"#,
)
.bind(bot_id.get() as i64)
.bind(guild_id.get() as i64)
.fetch_optional(pool)
.await
.ok()
.flatten();
let mut settings = default_settings();
if let Some((enabled, title, description, color)) = row {
settings.enabled = enabled;
settings.title = title;
settings.description = description;
settings.color = color;
}
if let Some((channel_id, enabled)) = channel_row {
settings.boost_channel_id = channel_id;
settings.boost_channel_enabled = enabled;
}
settings
}
fn settings_embed(settings: &BoostEmbedSettings) -> CreateEmbed {
let channel_text = if settings.boost_channel_enabled {
settings
.boost_channel_id
.map(|id| format!("<#{}>", id))
.unwrap_or_else(|| "activé mais salon non défini".to_string())
} else {
"désactivé".to_string()
};
CreateEmbed::new()
.title("Configuration Boost Embed")
.description("Utilise les boutons/modals ci-dessous pour paramétrer l'embed de boost et son salon d'envoi.")
.field("Embed", if settings.enabled { "on" } else { "off" }, true)
.field("Salon d'envoi boost", channel_text, true)
.field(
"Titre",
settings
.title
.clone()
.unwrap_or_else(|| "(défaut)".to_string()),
false,
)
.field(
"Description",
settings
.description
.clone()
.unwrap_or_else(|| "(défaut)".to_string()),
false,
)
.field(
"Couleur",
settings
.color
.map(|v| format!("#{:06X}", v.max(0) as u32))
.unwrap_or_else(|| "(défaut)".to_string()),
true,
)
.color(0xF47FFF)
}
fn settings_components(owner_id: UserId, settings: &BoostEmbedSettings) -> Vec<CreateActionRow> {
let toggle_style = if settings.enabled {
ButtonStyle::Danger
} else {
ButtonStyle::Success
};
vec![
CreateActionRow::Buttons(vec![
CreateButton::new(format!("{}:toggle:{}", BOOSTEMBED_MENU, owner_id.get()))
.label(if settings.enabled {
"Désactiver embed"
} else {
"Activer embed"
})
.style(toggle_style),
CreateButton::new(format!("{}:test:{}", BOOSTEMBED_MENU, owner_id.get()))
.label("Envoyer test")
.style(ButtonStyle::Primary),
CreateButton::new(format!("{}:refresh:{}", BOOSTEMBED_MENU, owner_id.get()))
.label("Rafraîchir")
.style(ButtonStyle::Secondary),
]),
CreateActionRow::Buttons(vec![
CreateButton::new(format!("{}:set_here:{}", BOOSTEMBED_MENU, owner_id.get()))
.label("Salon = ici")
.style(ButtonStyle::Success),
CreateButton::new(format!("{}:edit_channel:{}", BOOSTEMBED_MENU, owner_id.get()))
.label("Définir salon")
.style(ButtonStyle::Secondary),
CreateButton::new(format!("{}:disable_channel:{}", BOOSTEMBED_MENU, owner_id.get()))
.label("Couper envoi")
.style(ButtonStyle::Danger),
]),
CreateActionRow::Buttons(vec![
CreateButton::new(format!("{}:edit_title:{}", BOOSTEMBED_MENU, owner_id.get()))
.label("Modifier titre")
.style(ButtonStyle::Secondary),
CreateButton::new(format!("{}:edit_description:{}", BOOSTEMBED_MENU, owner_id.get()))
.label("Modifier description")
.style(ButtonStyle::Secondary),
CreateButton::new(format!("{}:edit_color:{}", BOOSTEMBED_MENU, owner_id.get()))
.label("Modifier couleur")
.style(ButtonStyle::Secondary),
]),
]
}
async fn show_panel(
ctx: &Context,
msg: &Message,
pool: &sqlx::PgPool,
bot_id: UserId,
guild_id: GuildId,
) {
ensure_boost_embed_row(pool, bot_id, guild_id).await;
let settings = read_settings(pool, bot_id, guild_id).await;
let _ = msg
.channel_id
.send_message(
&ctx.http,
CreateMessage::new()
.embed(settings_embed(&settings))
.components(settings_components(msg.author.id, &settings)),
)
.await;
}
pub async fn handle_boostembed(ctx: &Context, msg: &Message, args: &[&str]) { pub async fn handle_boostembed(ctx: &Context, msg: &Message, args: &[&str]) {
logs_service::handle_boostembed(ctx, msg, args).await; let Some(guild_id) = msg.guild_id else {
return;
};
let Some(pool) = pool(ctx).await else {
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("BoostEmbed")
.description("DB indisponible.")
.color(0xED4245),
)
.await;
return;
};
let bot_id = ctx.cache.current_user().id;
if let Some(action) = args.first().map(|v| v.to_lowercase()) {
match action.as_str() {
"on" | "off" => {
set_boost_embed_enabled(&pool, bot_id, guild_id, action == "on").await;
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("BoostEmbed")
.description(if action == "on" { "Activé." } else { "Désactivé." })
.color(theme_color(ctx).await),
)
.await;
return;
}
"test" => {
logs_service::send_boost_embed(ctx, guild_id, &msg.author).await;
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("BoostEmbed")
.description("Test envoyé.")
.color(theme_color(ctx).await),
)
.await;
return;
}
"settings" | "panel" => {
show_panel(ctx, msg, &pool, bot_id, guild_id).await;
return;
}
_ => {
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("BoostEmbed")
.description("Usage: +boostembed [on|off|test|settings]")
.color(0xED4245),
)
.await;
return;
}
}
}
show_panel(ctx, msg, &pool, bot_id, guild_id).await;
}
pub async fn handle_component_interaction(ctx: &Context, component: &ComponentInteraction) -> bool {
if !component.data.custom_id.starts_with(BOOSTEMBED_MENU) {
return false;
}
let Some((action, owner_id)) = parse_owner_id(&component.data.custom_id) else {
return false;
};
if component.user.id.get() != owner_id {
let _ = component
.create_response(
&ctx.http,
CreateInteractionResponse::Message(
CreateInteractionResponseMessage::new()
.content("Seul l'auteur du panneau peut l'utiliser.")
.ephemeral(true),
),
)
.await;
return true;
}
let Some(guild_id) = component.guild_id else {
return true;
};
let Some(pool) = pool(ctx).await else {
let _ = component
.create_response(
&ctx.http,
CreateInteractionResponse::Message(
CreateInteractionResponseMessage::new()
.content("DB indisponible.")
.ephemeral(true),
),
)
.await;
return true;
};
let bot_id = ctx.cache.current_user().id;
ensure_boost_embed_row(&pool, bot_id, guild_id).await;
if action.ends_with(":edit_title") {
let modal = CreateModal::new(
format!("{}:modal:title:{}", BOOSTEMBED_MENU, component.user.id.get()),
"Modifier le titre du boost embed",
)
.components(vec![CreateActionRow::InputText(
CreateInputText::new(InputTextStyle::Short, "Titre (vide = défaut)", "title")
.required(false),
)]);
let _ = component
.create_response(&ctx.http, CreateInteractionResponse::Modal(modal))
.await;
return true;
}
if action.ends_with(":edit_description") {
let modal = CreateModal::new(
format!(
"{}:modal:description:{}",
BOOSTEMBED_MENU,
component.user.id.get()
),
"Modifier la description du boost embed",
)
.components(vec![CreateActionRow::InputText(
CreateInputText::new(
InputTextStyle::Paragraph,
"Description (vide = défaut)",
"description",
)
.required(false),
)]);
let _ = component
.create_response(&ctx.http, CreateInteractionResponse::Modal(modal))
.await;
return true;
}
if action.ends_with(":edit_color") {
let modal = CreateModal::new(
format!("{}:modal:color:{}", BOOSTEMBED_MENU, component.user.id.get()),
"Modifier la couleur du boost embed",
)
.components(vec![CreateActionRow::InputText(
CreateInputText::new(InputTextStyle::Short, "Couleur hex (#FF66CC)", "color")
.required(false),
)]);
let _ = component
.create_response(&ctx.http, CreateInteractionResponse::Modal(modal))
.await;
return true;
}
if action.ends_with(":edit_channel") {
let modal = CreateModal::new(
format!("{}:modal:channel:{}", BOOSTEMBED_MENU, component.user.id.get()),
"Définir le salon boost",
)
.components(vec![CreateActionRow::InputText(
CreateInputText::new(
InputTextStyle::Short,
"Salon (#mention ou ID, vide = désactiver)",
"channel",
)
.required(false),
)]);
let _ = component
.create_response(&ctx.http, CreateInteractionResponse::Modal(modal))
.await;
return true;
}
if action.ends_with(":toggle") {
let settings = read_settings(&pool, bot_id, guild_id).await;
set_boost_embed_enabled(&pool, bot_id, guild_id, !settings.enabled).await;
} else if action.ends_with(":set_here") {
set_boost_log_channel(&pool, bot_id, guild_id, Some(component.channel_id), true).await;
} else if action.ends_with(":disable_channel") {
set_boost_log_channel(&pool, bot_id, guild_id, None, false).await;
} else if action.ends_with(":test") {
logs_service::send_boost_embed(ctx, guild_id, &component.user).await;
}
let settings = read_settings(&pool, bot_id, guild_id).await;
let _ = component
.create_response(
&ctx.http,
CreateInteractionResponse::UpdateMessage(
CreateInteractionResponseMessage::new()
.embed(settings_embed(&settings))
.components(settings_components(component.user.id, &settings)),
),
)
.await;
true
}
pub async fn handle_modal_interaction(ctx: &Context, modal: &ModalInteraction) -> bool {
if !modal.data.custom_id.starts_with(&format!("{}:modal:", BOOSTEMBED_MENU)) {
return false;
}
let Some((action, owner_id)) = parse_owner_id(&modal.data.custom_id) else {
return false;
};
if modal.user.id.get() != owner_id {
let _ = modal
.create_response(
&ctx.http,
CreateInteractionResponse::Message(
CreateInteractionResponseMessage::new()
.content("Seul l'auteur du panneau peut l'utiliser.")
.ephemeral(true),
),
)
.await;
return true;
}
let Some(guild_id) = modal.guild_id else {
return true;
};
let Some(pool) = pool(ctx).await else {
let _ = modal
.create_response(
&ctx.http,
CreateInteractionResponse::Message(
CreateInteractionResponseMessage::new()
.content("DB indisponible.")
.ephemeral(true),
),
)
.await;
return true;
};
let bot_id = ctx.cache.current_user().id;
ensure_boost_embed_row(&pool, bot_id, guild_id).await;
if action.ends_with(":modal:title") {
let title = modal_value(modal, "title").unwrap_or_default();
let title_value = if title.trim().is_empty() {
None
} else {
Some(title)
};
let _ = sqlx::query(
"UPDATE bot_boost_embed SET title = $3, updated_at = NOW() WHERE bot_id = $1 AND guild_id = $2",
)
.bind(bot_id.get() as i64)
.bind(guild_id.get() as i64)
.bind(title_value)
.execute(&pool)
.await;
} else if action.ends_with(":modal:description") {
let description = modal_value(modal, "description").unwrap_or_default();
let desc_value = if description.trim().is_empty() {
None
} else {
Some(description)
};
let _ = sqlx::query(
"UPDATE bot_boost_embed SET description = $3, updated_at = NOW() WHERE bot_id = $1 AND guild_id = $2",
)
.bind(bot_id.get() as i64)
.bind(guild_id.get() as i64)
.bind(desc_value)
.execute(&pool)
.await;
} else if action.ends_with(":modal:color") {
let raw = modal_value(modal, "color").unwrap_or_default();
let color_value = if raw.trim().is_empty() {
None
} else {
let normalized = raw.trim().trim_start_matches('#').trim_start_matches("0x");
match u32::from_str_radix(normalized, 16) {
Ok(value) => Some(value as i32),
Err(_) => {
let _ = modal
.create_response(
&ctx.http,
CreateInteractionResponse::Message(
CreateInteractionResponseMessage::new()
.content("Couleur invalide. Exemple: `#FF66CC`")
.ephemeral(true),
),
)
.await;
return true;
}
}
};
let _ = sqlx::query(
"UPDATE bot_boost_embed SET color = $3, updated_at = NOW() WHERE bot_id = $1 AND guild_id = $2",
)
.bind(bot_id.get() as i64)
.bind(guild_id.get() as i64)
.bind(color_value)
.execute(&pool)
.await;
} else if action.ends_with(":modal:channel") {
let raw = modal_value(modal, "channel").unwrap_or_default();
if raw.trim().is_empty() {
set_boost_log_channel(&pool, bot_id, guild_id, None, false).await;
} else if let Some(channel) = parse_channel_id(&raw) {
set_boost_log_channel(&pool, bot_id, guild_id, Some(channel), true).await;
} else {
let _ = modal
.create_response(
&ctx.http,
CreateInteractionResponse::Message(
CreateInteractionResponseMessage::new()
.content("Salon invalide. Donne une mention `#salon` ou un ID.")
.ephemeral(true),
),
)
.await;
return true;
}
}
let _ = modal
.create_response(
&ctx.http,
CreateInteractionResponse::Message(
CreateInteractionResponseMessage::new()
.content("Configuration boost embed mise à jour. Clique sur `Rafraîchir` dans le panneau.")
.ephemeral(true),
),
)
.await;
true
} }
pub struct BoostembedCommand; pub struct BoostembedCommand;
@@ -15,10 +644,10 @@ impl crate::commands::command_contract::CommandSpec for BoostembedCommand {
key: "boostembed", key: "boostembed",
command: "boostembed", command: "boostembed",
category: "admin", category: "admin",
params: "<on|off|test>", params: "[on|off|test|settings]",
summary: "Active, coupe ou teste l embed boost", summary: "Configure l embed boost avec panneau interactif",
description: "Controle l embed de boost et permet un test rapide.", description: "Ouvre un panneau avec composants pour paramétrer l'embed boost et le salon où il est envoyé.",
examples: &["+boostembed on", "+boostembed test"], examples: &["+boostembed", "+boostembed settings", "+boostembed test"],
alias_source_key: "boostembed", alias_source_key: "boostembed",
default_aliases: &["bembed"], default_aliases: &["bembed"],
default_permission: 8, default_permission: 8,
+4 -1
View File
@@ -90,7 +90,10 @@ pub async fn handle_rename(ctx: &Context, msg: &Message, args: &[&str]) {
if msg if msg
.channel_id .channel_id
.edit(&ctx.http, serenity::builder::EditChannel::new().name(new_name.clone())) .edit(
&ctx.http,
serenity::builder::EditChannel::new().name(new_name.clone()),
)
.await .await
.is_err() .is_err()
{ {
+41 -15
View File
@@ -3,10 +3,10 @@ use serenity::builder::{
CreateActionRow, CreateButton, CreateEmbed, CreateInputText, CreateInteractionResponse, CreateActionRow, CreateButton, CreateEmbed, CreateInputText, CreateInteractionResponse,
CreateInteractionResponseMessage, CreateMessage, CreateModal, CreateInteractionResponseMessage, CreateMessage, CreateModal,
}; };
use serenity::model::Colour;
use serenity::model::application::{ use serenity::model::application::{
ActionRowComponent, ButtonStyle, ComponentInteraction, InputTextStyle, ModalInteraction, ActionRowComponent, ButtonStyle, ComponentInteraction, InputTextStyle, ModalInteraction,
}; };
use serenity::model::Colour;
use serenity::model::prelude::*; use serenity::model::prelude::*;
use serenity::prelude::*; use serenity::prelude::*;
@@ -40,9 +40,7 @@ fn suggestion_embed(author: &User, content: &str) -> CreateEmbed {
.title("💡 Suggestion") .title("💡 Suggestion")
.description(content) .description(content)
.colour(Colour::from_rgb(255, 200, 0)) .colour(Colour::from_rgb(255, 200, 0))
.author( .author(serenity::builder::CreateEmbedAuthor::new(&author.name).icon_url(author.face()))
serenity::builder::CreateEmbedAuthor::new(&author.name).icon_url(author.face()),
)
.timestamp(Utc::now()) .timestamp(Utc::now())
} }
@@ -52,7 +50,11 @@ fn suggestion_settings_embed(settings: &db::SuggestionSettings) -> CreateEmbed {
.description("Configure le système de suggestions du serveur.") .description("Configure le système de suggestions du serveur.")
.colour(Colour::from_rgb(255, 200, 0)) .colour(Colour::from_rgb(255, 200, 0))
.timestamp(Utc::now()) .timestamp(Utc::now())
.field("Statut", if settings.enabled { "Actif" } else { "Inactif" }, true); .field(
"Statut",
if settings.enabled { "Actif" } else { "Inactif" },
true,
);
if let Some(channel_id) = settings.channel_id { if let Some(channel_id) = settings.channel_id {
embed = embed.field("Canal", format!("<#{}>", channel_id), true); embed = embed.field("Canal", format!("<#{}>", channel_id), true);
@@ -65,8 +67,15 @@ fn suggestion_settings_embed(settings: &db::SuggestionSettings) -> CreateEmbed {
embed embed
} }
fn suggestion_components(owner_id: UserId, settings: &db::SuggestionSettings) -> Vec<CreateActionRow> { fn suggestion_components(
let toggle_label = if settings.enabled { "Désactiver" } else { "Activer" }; owner_id: UserId,
settings: &db::SuggestionSettings,
) -> Vec<CreateActionRow> {
let toggle_label = if settings.enabled {
"Désactiver"
} else {
"Activer"
};
vec![CreateActionRow::Buttons(vec![ vec![CreateActionRow::Buttons(vec![
CreateButton::new(format!("{}:submit:{}", SUGGESTION_MENU, owner_id.get())) CreateButton::new(format!("{}:submit:{}", SUGGESTION_MENU, owner_id.get()))
@@ -124,7 +133,9 @@ async fn submit_suggestion(
author: &User, author: &User,
content: String, content: String,
) -> Result<(), String> { ) -> Result<(), String> {
let pool = pool(ctx).await.ok_or_else(|| "Base de données indisponible".to_string())?; let pool = pool(ctx)
.await
.ok_or_else(|| "Base de données indisponible".to_string())?;
let bot_id = ctx.cache.current_user().id.get() as i64; let bot_id = ctx.cache.current_user().id.get() as i64;
let settings = db::get_or_create_suggestion_settings(&pool, bot_id, guild_id.get() as i64) let settings = db::get_or_create_suggestion_settings(&pool, bot_id, guild_id.get() as i64)
.await .await
@@ -134,12 +145,16 @@ async fn submit_suggestion(
return Err("Le système de suggestions est désactivé.".to_string()); return Err("Le système de suggestions est désactivé.".to_string());
} }
let channel_id = settings.channel_id.ok_or_else(|| "Canal de suggestions non configuré".to_string())?; let channel_id = settings
.channel_id
.ok_or_else(|| "Canal de suggestions non configuré".to_string())?;
let channel = ChannelId::new(channel_id as u64) let channel = ChannelId::new(channel_id as u64)
.to_channel(&ctx.http) .to_channel(&ctx.http)
.await .await
.map_err(|e| format!("Erreur: {e}"))?; .map_err(|e| format!("Erreur: {e}"))?;
let guild_channel = channel.guild().ok_or_else(|| "Canal de suggestions introuvable".to_string())?; let guild_channel = channel
.guild()
.ok_or_else(|| "Canal de suggestions introuvable".to_string())?;
let message = guild_channel let message = guild_channel
.send_message( .send_message(
@@ -184,7 +199,11 @@ async fn submit_suggestion(
} }
pub async fn handle_suggestion(ctx: &Context, msg: &Message, args: &[&str]) { pub async fn handle_suggestion(ctx: &Context, msg: &Message, args: &[&str]) {
if args.first().map(|value| value.eq_ignore_ascii_case("settings")).unwrap_or(false) { if args
.first()
.map(|value| value.eq_ignore_ascii_case("settings"))
.unwrap_or(false)
{
show_menu(ctx, msg).await; show_menu(ctx, msg).await;
return; return;
} }
@@ -316,14 +335,21 @@ pub async fn handle_component_interaction(ctx: &Context, component: &ComponentIn
} }
if action.ends_with(":configure") { if action.ends_with(":configure") {
let modal = CreateModal::new(component.data.custom_id.clone(), "Configurer les suggestions") let modal = CreateModal::new(
component.data.custom_id.clone(),
"Configurer les suggestions",
)
.components(vec![ .components(vec![
CreateActionRow::InputText( CreateActionRow::InputText(
CreateInputText::new(InputTextStyle::Short, "Canal des suggestions", "channel_id") CreateInputText::new(InputTextStyle::Short, "Canal des suggestions", "channel_id")
.required(false), .required(false),
), ),
CreateActionRow::InputText( CreateActionRow::InputText(
CreateInputText::new(InputTextStyle::Short, "Canal d'approbation", "approve_channel_id") CreateInputText::new(
InputTextStyle::Short,
"Canal d'approbation",
"approve_channel_id",
)
.required(false), .required(false),
), ),
]); ]);
@@ -392,8 +418,8 @@ pub async fn handle_modal_interaction(ctx: &Context, modal: &ModalInteraction) -
}; };
if action.ends_with(":configure") { if action.ends_with(":configure") {
let channel_id = modal_value(modal, "channel_id") let channel_id =
.and_then(|value| value.trim().parse::<i64>().ok()); modal_value(modal, "channel_id").and_then(|value| value.trim().parse::<i64>().ok());
let approve_channel_id = modal_value(modal, "approve_channel_id") let approve_channel_id = modal_value(modal, "approve_channel_id")
.and_then(|value| value.trim().parse::<i64>().ok()); .and_then(|value| value.trim().parse::<i64>().ok());
+23 -9
View File
@@ -3,10 +3,10 @@ use serenity::builder::{
CreateActionRow, CreateButton, CreateChannel, CreateEmbed, CreateInputText, CreateActionRow, CreateButton, CreateChannel, CreateEmbed, CreateInputText,
CreateInteractionResponse, CreateInteractionResponseMessage, CreateMessage, CreateModal, CreateInteractionResponse, CreateInteractionResponseMessage, CreateMessage, CreateModal,
}; };
use serenity::model::Colour;
use serenity::model::application::{ use serenity::model::application::{
ActionRowComponent, ButtonStyle, ComponentInteraction, InputTextStyle, ModalInteraction, ActionRowComponent, ButtonStyle, ComponentInteraction, InputTextStyle, ModalInteraction,
}; };
use serenity::model::Colour;
use serenity::model::prelude::*; use serenity::model::prelude::*;
use serenity::prelude::*; use serenity::prelude::*;
@@ -40,7 +40,11 @@ fn tempvoc_embed(settings: &db::TempvocSettings) -> CreateEmbed {
.description("Gère les vocaux temporaires du serveur.") .description("Gère les vocaux temporaires du serveur.")
.colour(Colour::from_rgb(100, 180, 255)) .colour(Colour::from_rgb(100, 180, 255))
.timestamp(Utc::now()) .timestamp(Utc::now())
.field("Statut", if settings.enabled { "Actif" } else { "Inactif" }, true); .field(
"Statut",
if settings.enabled { "Actif" } else { "Inactif" },
true,
);
if let Some(trigger) = settings.trigger_channel_id { if let Some(trigger) = settings.trigger_channel_id {
embed = embed.field("Canal déclencheur", format!("<#{}>", trigger), true); embed = embed.field("Canal déclencheur", format!("<#{}>", trigger), true);
@@ -54,7 +58,11 @@ fn tempvoc_embed(settings: &db::TempvocSettings) -> CreateEmbed {
} }
fn tempvoc_components(owner_id: UserId, settings: &db::TempvocSettings) -> Vec<CreateActionRow> { fn tempvoc_components(owner_id: UserId, settings: &db::TempvocSettings) -> Vec<CreateActionRow> {
let toggle_label = if settings.enabled { "Désactiver" } else { "Activer" }; let toggle_label = if settings.enabled {
"Désactiver"
} else {
"Activer"
};
vec![CreateActionRow::Buttons(vec![ vec![CreateActionRow::Buttons(vec![
CreateButton::new(format!("{}:toggle:{}", TEMPVOC_MENU, owner_id.get())) CreateButton::new(format!("{}:toggle:{}", TEMPVOC_MENU, owner_id.get()))
@@ -254,10 +262,10 @@ pub async fn handle_modal_interaction(ctx: &Context, modal: &ModalInteraction) -
}; };
let bot_id = ctx.cache.current_user().id.get() as i64; let bot_id = ctx.cache.current_user().id.get() as i64;
let trigger_channel_id = modal_value(modal, "trigger_channel_id") let trigger_channel_id =
.and_then(|value| value.trim().parse::<i64>().ok()); modal_value(modal, "trigger_channel_id").and_then(|value| value.trim().parse::<i64>().ok());
let category_id = modal_value(modal, "category_id") let category_id =
.and_then(|value| value.trim().parse::<i64>().ok()); modal_value(modal, "category_id").and_then(|value| value.trim().parse::<i64>().ok());
let updated = db::update_tempvoc_settings( let updated = db::update_tempvoc_settings(
&pool, &pool,
@@ -317,14 +325,20 @@ async fn cached_room_members(ctx: &Context, guild_id: GuildId, channel_id: Chann
.unwrap_or(0) .unwrap_or(0)
} }
async fn create_temp_channel(ctx: &Context, guild_id: GuildId, user: &User, settings: &db::TempvocSettings) { async fn create_temp_channel(
ctx: &Context,
guild_id: GuildId,
user: &User,
settings: &db::TempvocSettings,
) {
let Some(trigger_channel_id) = settings.trigger_channel_id else { let Some(trigger_channel_id) = settings.trigger_channel_id else {
return; return;
}; };
let Ok(trigger_channel) = ChannelId::new(trigger_channel_id as u64) let Ok(trigger_channel) = ChannelId::new(trigger_channel_id as u64)
.to_channel(&ctx.http) .to_channel(&ctx.http)
.await else { .await
else {
return; return;
}; };
+19 -9
View File
@@ -1,13 +1,13 @@
use chrono::Utc; use chrono::Utc;
use serenity::all::{PermissionOverwrite, PermissionOverwriteType, Permissions};
use serenity::builder::{ use serenity::builder::{
CreateActionRow, CreateButton, CreateChannel, CreateEmbed, CreateInputText, CreateActionRow, CreateButton, CreateChannel, CreateEmbed, CreateInputText,
CreateInteractionResponse, CreateInteractionResponseMessage, CreateMessage, CreateModal, CreateInteractionResponse, CreateInteractionResponseMessage, CreateMessage, CreateModal,
}; };
use serenity::model::Colour;
use serenity::model::application::{ use serenity::model::application::{
ActionRowComponent, ButtonStyle, ComponentInteraction, InputTextStyle, ModalInteraction, ActionRowComponent, ButtonStyle, ComponentInteraction, InputTextStyle, ModalInteraction,
}; };
use serenity::all::{PermissionOverwrite, PermissionOverwriteType, Permissions};
use serenity::model::Colour;
use serenity::model::prelude::*; use serenity::model::prelude::*;
use serenity::prelude::*; use serenity::prelude::*;
@@ -58,7 +58,11 @@ fn ticket_embed(settings: &db::TicketSettings) -> CreateEmbed {
.description("Utilise les boutons ci-dessous pour gérer le système de tickets.") .description("Utilise les boutons ci-dessous pour gérer le système de tickets.")
.colour(Colour::from_rgb(90, 160, 255)) .colour(Colour::from_rgb(90, 160, 255))
.timestamp(Utc::now()) .timestamp(Utc::now())
.field("Statut", if settings.enabled { "Actif" } else { "Inactif" }, true); .field(
"Statut",
if settings.enabled { "Actif" } else { "Inactif" },
true,
);
if let Some(category_id) = settings.category_id { if let Some(category_id) = settings.category_id {
embed = embed.field("Catégorie", format!("<#{}>", category_id), true); embed = embed.field("Catégorie", format!("<#{}>", category_id), true);
@@ -72,7 +76,11 @@ fn ticket_embed(settings: &db::TicketSettings) -> CreateEmbed {
} }
fn ticket_components(owner_id: UserId, settings: &db::TicketSettings) -> Vec<CreateActionRow> { fn ticket_components(owner_id: UserId, settings: &db::TicketSettings) -> Vec<CreateActionRow> {
let toggle_label = if settings.enabled { "Désactiver" } else { "Activer" }; let toggle_label = if settings.enabled {
"Désactiver"
} else {
"Activer"
};
vec![CreateActionRow::Buttons(vec![ vec![CreateActionRow::Buttons(vec![
CreateButton::new(format!("{}:create:{}", TICKET_MENU, owner_id.get())) CreateButton::new(format!("{}:create:{}", TICKET_MENU, owner_id.get()))
@@ -130,7 +138,9 @@ async fn create_ticket_channel(
title: String, title: String,
settings: &db::TicketSettings, settings: &db::TicketSettings,
) -> Result<ChannelId, String> { ) -> Result<ChannelId, String> {
let pool = pool(ctx).await.ok_or_else(|| "Base de données indisponible".to_string())?; let pool = pool(ctx)
.await
.ok_or_else(|| "Base de données indisponible".to_string())?;
let name = sanitize_channel_name(&title); let name = sanitize_channel_name(&title);
if name.is_empty() { if name.is_empty() {
@@ -344,10 +354,10 @@ pub async fn handle_modal_interaction(ctx: &Context, modal: &ModalInteraction) -
}; };
if action.ends_with(":configure") { if action.ends_with(":configure") {
let category_id = modal_value(modal, "category_id") let category_id =
.and_then(|value| value.trim().parse::<i64>().ok()); modal_value(modal, "category_id").and_then(|value| value.trim().parse::<i64>().ok());
let log_channel_id = modal_value(modal, "log_channel_id") let log_channel_id =
.and_then(|value| value.trim().parse::<i64>().ok()); modal_value(modal, "log_channel_id").and_then(|value| value.trim().parse::<i64>().ok());
if let Ok(updated) = db::update_ticket_settings( if let Ok(updated) = db::update_ticket_settings(
&pool, &pool,
+12 -7
View File
@@ -16,9 +16,10 @@ const TICKET_ALLOW: Permissions = Permissions::VIEW_CHANNEL
.union(Permissions::ADD_REACTIONS); .union(Permissions::ADD_REACTIONS);
fn ticket_member_id(args: &[&str], msg: &Message) -> Option<UserId> { fn ticket_member_id(args: &[&str], msg: &Message) -> Option<UserId> {
msg.mentions.first().map(|user| user.id).or_else(|| { msg.mentions
args.first().and_then(|value| parse_user_id(value)) .first()
}) .map(|user| user.id)
.or_else(|| args.first().and_then(|value| parse_user_id(value)))
} }
async fn ticket_member_update( async fn ticket_member_update(
@@ -81,9 +82,9 @@ async fn ticket_member_update(
}; };
let mut overwrites = guild_channel.permission_overwrites.clone(); let mut overwrites = guild_channel.permission_overwrites.clone();
overwrites.retain(|overwrite| { overwrites.retain(
!matches!(overwrite.kind, PermissionOverwriteType::Member(id) if id == user_id) |overwrite| !matches!(overwrite.kind, PermissionOverwriteType::Member(id) if id == user_id),
}); );
if allow { if allow {
overwrites.push(PermissionOverwrite { overwrites.push(PermissionOverwrite {
@@ -117,7 +118,11 @@ async fn ticket_member_update(
let _ = db::remove_ticket_member(&pool, ticket.id, user_id.get() as i64).await; let _ = db::remove_ticket_member(&pool, ticket.id, user_id.get() as i64).await;
} }
let title = if allow { "Membre ajouté" } else { "Membre retiré" }; let title = if allow {
"Membre ajouté"
} else {
"Membre retiré"
};
let description = if allow { let description = if allow {
format!("<@{}> a été ajouté au ticket.", user_id.get()) format!("<@{}> a été ajouté au ticket.", user_id.get())
} else { } else {
+1 -7
View File
@@ -29,13 +29,7 @@ pub async fn handle_tickets(ctx: &Context, msg: &Message, args: &[&str]) {
let offset = (page - 1) * limit; let offset = (page - 1) * limit;
let bot_id = ctx.cache.current_user().id.get() as i64; let bot_id = ctx.cache.current_user().id.get() as i64;
let tickets = db::get_guild_tickets( let tickets = db::get_guild_tickets(&pool, bot_id, guild_id.get() as i64, limit, offset)
&pool,
bot_id,
guild_id.get() as i64,
limit,
offset,
)
.await .await
.unwrap_or_default(); .unwrap_or_default();
+6 -3
View File
@@ -161,8 +161,9 @@ fn help_page_for_command(
"owner" | "unowner" | "clear_owners" | "bl" | "unbl" | "blinfo" | "clear_bl" "owner" | "unowner" | "clear_owners" | "bl" | "unbl" | "blinfo" | "clear_bl"
| "allbots" | "alladmins" | "botadmins" | "mainprefix" | "prefix" | "mp" | "invite" | "allbots" | "alladmins" | "botadmins" | "mainprefix" | "prefix" | "mp" | "invite"
| "leave" | "discussion" => "administration", | "leave" | "discussion" => "administration",
"perms" | "del" | "clear_perms" | "allperms" | "alias" | "help" "perms" | "del" | "clear_perms" | "allperms" | "alias" | "help" | "helpsetting" => {
| "helpsetting" => "permissions", "permissions"
}
_ => match meta.category { _ => match meta.category {
"general" => "infos", "general" => "infos",
"profile" => "bot", "profile" => "bot",
@@ -487,7 +488,9 @@ fn help_page_content(
} else { } else {
lines.push(format!( lines.push(format!(
"`+{}`{} - {} · alias: `{}`", "`+{}`{} - {} · alias: `{}`",
label, permission, summary, label,
permission,
summary,
aliases.join("`, `") aliases.join("`, `")
)); ));
} }
+8 -2
View File
@@ -15,8 +15,14 @@ pub async fn handle_show_pics(ctx: &Context, msg: &Message, args: &[&str]) {
return; return;
}; };
let members = guild.members(ctx, Some(200), None).await.unwrap_or_default(); let members = guild
let members: Vec<_> = members.into_iter().filter(|member| !member.user.bot).collect(); .members(ctx, Some(200), None)
.await
.unwrap_or_default();
let members: Vec<_> = members
.into_iter()
.filter(|member| !member.user.bot)
.collect();
if members.is_empty() { if members.is_empty() {
send_embed( send_embed(
+1 -1
View File
@@ -6,7 +6,7 @@ use serenity::prelude::*;
use crate::commands::common::{send_embed, theme_color}; use crate::commands::common::{send_embed, theme_color};
use crate::db::DbPoolKey; use crate::db::DbPoolKey;
const LOGS_PER_PAGE: i64 = 5; const LOGS_PER_PAGE: i64 = 10;
pub async fn pool(ctx: &Context) -> Option<sqlx::PgPool> { pub async fn pool(ctx: &Context) -> Option<sqlx::PgPool> {
let data = ctx.data.read().await; let data = ctx.data.read().await;
-96
View File
@@ -569,102 +569,6 @@ async fn run_join_leave_action(ctx: &Context, guild_id: GuildId, kind: &str, use
let _ = channel_id.say(&ctx.http, content).await; let _ = channel_id.say(&ctx.http, content).await;
} }
pub async fn handle_boostembed(ctx: &Context, msg: &Message, args: &[&str]) {
let Some(guild_id) = msg.guild_id else {
return;
};
let Some(pool) = pool(ctx).await else {
return;
};
let bot_id = ctx.cache.current_user().id;
if let Some(action) = args.first().map(|v| v.to_lowercase()) {
match action.as_str() {
"on" | "off" => {
let enabled = action == "on";
let _ = sqlx::query(
r#"
INSERT INTO bot_boost_embed (bot_id, guild_id, enabled)
VALUES ($1, $2, $3)
ON CONFLICT (bot_id, guild_id)
DO UPDATE SET enabled = EXCLUDED.enabled, updated_at = NOW();
"#,
)
.bind(bot_id.get() as i64)
.bind(guild_id.get() as i64)
.bind(enabled)
.execute(&pool)
.await;
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("BoostEmbed")
.description(if enabled { "Activé" } else { "Désactivé" })
.color(theme_color(ctx).await),
)
.await;
return;
}
"test" => {
send_boost_embed(ctx, guild_id, &msg.author).await;
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("BoostEmbed")
.description("Test envoyé.")
.color(theme_color(ctx).await),
)
.await;
return;
}
_ => {}
}
}
let row = sqlx::query_as::<_, (bool, Option<String>, Option<String>, Option<i32>)>(
r#"
SELECT enabled, title, description, color
FROM bot_boost_embed
WHERE bot_id = $1 AND guild_id = $2
LIMIT 1;
"#,
)
.bind(bot_id.get() as i64)
.bind(guild_id.get() as i64)
.fetch_optional(&pool)
.await
.ok()
.flatten();
let desc = if let Some((enabled, title, description, color)) = row {
format!(
"État: {}\nTitle: {}\nDescription: {}\nColor: {}",
if enabled { "on" } else { "off" },
title.unwrap_or_else(|| "(défaut)".to_string()),
description.unwrap_or_else(|| "(défaut)".to_string()),
color
.map(|v| format!("#{:06X}", v.max(0) as u32))
.unwrap_or_else(|| "(thème)".to_string())
)
} else {
"Aucun réglage boost embed.".to_string()
};
send_embed(
ctx,
msg,
CreateEmbed::new()
.title("BoostEmbed")
.description(desc)
.color(theme_color(ctx).await),
)
.await;
}
pub async fn handle_set_boostembed(ctx: &Context, msg: &Message, args: &[&str]) { pub async fn handle_set_boostembed(ctx: &Context, msg: &Message, args: &[&str]) {
let Some(guild_id) = msg.guild_id else { let Some(guild_id) = msg.guild_id else {
return; return;
+22 -22
View File
@@ -17,6 +17,8 @@ pub mod allperms;
pub mod autobackup; pub mod autobackup;
#[path = "admin/autoconfiglog.rs"] #[path = "admin/autoconfiglog.rs"]
pub mod autoconfiglog; pub mod autoconfiglog;
#[path = "admin/autopublish.rs"]
pub mod autopublish;
#[path = "admin/autoreact.rs"] #[path = "admin/autoreact.rs"]
pub mod autoreact; pub mod autoreact;
#[path = "admin/backup.rs"] #[path = "admin/backup.rs"]
@@ -55,6 +57,8 @@ pub mod changeall;
pub mod channel; pub mod channel;
#[path = "general/choose.rs"] #[path = "general/choose.rs"]
pub mod choose; pub mod choose;
#[path = "admin/claim.rs"]
pub mod claim;
#[path = "admin/cleanup.rs"] #[path = "admin/cleanup.rs"]
pub mod cleanup; pub mod cleanup;
#[path = "admin/clear_all_sanctions.rs"] #[path = "admin/clear_all_sanctions.rs"]
@@ -69,6 +73,8 @@ pub mod clear_owners;
pub mod clear_perms; pub mod clear_perms;
#[path = "admin/clear_sanctions.rs"] #[path = "admin/clear_sanctions.rs"]
pub mod clear_sanctions; pub mod clear_sanctions;
#[path = "admin/close.rs"]
pub mod close;
#[path = "admin/cmute.rs"] #[path = "admin/cmute.rs"]
pub mod cmute; pub mod cmute;
pub mod command_contract; pub mod command_contract;
@@ -168,6 +174,8 @@ pub mod prefix;
pub mod raidlog; pub mod raidlog;
#[path = "profile/remove_activity.rs"] #[path = "profile/remove_activity.rs"]
pub mod remove_activity; pub mod remove_activity;
#[path = "admin/rename.rs"]
pub mod rename;
#[path = "admin/renew.rs"] #[path = "admin/renew.rs"]
pub mod renew; pub mod renew;
#[path = "admin/reroll.rs"] #[path = "admin/reroll.rs"]
@@ -194,10 +202,14 @@ pub mod set_boostembed;
pub mod set_modlogs; pub mod set_modlogs;
#[path = "general/shadowbot.rs"] #[path = "general/shadowbot.rs"]
pub mod shadowbot; pub mod shadowbot;
#[path = "general/showpics.rs"]
pub mod showpics;
#[path = "general/snipe.rs"] #[path = "general/snipe.rs"]
pub mod snipe; pub mod snipe;
#[path = "profile/stream.rs"] #[path = "profile/stream.rs"]
pub mod stream; pub mod stream;
#[path = "admin/suggestion.rs"]
pub mod suggestion;
#[path = "admin/sync.rs"] #[path = "admin/sync.rs"]
pub mod sync; pub mod sync;
#[path = "admin/tempban.rs"] #[path = "admin/tempban.rs"]
@@ -208,8 +220,18 @@ pub mod tempcmute;
pub mod tempmute; pub mod tempmute;
#[path = "admin/temprole.rs"] #[path = "admin/temprole.rs"]
pub mod temprole; pub mod temprole;
#[path = "admin/tempvoc.rs"]
pub mod tempvoc;
#[path = "admin/tempvoc_cmd.rs"]
pub mod tempvoc_cmd;
#[path = "profile/theme.rs"] #[path = "profile/theme.rs"]
pub mod theme; pub mod theme;
#[path = "admin/ticket.rs"]
pub mod ticket;
#[path = "admin/ticket_member.rs"]
pub mod ticket_member;
#[path = "admin/tickets.rs"]
pub mod tickets;
#[path = "admin/unban.rs"] #[path = "admin/unban.rs"]
pub mod unban; pub mod unban;
#[path = "admin/unbanall.rs"] #[path = "admin/unbanall.rs"]
@@ -244,34 +266,12 @@ pub mod viewlogs;
pub mod vocinfo; pub mod vocinfo;
#[path = "admin/voicekick.rs"] #[path = "admin/voicekick.rs"]
pub mod voicekick; pub mod voicekick;
#[path = "admin/ticket.rs"]
pub mod ticket;
#[path = "admin/tickets.rs"]
pub mod tickets;
#[path = "general/showpics.rs"]
pub mod showpics;
#[path = "admin/suggestion.rs"]
pub mod suggestion;
#[path = "admin/autopublish.rs"]
pub mod autopublish;
#[path = "admin/tempvoc.rs"]
pub mod tempvoc;
#[path = "admin/tempvoc_cmd.rs"]
pub mod tempvoc_cmd;
#[path = "admin/voicelog.rs"] #[path = "admin/voicelog.rs"]
pub mod voicelog; pub mod voicelog;
#[path = "admin/voicemove.rs"] #[path = "admin/voicemove.rs"]
pub mod voicemove; pub mod voicemove;
#[path = "admin/warn.rs"] #[path = "admin/warn.rs"]
pub mod warn; pub mod warn;
#[path = "admin/claim.rs"]
pub mod claim;
#[path = "admin/close.rs"]
pub mod close;
#[path = "admin/rename.rs"]
pub mod rename;
#[path = "admin/ticket_member.rs"]
pub mod ticket_member;
#[path = "profile/watch.rs"] #[path = "profile/watch.rs"]
pub mod watch; pub mod watch;
+13 -2
View File
@@ -77,7 +77,14 @@ fn build_embed(settings: &HelpSettingsData) -> CreateEmbed {
.field("Mode d'affichage", format!("`{}`", settings.layout), true) .field("Mode d'affichage", format!("`{}`", settings.layout), true)
.field( .field(
"Aliases", "Aliases",
format!("`{}`", if settings.aliases_enabled { "on" } else { "off" }), format!(
"`{}`",
if settings.aliases_enabled {
"on"
} else {
"off"
}
),
true, true,
) )
.field( .field(
@@ -166,7 +173,11 @@ fn build_components(owner_id: UserId, settings: &HelpSettingsData) -> Vec<Create
) )
.placeholder("Action rapide (select)"); .placeholder("Action rapide (select)");
vec![mode_row, toggle_row, CreateActionRow::SelectMenu(quick_menu)] vec![
mode_row,
toggle_row,
CreateActionRow::SelectMenu(quick_menu),
]
} }
async fn send_settings_panel( async fn send_settings_panel(
-1
View File
@@ -2741,4 +2741,3 @@ pub async fn delete_tempvoc_room(pool: &PgPool, channel_id: i64) -> Result<(), s
Ok(()) Ok(())
} }
+10 -3
View File
@@ -2,7 +2,8 @@ use serenity::model::prelude::*;
use serenity::prelude::*; use serenity::prelude::*;
use crate::commands::{ use crate::commands::{
advanced_tools, help, helpsetting, mp, perms_service, suggestion, tempvoc, ticket, advanced_tools, boostembed, help, helpsetting, mp, perms_service, suggestion, tempvoc,
ticket,
}; };
pub async fn handle_interaction_create(ctx: &Context, interaction: &Interaction) { pub async fn handle_interaction_create(ctx: &Context, interaction: &Interaction) {
@@ -21,6 +22,10 @@ pub async fn handle_interaction_create(ctx: &Context, interaction: &Interaction)
return; return;
} }
if boostembed::handle_component_interaction(ctx, component).await {
return;
}
if tempvoc::handle_component_interaction(ctx, component).await { if tempvoc::handle_component_interaction(ctx, component).await {
return; return;
} }
@@ -54,6 +59,10 @@ pub async fn handle_interaction_create(ctx: &Context, interaction: &Interaction)
return; return;
} }
if boostembed::handle_modal_interaction(ctx, modal).await {
return;
}
if tempvoc::handle_modal_interaction(ctx, modal).await { if tempvoc::handle_modal_interaction(ctx, modal).await {
return; return;
} }
@@ -61,5 +70,3 @@ pub async fn handle_interaction_create(ctx: &Context, interaction: &Interaction)
let _ = advanced_tools::handle_modal_interaction(ctx, modal).await; let _ = advanced_tools::handle_modal_interaction(ctx, modal).await;
} }
} }
+25 -15
View File
@@ -6,19 +6,19 @@ use std::sync::{Mutex, OnceLock};
use crate::commands::moderation_tools; use crate::commands::moderation_tools;
use crate::commands::remove_activity; use crate::commands::remove_activity;
use crate::commands::{ use crate::commands::{
addrole, alias, autobackup, autoconfiglog, autoreact, backup, ban, banlist, banner, bl, blinfo, addrole, alias, autobackup, autoconfiglog, autopublish, autoreact, backup, ban, banlist,
boostembed, boosters, boostlog, bringall, button, calc, change, changeall, channel, choose, banner, bl, blinfo, boostembed, boosters, boostlog, bringall, button, calc, change, changeall,
cleanup, clear_all_sanctions, clear_bl, clear_messages, clear_owners, clear_perms, channel, choose, claim, cleanup, clear_all_sanctions, clear_bl, clear_messages, clear_owners,
clear_sanctions, claim, cmute, compet, create, del, del_sanction, delrole, derank, discussion, clear_perms, clear_sanctions, close, cmute, compet, create, del, del_sanction, delrole, derank,
dnd, embed, emoji, end, giveaway, help, helpsetting, hide, hideall, idle, invisible, discussion, dnd, embed, emoji, end, giveaway, help, helpsetting, hide, hideall, idle,
invite, join, kick, leave, leave_settings, listen, loading, lock, lockall, mainprefix, invisible, invite, join, kick, leave, leave_settings, listen, loading, lock, lockall,
massiverole, member, messagelog, modlog, mp, mute, mutelist, newsticker, nolog, online, owner, mainprefix, massiverole, member, messagelog, modlog, mp, mute, mutelist, newsticker, nolog,
perms, pic, ping, playto, prefix, raidlog, renew, rename, reroll, role, rolelog, rolemembers, online, owner, perms, pic, ping, playto, prefix, raidlog, rename, renew, reroll, role, rolelog,
sanctions, say, server, serverinfo, set, set_boostembed, set_modlogs, shadowbot, showpics, rolemembers, sanctions, say, server, serverinfo, set, set_boostembed, set_modlogs, shadowbot,
snipe, stream, sync, suggestion, tempban, tempcmute, tempmute, temprole, tempvoc, theme, tickets, showpics, snipe, stream, suggestion, sync, tempban, tempcmute, tempmute, temprole, tempvoc,
unban, unbanall, unbl, uncmute, unhide, unhideall, unlock, unlockall, unmassiverole, unmute, tempvoc_cmd, theme, ticket, ticket_member, tickets, unban, unbanall, unbl, uncmute, unhide,
unmuteall, unowner, untemprole, user, viewlogs, vocinfo, voicekick, voicelog, voicemove, warn, unhideall, unlock, unlockall, unmassiverole, unmute, unmuteall, unowner, untemprole, user,
watch, autopublish, ticket, ticket_member, close, tempvoc_cmd, viewlogs, vocinfo, voicekick, voicelog, voicemove, warn, watch,
}; };
use crate::commands::{alladmins, allbots, allperms, botadmins}; use crate::commands::{alladmins, allbots, allperms, botadmins};
use crate::db::{DbPoolKey, upsert_message_observed}; use crate::db::{DbPoolKey, upsert_message_observed};
@@ -145,12 +145,22 @@ pub async fn handle_message(ctx: &Context, msg: &Message) {
"del" => ticket_member::handle_ticket_remove(ctx, msg, &args).await, "del" => ticket_member::handle_ticket_remove(ctx, msg, &args).await,
"close" => close::handle_close(ctx, msg, &args).await, "close" => close::handle_close(ctx, msg, &args).await,
"tickets" => tickets::handle_tickets(ctx, msg, &args).await, "tickets" => tickets::handle_tickets(ctx, msg, &args).await,
"show" if args.first().map(|s| s.eq_ignore_ascii_case("pics")).unwrap_or(false) => { "show"
if args
.first()
.map(|s| s.eq_ignore_ascii_case("pics"))
.unwrap_or(false) =>
{
showpics::handle_show_pics(ctx, msg, &args[1..]).await showpics::handle_show_pics(ctx, msg, &args[1..]).await
} }
"suggestion" => suggestion::handle_suggestion(ctx, msg, &args).await, "suggestion" => suggestion::handle_suggestion(ctx, msg, &args).await,
"autopublish" => autopublish::handle_autopublish(ctx, msg, &args).await, "autopublish" => autopublish::handle_autopublish(ctx, msg, &args).await,
"tempvoc" if args.first().map(|s| s.eq_ignore_ascii_case("cmd")).unwrap_or(false) => { "tempvoc"
if args
.first()
.map(|s| s.eq_ignore_ascii_case("cmd"))
.unwrap_or(false) =>
{
tempvoc_cmd::handle_tempvoc_cmd(ctx, msg, &args[1..]).await tempvoc_cmd::handle_tempvoc_cmd(ctx, msg, &args[1..]).await
} }
"tempvoc" => tempvoc::handle_tempvoc(ctx, msg, &args).await, "tempvoc" => tempvoc::handle_tempvoc(ctx, msg, &args).await,