Feature: Implement modals (#2087)
* Implement Modals (#428) * Socket Modal Support * fix shareded client support * Properly use `HasResponded` instead of `_hasResponded` * `ModalBuilder` and `TextInputBuilder` validation. * make orginisation more consistant. * Rest Modals. * Docs + add missing methods * fix message signatures and missing abstract members * modal changes * um????? * update modal docs * update docs - again for some reason * cleanup * fix message signatures * add modal commands support to interaction service * Fix _hasResponded * update to new unsupported standard. * Sending modals with Interaction service. * fix spelling in ComponentBuilder * sending IModals when responding to interactions * interaction service modals * fix rest modals * spelling and minor improvements. * improve interaction service modal proformance * use precompiled lambda for interaction service modals * respect user compiled lambda choice * changes to modals in the interaction service (more) * support compiled lambdas in modal properties. * modal interactions tweaks * fix inline doc * more modal docs * configure responce to faild modal component * init * solve runtime errors * solve build errors * add default value parsing * make modal info caching static * make ModalUtils static * add inline docs * fix build errors * code cleanup * Introduce Required and Label properties as seperate attributes. * replace internal dictionary of ModalInfo with a list * change input building logic of modals * update RespondWithModalAsync method * add initial value parameter back to ModalTextInput and fix optional modal field * add missing inline docs * dispose the reference modal instance after building * code cleanup on modalcommandbuilder * Update docs/guides/int_basics/message-components/text-input.md Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update docs/guides/int_basics/message-components/text-input.md Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update docs/guides/int_basics/modals/intro.md Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update docs/guides/int_basics/modals/intro.md Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update docs/guides/int_basics/modals/intro.md Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update docs/guides/int_basics/modals/intro.md Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update docs/guides/int_basics/modals/intro.md Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update docs/guides/int_basics/modals/intro.md Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update docs/guides/int_basics/modals/intro.md Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update docs/guides/int_framework/intro.md Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update docs/guides/int_framework/intro.md Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update docs/guides/int_framework/samples/intro/modal.cs Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update src/Discord.Net.Core/Entities/Interactions/MessageComponents/IComponentInteractionData.cs Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update src/Discord.Net.Core/Entities/Interactions/MessageComponents/TextInputComponent.cs Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update src/Discord.Net.Core/Entities/Interactions/Modals/IModalInteraction.cs Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update src/Discord.Net.Core/Entities/Interactions/Modals/ModalBuilder.cs Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update src/Discord.Net.Core/Entities/Interactions/Modals/ModalBuilder.cs Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update src/Discord.Net.Core/Entities/Interactions/Modals/ModalBuilder.cs Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update src/Discord.Net.Core/Entities/Interactions/Modals/ModalBuilder.cs Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update src/Discord.Net.Core/Entities/Interactions/Modals/ModalBuilder.cs Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update src/Discord.Net.Core/Entities/Interactions/Modals/ModalBuilder.cs Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update src/Discord.Net.Interactions/Attributes/Commands/ModalInteractionAttribute.cs Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update src/Discord.Net.Interactions/Attributes/Modals/RequiredInputAttribute.cs Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update src/Discord.Net.Interactions/InteractionServiceConfig.cs Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update src/Discord.Net.WebSocket/Entities/Interaction/MessageComponents/SocketMessageComponentData.cs Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update src/Discord.Net.WebSocket/Entities/Interaction/Modals/SocketModalData.cs Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * update interaction service modal docs * implements ExitOnMissingmModalField config option and adds Type field to modal info * Add WithValue to text input builders * Fix rare NRE on component enumeration * Fix RequestOptions being required in some methods * Use 'OfType' instead of 'Where' * Remove android unsported warning * Change publicity of properties in IInputComponeontBuilder.cs Co-authored-by: Cenk Ergen <57065323+Cenngo@users.noreply.github.com> Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Remove complex parameter ref Co-authored-by: CottageDwellingCat <80918250+CottageDwellingCat@users.noreply.github.com> Co-authored-by: Cenk Ergen <57065323+Cenngo@users.noreply.github.com> Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com>
This commit is contained in:
90
src/Discord.Net.Interactions/Info/ModalInfo.cs
Normal file
90
src/Discord.Net.Interactions/Info/ModalInfo.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
|
||||
namespace Discord.Interactions
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a cached object initialization delegate.
|
||||
/// </summary>
|
||||
/// <param name="args">Property arguments array.</param>
|
||||
/// <returns>
|
||||
/// Returns the constructed object.
|
||||
/// </returns>
|
||||
public delegate IModal ModalInitializer(object[] args);
|
||||
|
||||
/// <summary>
|
||||
/// Represents the info class of an <see cref="IModal"/> form.
|
||||
/// </summary>
|
||||
public class ModalInfo
|
||||
{
|
||||
internal readonly ModalInitializer _initializer;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the title of this modal.
|
||||
/// </summary>
|
||||
public string Title { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IModal"/> implementation used to initialize this object.
|
||||
/// </summary>
|
||||
public Type Type { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of the components of this modal.
|
||||
/// </summary>
|
||||
public IReadOnlyCollection<InputComponentInfo> Components { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of the text components of this modal.
|
||||
/// </summary>
|
||||
public IReadOnlyCollection<TextInputComponentInfo> TextComponents { get; }
|
||||
|
||||
internal ModalInfo(Builders.ModalBuilder builder)
|
||||
{
|
||||
Title = builder.Title;
|
||||
Type = builder.Type;
|
||||
Components = builder.Components.Select(x => x switch
|
||||
{
|
||||
Builders.TextInputComponentBuilder textComponent => textComponent.Build(this),
|
||||
_ => throw new InvalidOperationException($"{x.GetType().FullName} isn't a supported modal input component builder type.")
|
||||
}).ToImmutableArray();
|
||||
|
||||
TextComponents = Components.OfType<TextInputComponentInfo>().ToImmutableArray();
|
||||
|
||||
_initializer = builder.ModalInitializer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IModal"/> and fills it with provided message components.
|
||||
/// </summary>
|
||||
/// <param name="components"><see cref="IModalInteraction"/> that will be injected into the modal.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="IModal"/> filled with the provided components.
|
||||
/// </returns>
|
||||
public IModal CreateModal(IModalInteraction modalInteraction, bool throwOnMissingField = false)
|
||||
{
|
||||
var args = new object[Components.Count];
|
||||
var components = modalInteraction.Data.Components.ToList();
|
||||
|
||||
for (var i = 0; i < Components.Count; i++)
|
||||
{
|
||||
var input = Components.ElementAt(i);
|
||||
var component = components.Find(x => x.CustomId == input.CustomId);
|
||||
|
||||
if (component is null)
|
||||
{
|
||||
if (!throwOnMissingField)
|
||||
args[i] = input.DefaultValue;
|
||||
else
|
||||
throw new InvalidOperationException($"Modal interaction is missing the required field: {input.CustomId}");
|
||||
}
|
||||
else
|
||||
args[i] = component.Value;
|
||||
}
|
||||
|
||||
return _initializer(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user