feat(bot): allow separate member avatars for proxied messages (#523)
This allows for using one avatar for the member card, and a different avatar for proxied messages - so that users can set the main avatar to a "full" version of their avatar, and the "proxy" avatar to a cropped version.
This commit is contained in:
@@ -23,9 +23,9 @@ public class ProxyMember
|
||||
public string Name { get; } = "";
|
||||
|
||||
public string? ServerAvatar { get; }
|
||||
public string? WebhookAvatar { get; }
|
||||
public string? Avatar { get; }
|
||||
|
||||
|
||||
public bool AllowAutoproxy { get; }
|
||||
public string? Color { get; }
|
||||
|
||||
@@ -42,5 +42,5 @@ public class ProxyMember
|
||||
return memberName;
|
||||
}
|
||||
|
||||
public string? ProxyAvatar(MessageContext ctx) => ServerAvatar ?? Avatar ?? ctx.SystemAvatar;
|
||||
public string? ProxyAvatar(MessageContext ctx) => ServerAvatar ?? WebhookAvatar ?? Avatar ?? ctx.SystemAvatar;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
create function message_context(account_id bigint, guild_id bigint, channel_id bigint)
|
||||
create function message_context(account_id bigint, guild_id bigint, channel_id bigint)
|
||||
returns table (
|
||||
system_id int,
|
||||
log_channel bigint,
|
||||
@@ -67,6 +67,7 @@ create function proxy_members(account_id bigint, guild_id bigint)
|
||||
name text,
|
||||
|
||||
server_avatar text,
|
||||
webhook_avatar text,
|
||||
avatar text,
|
||||
|
||||
color char(6),
|
||||
@@ -76,22 +77,23 @@ create function proxy_members(account_id bigint, guild_id bigint)
|
||||
as $$
|
||||
select
|
||||
-- Basic data
|
||||
members.id as id,
|
||||
members.proxy_tags as proxy_tags,
|
||||
members.keep_proxy as keep_proxy,
|
||||
members.id as id,
|
||||
members.proxy_tags as proxy_tags,
|
||||
members.keep_proxy as keep_proxy,
|
||||
|
||||
-- Name info
|
||||
member_guild.display_name as server_name,
|
||||
members.display_name as display_name,
|
||||
members.name as name,
|
||||
member_guild.display_name as server_name,
|
||||
members.display_name as display_name,
|
||||
members.name as name,
|
||||
|
||||
-- Avatar info
|
||||
member_guild.avatar_url as server_avatar,
|
||||
members.avatar_url as avatar,
|
||||
member_guild.avatar_url as server_avatar,
|
||||
members.webhook_avatar_url as webhook_avatar,
|
||||
members.avatar_url as avatar,
|
||||
|
||||
members.color as color,
|
||||
members.color as color,
|
||||
|
||||
members.allow_autoproxy as allow_autoproxy
|
||||
members.allow_autoproxy as allow_autoproxy
|
||||
from accounts
|
||||
inner join systems on systems.id = accounts.system
|
||||
inner join members on members.system = systems.id
|
||||
|
||||
6
PluralKit.Core/Database/Migrations/33.sql
Normal file
6
PluralKit.Core/Database/Migrations/33.sql
Normal file
@@ -0,0 +1,6 @@
|
||||
-- database version 33
|
||||
-- add webhook_avatar_url to system members
|
||||
|
||||
alter table members add column webhook_avatar_url text;
|
||||
|
||||
update info set schema_version = 33;
|
||||
@@ -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 = 32;
|
||||
private const int TargetSchemaVersion = 33;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public DatabaseMigrator(ILogger logger)
|
||||
|
||||
@@ -39,6 +39,7 @@ public class PKMember
|
||||
public Guid Uuid { get; private set; }
|
||||
public SystemId System { get; private set; }
|
||||
public string Color { get; private set; }
|
||||
public string WebhookAvatarUrl { get; private set; }
|
||||
public string AvatarUrl { get; private set; }
|
||||
public string BannerImage { get; private set; }
|
||||
public string Name { get; private set; }
|
||||
@@ -90,6 +91,9 @@ public static class PKMemberExt
|
||||
public static string AvatarFor(this PKMember member, LookupContext ctx) =>
|
||||
member.AvatarPrivacy.Get(ctx, member.AvatarUrl.TryGetCleanCdnUrl());
|
||||
|
||||
public static string WebhookAvatarFor(this PKMember member, LookupContext ctx) =>
|
||||
member.AvatarPrivacy.Get(ctx, (member.WebhookAvatarUrl ?? member.AvatarUrl).TryGetCleanCdnUrl());
|
||||
|
||||
public static string DescriptionFor(this PKMember member, LookupContext ctx) =>
|
||||
member.DescriptionPrivacy.Get(ctx, member.Description);
|
||||
|
||||
@@ -128,6 +132,7 @@ public static class PKMemberExt
|
||||
o.Add("birthday", member.BirthdayFor(ctx)?.FormatExport());
|
||||
o.Add("pronouns", member.PronounsFor(ctx));
|
||||
o.Add("avatar_url", member.AvatarFor(ctx).TryGetCleanCdnUrl());
|
||||
o.Add("webhook_avatar_url", member.WebhookAvatarFor(ctx).TryGetCleanCdnUrl());
|
||||
o.Add("banner", member.DescriptionPrivacy.Get(ctx, member.BannerImage).TryGetCleanCdnUrl());
|
||||
o.Add("description", member.DescriptionFor(ctx));
|
||||
o.Add("created", member.CreatedFor(ctx)?.FormatExport());
|
||||
|
||||
@@ -12,6 +12,7 @@ public class MemberPatch: PatchObject
|
||||
public Partial<string> Name { get; set; }
|
||||
public Partial<string> Hid { get; set; }
|
||||
public Partial<string?> DisplayName { get; set; }
|
||||
public Partial<string?> WebhookAvatarUrl { get; set; }
|
||||
public Partial<string?> AvatarUrl { get; set; }
|
||||
public Partial<string?> BannerImage { get; set; }
|
||||
public Partial<string?> Color { get; set; }
|
||||
@@ -34,6 +35,7 @@ public class MemberPatch: PatchObject
|
||||
.With("name", Name)
|
||||
.With("hid", Hid)
|
||||
.With("display_name", DisplayName)
|
||||
.With("webhook_avatar_url", WebhookAvatarUrl)
|
||||
.With("avatar_url", AvatarUrl)
|
||||
.With("banner_image", BannerImage)
|
||||
.With("color", Color)
|
||||
@@ -62,6 +64,9 @@ public class MemberPatch: PatchObject
|
||||
if (AvatarUrl.Value != null)
|
||||
AssertValid(AvatarUrl.Value, "avatar_url", Limits.MaxUriLength,
|
||||
s => MiscUtils.TryMatchUri(s, out var avatarUri));
|
||||
if (WebhookAvatarUrl.Value != null)
|
||||
AssertValid(WebhookAvatarUrl.Value, "webhook_avatar_url", Limits.MaxUriLength,
|
||||
s => MiscUtils.TryMatchUri(s, out var webhookAvatarUri));
|
||||
if (BannerImage.Value != null)
|
||||
AssertValid(BannerImage.Value, "banner", Limits.MaxUriLength,
|
||||
s => MiscUtils.TryMatchUri(s, out var bannerUri));
|
||||
@@ -93,6 +98,7 @@ public class MemberPatch: PatchObject
|
||||
if (o.ContainsKey("name")) patch.Name = o.Value<string>("name");
|
||||
if (o.ContainsKey("color")) patch.Color = o.Value<string>("color").NullIfEmpty()?.ToLower();
|
||||
if (o.ContainsKey("display_name")) patch.DisplayName = o.Value<string>("display_name").NullIfEmpty();
|
||||
if (o.ContainsKey("webhook_avatar_url")) patch.WebhookAvatarUrl = o.Value<string>("webhook_avatar_url").NullIfEmpty();
|
||||
if (o.ContainsKey("avatar_url")) patch.AvatarUrl = o.Value<string>("avatar_url").NullIfEmpty();
|
||||
if (o.ContainsKey("banner")) patch.BannerImage = o.Value<string>("banner").NullIfEmpty();
|
||||
|
||||
@@ -177,6 +183,8 @@ public class MemberPatch: PatchObject
|
||||
o.Add("display_name", DisplayName.Value);
|
||||
if (AvatarUrl.IsPresent)
|
||||
o.Add("avatar_url", AvatarUrl.Value);
|
||||
if (WebhookAvatarUrl.IsPresent)
|
||||
o.Add("webhook_avatar_url", WebhookAvatarUrl.Value);
|
||||
if (BannerImage.IsPresent)
|
||||
o.Add("banner", BannerImage.Value);
|
||||
if (Color.IsPresent)
|
||||
|
||||
Reference in New Issue
Block a user