osu: make save command use interaction

This commit is contained in:
Natsu Kagami 2025-02-22 17:13:57 +01:00 committed by Natsu Kagami
parent e777d4d634
commit 068dd48550
6 changed files with 94 additions and 59 deletions

View file

@ -3,7 +3,7 @@ use serenity::{
all::{CreateInteractionResponse, Interaction, MessageId},
prelude::TypeMapKey,
};
use std::{ops::Deref, sync::Arc};
use std::sync::Arc;
#[derive(Debug, Clone)]
/// Handles distributing interaction to the handlers.
@ -13,16 +13,25 @@ pub struct InteractionCollector {
/// Wraps the interfaction receiver channel, automatically cleaning up upon drop.
#[derive(Debug)]
struct InteractionCollectorGuard {
pub struct InteractionCollectorGuard {
msg_id: MessageId,
ch: flume::Receiver<String>,
collector: InteractionCollector,
}
impl Deref for InteractionCollectorGuard {
type Target = flume::Receiver<String>;
impl InteractionCollectorGuard {
/// Returns the next fetched interaction, with the given timeout.
pub async fn next(&self, timeout: std::time::Duration) -> Option<String> {
match tokio::time::timeout(timeout, self.ch.clone().into_recv_async()).await {
Err(_) => None,
Ok(Err(_)) => None,
Ok(Ok(interaction)) => Some(interaction),
}
}
}
fn deref(&self) -> &Self::Target {
impl AsRef<flume::Receiver<String>> for InteractionCollectorGuard {
fn as_ref(&self) -> &flume::Receiver<String> {
&self.ch
}
}
@ -40,7 +49,7 @@ impl InteractionCollector {
}
}
/// Create a new collector, returning a receiver.
pub fn create_collector(&self, msg: MessageId) -> impl Deref<Target = flume::Receiver<String>> {
pub fn create_collector(&self, msg: MessageId) -> InteractionCollectorGuard {
let (send, recv) = flume::unbounded();
self.channels.insert(msg.clone(), send);
InteractionCollectorGuard {
@ -51,10 +60,7 @@ impl InteractionCollector {
}
/// Create a new collector, returning a receiver.
pub(crate) async fn create(
ctx: &Context,
msg: MessageId,
) -> Result<impl Deref<Target = flume::Receiver<String>>> {
pub async fn create(ctx: &Context, msg: MessageId) -> Result<InteractionCollectorGuard> {
Ok(ctx
.data
.read()

View file

@ -8,12 +8,6 @@ use serenity::{
builder::CreateMessage,
model::{channel::Message, id::ChannelId},
};
use tokio::time as tokio_time;
// const ARROW_RIGHT: &str = "➡️";
// const ARROW_LEFT: &str = "⬅️";
// const REWIND: &str = "⏪";
// const FAST_FORWARD: &str = "⏩";
const NEXT: &str = "youmubot_pagination_next";
const PREV: &str = "youmubot_pagination_prev";
@ -269,10 +263,9 @@ pub async fn paginate_with_first_message(
// Loop the handler function.
let res: Result<()> = loop {
match tokio_time::timeout(timeout, recv.clone().into_recv_async()).await {
Err(_) => break Ok(()),
Ok(Err(_)) => break Ok(()),
Ok(Ok(reaction)) => {
match recv.next(timeout).await {
None => break Ok(()),
Some(reaction) => {
page = match pager
.handle_reaction(page, ctx, &mut message, &reaction)
.await