| @@ -0,0 +1,25 @@ | |||||
| using Discord.Interactions; | |||||
| using System; | |||||
| namespace Discord.Rest | |||||
| { | |||||
| public static class RestExtensions | |||||
| { | |||||
| /// <summary> | |||||
| /// Respond to an interaction with a <see cref="IModal"/>. | |||||
| /// </summary> | |||||
| /// <typeparam name="T">Type of the <see cref="IModal"/> implementation.</typeparam> | |||||
| /// <param name="interaction">The interaction to respond to.</param> | |||||
| /// <param name="options">The request options for this <see langword="async"/> request.</param> | |||||
| /// <returns>Serialized payload to be used to create a HTTP response.</returns> | |||||
| public static string RespondWithModal<T>(this RestInteraction interaction, string customId, RequestOptions options = null, Action<ModalBuilder> modifyModal = null) | |||||
| where T : class, IModal | |||||
| { | |||||
| if (!ModalUtils.TryGet<T>(out var modalInfo)) | |||||
| throw new ArgumentException($"{typeof(T).FullName} isn't referenced by any registered Modal Interaction Command and doesn't have a cached {typeof(ModalInfo)}"); | |||||
| var modal = modalInfo.ToModal(customId, modifyModal); | |||||
| return interaction.RespondWithModal(modal, options); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -65,5 +65,39 @@ namespace Discord.Interactions | |||||
| else | else | ||||
| await InteractionService._restResponseCallback(Context, payload).ConfigureAwait(false); | await InteractionService._restResponseCallback(Context, payload).ConfigureAwait(false); | ||||
| } | } | ||||
| /// <summary> | |||||
| /// Responds to the interaction with a modal. | |||||
| /// </summary> | |||||
| /// <param name="modal">The modal to respond with.</param> | |||||
| /// <param name="options">The request options for this <see langword="async"/> request.</param> | |||||
| /// <returns>A string that contains json to write back to the incoming http request.</returns> | |||||
| /// <exception cref="TimeoutException"></exception> | |||||
| /// <exception cref="InvalidOperationException"></exception> | |||||
| protected override async Task RespondWithModalAsync(Modal modal, RequestOptions options = null) | |||||
| { | |||||
| if (Context.Interaction is not RestInteraction restInteraction) | |||||
| throw new InvalidOperationException($"Invalid interaction type. Interaction must be a type of {nameof(RestInteraction)} in order to execute this method"); | |||||
| var payload = restInteraction.RespondWithModal(modal, options); | |||||
| if (Context is IRestInteractionContext restContext && restContext.InteractionResponseCallback != null) | |||||
| await restContext.InteractionResponseCallback.Invoke(payload).ConfigureAwait(false); | |||||
| else | |||||
| await InteractionService._restResponseCallback(Context, payload).ConfigureAwait(false); | |||||
| } | |||||
| protected override async Task RespondWithModalAsync<T>(string customId, RequestOptions options = null) | |||||
| { | |||||
| if (Context.Interaction is not RestInteraction restInteraction) | |||||
| throw new InvalidOperationException($"Invalid interaction type. Interaction must be a type of {nameof(RestInteraction)} in order to execute this method"); | |||||
| var payload = restInteraction.RespondWithModal<T>(customId, options); | |||||
| if (Context is IRestInteractionContext restContext && restContext.InteractionResponseCallback != null) | |||||
| await restContext.InteractionResponseCallback.Invoke(payload).ConfigureAwait(false); | |||||
| else | |||||
| await InteractionService._restResponseCallback(Context, payload).ConfigureAwait(false); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -196,5 +196,26 @@ namespace Discord.Interactions | |||||
| }).ToList(), | }).ToList(), | ||||
| Options = commandOption.Options?.Select(x => x.ToApplicationCommandOptionProps()).ToList() | Options = commandOption.Options?.Select(x => x.ToApplicationCommandOptionProps()).ToList() | ||||
| }; | }; | ||||
| public static Modal ToModal(this ModalInfo modalInfo, string customId, Action<ModalBuilder> modifyModal = null) | |||||
| { | |||||
| var builder = new ModalBuilder(modalInfo.Title, customId); | |||||
| foreach (var input in modalInfo.Components) | |||||
| switch (input) | |||||
| { | |||||
| case TextInputComponentInfo textComponent: | |||||
| builder.AddTextInput(textComponent.Label, textComponent.CustomId, textComponent.Style, textComponent.Placeholder, textComponent.IsRequired ? textComponent.MinLength : null, | |||||
| textComponent.MaxLength, textComponent.IsRequired, textComponent.InitialValue); | |||||
| break; | |||||
| default: | |||||
| throw new InvalidOperationException($"{input.GetType().FullName} isn't a valid component info class"); | |||||
| } | |||||
| if(modifyModal is not null) | |||||
| modifyModal(builder); | |||||
| return builder.Build(); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||