From ab6ab127dda34e760dbb18557e4f7b0b0d0b9206 Mon Sep 17 00:00:00 2001 From: spiral Date: Fri, 2 Jul 2021 06:40:40 -0400 Subject: [PATCH] move Context#PromptYesNo to buttons --- PluralKit.Bot/Commands/Groups.cs | 4 +- PluralKit.Bot/Commands/ImportExport.cs | 4 +- PluralKit.Bot/Commands/Member.cs | 2 +- PluralKit.Bot/Commands/MemberEdit.cs | 2 +- PluralKit.Bot/Commands/MemberProxy.cs | 6 +-- PluralKit.Bot/Commands/Switch.cs | 14 +++---- PluralKit.Bot/Commands/SystemEdit.cs | 2 +- PluralKit.Bot/Commands/SystemLink.cs | 7 ++-- PluralKit.Bot/Utils/ContextUtils.cs | 56 +++++--------------------- 9 files changed, 31 insertions(+), 66 deletions(-) diff --git a/PluralKit.Bot/Commands/Groups.cs b/PluralKit.Bot/Commands/Groups.cs index e4c5aa68..e82c9f41 100644 --- a/PluralKit.Bot/Commands/Groups.cs +++ b/PluralKit.Bot/Commands/Groups.cs @@ -51,7 +51,7 @@ namespace PluralKit.Bot var existingGroup = await _repo.GetGroupByName(conn, ctx.System.Id, groupName); if (existingGroup != null) { var msg = $"{Emojis.Warn} You already have a group in your system with the name \"{existingGroup.Name}\" (with ID `{existingGroup.Hid}`). Do you want to create another group with the same name?"; - if (!await ctx.PromptYesNo(msg)) + if (!await ctx.PromptYesNo(msg, "Create")) throw new PKError("Group creation cancelled."); } @@ -81,7 +81,7 @@ namespace PluralKit.Bot var existingGroup = await _repo.GetGroupByName(conn, ctx.System.Id, newName); if (existingGroup != null && existingGroup.Id != target.Id) { var msg = $"{Emojis.Warn} You already have a group in your system with the name \"{existingGroup.Name}\" (with ID `{existingGroup.Hid}`). Do you want to rename this member to that name too?"; - if (!await ctx.PromptYesNo(msg)) + if (!await ctx.PromptYesNo(msg, "Rename")) throw new PKError("Group creation cancelled."); } diff --git a/PluralKit.Bot/Commands/ImportExport.cs b/PluralKit.Bot/Commands/ImportExport.cs index a4da57ba..61a6dc24 100644 --- a/PluralKit.Bot/Commands/ImportExport.cs +++ b/PluralKit.Bot/Commands/ImportExport.cs @@ -73,7 +73,7 @@ namespace PluralKit.Bot if (data.LinkedAccounts != null && !data.LinkedAccounts.Contains(ctx.Author.Id)) { var msg = $"{Emojis.Warn} You seem to importing a system profile belonging to another account. Are you sure you want to proceed?"; - if (!await ctx.PromptYesNo(msg)) throw Errors.ImportCancelled; + if (!await ctx.PromptYesNo(msg, "Import")) throw Errors.ImportCancelled; } // If passed system is null, it'll create a new one @@ -120,7 +120,7 @@ namespace PluralKit.Bot issueStr += "\n- PluralKit does not support per-member system tags. Since you had multiple members with distinct tags, those tags will be applied to the members' *display names*/nicknames instead."; var msg = $"{issueStr}\n\nDo you want to proceed with the import?"; - if (!await ctx.PromptYesNo(msg)) + if (!await ctx.PromptYesNo(msg, "Import")) throw Errors.ImportCancelled; } diff --git a/PluralKit.Bot/Commands/Member.cs b/PluralKit.Bot/Commands/Member.cs index 0ebf72c6..eb88e589 100644 --- a/PluralKit.Bot/Commands/Member.cs +++ b/PluralKit.Bot/Commands/Member.cs @@ -41,7 +41,7 @@ namespace PluralKit.Bot var existingMember = await _db.Execute(c => _repo.GetMemberByName(c, ctx.System.Id, memberName)); if (existingMember != null) { var msg = $"{Emojis.Warn} You already have a member in your system with the name \"{existingMember.NameFor(ctx)}\" (with ID `{existingMember.Hid}`). Do you want to create another member with the same name?"; - if (!await ctx.PromptYesNo(msg)) throw new PKError("Member creation cancelled."); + if (!await ctx.PromptYesNo(msg, "Create")) throw new PKError("Member creation cancelled."); } await using var conn = await _db.Obtain(); diff --git a/PluralKit.Bot/Commands/MemberEdit.cs b/PluralKit.Bot/Commands/MemberEdit.cs index b643ba88..76ade3ba 100644 --- a/PluralKit.Bot/Commands/MemberEdit.cs +++ b/PluralKit.Bot/Commands/MemberEdit.cs @@ -35,7 +35,7 @@ namespace PluralKit.Bot if (existingMember != null && existingMember.Id != target.Id) { var msg = $"{Emojis.Warn} You already have a member in your system with the name \"{existingMember.NameFor(ctx)}\" (`{existingMember.Hid}`). Do you want to rename this member to that name too?"; - if (!await ctx.PromptYesNo(msg)) throw new PKError("Member renaming cancelled."); + if (!await ctx.PromptYesNo(msg, "Rename")) throw new PKError("Member renaming cancelled."); } // Rename the member diff --git a/PluralKit.Bot/Commands/MemberProxy.cs b/PluralKit.Bot/Commands/MemberProxy.cs index 44873fb8..f9854ff0 100644 --- a/PluralKit.Bot/Commands/MemberProxy.cs +++ b/PluralKit.Bot/Commands/MemberProxy.cs @@ -42,7 +42,7 @@ namespace PluralKit.Bot var conflictList = conflicts.Select(m => $"- **{m.NameFor(ctx)}**"); var msg = $"{Emojis.Warn} The following members have conflicting proxy tags:\n{string.Join('\n', conflictList)}\nDo you want to proceed anyway?"; - return await ctx.PromptYesNo(msg); + return await ctx.PromptYesNo(msg, "Proceed"); } // "Sub"command: clear flag @@ -52,7 +52,7 @@ namespace PluralKit.Bot if (target.ProxyTags.Count > 1) { var msg = $"{Emojis.Warn} You already have multiple proxy tags set: {target.ProxyTagsString()}\nDo you want to clear them all?"; - if (!await ctx.PromptYesNo(msg)) + if (!await ctx.PromptYesNo(msg, "Clear")) throw Errors.GenericCancelled(); } @@ -117,7 +117,7 @@ namespace PluralKit.Bot if (target.ProxyTags.Count > 1) { var msg = $"This member already has more than one proxy tag set: {target.ProxyTagsString()}\nDo you want to replace them?"; - if (!await ctx.PromptYesNo(msg)) + if (!await ctx.PromptYesNo(msg, "Replace")) throw Errors.GenericCancelled(); } diff --git a/PluralKit.Bot/Commands/Switch.cs b/PluralKit.Bot/Commands/Switch.cs index 9486ceba..fc910de0 100644 --- a/PluralKit.Bot/Commands/Switch.cs +++ b/PluralKit.Bot/Commands/Switch.cs @@ -92,18 +92,18 @@ namespace PluralKit.Bot // But, we do a prompt to confirm. var lastSwitchMembers = _repo.GetSwitchMembers(conn, lastTwoSwitches[0].Id); var lastSwitchMemberStr = string.Join(", ", await lastSwitchMembers.Select(m => m.NameFor(ctx)).ToListAsync()); - var lastSwitchTimeStr = lastTwoSwitches[0].Timestamp.FormatZoned(ctx.System); + var lastSwitchTime = lastTwoSwitches[0].Timestamp.ToUnixTimeSeconds(); // .FormatZoned(ctx.System) var lastSwitchDeltaStr = (SystemClock.Instance.GetCurrentInstant() - lastTwoSwitches[0].Timestamp).FormatDuration(); - var newSwitchTimeStr = time.FormatZoned(); + var newSwitchTime = time.ToInstant().ToUnixTimeSeconds(); var newSwitchDeltaStr = (SystemClock.Instance.GetCurrentInstant() - time.ToInstant()).FormatDuration(); // yeet - var msg = $"{Emojis.Warn} This will move the latest switch ({lastSwitchMemberStr}) from {lastSwitchTimeStr} ({lastSwitchDeltaStr} ago) to {newSwitchTimeStr} ({newSwitchDeltaStr} ago). Is this OK?"; - if (!await ctx.PromptYesNo(msg)) throw Errors.SwitchMoveCancelled; + var msg = $"{Emojis.Warn} This will move the latest switch ({lastSwitchMemberStr}) from ({lastSwitchDeltaStr} ago) to ({newSwitchDeltaStr} ago). Is this OK?"; + if (!await ctx.PromptYesNo(msg, "Move Switch")) throw Errors.SwitchMoveCancelled; // aaaand *now* we do the move await _repo.MoveSwitch(conn, lastTwoSwitches[0].Id, time.ToInstant()); - await ctx.Reply($"{Emojis.Success} Switch moved to {newSwitchTimeStr} ({newSwitchDeltaStr} ago)."); + await ctx.Reply($"{Emojis.Success} Switch moved to ({newSwitchDeltaStr} ago)."); } public async Task SwitchDelete(Context ctx) @@ -114,7 +114,7 @@ namespace PluralKit.Bot { // Subcommand: "delete all" var purgeMsg = $"{Emojis.Warn} This will delete *all registered switches* in your system. Are you sure you want to proceed?"; - if (!await ctx.PromptYesNo(purgeMsg)) + if (!await ctx.PromptYesNo(purgeMsg, "Clear Switches")) throw Errors.GenericCancelled(); await _db.Execute(c => _repo.DeleteAllSwitches(c, ctx.System.Id)); await ctx.Reply($"{Emojis.Success} Cleared system switches!"); @@ -144,7 +144,7 @@ namespace PluralKit.Bot msg = $"{Emojis.Warn} This will delete the latest switch ({lastSwitchMemberStr}, {lastSwitchDeltaStr} ago). The next latest switch is {secondSwitchMemberStr} ({secondSwitchDeltaStr} ago). Is this okay?"; } - if (!await ctx.PromptYesNo(msg)) throw Errors.SwitchDeleteCancelled; + if (!await ctx.PromptYesNo(msg, "Delete Switch")) throw Errors.SwitchDeleteCancelled; await _repo.DeleteSwitch(conn, lastTwoSwitches[0].Id); await ctx.Reply($"{Emojis.Success} Switch deleted."); diff --git a/PluralKit.Bot/Commands/SystemEdit.cs b/PluralKit.Bot/Commands/SystemEdit.cs index 1e1988ec..a439041a 100644 --- a/PluralKit.Bot/Commands/SystemEdit.cs +++ b/PluralKit.Bot/Commands/SystemEdit.cs @@ -294,7 +294,7 @@ namespace PluralKit.Bot var currentTime = SystemClock.Instance.GetCurrentInstant().InZone(zone); var msg = $"This will change the system time zone to **{zone.Id}**. The current time is **{currentTime.FormatZoned()}**. Is this correct?"; - if (!await ctx.PromptYesNo(msg)) throw Errors.TimezoneChangeCancelled; + if (!await ctx.PromptYesNo(msg, "Change Timezone")) throw Errors.TimezoneChangeCancelled; var patch = new SystemPatch {UiTz = zone.Id}; await _db.Execute(conn => _repo.UpdateSystem(conn, ctx.System.Id, patch)); diff --git a/PluralKit.Bot/Commands/SystemLink.cs b/PluralKit.Bot/Commands/SystemLink.cs index 0ebc0d83..cc8736ba 100644 --- a/PluralKit.Bot/Commands/SystemLink.cs +++ b/PluralKit.Bot/Commands/SystemLink.cs @@ -34,9 +34,8 @@ namespace PluralKit.Bot if (existingAccount != null) throw Errors.AccountInOtherSystem(existingAccount); - var msg = $"{account.Mention()}, please confirm the link by clicking the {Emojis.Success} reaction on this message."; - var mentions = new AllowedMentions {Users = new[] {account.Id}}; - if (!await ctx.PromptYesNo(msg, user: account, mentions: mentions, matchFlag: false)) throw Errors.MemberLinkCancelled; + var msg = $"{account.Mention()}, please confirm the link."; + if (!await ctx.PromptYesNo(msg, "Confirm", user: account, matchFlag: false)) throw Errors.MemberLinkCancelled; await _repo.AddAccount(conn, ctx.System.Id, account.Id); await ctx.Reply($"{Emojis.Success} Account linked to system."); } @@ -58,7 +57,7 @@ namespace PluralKit.Bot if (accountIds.Count == 1) throw Errors.UnlinkingLastAccount; var msg = $"Are you sure you want to unlink <@{id}> from your system?"; - if (!await ctx.PromptYesNo(msg)) throw Errors.MemberUnlinkCancelled; + if (!await ctx.PromptYesNo(msg, "Unlink")) throw Errors.MemberUnlinkCancelled; await _repo.RemoveAccount(conn, ctx.System.Id, id); await ctx.Reply($"{Emojis.Success} Account unlinked."); diff --git a/PluralKit.Bot/Utils/ContextUtils.cs b/PluralKit.Bot/Utils/ContextUtils.cs index edb5d93d..88342b6b 100644 --- a/PluralKit.Bot/Utils/ContextUtils.cs +++ b/PluralKit.Bot/Utils/ContextUtils.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Threading; using System.Threading.Tasks; using Autofac; @@ -15,64 +14,31 @@ using Myriad.Types; using NodaTime; +using PluralKit.Bot.Interactive; using PluralKit.Core; namespace PluralKit.Bot { public static class ContextUtils { public static async Task ConfirmClear(this Context ctx, string toClear) { - if (!(await ctx.PromptYesNo($"{Emojis.Warn} Are you sure you want to clear {toClear}?"))) throw Errors.GenericCancelled(); + if (!(await ctx.PromptYesNo($"{Emojis.Warn} Are you sure you want to clear {toClear}?", "Clear"))) throw Errors.GenericCancelled(); else return true; } - public static async Task PromptYesNo(this Context ctx, string msgString, User user = null, Duration? timeout = null, AllowedMentions mentions = null, bool matchFlag = true) + public static async Task PromptYesNo(this Context ctx, string msgString, string acceptButton, User user = null, bool matchFlag = true) { - Message message; if (matchFlag && ctx.MatchFlag("y", "yes")) return true; - else message = await ctx.Reply(msgString, mentions: mentions); - var cts = new CancellationTokenSource(); - if (user == null) user = ctx.Author; - if (timeout == null) timeout = Duration.FromMinutes(5); - - if (!DiscordUtils.HasReactionPermissions(ctx)) - await ctx.Reply($"{Emojis.Note} PluralKit does not have permissions to add reactions in this channel. \nPlease reply with 'yes' to confirm, or 'no' to cancel."); - else - // "Fork" the task adding the reactions off so we don't have to wait for them to be finished to start listening for presses - await ctx.Rest.CreateReactionsBulk(message, new[] {Emojis.Success, Emojis.Error}); - - bool ReactionPredicate(MessageReactionAddEvent e) + + var prompt = new YesNoPrompt(ctx) { - if (e.ChannelId != message.ChannelId || e.MessageId != message.Id) return false; - if (e.UserId != user.Id) return false; - return true; - } + Message = msgString, + AcceptLabel = acceptButton, + User = user?.Id ?? ctx.Author.Id, + }; - bool MessagePredicate(MessageCreateEvent e) - { - if (e.ChannelId != message.ChannelId) return false; - if (e.Author.Id != user.Id) return false; + await prompt.Run(); - var strings = new [] {"y", "yes", "n", "no"}; - return strings.Any(str => string.Equals(e.Content, str, StringComparison.InvariantCultureIgnoreCase)); - } - - var messageTask = ctx.Services.Resolve>().WaitFor(MessagePredicate, timeout, cts.Token); - var reactionTask = ctx.Services.Resolve>().WaitFor(ReactionPredicate, timeout, cts.Token); - - var theTask = await Task.WhenAny(messageTask, reactionTask); - cts.Cancel(); - - if (theTask == messageTask) - { - var responseMsg = (await messageTask); - var positives = new[] {"y", "yes"}; - return positives.Any(p => string.Equals(responseMsg.Content, p, StringComparison.InvariantCultureIgnoreCase)); - } - - if (theTask == reactionTask) - return (await reactionTask).Emoji.Name == Emojis.Success; - - return false; + return prompt.Result == true; } public static async Task AwaitReaction(this Context ctx, Message message, User user = null, Func predicate = null, Duration? timeout = null)