diff --git a/PluralKit.Bot/CommandMeta/CommandHelp.cs b/PluralKit.Bot/CommandMeta/CommandHelp.cs index 5d3dc30e..843e2e1d 100644 --- a/PluralKit.Bot/CommandMeta/CommandHelp.cs +++ b/PluralKit.Bot/CommandMeta/CommandHelp.cs @@ -82,6 +82,7 @@ public partial class CommandTree public static Command SwitchMove = new Command("switch move", "switch move ", "Moves the latest switch in time"); public static Command SwitchEdit = new Command("switch edit", "switch edit [member 2] [member 3...]", "Edits the members in the latest switch"); public static Command SwitchEditOut = new Command("switch edit out", "switch edit out", "Turns the latest switch into a switch-out"); + public static Command SwitchCopy = new Command("switch copy", "switch copy [member 2] [member 3...]", "Makes a new switch with the listed members added"); public static Command SwitchDelete = new Command("switch delete", "switch delete", "Deletes the latest switch"); public static Command SwitchDeleteAll = new Command("switch delete", "switch delete all", "Deletes all logged switches"); public static Command Link = new Command("link", "link ", "Links your system to another account"); @@ -137,7 +138,7 @@ public partial class CommandTree public static Command[] SwitchCommands = { - Switch, SwitchOut, SwitchMove, SwitchEdit, SwitchEditOut, SwitchDelete, SwitchDeleteAll + Switch, SwitchOut, SwitchMove, SwitchEdit, SwitchEditOut, SwitchDelete, SwitchDeleteAll, SwitchCopy }; public static Command[] ConfigCommands = diff --git a/PluralKit.Bot/CommandMeta/CommandTree.cs b/PluralKit.Bot/CommandMeta/CommandTree.cs index 64d0a929..8864436c 100644 --- a/PluralKit.Bot/CommandMeta/CommandTree.cs +++ b/PluralKit.Bot/CommandMeta/CommandTree.cs @@ -430,13 +430,15 @@ public partial class CommandTree await ctx.Execute(SwitchEdit, m => m.SwitchEdit(ctx)); else if (ctx.Match("delete", "remove", "erase", "cancel", "yeet")) await ctx.Execute(SwitchDelete, m => m.SwitchDelete(ctx)); + else if (ctx.Match("copy", "add", "duplicate", "dupe")) + await ctx.Execute(SwitchCopy, m => m.SwitchEdit(ctx, true)); else if (ctx.Match("commands", "help")) await PrintCommandList(ctx, "switching", SwitchCommands); else if (ctx.HasNext()) // there are following arguments await ctx.Execute(Switch, m => m.SwitchDo(ctx)); else await PrintCommandNotFoundError(ctx, Switch, SwitchOut, SwitchMove, SwitchEdit, SwitchEditOut, - SwitchDelete, SystemFronter, SystemFrontHistory); + SwitchDelete, SwitchCopy, SystemFronter, SystemFrontHistory); } private async Task CommandHelpRoot(Context ctx) diff --git a/PluralKit.Bot/Commands/Switch.cs b/PluralKit.Bot/Commands/Switch.cs index 9272d911..d60da3b4 100644 --- a/PluralKit.Bot/Commands/Switch.cs +++ b/PluralKit.Bot/Commands/Switch.cs @@ -7,6 +7,7 @@ namespace PluralKit.Bot; public class Switch { + public async Task SwitchDo(Context ctx) { ctx.CheckSystem(); @@ -103,12 +104,67 @@ public class Switch await ctx.Reply($"{Emojis.Success} Switch moved to ({newSwitchDeltaStr} ago)."); } - public async Task SwitchEdit(Context ctx) + public async Task SwitchEdit(Context ctx, bool newSwitch = false) { ctx.CheckSystem(); - var members = await ctx.ParseMemberList(ctx.System.Id); - await DoEditCommand(ctx, members); + var newMembers = await ctx.ParseMemberList(ctx.System.Id); + + await using var conn = await ctx.Database.Obtain(); + var currentSwitch = await ctx.Repository.GetLatestSwitch(ctx.System.Id); + var currentSwitchMembers = await ctx.Repository.GetSwitchMembers(conn, currentSwitch.Id).ToListAsync().AsTask(); + + if (ctx.MatchFlag("first", "f")) + newMembers = FirstInSwitch(newMembers[0], currentSwitchMembers); + else if (ctx.MatchFlag("remove", "r")) + newMembers = RemoveFromSwitch(newMembers, currentSwitchMembers); + else if (ctx.MatchFlag("append", "a")) + newMembers = AppendToSwitch(newMembers, currentSwitchMembers); + else if (ctx.MatchFlag("prepend", "p")) + newMembers = PrependToSwitch(newMembers, currentSwitchMembers); + + if (newSwitch) + { + // if there's no edit flag, assume we're appending + if (!ctx.MatchFlag("first", "f", "remove", "r", "append", "a", "prepend", "p")) + newMembers = AppendToSwitch(newMembers, currentSwitchMembers); + await DoSwitchCommand(ctx, newMembers); + } + else + await DoEditCommand(ctx, newMembers); + } + + public List PrependToSwitch(List members, List currentSwitchMembers) + { + members.AddRange(currentSwitchMembers); + + return members; + } + + public List AppendToSwitch(List members, List currentSwitchMembers) + { + currentSwitchMembers.AddRange(members); + members = currentSwitchMembers; + + return members; + } + + public List RemoveFromSwitch(List members, List currentSwitchMembers) + { + var memberIds = members.Select(m => m.Id.Value); + currentSwitchMembers = currentSwitchMembers.Where(m => !memberIds.Contains(m.Id.Value)).ToList(); + members = currentSwitchMembers; + + return members; + } + + public List FirstInSwitch(PKMember member, List currentSwitchMembers) + { + currentSwitchMembers = currentSwitchMembers.Where(m => m.Id != member.Id).ToList(); + var members = new List { member }; + members.AddRange(currentSwitchMembers); + + return members; } public async Task SwitchEditOut(Context ctx) diff --git a/docs/content/command-list.md b/docs/content/command-list.md index 0df96f73..610b8858 100644 --- a/docs/content/command-list.md +++ b/docs/content/command-list.md @@ -123,7 +123,8 @@ You can have a space after `pk;`, e.g. `pk;system` and `pk; system` will do the ## Switching commands - `pk;switch [member...]` - Registers a switch with the given members. - `pk;switch out` - Registers a 'switch-out' - a switch with no associated members. -- `pk;switch edit ` - Edits the members in the latest switch. +- `pk;switch edit ` - Edits the members in the latest switch. +- `pk;switch add ` - Makes a new switch based off the current switch with the listed members added or removed. - `pk;switch move