use crate::error::ManifoldResult; use crate::ManifoldContext; use poise::{ReplyHandle, serenity_prelude}; use poise::serenity_prelude::CreateEmbed; pub async fn paginate(ctx: ManifoldContext<'_>, message: ReplyHandle<'_>, pages: Vec, mut current_page: usize) -> ManifoldResult<()> { // Define some unique identifiers for the navigation buttons let ctx_id = ctx.id(); let prev_button_id = format!("{}prev", ctx.id()); let next_button_id = format!("{}next", ctx.id()); // Send the embed with the first page as content message.edit(ctx, |m| { m.embeds = vec![pages[current_page].to_owned()]; m.components(|b| { b.create_action_row(|b| { b.create_button(|b| b.custom_id(&prev_button_id).emoji('◀')) .create_button(|b| b.custom_id(&next_button_id).emoji('▶')) }) }) }).await?; // Loop through incoming interactions with the navigation buttons while let Some(press) = serenity_prelude::CollectComponentInteraction::new(ctx) // We defined our button IDs to start with `ctx_id`. If they don't, some other command's // button was pressed .filter(move |press| press.data.custom_id.starts_with(&ctx_id.to_string())) // Timeout when no navigation button has been pressed for 24 hours .timeout(std::time::Duration::from_secs(300)) .await { // Depending on which button was pressed, go to next or previous page if press.data.custom_id == next_button_id { current_page += 1; if current_page >= pages.len() { current_page = 0; } } else if press.data.custom_id == prev_button_id { current_page = current_page.checked_sub(1).unwrap_or(pages.len() - 1); } else { // This is an unrelated button interaction continue; } // Update the message with the new page contents press .create_interaction_response(ctx, |b| { b.kind(serenity_prelude::InteractionResponseType::UpdateMessage) .interaction_response_data(|b| b.set_embeds(vec![pages[current_page.clone()].to_owned()])) }) .await?; } Ok(()) }