feat: guild-specific name format

This commit is contained in:
rladenson 2024-11-19 17:35:09 -07:00 committed by Petal Ladenson
parent da4c05d4ed
commit ec6cbb2a64
11 changed files with 75 additions and 5 deletions

View file

@ -32,6 +32,7 @@ public partial class CommandTree
public static Command ConfigGroupDefaultPrivacy = new("config private group", "config private group [on|off]", "Sets whether group privacy is automatically set to private when creating a new group"); public static Command ConfigGroupDefaultPrivacy = new("config private group", "config private group [on|off]", "Sets whether group privacy is automatically set to private when creating a new group");
public static Command ConfigProxySwitch = new Command("config proxyswitch", "config proxyswitch [on|off]", "Sets whether to log a switch every time a proxy tag is used"); public static Command ConfigProxySwitch = new Command("config proxyswitch", "config proxyswitch [on|off]", "Sets whether to log a switch every time a proxy tag is used");
public static Command ConfigNameFormat = new Command("config nameformat", "config nameformat [format]", "Changes your system's username formatting"); public static Command ConfigNameFormat = new Command("config nameformat", "config nameformat [format]", "Changes your system's username formatting");
public static Command ConfigServerNameFormat = new Command("config servernameformat", "config servernameformat [format]", "Changes your system's username formatting in the current server");
public static Command AutoproxySet = new Command("autoproxy", "autoproxy [off|front|latch|member]", "Sets your system's autoproxy mode for the current server"); public static Command AutoproxySet = new Command("autoproxy", "autoproxy [off|front|latch|member]", "Sets your system's autoproxy mode for the current server");
public static Command AutoproxyOff = new Command("autoproxy off", "autoproxy off", "Disables autoproxying for your system in the current server"); public static Command AutoproxyOff = new Command("autoproxy off", "autoproxy off", "Disables autoproxying for your system in the current server");
public static Command AutoproxyFront = new Command("autoproxy front", "autoproxy front", "Sets your system's autoproxy in this server to proxy the first member currently registered as front"); public static Command AutoproxyFront = new Command("autoproxy front", "autoproxy front", "Sets your system's autoproxy in this server to proxy the first member currently registered as front");
@ -150,7 +151,7 @@ public partial class CommandTree
{ {
ConfigAutoproxyAccount, ConfigAutoproxyTimeout, ConfigTimezone, ConfigPing, ConfigAutoproxyAccount, ConfigAutoproxyTimeout, ConfigTimezone, ConfigPing,
ConfigMemberDefaultPrivacy, ConfigGroupDefaultPrivacy, ConfigShowPrivate, ConfigMemberDefaultPrivacy, ConfigGroupDefaultPrivacy, ConfigShowPrivate,
ConfigProxySwitch, ConfigNameFormat ConfigProxySwitch, ConfigNameFormat, ConfigServerNameFormat
}; };
public static Command[] ServerConfigCommands = public static Command[] ServerConfigCommands =

View file

@ -596,6 +596,8 @@ public partial class CommandTree
return ctx.Execute<Config>(null, m => m.LimitUpdate(ctx)); return ctx.Execute<Config>(null, m => m.LimitUpdate(ctx));
if (ctx.MatchMultiple(new[] { "proxy" }, new[] { "switch" }) || ctx.Match("proxyswitch", "ps")) if (ctx.MatchMultiple(new[] { "proxy" }, new[] { "switch" }) || ctx.Match("proxyswitch", "ps"))
return ctx.Execute<Config>(null, m => m.ProxySwitch(ctx)); return ctx.Execute<Config>(null, m => m.ProxySwitch(ctx));
if (ctx.MatchMultiple(new[] { "server" }, new[] { "name" }, new[] { "format" }) || ctx.MatchMultiple(new[] { "server", "servername" }, new[] { "format", "nameformat", "nf" }) || ctx.Match("snf", "servernf", "servernameformat", "snameformat"))
return ctx.Execute<Config>(null, m => m.ServerNameFormat(ctx));
// todo: maybe add the list of configuration keys here? // todo: maybe add the list of configuration keys here?
return ctx.Reply($"{Emojis.Error} Could not find a setting with that name. Please see `pk;commands config` for the list of possible config settings."); return ctx.Reply($"{Emojis.Error} Could not find a setting with that name. Please see `pk;commands config` for the list of possible config settings.");

View file

