diff --git a/cogs/basic.py b/cogs/basic.py index 0dd87b5..3f4b9f8 100644 --- a/cogs/basic.py +++ b/cogs/basic.py @@ -318,7 +318,7 @@ class Basic(commands.Cog): await ctx.send(player.get_msg('skipped').format(ctx.author)) if player.queue._repeat == 1: - player.queue.set_repeat("off") + await player.queue.set_repeat("off") await player.stop() @commands.hybrid_command(name="back", aliases=get_aliases("back")) @@ -353,7 +353,7 @@ class Basic(commands.Cog): await ctx.send(player.get_msg('backed').format(ctx.author)) if player.queue._repeat == 1: - player.queue.set_repeat("off") + await player.queue.set_repeat("off") @commands.hybrid_command(name="seek", aliases=get_aliases("seek")) @app_commands.describe(position="Input position. Exmaple: 1:20.") @@ -465,7 +465,7 @@ class Basic(commands.Cog): if mode.lower() not in ['off', 'track', 'queue']: mode = "off" - player.queue.set_repeat(mode) + await player.set_repeat(mode) await ctx.send(player.get_msg('repeat').format(mode.capitalize())) @commands.hybrid_command(name="clear", aliases=get_aliases("clear")) diff --git a/views/controller.py b/views/controller.py index 82709d7..6a3d080 100644 --- a/views/controller.py +++ b/views/controller.py @@ -63,7 +63,7 @@ class Back(discord.ui.Button): await interaction.response.send_message(self.player.get_msg("backed").format(interaction.user)) if self.player.queue._repeat == 1: - self.player.queue.set_repeat("off") + await self.player.set_repeat("off") class Resume(discord.ui.Button): def __init__(self, player, style, row): @@ -127,7 +127,7 @@ class Skip(discord.ui.Button): await interaction.response.send_message(self.player.get_msg("skipped").format(interaction.user)) if self.player.queue._repeat == 1: - self.player.queue.set_repeat("off") + await self.player.set_repeat("off") await self.player.stop() class Stop(discord.ui.Button): @@ -182,20 +182,13 @@ class Add(discord.ui.Button): class Loop(discord.ui.Button): def __init__(self, player, style, row): self.player = player - self.loopType = { - 0: "off", - 1: "track", - 2: "queue", - } super().__init__(emoji="🔁", label=player.get_msg('buttonLoop'), style=style, row=row) async def callback(self, interaction: discord.Interaction): if not self.player.is_privileged(interaction.user): return await interaction.response.send_message(self.player.get_msg('missingPerms_mode'), ephemeral=True) - current_repeat = self.player.queue._repeat - mode = self.loopType.get((current_repeat + 1)%len(self.loopType), 'off') - self.player.queue.set_repeat(mode) + mode = await self.player.set_repeat() await interaction.response.send_message(self.player.get_msg('repeat').format(mode.capitalize())) class VolumeUp(discord.ui.Button): diff --git a/voicelink/player.py b/voicelink/player.py index 048684b..38a1640 100644 --- a/voicelink/player.py +++ b/voicelink/player.py @@ -43,7 +43,8 @@ from discord import ( StageChannel, Member, Embed, - ui + ui, + Message ) from discord.ext import commands @@ -85,27 +86,27 @@ class Player(VoiceProtocol): self._guild = channel.guild if channel else None self.settings: dict = func.get_settings(ctx.guild.id) - self.joinTime = round(time.time()) - self._volume = self.settings.get('volume', 100) - self.lang = self.settings.get('lang', 'EN') if self.settings.get('lang', 'EN') in func.langs else "EN" - self.queue = eval(self.settings.get("queueType", "Queue"))(self.settings.get("maxQueue", func.settings.max_queue), self.settings.get("duplicateTrack", True), self.get_msg) + self.joinTime: float = round(time.time()) + self._volume: int = self.settings.get('volume', 100) + self.lang: dict = self.settings.get('lang', 'EN') if self.settings.get('lang', 'EN') in func.langs else "EN" + self.queue: Queue = eval(self.settings.get("queueType", "Queue"))(self.settings.get("maxQueue", func.settings.max_queue), self.settings.get("duplicateTrack", True), self.get_msg) self._node = NodePool.get_node() self._current: Track = None self._filters: Filters = Filters() - self._paused = False - self._is_connected = False - self._ping = 0.0 + self._paused: bool = False + self._is_connected: bool = False + self._ping: float = 0.0 - self._position = 0 - self._last_position = 0 - self._last_update = 0 + self._position: int = 0 + self._last_position: int = 0 + self._last_update: int = 0 self._ending_track: Optional[Track] = None - self._voice_state = {} + self._voice_state: dict = {} - self.controller = None - self.updating = False + self.controller: Message = None + self.updating: bool = False self.pause_votes = set() self.resume_votes = set() @@ -567,9 +568,7 @@ class Player(VoiceProtocol): async def seek(self, position: float, requester: Member = None) -> float: """Seeks to a position in the currently playing track milliseconds""" if position < 0 or position > self._current.original.length: - raise TrackInvalidPosition( - "Seek position must be between 0 and the track length" - ) + raise TrackInvalidPosition("Seek position must be between 0 and the track length") await self._node.send(method=0, guild_id=self._guild.id, data={"position": position}) if self.bot.ipc.connections: @@ -610,6 +609,27 @@ class Player(VoiceProtocol): } }, requester) + async def set_repeat(self, mode:str = None): + if not mode: + mode = self.queue._repeat_mode.get((self.queue._repeat + 1)%len(self.queue._repeat_mode), 'off') + + is_found = False + for i, m in self.queue._repeat_mode.items(): + if m == mode.lower(): + is_found = True + self.queue._repeat = i + if i == 2: + self._repeat_position = self._position - 1 + break + + if not is_found: + raise VoicelinkException("Invalid repeat mode.") + + if self.bot.ipc.connections: + await self.send_ws({"op": "repeatTrack", "repeatMode": mode}) + + return mode + async def add_filter(self, filter: Filter, fast_apply=False) -> Filters: try: self._filters.add_filter(filter=filter) diff --git a/voicelink/queue.py b/voicelink/queue.py index 20ff437..7b8800d 100644 --- a/voicelink/queue.py +++ b/voicelink/queue.py @@ -26,13 +26,20 @@ from .objects import Track from discord import Member class Queue: - def __init__(self, size:int, duplicateTrack: bool, get_msg): + def __init__(self, size:int, duplicate_track: bool, get_msg): self._queue = [] self._position = 0 self._size = size self._repeat = 0 self._repeat_position = 0 - self._duplicateTrack = duplicateTrack + self._duplicate_track = duplicate_track + + self._repeat_mode = { + 0: "off", + 1: "track", + 2: "queue", + } + self.get_msg = get_msg def get(self): @@ -55,7 +62,7 @@ class Queue: if self.count >= self._size: raise QueueFull(self.get_msg("voicelinkQueueFull").format(self._size)) - if not self._duplicateTrack: + if not self._duplicate_track: if item.uri in [track.uri for track in self._queue]: raise DuplicateTrack(self.get_msg("voicelinkDuplicateTrack")) @@ -66,7 +73,7 @@ class Queue: if self.count >= self._size: raise QueueFull(self.get_msg("voicelinkQueueFull").format(self._size)) - if not self._duplicateTrack: + if not self._duplicate_track: if item.uri in [track.uri for track in self._queue]: raise DuplicateTrack(self.get_msg("voicelinkDuplicateTrack")) @@ -77,7 +84,7 @@ class Queue: if self.count >= self._size: raise QueueFull(self.get_msg("voicelinkQueueFull").format(self._size)) - if not self._duplicateTrack: + if not self._duplicate_track: if item.uri in [track.uri for track in self._queue]: raise DuplicateTrack(self.get_msg("voicelinkDuplicateTrack")) @@ -94,15 +101,6 @@ class Queue: raise OutofList(self.get_msg("voicelinkOutofList")) else: self._position -= index - - def set_repeat(self, mode:str): - if mode == 'track': - self._repeat = 1 - elif mode == 'queue': - self._repeat = 2 - self._repeat_position = self._position - 1 - else: - self._repeat = 0 def history_clear(self, is_playing: bool): self._queue[:self._position - 1 if is_playing else self._position] = [] @@ -173,7 +171,7 @@ class Queue: @property def repeat(self): - return "Off" if self._repeat == 0 else ("Track" if self._repeat == 1 else "Queue") + return self._repeat_mode.get(self._repeat, "Off").capitalize() @property def is_empty(self): @@ -184,15 +182,15 @@ class Queue: return False class FairQueue(Queue): - def __init__(self, size:int, duplicateTrack: bool, get_msg): - super().__init__(size, duplicateTrack, get_msg) + def __init__(self, size:int, duplicate_track: bool, get_msg): + super().__init__(size, duplicate_track, get_msg) self._set = set() async def put(self, item: Track) -> int: if len(self._queue) >= self._size: raise QueueFull(self.get_msg("voicelinkQueueFull").format(self._size)) - if not self._duplicateTrack: + if not self._duplicate_track: if item.uri in [track.uri for track in self._queue]: raise DuplicateTrack(self.get_msg("voicelinkDuplicateTrack")) diff --git a/web/ipc/methods.py b/web/ipc/methods.py index c8c7026..ad69f9e 100644 --- a/web/ipc/methods.py +++ b/web/ipc/methods.py @@ -35,7 +35,7 @@ async def skipTo(player, member: Member, data: dict): player.queue.skipto(index) if player.queue._repeat == 1: - player.queue.set_repeat("off") + await player.set_repeat("off") await player.stop() async def backTo(player, member: Member, data: dict): @@ -105,14 +105,11 @@ async def shuffleTrack(player, member: Member, data: dict): await player.shuffle(data.get("type", "queue"), member) -async def updateRepeatMode(player, member: Member, data: dict): +async def repeatTrack(player, member: Member, data: dict): if not player.is_privileged(member): return missingPermission(member.id) - mode = data.get("mode", "off") - if mode.lower() not in ['off', 'track', 'queue']: - mode = "off" - player.queue.set_repeat(mode) + await player.set_repeat() async def updatePause(player, member: Member, data: dict): if not player.is_privileged(member): @@ -140,7 +137,7 @@ methods = { "addTracks": addTracks, "getTracks": getTracks, "shuffleTrack": shuffleTrack, - "updateRepeat": updateRepeatMode, + "repeatTrack": repeatTrack, "updatePause": updatePause, "updatePosition": updatePosition, } diff --git a/web/static/js/action.js b/web/static/js/action.js index aa6cac0..b17c516 100644 --- a/web/static/js/action.js +++ b/web/static/js/action.js @@ -5,7 +5,7 @@ $(document).ready(function () { var typingTimer; var doneTypingInterval = 2000; - $('body').click(function(event) { + $('body').click(function (event) { var $target = $(event.target); var $resultList = $target.closest(".search-contrainer"); @@ -91,7 +91,7 @@ $(document).ready(function () { player.seekTo($(this).val()); }) - $("#shuffle-button").on('click', function() { + $("#shuffle-button").on('click', function () { player.shuffle(); }) -}); \ No newline at end of file +});