2021-07-02 10:35:25 +00:00
|
|
|
using System;
|
|
|
|
using System.Threading;
|
2021-05-30 14:45:29 +00:00
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
2021-07-02 10:35:25 +00:00
|
|
|
using Myriad.Gateway;
|
|
|
|
using Myriad.Rest.Types;
|
2021-05-30 14:45:29 +00:00
|
|
|
using Myriad.Types;
|
|
|
|
|
2021-07-02 10:35:25 +00:00
|
|
|
using PluralKit.Core;
|
|
|
|
|
|
|
|
using Autofac;
|
|
|
|
|
2021-05-30 14:45:29 +00:00
|
|
|
namespace PluralKit.Bot.Interactive
|
|
|
|
{
|
|
|
|
public class YesNoPrompt: BaseInteractive
|
|
|
|
{
|
|
|
|
public bool? Result { get; private set; }
|
|
|
|
public ulong? User { get; set; }
|
|
|
|
public string Message { get; set; } = "Are you sure?";
|
|
|
|
|
|
|
|
public string AcceptLabel { get; set; } = "OK";
|
|
|
|
public ButtonStyle AcceptStyle { get; set; } = ButtonStyle.Primary;
|
|
|
|
|
|
|
|
public string CancelLabel { get; set; } = "Cancel";
|
|
|
|
public ButtonStyle CancelStyle { get; set; } = ButtonStyle.Secondary;
|
2021-08-27 15:03:47 +00:00
|
|
|
|
2021-05-30 14:45:29 +00:00
|
|
|
public override async Task Start()
|
|
|
|
{
|
|
|
|
AddButton(ctx => OnButtonClick(ctx, true), AcceptLabel, AcceptStyle);
|
|
|
|
AddButton(ctx => OnButtonClick(ctx, false), CancelLabel, CancelStyle);
|
2021-07-02 10:35:25 +00:00
|
|
|
|
|
|
|
AllowedMentions mentions = null;
|
|
|
|
|
|
|
|
if (User != _ctx.Author.Id)
|
2021-08-27 15:03:47 +00:00
|
|
|
mentions = new AllowedMentions { Users = new[] { User!.Value } };
|
2021-07-02 10:35:25 +00:00
|
|
|
|
|
|
|
await Send(Message, mentions: mentions);
|
2021-05-30 14:45:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private async Task OnButtonClick(InteractionContext ctx, bool result)
|
|
|
|
{
|
|
|
|
if (ctx.User.Id != User)
|
|
|
|
{
|
|
|
|
await Update(ctx);
|
|
|
|
return;
|
|
|
|
}
|
2021-08-27 15:03:47 +00:00
|
|
|
|
2021-05-30 14:45:29 +00:00
|
|
|
Result = result;
|
|
|
|
await Finish(ctx);
|
|
|
|
}
|
|
|
|
|
2021-07-02 10:35:25 +00:00
|
|
|
private bool MessagePredicate(MessageCreateEvent e)
|
|
|
|
{
|
|
|
|
if (e.ChannelId != _ctx.Channel.Id) return false;
|
|
|
|
if (e.Author.Id != User) return false;
|
|
|
|
|
|
|
|
var response = e.Content.ToLowerInvariant();
|
|
|
|
|
|
|
|
if (response == "y" || response == "yes")
|
|
|
|
{
|
|
|
|
Result = true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (response == "n" || response == "no")
|
|
|
|
{
|
|
|
|
Result = false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public new async Task Run()
|
|
|
|
{
|
|
|
|
// todo: can we split this up somehow so it doesn't need to be *completely* copied from BaseInteractive?
|
|
|
|
|
|
|
|
var cts = new CancellationTokenSource(Timeout.ToTimeSpan());
|
|
|
|
|
|
|
|
if (_running)
|
|
|
|
throw new InvalidOperationException("Action is already running");
|
|
|
|
_running = true;
|
|
|
|
|
|
|
|
var queue = _ctx.Services.Resolve<HandlerQueue<MessageCreateEvent>>();
|
2021-08-27 15:03:47 +00:00
|
|
|
|
2021-07-02 10:35:25 +00:00
|
|
|
var messageDispatch = queue.WaitFor(MessagePredicate, Timeout, cts.Token);
|
|
|
|
|
|
|
|
await Start();
|
2021-08-27 15:03:47 +00:00
|
|
|
|
2021-07-02 10:35:25 +00:00
|
|
|
cts.Token.Register(() => _tcs.TrySetException(new TimeoutException("Action timed out")));
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
var doneTask = await Task.WhenAny(_tcs.Task, messageDispatch);
|
|
|
|
if (doneTask == messageDispatch)
|
|
|
|
await Finish();
|
|
|
|
}
|
|
|
|
finally
|
|
|
|
{
|
|
|
|
Cleanup();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-27 15:03:47 +00:00
|
|
|
public YesNoPrompt(Context ctx) : base(ctx)
|
2021-05-30 14:45:29 +00:00
|
|
|
{
|
|
|
|
User = ctx.Author.Id;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|