mirror of
https://github.com/PluralKit/PluralKit.git
synced 2026-02-07 22:37:54 +00:00
feat: implement system avatar commands
This commit is contained in:
parent
293570c91c
commit
b62340cbb3
11 changed files with 155 additions and 101 deletions
|
|
@ -6,34 +6,8 @@ namespace PluralKit.Bot;
|
|||
|
||||
public static class ContextAvatarExt
|
||||
{
|
||||
public static async Task<ParsedImage?> MatchImage(this Context ctx)
|
||||
public static ParsedImage? ExtractImageFromAttachment(this Context ctx)
|
||||
{
|
||||
// If we have a user @mention/ID, use their avatar
|
||||
if (await ctx.MatchUser() is { } user)
|
||||
{
|
||||
var url = user.AvatarUrl("png", 256);
|
||||
return new ParsedImage { Url = url, Source = AvatarSource.User, SourceUser = user };
|
||||
}
|
||||
|
||||
// If we have raw or plaintext, don't try to parse as a URL
|
||||
if (ctx.PeekMatchFormat() != ReplyFormat.Standard)
|
||||
return null;
|
||||
|
||||
// If we have a positional argument, try to parse it as a URL
|
||||
var arg = ctx.RemainderOrNull();
|
||||
if (arg != null)
|
||||
{
|
||||
// Allow surrounding the URL with <angle brackets> to "de-embed"
|
||||
if (arg.StartsWith("<") && arg.EndsWith(">"))
|
||||
arg = arg.Substring(1, arg.Length - 2);
|
||||
|
||||
if (!Core.MiscUtils.TryMatchUri(arg, out var uri))
|
||||
throw Errors.InvalidUrl;
|
||||
|
||||
// ToString URL-decodes, which breaks URLs to spaces; AbsoluteUri doesn't
|
||||
return new ParsedImage { Url = uri.AbsoluteUri, Source = AvatarSource.Url };
|
||||
}
|
||||
|
||||
// If we have an attachment, use that
|
||||
if (ctx.Message.Attachments.FirstOrDefault() is { } attachment)
|
||||
{
|
||||
|
|
@ -51,6 +25,33 @@ public static class ContextAvatarExt
|
|||
// and if there are no attachments (which would have been caught just before)
|
||||
return null;
|
||||
}
|
||||
public static async Task<ParsedImage?> GetUserPfp(this Context ctx, string arg)
|
||||
{
|
||||
// If we have a user @mention/ID, use their avatar
|
||||
if (await ctx.ParseUser(arg) is { } user)
|
||||
{
|
||||
var url = user.AvatarUrl("png", 256);
|
||||
return new ParsedImage { Url = url, Source = AvatarSource.User, SourceUser = user };
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
public static ParsedImage ParseImage(this Context ctx, string arg)
|
||||
{
|
||||
// Allow surrounding the URL with <angle brackets> to "de-embed"
|
||||
if (arg.StartsWith("<") && arg.EndsWith(">"))
|
||||
arg = arg.Substring(1, arg.Length - 2);
|
||||
|
||||
if (!Core.MiscUtils.TryMatchUri(arg, out var uri))
|
||||
throw Errors.InvalidUrl;
|
||||
|
||||
// ToString URL-decodes, which breaks URLs to spaces; AbsoluteUri doesn't
|
||||
return new ParsedImage { Url = uri.AbsoluteUri, Source = AvatarSource.Url };
|
||||
}
|
||||
public static async Task<ParsedImage?> MatchImage(this Context ctx)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public struct ParsedImage
|
||||
|
|
|
|||
|
|
@ -10,6 +10,14 @@ namespace PluralKit.Bot;
|
|||
|
||||
public static class ContextEntityArgumentsExt
|
||||
{
|
||||
public static async Task<User> ParseUser(this Context ctx, string arg)
|
||||
{
|
||||
if (arg.TryParseMention(out var id))
|
||||
return await ctx.Cache.GetOrFetchUser(ctx.Rest, id);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static async Task<User> MatchUser(this Context ctx)
|
||||
{
|
||||
var text = ctx.PeekArgument();
|
||||
|
|
|
|||
|
|
@ -51,4 +51,12 @@ public static class ContextParametersExt
|
|||
param => (param as Parameter.Toggle)?.value
|
||||
);
|
||||
}
|
||||
|
||||
public static async Task<ParsedImage?> ParamResolveAvatar(this Context ctx, string param_name)
|
||||
{
|
||||
return await ctx.Parameters.ResolveParameter(
|
||||
ctx, param_name,
|
||||
param => (param as Parameter.Avatar)?.avatar
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
using System.Diagnostics;
|
||||
using Myriad.Types;
|
||||
using PluralKit.Core;
|
||||
using uniffi.commands;
|
||||
|
||||
|
|
@ -13,6 +14,7 @@ public abstract record Parameter()
|
|||
public record PrivacyLevel(string level): Parameter;
|
||||
public record Toggle(bool value): Parameter;
|
||||
public record Opaque(string value): Parameter;
|
||||
public record Avatar(ParsedImage avatar): Parameter;
|
||||
}
|
||||
|
||||
public class Parameters
|
||||
|
|
@ -79,6 +81,8 @@ public class Parameters
|
|||
return new Parameter.Toggle(toggle.toggle);
|
||||
case uniffi.commands.Parameter.OpaqueString opaque:
|
||||
return new Parameter.Opaque(opaque.raw);
|
||||
case uniffi.commands.Parameter.Avatar avatar:
|
||||
return new Parameter.Avatar(await ctx.GetUserPfp(avatar.avatar) ?? ctx.ParseImage(avatar.avatar));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue