Add banner (large) image
This commit is contained in:
@@ -16,6 +16,7 @@ namespace PluralKit.Bot
|
||||
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 SystemBannerImage = new Command("system banner", "system banner [url]", "Set the system's banner image");
|
||||
public static Command SystemDelete = new Command("system delete", "system delete", "Deletes your system");
|
||||
public static Command SystemTimezone = new Command("system timezone", "system timezone [timezone]", "Changes your system's time zone");
|
||||
public static Command SystemProxy = new Command("system proxy", "system proxy [server id] [on|off]", "Enables or disables message proxying in a specific server");
|
||||
@@ -38,6 +39,7 @@ namespace PluralKit.Bot
|
||||
public static Command MemberBirthday = new Command("member birthday", "member <member> birthday [birthday]", "Changes a member's birthday");
|
||||
public static Command MemberProxy = new Command("member proxy", "member <member> proxy [add|remove] [example proxy]", "Changes, adds, or removes a member's proxy tags");
|
||||
public static Command MemberDelete = new Command("member delete", "member <member> delete", "Deletes a member");
|
||||
public static Command MemberBannerImage = new Command("member banner", "member <member> banner [url]", "Set the member's banner image");
|
||||
public static Command MemberAvatar = new Command("member avatar", "member <member> avatar [url|@mention]", "Changes a member's avatar");
|
||||
public static Command MemberGroups = new Command("member group", "member <member> group", "Shows the groups a member is in");
|
||||
public static Command MemberGroupAdd = new Command("member group", "member <member> group add <group> [group 2] [group 3...]", "Adds a member to one or more groups");
|
||||
@@ -60,6 +62,7 @@ namespace PluralKit.Bot
|
||||
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");
|
||||
public static Command GroupBannerImage = new Command("group banner", "group <group> banner [url]", "Set the group's banner image");
|
||||
public static Command GroupIcon = new Command("group icon", "group <group> icon [url|@mention]", "Changes a group's icon");
|
||||
public static Command GroupDelete = new Command("group delete", "group <group> delete", "Deletes a group");
|
||||
public static Command GroupFrontPercent = new Command("group frontpercent", "group <group> frontpercent [timespan]", "Shows a group's front breakdown.");
|
||||
@@ -93,20 +96,20 @@ namespace PluralKit.Bot
|
||||
public static Command Admin = new Command("admin", "admin", "Super secret admin commands (sshhhh)");
|
||||
|
||||
public static Command[] SystemCommands = {
|
||||
SystemInfo, SystemNew, SystemRename, SystemTag, SystemDesc, SystemAvatar, SystemColor, SystemDelete, SystemTimezone,
|
||||
SystemList, SystemFronter, SystemFrontHistory, SystemFrontPercent, SystemPrivacy, SystemProxy
|
||||
SystemInfo, SystemNew, SystemRename, SystemTag, SystemDesc, SystemAvatar, SystemBannerImage, SystemColor, SystemDelete,
|
||||
SystemTimezone, SystemList, SystemFronter, SystemFrontHistory, SystemFrontPercent, SystemPrivacy, SystemProxy
|
||||
};
|
||||
|
||||
public static Command[] MemberCommands = {
|
||||
MemberInfo, MemberNew, MemberRename, MemberDisplayName, MemberServerName, MemberDesc, MemberPronouns,
|
||||
MemberColor, MemberBirthday, MemberProxy, MemberAutoproxy, MemberKeepProxy, MemberGroups, MemberGroupAdd, MemberGroupRemove,
|
||||
MemberDelete, MemberAvatar, MemberServerAvatar, MemberPrivacy, MemberRandom
|
||||
MemberDelete, MemberAvatar, MemberServerAvatar, MemberBannerImage, MemberPrivacy, MemberRandom
|
||||
};
|
||||
|
||||
public static Command[] GroupCommands =
|
||||
{
|
||||
GroupInfo, GroupList, GroupNew, GroupAdd, GroupRemove, GroupMemberList, GroupRename, GroupDesc,
|
||||
GroupIcon, GroupColor, GroupPrivacy, GroupDelete
|
||||
GroupIcon, GroupBannerImage, GroupColor, GroupPrivacy, GroupDelete
|
||||
};
|
||||
|
||||
public static Command[] GroupCommandsTargeted =
|
||||
@@ -244,6 +247,8 @@ namespace PluralKit.Bot
|
||||
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("banner", "splash", "cover"))
|
||||
await ctx.Execute<SystemEdit>(SystemBannerImage, m => m.BannerImage(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"))
|
||||
@@ -355,6 +360,8 @@ namespace PluralKit.Bot
|
||||
await ctx.Execute<MemberEdit>(MemberDelete, m => m.Delete(ctx, target));
|
||||
else if (ctx.Match("avatar", "profile", "picture", "icon", "image", "pfp", "pic"))
|
||||
await ctx.Execute<MemberAvatar>(MemberAvatar, m => m.Avatar(ctx, target));
|
||||
else if (ctx.Match("banner", "splash", "cover"))
|
||||
await ctx.Execute<MemberEdit>(MemberBannerImage, m => m.BannerImage(ctx, target));
|
||||
else if (ctx.Match("group", "groups"))
|
||||
if (ctx.Match("add", "a"))
|
||||
await ctx.Execute<MemberGroup>(MemberGroupAdd, m => m.AddRemove(ctx, target, Groups.AddRemoveOperation.Add));
|
||||
@@ -422,6 +429,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("banner", "splash", "cover"))
|
||||
await ctx.Execute<Groups>(GroupBannerImage, g => g.GroupBannerImage(ctx, target));
|
||||
else if (ctx.Match("fp", "frontpercent", "front%", "frontbreakdown"))
|
||||
await ctx.Execute<Groups>(GroupFrontPercent, g => g.GroupFrontPercent(ctx, target));
|
||||
else if (ctx.Match("color", "colour"))
|
||||
|
@@ -247,6 +247,69 @@ namespace PluralKit.Bot
|
||||
else
|
||||
await ShowIcon();
|
||||
}
|
||||
|
||||
public async Task GroupBannerImage(Context ctx, PKGroup target)
|
||||
{
|
||||
async Task ClearBannerImage()
|
||||
{
|
||||
ctx.CheckOwnGroup(target);
|
||||
|
||||
await _db.Execute(c => _repo.UpdateGroup(c, target.Id, new GroupPatch {BannerImage = null}));
|
||||
await ctx.Reply($"{Emojis.Success} Group banner image cleared.");
|
||||
}
|
||||
|
||||
async Task SetBannerImage(ParsedImage img)
|
||||
{
|
||||
ctx.CheckOwnGroup(target);
|
||||
|
||||
await AvatarUtils.VerifyAvatarOrThrow(img.Url, isFullSizeImage: true);
|
||||
|
||||
await _db.Execute(c => _repo.UpdateGroup(c, target.Id, new GroupPatch {BannerImage = img.Url}));
|
||||
|
||||
var msg = img.Source switch
|
||||
{
|
||||
AvatarSource.Url => $"{Emojis.Success} Group banner image changed to the image at the given URL.",
|
||||
AvatarSource.Attachment => $"{Emojis.Success} Group banner image changed to attached image.\n{Emojis.Warn} If you delete the message containing the attachment, the banner image will stop working.",
|
||||
AvatarSource.User => throw new PKError("Cannot set a banner image to an user's avatar."),
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
|
||||
// The attachment's already right there, no need to preview it.
|
||||
var hasEmbed = img.Source != AvatarSource.Attachment;
|
||||
await (hasEmbed
|
||||
? ctx.Reply(msg, embed: new EmbedBuilder().Image(new(img.Url)).Build())
|
||||
: ctx.Reply(msg));
|
||||
}
|
||||
|
||||
async Task ShowBannerImage()
|
||||
{
|
||||
if (!target.DescriptionPrivacy.CanAccess(ctx.LookupContextFor(target.System)))
|
||||
throw Errors.LookupNotAllowed;
|
||||
if ((target.BannerImage?.Trim() ?? "").Length > 0)
|
||||
{
|
||||
var eb = new EmbedBuilder()
|
||||
.Title("Group banner image")
|
||||
.Image(new(target.BannerImage));
|
||||
|
||||
if (target.System == ctx.System?.Id)
|
||||
{
|
||||
eb.Description($"To clear, use `pk;group {target.Reference()} banner clear`.");
|
||||
}
|
||||
|
||||
await ctx.Reply(embed: eb.Build());
|
||||
}
|
||||
else
|
||||
throw new PKSyntaxError("This group does not have a banner image set. Set one by attaching an image to this command, or by passing an image URL or @mention.");
|
||||
}
|
||||
|
||||
if (await ctx.MatchClear("this group's banner image"))
|
||||
await ClearBannerImage();
|
||||
else if (await ctx.MatchImage() is {} img)
|
||||
await SetBannerImage(img);
|
||||
else
|
||||
await ShowBannerImage();
|
||||
}
|
||||
|
||||
public async Task GroupColor(Context ctx, PKGroup target)
|
||||
{
|
||||
var color = ctx.RemainderOrNull();
|
||||
|
@@ -136,6 +136,59 @@ namespace PluralKit.Bot
|
||||
}
|
||||
}
|
||||
|
||||
public async Task BannerImage(Context ctx, PKMember target)
|
||||
{
|
||||
ctx.CheckOwnMember(target);
|
||||
|
||||
async Task ClearBannerImage()
|
||||
{
|
||||
await _db.Execute(c => _repo.UpdateMember(c, target.Id, new MemberPatch {BannerImage = null}));
|
||||
await ctx.Reply($"{Emojis.Success} Member banner image cleared.");
|
||||
}
|
||||
|
||||
async Task SetBannerImage(ParsedImage img)
|
||||
{
|
||||
await AvatarUtils.VerifyAvatarOrThrow(img.Url, isFullSizeImage: true);
|
||||
|
||||
await _db.Execute(c => _repo.UpdateMember(c, target.Id, new MemberPatch {BannerImage = img.Url}));
|
||||
|
||||
var msg = img.Source switch
|
||||
{
|
||||
AvatarSource.Url => $"{Emojis.Success} Member banner image changed to the image at the given URL.",
|
||||
AvatarSource.Attachment => $"{Emojis.Success} Member banner image changed to attached image.\n{Emojis.Warn} If you delete the message containing the attachment, the banner image will stop working.",
|
||||
AvatarSource.User => throw new PKError("Cannot set a banner image to an user's avatar."),
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
|
||||
// The attachment's already right there, no need to preview it.
|
||||
var hasEmbed = img.Source != AvatarSource.Attachment;
|
||||
await (hasEmbed
|
||||
? ctx.Reply(msg, embed: new EmbedBuilder().Image(new(img.Url)).Build())
|
||||
: ctx.Reply(msg));
|
||||
}
|
||||
|
||||
async Task ShowBannerImage()
|
||||
{
|
||||
if ((target.BannerImage?.Trim() ?? "").Length > 0)
|
||||
{
|
||||
var eb = new EmbedBuilder()
|
||||
.Title($"{target.NameFor(ctx)}'s banner image")
|
||||
.Image(new(target.BannerImage))
|
||||
.Description($"To clear, use `pk;member {target.Hid} banner clear`.");
|
||||
await ctx.Reply(embed: eb.Build());
|
||||
}
|
||||
else
|
||||
throw new PKSyntaxError("This member does not have a banner image set. Set one by attaching an image to this command, or by passing an image URL or @mention.");
|
||||
}
|
||||
|
||||
if (await ctx.MatchClear("this member's banner image"))
|
||||
await ClearBannerImage();
|
||||
else if (await ctx.MatchImage() is {} img)
|
||||
await SetBannerImage(img);
|
||||
else
|
||||
await ShowBannerImage();
|
||||
}
|
||||
|
||||
public async Task Color(Context ctx, PKMember target)
|
||||
{
|
||||
var color = ctx.RemainderOrNull();
|
||||
|
@@ -218,7 +218,60 @@ namespace PluralKit.Bot
|
||||
else
|
||||
await ShowIcon();
|
||||
}
|
||||
|
||||
|
||||
public async Task BannerImage(Context ctx)
|
||||
{
|
||||
ctx.CheckSystem();
|
||||
|
||||
async Task ClearImage()
|
||||
{
|
||||
await _db.Execute(c => _repo.UpdateSystem(c, ctx.System.Id, new SystemPatch {BannerImage = null}));
|
||||
await ctx.Reply($"{Emojis.Success} System banner image cleared.");
|
||||
}
|
||||
|
||||
async Task SetImage(ParsedImage img)
|
||||
{
|
||||
await AvatarUtils.VerifyAvatarOrThrow(img.Url, isFullSizeImage: true);
|
||||
|
||||
await _db.Execute(c => _repo.UpdateSystem(c, ctx.System.Id, new SystemPatch {BannerImage = img.Url}));
|
||||
|
||||
var msg = img.Source switch
|
||||
{
|
||||
AvatarSource.Url => $"{Emojis.Success} System banner image changed to the image at the given URL.",
|
||||
AvatarSource.Attachment => $"{Emojis.Success} System banner image changed to attached image.\n{Emojis.Warn} If you delete the message containing the attachment, the banner image will stop working.",
|
||||
AvatarSource.User => throw new PKError("Cannot set a banner image to an user's avatar."),
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
|
||||
// The attachment's already right there, no need to preview it.
|
||||
var hasEmbed = img.Source != AvatarSource.Attachment;
|
||||
await (hasEmbed
|
||||
? ctx.Reply(msg, embed: new EmbedBuilder().Image(new(img.Url)).Build())
|
||||
: ctx.Reply(msg));
|
||||
}
|
||||
|
||||
async Task ShowImage()
|
||||
{
|
||||
if ((ctx.System.BannerImage?.Trim() ?? "").Length > 0)
|
||||
{
|
||||
var eb = new EmbedBuilder()
|
||||
.Title("System banner image")
|
||||
.Image(new(ctx.System.BannerImage))
|
||||
.Description("To clear, use `pk;system banner clear`.");
|
||||
await ctx.Reply(embed: eb.Build());
|
||||
}
|
||||
else
|
||||
throw new PKSyntaxError("This system does not have a banner image set. Set one by attaching an image to this command, or by passing an image URL or @mention.");
|
||||
}
|
||||
|
||||
if (await ctx.MatchClear("your system's banner image"))
|
||||
await ClearImage();
|
||||
else if (await ctx.MatchImage() is {} img)
|
||||
await SetImage(img);
|
||||
else
|
||||
await ShowImage();
|
||||
}
|
||||
|
||||
public async Task Delete(Context ctx) {
|
||||
ctx.CheckSystem();
|
||||
|
||||
|
@@ -70,6 +70,9 @@ namespace PluralKit.Bot {
|
||||
.Footer(new($"System ID: {system.Hid} | Created on {system.Created.FormatZoned(system)}"))
|
||||
.Color(color);
|
||||
|
||||
if (system.DescriptionPrivacy.CanAccess(ctx))
|
||||
eb.Image(new(system.BannerImage));
|
||||
|
||||
var latestSwitch = await _repo.GetLatestSwitch(conn, system.Id);
|
||||
if (latestSwitch != null && system.FrontPrivacy.CanAccess(ctx))
|
||||
{
|
||||
@@ -165,6 +168,9 @@ namespace PluralKit.Bot {
|
||||
.Footer(new(
|
||||
$"System ID: {system.Hid} | Member ID: {member.Hid} {(member.MetadataPrivacy.CanAccess(ctx) ? $"| Created on {member.Created.FormatZoned(system)}" : "")}"));
|
||||
|
||||
if (member.DescriptionPrivacy.CanAccess(ctx))
|
||||
eb.Image(new(member.BannerImage));
|
||||
|
||||
var description = "";
|
||||
if (member.MemberVisibility == PrivacyLevel.Private) description += "*(this member is hidden)*\n";
|
||||
if (guildSettings?.AvatarUrl != null)
|
||||
@@ -230,6 +236,9 @@ namespace PluralKit.Bot {
|
||||
.Color(color)
|
||||
.Footer(new($"System ID: {system.Hid} | Group ID: {target.Hid} | Created on {target.Created.FormatZoned(system)}"));
|
||||
|
||||
if (target.DescriptionPrivacy.CanAccess(ctx.LookupContextFor(target.System)))
|
||||
eb.Image(new(target.BannerImage));
|
||||
|
||||
if (target.DisplayName != null)
|
||||
eb.Field(new("Display Name", target.DisplayName, true));
|
||||
|
||||
|
@@ -10,7 +10,7 @@ using SixLabors.ImageSharp;
|
||||
|
||||
namespace PluralKit.Bot {
|
||||
public static class AvatarUtils {
|
||||
public static async Task VerifyAvatarOrThrow(string url)
|
||||
public static async Task VerifyAvatarOrThrow(string url, bool isFullSizeImage = false)
|
||||
{
|
||||
if (url.Length > Limits.MaxUriLength)
|
||||
throw Errors.UrlTooLong(url);
|
||||
@@ -45,7 +45,7 @@ namespace PluralKit.Bot {
|
||||
var stream = await response.Content.ReadAsStreamAsync();
|
||||
var image = await Task.Run(() => Image.Identify(stream));
|
||||
if (image == null) throw Errors.AvatarInvalid;
|
||||
if (image.Width > Limits.AvatarDimensionLimit || image.Height > Limits.AvatarDimensionLimit) // Check image size
|
||||
if (!isFullSizeImage && (image.Width > Limits.AvatarDimensionLimit || image.Height > Limits.AvatarDimensionLimit)) // Check image size
|
||||
throw Errors.AvatarDimensionsTooLarge(image.Width, image.Height);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user