mirror of
https://github.com/wlinator/luminara.git
synced 2024-10-02 20:23:12 +00:00
Add introduction command
This commit is contained in:
parent
48f50415b1
commit
aa2a4c21a6
3 changed files with 277 additions and 0 deletions
|
@ -191,6 +191,7 @@
|
|||
"intro_no_channel_author": "Channel Not Set",
|
||||
"intro_no_guild": "you're not in a server that supports introductions.",
|
||||
"intro_no_guild_author": "Server Not Supported",
|
||||
"intro_post_confirmation_author": "Introduction Posted",
|
||||
"intro_post_confirmation": "your introduction has been posted in {0}!",
|
||||
"intro_preview_field": "**{0}:** {1}\n\n",
|
||||
"intro_question_footer": "Type your answer below.",
|
||||
|
|
193
modules/misc/introduction.py
Normal file
193
modules/misc/introduction.py
Normal file
|
@ -0,0 +1,193 @@
|
|||
import asyncio
|
||||
from typing import Dict, Optional
|
||||
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
|
||||
from lib.const import CONST
|
||||
from ui.embeds import builder
|
||||
from ui.views.introduction import (
|
||||
IntroductionFinishButtons,
|
||||
IntroductionStartButtons,
|
||||
)
|
||||
|
||||
|
||||
class Introduction(commands.Cog):
|
||||
def __init__(self, bot: commands.Bot):
|
||||
self.bot = bot
|
||||
|
||||
@commands.hybrid_command(
|
||||
name="introduction",
|
||||
aliases=["intro"],
|
||||
usage="introduction",
|
||||
)
|
||||
async def introduction(self, ctx: commands.Context[commands.Bot]) -> None:
|
||||
guild: Optional[discord.Guild] = self.bot.get_guild(
|
||||
CONST.INTRODUCTIONS_GUILD_ID,
|
||||
)
|
||||
member: Optional[discord.Member] = (
|
||||
guild.get_member(ctx.author.id) if guild else None
|
||||
)
|
||||
|
||||
if not guild or not member:
|
||||
await ctx.send(
|
||||
embed=builder.create_embed(
|
||||
theme="error",
|
||||
user_name=ctx.author.name,
|
||||
author_text=CONST.STRINGS["intro_no_guild_author"],
|
||||
description=CONST.STRINGS["intro_no_guild"],
|
||||
footer_text=CONST.STRINGS["intro_service_name"],
|
||||
),
|
||||
)
|
||||
return
|
||||
|
||||
question_mapping: Dict[str, str] = CONST.INTRODUCTIONS_QUESTION_MAPPING
|
||||
channel: Optional[discord.abc.GuildChannel] = guild.get_channel(
|
||||
CONST.INTRODUCTIONS_CHANNEL_ID,
|
||||
)
|
||||
|
||||
if not channel or isinstance(
|
||||
channel,
|
||||
(discord.ForumChannel, discord.CategoryChannel),
|
||||
):
|
||||
await ctx.send(
|
||||
embed=builder.create_embed(
|
||||
theme="error",
|
||||
user_name=ctx.author.name,
|
||||
author_text=CONST.STRINGS["intro_no_channel_author"],
|
||||
description=CONST.STRINGS["intro_no_channel"],
|
||||
footer_text=CONST.STRINGS["intro_service_name"],
|
||||
),
|
||||
)
|
||||
return
|
||||
|
||||
view: IntroductionStartButtons | IntroductionFinishButtons = (
|
||||
IntroductionStartButtons(ctx)
|
||||
)
|
||||
await ctx.send(
|
||||
embed=builder.create_embed(
|
||||
theme="info",
|
||||
user_name=ctx.author.name,
|
||||
author_text=CONST.STRINGS["intro_service_name"],
|
||||
description=CONST.STRINGS["intro_start"].format(channel.mention),
|
||||
footer_text=CONST.STRINGS["intro_start_footer"],
|
||||
),
|
||||
view=view,
|
||||
)
|
||||
|
||||
await view.wait()
|
||||
|
||||
if view.clicked_stop:
|
||||
await ctx.send(
|
||||
embed=builder.create_embed(
|
||||
theme="error",
|
||||
user_name=ctx.author.name,
|
||||
author_text=CONST.STRINGS["intro_stopped_author"],
|
||||
description=CONST.STRINGS["intro_stopped"],
|
||||
footer_text=CONST.STRINGS["intro_service_name"],
|
||||
),
|
||||
)
|
||||
return
|
||||
|
||||
if view.clicked_start:
|
||||
|
||||
def check(message: discord.Message) -> bool:
|
||||
return message.author == ctx.author and isinstance(
|
||||
message.channel,
|
||||
discord.DMChannel,
|
||||
)
|
||||
|
||||
answer_mapping: Dict[str, str] = {}
|
||||
|
||||
for key, question in question_mapping.items():
|
||||
await ctx.send(
|
||||
embed=builder.create_embed(
|
||||
theme="info",
|
||||
user_name=ctx.author.name,
|
||||
author_text=key,
|
||||
description=question,
|
||||
footer_text=CONST.STRINGS["intro_question_footer"],
|
||||
),
|
||||
)
|
||||
|
||||
try:
|
||||
answer: discord.Message = await self.bot.wait_for(
|
||||
"message",
|
||||
check=check,
|
||||
timeout=300,
|
||||
)
|
||||
answer_content: str = answer.content.replace("\n", " ")
|
||||
|
||||
if len(answer_content) > 200:
|
||||
await ctx.send(
|
||||
embed=builder.create_embed(
|
||||
theme="error",
|
||||
user_name=ctx.author.name,
|
||||
author_text=CONST.STRINGS["intro_too_long_author"],
|
||||
description=CONST.STRINGS["intro_too_long"],
|
||||
footer_text=CONST.STRINGS["intro_service_name"],
|
||||
),
|
||||
)
|
||||
return
|
||||
|
||||
answer_mapping[key] = answer_content
|
||||
|
||||
except asyncio.TimeoutError:
|
||||
await ctx.send(
|
||||
embed=builder.create_embed(
|
||||
theme="error",
|
||||
user_name=ctx.author.name,
|
||||
author_text=CONST.STRINGS["intro_timeout_author"],
|
||||
description=CONST.STRINGS["intro_timeout"],
|
||||
footer_text=CONST.STRINGS["intro_service_name"],
|
||||
),
|
||||
)
|
||||
return
|
||||
|
||||
description: str = "".join(
|
||||
CONST.STRINGS["intro_preview_field"].format(key, value)
|
||||
for key, value in answer_mapping.items()
|
||||
)
|
||||
|
||||
preview: discord.Embed = builder.create_embed(
|
||||
theme="info",
|
||||
user_name=ctx.author.name,
|
||||
author_text=ctx.author.name,
|
||||
author_icon_url=ctx.author.display_avatar.url,
|
||||
description=description,
|
||||
footer_text=CONST.STRINGS["intro_content_footer"],
|
||||
)
|
||||
view = IntroductionFinishButtons(ctx)
|
||||
|
||||
await ctx.send(embed=preview, view=view)
|
||||
await view.wait()
|
||||
|
||||
if view.clicked_confirm:
|
||||
await channel.send(
|
||||
embed=preview,
|
||||
content=CONST.STRINGS["intro_content"].format(ctx.author.mention),
|
||||
)
|
||||
await ctx.send(
|
||||
embed=builder.create_embed(
|
||||
theme="info",
|
||||
user_name=ctx.author.name,
|
||||
author_text=CONST.STRINGS["intro_post_confirmation_author"],
|
||||
description=CONST.STRINGS["intro_post_confirmation"].format(
|
||||
channel.mention,
|
||||
),
|
||||
),
|
||||
)
|
||||
else:
|
||||
await ctx.send(
|
||||
embed=builder.create_embed(
|
||||
theme="error",
|
||||
user_name=ctx.author.name,
|
||||
author_text=CONST.STRINGS["intro_stopped_author"],
|
||||
description=CONST.STRINGS["intro_stopped"],
|
||||
footer_text=CONST.STRINGS["intro_service_name"],
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
async def setup(bot: commands.Bot) -> None:
|
||||
await bot.add_cog(Introduction(bot))
|
83
ui/views/introduction.py
Normal file
83
ui/views/introduction.py
Normal file
|
@ -0,0 +1,83 @@
|
|||
from typing import Optional
|
||||
|
||||
import discord
|
||||
from discord.ui import Button, View
|
||||
|
||||
|
||||
class IntroductionStartButtons(View):
|
||||
def __init__(self, ctx) -> None:
|
||||
super().__init__(timeout=60)
|
||||
self.ctx = ctx
|
||||
self.clicked_start: bool = False
|
||||
self.clicked_stop: bool = False
|
||||
self.message: Optional[discord.Message] = None
|
||||
|
||||
async def on_timeout(self) -> None:
|
||||
for child in self.children:
|
||||
if isinstance(child, Button):
|
||||
child.disabled = True
|
||||
if self.message:
|
||||
await self.message.edit(view=None)
|
||||
|
||||
@discord.ui.button(label="Start", style=discord.ButtonStyle.primary)
|
||||
async def start_button_callback(
|
||||
self,
|
||||
interaction: discord.Interaction,
|
||||
button: Button,
|
||||
) -> None:
|
||||
await interaction.response.edit_message(view=None)
|
||||
self.clicked_start = True
|
||||
self.stop()
|
||||
|
||||
@discord.ui.button(label="Stop", style=discord.ButtonStyle.red)
|
||||
async def stop_button_callback(
|
||||
self,
|
||||
interaction: discord.Interaction,
|
||||
button: Button,
|
||||
) -> None:
|
||||
await interaction.response.edit_message(view=None)
|
||||
self.clicked_stop = True
|
||||
self.stop()
|
||||
|
||||
|
||||
class IntroductionFinishButtons(View):
|
||||
def __init__(self, ctx) -> None:
|
||||
super().__init__(timeout=60)
|
||||
self.ctx = ctx
|
||||
self.clicked_confirm: bool = False
|
||||
self.message: Optional[discord.Message] = None
|
||||
|
||||
async def on_timeout(self) -> None:
|
||||
for child in self.children:
|
||||
if isinstance(child, Button):
|
||||
child.disabled = True
|
||||
if self.message:
|
||||
await self.message.edit(view=None)
|
||||
|
||||
@discord.ui.button(label="Post it!", style=discord.ButtonStyle.green)
|
||||
async def confirm_button_callback(
|
||||
self,
|
||||
interaction: discord.Interaction,
|
||||
button: Button,
|
||||
) -> None:
|
||||
await interaction.response.edit_message(view=None)
|
||||
self.clicked_confirm = True
|
||||
self.stop()
|
||||
|
||||
@discord.ui.button(label="Stop", style=discord.ButtonStyle.red)
|
||||
async def stop_button_callback(
|
||||
self,
|
||||
interaction: discord.Interaction,
|
||||
button: Button,
|
||||
) -> None:
|
||||
await interaction.response.edit_message(view=None)
|
||||
self.stop()
|
||||
|
||||
async def interaction_check(self, interaction: discord.Interaction) -> bool:
|
||||
if interaction.user == self.ctx.author:
|
||||
return True
|
||||
await interaction.response.send_message(
|
||||
"You can't use these buttons.",
|
||||
ephemeral=True,
|
||||
)
|
||||
return False
|
Loading…
Reference in a new issue