Skip to content

Commit e5909ef

Browse files
committed
feat(paginate): copy paginate logic over and restrict to the author id
1 parent 4add437 commit e5909ef

3 files changed

Lines changed: 73 additions & 7 deletions

File tree

src/abstraction/command.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
use crate::built_info;
22
use lazy_static::lazy_static;
3+
use poise::CreateReply;
4+
use poise::serenity_prelude::CreateActionRow;
35
use reqwest::header::HeaderMap;
46
use serenity::all::RoleId;
7+
use serenity::builder::{
8+
CreateButton, CreateEmbed, CreateInteractionResponse, CreateInteractionResponseMessage,
9+
};
510
use std::env;
611
use std::sync::Arc;
12+
use std::time::Duration;
713

814
pub type CommandError = anyhow::Error;
915
pub type CommandContext<'a> = poise::Context<'a, CommandData, CommandError>;
@@ -89,3 +95,67 @@ pub async fn is_user_trusted_or_above(ctx: CommandContext<'_>) -> CheckResult {
8995

9096
Ok(false)
9197
}
98+
99+
pub async fn paginate<U, E>(
100+
ctx: poise::Context<'_, U, E>,
101+
pages: &[&str],
102+
) -> Result<(), serenity::Error> {
103+
// Define some unique identifiers for the navigation buttons
104+
let ctx_id = ctx.id();
105+
let author_id = ctx.author().id;
106+
let prev_button_id = format!("{}prev", ctx_id);
107+
let next_button_id = format!("{}next", ctx_id);
108+
109+
// Send the embed with the first page as content
110+
let reply = {
111+
let components = CreateActionRow::Buttons(vec![
112+
CreateButton::new(&prev_button_id).emoji('◀'),
113+
CreateButton::new(&next_button_id).emoji('▶'),
114+
]);
115+
116+
CreateReply::default()
117+
.embed(CreateEmbed::default().description(pages[0]))
118+
.components(vec![components])
119+
};
120+
121+
ctx.send(reply).await?;
122+
123+
// Loop through incoming interactions with the navigation buttons
124+
let mut current_page = 0;
125+
while let Some(press) = serenity::collector::ComponentInteractionCollector::new(ctx)
126+
// We defined our button IDs to start with `ctx_id`. If they don't, some other command's
127+
// button was pressed
128+
.filter(move |press| {
129+
press.data.custom_id.starts_with(&ctx_id.to_string()) && press.user.id == author_id
130+
})
131+
// Timeout when no navigation button has been pressed for 24 hours
132+
.timeout(Duration::from_secs(3600 * 24))
133+
.await
134+
{
135+
// Depending on which button was pressed, go to next or previous page
136+
if press.data.custom_id == next_button_id {
137+
current_page += 1;
138+
if current_page >= pages.len() {
139+
current_page = 0;
140+
}
141+
} else if press.data.custom_id == prev_button_id {
142+
current_page = current_page.checked_sub(1).unwrap_or(pages.len() - 1);
143+
} else {
144+
// This is an unrelated button interaction
145+
continue;
146+
}
147+
148+
// Update the message with the new page contents
149+
press
150+
.create_response(
151+
ctx.serenity_context(),
152+
CreateInteractionResponse::UpdateMessage(
153+
CreateInteractionResponseMessage::new()
154+
.embed(CreateEmbed::new().description(pages[current_page])),
155+
),
156+
)
157+
.await?;
158+
}
159+
160+
Ok(())
161+
}

src/abstraction/playmatch.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::abstraction::command::CommandContext;
1+
use crate::abstraction::command::{CommandContext, paginate};
22
use crate::util::create_discord_markdown_table;
33
use playmatch_client::types::{
44
CompanyMetadataResponse, ExternalMetadata, MatchType, MetadataProvider,
@@ -109,7 +109,7 @@ where
109109
.map(|s| s.as_str())
110110
.collect::<Vec<&str>>();
111111

112-
poise::builtins::paginate(ctx, markdown_pages_ref.as_slice()).await?;
112+
paginate(ctx, markdown_pages_ref.as_slice()).await?;
113113

114114
Ok(())
115115
}

src/command/playmatch.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -838,11 +838,7 @@ async fn handle_suggestion_message(data: SuggestionMessageHandleData) -> Command
838838
.await?;
839839

840840
let message = match data.r#type {
841-
SuggestionType::Platform => format!(
842-
"Your Playmatch Metadata Suggestion for {display_type} **{}** was approved! Thank you very much for your contribution 🎉!",
843-
data.name
844-
),
845-
SuggestionType::Company => format!(
841+
SuggestionType::Platform | SuggestionType::Company => format!(
846842
"Your Playmatch Metadata Suggestion for {display_type} **{}** was approved! Thank you very much for your contribution 🎉!",
847843
data.name
848844
),

0 commit comments

Comments
 (0)