diff --git a/Cargo.lock b/Cargo.lock index 29a2260..a933bcd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -123,15 +123,14 @@ dependencies = [ "num-integer", "num-traits", "serde", - "time", "winapi", ] [[package]] name = "command_attr" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a6c3666f685cb1efc0628b8c984dbad9c372d080450736c7732089c385ed81d" +checksum = "9e74a021f9d0b577821bf9f5b1a2be88677e95ee05713e5d44fb4236cfa1744c" dependencies = [ "proc-macro2", "quote", @@ -1057,9 +1056,9 @@ dependencies = [ [[package]] name = "serenity" -version = "0.10.8" +version = "0.10.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b68c1f5dbe25b32516f3f104726a9e8e3a96cf5960a106213241738ffe108f81" +checksum = "dde86919535c6047e055d512641c5241320c01cb8fee54f1e5ba77c939a0ec23" dependencies = [ "async-trait", "async-tungstenite", @@ -1196,16 +1195,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "time" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "tinyvec" version = "1.2.0" diff --git a/Cargo.toml b/Cargo.toml index dea24b7..69a52cd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ tokio-postgres = "*" rand = "*" [dependencies.serenity] -version = "0.10.*" +version = "0.10.10" features = ["cache", "framework", "standard_framework", "rustls_backend", "unstable_discord_api", "collector"] [dependencies.tokio] diff --git a/src/commands/count.rs b/src/commands/count.rs index 9ccdd04..119e5cc 100644 --- a/src/commands/count.rs +++ b/src/commands/count.rs @@ -1,3 +1,4 @@ +use crate::commands::macros::*; use core::time::Duration; use serenity::{ collector::component_interaction_collector::ComponentInteractionCollectorBuilder, @@ -5,7 +6,7 @@ use serenity::{ futures::StreamExt, model::{ channel::ReactionType, - interactions::{ButtonStyle, InteractionData}, + interactions::{message_component::ButtonStyle, InteractionResponseType}, prelude::*, }, prelude::*, @@ -193,43 +194,27 @@ macro_rules! make_embed { $e = $e.field( format!("{}. {}", idx, name), format!(" by <@{}>", owner_id), - true, + false, ); } $e }}; } -macro_rules! make_terminal_components { - ($c: expr, $terminal: expr ) => {{ - $c.create_action_row(|ar| { - ar.create_button(|b| { - b.style(ButtonStyle::Primary) - .label("Prev") - .emoji(ReactionType::Unicode("\u{2B05}".to_string())) - .custom_id("prev") - .disabled($terminal == "first") - }) - .create_button(|b| { - b.style(ButtonStyle::Primary) - .label("Next") - .emoji(ReactionType::Unicode("\u{27A1}".to_string())) - .custom_id("next") - .disabled($terminal == "last") - }) - .create_button(|b| { - b.style(ButtonStyle::Danger) - .label("Delete") - .emoji(ReactionType::Unicode("\u{1F5D1}".to_string())) - .custom_id("delete") - }) - }) - }}; -} - #[command] -#[aliases("clist")] -pub async fn clist(ctx: &Context, msg: &Message, _: Args) -> CommandResult { +#[aliases("cls")] +pub async fn clist(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult { + let size = if args.len() > 0 { + args.single::()? + } else { + 5usize + }; + + if size > 15 { + msg.reply(ctx, "Please input a number less than 15").await?; + () + } + let data_read = ctx.data.read().await; let db = data_read .get::() @@ -245,14 +230,14 @@ pub async fn clist(ctx: &Context, msg: &Message, _: Args) -> CommandResult { msg.reply(ctx, "No words stored").await?; return Ok(()); } - let groups: Vec<&[Row]> = rows.chunks(5).collect(); + let groups: Vec<&[Row]> = rows.chunks(size).collect(); let mut cur = 1; let message = msg .channel_id .send_message(ctx, |m| { m.embed(|mut e| make_embed!(e, cur, groups[cur - 1])) - .components(|c| make_terminal_components!(c, "first")) + .components(|c| make_terminal_components!(c, "first", groups.len())) }) .await?; let mut collector = ComponentInteractionCollectorBuilder::new(&ctx) @@ -261,56 +246,104 @@ pub async fn clist(ctx: &Context, msg: &Message, _: Args) -> CommandResult { .message_id(message.id) .await; while let Some(interaction) = collector.next().await { - if let InteractionData::MessageComponent(component) = interaction.data.as_ref().unwrap() { - match component.custom_id.as_ref() { - "next" => { - if cur != groups.len() { - cur += 1; - let _ = interaction - .create_interaction_response(&ctx, |r| { - r.kind(InteractionResponseType::UpdateMessage) - .interaction_response_data(|m| { - m.create_embed(|mut e| make_embed!(e, cur, groups[cur - 1])) - .components(|c| { - make_terminal_components!( - c, - if cur == groups.len() { - "last" - } else { - "mid" - } - ) - }) - }) - }) - .await; - } + match interaction.data.custom_id.as_ref() { + "next" => { + if cur != groups.len() { + cur += 1; + let _ = interaction + .create_interaction_response(&ctx, |r| { + r.kind(InteractionResponseType::UpdateMessage) + .interaction_response_data(|m| { + m.create_embed(|mut e| make_embed!(e, cur, groups[cur - 1])) + .components(|c| { + make_terminal_components!( + c, + if cur == groups.len() { "last" } else { "mid" }, + groups.len() + ) + }) + }) + }) + .await; } - "prev" => { - if cur != 1 { - cur -= 1; - let _ = interaction - .create_interaction_response(&ctx, |r| { - r.kind(InteractionResponseType::UpdateMessage) - .interaction_response_data(|m| { - m.create_embed(|mut e| make_embed!(e, cur, groups[cur - 1])) - .components(|c| { - make_terminal_components!( - c, - if cur == 1 { "first" } else { "mid" } - ) - }) - }) - }) - .await; - } - } - "delete" => { - message.delete(ctx).await?; - msg.delete(ctx).await?; - } - _ => {} } + "prev" => { + if cur != 1 { + cur -= 1; + let _ = interaction + .create_interaction_response(&ctx, |r| { + r.kind(InteractionResponseType::UpdateMessage) + .interaction_response_data(|m| { + m.create_embed(|mut e| make_embed!(e, cur, groups[cur - 1])) + .components(|c| { + make_terminal_components!( + c, + if cur == 1 { "first" } else { "mid" }, + groups.len() + ) + }) + }) + }) + .await; + } + } + "first" => { + cur = 1; + let _ = interaction + .create_interaction_response(&ctx, |r| { + r.kind(InteractionResponseType::UpdateMessage) + .interaction_response_data(|m| { + m.create_embed(|mut e| make_embed!(e, cur, groups[cur - 1])) + .components(|c| { + make_terminal_components!(c, "first", groups.len()) + }) + }) + }) + .await; + } + "last" => { + cur = groups.len(); + let _ = interaction + .create_interaction_response(&ctx, |r| { + r.kind(InteractionResponseType::UpdateMessage) + .interaction_response_data(|m| { + m.create_embed(|mut e| make_embed!(e, cur, groups[cur - 1])) + .components(|c| { + make_terminal_components!(c, "last", groups.len()) + }) + }) + }) + .await; + } + "delete" => { + message.delete(ctx).await?; + msg.delete(ctx).await?; + } + "range" => { + cur = interaction.data.values[0].parse().unwrap(); + let _ = interaction + .create_interaction_response(&ctx, |r| { + r.kind(InteractionResponseType::UpdateMessage) + .interaction_response_data(|m| { + m.create_embed(|mut e| make_embed!(e, cur, groups[cur - 1])) + .components(|c| { + make_terminal_components!( + c, + if cur == 1 { + "first" + } else if cur == groups.len() { + "last" + } else { + "mid" + }, + groups.len() + ) + }) + }) + }) + .await; + } + _ => {} } } Ok(()) diff --git a/src/commands/macros.rs b/src/commands/macros.rs new file mode 100644 index 0000000..c38d724 --- /dev/null +++ b/src/commands/macros.rs @@ -0,0 +1,57 @@ +macro_rules! make_range_select_menu { + ($sm:expr, $f: expr, $l: expr) => {{ + $sm.custom_id("range") + .placeholder("Page No") + .options(|mut os| { + for x in $f..=$l { + os = os.create_option(|o| o.label(x).value(x)); + } + + os + }) + }}; +} + +macro_rules! make_terminal_components { + ($c: expr, $terminal: expr, $pages: expr ) => {{ + $c.create_action_row(|ar| { + ar.create_button(|b| { + b.style(ButtonStyle::Primary) + .label("First") + .emoji(ReactionType::Unicode("\u{23EA}".to_string())) + .custom_id("first") + .disabled($terminal == "first") + }) + .create_button(|b| { + b.style(ButtonStyle::Primary) + .label("Prev") + .emoji(ReactionType::Unicode("\u{25C0}".to_string())) + .custom_id("prev") + .disabled($terminal == "first") + }) + .create_button(|b| { + b.style(ButtonStyle::Primary) + .label("Next") + .emoji(ReactionType::Unicode("\u{25B6}".to_string())) + .custom_id("next") + .disabled($terminal == "last") + }) + .create_button(|b| { + b.style(ButtonStyle::Primary) + .label("Last") + .emoji(ReactionType::Unicode("\u{23E9}".to_string())) + .custom_id("last") + .disabled($terminal == "last") + }) + .create_button(|b| { + b.style(ButtonStyle::Danger) + .label("Delete") + .emoji(ReactionType::Unicode("\u{1F5D1}".to_string())) + .custom_id("delete") + }) + }) + .create_action_row(|ar| ar.create_select_menu(|sm| make_range_select_menu!(sm, 1, $pages))) + }}; +} +pub(crate) use make_range_select_menu; +pub(crate) use make_terminal_components; diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 754b8fe..dd85fa4 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -2,3 +2,4 @@ pub mod count; pub mod general; pub mod minigames; pub mod tags; +pub mod macros; diff --git a/src/commands/tags.rs b/src/commands/tags.rs index c7e7880..6f61826 100644 --- a/src/commands/tags.rs +++ b/src/commands/tags.rs @@ -1,3 +1,4 @@ +use crate::commands::macros::*; use core::time::Duration; use serenity::{ collector::component_interaction_collector::ComponentInteractionCollectorBuilder, @@ -5,7 +6,7 @@ use serenity::{ futures::StreamExt, model::{ channel::ReactionType, - interactions::{ButtonStyle, InteractionData}, + interactions::{message_component::ButtonStyle, InteractionResponseType}, prelude::*, }, prelude::*, @@ -233,43 +234,27 @@ macro_rules! make_embed { $e = $e.field( format!("{}. {}", idx, name), format!(" by <@{}>", owner_id), - true, + false, ); } $e }}; } -macro_rules! make_terminal_components { - ($c: expr, $terminal: expr ) => {{ - $c.create_action_row(|ar| { - ar.create_button(|b| { - b.style(ButtonStyle::Primary) - .label("Prev") - .emoji(ReactionType::Unicode("\u{2B05}".to_string())) - .custom_id("prev") - .disabled($terminal == "first") - }) - .create_button(|b| { - b.style(ButtonStyle::Primary) - .label("Next") - .emoji(ReactionType::Unicode("\u{27A1}".to_string())) - .custom_id("next") - .disabled($terminal == "last") - }) - .create_button(|b| { - b.style(ButtonStyle::Danger) - .label("Delete") - .emoji(ReactionType::Unicode("\u{1F5D1}".to_string())) - .custom_id("delete") - }) - }) - }}; -} - #[command] #[aliases("tls")] -pub async fn tlist(ctx: &Context, msg: &Message, _: Args) -> CommandResult { +pub async fn tlist(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult { + let size = if args.len() > 0 { + args.single::()? + } else { + 5usize + }; + + if size > 15 { + msg.reply(ctx, "Please input a number less than 15").await?; + () + } + let data_read = ctx.data.read().await; let db = data_read .get::() @@ -285,14 +270,14 @@ pub async fn tlist(ctx: &Context, msg: &Message, _: Args) -> CommandResult { msg.reply(ctx, "No tags stored").await?; return Ok(()); } - let groups: Vec<&[Row]> = rows.chunks(5).collect(); + let groups: Vec<&[Row]> = rows.chunks(size).collect(); let mut cur = 1; let message = msg .channel_id .send_message(ctx, |m| { m.embed(|mut e| make_embed!(e, cur, groups[cur - 1])) - .components(|c| make_terminal_components!(c, "first")) + .components(|c| make_terminal_components!(c, "first", groups.len())) }) .await?; let mut collector = ComponentInteractionCollectorBuilder::new(&ctx) @@ -300,57 +285,107 @@ pub async fn tlist(ctx: &Context, msg: &Message, _: Args) -> CommandResult { .author_id(msg.author.id) .message_id(message.id) .await; + while let Some(interaction) = collector.next().await { - if let InteractionData::MessageComponent(component) = interaction.data.as_ref().unwrap() { - match component.custom_id.as_ref() { - "next" => { - if cur != groups.len() { - cur += 1; - let _ = interaction - .create_interaction_response(&ctx, |r| { - r.kind(InteractionResponseType::UpdateMessage) - .interaction_response_data(|m| { - m.create_embed(|mut e| make_embed!(e, cur, groups[cur - 1])) - .components(|c| { - make_terminal_components!( - c, - if cur == groups.len() { - "last" - } else { - "mid" - } - ) - }) - }) - }) - .await; - } + let custom_id = interaction.data.custom_id.as_ref(); + match custom_id { + "next" => { + if cur != groups.len() { + cur += 1; + let _ = interaction + .create_interaction_response(&ctx, |r| { + r.kind(InteractionResponseType::UpdateMessage) + .interaction_response_data(|m| { + m.create_embed(|mut e| make_embed!(e, cur, groups[cur - 1])) + .components(|c| { + make_terminal_components!( + c, + if cur == groups.len() { "last" } else { "mid" }, + groups.len() + ) + }) + }) + }) + .await; } - "prev" => { - if cur != 1 { - cur -= 1; - let _ = interaction - .create_interaction_response(&ctx, |r| { - r.kind(InteractionResponseType::UpdateMessage) - .interaction_response_data(|m| { - m.create_embed(|mut e| make_embed!(e, cur, groups[cur - 1])) - .components(|c| { - make_terminal_components!( - c, - if cur == 1 { "first" } else { "mid" } - ) - }) - }) - }) - .await; - } - } - "delete" => { - message.delete(ctx).await?; - msg.delete(ctx).await?; - } - _ => {} } + "prev" => { + if cur != 1 { + cur -= 1; + let _ = interaction + .create_interaction_response(&ctx, |r| { + r.kind(InteractionResponseType::UpdateMessage) + .interaction_response_data(|m| { + m.create_embed(|mut e| make_embed!(e, cur, groups[cur - 1])) + .components(|c| { + make_terminal_components!( + c, + if cur == 1 { "first" } else { "mid" }, + groups.len() + ) + }) + }) + }) + .await; + } + } + "first" => { + cur = 1; + let _ = interaction + .create_interaction_response(&ctx, |r| { + r.kind(InteractionResponseType::UpdateMessage) + .interaction_response_data(|m| { + m.create_embed(|mut e| make_embed!(e, cur, groups[cur - 1])) + .components(|c| { + make_terminal_components!(c, "first", groups.len()) + }) + }) + }) + .await; + } + "last" => { + cur = groups.len(); + let _ = interaction + .create_interaction_response(&ctx, |r| { + r.kind(InteractionResponseType::UpdateMessage) + .interaction_response_data(|m| { + m.create_embed(|mut e| make_embed!(e, cur, groups[cur - 1])) + .components(|c| { + make_terminal_components!(c, "last", groups.len()) + }) + }) + }) + .await; + } + "delete" => { + message.delete(ctx).await?; + msg.delete(ctx).await?; + } + "range" => { + cur = interaction.data.values[0].parse().unwrap(); + let _ = interaction + .create_interaction_response(&ctx, |r| { + r.kind(InteractionResponseType::UpdateMessage) + .interaction_response_data(|m| { + m.create_embed(|mut e| make_embed!(e, cur, groups[cur - 1])) + .components(|c| { + make_terminal_components!( + c, + if cur == 1 { + "first" + } else if cur == groups.len() { + "last" + } else { + "mid" + }, + groups.len() + ) + }) + }) + }) + .await; + } + _ => {} } } Ok(()) diff --git a/src/handler/mod.rs b/src/handler/mod.rs index 844efd9..f71bece 100644 --- a/src/handler/mod.rs +++ b/src/handler/mod.rs @@ -2,15 +2,7 @@ mod count; mod interactions; use serenity::{ async_trait, - model::{ - channel::Message, - event::ResumedEvent, - gateway::Ready, - interactions::{ - ApplicationCommand, Interaction, InteractionData, InteractionResponseType, - InteractionType, - }, - }, + model::{channel::Message, event::ResumedEvent, gateway::Ready}, prelude::*, }; use tracing::info; @@ -19,12 +11,8 @@ pub struct Handler; #[async_trait] impl EventHandler for Handler { - async fn ready(&self, ctx: Context, ready: Ready) { - info!("{} connected bhay", ready.user.name); - let _ = ApplicationCommand::create_global_application_commands(&ctx.http, |commands| { - commands.set_application_commands(interactions::general()) - }) - .await; + async fn ready(&self, _: Context, ready: Ready) { + println!("{} connected bhay", ready.user.name); } async fn resume(&self, _: Context, _: ResumedEvent) { info!("how th when the"); @@ -37,23 +25,4 @@ impl EventHandler for Handler { .clone(); count::count(msg, db_client).await; } - - async fn interaction_create(&self, ctx: Context, interaction: Interaction) { - if interaction.kind == InteractionType::ApplicationCommand { - if let Some(InteractionData::ApplicationCommand(data)) = interaction.data.as_ref() { - if let Err(why) = interaction - .create_interaction_response(&ctx.http, |response| { - response - .kind(InteractionResponseType::ChannelMessageWithSource) - .interaction_response_data(|message| { - interactions::responses(data.name.to_string(), message) - }) - }) - .await - { - println!("Cannot respond to slash command: {}", why); - } - } - } - } }