Skip to content

Commit f11dcaa

Browse files
author
Mg Grignard
committed
[Audio] Expose the Keep in Queue mode, where the queue acts more like a playlist
1 parent 6758c1b commit f11dcaa

File tree

6 files changed

+116
-28
lines changed

6 files changed

+116
-28
lines changed

redbot/cogs/audio/core/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ def __init__(self, bot: Red):
134134
prefer_lyrics=False,
135135
repeat=False,
136136
shuffle=False,
137+
keep_in_queue=False,
137138
shuffle_bumped=True,
138139
thumbnail=False,
139140
volume=100,

redbot/cogs/audio/core/commands/controller.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ async def command_now(self, ctx: commands.Context):
124124
shuffle = guild_data["shuffle"]
125125
repeat = guild_data["repeat"]
126126
autoplay = guild_data["auto_play"]
127+
keep_in_queue = guild_data["keep_in_queue"]
127128
text = ""
128129
text += (
129130
_("Auto-Play")
@@ -148,6 +149,12 @@ async def command_now(self, ctx: commands.Context):
148149
+ ": "
149150
+ ("\N{WHITE HEAVY CHECK MARK}" if player.repeat_current else "\N{CROSS MARK}")
150151
)
152+
text += (
153+
(" | " if text else "")
154+
+ _("Keep in Queue")
155+
+ ": "
156+
+ ("\N{WHITE HEAVY CHECK MARK}" if keep_in_queue else "\N{CROSS MARK}")
157+
)
151158

152159
message = await self.send_embed_msg(ctx, embed=embed, footer=text)
153160

@@ -608,6 +615,7 @@ async def command_stop(self, ctx: commands.Context):
608615
if eq:
609616
await self.config.custom("EQUALIZER", ctx.guild.id).eq_bands.set(eq.bands)
610617
player.queue = []
618+
player.next_queue_position = 0
611619
player.store("playing_song", None)
612620
player.store("prev_requester", None)
613621
player.store("prev_song", None)
@@ -830,6 +838,46 @@ async def command_repeat_current(self, ctx: commands.Context):
830838
embed = discord.Embed(title=_("Setting Changed"), description=msg)
831839
await self.send_embed_msg(ctx, embed=embed)
832840

