Add member proxy display names
This commit is contained in:
		@@ -29,7 +29,7 @@ namespace PluralKit.Bot.Commands
 | 
			
		||||
 | 
			
		||||
            // Warn if member name will be unproxyable (with/without tag)
 | 
			
		||||
            if (memberName.Length > Context.SenderSystem.MaxMemberNameLength) {
 | 
			
		||||
                var msg = await Context.Channel.SendMessageAsync($"{Emojis.Warn} Member name too long ({memberName.Length} > {Context.SenderSystem.MaxMemberNameLength} characters), this member will be unproxyable. Do you want to create it anyway? (You can change the name later)");
 | 
			
		||||
                var msg = await Context.Channel.SendMessageAsync($"{Emojis.Warn} Member name too long ({memberName.Length} > {Context.SenderSystem.MaxMemberNameLength} characters), this member will be unproxyable. Do you want to create it anyway? (You can change the name later, or set a member display name)");
 | 
			
		||||
                if (!await Context.PromptYesNo(msg)) throw new PKError("Member creation cancelled.");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -58,9 +58,9 @@ namespace PluralKit.Bot.Commands
 | 
			
		||||
            // Hard name length cap
 | 
			
		||||
            if (newName.Length > Limits.MaxMemberNameLength) throw Errors.MemberNameTooLongError(newName.Length);
 | 
			
		||||
 | 
			
		||||
            // Warn if member name will be unproxyable (with/without tag)
 | 
			
		||||
            if (newName.Length > Context.SenderSystem.MaxMemberNameLength) {
 | 
			
		||||
                var msg = await Context.Channel.SendMessageAsync($"{Emojis.Warn} New member name too long ({newName.Length} > {Context.SenderSystem.MaxMemberNameLength} characters), this member will be unproxyable. Do you want to change it anyway?");
 | 
			
		||||
            // Warn if member name will be unproxyable (with/without tag), only if member doesn't have a display name
 | 
			
		||||
            if (ContextEntity.DisplayName == null && newName.Length > Context.SenderSystem.MaxMemberNameLength) {
 | 
			
		||||
                var msg = await Context.Channel.SendMessageAsync($"{Emojis.Warn} New member name too long ({newName.Length} > {Context.SenderSystem.MaxMemberNameLength} characters), this member will be unproxyable. Do you want to change it anyway? (You can set a member display name instead)");
 | 
			
		||||
                if (!await Context.PromptYesNo(msg)) throw new PKError("Member renaming cancelled.");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -77,6 +77,7 @@ namespace PluralKit.Bot.Commands
 | 
			
		||||
 | 
			
		||||
            await Context.Channel.SendMessageAsync($"{Emojis.Success} Member renamed.");
 | 
			
		||||
            if (newName.Contains(" ")) await Context.Channel.SendMessageAsync($"{Emojis.Note} Note that this member's name now contains spaces. You will need to surround it with \"double quotes\" when using commands referring to it.");
 | 
			
		||||
            if (ContextEntity.DisplayName != null) await Context.Channel.SendMessageAsync($"{Emojis.Note} Note that this member has a display name set (`{ContextEntity.DisplayName}`), and will be proxied using that name instead.");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Command("description")]
 | 
			
		||||
@@ -213,6 +214,39 @@ namespace PluralKit.Bot.Commands
 | 
			
		||||
            var embed = url != null ? new EmbedBuilder().WithImageUrl(url).Build() : null;
 | 
			
		||||
            await Context.Channel.SendMessageAsync($"{Emojis.Success} Member avatar {(url == null ? "cleared" : "changed")}.", embed: embed);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        [Command("displayname")]
 | 
			
		||||
        [Alias("nick", "nickname", "displayname")]
 | 
			
		||||
        [Remarks("member <member> displayname <displayname>")]
 | 
			
		||||
        [MustPassOwnMember]
 | 
			
		||||
        public async Task MemberDisplayName([Remainder] string newDisplayName = null)
 | 
			
		||||
        {            
 | 
			
		||||
            // Refuse if proxy name will be unproxyable (with/without tag)
 | 
			
		||||
            if (newDisplayName != null && newDisplayName.Length > Context.SenderSystem.MaxMemberNameLength)
 | 
			
		||||
                throw Errors.DisplayNameTooLong(newDisplayName, Context.SenderSystem.MaxMemberNameLength);
 | 
			
		||||
            
 | 
			
		||||
            ContextEntity.DisplayName = newDisplayName;
 | 
			
		||||
            await Members.Save(ContextEntity);
 | 
			
		||||
 | 
			
		||||
            var successStr = $"{Emojis.Success} ";
 | 
			
		||||
            if (newDisplayName != null)
 | 
			
		||||
            {
 | 
			
		||||
                successStr +=
 | 
			
		||||
                    $"Member display name changed. This member will now be proxied using the name `{newDisplayName}`.";
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                successStr += $"Member display name cleared. ";
 | 
			
		||||
                
 | 
			
		||||
                // If we're removing display name and the *real* name will be unproxyable, warn.
 | 
			
		||||
                if (ContextEntity.Name.Length > Context.SenderSystem.MaxMemberNameLength)
 | 
			
		||||
                    successStr +=
 | 
			
		||||
                        $" {Emojis.Warn} This member's actual name is too long ({ContextEntity.Name.Length} > {Context.SenderSystem.MaxMemberNameLength} characters), and thus cannot be proxied.";
 | 
			
		||||
                else
 | 
			
		||||
                    successStr += $"This member will now be proxied using their member name `{ContextEntity.Name}.";
 | 
			
		||||
            }
 | 
			
		||||
            await Context.Channel.SendMessageAsync(successStr);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Command]
 | 
			
		||||
        [Alias("view", "show", "info")]
 | 
			
		||||
 
 | 
			
		||||
@@ -73,5 +73,8 @@ namespace PluralKit.Bot {
 | 
			
		||||
        public static PKError FrontPercentTimeInFuture => new PKError("Cannot get the front percent between now and a time in the future.");
 | 
			
		||||
 | 
			
		||||
        public static PKError GuildNotFound(ulong guildId) => new PKError($"Guild with ID {guildId} not found.");
 | 
			
		||||
 | 
			
		||||
        public static PKError DisplayNameTooLong(string displayName, int maxLength) => new PKError(
 | 
			
		||||
            $"Display name too long ({displayName.Length} > {maxLength} characters). Use a shorter display name, or shorten your system tag.");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -24,8 +24,6 @@ namespace PluralKit.Bot
 | 
			
		||||
        public PKMember Member;
 | 
			
		||||
        public PKSystem System;
 | 
			
		||||
        public string InnerText;
 | 
			
		||||
 | 
			
		||||
        public string ProxyName => Member.Name + (System.Tag != null ? " " + System.Tag : "");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class ProxyService: IDisposable {
 | 
			
		||||
@@ -118,7 +116,8 @@ namespace PluralKit.Bot
 | 
			
		||||
            // Fetch a webhook for this channel, and send the proxied message
 | 
			
		||||
            var webhook = await _webhookCache.GetWebhook(message.Channel as ITextChannel);
 | 
			
		||||
            var avatarUrl = match.Member.AvatarUrl ?? match.System.AvatarUrl;
 | 
			
		||||
            var hookMessageId = await ExecuteWebhook(webhook, messageContents, match.ProxyName, avatarUrl, message.Attachments.FirstOrDefault());
 | 
			
		||||
            var proxyName = match.Member.ProxyName(match.System.Tag);
 | 
			
		||||
            var hookMessageId = await ExecuteWebhook(webhook, messageContents, proxyName, avatarUrl, message.Attachments.FirstOrDefault());
 | 
			
		||||
 | 
			
		||||
            // Store the message in the database, and log it in the log channel (if applicable)
 | 
			
		||||
            await _messageStorage.Store(message.Author.Id, hookMessageId, message.Channel.Id, message.Id, match.Member);
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,7 @@ namespace PluralKit
 | 
			
		||||
{
 | 
			
		||||
    public class PKSystem
 | 
			
		||||
    {
 | 
			
		||||
        // Additions here should be mirrored in SystemStore::Save
 | 
			
		||||
        [Key] [JsonIgnore] public int Id { get; set; }
 | 
			
		||||
        [JsonProperty("id")] public string Hid { get; set; }
 | 
			
		||||
        [JsonProperty("name")] public string Name { get; set; }
 | 
			
		||||
@@ -24,12 +25,14 @@ namespace PluralKit
 | 
			
		||||
 | 
			
		||||
    public class PKMember
 | 
			
		||||
    {
 | 
			
		||||
        // Additions here should be mirrored in MemberStore::Save
 | 
			
		||||
        [JsonIgnore] public int Id { get; set; }
 | 
			
		||||
        [JsonProperty("id")] public string Hid { get; set; }
 | 
			
		||||
        [JsonIgnore] public int System { get; set; }
 | 
			
		||||
        [JsonProperty("color")] public string Color { get; set; }
 | 
			
		||||
        [JsonProperty("avatar_url")] public string AvatarUrl { get; set; }
 | 
			
		||||
        [JsonProperty("name")] public string Name { get; set; }
 | 
			
		||||
        [JsonProperty("display_name")] public string DisplayName { get; set; }
 | 
			
		||||
        [JsonProperty("birthday")] public LocalDate? Birthday { get; set; }
 | 
			
		||||
        [JsonProperty("pronouns")] public string Pronouns { get; set; }
 | 
			
		||||
        [JsonProperty("description")] public string Description { get; set; }
 | 
			
		||||
@@ -52,6 +55,12 @@ namespace PluralKit
 | 
			
		||||
 | 
			
		||||
        [JsonIgnore] public bool HasProxyTags => Prefix != null || Suffix != null;
 | 
			
		||||
        [JsonIgnore] public string ProxyString => $"{Prefix ?? ""}text{Suffix ?? ""}";
 | 
			
		||||
        
 | 
			
		||||
        public string ProxyName(string systemTag)
 | 
			
		||||
        {
 | 
			
		||||
            if (systemTag == null) return DisplayName ?? Name;
 | 
			
		||||
            return $"{DisplayName ?? Name} {systemTag}";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class PKSwitch
 | 
			
		||||
 
 | 
			
		||||
@@ -150,7 +150,7 @@ namespace PluralKit {
 | 
			
		||||
 | 
			
		||||
        public async Task Save(PKMember member) {
 | 
			
		||||
            using (var conn = await _conn.Obtain())
 | 
			
		||||
                await conn.ExecuteAsync("update members set name = @Name, description = @Description, color = @Color, avatar_url = @AvatarUrl, birthday = @Birthday, pronouns = @Pronouns, prefix = @Prefix, suffix = @Suffix where id = @Id", member);
 | 
			
		||||
                await conn.ExecuteAsync("update members set name = @Name, display_name = @DisplayName, description = @Description, color = @Color, avatar_url = @AvatarUrl, birthday = @Birthday, pronouns = @Pronouns, prefix = @Prefix, suffix = @Suffix where id = @Id", member);
 | 
			
		||||
 | 
			
		||||
            _logger.Information("Updated member {@Member}", member);
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -242,7 +242,7 @@ namespace PluralKit
 | 
			
		||||
        public static readonly string Warn = "\u26A0";
 | 
			
		||||
        public static readonly string Success = "\u2705";
 | 
			
		||||
        public static readonly string Error = "\u274C";
 | 
			
		||||
        public static readonly string Note = "\u2757";
 | 
			
		||||
        public static readonly string Note = "\U0001f4dd";
 | 
			
		||||
        public static readonly string ThumbsUp = "\U0001f44d";
 | 
			
		||||
        public static readonly string RedQuestion = "\u2753";
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -13,18 +13,19 @@ create table if not exists systems
 | 
			
		||||
 | 
			
		||||
create table if not exists members
 | 
			
		||||
(
 | 
			
		||||
    id          serial primary key,
 | 
			
		||||
    hid         char(5) unique not null,
 | 
			
		||||
    system      serial         not null references systems (id) on delete cascade,
 | 
			
		||||
    color       char(6),
 | 
			
		||||
    avatar_url  text,
 | 
			
		||||
    name        text           not null,
 | 
			
		||||
    birthday    date,
 | 
			
		||||
    pronouns    text,
 | 
			
		||||
    description text,
 | 
			
		||||
    prefix      text,
 | 
			
		||||
    suffix      text,
 | 
			
		||||
    created     timestamp      not null default (current_timestamp at time zone 'utc')
 | 
			
		||||
    id           serial primary key,
 | 
			
		||||
    hid          char(5) unique not null,
 | 
			
		||||
    system       serial         not null references systems (id) on delete cascade,
 | 
			
		||||
    color        char(6),
 | 
			
		||||
    avatar_url   text,
 | 
			
		||||
    name         text           not null,
 | 
			
		||||
    display_name text,
 | 
			
		||||
    birthday     date,
 | 
			
		||||
    pronouns     text,
 | 
			
		||||
    description  text,
 | 
			
		||||
    prefix       text,
 | 
			
		||||
    suffix       text,
 | 
			
		||||
    created      timestamp      not null default (current_timestamp at time zone 'utc')
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
create table if not exists accounts
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user