diff --git a/src/main/kotlin/org/dreamexposure/ticketbird/business/ComponentService.kt b/src/main/kotlin/org/dreamexposure/ticketbird/business/ComponentService.kt index 4494ddd..949e123 100644 --- a/src/main/kotlin/org/dreamexposure/ticketbird/business/ComponentService.kt +++ b/src/main/kotlin/org/dreamexposure/ticketbird/business/ComponentService.kt @@ -85,6 +85,32 @@ class ComponentService( return arrayOf(ActionRow.of(titleInput), ActionRow.of(descriptionInput)) } + suspend fun getAddProjectModalComponents(settings: GuildSettings): Array { + val nameInput = TextInput.small( + "add-project.name", + localeService.getString(settings.locale, "modal.add-project.name.label"), + 1, + 100 + ).placeholder(localeService.getString(settings.locale, "modal.add-project.name.placeholder")) + .required() + val prefixInput = TextInput.small( + "add-project.prefix", + localeService.getString(settings.locale, "modal.add-project.prefix.label"), + 1, + 16 + ).placeholder(localeService.getString(settings.locale, "modal.add-project.prefix.placeholder")) + .required() + val infoInput = TextInput.paragraph( + "add-project.info", + localeService.getString(settings.locale, "modal.add-project.info.label"), + 0, + 4000 + ).placeholder(localeService.getString(settings.locale, "modal.add-project.info.placeholder").textInputPlaceholderSafe()) + .required(false) + + return arrayOf(ActionRow.of(nameInput), ActionRow.of(prefixInput), ActionRow.of(infoInput)) + } + suspend fun getEditProjectModalComponents(settings: GuildSettings, project: Project): Array { val infoInput = TextInput.paragraph( "edit-project.info", diff --git a/src/main/kotlin/org/dreamexposure/ticketbird/commands/global/ProjectCommand.kt b/src/main/kotlin/org/dreamexposure/ticketbird/commands/global/ProjectCommand.kt index 50210f9..1020ab2 100644 --- a/src/main/kotlin/org/dreamexposure/ticketbird/commands/global/ProjectCommand.kt +++ b/src/main/kotlin/org/dreamexposure/ticketbird/commands/global/ProjectCommand.kt @@ -32,7 +32,7 @@ class ProjectCommand( override suspend fun shouldDefer(event: ChatInputInteractionEvent): Boolean { return when (event.options[0].name) { - "edit-info" -> false + "add", "edit-info" -> false else -> super.shouldDefer(event) } } @@ -61,36 +61,20 @@ class ProjectCommand( } private suspend fun add(event: ChatInputInteractionEvent, settings: GuildSettings) { - val name = event.options[0].getOption("name") - .flatMap(ApplicationCommandInteractionOption::getValue) - .map(ApplicationCommandInteractionOptionValue::asString) - .map { it.substring(0, 100.coerceAtMost(it.length)) } - .get() - val prefix = event.options[0].getOption("prefix") - .flatMap(ApplicationCommandInteractionOption::getValue) - .map(ApplicationCommandInteractionOptionValue::asString) - .map { it.replace(Regex("\\W"), "") } // Keep only alphanumeric chars - .map { it.substring(0, 16.coerceAtMost(it.length)) } - .get() - // Check if max amount of projects has been created if (projectService.getAllProjects(settings.guildId).size >= 25) { - event.createFollowup(localeService.getString(settings.locale, "command.project.add.limit-reached")) + event.reply(localeService.getString(settings.locale, "command.project.add.limit-reached")) .withEmbeds(embedService.getProjectListEmbed(settings)) .withEphemeral(ephemeral) - .map(Message::getId) - .flatMap { event.deleteFollowupDelayed(it, messageDeleteSeconds) } .awaitSingleOrNull() return } - projectService.createProject(Project(guildId = settings.guildId, name = name, prefix = prefix)) - - event.createFollowup(localeService.getString(settings.locale, "command.project.add.success")) - .withEmbeds(embedService.getProjectListEmbed(settings)) - .withEphemeral(ephemeral) - .map(Message::getId) - .flatMap { event.deleteFollowupDelayed(it, messageDeleteSeconds) } + // pop modal + event.presentModal() + .withCustomId("add-project-modal") + .withTitle(localeService.getString(settings.locale, "modal.add-project.title")) + .withComponents(*componentService.getAddProjectModalComponents(settings)) .awaitSingleOrNull() } diff --git a/src/main/kotlin/org/dreamexposure/ticketbird/interaction/AddProjectModal.kt b/src/main/kotlin/org/dreamexposure/ticketbird/interaction/AddProjectModal.kt new file mode 100644 index 0000000..943bd54 --- /dev/null +++ b/src/main/kotlin/org/dreamexposure/ticketbird/interaction/AddProjectModal.kt @@ -0,0 +1,61 @@ +package org.dreamexposure.ticketbird.interaction + +import discord4j.core.event.domain.interaction.ModalSubmitInteractionEvent +import discord4j.core.`object`.component.TextInput +import discord4j.core.`object`.entity.Message +import kotlinx.coroutines.reactor.awaitSingleOrNull +import org.dreamexposure.ticketbird.business.EmbedService +import org.dreamexposure.ticketbird.business.LocaleService +import org.dreamexposure.ticketbird.business.ProjectService +import org.dreamexposure.ticketbird.config.Config +import org.dreamexposure.ticketbird.extensions.asSeconds +import org.dreamexposure.ticketbird.extensions.discord4j.deleteFollowupDelayed +import org.dreamexposure.ticketbird.`object`.GuildSettings +import org.dreamexposure.ticketbird.`object`.Project +import org.springframework.stereotype.Component +import kotlin.jvm.optionals.getOrNull + +@Component +class AddProjectModal( + private val projectService: ProjectService, + private val localeService: LocaleService, + private val embedService: EmbedService, +): InteractionHandler { + override val ids = arrayOf("add-project-modal") + override val ephemeral = true + + private val messageDeleteSeconds = Config.TIMING_MESSAGE_DELETE_GENERIC_SECONDS.getLong().asSeconds() + + override suspend fun handle(event: ModalSubmitInteractionEvent, settings: GuildSettings) { + val inputs = event.getComponents(TextInput::class.java) + + val name = inputs.first { it.customId == "add-project.name" }.value.get() + val prefix = inputs.first { it.customId == "add-project.prefix" }.value.get() + val info = inputs.first { it.customId == "add-project.info" }.value.getOrNull() + + // Double check if max amount of projects have been created + if (projectService.getAllProjects(settings.guildId).size >= 25) { + event.createFollowup(localeService.getString(settings.locale, "command.project.add.limit-reached")) + .withEmbeds(embedService.getProjectListEmbed(settings)) + .withEphemeral(ephemeral) + .map(Message::getId) + .flatMap { event.deleteFollowupDelayed(it, messageDeleteSeconds) } + .awaitSingleOrNull() + return + } + + val project = projectService.createProject(Project( + guildId = settings.guildId, + name = name, + prefix = prefix, + additionalInfo = info + )) + + event.createFollowup(localeService.getString(settings.locale, "command.project.add.success")) + .withEmbeds(embedService.getProjectViewEmbed(settings, project)) + .withEphemeral(ephemeral) + .map(Message::getId) + .flatMap { event.deleteFollowupDelayed(it, messageDeleteSeconds) } + .awaitSingleOrNull() + } +} diff --git a/src/main/resources/commands/global/project.json b/src/main/resources/commands/global/project.json index 28595ed..7d704f6 100644 --- a/src/main/resources/commands/global/project.json +++ b/src/main/resources/commands/global/project.json @@ -7,25 +7,7 @@ { "type": 1, "name": "add", - "description": "Adds a new project that users can select when opening tickets. Up to 25", - "options": [ - { - "type": 3, - "name": "name", - "description": "The name of the new project.", - "required": true, - "max_length": 100, - "min_length": 1 - }, - { - "type": 3, - "name": "prefix", - "description": "A prefix to help identify tickets for this project. 16 characters max, alphanumeric allowed", - "required": true, - "max_length": 16, - "min_length": 1 - } - ] + "description": "Adds a new project that users can select when opening tickets. Up to 25 can be created" }, { "type": 1, diff --git a/src/main/resources/locale/values.properties b/src/main/resources/locale/values.properties index 5018580..b143c07 100644 --- a/src/main/resources/locale/values.properties +++ b/src/main/resources/locale/values.properties @@ -161,9 +161,18 @@ modal.edit-support-message.description.label=Description modal.edit-support-message.description.placeholder=Need help with something? \n\n Open a new ticket by clicking the button below or using the \ `/support` command. +modal.add-project.title=Add Project +modal.add-project.name.label=Name +modal.add-project.name.placeholder=The name of the project, what users will see when opening a ticket +modal.add-project.prefix.label=Prefix +modal.add-project.prefix.placeholder=Prefix added to a ticket channel's name to help identify it +modal.add-project.info.label=Additional Info +modal.add-project.info.placeholder=Any additional info you want to provide to users when a ticket has been opened + + modal.edit-project.title=Edit Project modal.edit-project.info.label=Additional Info -modal.edit-project.info.placeholder=Any additional info you want to provide to users when a ticket has been opened. +modal.edit-project.info.placeholder=Any additional info you want to provide to users when a ticket has been opened # Auto complete auto-complete.setup.actions.auto-close=Auto Close Ticket (Current: {0})