@ -1,7 +1,7 @@
using System.Text; using System.Text;
using Humanizer; using Humanizer;
using Myriad.Builders;
using NodaTime; using NodaTime;
using NodaTime.Text; using NodaTime.Text;
using NodaTime.TimeZones; using NodaTime.TimeZones;
@ -137,6 +137,13 @@ public class Config
ProxyMember.DefaultFormat ProxyMember.DefaultFormat
)); ));
items.Add(new(
"Server Name Format",
"Format string used to display a member's name in the current server",
(await ctx.Repository.GetSystemGuild(ctx.Guild.Id, ctx.System.Id)).NameFormat ?? "none set",
"none set"
));
await ctx.Paginate<PaginatedConfigItem>( await ctx.Paginate<PaginatedConfigItem>(
items.ToAsyncEnumerable(), items.ToAsyncEnumerable(),
items.Count, items.Count,
@ -584,6 +591,47 @@ public class Config
await ctx.Reply($"Member names are now formatted as `{formatString}`"); await ctx.Reply($"Member names are now formatted as `{formatString}`");
} }
public async Task ServerNameFormat(Context ctx)
{
var clearFlag = ctx.MatchClear();
var format = ctx.MatchFormat();
// if there's nothing next or what's next is raw/plaintext and we're not clearing, it's a query
if ((!ctx.HasNext() || format != ReplyFormat.Standard) && !clearFlag)
{
var guildCfg = await ctx.Repository.GetSystemGuild(ctx.Guild.Id, ctx.System.Id);
if (guildCfg.NameFormat == null)
await ctx.Reply("You do not have a specific name format set for this server and member names are formatted with your global name format.");
else
switch (format)
{
case ReplyFormat.Raw:
await ctx.Reply($"`{guildCfg.NameFormat}`");
break;
case ReplyFormat.Plaintext:
var eb = new EmbedBuilder()
.Description($"Showing guild Name Format for system {ctx.System.DisplayHid(ctx.Config)}");
await ctx.Reply(guildCfg.NameFormat, eb.Build());
break;
default:
await ctx.Reply($"Your member names in this server are currently formatted as `{guildCfg.NameFormat}`");
break;
}
return;
}
string? formatString = null;
if (!clearFlag)
{
formatString = ctx.RemainderOrNull();
}
await ctx.Repository.UpdateSystemGuild(ctx.System.Id, ctx.Guild.Id, new() { NameFormat = formatString });
if (formatString == null)
await ctx.Reply($"Member names are now formatted with your global name format in this server.");
else
await ctx.Reply($"Member names are now formatted as `{formatString}` in this server.");
}
public Task LimitUpdate(Context ctx) public Task LimitUpdate(Context ctx)
{ {
throw new PKError("You cannot update your own member or group limits. If you need a limit update, please join the " + throw new PKError("You cannot update your own member or group limits. If you need a limit update, please join the " +

View file

@ -27,6 +27,7 @@ public class MessageContext
public string? SystemGuildTag { get; } public string? SystemGuildTag { get; }
public bool TagEnabled { get; } public bool TagEnabled { get; }
public string? NameFormat { get; } public string? NameFormat { get; }
public string? GuildNameFormat { get; }
public string? SystemAvatar { get; } public string? SystemAvatar { get; }
public string? SystemGuildAvatar { get; } public string? SystemGuildAvatar { get; }
public bool AllowAutoproxy { get; } public bool AllowAutoproxy { get; }

View file

@ -9,7 +9,7 @@ public static class MessageContextExt
if (!ctx.TagEnabled || tag == null) if (!ctx.TagEnabled || tag == null)
return false; return false;
var format = ctx.NameFormat ?? ProxyMember.DefaultFormat; var format = ctx.GuildNameFormat ?? ctx.NameFormat ?? ProxyMember.DefaultFormat;
if (!format.Contains("{tag}")) if (!format.Contains("{tag}"))
return false; return false;

View file

@ -45,7 +45,7 @@ public class ProxyMember
var tag = ctx.SystemGuildTag ?? ctx.SystemTag; var tag = ctx.SystemGuildTag ?? ctx.SystemTag;
if (!ctx.TagEnabled) tag = null; if (!ctx.TagEnabled) tag = null;
return FormatTag(ctx.NameFormat ?? DefaultFormat, tag, memberName); return FormatTag(ctx.GuildNameFormat ?? ctx.NameFormat ?? DefaultFormat, tag, memberName);
} }
public string? ProxyAvatar(MessageContext ctx) => ServerAvatar ?? WebhookAvatar ?? Avatar ?? ctx.SystemGuildAvatar ?? ctx.SystemAvatar; public string? ProxyAvatar(MessageContext ctx) => ServerAvatar ?? WebhookAvatar ?? Avatar ?? ctx.SystemGuildAvatar ?? ctx.SystemAvatar;

View file

@ -16,6 +16,7 @@ create function message_context(account_id bigint, guild_id bigint, channel_id b
proxy_enabled bool, proxy_enabled bool,
system_guild_tag text, system_guild_tag text,
system_guild_avatar text, system_guild_avatar text,
guild_name_format text,
last_switch int, last_switch int,
last_switch_members int[], last_switch_members int[],
@ -51,6 +52,7 @@ as $$
coalesce(system_guild.proxy_enabled, true) as proxy_enabled, coalesce(system_guild.proxy_enabled, true) as proxy_enabled,
system_guild.tag as system_guild_tag, system_guild.tag as system_guild_tag,
system_guild.avatar_url as system_guild_avatar, system_guild.avatar_url as system_guild_avatar,
system_guild.name_format as guild_name_format,
-- system_last_switch view -- system_last_switch view
system_last_switch.switch as last_switch, system_last_switch.switch as last_switch,

View file

@ -0,0 +1,6 @@
-- database version 49
-- add guild name format
alter table system_guild add column name_format text;
update info set schema_version = 49;

View file

@ -9,7 +9,7 @@ namespace PluralKit.Core;
internal class DatabaseMigrator internal class DatabaseMigrator
{ {
private const string RootPath = "PluralKit.Core.Database"; // "resource path" root for SQL files private const string RootPath = "PluralKit.Core.Database"; // "resource path" root for SQL files
private const int TargetSchemaVersion = 48; private const int TargetSchemaVersion = 49;
private readonly ILogger _logger; private readonly ILogger _logger;
public DatabaseMigrator(ILogger logger) public DatabaseMigrator(ILogger logger)

View file

@ -13,6 +13,7 @@ public class SystemGuildPatch: PatchObject
public Partial<bool?> TagEnabled { get; set; } public Partial<bool?> TagEnabled { get; set; }
public Partial<string?> AvatarUrl { get; set; } public Partial<string?> AvatarUrl { get; set; }
public Partial<string?> DisplayName { get; set; } public Partial<string?> DisplayName { get; set; }
public Partial<string?> NameFormat { get; set; }
public override Query Apply(Query q) => q.ApplyPatch(wrapper => wrapper public override Query Apply(Query q) => q.ApplyPatch(wrapper => wrapper
.With("proxy_enabled", ProxyEnabled) .With("proxy_enabled", ProxyEnabled)
@ -20,6 +21,7 @@ public class SystemGuildPatch: PatchObject
.With("tag_enabled", TagEnabled) .With("tag_enabled", TagEnabled)
.With("avatar_url", AvatarUrl) .With("avatar_url", AvatarUrl)
.With("display_name", DisplayName) .With("display_name", DisplayName)
.With("name_format", NameFormat)
); );
public new void AssertIsValid() public new void AssertIsValid()
@ -53,6 +55,9 @@ public class SystemGuildPatch: PatchObject
if (o.ContainsKey("display_name")) if (o.ContainsKey("display_name"))
patch.DisplayName = o.Value<string>("display_name").NullIfEmpty(); patch.DisplayName = o.Value<string>("display_name").NullIfEmpty();
if (o.ContainsKey("name_format"))
patch.NameFormat = o.Value<string>("name_format").NullIfEmpty();
return patch; return patch;
} }
@ -77,6 +82,9 @@ public class SystemGuildPatch: PatchObject
if (DisplayName.IsPresent) if (DisplayName.IsPresent)
o.Add("display_name", DisplayName.Value); o.Add("display_name", DisplayName.Value);
if (NameFormat.IsPresent)
o.Add("name_format", NameFormat.Value);
return o; return o;
} }
} }

View file

@ -11,6 +11,7 @@ public class SystemGuildSettings
public bool TagEnabled { get; } public bool TagEnabled { get; }
public string? AvatarUrl { get; } public string? AvatarUrl { get; }
public string? DisplayName { get; } public string? DisplayName { get; }
public string? NameFormat { get; }
} }
public static class SystemGuildExt public static class SystemGuildExt
@ -24,6 +25,7 @@ public static class SystemGuildExt
o.Add("tag_enabled", settings.TagEnabled); o.Add("tag_enabled", settings.TagEnabled);
o.Add("avatar_url", settings.AvatarUrl); o.Add("avatar_url", settings.AvatarUrl);
o.Add("display_name", settings.DisplayName); o.Add("display_name", settings.DisplayName);
o.Add("name_format", settings.NameFormat);
return o; return o;
} }