diff --git a/DisCatSharp.Interactivity/Extensions/InteractionExtensions.cs b/DisCatSharp.Interactivity/Extensions/InteractionExtensions.cs
index 73aa9e37b..a6de60d97 100644
--- a/DisCatSharp.Interactivity/Extensions/InteractionExtensions.cs
+++ b/DisCatSharp.Interactivity/Extensions/InteractionExtensions.cs
@@ -1,121 +1,120 @@
// This file is part of the DisCatSharp project, based off DSharpPlus.
//
// Copyright (c) 2021-2022 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using DisCatSharp.Entities;
using DisCatSharp.Interactivity.Enums;
using DisCatSharp.Interactivity.EventHandling;
namespace DisCatSharp.Interactivity.Extensions;
///
/// The interaction extensions.
///
public static class InteractionExtensions
{
///
/// Sends a paginated message in response to an interaction.
///
/// Pass the interaction directly. Interactivity will ACK it.
///
///
/// The interaction to create a response to.
/// Whether the interaction was deferred.
/// Whether the response should be ephemeral.
/// The user to listen for button presses from.
/// The pages to paginate.
/// Optional: custom buttons
/// Pagination behaviour.
/// Deletion behaviour
/// A custom cancellation token that can be cancelled at any point.
public static Task SendPaginatedResponseAsync(this DiscordInteraction interaction, bool deferred, bool ephemeral, DiscordUser user, IEnumerable pages, PaginationButtons buttons = null, PaginationBehaviour? behaviour = default, ButtonPaginationBehavior? deletion = default, CancellationToken token = default)
=> MessageExtensions.GetInteractivity(interaction.Message).SendPaginatedResponseAsync(interaction, deferred, ephemeral, user, pages, buttons, behaviour, deletion, token);
///
/// Sends multiple modals to the user with a prompt to open the next one.
///
/// The interaction to create a response to.
/// The modal pages.
/// A custom timeout. (Default: 15 minutes)
/// A read-only dictionary with the customid of the components as the key.
/// Is thrown when no modals are defined.
/// Is thrown when interactivity is not enabled for the client/shard.
public static async Task CreatePaginatedModalResponseAsync(this DiscordInteraction interaction, IReadOnlyList modals, TimeSpan? timeOutOverride = null)
{
if (modals is null || modals.Count == 0)
throw new ArgumentException("You have to set at least one page");
var client = (DiscordClient)interaction.Discord;
var interactivity = client.GetInteractivity() ?? throw new InvalidOperationException($"Interactivity is not enabled for this {(client.IsShard ? "shard" : "client")}.");
timeOutOverride ??= TimeSpan.FromMinutes(15);
Dictionary caughtResponses = new();
var previousInteraction = interaction;
foreach (var b in modals)
{
var modal = b.Modal.WithCustomId(Guid.NewGuid().ToString());
if (previousInteraction.Type is InteractionType.Ping or InteractionType.ModalSubmit)
{
await previousInteraction.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, b.OpenMessage.AddComponents(b.OpenButton));
var originalResponse = await previousInteraction.GetOriginalResponseAsync();
var modalOpen = await interactivity.WaitForButtonAsync(originalResponse, new List { b.OpenButton }, timeOutOverride);
if (modalOpen.TimedOut)
{
_ = previousInteraction.EditOriginalResponseAsync(new DiscordWebhookBuilder().WithContent(b.OpenMessage.Content).AddComponents(b.OpenButton.Disable()));
return new PaginatedModalResponse { TimedOut = true };
}
await modalOpen.Result.Interaction.CreateInteractionModalResponseAsync(modal);
}
else
{
await previousInteraction.CreateInteractionModalResponseAsync(modal);
}
_ = previousInteraction.EditOriginalResponseAsync(new DiscordWebhookBuilder().WithContent(b.OpenMessage.Content).AddComponents(b.OpenButton.Disable()));
var modalResult = await interactivity.WaitForModalAsync(modal.CustomId, timeOutOverride);
if (modalResult.TimedOut)
return new PaginatedModalResponse { TimedOut = true };
- foreach (var row in modalResult.Result.Interaction.Data.Components)
- foreach (var submissions in row.Components)
+ foreach (var submissions in modalResult.Result.Interaction.Data.Components)
caughtResponses.Add(submissions.CustomId, submissions.Value);
previousInteraction = modalResult.Result.Interaction;
}
await previousInteraction.CreateResponseAsync(InteractionResponseType.DeferredChannelMessageWithSource, new DiscordInteractionResponseBuilder().AsEphemeral());
return new PaginatedModalResponse { TimedOut = false, Responses = caughtResponses, Interaction = previousInteraction };
}
}