From b13e662569afa3b78d0ebf100d7eb5d4c48746aa Mon Sep 17 00:00:00 2001 From: Natsu Kagami Date: Sat, 15 Feb 2025 17:46:40 +0100 Subject: [PATCH] wip --- youmubot-osu/src/discord/display.rs | 9 ++- youmubot-prelude/src/editable.rs | 2 +- youmubot-prelude/src/pagination.rs | 121 ++++++++++++++-------------- 3 files changed, 68 insertions(+), 64 deletions(-) diff --git a/youmubot-osu/src/discord/display.rs b/youmubot-osu/src/discord/display.rs index 35fbc2e..a0d08f9 100644 --- a/youmubot-osu/src/discord/display.rs +++ b/youmubot-osu/src/discord/display.rs @@ -43,7 +43,7 @@ mod scores { mode: Mode, ctx: &Context, guild_id: Option, - m: Message, + m: impl Editable, ) -> Result<()> { match self { ScoreListStyle::Table => table::display_scores_table(scores, mode, ctx, m).await, @@ -56,6 +56,7 @@ mod scores { mod grid { use pagination::paginate_with_first_message; + use poise::CreateReply; use serenity::all::GuildId; use serenity::builder::EditMessage; use serenity::model::channel::Message; @@ -71,10 +72,10 @@ mod scores { mode: Mode, ctx: &Context, guild_id: Option, - mut on: Message, + mut on: impl Editable, ) -> Result<()> { if scores.is_empty() { - on.edit(&ctx, EditMessage::new().content("No plays found")) + on.edit_msg(CreateReply::default().content("No plays found")) .await?; return Ok(()); } @@ -160,7 +161,7 @@ mod scores { scores: Vec, mode: Mode, ctx: &Context, - mut on: Message, + mut on: impl Editable, ) -> Result<()> { if scores.is_empty() { on.edit(&ctx, EditMessage::new().content("No plays found")) diff --git a/youmubot-prelude/src/editable.rs b/youmubot-prelude/src/editable.rs index 2197b24..115a535 100644 --- a/youmubot-prelude/src/editable.rs +++ b/youmubot-prelude/src/editable.rs @@ -5,7 +5,7 @@ use crate::CmdContext; use core::future::Future; /// Represents an editable message context. -pub trait Editable { +pub trait Editable: Send { /// Edits the underlying message. fn edit_msg(&mut self, reply: CreateReply) -> impl Future> + Send; } diff --git a/youmubot-prelude/src/pagination.rs b/youmubot-prelude/src/pagination.rs index f1817b5..516fcca 100644 --- a/youmubot-prelude/src/pagination.rs +++ b/youmubot-prelude/src/pagination.rs @@ -1,4 +1,4 @@ -use crate::{Context, OkPrint, Result}; +use crate::{editable_message, Context, Editable, OkPrint, Result}; use futures_util::{future::Future, StreamExt as _}; use serenity::{ builder::CreateMessage, @@ -20,15 +20,15 @@ const FAST_FORWARD: &str = "⏩"; #[async_trait::async_trait] pub trait Paginate: Send + Sized { /// Render the given page. - async fn render(&mut self, page: u8, ctx: &Context, m: &mut Message) -> Result; + async fn render(&mut self, page: u8, ctx: &Context, m: &mut impl Editable) -> Result; /// Any setting-up before the rendering stage. - async fn prerender(&mut self, _ctx: &Context, _m: &mut Message) -> Result<()> { + async fn prerender(&mut self, _ctx: &Context, _m: &mut impl Editable) -> Result<()> { Ok(()) } /// Cleans up after the pagination has timed out. - async fn cleanup(&mut self, _ctx: &Context, _m: &mut Message) -> () {} + async fn cleanup(&mut self, _ctx: &Context, _m: &mut impl Editable) -> () {} /// Handle the incoming reaction. Defaults to calling `handle_pagination_reaction`, but you can do some additional handling /// before handing the functionality over. @@ -38,7 +38,7 @@ pub trait Paginate: Send + Sized { &mut self, page: u8, ctx: &Context, - message: &mut Message, + message: &mut impl Editable, reaction: &Reaction, ) -> Result> { handle_pagination_reaction(page, self, ctx, message, reaction) @@ -65,16 +65,17 @@ pub trait Paginate: Send + Sized { } } -pub fn paginate_from_fn( - pager: impl for<'m> FnMut( - u8, - &'m Context, - &'m mut Message, - ) -> std::pin::Pin> + Send + 'm>> - + Send, -) -> impl Paginate { - pager -} +// pub fn paginate_from_fn( +// pager: impl for<'m, M: Editable> FnMut( +// u8, +// &'m Context, +// &'m mut M, +// ) -> std::pin::Pin< +// Box> + Send + 'm>, +// > + Send, +// ) -> impl Paginate { +// pager +// } struct WithPageCount { inner: Inner, @@ -83,13 +84,13 @@ struct WithPageCount { #[async_trait::async_trait] impl Paginate for WithPageCount { - async fn render(&mut self, page: u8, ctx: &Context, m: &mut Message) -> Result { + async fn render(&mut self, page: u8, ctx: &Context, m: &mut impl Editable) -> Result { if page as usize >= self.page_count { return Ok(false); } self.inner.render(page, ctx, m).await } - async fn prerender(&mut self, ctx: &Context, m: &mut Message) -> Result<()> { + async fn prerender(&mut self, ctx: &Context, m: &mut impl Editable) -> Result<()> { self.inner.prerender(ctx, m).await } @@ -97,7 +98,7 @@ impl Paginate for WithPageCount { &mut self, page: u8, ctx: &Context, - message: &mut Message, + message: &mut impl Editable, reaction: &Reaction, ) -> Result> { // handle normal reactions first, then fallback to the inner one @@ -120,25 +121,25 @@ impl Paginate for WithPageCount { Some(self.page_count == 0) } - async fn cleanup(&mut self, ctx: &Context, msg: &mut Message) { + async fn cleanup(&mut self, ctx: &Context, msg: &mut impl Editable) { self.inner.cleanup(ctx, msg).await; } } -#[async_trait::async_trait] -impl Paginate for T -where - T: for<'m> FnMut( - u8, - &'m Context, - &'m mut Message, - ) -> std::pin::Pin> + Send + 'm>> - + Send, -{ - async fn render(&mut self, page: u8, ctx: &Context, m: &mut Message) -> Result { - self(page, ctx, m).await - } -} +// #[async_trait::async_trait] +// impl Paginate for T +// where +// T: for<'m> FnMut( +// u8, +// &'m Context, +// &'m mut Message, +// ) -> std::pin::Pin> + Send + 'm>> +// + Send, +// { +// async fn render(&mut self, page: u8, ctx: &Context, m: &mut impl Editable) -> Result { +// self(page, ctx, m).await +// } +// } // Paginate! with a pager function, and replying to a message. /// If awaited, will block until everything is done. @@ -151,7 +152,8 @@ pub async fn paginate_reply( let message = reply_to .reply(&ctx, "Youmu is loading the first page...") .await?; - paginate_with_first_message(pager, ctx, message, timeout).await + let mut edit = editable_message(message, ctx.clone()); + paginate_with_first_message(pager, ctx, edit, timeout).await } // Paginate! with a pager function. @@ -168,14 +170,15 @@ pub async fn paginate( CreateMessage::new().content("Youmu is loading the first page..."), ) .await?; - paginate_with_first_message(pager, ctx, message, timeout).await + let mut edit = editable_message(message, ctx.clone()); + paginate_with_first_message(pager, ctx, edit, timeout).await } /// Paginate with the first message already created. pub async fn paginate_with_first_message( mut pager: impl Paginate, ctx: &Context, - mut message: Message, + message: impl Editable, timeout: std::time::Duration, ) -> Result<()> { pager.prerender(ctx, &mut message).await?; @@ -188,28 +191,28 @@ pub async fn paginate_with_first_message( let large_count = pager.len().filter(|&p| p > 10).is_some(); let reactions = { let mut rs = Vec::::with_capacity(4); - if large_count { - // add >> and << buttons - rs.push(message.react(&ctx, ReactionType::try_from(REWIND)?).await?); - } - rs.push( - message - .react(&ctx, ReactionType::try_from(ARROW_LEFT)?) - .await?, - ); - rs.push( - message - .react(&ctx, ReactionType::try_from(ARROW_RIGHT)?) - .await?, - ); - if large_count { - // add >> and << buttons - rs.push( - message - .react(&ctx, ReactionType::try_from(FAST_FORWARD)?) - .await?, - ); - } + // if large_count { + // // add >> and << buttons + // rs.push(message.react(&ctx, ReactionType::try_from(REWIND)?).await?); + // } + // rs.push( + // message + // .react(&ctx, ReactionType::try_from(ARROW_LEFT)?) + // .await?, + // ); + // rs.push( + // message + // .react(&ctx, ReactionType::try_from(ARROW_RIGHT)?) + // .await?, + // ); + // if large_count { + // // add >> and << buttons + // rs.push( + // message + // .react(&ctx, ReactionType::try_from(FAST_FORWARD)?) + // .await?, + // ); + // } rs }; // Build a reaction collector @@ -264,7 +267,7 @@ pub async fn handle_pagination_reaction( page: u8, pager: &mut impl Paginate, ctx: &Context, - message: &mut Message, + message: &mut impl Editable, reaction: &Reaction, ) -> Result { let pages = pager.len();