Skip to content

Commit

Permalink
Add ability to view previous topics with .topic command
Browse files Browse the repository at this point in the history
After a user invokes the ".topic" command and reacts with the reroll emoji, the embed will now show the previous few messages. It cannot display more than
256 characters, which is usually around 5 prompts.

Implements: python-discord#1145
  • Loading branch information
Anonymous4045 authored and Ibrahim2750mi committed Feb 25, 2023
1 parent a85401f commit 4a2b741
Showing 1 changed file with 44 additions and 17 deletions.
61 changes: 44 additions & 17 deletions bot/exts/utilities/conversationstarters.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def __init__(self, bot: Bot):
self.bot = bot

@staticmethod
def _build_topic_embed(channel_id: int) -> discord.Embed:
def _build_topic_embed(channel_id: int, previous_topic: None | str) -> discord.Embed:
"""
Build an embed containing a conversation topic.
Expand All @@ -56,21 +56,46 @@ def _build_topic_embed(channel_id: int) -> discord.Embed:
color=discord.Colour.og_blurple()
)

try:
channel_topics = TOPICS[channel_id]
except KeyError:
# Channel doesn't have any topics.
embed.title = f"**{next(TOPICS['default'])}**"
if previous_topic is None:
# Message first sent
try:
channel_topics = TOPICS[channel_id]
except KeyError:
# Channel doesn't have any topics.
embed.title = f"**{next(TOPICS['default'])}**"
else:
embed.title = f"**{next(channel_topics)}**"
else:
embed.title = f"**{next(channel_topics)}**"
# Message is being edited

try:
channel_topics = TOPICS[channel_id]
except KeyError:
# Channel doesn't have any topics.
new_topic = f"**{next(TOPICS['default'])}**"
else:
new_topic = f"\n**{next(channel_topics)}**"

total_topics = previous_topic.count("\n") + 1

# Add 1 before first topic
if total_topics == 1:
previous_topic = f"1. {previous_topic}"

embed.title = previous_topic + f"\n{total_topics + 1}. {new_topic}"

# When the embed will be larger than the limit, use the previous embed instead
if len(embed.title) > 256:
embed.title = previous_topic

return embed

@staticmethod
def _predicate(
command_invoker: Union[discord.User, discord.Member],
message: discord.Message,
reaction: discord.Reaction,
user: discord.User
command_invoker: Union[discord.User, discord.Member],
message: discord.Message,
reaction: discord.Reaction,
user: discord.User
) -> bool:
user_is_moderator = any(role.id in MODERATION_ROLES for role in getattr(user, "roles", []))
user_is_invoker = user.id == command_invoker.id
Expand All @@ -83,9 +108,9 @@ def _predicate(
return is_right_reaction

async def _listen_for_refresh(
self,
command_invoker: Union[discord.User, discord.Member],
message: discord.Message
self,
command_invoker: Union[discord.User, discord.Member],
message: discord.Message
) -> None:
await message.add_reaction("🔄")
while True:
Expand All @@ -101,23 +126,25 @@ async def _listen_for_refresh(
break

try:
await message.edit(embed=self._build_topic_embed(message.channel.id))
# The returned discord.Message object from discord.Message.edit is different than the current
# discord.Message object, so it must be reassigned to update properly
message = await message.edit(embed=self._build_topic_embed(message.channel.id, message.embeds[0].title))
except discord.NotFound:
break

with suppress(discord.NotFound):
await message.remove_reaction(reaction, user)

@commands.command()
@commands.cooldown(1, 60*2, commands.BucketType.channel)
@commands.cooldown(1, 60 * 2, commands.BucketType.channel)
@whitelist_override(channels=ALL_ALLOWED_CHANNELS)
async def topic(self, ctx: commands.Context) -> None:
"""
Responds with a random topic to start a conversation.
Allows the refresh of a topic by pressing an emoji.
"""
message = await ctx.send(embed=self._build_topic_embed(ctx.channel.id))
message = await ctx.send(embed=self._build_topic_embed(ctx.channel.id, None))
self.bot.loop.create_task(self._listen_for_refresh(ctx.author, message))


Expand Down

0 comments on commit 4a2b741

Please sign in to comment.