diff --git a/bot.py b/bot.py index 1e1092a..5606b2f 100644 --- a/bot.py +++ b/bot.py @@ -40,6 +40,7 @@ async def on_ready(): activity = discord.Activity(name=f"{len(bot.guilds)} guilds", type=discord.ActivityType.listening) await bot.change_presence(activity=activity, status = discord.Status.online) print(f"Logged in as {bot.user}") + await bot.sync_commands(force=True) for i in bot.guilds: if str(i.id) not in GuildAppDB.get_all_guilds(): GuildAppDB.create_guild(str(i.id), i.name) @@ -75,6 +76,269 @@ async def on_application_command_error(ctx, error): else: raise error +application = discord.SlashCommandGroup("application", "The main command to manage applications") + +@application.command(description="Create application") +async def create(ctx, application): + if len(application) < 40: + result = GuildAppDB.add_application_entry(str(ctx.guild.id), application) + if result == "success": + await ctx.response.send_message(f"Successfully created application: {application}", ephemeral=True) # create a new application, modal with name ask + else: + print(result) + else: + await ctx.response.send_message(f"please choose shorter name", ephemeral=True) + +@application.command(description="Remove application") +async def remove(ctx, application): + result = GuildAppDB.remove_application_entry(str(ctx.guild.id), application) + if result == "success": + await ctx.response.send_message(f"Successfully removed application: {application}", ephemeral=True) + else: + await ctx.response.send_message(f"Application {application} not found") + +@application.command(description="List all applications") +async def list(ctx): + applications = GuildAppDB.get_applications(str(ctx.guild.id)) + print(applications) + embed = discord.Embed() + for i in applications: + embed.add_field(name=i, value="", inline=False) + await ctx.response.send_message(embed=embed) + + +@application.command(description="Opens editor for selected application") +async def editor(ctx): + view = discord.ui.View() + options = SelectApplicationOptionsEditor(max_values=1, placeholder="Select application") + for i in GuildAppDB.get_applications(str(ctx.guild.id)): + options.add_option(label=i, value=i) + view.add_item(options) + await ctx.response.send_message(view=view, ephemeral=True) + +@application.command(description="Select response channel for application") +async def response_channel(ctx): + view = discord.ui.View() + options = SelectApplicationOptionsRespChannel(max_values=1, placeholder="Select application") + for i in GuildAppDB.get_applications(str(ctx.guild.id)): + options.add_option(label=i, value=i) + view.add_item(options) + await ctx.response.send_message(view=view, ephemeral=True) + +''' +@application.command(description="test") +async def test(ctx): + view = SelectResponseChannelView() + await ctx.response.send_message(view=view, ephemeral=True) + +@application.command(description="appl") +async def appl(ctx): + viewx = discord.ui.View() + options = SelectApplicationOptionsEditor(max_values=1) + for i in GuildAppDB.get_applications(str(ctx.guild.id)): + options.add_option(label=i, value=i) + viewx.add_item(options) + await ctx.response.send_message(view=viewx, ephemeral=True)''' + +bot.add_application_command(application) # add application group commands + + + + +class SelectResponseChannelView(discord.ui.View): + @discord.ui.select( + select_type=discord.ComponentType.channel_select, + channel_types=[discord.ChannelType.text], + max_values=1 + ) + async def select_callback(self, select, interaction: discord.Interaction): + self.disable_all_items() + print(select.values[0].id) + GuildAppDB.set_response_channel(interaction.guild.id, ) + await interaction.response.edit_message(content=f"Selected channel: {select.values[0].mention}", view=None) + +class SelectResponseChannel(discord.ui.Select): + def set_app_name(self, app_name): + self.app_name = app_name + + async def callback(self, interaction: discord.Interaction): + self.disabled = True + GuildAppDB.set_response_channel(str(interaction.guild.id), self.app_name, str(self.values[0].id)) + await interaction.response.edit_message(content=f"Selected channel: {self.values[0].mention} for application: {self.app_name}", view=None) + +class SelectApplicationOptionsEditor(discord.ui.Select): + async def callback(self, interaction: discord.Interaction): + self.disabled = True + editor = ApplicationEditorView(str(interaction.guild.id), self.values[0]) + embed = get_questions_embed(str(interaction.guild.id), self.values[0]) + await interaction.response.edit_message(embed = embed, view=editor) + +class SelectApplicationOptionsRespChannel(discord.ui.Select): + async def callback(self, interaction: discord.Interaction): + self.disabled = True + view = discord.ui.View() + options = SelectResponseChannel(select_type=discord.ComponentType.channel_select, channel_types=[discord.ChannelType.text], max_values=1) + options.set_app_name(self.values[0]) + view.add_item(options) + await interaction.response.edit_message(view=view) + +def get_questions_embed(guild_id, application) -> discord.Embed: + embed = discord.Embed(title=f"Application: {application}") + questions, length = GuildAppDB.get_questions(str(guild_id), application) + for i, que in enumerate(questions): + embed.add_field(value=f"**{i+1}. {que}**", name="", inline=False) + embed.set_footer(text="Made by @anorak01", icon_url="https://cdn.discordapp.com/avatars/269164865480949760/a1af9962da20d5ddaa136043cf45d015?size=1024") + return embed + +class ApplicationEditorView(discord.ui.View): + def __init__(self, guild_id, application_name): + super().__init__(timeout=180) + self.guild_id = guild_id + self.application_name = application_name + + @discord.ui.button( + label="New", + style=discord.ButtonStyle.green, + custom_id="editor:add", + row=0 + ) + async def add_question(self, button: discord.ui.Button, interaction: discord.Interaction): + print("add question") + modal = AddQuestionModal(self.application_name) + await interaction.response.send_modal(modal) + + @discord.ui.button( + label="Remove", + style=discord.ButtonStyle.red, + custom_id="editor:remove", + row=0 + ) + async def remove_question(self, button, interaction: discord.Interaction): + print("remove question") + view = ApplicationEditorView(str(interaction.guild.id), self.application_name) + options = RemoveQuestionSelect(max_values=1, placeholder="Select question to remove") + options.set_app_name(self.application_name) + questions, length = GuildAppDB.get_questions(str(interaction.guild.id), self.application_name) + for i, que in enumerate(questions): + options.add_option(label=f"{str(i+1)}. {que}", value=str(i)) + view.add_item(options) + await interaction.response.edit_message(view=view) + + @discord.ui.button( + label="Edit", + style=discord.ButtonStyle.primary, + custom_id="editor:edit", + row=0 + ) + async def edit_question(self, button, interaction: discord.Interaction): + print("edit question") + view = ApplicationEditorView(str(interaction.guild.id), self.application_name) + options = EditQuestionSelect(max_values=1, placeholder="Select question to edit") + options.set_app_name(self.application_name) + questions, length = GuildAppDB.get_questions(str(interaction.guild.id), self.application_name) + for i, que in enumerate(questions): + options.add_option(label=f"{str(i+1)}. {que}", value=str(i)) + view.add_item(options) + await interaction.response.edit_message(view=view) + + @discord.ui.button( + label="Move", + style=discord.ButtonStyle.gray, + custom_id="editor:move", + row=0 + ) + async def move_question(self, button, interaction: discord.Interaction): + print("move question") + view = ApplicationEditorView(str(interaction.guild.id), self.application_name) + options = MoveQuestionSelect(max_values=1, placeholder="Select question to move") + options.set_app_name(self.application_name) + questions, length = GuildAppDB.get_questions(str(interaction.guild.id), self.application_name) + for i, que in enumerate(questions): + options.add_option(label=f"{str(i+1)}. {que}", value=str(i)) + view.add_item(options) + await interaction.response.edit_message(view=view) + + +class AddQuestionModal(discord.ui.Modal): + def __init__(self, app_name): + self.app_name = app_name + super().__init__(discord.ui.InputText(label=f"New Question: "), title = "") + + async def callback(self, interaction: discord.Interaction): + question = self.children[0].value + GuildAppDB.add_question(str(interaction.guild.id), self.app_name, question) + embed = get_questions_embed(str(interaction.guild.id), self.app_name) + await interaction.response.edit_message(embed=embed) + + +class RemoveQuestionSelect(discord.ui.Select): + def set_app_name(self, app_name): + self.app_name = app_name + + async def callback(self, interaction: discord.Interaction): + self.disabled = True + GuildAppDB.remove_question(str(interaction.guild.id), self.app_name, int(self.values[0])+1) + editor = ApplicationEditorView(str(interaction.guild.id), self.app_name) + embed = get_questions_embed(str(interaction.guild.id), self.app_name) + await interaction.response.edit_message(embed = embed, view = editor) + + +class EditQuestionSelect(discord.ui.Select): + def set_app_name(self, app_name): + self.app_name = app_name + + async def callback(self, interaction: discord.Interaction): + self.disabled = True + editor = ApplicationEditorView(str(interaction.guild.id), self.app_name) + modal = EditQuestionModal(self.app_name, int(self.values[0])+1) + await interaction.response.send_modal(modal) + await interaction.followup.edit_message(view = editor, message_id=interaction.message.id) + +class EditQuestionModal(discord.ui.Modal): + def __init__(self, app_name, question_index): + self.app_name = app_name + self.question_index = question_index + super().__init__(discord.ui.InputText(label=f"Edited Question: "), title = "") + + async def callback(self, interaction: discord.Interaction): + question = self.children[0].value + GuildAppDB.edit_question(str(interaction.guild.id), self.app_name, self.question_index, question) + embed = get_questions_embed(str(interaction.guild.id), self.app_name) + await interaction.response.edit_message(embed=embed) + + +class MoveQuestionSelect(discord.ui.Select): + def set_app_name(self, app_name): + self.app_name = app_name + + async def callback(self, interaction: discord.Interaction): + self.disabled = True + view = ApplicationEditorView(str(interaction.guild.id), self.app_name) + options = MoveQuestionSelectNum(max_values=1, placeholder="Select place for move") + options.set_app_name(self.app_name) + options.set_init_index(int(self.values[0])+1) + questions, length = GuildAppDB.get_questions(str(interaction.guild.id), self.app_name) + for i in range(length): + options.add_option(label=str(i+1), value=str(i+1)) + view.add_item(options) + await interaction.response.edit_message(view = view) + +class MoveQuestionSelectNum(discord.ui.Select): + def set_app_name(self, app_name): + self.app_name = app_name + + def set_init_index(self, init_index: int): + self.init_index = init_index + + async def callback(self, interaction: discord.Interaction): + self.disabled = True + editor = ApplicationEditorView(str(interaction.guild.id), self.app_name) + GuildAppDB.move_question(str(interaction.guild.id), self.app_name, int(self.init_index), int(self.values[0])) + embed = get_questions_embed(str(interaction.guild.id), self.app_name) + await interaction.response.edit_message(view = editor, embed=embed) + + + # View with button that starts the application process class ApplicationStartButtonView(discord.ui.View): def __init__(self):