use serenity::{
http::Http,
model::prelude::*,
};
use std::sync::Arc;
const LOADING_EMOJI: char = '⌛';
const OK_EMOJI: char = '✅';
const ERR_EMOJI: char = '❌';
pub struct LoadingReaction {
http: Arc<Http>,
channel_id: ChannelId,
msg_id: MessageId,
sent_reaction: bool,
}
impl std::fmt::Debug for LoadingReaction {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("LoadingReaction")
.field("channel_id", &self.channel_id)
.field("msg_id", &self.msg_id)
.field("sent_reaction", &self.sent_reaction)
.finish()
}
}
impl LoadingReaction {
pub fn new(http: Arc<Http>, msg: &Message) -> Self {
let channel_id = msg.channel_id;
let msg_id = msg.id;
let ret = LoadingReaction {
http,
channel_id,
msg_id,
sent_reaction: false,
};
ret.send_reaction(LOADING_EMOJI);
ret
}
pub fn send_reaction<T>(&self, reaction: T)
where
T: Into<ReactionType>,
{
{
let msg_id = self.msg_id;
let channel_id = self.channel_id;
let http = self.http.clone();
let reaction = reaction.into();
tokio::spawn(async move {
http.create_reaction(channel_id, msg_id, &reaction)
.await
.ok();
});
}
}
pub fn send_ok(&mut self) {
self.send_reaction(OK_EMOJI);
self.sent_reaction = true;
}
pub fn send_fail(&mut self) {
self.send_reaction(ERR_EMOJI);
self.sent_reaction = true;
}
}
impl Drop for LoadingReaction {
fn drop(&mut self) {
if !self.sent_reaction {
self.send_fail();
}
}
}