Upgrading views manager in messages timeout

This commit is contained in:
Rafael Vargas 2022-08-16 18:19:17 -04:00
parent 2d27a2f080
commit 2794f1a6d0
9 changed files with 48 additions and 14 deletions

View File

@ -11,7 +11,7 @@ from Music.Song import Song
from Music.Playlist import Playlist
from typing import List, Union
from discord import Button, Interaction
from UI.Buttons.EmptyButton import CallbackButton
from UI.Buttons.CallbackButton import CallbackButton
from UI.Buttons.PlaylistDropdown import PlaylistDropdown
from Config.Emojis import VEmojis

View File

@ -1,6 +1,7 @@
from typing import Dict, List
from discord import Message
from Config.Singleton import Singleton
from UI.Views.AbstractView import AbstractView
from Messages.MessagesCategory import MessagesCategory
@ -9,8 +10,10 @@ class MessagesManager(Singleton):
if not super().created:
# For each guild, and for each category, there will be a list of messages
self.__guildsMessages: Dict[int, Dict[MessagesCategory, List[Message]]] = {}
# Will, for each message, store the AbstractView that controls it
self.__messagesViews: Dict[Message, AbstractView] = {}
def addMessage(self, guildID: int, category: MessagesCategory, message: Message) -> None:
def addMessage(self, guildID: int, category: MessagesCategory, message: Message, view: AbstractView = None) -> None:
if message is None:
return
@ -22,9 +25,11 @@ class MessagesManager(Singleton):
self.__guildsMessages[guildID][category] = []
sendedMessages = self.__guildsMessages[guildID][category]
if view is not None and isinstance(view, AbstractView):
self.__messagesViews[message] = view
sendedMessages.append(message)
async def addMessageAndClearPrevious(self, guildID: int, category: MessagesCategory, message: Message) -> None:
async def addMessageAndClearPrevious(self, guildID: int, category: MessagesCategory, message: Message, view: AbstractView = None) -> None:
if message is None:
return
@ -44,6 +49,10 @@ class MessagesManager(Singleton):
# Create a new list with only the new message
self.__guildsMessages[guildID][category] = [message]
# Store the view of this message
if view is not None and isinstance(view, AbstractView):
self.__messagesViews[message] = view
async def clearMessagesOfCategory(self, guildID: int, category: MessagesCategory) -> None:
sendedMessages = self.__guildsMessages[guildID][category]
@ -59,6 +68,12 @@ class MessagesManager(Singleton):
async def __deleteMessage(self, message: Message) -> None:
try:
# If there is a view for this message delete the key
if message in self.__messagesViews.keys():
messageView = self.__messagesViews.pop(message)
messageView.stopView()
del messageView
await message.delete()
except Exception as e:
print(f'[ERROR DELETING MESSAGE] -> {e}')

View File

@ -19,6 +19,6 @@ class EmbedCommandResponse(AbstractCommandResponse):
if message:
# Only delete the previous message if this is not error and not forbidden by method caller
if deleteLast and self.response.success:
await self.manager.addMessageAndClearPrevious(self.context.guild.id, self.category, message)
await self.manager.addMessageAndClearPrevious(self.context.guild.id, self.category, message, self.response.view)
else:
self.manager.addMessage(self.context.guild.id, self.category, message)

View File

@ -43,7 +43,7 @@ class ProcessCommandsExecutor:
view = self.__getPlayerView(channel)
# Send Message and add to the MessagesManager
message = await channel.send(embed=embed, view=view)
await self.__messagesManager.addMessageAndClearPrevious(self.__guildID, MessagesCategory.NOW_PLAYING, message)
await self.__messagesManager.addMessageAndClearPrevious(self.__guildID, MessagesCategory.NOW_PLAYING, message, view)
# Set in the view the message witch contains the view
view.set_message(message=message)

View File

@ -39,7 +39,7 @@ class CallbackButton(Button):
# Clear the last sended message in this category and add the new one
if message:
await self.__messagesManager.addMessageAndClearPrevious(self.__guildID, self.__category, message)
await self.__messagesManager.addMessageAndClearPrevious(self.__guildID, self.__category, message, response.view)
def set_view(self, view: View):
self.__view = view

View File

@ -41,7 +41,7 @@ class HandlerButton(Button):
# Clear the last category sended message and add the new one
if message:
await self.__messagesManager.addMessageAndClearPrevious(self.__guildID, self.__category, message)
await self.__messagesManager.addMessageAndClearPrevious(self.__guildID, self.__category, message, response.view)
def set_view(self, view: View):
self.__view = view

View File

@ -19,15 +19,17 @@ class PlaylistDropdown(Select, AbstractItem):
songs = list(playlist.getSongs())
values = [str(x) for x in range(1, len(songs) + 1)]
# Get the title of each of the 20 first songs, library doesn't accept more
songsNames = [song.title[:80] for song in songs[:20]]
# Get the title of each of the 20 first songs, the pycord library doesn't accept more
songsNames: List[str] = []
for x in range(20):
songsNames.append(f'{x + 1} - {songs[x].title[:80]}')
selectOptions: List[SelectOption] = []
for x in range(len(songsNames)):
selectOptions.append(SelectOption(label=songsNames[x], value=values[x]))
super().__init__(placeholder="Select one music to play now, may be overdue",
super().__init__(placeholder="Select one music to play now, may be outdated",
min_values=1, max_values=1, options=selectOptions)
self.__playlist = playlist
@ -55,7 +57,7 @@ class PlaylistDropdown(Select, AbstractItem):
# Clear the last sended message in this category and add the new one
if message:
await self.__messagesManager.addMessageAndClearPrevious(self.__guildID, self.__category, message)
await self.__messagesManager.addMessageAndClearPrevious(self.__guildID, self.__category, message, response.view)
# Extreme ugly way to wait for the player process to actually retrieve the next song
await asyncio.sleep(2)

View File

@ -8,3 +8,7 @@ class AbstractView(ABC):
def set_message(self, message) -> None:
pass
@abstractmethod
def stopView(self) -> None:
pass

View File

@ -16,18 +16,25 @@ class BasicView(View, AbstractView):
super().__init__(timeout=timeout)
self.__bot = bot
self.__message: Message = None
self.__working = True
for button in buttons:
# Set the buttons to have a instance of the view that contains them
button.set_view(self)
self.add_item(button)
def stopView(self):
self.__working = False
async def on_timeout(self) -> None:
# Disable all itens and, if has the message, edit it
try:
if not self.__working:
return
self.disable_all_items()
if self.__message is not None and isinstance(self.__message, Message):
await self.__message.edit(view=self)
await self.__message.edit(f"{emojis.MUSIC} - The buttons in this message have been disabled due timeout", view=self)
except Exception as e:
print(f'[ERROR EDITING MESSAGE] -> {e}')
@ -35,5 +42,11 @@ class BasicView(View, AbstractView):
self.__message = message
async def update(self):
try:
if not self.__working:
return
if self.__message is not None:
await self.__message.edit(view=self)
except Exception as e:
print(f'[ERROR UPDATING MESSAGE] -> {e}')