mirror of
https://github.com/natsukagami/youmubot.git
synced 2025-05-24 01:00:49 +00:00
Change pagination to use interactions instead of reactions
This commit is contained in:
parent
460624c7fe
commit
d1f3aa5fa9
8 changed files with 281 additions and 227 deletions
|
@ -92,7 +92,12 @@ mod scores {
|
|||
|
||||
#[async_trait]
|
||||
impl pagination::Paginate for Paginate {
|
||||
async fn render(&mut self, page: u8, ctx: &Context, msg: &mut Message) -> Result<bool> {
|
||||
async fn render(
|
||||
&mut self,
|
||||
page: u8,
|
||||
ctx: &Context,
|
||||
msg: &Message,
|
||||
) -> Result<Option<EditMessage>> {
|
||||
let env = ctx.data.read().await.get::<OsuEnv>().unwrap().clone();
|
||||
let page = page as usize;
|
||||
let score = &self.scores[page];
|
||||
|
@ -115,22 +120,17 @@ mod scores {
|
|||
.await?
|
||||
.ok_or_else(|| Error::msg("user not found"))?;
|
||||
|
||||
msg.edit(
|
||||
ctx,
|
||||
hourglass.delete(ctx).await?;
|
||||
save_beatmap(&env, msg.channel_id, &bm).await?;
|
||||
Ok(Some(
|
||||
EditMessage::new()
|
||||
.embed({
|
||||
crate::discord::embeds::score_embed(score, &bm, &content, &user)
|
||||
.footer(format!("Page {}/{}", page + 1, self.scores.len()))
|
||||
.build()
|
||||
})
|
||||
.components(vec![score_components(self.guild_id)]),
|
||||
)
|
||||
.await?;
|
||||
save_beatmap(&env, msg.channel_id, &bm).await?;
|
||||
|
||||
// End
|
||||
hourglass.delete(ctx).await?;
|
||||
Ok(true)
|
||||
.components(vec![score_components(self.guild_id), self.pagination_row()]),
|
||||
))
|
||||
}
|
||||
|
||||
fn len(&self) -> Option<usize> {
|
||||
|
@ -193,7 +193,12 @@ mod scores {
|
|||
|
||||
#[async_trait]
|
||||
impl pagination::Paginate for Paginate {
|
||||
async fn render(&mut self, page: u8, ctx: &Context, msg: &mut Message) -> Result<bool> {
|
||||
async fn render(
|
||||
&mut self,
|
||||
page: u8,
|
||||
ctx: &Context,
|
||||
msg: &Message,
|
||||
) -> Result<Option<EditMessage>> {
|
||||
let env = ctx.data.read().await.get::<OsuEnv>().unwrap().clone();
|
||||
|
||||
let meta_cache = &env.beatmaps;
|
||||
|
@ -202,7 +207,7 @@ mod scores {
|
|||
let start = page * ITEMS_PER_PAGE;
|
||||
let end = self.scores.len().min(start + ITEMS_PER_PAGE);
|
||||
if start >= end {
|
||||
return Ok(false);
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let hourglass = msg.react(ctx, '⌛').await?;
|
||||
|
@ -321,9 +326,12 @@ mod scores {
|
|||
.push_line("[?] means pp was predicted by oppai-rs.")
|
||||
.build();
|
||||
|
||||
msg.edit(ctx, EditMessage::new().content(content)).await?;
|
||||
hourglass.delete(ctx).await?;
|
||||
Ok(true)
|
||||
Ok(Some(
|
||||
EditMessage::new()
|
||||
.content(content)
|
||||
.components(vec![self.pagination_row()]),
|
||||
))
|
||||
}
|
||||
|
||||
fn len(&self) -> Option<usize> {
|
||||
|
@ -335,7 +343,7 @@ mod scores {
|
|||
|
||||
mod beatmapset {
|
||||
use serenity::{
|
||||
all::{GuildId, Reaction},
|
||||
all::{CreateButton, GuildId},
|
||||
builder::{CreateEmbedFooter, EditMessage},
|
||||
model::channel::{Message, ReactionType},
|
||||
};
|
||||
|
@ -352,6 +360,7 @@ mod beatmapset {
|
|||
};
|
||||
|
||||
const SHOW_ALL_EMOTE: &str = "🗒️";
|
||||
const SHOW_ALL: &str = "youmubot_osu::discord::display::show_all";
|
||||
|
||||
pub async fn display_beatmapset(
|
||||
ctx: Context,
|
||||
|
@ -377,8 +386,6 @@ mod beatmapset {
|
|||
mode,
|
||||
mods,
|
||||
guild_id,
|
||||
|
||||
all_reaction: None,
|
||||
};
|
||||
|
||||
let ctx = ctx.clone();
|
||||
|
@ -401,8 +408,6 @@ mod beatmapset {
|
|||
mode: Option<Mode>,
|
||||
mods: Option<UnparsedMods>,
|
||||
guild_id: Option<GuildId>,
|
||||
|
||||
all_reaction: Option<Reaction>,
|
||||
}
|
||||
|
||||
impl Paginate {
|
||||
|
@ -427,21 +432,25 @@ mod beatmapset {
|
|||
Some(self.maps.len())
|
||||
}
|
||||
|
||||
async fn render(&mut self, page: u8, ctx: &Context, msg: &mut Message) -> Result<bool> {
|
||||
async fn render(
|
||||
&mut self,
|
||||
page: u8,
|
||||
ctx: &Context,
|
||||
msg: &Message,
|
||||
) -> Result<Option<EditMessage>> {
|
||||
let page = page as usize;
|
||||
if page == self.maps.len() {
|
||||
msg.edit(
|
||||
ctx,
|
||||
EditMessage::new().embed(crate::discord::embeds::beatmapset_embed(
|
||||
&self.maps[..],
|
||||
self.mode,
|
||||
)),
|
||||
)
|
||||
.await?;
|
||||
return Ok(true);
|
||||
return Ok(Some(
|
||||
EditMessage::new()
|
||||
.embed(crate::discord::embeds::beatmapset_embed(
|
||||
&self.maps[..],
|
||||
self.mode,
|
||||
))
|
||||
.components(vec![self.pagination_row()]),
|
||||
));
|
||||
}
|
||||
if page > self.maps.len() {
|
||||
return Ok(false);
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let map = &self.maps[page];
|
||||
|
@ -458,7 +467,16 @@ mod beatmapset {
|
|||
self.infos[page].insert(info)
|
||||
}
|
||||
};
|
||||
msg.edit(ctx,
|
||||
let env = ctx.data.read().await.get::<OsuEnv>().unwrap().clone();
|
||||
save_beatmap(
|
||||
&env,
|
||||
msg.channel_id,
|
||||
&BeatmapWithMode(map.clone(), self.mode),
|
||||
)
|
||||
.await
|
||||
.pls_ok();
|
||||
|
||||
Ok(Some(
|
||||
EditMessage::new().embed(
|
||||
crate::discord::embeds::beatmap_embed(
|
||||
map,
|
||||
|
@ -475,31 +493,19 @@ mod beatmapset {
|
|||
))
|
||||
})
|
||||
)
|
||||
.components(vec![beatmap_components(map.mode, self.guild_id)]),
|
||||
)
|
||||
.await?;
|
||||
let env = ctx.data.read().await.get::<OsuEnv>().unwrap().clone();
|
||||
save_beatmap(
|
||||
&env,
|
||||
msg.channel_id,
|
||||
&BeatmapWithMode(map.clone(), self.mode),
|
||||
)
|
||||
.await
|
||||
.pls_ok();
|
||||
|
||||
Ok(true)
|
||||
.components(vec![beatmap_components(map.mode, self.guild_id), self.pagination_row()]),
|
||||
))
|
||||
}
|
||||
|
||||
async fn prerender(
|
||||
&mut self,
|
||||
ctx: &Context,
|
||||
m: &mut serenity::model::channel::Message,
|
||||
) -> Result<()> {
|
||||
self.all_reaction = Some(
|
||||
m.react(&ctx, SHOW_ALL_EMOTE.parse::<ReactionType>().unwrap())
|
||||
.await?,
|
||||
fn interaction_buttons(&self) -> Vec<CreateButton> {
|
||||
let mut btns = pagination::default_buttons(self);
|
||||
btns.insert(
|
||||
0,
|
||||
CreateButton::new(SHOW_ALL)
|
||||
.emoji(ReactionType::try_from(SHOW_ALL_EMOTE).unwrap())
|
||||
.label("Show all"),
|
||||
);
|
||||
Ok(())
|
||||
btns
|
||||
}
|
||||
|
||||
async fn handle_reaction(
|
||||
|
@ -507,26 +513,16 @@ mod beatmapset {
|
|||
page: u8,
|
||||
ctx: &Context,
|
||||
message: &mut serenity::model::channel::Message,
|
||||
reaction: &Reaction,
|
||||
reaction: &str,
|
||||
) -> Result<Option<u8>> {
|
||||
// Render the old style.
|
||||
if let ReactionType::Unicode(s) = &reaction.emoji {
|
||||
if s == SHOW_ALL_EMOTE {
|
||||
self.render(self.maps.len() as u8, ctx, message).await?;
|
||||
return Ok(Some(self.maps.len() as u8));
|
||||
}
|
||||
if reaction == SHOW_ALL {
|
||||
pagination::do_render(self, self.maps.len() as u8, ctx, message).await?;
|
||||
return Ok(Some(self.maps.len() as u8));
|
||||
}
|
||||
pagination::handle_pagination_reaction(page, self, ctx, message, reaction)
|
||||
.await
|
||||
.map(Some)
|
||||
}
|
||||
|
||||
async fn cleanup(&mut self, ctx: &Context, _msg: &mut Message) {
|
||||
if let Some(r) = self.all_reaction.take() {
|
||||
if !r.delete_all(&ctx).await.is_ok() {
|
||||
r.delete(&ctx).await.pls_ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -192,18 +192,18 @@ pub fn dot_osu_hook<'a>(
|
|||
} else {
|
||||
let osu_embeds = Arc::new(osu_embeds);
|
||||
paginate_reply(
|
||||
paginate_from_fn(|page, ctx, msg| {
|
||||
paginate_from_fn(|page, _, _, btns| {
|
||||
let osu_embeds = osu_embeds.clone();
|
||||
Box::pin(async move {
|
||||
let (embed, attachments) = &osu_embeds[page as usize];
|
||||
let mut edit = EditMessage::new()
|
||||
.content(format!("Attached beatmaps ({}/{})", page + 1, embed_len))
|
||||
.embed(embed.clone());
|
||||
.embed(embed.clone())
|
||||
.components(vec![btns]);
|
||||
for att in attachments {
|
||||
edit = edit.new_attachment(att.clone());
|
||||
}
|
||||
msg.edit(&ctx, edit).await?;
|
||||
Ok(true)
|
||||
Ok(Some(edit))
|
||||
})
|
||||
})
|
||||
.with_page_count(embed_len),
|
||||
|
|
|
@ -236,7 +236,7 @@ where
|
|||
let total_len = users.len();
|
||||
let total_pages = (total_len + ITEMS_PER_PAGE - 1) / ITEMS_PER_PAGE;
|
||||
paginate_with_first_message(
|
||||
paginate_from_fn(move |page: u8, ctx: &Context, m: &mut Message| {
|
||||
paginate_from_fn(move |page: u8, _: &Context, _: &Message, btns| {
|
||||
let header = header.clone();
|
||||
use Align::*;
|
||||
let users = users.clone();
|
||||
|
@ -244,7 +244,7 @@ where
|
|||
let start = (page as usize) * ITEMS_PER_PAGE;
|
||||
let end = (start + ITEMS_PER_PAGE).min(users.len());
|
||||
if start >= end {
|
||||
return Ok(false);
|
||||
return Ok(None);
|
||||
}
|
||||
let users = &users[start..end];
|
||||
let table = match query {
|
||||
|
@ -317,8 +317,9 @@ where
|
|||
last_update.format("<t:%s:R>"),
|
||||
))
|
||||
.build();
|
||||
m.edit(ctx, EditMessage::new().content(content)).await?;
|
||||
Ok(true)
|
||||
Ok(Some(
|
||||
EditMessage::new().content(content).components(vec![btns]),
|
||||
))
|
||||
})
|
||||
})
|
||||
.with_page_count(total_pages),
|
||||
|
@ -617,11 +618,11 @@ pub async fn display_rankings_table(
|
|||
let header = Arc::new(to.content.clone());
|
||||
|
||||
paginate_with_first_message(
|
||||
paginate_from_fn(move |page: u8, ctx: &Context, m: &mut Message| {
|
||||
paginate_from_fn(move |page: u8, _, _, btns| {
|
||||
let start = (page as usize) * ITEMS_PER_PAGE;
|
||||
let end = (start + ITEMS_PER_PAGE).min(scores.len());
|
||||
if start >= end {
|
||||
return Box::pin(future::ready(Ok(false)));
|
||||
return Box::pin(future::ready(Ok(None)));
|
||||
}
|
||||
let scores = scores[start..end].to_vec();
|
||||
let header = header.clone();
|
||||
|
@ -720,8 +721,9 @@ pub async fn display_rankings_table(
|
|||
))
|
||||
.build();
|
||||
|
||||
m.edit(&ctx, EditMessage::new().content(content)).await?;
|
||||
Ok(true)
|
||||
Ok(Some(
|
||||
EditMessage::new().content(content).components(vec![btns]),
|
||||
))
|
||||
})
|
||||
})
|
||||
.with_page_count(total_pages),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue