mirror of
https://github.com/arthur-pbty/shadowbot.git
synced 2026-06-03 15:07:37 +02:00
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:
@@ -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::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]) {
|
||||
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;
|
||||
@@ -15,10 +644,10 @@ impl crate::commands::command_contract::CommandSpec for BoostembedCommand {
|
||||
key: "boostembed",
|
||||
command: "boostembed",
|
||||
category: "admin",
|
||||
params: "<on|off|test>",
|
||||
summary: "Active, coupe ou teste l embed boost",
|
||||
description: "Controle l embed de boost et permet un test rapide.",
|
||||
examples: &["+boostembed on", "+boostembed test"],
|
||||
params: "[on|off|test|settings]",
|
||||
summary: "Configure l embed boost avec panneau interactif",
|
||||
description: "Ouvre un panneau avec composants pour paramétrer l'embed boost et le salon où il est envoyé.",
|
||||
examples: &["+boostembed", "+boostembed settings", "+boostembed test"],
|
||||
alias_source_key: "boostembed",
|
||||
default_aliases: &["bembed"],
|
||||
default_permission: 8,
|
||||
|
||||
@@ -90,7 +90,10 @@ pub async fn handle_rename(ctx: &Context, msg: &Message, args: &[&str]) {
|
||||
|
||||
if msg
|
||||
.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
|
||||
.is_err()
|
||||
{
|
||||
|
||||
@@ -3,10 +3,10 @@ use serenity::builder::{
|
||||
CreateActionRow, CreateButton, CreateEmbed, CreateInputText, CreateInteractionResponse,
|
||||
CreateInteractionResponseMessage, CreateMessage, CreateModal,
|
||||
};
|
||||
use serenity::model::Colour;
|
||||
use serenity::model::application::{
|
||||
ActionRowComponent, ButtonStyle, ComponentInteraction, InputTextStyle, ModalInteraction,
|
||||
};
|
||||
use serenity::model::Colour;
|
||||
use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
@@ -40,9 +40,7 @@ fn suggestion_embed(author: &User, content: &str) -> CreateEmbed {
|
||||
.title("💡 Suggestion")
|
||||
.description(content)
|
||||
.colour(Colour::from_rgb(255, 200, 0))
|
||||
.author(
|
||||
serenity::builder::CreateEmbedAuthor::new(&author.name).icon_url(author.face()),
|
||||
)
|
||||
.author(serenity::builder::CreateEmbedAuthor::new(&author.name).icon_url(author.face()))
|
||||
.timestamp(Utc::now())
|
||||
}
|
||||
|
||||
@@ -52,7 +50,11 @@ fn suggestion_settings_embed(settings: &db::SuggestionSettings) -> CreateEmbed {
|
||||
.description("Configure le système de suggestions du serveur.")
|
||||
.colour(Colour::from_rgb(255, 200, 0))
|
||||
.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 {
|
||||
embed = embed.field("Canal", format!("<#{}>", channel_id), true);
|
||||
@@ -65,8 +67,15 @@ fn suggestion_settings_embed(settings: &db::SuggestionSettings) -> CreateEmbed {
|
||||
embed
|
||||
}
|
||||
|
||||
fn suggestion_components(owner_id: UserId, settings: &db::SuggestionSettings) -> Vec<CreateActionRow> {
|
||||
let toggle_label = if settings.enabled { "Désactiver" } else { "Activer" };
|
||||
fn suggestion_components(
|
||||
owner_id: UserId,
|
||||
settings: &db::SuggestionSettings,
|
||||
) -> Vec<CreateActionRow> {
|
||||
let toggle_label = if settings.enabled {
|
||||
"Désactiver"
|
||||
} else {
|
||||
"Activer"
|
||||
};
|
||||
|
||||
vec![CreateActionRow::Buttons(vec![
|
||||
CreateButton::new(format!("{}:submit:{}", SUGGESTION_MENU, owner_id.get()))
|
||||
@@ -124,7 +133,9 @@ async fn submit_suggestion(
|
||||
author: &User,
|
||||
content: 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 settings = db::get_or_create_suggestion_settings(&pool, bot_id, guild_id.get() as i64)
|
||||
.await
|
||||
@@ -134,12 +145,16 @@ async fn submit_suggestion(
|
||||
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)
|
||||
.to_channel(&ctx.http)
|
||||
.await
|
||||
.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
|
||||
.send_message(
|
||||
@@ -184,7 +199,11 @@ async fn submit_suggestion(
|
||||
}
|
||||
|
||||
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;
|
||||
return;
|
||||
}
|
||||
@@ -316,17 +335,24 @@ pub async fn handle_component_interaction(ctx: &Context, component: &ComponentIn
|
||||
}
|
||||
|
||||
if action.ends_with(":configure") {
|
||||
let modal = CreateModal::new(component.data.custom_id.clone(), "Configurer les suggestions")
|
||||
.components(vec![
|
||||
CreateActionRow::InputText(
|
||||
CreateInputText::new(InputTextStyle::Short, "Canal des suggestions", "channel_id")
|
||||
.required(false),
|
||||
),
|
||||
CreateActionRow::InputText(
|
||||
CreateInputText::new(InputTextStyle::Short, "Canal d'approbation", "approve_channel_id")
|
||||
.required(false),
|
||||
),
|
||||
]);
|
||||
let modal = CreateModal::new(
|
||||
component.data.custom_id.clone(),
|
||||
"Configurer les suggestions",
|
||||
)
|
||||
.components(vec![
|
||||
CreateActionRow::InputText(
|
||||
CreateInputText::new(InputTextStyle::Short, "Canal des suggestions", "channel_id")
|
||||
.required(false),
|
||||
),
|
||||
CreateActionRow::InputText(
|
||||
CreateInputText::new(
|
||||
InputTextStyle::Short,
|
||||
"Canal d'approbation",
|
||||
"approve_channel_id",
|
||||
)
|
||||
.required(false),
|
||||
),
|
||||
]);
|
||||
|
||||
let _ = component
|
||||
.create_response(&ctx.http, CreateInteractionResponse::Modal(modal))
|
||||
@@ -392,8 +418,8 @@ pub async fn handle_modal_interaction(ctx: &Context, modal: &ModalInteraction) -
|
||||
};
|
||||
|
||||
if action.ends_with(":configure") {
|
||||
let channel_id = modal_value(modal, "channel_id")
|
||||
.and_then(|value| value.trim().parse::<i64>().ok());
|
||||
let channel_id =
|
||||
modal_value(modal, "channel_id").and_then(|value| value.trim().parse::<i64>().ok());
|
||||
let approve_channel_id = modal_value(modal, "approve_channel_id")
|
||||
.and_then(|value| value.trim().parse::<i64>().ok());
|
||||
|
||||
|
||||
@@ -3,10 +3,10 @@ use serenity::builder::{
|
||||
CreateActionRow, CreateButton, CreateChannel, CreateEmbed, CreateInputText,
|
||||
CreateInteractionResponse, CreateInteractionResponseMessage, CreateMessage, CreateModal,
|
||||
};
|
||||
use serenity::model::Colour;
|
||||
use serenity::model::application::{
|
||||
ActionRowComponent, ButtonStyle, ComponentInteraction, InputTextStyle, ModalInteraction,
|
||||
};
|
||||
use serenity::model::Colour;
|
||||
use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
@@ -40,7 +40,11 @@ fn tempvoc_embed(settings: &db::TempvocSettings) -> CreateEmbed {
|
||||
.description("Gère les vocaux temporaires du serveur.")
|
||||
.colour(Colour::from_rgb(100, 180, 255))
|
||||
.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 {
|
||||
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> {
|
||||
let toggle_label = if settings.enabled { "Désactiver" } else { "Activer" };
|
||||
let toggle_label = if settings.enabled {
|
||||
"Désactiver"
|
||||
} else {
|
||||
"Activer"
|
||||
};
|
||||
|
||||
vec![CreateActionRow::Buttons(vec![
|
||||
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 trigger_channel_id = modal_value(modal, "trigger_channel_id")
|
||||
.and_then(|value| value.trim().parse::<i64>().ok());
|
||||
let category_id = modal_value(modal, "category_id")
|
||||
.and_then(|value| value.trim().parse::<i64>().ok());
|
||||
let trigger_channel_id =
|
||||
modal_value(modal, "trigger_channel_id").and_then(|value| value.trim().parse::<i64>().ok());
|
||||
let category_id =
|
||||
modal_value(modal, "category_id").and_then(|value| value.trim().parse::<i64>().ok());
|
||||
|
||||
let updated = db::update_tempvoc_settings(
|
||||
&pool,
|
||||
@@ -317,14 +325,20 @@ async fn cached_room_members(ctx: &Context, guild_id: GuildId, channel_id: Chann
|
||||
.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 {
|
||||
return;
|
||||
};
|
||||
|
||||
let Ok(trigger_channel) = ChannelId::new(trigger_channel_id as u64)
|
||||
.to_channel(&ctx.http)
|
||||
.await else {
|
||||
.await
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
use chrono::Utc;
|
||||
use serenity::all::{PermissionOverwrite, PermissionOverwriteType, Permissions};
|
||||
use serenity::builder::{
|
||||
CreateActionRow, CreateButton, CreateChannel, CreateEmbed, CreateInputText,
|
||||
CreateInteractionResponse, CreateInteractionResponseMessage, CreateMessage, CreateModal,
|
||||
};
|
||||
use serenity::model::Colour;
|
||||
use serenity::model::application::{
|
||||
ActionRowComponent, ButtonStyle, ComponentInteraction, InputTextStyle, ModalInteraction,
|
||||
};
|
||||
use serenity::all::{PermissionOverwrite, PermissionOverwriteType, Permissions};
|
||||
use serenity::model::Colour;
|
||||
use serenity::model::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.")
|
||||
.colour(Colour::from_rgb(90, 160, 255))
|
||||
.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 {
|
||||
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> {
|
||||
let toggle_label = if settings.enabled { "Désactiver" } else { "Activer" };
|
||||
let toggle_label = if settings.enabled {
|
||||
"Désactiver"
|
||||
} else {
|
||||
"Activer"
|
||||
};
|
||||
|
||||
vec![CreateActionRow::Buttons(vec![
|
||||
CreateButton::new(format!("{}:create:{}", TICKET_MENU, owner_id.get()))
|
||||
@@ -130,7 +138,9 @@ async fn create_ticket_channel(
|
||||
title: String,
|
||||
settings: &db::TicketSettings,
|
||||
) -> 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);
|
||||
if name.is_empty() {
|
||||
@@ -344,10 +354,10 @@ pub async fn handle_modal_interaction(ctx: &Context, modal: &ModalInteraction) -
|
||||
};
|
||||
|
||||
if action.ends_with(":configure") {
|
||||
let category_id = modal_value(modal, "category_id")
|
||||
.and_then(|value| value.trim().parse::<i64>().ok());
|
||||
let log_channel_id = modal_value(modal, "log_channel_id")
|
||||
.and_then(|value| value.trim().parse::<i64>().ok());
|
||||
let category_id =
|
||||
modal_value(modal, "category_id").and_then(|value| value.trim().parse::<i64>().ok());
|
||||
let log_channel_id =
|
||||
modal_value(modal, "log_channel_id").and_then(|value| value.trim().parse::<i64>().ok());
|
||||
|
||||
if let Ok(updated) = db::update_ticket_settings(
|
||||
&pool,
|
||||
|
||||
@@ -16,9 +16,10 @@ const TICKET_ALLOW: Permissions = Permissions::VIEW_CHANNEL
|
||||
.union(Permissions::ADD_REACTIONS);
|
||||
|
||||
fn ticket_member_id(args: &[&str], msg: &Message) -> Option<UserId> {
|
||||
msg.mentions.first().map(|user| user.id).or_else(|| {
|
||||
args.first().and_then(|value| parse_user_id(value))
|
||||
})
|
||||
msg.mentions
|
||||
.first()
|
||||
.map(|user| user.id)
|
||||
.or_else(|| args.first().and_then(|value| parse_user_id(value)))
|
||||
}
|
||||
|
||||
async fn ticket_member_update(
|
||||
@@ -81,9 +82,9 @@ async fn ticket_member_update(
|
||||
};
|
||||
|
||||
let mut overwrites = guild_channel.permission_overwrites.clone();
|
||||
overwrites.retain(|overwrite| {
|
||||
!matches!(overwrite.kind, PermissionOverwriteType::Member(id) if id == user_id)
|
||||
});
|
||||
overwrites.retain(
|
||||
|overwrite| !matches!(overwrite.kind, PermissionOverwriteType::Member(id) if id == user_id),
|
||||
);
|
||||
|
||||
if allow {
|
||||
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 title = if allow { "Membre ajouté" } else { "Membre retiré" };
|
||||
let title = if allow {
|
||||
"Membre ajouté"
|
||||
} else {
|
||||
"Membre retiré"
|
||||
};
|
||||
let description = if allow {
|
||||
format!("<@{}> a été ajouté au ticket.", user_id.get())
|
||||
} else {
|
||||
|
||||
@@ -29,15 +29,9 @@ pub async fn handle_tickets(ctx: &Context, msg: &Message, args: &[&str]) {
|
||||
let offset = (page - 1) * limit;
|
||||
let bot_id = ctx.cache.current_user().id.get() as i64;
|
||||
|
||||
let tickets = db::get_guild_tickets(
|
||||
&pool,
|
||||
bot_id,
|
||||
guild_id.get() as i64,
|
||||
limit,
|
||||
offset,
|
||||
)
|
||||
.await
|
||||
.unwrap_or_default();
|
||||
let tickets = db::get_guild_tickets(&pool, bot_id, guild_id.get() as i64, limit, offset)
|
||||
.await
|
||||
.unwrap_or_default();
|
||||
|
||||
if tickets.is_empty() {
|
||||
send_embed(
|
||||
|
||||
@@ -161,8 +161,9 @@ fn help_page_for_command(
|
||||
"owner" | "unowner" | "clear_owners" | "bl" | "unbl" | "blinfo" | "clear_bl"
|
||||
| "allbots" | "alladmins" | "botadmins" | "mainprefix" | "prefix" | "mp" | "invite"
|
||||
| "leave" | "discussion" => "administration",
|
||||
"perms" | "del" | "clear_perms" | "allperms" | "alias" | "help"
|
||||
| "helpsetting" => "permissions",
|
||||
"perms" | "del" | "clear_perms" | "allperms" | "alias" | "help" | "helpsetting" => {
|
||||
"permissions"
|
||||
}
|
||||
_ => match meta.category {
|
||||
"general" => "infos",
|
||||
"profile" => "bot",
|
||||
@@ -487,7 +488,9 @@ fn help_page_content(
|
||||
} else {
|
||||
lines.push(format!(
|
||||
"`+{}`{} - {} · alias: `{}`",
|
||||
label, permission, summary,
|
||||
label,
|
||||
permission,
|
||||
summary,
|
||||
aliases.join("`, `")
|
||||
));
|
||||
}
|
||||
|
||||
@@ -15,8 +15,14 @@ pub async fn handle_show_pics(ctx: &Context, msg: &Message, args: &[&str]) {
|
||||
return;
|
||||
};
|
||||
|
||||
let members = guild.members(ctx, Some(200), None).await.unwrap_or_default();
|
||||
let members: Vec<_> = members.into_iter().filter(|member| !member.user.bot).collect();
|
||||
let members = guild
|
||||
.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() {
|
||||
send_embed(
|
||||
|
||||
@@ -6,7 +6,7 @@ use serenity::prelude::*;
|
||||
use crate::commands::common::{send_embed, theme_color};
|
||||
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> {
|
||||
let data = ctx.data.read().await;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
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]) {
|
||||
let Some(guild_id) = msg.guild_id else {
|
||||
return;
|
||||
|
||||
+22
-22
@@ -17,6 +17,8 @@ pub mod allperms;
|
||||
pub mod autobackup;
|
||||
#[path = "admin/autoconfiglog.rs"]
|
||||
pub mod autoconfiglog;
|
||||
#[path = "admin/autopublish.rs"]
|
||||
pub mod autopublish;
|
||||
#[path = "admin/autoreact.rs"]
|
||||
pub mod autoreact;
|
||||
#[path = "admin/backup.rs"]
|
||||
@@ -55,6 +57,8 @@ pub mod changeall;
|
||||
pub mod channel;
|
||||
#[path = "general/choose.rs"]
|
||||
pub mod choose;
|
||||
#[path = "admin/claim.rs"]
|
||||
pub mod claim;
|
||||
#[path = "admin/cleanup.rs"]
|
||||
pub mod cleanup;
|
||||
#[path = "admin/clear_all_sanctions.rs"]
|
||||
@@ -69,6 +73,8 @@ pub mod clear_owners;
|
||||
pub mod clear_perms;
|
||||
#[path = "admin/clear_sanctions.rs"]
|
||||
pub mod clear_sanctions;
|
||||
#[path = "admin/close.rs"]
|
||||
pub mod close;
|
||||
#[path = "admin/cmute.rs"]
|
||||
pub mod cmute;
|
||||
pub mod command_contract;
|
||||
@@ -168,6 +174,8 @@ pub mod prefix;
|
||||
pub mod raidlog;
|
||||
#[path = "profile/remove_activity.rs"]
|
||||
pub mod remove_activity;
|
||||
#[path = "admin/rename.rs"]
|
||||
pub mod rename;
|
||||
#[path = "admin/renew.rs"]
|
||||
pub mod renew;
|
||||
#[path = "admin/reroll.rs"]
|
||||
@@ -194,10 +202,14 @@ pub mod set_boostembed;
|
||||
pub mod set_modlogs;
|
||||
#[path = "general/shadowbot.rs"]
|
||||
pub mod shadowbot;
|
||||
#[path = "general/showpics.rs"]
|
||||
pub mod showpics;
|
||||
#[path = "general/snipe.rs"]
|
||||
pub mod snipe;
|
||||
#[path = "profile/stream.rs"]
|
||||
pub mod stream;
|
||||
#[path = "admin/suggestion.rs"]
|
||||
pub mod suggestion;
|
||||
#[path = "admin/sync.rs"]
|
||||
pub mod sync;
|
||||
#[path = "admin/tempban.rs"]
|
||||
@@ -208,8 +220,18 @@ pub mod tempcmute;
|
||||
pub mod tempmute;
|
||||
#[path = "admin/temprole.rs"]
|
||||
pub mod temprole;
|
||||
#[path = "admin/tempvoc.rs"]
|
||||
pub mod tempvoc;
|
||||
#[path = "admin/tempvoc_cmd.rs"]
|
||||
pub mod tempvoc_cmd;
|
||||
#[path = "profile/theme.rs"]
|
||||
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"]
|
||||
pub mod unban;
|
||||
#[path = "admin/unbanall.rs"]
|
||||
@@ -244,34 +266,12 @@ pub mod viewlogs;
|
||||
pub mod vocinfo;
|
||||
#[path = "admin/voicekick.rs"]
|
||||
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"]
|
||||
pub mod voicelog;
|
||||
#[path = "admin/voicemove.rs"]
|
||||
pub mod voicemove;
|
||||
#[path = "admin/warn.rs"]
|
||||
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"]
|
||||
pub mod watch;
|
||||
|
||||
|
||||
@@ -77,7 +77,14 @@ fn build_embed(settings: &HelpSettingsData) -> CreateEmbed {
|
||||
.field("Mode d'affichage", format!("`{}`", settings.layout), true)
|
||||
.field(
|
||||
"Aliases",
|
||||
format!("`{}`", if settings.aliases_enabled { "on" } else { "off" }),
|
||||
format!(
|
||||
"`{}`",
|
||||
if settings.aliases_enabled {
|
||||
"on"
|
||||
} else {
|
||||
"off"
|
||||
}
|
||||
),
|
||||
true,
|
||||
)
|
||||
.field(
|
||||
@@ -166,7 +173,11 @@ fn build_components(owner_id: UserId, settings: &HelpSettingsData) -> Vec<Create
|
||||
)
|
||||
.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(
|
||||
|
||||
@@ -2741,4 +2741,3 @@ pub async fn delete_tempvoc_room(pool: &PgPool, channel_id: i64) -> Result<(), s
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,8 @@ use serenity::model::prelude::*;
|
||||
use serenity::prelude::*;
|
||||
|
||||
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) {
|
||||
@@ -21,6 +22,10 @@ pub async fn handle_interaction_create(ctx: &Context, interaction: &Interaction)
|
||||
return;
|
||||
}
|
||||
|
||||
if boostembed::handle_component_interaction(ctx, component).await {
|
||||
return;
|
||||
}
|
||||
|
||||
if tempvoc::handle_component_interaction(ctx, component).await {
|
||||
return;
|
||||
}
|
||||
@@ -54,6 +59,10 @@ pub async fn handle_interaction_create(ctx: &Context, interaction: &Interaction)
|
||||
return;
|
||||
}
|
||||
|
||||
if boostembed::handle_modal_interaction(ctx, modal).await {
|
||||
return;
|
||||
}
|
||||
|
||||
if tempvoc::handle_modal_interaction(ctx, modal).await {
|
||||
return;
|
||||
}
|
||||
@@ -61,5 +70,3 @@ pub async fn handle_interaction_create(ctx: &Context, interaction: &Interaction)
|
||||
let _ = advanced_tools::handle_modal_interaction(ctx, modal).await;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+25
-15
@@ -6,19 +6,19 @@ use std::sync::{Mutex, OnceLock};
|
||||
use crate::commands::moderation_tools;
|
||||
use crate::commands::remove_activity;
|
||||
use crate::commands::{
|
||||
addrole, alias, autobackup, autoconfiglog, autoreact, backup, ban, banlist, banner, bl, blinfo,
|
||||
boostembed, boosters, boostlog, bringall, button, calc, change, changeall, channel, choose,
|
||||
cleanup, clear_all_sanctions, clear_bl, clear_messages, clear_owners, clear_perms,
|
||||
clear_sanctions, claim, cmute, compet, create, del, del_sanction, delrole, derank, discussion,
|
||||
dnd, embed, emoji, end, giveaway, help, helpsetting, hide, hideall, idle, invisible,
|
||||
invite, join, kick, leave, leave_settings, listen, loading, lock, lockall, mainprefix,
|
||||
massiverole, member, messagelog, modlog, mp, mute, mutelist, newsticker, nolog, online, owner,
|
||||
perms, pic, ping, playto, prefix, raidlog, renew, rename, reroll, role, rolelog, rolemembers,
|
||||
sanctions, say, server, serverinfo, set, set_boostembed, set_modlogs, shadowbot, showpics,
|
||||
snipe, stream, sync, suggestion, tempban, tempcmute, tempmute, temprole, tempvoc, theme, tickets,
|
||||
unban, unbanall, unbl, uncmute, unhide, unhideall, unlock, unlockall, unmassiverole, unmute,
|
||||
unmuteall, unowner, untemprole, user, viewlogs, vocinfo, voicekick, voicelog, voicemove, warn,
|
||||
watch, autopublish, ticket, ticket_member, close, tempvoc_cmd,
|
||||
addrole, alias, autobackup, autoconfiglog, autopublish, autoreact, backup, ban, banlist,
|
||||
banner, bl, blinfo, boostembed, boosters, boostlog, bringall, button, calc, change, changeall,
|
||||
channel, choose, claim, cleanup, clear_all_sanctions, clear_bl, clear_messages, clear_owners,
|
||||
clear_perms, clear_sanctions, close, cmute, compet, create, del, del_sanction, delrole, derank,
|
||||
discussion, dnd, embed, emoji, end, giveaway, help, helpsetting, hide, hideall, idle,
|
||||
invisible, invite, join, kick, leave, leave_settings, listen, loading, lock, lockall,
|
||||
mainprefix, massiverole, member, messagelog, modlog, mp, mute, mutelist, newsticker, nolog,
|
||||
online, owner, perms, pic, ping, playto, prefix, raidlog, rename, renew, reroll, role, rolelog,
|
||||
rolemembers, sanctions, say, server, serverinfo, set, set_boostembed, set_modlogs, shadowbot,
|
||||
showpics, snipe, stream, suggestion, sync, tempban, tempcmute, tempmute, temprole, tempvoc,
|
||||
tempvoc_cmd, theme, ticket, ticket_member, tickets, unban, unbanall, unbl, uncmute, unhide,
|
||||
unhideall, unlock, unlockall, unmassiverole, unmute, unmuteall, unowner, untemprole, user,
|
||||
viewlogs, vocinfo, voicekick, voicelog, voicemove, warn, watch,
|
||||
};
|
||||
use crate::commands::{alladmins, allbots, allperms, botadmins};
|
||||
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,
|
||||
"close" => close::handle_close(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
|
||||
}
|
||||
"suggestion" => suggestion::handle_suggestion(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" => tempvoc::handle_tempvoc(ctx, msg, &args).await,
|
||||
|
||||
Reference in New Issue
Block a user