fixed del pager. todo stuff
This commit is contained in:
parent
379e488f7a
commit
6b5d6ae288
@ -416,132 +416,12 @@ Any commands ran as part of recording will be inconsequential")
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
#[command("alias")]
|
||||
#[supports_dm(false)]
|
||||
#[permission_level(Managed)]
|
||||
async fn alias(ctx: &Context, msg: &Message, args: String) {
|
||||
let (pool, lm) = get_ctx_data(&ctx).await;
|
||||
|
||||
let language = UserData::language_of(&msg.author, &pool).await;
|
||||
|
||||
let guild_id = msg.guild_id.unwrap().as_u64().to_owned();
|
||||
|
||||
let matches_opt = REGEX_ALIAS.captures(&args);
|
||||
|
||||
if let Some(matches) = matches_opt {
|
||||
let name = matches.name("name").unwrap().as_str();
|
||||
let command_opt = matches.name("cmd").map(|m| m.as_str());
|
||||
|
||||
match name {
|
||||
"list" => {
|
||||
let aliases = sqlx::query!(
|
||||
"
|
||||
SELECT name, command FROM command_aliases WHERE guild_id = (SELECT id FROM guilds WHERE guild = ?)
|
||||
",
|
||||
guild_id
|
||||
)
|
||||
.fetch_all(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let content = iter::once("Aliases:".to_string()).chain(
|
||||
aliases
|
||||
.iter()
|
||||
.map(|row| format!("**{}**: `{}`", row.name, row.command)),
|
||||
);
|
||||
|
||||
let _ = msg.channel_id.say_lines(&ctx, content).await;
|
||||
}
|
||||
|
||||
"remove" => {
|
||||
if let Some(command) = command_opt {
|
||||
let deleted_count = sqlx::query!(
|
||||
"
|
||||
SELECT COUNT(1) AS count FROM command_aliases WHERE name = ? AND guild_id = (SELECT id FROM guilds WHERE guild = ?)
|
||||
", command, guild_id)
|
||||
.fetch_one(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
sqlx::query!(
|
||||
"
|
||||
DELETE FROM command_aliases WHERE name = ? AND guild_id = (SELECT id FROM guilds WHERE guild = ?)
|
||||
",
|
||||
command,
|
||||
guild_id
|
||||
)
|
||||
.execute(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let content = lm
|
||||
.get(&language, "alias/removed")
|
||||
.replace("{count}", &deleted_count.count.to_string());
|
||||
|
||||
let _ = msg.channel_id.say(&ctx, content).await;
|
||||
} else {
|
||||
let _ = msg
|
||||
.channel_id
|
||||
.say(&ctx, lm.get(&language, "alias/help"))
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
name => {
|
||||
if let Some(command) = command_opt {
|
||||
let res = sqlx::query!(
|
||||
"
|
||||
INSERT INTO command_aliases (guild_id, name, command) VALUES ((SELECT id FROM guilds WHERE guild = ?), ?, ?)
|
||||
", guild_id, name, command)
|
||||
.execute(&pool)
|
||||
.await;
|
||||
|
||||
if res.is_err() {
|
||||
sqlx::query!(
|
||||
"
|
||||
UPDATE command_aliases SET command = ? WHERE guild_id = (SELECT id FROM guilds WHERE guild = ?) AND name = ?
|
||||
", command, guild_id, name)
|
||||
.execute(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let content = lm.get(&language, "alias/created").replace("{name}", name);
|
||||
|
||||
let _ = msg.channel_id.say(&ctx, content).await;
|
||||
} else {
|
||||
match sqlx::query!(
|
||||
"
|
||||
SELECT command FROM command_aliases WHERE guild_id = (SELECT id FROM guilds WHERE guild = ?) AND name = ?
|
||||
", guild_id, name)
|
||||
.fetch_one(&pool)
|
||||
.await {
|
||||
|
||||
Ok(row) => {
|
||||
let framework = ctx.data.read().await
|
||||
.get::<FrameworkCtx>().cloned().expect("Could not get FrameworkCtx from data");
|
||||
|
||||
let mut new_msg = msg.clone();
|
||||
new_msg.content = format!("<@{}> {}", &ctx.cache.current_user_id(), row.command);
|
||||
new_msg.id = MessageId(0);
|
||||
|
||||
framework.dispatch(ctx.clone(), new_msg).await;
|
||||
},
|
||||
|
||||
Err(_) => {
|
||||
let content = lm.get(&language, "alias/not_found").replace("{name}", name);
|
||||
|
||||
let _ = msg.channel_id.say(&ctx, content).await;
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let prefix = ctx.prefix(msg.guild_id).await;
|
||||
|
||||
command_help(ctx, msg, lm, &prefix, &language, "alias").await;
|
||||
}
|
||||
}
|
||||
*/
|
||||
#[command("webhook")]
|
||||
#[description("Modify this channel's webhooks")]
|
||||
#[subcommand("username")]
|
||||
#[description("Change the webhook username")]
|
||||
#[arg(name = "username", description = "The username to use", kind = "String", required = true)]
|
||||
#[subcommand("avatar")]
|
||||
#[description("Change the webhook avatar")]
|
||||
#[arg(name = "url", description = "The URL of the image to use", kind = "String", required = true)]
|
||||
async fn configure_webhook(ctx: &Context, invoke: CommandInvoke, args: CommandOptions) {}
|
||||
|
@ -22,7 +22,7 @@ use crate::{
|
||||
},
|
||||
consts::{
|
||||
EMBED_DESCRIPTION_MAX_LENGTH, REGEX_CHANNEL_USER, REGEX_NATURAL_COMMAND_1,
|
||||
REGEX_NATURAL_COMMAND_2, THEME_COLOR,
|
||||
REGEX_NATURAL_COMMAND_2, SELECT_MAX_ENTRIES, THEME_COLOR,
|
||||
},
|
||||
framework::{CommandInvoke, CommandOptions, CreateGenericResponse, OptionValue},
|
||||
hooks::{CHECK_GUILD_PERMISSIONS_HOOK, CHECK_MANAGED_PERMISSIONS_HOOK},
|
||||
@ -290,7 +290,7 @@ async fn look(ctx: &Context, invoke: CommandInvoke, args: CommandOptions) {
|
||||
|
||||
let channel_id = if let Some(Channel::Guild(channel)) = channel_opt {
|
||||
if Some(channel.guild_id) == invoke.guild_id() {
|
||||
flags.channel_id.unwrap_or(invoke.channel_id())
|
||||
flags.channel_id.unwrap_or_else(|| invoke.channel_id())
|
||||
} else {
|
||||
invoke.channel_id()
|
||||
}
|
||||
@ -374,45 +374,57 @@ async fn delete(ctx: &Context, invoke: CommandInvoke, _args: CommandOptions) {
|
||||
let _ = interaction
|
||||
.create_interaction_response(&ctx, |r| {
|
||||
*r = resp;
|
||||
r
|
||||
r.kind(InteractionResponseType::ChannelMessageWithSource)
|
||||
})
|
||||
.await;
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
pub fn max_delete_page(reminders: &Vec<Reminder>, timezone: &Tz) -> usize {
|
||||
pub fn max_delete_page(reminders: &[Reminder], timezone: &Tz) -> usize {
|
||||
let mut rows = 0;
|
||||
let mut char_count = 0;
|
||||
|
||||
reminders
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(count, reminder)| reminder.display_del(count, timezone))
|
||||
.fold(0, |t, r| t + r.len())
|
||||
.div_ceil(EMBED_DESCRIPTION_MAX_LENGTH)
|
||||
.fold(1, |mut pages, reminder| {
|
||||
rows += 1;
|
||||
char_count += reminder.len();
|
||||
|
||||
if char_count > EMBED_DESCRIPTION_MAX_LENGTH || rows > SELECT_MAX_ENTRIES {
|
||||
rows = 1;
|
||||
char_count = reminder.len();
|
||||
pages += 1;
|
||||
}
|
||||
|
||||
pages
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn show_delete_page(
|
||||
reminders: &Vec<Reminder>,
|
||||
reminders: &[Reminder],
|
||||
page: usize,
|
||||
timezone: Tz,
|
||||
) -> CreateInteractionResponse {
|
||||
let pager = DelPager::new(timezone);
|
||||
let pager = DelPager::new(page, timezone);
|
||||
|
||||
if reminders.is_empty() {
|
||||
let mut embed = CreateEmbed::default();
|
||||
embed.title("Delete Reminders").description("No Reminders").color(*THEME_COLOR);
|
||||
|
||||
let mut response = CreateInteractionResponse::default();
|
||||
response.kind(InteractionResponseType::UpdateMessage).interaction_response_data(
|
||||
|response| {
|
||||
response.interaction_response_data(|response| {
|
||||
response.embeds(vec![embed]).components(|comp| {
|
||||
pager.create_button_row(0, comp);
|
||||
comp
|
||||
})
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
let pages = max_delete_page(&reminders, &timezone);
|
||||
let pages = max_delete_page(reminders, &timezone);
|
||||
|
||||
let mut page = page;
|
||||
if page >= pages {
|
||||
@ -420,23 +432,37 @@ pub async fn show_delete_page(
|
||||
}
|
||||
|
||||
let mut char_count = 0;
|
||||
let mut skip_char_count = 0;
|
||||
let mut rows = 0;
|
||||
let mut skipped_rows = 0;
|
||||
let mut skipped_char_count = 0;
|
||||
let mut first_num = 0;
|
||||
|
||||
let mut skipped_pages = 0;
|
||||
|
||||
let (shown_reminders, display_vec): (Vec<&Reminder>, Vec<String>) = reminders
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(count, reminder)| (reminder, reminder.display_del(count, &timezone)))
|
||||
.skip_while(|(_, p)| {
|
||||
first_num += 1;
|
||||
skip_char_count += p.len();
|
||||
skipped_rows += 1;
|
||||
skipped_char_count += p.len();
|
||||
|
||||
skip_char_count < EMBED_DESCRIPTION_MAX_LENGTH * page
|
||||
if skipped_char_count > EMBED_DESCRIPTION_MAX_LENGTH
|
||||
|| skipped_rows > SELECT_MAX_ENTRIES
|
||||
{
|
||||
skipped_rows = 1;
|
||||
skipped_char_count = p.len();
|
||||
skipped_pages += 1;
|
||||
}
|
||||
|
||||
skipped_pages < page
|
||||
})
|
||||
.take_while(|(_, p)| {
|
||||
rows += 1;
|
||||
char_count += p.len();
|
||||
|
||||
char_count < EMBED_DESCRIPTION_MAX_LENGTH
|
||||
char_count < EMBED_DESCRIPTION_MAX_LENGTH && rows <= SELECT_MAX_ENTRIES
|
||||
})
|
||||
.unzip();
|
||||
|
||||
@ -452,7 +478,7 @@ pub async fn show_delete_page(
|
||||
.color(*THEME_COLOR);
|
||||
|
||||
let mut response = CreateInteractionResponse::default();
|
||||
response.kind(InteractionResponseType::UpdateMessage).interaction_response_data(|d| {
|
||||
response.interaction_response_data(|d| {
|
||||
d.embeds(vec![embed]).components(|comp| {
|
||||
pager.create_button_row(pages, comp);
|
||||
|
||||
@ -596,7 +622,7 @@ DELETE FROM timers WHERE owner = ? AND name = ?
|
||||
"list" => {
|
||||
let timers = Timer::from_owner(owner, &pool).await;
|
||||
|
||||
if timers.len() > 0 {
|
||||
if !timers.is_empty() {
|
||||
let _ = invoke
|
||||
.respond(
|
||||
ctx.http.clone(),
|
||||
@ -699,7 +725,7 @@ async fn remind(ctx: &Context, invoke: CommandInvoke, args: CommandOptions) {
|
||||
let list = args
|
||||
.get("channels")
|
||||
.map(|arg| parse_mention_list(&arg.to_string()))
|
||||
.unwrap_or(vec![]);
|
||||
.unwrap_or_default();
|
||||
|
||||
if list.is_empty() {
|
||||
vec![ReminderScope::Channel(interaction.channel_id.0)]
|
||||
|
@ -1,7 +1,10 @@
|
||||
use regex_command_attr::command;
|
||||
use serenity::client::Context;
|
||||
|
||||
use crate::framework::{CommandInvoke, CommandOptions};
|
||||
use crate::{
|
||||
framework::{CommandInvoke, CommandOptions, CreateGenericResponse},
|
||||
SQLPool,
|
||||
};
|
||||
|
||||
#[command]
|
||||
#[description("Manage todo lists")]
|
||||
@ -41,4 +44,55 @@ use crate::framework::{CommandInvoke, CommandOptions};
|
||||
)]
|
||||
#[subcommand("view")]
|
||||
#[description("View and remove from your personal todo list")]
|
||||
async fn todo(ctx: &Context, invoke: CommandInvoke, args: CommandOptions) {}
|
||||
async fn todo(ctx: &Context, invoke: CommandInvoke, args: CommandOptions) {
|
||||
if invoke.guild_id().is_none() && args.subcommand_group != Some("user".to_string()) {
|
||||
let _ = invoke
|
||||
.respond(
|
||||
&ctx,
|
||||
CreateGenericResponse::new().content("Please use `/todo user` in direct messages"),
|
||||
)
|
||||
.await;
|
||||
} else {
|
||||
let pool = ctx.data.read().await.get::<SQLPool>().cloned().unwrap();
|
||||
|
||||
let keys = match args.subcommand_group.as_ref().unwrap().as_str() {
|
||||
"server" => (None, None, invoke.guild_id().map(|g| g.0)),
|
||||
"channel" => (None, Some(invoke.channel_id().0), invoke.guild_id().map(|g| g.0)),
|
||||
_ => (Some(invoke.author_id().0), None, None),
|
||||
};
|
||||
|
||||
match args.get("task") {
|
||||
Some(task) => {
|
||||
let task = task.to_string();
|
||||
|
||||
sqlx::query!(
|
||||
"INSERT INTO todos (user_id, channel_id, guild_id, value) VALUES (?, ?, ?, ?)",
|
||||
keys.0,
|
||||
keys.1,
|
||||
keys.2,
|
||||
task
|
||||
)
|
||||
.execute(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let _ = invoke
|
||||
.respond(&ctx, CreateGenericResponse::new().content("Item added to todo list"))
|
||||
.await;
|
||||
}
|
||||
None => {
|
||||
let values = sqlx::query!(
|
||||
"SELECT value FROM todos WHERE user_id = ? AND channel_id = ? AND guild_id = ?",
|
||||
keys.0,
|
||||
keys.1,
|
||||
keys.2,
|
||||
)
|
||||
.fetch_all(&pool)
|
||||
.await
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|row| &row.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -174,7 +174,7 @@ INSERT IGNORE INTO roles (role, name, guild_id) VALUES (?, \"Role\", (SELECT id
|
||||
let _ = component
|
||||
.create_interaction_response(&ctx, move |r| {
|
||||
*r = resp;
|
||||
r
|
||||
r.kind(InteractionResponseType::UpdateMessage)
|
||||
})
|
||||
.await;
|
||||
}
|
||||
@ -195,7 +195,7 @@ INSERT IGNORE INTO roles (role, name, guild_id) VALUES (?, \"Role\", (SELECT id
|
||||
let _ = component
|
||||
.create_interaction_response(&ctx, move |r| {
|
||||
*r = resp;
|
||||
r
|
||||
r.kind(InteractionResponseType::UpdateMessage)
|
||||
})
|
||||
.await;
|
||||
}
|
||||
|
@ -186,8 +186,8 @@ impl Pager for DelPager {
|
||||
}
|
||||
|
||||
impl DelPager {
|
||||
pub fn new(timezone: Tz) -> Self {
|
||||
Self { page: 0, action: PageAction::First, timezone }
|
||||
pub fn new(page: usize, timezone: Tz) -> Self {
|
||||
Self { page, action: PageAction::Refresh, timezone }
|
||||
}
|
||||
|
||||
pub fn buttons(
|
||||
|
@ -2,6 +2,7 @@ pub const DAY: u64 = 86_400;
|
||||
pub const HOUR: u64 = 3_600;
|
||||
pub const MINUTE: u64 = 60;
|
||||
pub const EMBED_DESCRIPTION_MAX_LENGTH: usize = 4000;
|
||||
pub const SELECT_MAX_ENTRIES: usize = 25;
|
||||
|
||||
pub const CHARACTERS: &str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
|
||||
|
||||
|
@ -144,7 +144,7 @@ impl CommandInvoke {
|
||||
d.content(generic_response.content);
|
||||
|
||||
if let Some(embed) = generic_response.embed {
|
||||
d.add_embed(embed.clone());
|
||||
d.add_embed(embed);
|
||||
}
|
||||
|
||||
if let Some(components) = generic_response.components {
|
||||
@ -164,7 +164,7 @@ impl CommandInvoke {
|
||||
d.content(generic_response.content);
|
||||
|
||||
if let Some(embed) = generic_response.embed {
|
||||
d.add_embed(embed.clone());
|
||||
d.add_embed(embed);
|
||||
}
|
||||
|
||||
if let Some(components) = generic_response.components {
|
||||
@ -186,7 +186,7 @@ impl CommandInvoke {
|
||||
m.content(generic_response.content);
|
||||
|
||||
if let Some(embed) = generic_response.embed {
|
||||
m.set_embed(embed.clone());
|
||||
m.set_embed(embed);
|
||||
}
|
||||
|
||||
if let Some(components) = generic_response.components {
|
||||
@ -308,7 +308,7 @@ impl CommandOptions {
|
||||
ApplicationCommandOptionType::String => {
|
||||
cmd_opts.options.insert(
|
||||
option.name,
|
||||
OptionValue::String(option.value.unwrap().to_string()),
|
||||
OptionValue::String(option.value.unwrap().as_str().unwrap().to_string()),
|
||||
);
|
||||
}
|
||||
ApplicationCommandOptionType::Integer => {
|
||||
@ -404,10 +404,7 @@ pub enum CommandFnType {
|
||||
|
||||
impl CommandFnType {
|
||||
pub fn is_slash(&self) -> bool {
|
||||
match self {
|
||||
CommandFnType::Text(_) => false,
|
||||
_ => true,
|
||||
}
|
||||
!matches!(self, CommandFnType::Text(_))
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user