diff --git a/DiscordChatExporter.Core/Exporting/ExportContext.cs b/DiscordChatExporter.Core/Exporting/ExportContext.cs index 9051f97..7309df6 100644 --- a/DiscordChatExporter.Core/Exporting/ExportContext.cs +++ b/DiscordChatExporter.Core/Exporting/ExportContext.cs @@ -90,20 +90,25 @@ internal class ExportContext public Role? TryGetRole(Snowflake id) => _roles.GetValueOrDefault(id); public Color? TryGetUserColor(Snowflake id) + { + var memberRoles = GetUserRoles(id); + + return memberRoles? + .Where(r => r.Color is not null) + .Select(r => r.Color) + .FirstOrDefault(); + } + + public IReadOnlyList GetUserRoles(Snowflake id) { var member = TryGetMember(id); - var memberRoles = member? + return member? .RoleIds .Select(TryGetRole) .WhereNotNull() - .ToArray(); - - return memberRoles? - .Where(r => r.Color is not null) .OrderByDescending(r => r.Position) - .Select(r => r.Color) - .FirstOrDefault(); + .ToArray() ?? Array.Empty(); } public async ValueTask ResolveAssetUrlAsync(string url, CancellationToken cancellationToken = default) diff --git a/DiscordChatExporter.Core/Exporting/JsonMessageWriter.cs b/DiscordChatExporter.Core/Exporting/JsonMessageWriter.cs index 88d36d7..469de22 100644 --- a/DiscordChatExporter.Core/Exporting/JsonMessageWriter.cs +++ b/DiscordChatExporter.Core/Exporting/JsonMessageWriter.cs @@ -1,4 +1,5 @@ -using System.IO; +using System.Collections.Generic; +using System.IO; using System.Text.Encodings.Web; using System.Text.Json; using System.Threading; @@ -48,6 +49,9 @@ internal class JsonMessageWriter : MessageWriter _writer.WriteString("color", Context.TryGetUserColor(user.Id)?.ToHex()); _writer.WriteBoolean("isBot", user.IsBot); + _writer.WritePropertyName("roles"); + await WriteRolesAsync(Context.GetUserRoles(user.Id), cancellationToken); + _writer.WriteString( "avatarUrl", await Context.ResolveAssetUrlAsync( @@ -60,6 +64,28 @@ internal class JsonMessageWriter : MessageWriter await _writer.FlushAsync(cancellationToken); } + private async ValueTask WriteRolesAsync( + IReadOnlyList roles, + CancellationToken cancellationToken = default) + { + _writer.WriteStartArray(); + + foreach (var role in roles) + { + _writer.WriteStartObject(); + + _writer.WriteString("id", role.Id.ToString()); + _writer.WriteString("name", role.Name); + _writer.WriteString("color", role.Color?.ToHex()); + _writer.WriteNumber("position", role.Position); + + _writer.WriteEndObject(); + } + + _writer.WriteEndArray(); + await _writer.FlushAsync(cancellationToken); + } + private async ValueTask WriteEmbedAuthorAsync( EmbedAuthor embedAuthor, CancellationToken cancellationToken = default)