From 5fde2f343a5e96c86bced194b6201fc316cedabd Mon Sep 17 00:00:00 2001 From: Natsu Kagami Date: Thu, 20 Feb 2025 20:07:17 +0100 Subject: [PATCH] pagination: Directly pass list of interactions to render --- youmubot-cf/src/lib.rs | 8 +--- youmubot-core/src/community/roles.rs | 4 +- youmubot-core/src/fun/images.rs | 2 +- youmubot-osu/src/discord/display.rs | 25 ++++++----- youmubot-osu/src/discord/hook.rs | 2 +- youmubot-osu/src/discord/server_rank.rs | 8 +--- youmubot-prelude/src/pagination.rs | 57 ++++++++++++++++--------- 7 files changed, 59 insertions(+), 47 deletions(-) diff --git a/youmubot-cf/src/lib.rs b/youmubot-cf/src/lib.rs index 49d0531..d419a56 100644 --- a/youmubot-cf/src/lib.rs +++ b/youmubot-cf/src/lib.rs @@ -222,9 +222,7 @@ pub async fn ranks(ctx: &Context, m: &Message) -> CommandResult { )) .build(); - Ok(Some( - EditMessage::new().content(content).components(vec![btns]), - )) + Ok(Some(EditMessage::new().content(content).components(btns))) }) }) .with_page_count(total_pages), @@ -390,9 +388,7 @@ pub(crate) async fn contest_rank_table( .push_line(format!("Page **{}/{}**", page + 1, total_pages)) .build(); - Ok(Some( - EditMessage::new().content(content).components(vec![btns]), - )) + Ok(Some(EditMessage::new().content(content).components(btns))) }) }) .with_page_count(total_pages), diff --git a/youmubot-core/src/community/roles.rs b/youmubot-core/src/community/roles.rs index 06f9db8..dfb96ab 100644 --- a/youmubot-core/src/community/roles.rs +++ b/youmubot-core/src/community/roles.rs @@ -77,9 +77,7 @@ async fn list(ctx: &Context, m: &Message, _: Args) -> CommandResult { .push_line(format!("Page **{}/{}**", page + 1, pages)) .build(); - Ok(Some( - EditMessage::new().content(content).components(vec![btns]), - )) + Ok(Some(EditMessage::new().content(content).components(btns))) }) }) .with_page_count(pages), diff --git a/youmubot-core/src/fun/images.rs b/youmubot-core/src/fun/images.rs index 733e84a..48c0fb3 100644 --- a/youmubot-core/src/fun/images.rs +++ b/youmubot-core/src/fun/images.rs @@ -81,7 +81,7 @@ async fn message_command( images.len(), images[page] )) - .components(vec![btns]), + .components(btns), )) } }) diff --git a/youmubot-osu/src/discord/display.rs b/youmubot-osu/src/discord/display.rs index 7621806..1d5b381 100644 --- a/youmubot-osu/src/discord/display.rs +++ b/youmubot-osu/src/discord/display.rs @@ -53,7 +53,7 @@ mod scores { mod grid { use pagination::paginate_with_first_message; - use serenity::all::GuildId; + use serenity::all::{CreateActionRow, GuildId}; use serenity::builder::EditMessage; use serenity::model::channel::Message; @@ -97,6 +97,7 @@ mod scores { page: u8, ctx: &Context, msg: &Message, + btns: Vec, ) -> Result> { let env = ctx.data.read().await.get::().unwrap().clone(); let page = page as usize; @@ -127,7 +128,12 @@ mod scores { .footer(format!("Page {}/{}", page + 1, self.scores.len())) .build() }) - .components(vec![score_components(self.guild_id), self.pagination_row()]), + .components( + vec![score_components(self.guild_id)] + .into_iter() + .chain(btns) + .collect(), + ), )) } @@ -141,6 +147,7 @@ mod scores { use std::borrow::Cow; use pagination::paginate_with_first_message; + use serenity::all::CreateActionRow; use serenity::builder::EditMessage; use serenity::model::channel::Message; @@ -196,6 +203,7 @@ mod scores { page: u8, ctx: &Context, _: &Message, + btns: Vec, ) -> Result> { let env = ctx.data.read().await.get::().unwrap().clone(); @@ -323,11 +331,7 @@ mod scores { .push_line("[?] means pp was predicted by oppai-rs.") .build(); - Ok(Some( - EditMessage::new() - .content(content) - .components(vec![self.pagination_row()]), - )) + Ok(Some(EditMessage::new().content(content).components(btns))) } fn len(&self) -> Option { @@ -339,7 +343,7 @@ mod scores { mod beatmapset { use serenity::{ - all::{CreateButton, GuildId}, + all::{CreateActionRow, CreateButton, GuildId}, builder::{CreateEmbedFooter, EditMessage}, model::channel::{Message, ReactionType}, }; @@ -433,6 +437,7 @@ mod beatmapset { page: u8, ctx: &Context, msg: &Message, + btns: Vec, ) -> Result> { let page = page as usize; if page == self.maps.len() { @@ -442,7 +447,7 @@ mod beatmapset { &self.maps[..], self.mode, )) - .components(vec![self.pagination_row()]), + .components(btns), )); } if page > self.maps.len() { @@ -489,7 +494,7 @@ mod beatmapset { )) }) ) - .components(vec![beatmap_components(map.mode, self.guild_id), self.pagination_row()]), + .components(std::iter::once(beatmap_components(map.mode, self.guild_id)).chain(btns).collect()), )) } diff --git a/youmubot-osu/src/discord/hook.rs b/youmubot-osu/src/discord/hook.rs index 2cf7bc3..0c4145b 100644 --- a/youmubot-osu/src/discord/hook.rs +++ b/youmubot-osu/src/discord/hook.rs @@ -199,7 +199,7 @@ pub fn dot_osu_hook<'a>( let mut edit = EditMessage::new() .content(format!("Attached beatmaps ({}/{})", page + 1, embed_len)) .embed(embed.clone()) - .components(vec![btns]); + .components(btns); for att in attachments { edit = edit.new_attachment(att.clone()); } diff --git a/youmubot-osu/src/discord/server_rank.rs b/youmubot-osu/src/discord/server_rank.rs index f5a2bd4..ce4e1d6 100644 --- a/youmubot-osu/src/discord/server_rank.rs +++ b/youmubot-osu/src/discord/server_rank.rs @@ -317,9 +317,7 @@ where last_update.format(""), )) .build(); - Ok(Some( - EditMessage::new().content(content).components(vec![btns]), - )) + Ok(Some(EditMessage::new().content(content).components(btns))) }) }) .with_page_count(total_pages), @@ -719,9 +717,7 @@ pub async fn display_rankings_table( )) .build(); - Ok(Some( - EditMessage::new().content(content).components(vec![btns]), - )) + Ok(Some(EditMessage::new().content(content).components(btns))) }) }) .with_page_count(total_pages), diff --git a/youmubot-prelude/src/pagination.rs b/youmubot-prelude/src/pagination.rs index 01213d2..397b2c6 100644 --- a/youmubot-prelude/src/pagination.rs +++ b/youmubot-prelude/src/pagination.rs @@ -1,4 +1,4 @@ -use crate::{Context, Result}; +use crate::{Context, OkPrint, Result}; use futures_util::future::Future; use serenity::{ all::{ @@ -30,13 +30,17 @@ const FAST_PREV: &str = "youmubot_pagination_fast_prev"; pub trait Paginate: Send + Sized { /// Render the given page. /// Remember to add the [[interaction_buttons]] as an action row! - async fn render(&mut self, page: u8, ctx: &Context, m: &Message) - -> Result>; + async fn render( + &mut self, + page: u8, + ctx: &Context, + m: &Message, + btns: Vec, + ) -> Result>; - /// The [[CreateActionRow]] for pagination. - fn pagination_row(&self) -> CreateActionRow { - CreateActionRow::Buttons(self.interaction_buttons()) - } + // /// The [[CreateActionRow]] for pagination. + // fn pagination_row(&self) -> CreateActionRow { + // } /// A list of buttons to create that would interact with pagination logic. fn interaction_buttons(&self) -> Vec { @@ -84,7 +88,18 @@ pub async fn do_render( ctx: &Context, m: &mut Message, ) -> Result { - if let Some(edit) = p.render(page, ctx, m).await? { + let btns = vec![CreateActionRow::Buttons(p.interaction_buttons())]; + do_render_with_btns(p, page, ctx, m, btns).await +} + +async fn do_render_with_btns( + p: &mut impl Paginate, + page: u8, + ctx: &Context, + m: &mut Message, + btns: Vec, +) -> Result { + if let Some(edit) = p.render(page, ctx, m, btns).await? { m.edit(ctx, edit).await?; Ok(true) } else { @@ -97,7 +112,7 @@ pub fn paginate_from_fn( u8, &'m Context, &'m Message, - CreateActionRow, + Vec, ) -> std::pin::Pin< Box>> + Send + 'm>, > + Send, @@ -132,11 +147,12 @@ impl Paginate for WithPageCount { page: u8, ctx: &Context, m: &Message, + btns: Vec, ) -> Result> { if page as usize >= self.page_count { return Ok(None); } - self.inner.render(page, ctx, m).await + self.inner.render(page, ctx, m, btns).await } async fn handle_reaction( @@ -167,7 +183,7 @@ where u8, &'m Context, &'m Message, - CreateActionRow, + Vec, ) -> std::pin::Pin< Box>> + Send + 'm>, > + Send, @@ -177,8 +193,8 @@ where page: u8, ctx: &Context, m: &Message, + btns: Vec, ) -> Result> { - let btns = self.pagination_row(); self(page, ctx, m, btns).await } } @@ -249,6 +265,10 @@ pub async fn paginate_with_first_message( } }; + // Render one last time with no buttons + do_render_with_btns(&mut pager, page, ctx, &mut message, vec![]) + .await + .pls_ok(); Paginator::pop(ctx, &message).await?; res @@ -279,14 +299,11 @@ pub async fn handle_pagination_reaction( FAST_NEXT => (pages.unwrap() as u8 - 1).min(page + fast), _ => return Ok(page), }; - Ok( - if let Some(edit) = pager.render(new_page, ctx, message).await? { - message.edit(ctx, edit).await?; - new_page - } else { - page - }, - ) + Ok(if do_render(pager, new_page, ctx, message).await? { + new_page + } else { + page + }) } #[derive(Debug, Clone)]