Add group and system colors
This commit is contained in:
		
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -17,4 +17,5 @@ pluralkit.*.conf | ||||
| *.DotSettings.user | ||||
|  | ||||
| # Generated | ||||
| logs/ | ||||
| logs/ | ||||
| *.dll | ||||
|   | ||||
| @@ -13,6 +13,7 @@ namespace PluralKit.Bot | ||||
|         public static Command SystemNew = new Command("system new", "system new [name]", "Creates a new system"); | ||||
|         public static Command SystemRename = new Command("system name", "system rename [name]", "Renames your system"); | ||||
|         public static Command SystemDesc = new Command("system description", "system description [description]", "Changes your system's description"); | ||||
|         public static Command SystemColor = new Command("system color", "system color [color]", "Changes your system's color"); | ||||
|         public static Command SystemTag = new Command("system tag", "system tag [tag]", "Changes your system's tag"); | ||||
|         public static Command SystemAvatar = new Command("system icon", "system icon [url|@mention]", "Changes your system's icon"); | ||||
|         public static Command SystemDelete = new Command("system delete", "system delete", "Deletes your system"); | ||||
| @@ -55,6 +56,7 @@ namespace PluralKit.Bot | ||||
|         public static Command GroupRename = new Command("group rename", "group <group> rename <new name>", "Renames a group"); | ||||
|         public static Command GroupDisplayName = new Command("group displayname", "group <group> displayname [display name]", "Changes a group's display name"); | ||||
|         public static Command GroupDesc = new Command("group description", "group <group> description [description]", "Changes a group's description"); | ||||
|         public static Command GroupColor = new Command("group color", "group <group> color [color]", "Changes a group's color"); | ||||
|         public static Command GroupAdd = new Command("group add", "group <group> add <member> [member 2] [member 3...]", "Adds one or more members to a group"); | ||||
|         public static Command GroupRemove = new Command("group remove", "group <group> remove <member> [member 2] [member 3...]", "Removes one or more members from a group"); | ||||
|         public static Command GroupPrivacy = new Command("group privacy", "group <group> privacy <description|icon|visibility|all> <public|private>", "Changes a group's privacy settings"); | ||||
| @@ -89,7 +91,7 @@ namespace PluralKit.Bot | ||||
|         public static Command PermCheck = new Command("permcheck", "permcheck <guild>", "Checks whether a server's permission setup is correct"); | ||||
|  | ||||
|         public static Command[] SystemCommands = { | ||||
|             SystemInfo, SystemNew, SystemRename, SystemTag, SystemDesc, SystemAvatar, SystemDelete, SystemTimezone, | ||||
|             SystemInfo, SystemNew, SystemRename, SystemTag, SystemDesc, SystemAvatar, SystemColor, SystemDelete, SystemTimezone, | ||||
|             SystemList, SystemFronter, SystemFrontHistory, SystemFrontPercent, SystemPrivacy, SystemProxy | ||||
|         }; | ||||
|  | ||||
| @@ -102,7 +104,7 @@ namespace PluralKit.Bot | ||||
|         public static Command[] GroupCommands = | ||||
|         { | ||||
|             GroupInfo, GroupList, GroupNew, GroupAdd, GroupRemove, GroupMemberList, GroupRename, GroupDesc, | ||||
|             GroupIcon, GroupPrivacy, GroupDelete | ||||
|             GroupIcon, GroupColor, GroupPrivacy, GroupDelete | ||||
|         }; | ||||
|  | ||||
|         public static Command[] GroupCommandsTargeted = | ||||
| @@ -218,6 +220,8 @@ namespace PluralKit.Bot | ||||
|                 await ctx.Execute<SystemEdit>(SystemTag, m => m.Tag(ctx)); | ||||
|             else if (ctx.Match("description", "desc", "bio")) | ||||
|                 await ctx.Execute<SystemEdit>(SystemDesc, m => m.Description(ctx)); | ||||
|             else if (ctx.Match("color", "colour")) | ||||
|                 await ctx.Execute<SystemEdit>(SystemColor, m => m.Color(ctx)); | ||||
|             else if (ctx.Match("avatar", "picture", "icon", "image", "pic", "pfp")) | ||||
|                 await ctx.Execute<SystemEdit>(SystemAvatar, m => m.Avatar(ctx)); | ||||
|             else if (ctx.Match("delete", "remove", "destroy", "erase", "yeet")) | ||||
| @@ -398,6 +402,8 @@ namespace PluralKit.Bot | ||||
|                     await ctx.Execute<Groups>(GroupDelete, g => g.DeleteGroup(ctx, target)); | ||||
|                 else if (ctx.Match("avatar", "picture", "icon", "image", "pic", "pfp")) | ||||
|                     await ctx.Execute<Groups>(GroupIcon, g => g.GroupIcon(ctx, target)); | ||||
|                 else if (ctx.Match("color", "colour")) | ||||
|                     await ctx.Execute<Groups>(GroupColor, g => g.GroupColor(ctx, target)); | ||||
|                 else if (ctx.Match("fp", "frontpercent", "front%", "frontbreakdown")) | ||||
|                     await ctx.Execute<Groups>(GroupFrontPercent, g => g.GroupFrontPercent(ctx, target)); | ||||
|                 else if (!ctx.HasNext()) | ||||
|   | ||||
| @@ -2,6 +2,7 @@ using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Text.RegularExpressions; | ||||
| using System.Threading.Tasks; | ||||
|  | ||||
| using Dapper; | ||||
| @@ -226,6 +227,53 @@ namespace PluralKit.Bot | ||||
|             else | ||||
|                 await ShowIcon(); | ||||
|         } | ||||
|         public async Task GroupColor(Context ctx, PKGroup target) | ||||
|         { | ||||
|             var color = ctx.RemainderOrNull(); | ||||
|             if (await ctx.MatchClear()) | ||||
|             { | ||||
|                 ctx.CheckOwnGroup(target); | ||||
|                  | ||||
|                 var patch = new GroupPatch {Color = Partial<string>.Null()}; | ||||
|                 await _db.Execute(conn => _repo.UpdateGroup(conn, target.Id, patch)); | ||||
|                  | ||||
|                 await ctx.Reply($"{Emojis.Success} Group color cleared."); | ||||
|             } | ||||
|             else if (!ctx.HasNext()) | ||||
|             { | ||||
|  | ||||
|                 if (target.Color == null) | ||||
|                     if (ctx.System?.Id == target.System) | ||||
|                         await ctx.Reply( | ||||
|                             $"This group does not have a color set. To set one, type `pk;group {target.Reference()} color <color>`."); | ||||
|                     else | ||||
|                         await ctx.Reply("This group does not have a color set."); | ||||
|                 else | ||||
|                     await ctx.Reply(embed: new EmbedBuilder() | ||||
|                         .Title("Group color") | ||||
|                         .Color(target.Color.ToDiscordColor()) | ||||
|                         .Thumbnail(new($"https://fakeimg.pl/256x256/{target.Color}/?text=%20")) | ||||
|                         .Description($"This group's color is **#{target.Color}**." | ||||
|                                          + (ctx.System?.Id == target.System ? $" To clear it, type `pk;group {target.Reference()} color -clear`." : "")) | ||||
|                         .Build()); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 ctx.CheckOwnGroup(target); | ||||
|  | ||||
|                 if (color.StartsWith("#")) color = color.Substring(1); | ||||
|                 if (!Regex.IsMatch(color, "^[0-9a-fA-F]{6}$")) throw Errors.InvalidColorError(color); | ||||
|                  | ||||
|                 var patch = new GroupPatch {Color = Partial<string>.Present(color.ToLowerInvariant())}; | ||||
|                 await _db.Execute(conn => _repo.UpdateGroup(conn, target.Id, patch)); | ||||
|  | ||||
|                 await ctx.Reply(embed: new EmbedBuilder() | ||||
|                     .Title($"{Emojis.Success} Group color changed.") | ||||
|                     .Color(color.ToDiscordColor()) | ||||
|                     .Thumbnail(new($"https://fakeimg.pl/256x256/{color}/?text=%20")) | ||||
|                     .Build()); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public async Task ListSystemGroups(Context ctx, PKSystem system) | ||||
|         { | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| using System; | ||||
| using System.Linq; | ||||
| using System.Text.RegularExpressions; | ||||
| using System.Threading.Tasks; | ||||
|  | ||||
| using Myriad.Builders; | ||||
| @@ -91,6 +92,47 @@ namespace PluralKit.Bot | ||||
|                 await ctx.Reply($"{Emojis.Success} System description changed."); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public async Task Color(Context ctx) { | ||||
|             ctx.CheckSystem(); | ||||
|  | ||||
|             if (await ctx.MatchClear()) | ||||
|             { | ||||
|                 var patch = new SystemPatch {Color = Partial<string>.Null()}; | ||||
|                 await _db.Execute(conn => _repo.UpdateSystem(conn, ctx.System.Id, patch)); | ||||
|  | ||||
|                 await ctx.Reply($"{Emojis.Success} System color cleared."); | ||||
|             } | ||||
|             else if (!ctx.HasNext())  | ||||
|             { | ||||
|                 if (ctx.System.Color == null)  | ||||
|                     await ctx.Reply( | ||||
|                             $"Your system does not have a color set. To set one, type `pk;system color <color>`."); | ||||
|                 else | ||||
|                     await ctx.Reply(embed: new EmbedBuilder() | ||||
|                         .Title("System color") | ||||
|                         .Color(ctx.System.Color.ToDiscordColor()) | ||||
|                         .Thumbnail(new($"https://fakeimg.pl/256x256/{ctx.System.Color}/?text=%20")) | ||||
|                         .Description($"Your system's color is **#{ctx.System.Color}**. To clear it, type `pk;s color -clear`.") | ||||
|                         .Build()); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 var color = ctx.RemainderOrNull(); | ||||
|  | ||||
|                 if (color.StartsWith("#")) color = color.Substring(1); | ||||
|                 if (!Regex.IsMatch(color, "^[0-9a-fA-F]{6}$")) throw Errors.InvalidColorError(color); | ||||
|  | ||||
|                 var patch = new SystemPatch {Color = Partial<string>.Present(color.ToLowerInvariant())}; | ||||
|                 await _db.Execute(conn => _repo.UpdateSystem(conn, ctx.System.Id, patch)); | ||||
|  | ||||
|                 await ctx.Reply(embed: new EmbedBuilder() | ||||
|                     .Title($"{Emojis.Success} Member color changed.") | ||||
|                     .Color(color.ToDiscordColor()) | ||||
|                     .Thumbnail(new($"https://fakeimg.pl/256x256/{color}/?text=%20")) | ||||
|                     .Build()); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         public async Task Tag(Context ctx) | ||||
|         { | ||||
|   | ||||
| @@ -53,11 +53,22 @@ namespace PluralKit.Bot { | ||||
|  | ||||
|             var memberCount = cctx.MatchPrivateFlag(ctx) ? await _repo.GetSystemMemberCount(conn, system.Id, PrivacyLevel.Public) : await _repo.GetSystemMemberCount(conn, system.Id); | ||||
|  | ||||
|             uint color; | ||||
|             try | ||||
|             { | ||||
|                 color = system.Color?.ToDiscordColor() ?? DiscordUtils.Gray; | ||||
|             } | ||||
|             catch (ArgumentException) | ||||
|             { | ||||
|                 // There's no API for system colors yet, but defaulting to a blank color in advance can't be a bad idea | ||||
|                 color = DiscordUtils.Gray; | ||||
|             } | ||||
|  | ||||
|             var eb = new EmbedBuilder() | ||||
|                 .Title(system.Name) | ||||
|                 .Thumbnail(new(system.AvatarUrl)) | ||||
|                 .Footer(new($"System ID: {system.Hid} | Created on {system.Created.FormatZoned(system)}")) | ||||
|                 .Color(DiscordUtils.Gray); | ||||
|                 .Color(color); | ||||
|  | ||||
|             var latestSwitch = await _repo.GetLatestSwitch(conn, system.Id); | ||||
|             if (latestSwitch != null && system.FrontPrivacy.CanAccess(ctx)) | ||||
| @@ -187,8 +198,20 @@ namespace PluralKit.Bot { | ||||
|             if (system.Name != null) | ||||
|                 nameField = $"{nameField} ({system.Name})"; | ||||
|  | ||||
|             uint color; | ||||
|             try | ||||
|             { | ||||
|                 color = target.Color?.ToDiscordColor() ?? DiscordUtils.Gray; | ||||
|             } | ||||
|             catch (ArgumentException) | ||||
|             { | ||||
|                 // There's no API for group colors yet, but defaulting to a blank color regardless | ||||
|                 color = DiscordUtils.Gray; | ||||
|             } | ||||
|  | ||||
|             var eb = new EmbedBuilder() | ||||
|                 .Author(new(nameField, IconUrl: DiscordUtils.WorkaroundForUrlBug(target.IconFor(pctx)))) | ||||
|                 .Color(color) | ||||
|                 .Footer(new($"System ID: {system.Hid} | Group ID: {target.Hid} | Created on {target.Created.FormatZoned(system)}")); | ||||
|  | ||||
|             if (target.DisplayName != null) | ||||
|   | ||||
| @@ -19,7 +19,7 @@ namespace PluralKit.Core | ||||
|     internal class Database: IDatabase | ||||
|     { | ||||
|         private const string RootPath = "PluralKit.Core.Database"; // "resource path" root for SQL files | ||||
|         private const int TargetSchemaVersion = 12; | ||||
|         private const int TargetSchemaVersion = 13; | ||||
|          | ||||
|         private readonly CoreConfig _config; | ||||
|         private readonly ILogger _logger; | ||||
|   | ||||
							
								
								
									
										7
									
								
								PluralKit.Core/Database/Migrations/13.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								PluralKit.Core/Database/Migrations/13.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| -- SCHEMA VERSION 13: 2021-03-28 -- | ||||
| -- Add system and group colors -- | ||||
|  | ||||
| alter table systems add column color char(6); | ||||
| alter table groups add column color char(6); | ||||
|  | ||||
| update info set schema_version = 13; | ||||
| @@ -13,6 +13,7 @@ namespace PluralKit.Core | ||||
|         public string? DisplayName { get; private set; } | ||||
|         public string? Description { get; private set; } | ||||
|         public string? Icon { get; private set; } | ||||
|         public string? Color { get; private set; } | ||||
|  | ||||
|         public PrivacyLevel DescriptionPrivacy { get; private set; } | ||||
|         public PrivacyLevel IconPrivacy { get; private set; } | ||||
|   | ||||
| @@ -14,6 +14,7 @@ namespace PluralKit.Core { | ||||
|         public string Description { get; } | ||||
|         public string Tag { get; } | ||||
|         public string AvatarUrl { get; } | ||||
|         public string Color { get; } | ||||
|         public string Token { get; } | ||||
|         public Instant Created { get; } | ||||
|         public string UiTz { get; set; } | ||||
|   | ||||
| @@ -7,6 +7,7 @@ namespace PluralKit.Core | ||||
|         public Partial<string?> DisplayName { get; set; } | ||||
|         public Partial<string?> Description { get; set; } | ||||
|         public Partial<string?> Icon { get; set; } | ||||
|         public Partial<string?> Color { get; set; } | ||||
|          | ||||
|         public Partial<PrivacyLevel> DescriptionPrivacy { get; set; } | ||||
|         public Partial<PrivacyLevel> IconPrivacy { get; set; } | ||||
| @@ -18,6 +19,7 @@ namespace PluralKit.Core | ||||
|             .With("display_name", DisplayName) | ||||
|             .With("description", Description) | ||||
|             .With("icon", Icon) | ||||
|             .With("color", Color) | ||||
|             .With("description_privacy", DescriptionPrivacy) | ||||
|             .With("icon_privacy", IconPrivacy) | ||||
|             .With("list_privacy", ListPrivacy) | ||||
|   | ||||
| @@ -7,6 +7,7 @@ namespace PluralKit.Core | ||||
|         public Partial<string?> Description { get; set; } | ||||
|         public Partial<string?> Tag { get; set; } | ||||
|         public Partial<string?> AvatarUrl { get; set; } | ||||
|         public Partial<string?> Color { get; set; } | ||||
|         public Partial<string?> Token { get; set; } | ||||
|         public Partial<string> UiTz { get; set; } | ||||
|         public Partial<PrivacyLevel> DescriptionPrivacy { get; set; } | ||||
| @@ -22,6 +23,7 @@ namespace PluralKit.Core | ||||
|             .With("description", Description) | ||||
|             .With("tag", Tag) | ||||
|             .With("avatar_url", AvatarUrl) | ||||
|             .With("color", Color) | ||||
|             .With("token", Token) | ||||
|             .With("ui_tz", UiTz) | ||||
|             .With("description_privacy", DescriptionPrivacy) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user