841+
@commands.command(name="keepinqueue")
842+
@commands.guild_only()
843+
@commands.bot_has_permissions(embed_links=True)
844+
async def command_keepinqueue(self, ctx: commands.Context):
845+
"""Toggle keep in queue."""
846+
dj_enabled = self._dj_status_cache.setdefault(
847+
ctx.guild.id, await self.config.guild(ctx.guild).dj_enabled()
848+
)
849+
can_skip = await self._can_instaskip(ctx, ctx.author)
850+
if dj_enabled and not can_skip and not await self._has_dj_role(ctx, ctx.author):
851+
return await self.send_embed_msg(
852+
ctx,
853+
title=_("Unable To Toggle Keep In Queue"),
854+
description=_("You need the DJ role to toggle keep in queue."),
855+
)
856+
if self._player_check(ctx):
857+
await self.set_player_settings(ctx)
858+
player = lavalink.get_player(ctx.guild.id)
859+
if (
860+
not ctx.author.voice or ctx.author.voice.channel != player.channel
861+
) and not can_skip:
862+
return await self.send_embed_msg(
863+
ctx,
864+
title=_("Unable To Toggle Keep In Queue"),
865+
description=_("You must be in the voice channel to toggle keep in queue."),
866+
)
867+
player.store("notify_channel", ctx.channel.id)
868+
869+
keep_in_queue = await self.config.guild(ctx.guild).keep_in_queue()
870+
msg = ""
871+
msg += _("Keep tracks in queue: {true_or_false}.").format(
872+
true_or_false=_("Enabled") if not keep_in_queue else _("Disabled")
873+
)
874+
await self.config.guild(ctx.guild).keep_in_queue.set(not keep_in_queue)
875+
876+
embed = discord.Embed(title=_("Setting Changed"), description=msg)
877+
await self.send_embed_msg(ctx, embed=embed)
878+
if self._player_check(ctx):
879+
await self.set_player_settings(ctx)
880+
833881
@commands.command(name="remove")
834882
@commands.guild_only()
835883
@commands.bot_has_permissions(embed_links=True)
@@ -868,6 +916,9 @@ async def command_remove(self, ctx: commands.Context, index_or_url: Union[int, s
868916
)
869917
index_or_url -= 1
870918
removed = player.queue.pop(index_or_url)
919+
if index_or_url < player.next_queue_position:
920+
player.next_queue_position -= 1
921+
871922
await self.api_interface.persistent_queue_api.played(
872923
ctx.guild.id, removed.extras.get("enqueue_time")
873924
)
@@ -989,6 +1040,11 @@ async def command_move(self, ctx: commands.Context, from_index: int, to_index: i
9891040
player.store("notify_channel", ctx.channel.id)
9901041
removed = player.queue.pop(from_index - 1)
9911042
player.queue.insert(to_index - 1, removed)
1043+
original_next = player.next_queue_position
1044+
if from_index - 1 < original_next:
1045+
player.next_queue_position -= 1
1046+
if to_index - 1 < original_next:
1047+
player.next_queue_position += 1
9921048
description = await self.get_track_description(removed, self.local_folder_current_path)
9931049
await self.send_embed_msg(
9941050
ctx,

redbot/cogs/audio/core/commands/queue.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ async def _queue_menu(
8888
shuffle = guild_data["shuffle"]
8989
repeat = guild_data["repeat"]
9090
autoplay = guild_data["auto_play"]
91+
keep_in_queue = guild_data["keep_in_queue"]
9192
text = ""
9293
text += (
9394
_("Auto-Play")
@@ -112,6 +113,12 @@ async def _queue_menu(
112113
+ ": "
113114
+ ("\N{WHITE HEAVY CHECK MARK}" if player.repeat_current else "\N{CROSS MARK}")
114115
)
116+
text += (
117+
(" | " if text else "")
118+
+ _("Keep in Queue")
119+
+ ": "
120+
+ ("\N{WHITE HEAVY CHECK MARK}" if keep_in_queue else "\N{CROSS MARK}")
121+
)
115122
embed.set_footer(text=text)
116123
message = await self.send_embed_msg(ctx, embed=embed)
117124
dj_enabled = self._dj_status_cache.setdefault(ctx.guild.id, guild_data["dj_enabled"])

redbot/cogs/audio/core/utilities/miscellaneous.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,9 +214,12 @@ def time_convert(self, length: Union[int, str]) -> int:
214214

215215
async def queue_duration(self, ctx: commands.Context) -> int:
216216
player = lavalink.get_player(ctx.guild.id)
217+
next_index = min(player.next_queue_position, len(player.queue))
217218
dur = [
218219
i.length
219-
async for i in AsyncIter(player.queue, steps=50).filter(lambda x: not x.is_stream)
220+
async for i in AsyncIter(player.queue[next_index:], steps=50).filter(
221+
lambda x: not x.is_stream
222+
)
220223
]
221224
queue_dur = sum(dur)
222225
if not player.queue:

redbot/cogs/audio/core/utilities/player.py

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ async def _skip_action(self, ctx: commands.Context, skip_to_track: int = None) -
162162
return
163163

164164
queue_to_append = []
165-
if skip_to_track is not None and skip_to_track != 1:
165+
if skip_to_track is not None:
166166
if skip_to_track < 1:
167167
await self.send_embed_msg(
168168
ctx, title=_("Track number must be equal to or greater than 1.")
@@ -176,15 +176,26 @@ async def _skip_action(self, ctx: commands.Context, skip_to_track: int = None) -
176176
),
177177
)
178178
return
179-
embed = discord.Embed(
180-
title=_("{skip_to_track} Tracks Skipped").format(skip_to_track=skip_to_track)
181-
)
179+
if skip_to_track - 1 >= player.next_queue_position:
180+
skipped_count = skip_to_track - player.next_queue_position
181+
embed = discord.Embed(
182+
title=_("{skipped_count} Tracks Skipped").format(skipped_count=skipped_count)
183+
)
184+
else:
185+
embed = discord.Embed(
186+
title=_("Skipped to Track {skip_to_track}").format(skip_to_track=skip_to_track)
187+
)
182188
await self.send_embed_msg(ctx, embed=embed)
183-
if player.repeat:
184-
queue_to_append = player.queue[0 : min(skip_to_track - 1, len(player.queue) - 1)]
185-
player.queue = player.queue[
186-
min(skip_to_track - 1, len(player.queue) - 1) : len(player.queue)
187-
]
189+
if player.keep_in_queue:
190+
player.next_queue_position = skip_to_track - 1
191+
else:
192+
if player.repeat:
193+
queue_to_append = player.queue[
194+
0 : min(skip_to_track - 1, len(player.queue) - 1)
195+
]
196+
player.queue = player.queue[
197+
min(skip_to_track - 1, len(player.queue) - 1) : len(player.queue)
198+
]
188199
else:
189200
embed = discord.Embed(
190201
title=_("Track Skipped"),
@@ -651,10 +662,12 @@ async def set_player_settings(self, ctx: commands.Context) -> None:
651662
player = lavalink.get_player(ctx.guild.id)
652663
shuffle = await self.config.guild(ctx.guild).shuffle()
653664
repeat = await self.config.guild(ctx.guild).repeat()
665+
keep_in_queue = await self.config.guild(ctx.guild).keep_in_queue()
654666
volume = await self.config.guild(ctx.guild).volume()
655667
shuffle_bumped = await self.config.guild(ctx.guild).shuffle_bumped()
656668
player.repeat = repeat
657669
player.shuffle = shuffle
670+
player.keep_in_queue = keep_in_queue
658671
player.shuffle_bumped = shuffle_bumped
659672
if player.volume != volume:
660673
await player.set_volume(volume)

redbot/cogs/audio/core/utilities/queue.py

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ async def _build_queue_page(
3232
shuffle = await self.config.guild(ctx.guild).shuffle()
3333
repeat = await self.config.guild(ctx.guild).repeat()
3434
autoplay = await self.config.guild(ctx.guild).auto_play()
35+
keep_in_queue = await self.config.guild(ctx.guild).keep_in_queue()
3536

3637
queue_num_pages = math.ceil(len(queue) / 10)
3738
queue_idx_start = (page_num - 1) * 10
@@ -44,25 +45,26 @@ async def _build_queue_page(
4445
arrow = await self.draw_time(ctx)
4546
pos = self.format_time(player.position)
4647

47-
if player.current.is_stream:
48-
dur = "LIVE"
49-
else:
50-
dur = self.format_time(player.current.length)
48+
if player.current:
49+
if player.current.is_stream:
50+
dur = "LIVE"
51+
else:
52+
dur = self.format_time(player.current.length)
5153

52-
query = Query.process_input(player.current, self.local_folder_current_path)
53-
current_track_description = await self.get_track_description(
54-
player.current, self.local_folder_current_path
55-
)
56-
if query.is_stream:
57-
queue_list += _("**Currently livestreaming:**\n")
58-
queue_list += f"{current_track_description}\n"
59-
queue_list += _("Requested by: **{user}**").format(user=player.current.requester)
60-
queue_list += f"\n\n{arrow}`{pos}`/`{dur}`\n\n"
61-
else:
62-
queue_list += _("Playing: ")
63-
queue_list += f"{current_track_description}\n"
64-
queue_list += _("Requested by: **{user}**").format(user=player.current.requester)
65-
queue_list += f"\n\n{arrow}`{pos}`/`{dur}`\n\n"
54+
query = Query.process_input(player.current, self.local_folder_current_path)
55+
current_track_description = await self.get_track_description(
56+
player.current, self.local_folder_current_path
57+
)
58+
if query.is_stream:
59+
queue_list += _("**Currently livestreaming:**\n")
60+
queue_list += f"{current_track_description}\n"
61+
queue_list += _("Requested by: **{user}**").format(user=player.current.requester)
62+
queue_list += f"\n\n{arrow}`{pos}`/`{dur}`\n\n"
63+
else:
64+
queue_list += _("Playing: ")
65+
queue_list += f"{current_track_description}\n"
66+
queue_list += _("Requested by: **{user}**").format(user=player.current.requester)
67+
queue_list += f"\n\n{arrow}`{pos}`/`{dur}`\n\n"
6668

6769
async for i, track in AsyncIter(queue[queue_idx_start:queue_idx_end]).enumerate(
6870
start=queue_idx_start
@@ -116,6 +118,12 @@ async def _build_queue_page(
116118
+ ": "
117119
+ ("\N{WHITE HEAVY CHECK MARK}" if player.repeat_current else "\N{CROSS MARK}")
118120
)
121+
text += (
122+
(" | " if text else "")
123+
+ _("Keep in Queue")
124+
+ ": "
125+
+ ("\N{WHITE HEAVY CHECK MARK}" if keep_in_queue else "\N{CROSS MARK}")
126+
)
119127
embed.set_footer(text=text)
120128
return embed
121129

0 commit comments

Comments
 (0)