diff --git a/PluralKit.Bot/CommandMeta/CommandTree.cs b/PluralKit.Bot/CommandMeta/CommandTree.cs index 3f03c84c..6cbf3245 100644 --- a/PluralKit.Bot/CommandMeta/CommandTree.cs +++ b/PluralKit.Bot/CommandMeta/CommandTree.cs @@ -52,6 +52,10 @@ public partial class CommandTree Commands.SystemShowServerTag(var param, var flags) => ctx.Execute(SystemServerTag, m => m.ShowServerTag(ctx, param.target, flags.GetReplyFormat())), Commands.SystemClearServerTag(var param, _) => ctx.Execute(SystemServerTag, m => m.ClearServerTag(ctx, ctx.System)), Commands.SystemChangeServerTag(var param, _) => ctx.Execute(SystemServerTag, m => m.ChangeServerTag(ctx, ctx.System, param.tag)), + Commands.SystemShowPronounsSelf(_, var flags) => ctx.Execute(SystemPronouns, m => m.ShowPronouns(ctx, ctx.System, flags.GetReplyFormat())), + Commands.SystemShowPronouns(var param, var flags) => ctx.Execute(SystemPronouns, m => m.ShowPronouns(ctx, param.target, flags.GetReplyFormat())), + Commands.SystemClearPronouns(var param, var flags) => ctx.Execute(SystemPronouns, m => m.ClearPronouns(ctx, ctx.System, flags.yes)), + Commands.SystemChangePronouns(var param, _) => ctx.Execute(SystemPronouns, m => m.ChangePronouns(ctx, ctx.System, param.pronouns)), _ => // this should only ever occur when deving if commands are not implemented... ctx.Reply( @@ -300,9 +304,7 @@ public partial class CommandTree private async Task HandleSystemCommandTargeted(Context ctx, PKSystem target) { - if (ctx.Match("pronouns", "pronoun", "prns", "pn")) - await ctx.CheckSystem(target).Execute(SystemPronouns, m => m.Pronouns(ctx, target)); - else if (ctx.Match("banner", "splash", "cover")) + if (ctx.Match("banner", "splash", "cover")) await ctx.CheckSystem(target).Execute(SystemBannerImage, m => m.BannerImage(ctx, target)); else if (ctx.Match("avatar", "picture", "icon", "image", "pic", "pfp")) await ctx.CheckSystem(target).Execute(SystemAvatar, m => m.Avatar(ctx, target)); diff --git a/PluralKit.Bot/Commands/SystemEdit.cs b/PluralKit.Bot/Commands/SystemEdit.cs index 32e87da2..c0eba729 100644 --- a/PluralKit.Bot/Commands/SystemEdit.cs +++ b/PluralKit.Bot/Commands/SystemEdit.cs @@ -479,25 +479,47 @@ public class SystemEdit await ctx.Reply(str); } - public async Task Pronouns(Context ctx, PKSystem target) + public async Task ClearPronouns(Context ctx, PKSystem target, bool flagConfirmYes) + { + ctx.CheckSystemPrivacy(target.Id, target.PronounPrivacy); + ctx.CheckSystem().CheckOwnSystem(target); + + if (await ctx.ConfirmClear("your system's pronouns", flagConfirmYes)) + { + await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { Pronouns = null }); + await ctx.Reply($"{Emojis.Success} System pronouns cleared."); + } + } + + public async Task ChangePronouns(Context ctx, PKSystem target, string newPronouns) + { + ctx.CheckSystemPrivacy(target.Id, target.PronounPrivacy); + ctx.CheckSystem().CheckOwnSystem(target); + + newPronouns = newPronouns.NormalizeLineEndSpacing(); + if (newPronouns.Length > Limits.MaxPronounsLength) + throw Errors.StringTooLongError("Pronouns", newPronouns.Length, Limits.MaxPronounsLength); + + await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { Pronouns = newPronouns }); + + await ctx.Reply($"{Emojis.Success} System pronouns changed (using {newPronouns.Length}/{Limits.MaxPronounsLength} characters)."); + } + + public async Task ShowPronouns(Context ctx, PKSystem target, ReplyFormat format) { ctx.CheckSystemPrivacy(target.Id, target.PronounPrivacy); var isOwnSystem = ctx.System.Id == target.Id; - var noPronounsSetMessage = "This system does not have pronouns set."; - if (isOwnSystem) - noPronounsSetMessage += $" To set some, type `{ctx.DefaultPrefix}system pronouns `"; + if (target.Pronouns == null) + { + var noPronounsSetMessage = "This system does not have pronouns set."; + if (isOwnSystem) + noPronounsSetMessage += $" To set some, type `{ctx.DefaultPrefix}system pronouns `"; - var format = ctx.MatchFormat(); - - // if there's nothing next or what's next is "raw"/"plaintext" we're doing a query, so check for null - if (!ctx.HasNext(false) || format != ReplyFormat.Standard) - if (target.Pronouns == null) - { - await ctx.Reply(noPronounsSetMessage); - return; - } + await ctx.Reply(noPronounsSetMessage); + return; + } if (format == ReplyFormat.Raw) { @@ -512,34 +534,9 @@ public class SystemEdit return; } - if (!ctx.HasNext(false)) - { - await ctx.Reply($"{(isOwnSystem ? "Your" : "This system's")} current pronouns are **{target.Pronouns}**.\nTo print the pronouns with formatting, type `{ctx.DefaultPrefix}system pronouns -raw`." + await ctx.Reply($"{(isOwnSystem ? "Your" : "This system's")} current pronouns are **{target.Pronouns}**.\nTo print the pronouns with formatting, type `{ctx.DefaultPrefix}system pronouns -raw`." + (isOwnSystem ? $" To clear them, type `{ctx.DefaultPrefix}system pronouns -clear`." + $" Using {target.Pronouns.Length}/{Limits.MaxPronounsLength} characters." : "")); - return; - } - - ctx.CheckSystem().CheckOwnSystem(target); - - if (ctx.MatchClear() && await ctx.ConfirmClear("your system's pronouns")) - { - await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { Pronouns = null }); - - await ctx.Reply($"{Emojis.Success} System pronouns cleared."); - } - else - { - var newPronouns = ctx.RemainderOrNull(false).NormalizeLineEndSpacing(); - if (newPronouns != null) - if (newPronouns.Length > Limits.MaxPronounsLength) - throw Errors.StringTooLongError("Pronouns", newPronouns.Length, Limits.MaxPronounsLength); - - await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { Pronouns = newPronouns }); - - await ctx.Reply( - $"{Emojis.Success} System pronouns changed (using {newPronouns.Length}/{Limits.MaxPronounsLength} characters)."); - } } public async Task Avatar(Context ctx, PKSystem target) diff --git a/PluralKit.Bot/Utils/ContextUtils.cs b/PluralKit.Bot/Utils/ContextUtils.cs index ce353472..fbadc2e5 100644 --- a/PluralKit.Bot/Utils/ContextUtils.cs +++ b/PluralKit.Bot/Utils/ContextUtils.cs @@ -15,17 +15,17 @@ namespace PluralKit.Bot; public static class ContextUtils { - public static async Task ConfirmClear(this Context ctx, string toClear) + public static async Task ConfirmClear(this Context ctx, string toClear, bool? confirmYes = null) { - if (!await ctx.PromptYesNo($"{Emojis.Warn} Are you sure you want to clear {toClear}?", "Clear")) + if (!await ctx.PromptYesNo($"{Emojis.Warn} Are you sure you want to clear {toClear}?", "Clear", null, true, confirmYes)) throw Errors.GenericCancelled(); return true; } public static async Task PromptYesNo(this Context ctx, string msgString, string acceptButton, - User user = null, bool matchFlag = true) + User user = null, bool matchFlag = true, bool? flagValue = null) { - if (matchFlag && ctx.MatchFlag("y", "yes")) return true; + if (matchFlag && (flagValue ?? ctx.MatchFlag("y", "yes"))) return true; var prompt = new YesNoPrompt(ctx) { diff --git a/crates/command_definitions/src/system.rs b/crates/command_definitions/src/system.rs index f7262832..133400d0 100644 --- a/crates/command_definitions/src/system.rs +++ b/crates/command_definitions/src/system.rs @@ -126,6 +126,23 @@ pub fn edit() -> impl Iterator { ] .into_iter(); + let system_pronouns = tokens!(system_target, ("pronouns", ["prns"])); + let system_pronouns_cmd = [ + command!(system_pronouns => "system_show_pronouns").help("Shows the system's pronouns"), + ] + .into_iter(); + + let system_pronouns_self = tokens!(system, ("pronouns", ["prns"])); + let system_pronouns_self_cmd = [ + command!(system_pronouns_self => "system_show_pronouns_self").help("Shows your system's pronouns"), + command!(system_pronouns_self, ("clear", ["c"]) => "system_clear_pronouns") + .flag(("yes", ["y"])) + .help("Clears your system's pronouns"), + command!(system_pronouns_self, ("pronouns", OpaqueString) => "system_change_pronouns") + .help("Changes your system's pronouns"), + ] + .into_iter(); + system_new_cmd .chain(system_name_self_cmd) .chain(system_server_name_self_cmd) @@ -133,11 +150,13 @@ pub fn edit() -> impl Iterator { .chain(system_color_self_cmd) .chain(system_tag_self_cmd) .chain(system_server_tag_self_cmd) + .chain(system_pronouns_self_cmd) .chain(system_name_cmd) .chain(system_server_name_cmd) .chain(system_description_cmd) .chain(system_color_cmd) .chain(system_tag_cmd) .chain(system_server_tag_cmd) + .chain(system_pronouns_cmd) .chain(system_info_cmd) } \ No newline at end of file