From 6043d31b087b8b495a4be6f1fa44395aad788011 Mon Sep 17 00:00:00 2001 From: Petal Ladenson Date: Thu, 5 Dec 2024 18:24:20 -0700 Subject: [PATCH] feat: alternate proxy switch mode "add" (#702) * feat: alternate proxy switch mode "add" * docs: add proxy switch add to docs * chore: change default alias to proxy switch new from proxy switch on --- PluralKit.Bot/CommandMeta/CommandHelp.cs | 2 +- PluralKit.Bot/Commands/Config.cs | 27 ++++++++++++++----- PluralKit.Bot/Proxy/ProxyService.cs | 19 ++++++++++--- .../Database/Functions/MessageContext.cs | 2 +- .../Database/Functions/functions.sql | 2 +- PluralKit.Core/Database/Migrations/50.sql | 11 ++++++++ .../Database/Utils/DatabaseMigrator.cs | 2 +- .../Models/Patch/SystemConfigPatch.cs | 6 ++--- PluralKit.Core/Models/SystemConfig.cs | 13 +++++++-- docs/content/command-list.md | 2 +- docs/content/user-guide.md | 9 +++++++ 11 files changed, 76 insertions(+), 19 deletions(-) create mode 100644 PluralKit.Core/Database/Migrations/50.sql diff --git a/PluralKit.Bot/CommandMeta/CommandHelp.cs b/PluralKit.Bot/CommandMeta/CommandHelp.cs index 56b545a3..157b7edb 100644 --- a/PluralKit.Bot/CommandMeta/CommandHelp.cs +++ b/PluralKit.Bot/CommandMeta/CommandHelp.cs @@ -30,7 +30,7 @@ public partial class CommandTree public static Command ConfigShowPrivate = new Command("config show private", "config show private [on|off]", "Sets whether private information is shown to linked accounts by default"); public static Command ConfigMemberDefaultPrivacy = new("config private member", "config private member [on|off]", "Sets whether member privacy is automatically set to private when creating a new member"); public static Command ConfigGroupDefaultPrivacy = new("config private group", "config private group [on|off]", "Sets whether group privacy is automatically set to private when creating a new group"); - public static Command ConfigProxySwitch = new Command("config proxyswitch", "config proxyswitch [on|off]", "Sets whether to log a switch every time a proxy tag is used"); + public static Command ConfigProxySwitch = new Command("config proxyswitch", "config proxyswitch [new|add|off]", "Switching behavior when proxy tags are used"); public static Command ConfigNameFormat = new Command("config nameformat", "config nameformat [format]", "Changes your system's username formatting"); public static Command ConfigServerNameFormat = new Command("config servernameformat", "config servernameformat [format]", "Changes your system's username formatting in the current server"); public static Command AutoproxySet = new Command("autoproxy", "autoproxy [off|front|latch|member]", "Sets your system's autoproxy mode for the current server"); diff --git a/PluralKit.Bot/Commands/Config.cs b/PluralKit.Bot/Commands/Config.cs index a6783fb7..00da3a52 100644 --- a/PluralKit.Bot/Commands/Config.cs +++ b/PluralKit.Bot/Commands/Config.cs @@ -125,9 +125,9 @@ public class Config items.Add(new( "Proxy Switch", - "Whether using a proxy tag logs a switch", - EnabledDisabled(ctx.Config.ProxySwitch), - "disabled" + "Switching behavior when proxy tags are used", + ctx.Config.ProxySwitch.ToUserString(), + "off" )); items.Add(new( @@ -574,14 +574,29 @@ public class Config { if (!ctx.HasNext()) { - var msg = $"Logging a switch every time a proxy tag is used is currently **{EnabledDisabled(ctx.Config.ProxySwitch)}**."; + string msg = ctx.Config.ProxySwitch switch + { + SystemConfig.ProxySwitchAction.Off => "Currently, when you proxy as a member, no switches are logged or changed.", + SystemConfig.ProxySwitchAction.New => "When you proxy as a member, currently it makes a new switch.", + SystemConfig.ProxySwitchAction.Add => "When you proxy as a member, currently it adds them to the current switch.", + _ => throw new Exception("unreachable"), + }; await ctx.Reply(msg); return; } - var newVal = ctx.MatchToggle(false); + // toggle = false means off, toggle = true means new, otherwise if they said add that means add or if they said new they mean new. If none of those, error + var toggle = ctx.MatchToggleOrNull(false); + var newVal = toggle == false ? SystemConfig.ProxySwitchAction.Off : toggle == true ? SystemConfig.ProxySwitchAction.New : ctx.Match("add", "a") ? SystemConfig.ProxySwitchAction.Add : ctx.Match("new", "n") ? SystemConfig.ProxySwitchAction.New : throw new PKError("You must pass either \"new\", \"add\", or \"off\" to this command."); + await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { ProxySwitch = newVal }); - await ctx.Reply($"Logging a switch every time a proxy tag is used is now {EnabledDisabled(newVal)}."); + switch (newVal) + { + case SystemConfig.ProxySwitchAction.Off: await ctx.Reply("Now when you proxy as a member, no switches are logged or changed."); break; + case SystemConfig.ProxySwitchAction.New: await ctx.Reply("When you proxy as a member, it now makes a new switch."); break; + case SystemConfig.ProxySwitchAction.Add: await ctx.Reply("When you proxy as a member, it now adds them to the current switch."); break; + default: throw new Exception("unreachable"); + } } public async Task NameFormat(Context ctx) diff --git a/PluralKit.Bot/Proxy/ProxyService.cs b/PluralKit.Bot/Proxy/ProxyService.cs index ebdb0fe3..f7ce4073 100644 --- a/PluralKit.Bot/Proxy/ProxyService.cs +++ b/PluralKit.Bot/Proxy/ProxyService.cs @@ -521,9 +521,22 @@ public class ProxyService Task DispatchWebhook() => _dispatch.Dispatch(ctx.SystemId.Value, sentMessage); - Task MaybeLogSwitch() => (ctx.ProxySwitch && !Array.Exists(ctx.LastSwitchMembers, element => element == match.Member.Id)) - ? _db.Execute(conn => _repo.AddSwitch(conn, (SystemId)ctx.SystemId, new[] { match.Member.Id })) - : Task.CompletedTask; + async Task MaybeLogSwitch() + { + if (ctx.ProxySwitch == SystemConfig.ProxySwitchAction.New && !Array.Exists(ctx.LastSwitchMembers, element => element == match.Member.Id)) + await _db.Execute(conn => _repo.AddSwitch(conn, (SystemId)ctx.SystemId, new[] { match.Member.Id })); + else if (ctx.ProxySwitch == SystemConfig.ProxySwitchAction.Add) + { + if (ctx.LastSwitchMembers.Length == 0) + { + await _db.Execute(conn => _repo.AddSwitch(conn, (SystemId)ctx.SystemId, new[] { match.Member.Id })); + } + else if (!Array.Exists(ctx.LastSwitchMembers, element => element == match.Member.Id)) + { + await _db.Execute(conn => _repo.EditSwitch(conn, (SwitchId)ctx.LastSwitch, ctx.LastSwitchMembers.Append(match.Member.Id).ToList())); + } + } + } async Task DeleteProxyTriggerMessage() { diff --git a/PluralKit.Core/Database/Functions/MessageContext.cs b/PluralKit.Core/Database/Functions/MessageContext.cs index 1d110eeb..ce579522 100644 --- a/PluralKit.Core/Database/Functions/MessageContext.cs +++ b/PluralKit.Core/Database/Functions/MessageContext.cs @@ -34,6 +34,6 @@ public class MessageContext public int? LatchTimeout { get; } public bool CaseSensitiveProxyTags { get; } public bool ProxyErrorMessageEnabled { get; } - public bool ProxySwitch { get; } + public SystemConfig.ProxySwitchAction ProxySwitch { get; } public bool DenyBotUsage { get; } } \ No newline at end of file diff --git a/PluralKit.Core/Database/Functions/functions.sql b/PluralKit.Core/Database/Functions/functions.sql index 29eccbca..895d064d 100644 --- a/PluralKit.Core/Database/Functions/functions.sql +++ b/PluralKit.Core/Database/Functions/functions.sql @@ -9,7 +9,7 @@ create function message_context(account_id bigint, guild_id bigint, channel_id b latch_timeout integer, case_sensitive_proxy_tags bool, proxy_error_message_enabled bool, - proxy_switch bool, + proxy_switch int, name_format text, tag_enabled bool, diff --git a/PluralKit.Core/Database/Migrations/50.sql b/PluralKit.Core/Database/Migrations/50.sql new file mode 100644 index 00000000..335fc132 --- /dev/null +++ b/PluralKit.Core/Database/Migrations/50.sql @@ -0,0 +1,11 @@ +-- database version 50 +-- change proxy switch config to an enum + +alter table system_config + alter column proxy_switch drop default, + alter column proxy_switch type int + using case when proxy_switch then 1 else 0 end, + alter column proxy_switch set default 0, + add constraint proxy_switch_check check (proxy_switch = ANY (ARRAY[0,1,2])); + +update info set schema_version = 50; \ No newline at end of file diff --git a/PluralKit.Core/Database/Utils/DatabaseMigrator.cs b/PluralKit.Core/Database/Utils/DatabaseMigrator.cs index 4e212d46..6db95ae5 100644 --- a/PluralKit.Core/Database/Utils/DatabaseMigrator.cs +++ b/PluralKit.Core/Database/Utils/DatabaseMigrator.cs @@ -9,7 +9,7 @@ namespace PluralKit.Core; internal class DatabaseMigrator { private const string RootPath = "PluralKit.Core.Database"; // "resource path" root for SQL files - private const int TargetSchemaVersion = 49; + private const int TargetSchemaVersion = 50; private readonly ILogger _logger; public DatabaseMigrator(ILogger logger) diff --git a/PluralKit.Core/Models/Patch/SystemConfigPatch.cs b/PluralKit.Core/Models/Patch/SystemConfigPatch.cs index b8f4d27a..eb0c9ff3 100644 --- a/PluralKit.Core/Models/Patch/SystemConfigPatch.cs +++ b/PluralKit.Core/Models/Patch/SystemConfigPatch.cs @@ -23,7 +23,7 @@ public class SystemConfigPatch: PatchObject public Partial HidDisplayCaps { get; set; } public Partial NameFormat { get; set; } public Partial HidListPadding { get; set; } - public Partial ProxySwitch { get; set; } + public Partial ProxySwitch { get; set; } public override Query Apply(Query q) => q.ApplyPatch(wrapper => wrapper .With("ui_tz", UiTz) @@ -107,7 +107,7 @@ public class SystemConfigPatch: PatchObject o.Add("hid_list_padding", HidListPadding.Value.ToUserString()); if (ProxySwitch.IsPresent) - o.Add("proxy_switch", ProxySwitch.Value); + o.Add("proxy_switch", ProxySwitch.Value.ToUserString()); if (NameFormat.IsPresent) o.Add("name_format", NameFormat.Value); @@ -150,7 +150,7 @@ public class SystemConfigPatch: PatchObject patch.HidDisplayCaps = o.Value("hid_display_caps"); if (o.ContainsKey("proxy_switch")) - patch.ProxySwitch = o.Value("proxy_switch"); + patch.ProxySwitch = o.Value("proxy_switch"); if (o.ContainsKey("name_format")) patch.NameFormat = o.Value("name_format"); diff --git a/PluralKit.Core/Models/SystemConfig.cs b/PluralKit.Core/Models/SystemConfig.cs index 2f8fc4cb..b4148211 100644 --- a/PluralKit.Core/Models/SystemConfig.cs +++ b/PluralKit.Core/Models/SystemConfig.cs @@ -24,7 +24,7 @@ public class SystemConfig public bool HidDisplaySplit { get; } public bool HidDisplayCaps { get; } public HidPadFormat HidListPadding { get; } - public bool ProxySwitch { get; } + public ProxySwitchAction ProxySwitch { get; } public string NameFormat { get; } public enum HidPadFormat @@ -33,6 +33,12 @@ public class SystemConfig Left = 1, Right = 2, } + public enum ProxySwitchAction + { + Off = 0, + New = 1, + Add = 2, + } } public static class SystemConfigExt @@ -54,7 +60,7 @@ public static class SystemConfigExt o.Add("hid_display_split", cfg.HidDisplaySplit); o.Add("hid_display_caps", cfg.HidDisplayCaps); o.Add("hid_list_padding", cfg.HidListPadding.ToUserString()); - o.Add("proxy_switch", cfg.ProxySwitch); + o.Add("proxy_switch", cfg.ProxySwitch.ToUserString()); o.Add("name_format", cfg.NameFormat); o.Add("description_templates", JArray.FromObject(cfg.DescriptionTemplates)); @@ -67,4 +73,7 @@ public static class SystemConfigExt if (val == SystemConfig.HidPadFormat.None) return "off"; return val.ToString().ToLower(); } + + public static string ToUserString(this SystemConfig.ProxySwitchAction val) => val.ToString().ToLower(); + } \ No newline at end of file diff --git a/docs/content/command-list.md b/docs/content/command-list.md index b89d6312..fffd9073 100644 --- a/docs/content/command-list.md +++ b/docs/content/command-list.md @@ -148,7 +148,7 @@ You can have a space after `pk;`, e.g. `pk;system` and `pk; system` will do the - `pk;config split IDs [on|off]` - Toggles whether to display 6-letter IDs with a hyphen, to ease readability. - `pk;config capitalize IDs [on|off]` - Toggles whether to display IDs as capital letters, to ease readability. - `pk;config pad IDs [left|right|off]` - Toggles whether to pad (add a space) 5-character IDs in lists. -- `pk;config proxy switch [on|off]` - Toggles whether to log a switch whenever you proxy as a different member. +- `pk;config proxy switch [new|add|off]` - Toggles whether to log a switch whenever you proxy as a different member (or add member to recent switch in add mode). - `pk;config name format [format]` - Changes your system's username formatting. - `pk;config server name format [format]` - Changes your system's username formatting for the current server. diff --git a/docs/content/user-guide.md b/docs/content/user-guide.md index cdf55ae2..ad86343b 100644 --- a/docs/content/user-guide.md +++ b/docs/content/user-guide.md @@ -552,6 +552,15 @@ To log a switch, use the `pk;switch` command with one or more members. For examp Note that the order of members are preserved (this is useful for indicating who's "more" at front, if applicable). If you want to specify a member with multiple words in their name, remember to encase the name in "double quotes". +### Automatic Switching +If you want PluralKit to automatically log a new switch whenever you [proxy](/guide/#proxying), you can tell it do so using the following command: + + pk;config proxy switch new + +Alternatively, if you want PluralKit to *add* the proxied member to the current switch instead of logging a new one, you can use this command: + + pk;config proxy switch add + ### Switching out If you want to log a switch with *no* members, you can log a switch-out as follows: