1
1
import discord
2
+
3
+ from discord import Reaction , User , Message
2
4
from discord .ext import commands
3
5
4
6
from cogs .voice .voice_fun import bot_audible_update
5
- from cogs .voice .voice_fun import create_playing_embed
6
7
from cogs .voice .voice_fun import create_queue_embed
7
8
from cogs .voice .voice_fun import droid_speak_translate
8
9
from cogs .voice .voice_fun import format_duration
9
10
from cogs .voice .voice_fun import play_queue
10
11
from cogs .voice .voice_fun import add_queue
11
12
from cogs .voice .voice_fun import YTDLSource
13
+ from cogs .voice .voice_fun import setup_player
12
14
13
15
14
16
class Music (commands .Cog ):
@@ -116,6 +118,31 @@ async def volume(self, ctx, *volume: int):
116
118
117
119
return await ctx .send ("Current volume is {}%" .format (bot_volume ))
118
120
121
+ @commands .command ()
122
+ async def flick (self , ctx ):
123
+ """Switch between paused and playing states
124
+
125
+ :param ctx: command invocation message context
126
+ :return: None
127
+ """
128
+ if ctx .voice_client .is_playing ():
129
+ ctx .voice_client .pause ()
130
+ elif ctx .voice_client .is_paused ():
131
+ ctx .voice_client .resume ()
132
+
133
+ @classmethod
134
+ async def _react_flick (cls , reaction ):
135
+ """Switch between paused and playing states
136
+
137
+ :param reaction: Reaction object invoking flick action
138
+ :return: None
139
+ """
140
+ guild = reaction .message .guild
141
+ if guild .voice_client .is_playing ():
142
+ guild .voice_client .pause ()
143
+ elif guild .voice_client .is_paused ():
144
+ guild .voice_client .resume ()
145
+
119
146
# Pause current audio stream
120
147
@commands .command ()
121
148
async def pause (self , ctx ):
@@ -162,6 +189,12 @@ async def skip(self, ctx, *queue_id):
162
189
await ctx .send ("Skipping:\t {}" .format (player_title ))
163
190
ctx .voice_client .stop ()
164
191
192
+ async def _react_skip (self , reaction ):
193
+ guild_id = reaction .message .guild .id
194
+ player_title = self .queues [guild_id ][0 ].title
195
+ await reaction .message .channel .send ("Skipping:\t {}" .format (player_title ))
196
+ reaction .message .guild .voice_client .stop ()
197
+
165
198
# Display information about current audio being played
166
199
@commands .command ()
167
200
async def player (self , ctx ):
@@ -175,8 +208,7 @@ async def player(self, ctx):
175
208
if queue :
176
209
source = queue [0 ]
177
210
status = "Paused" if ctx .voice_client .is_paused () else "Playing"
178
- embed_playing = create_playing_embed (source , status )
179
- await ctx .send (embed = embed_playing )
211
+ await setup_player (ctx , source )
180
212
181
213
# View the queue of the existing playlist
182
214
@commands .command ()
@@ -218,7 +250,8 @@ async def queue(self, ctx, first=5):
218
250
embed_queue .add_field (name = f"Queue (Displaying first { first } )" ,
219
251
value = queue_string ,
220
252
inline = False )
221
- await ctx .send (embed = embed_queue )
253
+ ret_msg : Message = await ctx .send (embed = embed_queue )
254
+ await ret_msg .delete (delay = 10 )
222
255
223
256
@commands .command ()
224
257
async def speak (self , ctx , * phrase : str ):
@@ -230,6 +263,39 @@ async def speak(self, ctx, *phrase: str):
230
263
if not ctx .voice_client .is_playing () or ctx .voice_client .is_paused ():
231
264
await droid_speak_translate (ctx , phrase )
232
265
266
+ @staticmethod
267
+ def _is_not_bot (user ):
268
+ return not user .bot
269
+
270
+ @commands .Cog .listener ()
271
+ async def on_reaction_add (self , reaction : Reaction , user : User ) -> None :
272
+ """Listen for all added reactions
273
+
274
+ :param reaction: Reaction that was submitted by a User
275
+ :param user: The User that submitted the Reaction
276
+ :return:
277
+ """
278
+ if self ._is_not_bot (user ):
279
+ await self .manage_music (reaction , user )
280
+
281
+ async def manage_music (self , reaction : Reaction , user : User ) -> None :
282
+ """For a given Reaction, determine if music player needs to be managed
283
+
284
+ :param reaction: a Reaction object
285
+ :param user: the User who sent the Reaction
286
+ :return:
287
+ """
288
+ if reaction .message .author .bot : # This loosely rules out reactions to non-bot messages messages.
289
+ if str (reaction ) == "⏭️" :
290
+ await self ._react_skip (reaction )
291
+ await reaction .message .clear_reactions ()
292
+ await reaction .message .delete (delay = 10 )
293
+ elif str (reaction ) == "⏯️" :
294
+ await self ._react_flick (reaction )
295
+ await reaction .remove (user )
296
+ else :
297
+ pass
298
+
233
299
@stream .before_invoke
234
300
@speak .before_invoke
235
301
async def ensure_voice (self , ctx ):
0 commit comments