pikadick/util/
loading_reaction.rs1use serenity::{
2 http::Http,
3 model::prelude::*,
4};
5use std::sync::Arc;
6
7const LOADING_EMOJI: char = '⌛';
8const OK_EMOJI: char = '✅';
9const ERR_EMOJI: char = '❌';
10
11pub struct LoadingReaction {
17 http: Arc<Http>,
18 channel_id: ChannelId,
19 msg_id: MessageId,
20
21 sent_reaction: bool,
22}
23
24impl std::fmt::Debug for LoadingReaction {
25 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26 f.debug_struct("LoadingReaction")
27 .field("channel_id", &self.channel_id)
28 .field("msg_id", &self.msg_id)
29 .field("sent_reaction", &self.sent_reaction)
30 .finish()
31 }
32}
33
34impl LoadingReaction {
35 pub fn new(http: Arc<Http>, msg: &Message) -> Self {
37 let channel_id = msg.channel_id;
38 let msg_id = msg.id;
39
40 let ret = LoadingReaction {
41 http,
42 channel_id,
43 msg_id,
44
45 sent_reaction: false,
46 };
47
48 ret.send_reaction(LOADING_EMOJI);
49
50 ret
51 }
52
53 pub fn send_reaction<T>(&self, reaction: T)
55 where
56 T: Into<ReactionType>,
57 {
58 {
59 let msg_id = self.msg_id;
60 let channel_id = self.channel_id;
61 let http = self.http.clone();
62 let reaction = reaction.into();
63
64 tokio::spawn(async move {
65 http.create_reaction(channel_id, msg_id, &reaction)
66 .await
67 .ok();
68 });
69 }
70 }
71
72 pub fn send_ok(&mut self) {
74 self.send_reaction(OK_EMOJI);
75 self.sent_reaction = true;
76 }
77
78 pub fn send_fail(&mut self) {
80 self.send_reaction(ERR_EMOJI);
81 self.sent_reaction = true;
82 }
83}
84
85impl Drop for LoadingReaction {
86 fn drop(&mut self) {
87 if !self.sent_reaction {
88 self.send_fail();
89 }
90 }
91}