[backend/federation] Federate user pronouns
This commit is contained in:
parent
6001ff960a
commit
2aa6eb608b
5 changed files with 51 additions and 3 deletions
|
@ -21,6 +21,7 @@ public static class Constants
|
||||||
public const string MastodonNs = "http://joinmastodon.org/ns";
|
public const string MastodonNs = "http://joinmastodon.org/ns";
|
||||||
public const string MisskeyNs = "https://misskey-hub.net/ns";
|
public const string MisskeyNs = "https://misskey-hub.net/ns";
|
||||||
public const string FedibirdNs = "http://fedibird.com/ns";
|
public const string FedibirdNs = "http://fedibird.com/ns";
|
||||||
|
public const string PancakesNs = "https://ns.pancakes.gay/as/";
|
||||||
public static readonly string[] SystemUsers = ["instance.actor", "relay.actor"];
|
public static readonly string[] SystemUsers = ["instance.actor", "relay.actor"];
|
||||||
|
|
||||||
public const string APMime = "application/activity+json";
|
public const string APMime = "application/activity+json";
|
||||||
|
|
|
@ -80,7 +80,14 @@ public class UserRenderer(
|
||||||
|
|
||||||
var attachments = profile?.Fields
|
var attachments = profile?.Fields
|
||||||
.Select(p => new ASField { Name = p.Name, Value = RenderFieldValue(p.Value) })
|
.Select(p => new ASField { Name = p.Name, Value = RenderFieldValue(p.Value) })
|
||||||
.Cast<ASAttachment>()
|
.Concat<ASAttachment>(profile.Pronouns != null && profile.Pronouns.Count != 0
|
||||||
|
?
|
||||||
|
[
|
||||||
|
profile.Pronouns.TryGetValue("", out var pronouns)
|
||||||
|
? new ASPronouns { Name = pronouns }
|
||||||
|
: new ASPronouns { NameMap = profile.Pronouns }
|
||||||
|
]
|
||||||
|
: [])
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
var summary = profile?.Description != null
|
var summary = profile?.Description != null
|
||||||
|
|
|
@ -43,7 +43,8 @@
|
||||||
|
|
||||||
"Bite": "https://ns.mia.jetzt/as#Bite",
|
"Bite": "https://ns.mia.jetzt/as#Bite",
|
||||||
"quoteUri": "http://fedibird.com/ns#quoteUri",
|
"quoteUri": "http://fedibird.com/ns#quoteUri",
|
||||||
"EmojiReact": "http://litepub.social/ns#EmojiReact"
|
"EmojiReact": "http://litepub.social/ns#EmojiReact",
|
||||||
|
"Pronouns": "https://ns.pancakes.gay/as/#Pronouns"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -1,8 +1,11 @@
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
using Iceshrimp.Backend.Core.Configuration;
|
using Iceshrimp.Backend.Core.Configuration;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using J = Newtonsoft.Json.JsonPropertyAttribute;
|
using J = Newtonsoft.Json.JsonPropertyAttribute;
|
||||||
using JC = Newtonsoft.Json.JsonConverterAttribute;
|
using JC = Newtonsoft.Json.JsonConverterAttribute;
|
||||||
|
using JI = System.Text.Json.Serialization.JsonIgnoreAttribute;
|
||||||
|
using JsonConverter = Newtonsoft.Json.JsonConverter;
|
||||||
|
|
||||||
namespace Iceshrimp.Backend.Core.Federation.ActivityStreams.Types;
|
namespace Iceshrimp.Backend.Core.Federation.ActivityStreams.Types;
|
||||||
|
|
||||||
|
@ -50,6 +53,21 @@ public class ASField : ASAttachment
|
||||||
public ASField() => Type = $"{Constants.SchemaNs}#PropertyValue";
|
public ASField() => Type = $"{Constants.SchemaNs}#PropertyValue";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class ASPronouns : ASAttachment
|
||||||
|
{
|
||||||
|
public ASPronouns() => Type = $"{Constants.PancakesNs}#Pronouns";
|
||||||
|
|
||||||
|
[J($"{Constants.ActivityStreamsNs}#name")]
|
||||||
|
[JC(typeof(ValueObjectConverter))]
|
||||||
|
[JI(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||||
|
public string? Name { get; set; }
|
||||||
|
|
||||||
|
[J($"{Constants.ActivityStreamsNs}#nameMap")]
|
||||||
|
[JC(typeof(ValueObjectConverter))]
|
||||||
|
[JI(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||||
|
public Dictionary<string, string>? NameMap { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public class ASImageConverter : ASSerializer.ListSingleObjectConverter<ASImage>;
|
public class ASImageConverter : ASSerializer.ListSingleObjectConverter<ASImage>;
|
||||||
|
|
||||||
public sealed class ASAttachmentConverter : JsonConverter
|
public sealed class ASAttachmentConverter : JsonConverter
|
||||||
|
@ -99,6 +117,7 @@ public sealed class ASAttachmentConverter : JsonConverter
|
||||||
$"{Constants.ActivityStreamsNs}#Document" => obj.ToObject<ASDocument?>(),
|
$"{Constants.ActivityStreamsNs}#Document" => obj.ToObject<ASDocument?>(),
|
||||||
$"{Constants.ActivityStreamsNs}#Image" => obj.ToObject<ASImage?>(),
|
$"{Constants.ActivityStreamsNs}#Image" => obj.ToObject<ASImage?>(),
|
||||||
$"{Constants.SchemaNs}#PropertyValue" => obj.ToObject<ASField?>(),
|
$"{Constants.SchemaNs}#PropertyValue" => obj.ToObject<ASField?>(),
|
||||||
|
$"{Constants.PancakesNs}#Pronouns" => obj.ToObject<ASPronouns?>(),
|
||||||
_ => attachment
|
_ => attachment
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,6 +159,15 @@ public class UserService(
|
||||||
.AwaitAllAsync()
|
.AwaitAllAsync()
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
|
var pronounsAttachment = actor.Attachments?.OfType<ASPronouns>()
|
||||||
|
.FirstOrDefault(p => p is { Name: not null } or { NameMap: not null });
|
||||||
|
var pronouns = pronounsAttachment switch
|
||||||
|
{
|
||||||
|
{ Name: not null } => new Dictionary<string, string> { { "", pronounsAttachment.Name } },
|
||||||
|
{ NameMap: not null } => pronounsAttachment.NameMap,
|
||||||
|
_ => null
|
||||||
|
};
|
||||||
|
|
||||||
var bio = actor.MkSummary?.ReplaceLineEndings("\n").Trim();
|
var bio = actor.MkSummary?.ReplaceLineEndings("\n").Trim();
|
||||||
if (bio == null)
|
if (bio == null)
|
||||||
{
|
{
|
||||||
|
@ -209,7 +218,8 @@ public class UserService(
|
||||||
//Location = TODO,
|
//Location = TODO,
|
||||||
Fields = fields?.ToArray() ?? [],
|
Fields = fields?.ToArray() ?? [],
|
||||||
UserHost = user.Host,
|
UserHost = user.Host,
|
||||||
Url = actor.Url?.Link
|
Url = actor.Url?.Link,
|
||||||
|
Pronouns = pronouns
|
||||||
};
|
};
|
||||||
|
|
||||||
var publicKey = new UserPublickey
|
var publicKey = new UserPublickey
|
||||||
|
@ -326,6 +336,15 @@ public class UserService(
|
||||||
.AwaitAllAsync()
|
.AwaitAllAsync()
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
|
var pronounsAttachment = actor.Attachments?.OfType<ASPronouns>()
|
||||||
|
.FirstOrDefault(p => p is { Name: not null } or { NameMap: not null });
|
||||||
|
var pronouns = pronounsAttachment switch
|
||||||
|
{
|
||||||
|
{ Name: not null } => new Dictionary<string, string> { { "", pronounsAttachment.Name } },
|
||||||
|
{ NameMap: not null } => pronounsAttachment.NameMap,
|
||||||
|
_ => null
|
||||||
|
};
|
||||||
|
|
||||||
user.Emojis = emoji.Select(p => p.Id).ToList();
|
user.Emojis = emoji.Select(p => p.Id).ToList();
|
||||||
//TODO: FollowersCount
|
//TODO: FollowersCount
|
||||||
//TODO: FollowingCount
|
//TODO: FollowingCount
|
||||||
|
@ -351,6 +370,7 @@ public class UserService(
|
||||||
user.UserProfile.Fields = fields?.ToArray() ?? [];
|
user.UserProfile.Fields = fields?.ToArray() ?? [];
|
||||||
user.UserProfile.UserHost = user.Host;
|
user.UserProfile.UserHost = user.Host;
|
||||||
user.UserProfile.Url = actor.Url?.Link;
|
user.UserProfile.Url = actor.Url?.Link;
|
||||||
|
user.UserProfile.Pronouns = pronouns;
|
||||||
|
|
||||||
user.UserProfile.MentionsResolved = false;
|
user.UserProfile.MentionsResolved = false;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue