mirror of
https://github.com/Tyrrrz/DiscordChatExporter.git
synced 2026-02-10 20:02:31 +00:00
@@ -56,4 +56,19 @@ public class HtmlReplySpecs
|
|||||||
message.Text().Should().Contain("reply to attachment");
|
message.Text().Should().Contain("reply to attachment");
|
||||||
message.QuerySelector(".chatlog__reply-link")?.Text().Should().Contain("Click to see attachment");
|
message.QuerySelector(".chatlog__reply-link")?.Text().Should().Contain("Click to see attachment");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Message_with_a_reply_to_an_interaction_is_rendered_correctly()
|
||||||
|
{
|
||||||
|
// https://github.com/Tyrrrz/DiscordChatExporter/issues/569
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var message = await ExportWrapper.GetMessageAsHtmlAsync(
|
||||||
|
ChannelIds.ReplyTestCases,
|
||||||
|
Snowflake.Parse("1075152916417085492")
|
||||||
|
);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
message.Text().Should().Contain("used /poll");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
18
DiscordChatExporter.Core/Discord/Data/Interaction.cs
Normal file
18
DiscordChatExporter.Core/Discord/Data/Interaction.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
using System.Text.Json;
|
||||||
|
using DiscordChatExporter.Core.Utils.Extensions;
|
||||||
|
using JsonExtensions.Reading;
|
||||||
|
|
||||||
|
namespace DiscordChatExporter.Core.Discord.Data;
|
||||||
|
|
||||||
|
// https://discord.com/developers/docs/interactions/receiving-and-responding#message-interaction-object
|
||||||
|
public record Interaction(Snowflake Id, string Name, User User)
|
||||||
|
{
|
||||||
|
public static Interaction Parse(JsonElement json)
|
||||||
|
{
|
||||||
|
var id = json.GetProperty("id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse);
|
||||||
|
var name = json.GetProperty("name").GetNonWhiteSpaceString();
|
||||||
|
var user = json.GetProperty("user").Pipe(User.Parse);
|
||||||
|
|
||||||
|
return new Interaction(id, name, user);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,7 +10,7 @@ using JsonExtensions.Reading;
|
|||||||
namespace DiscordChatExporter.Core.Discord.Data;
|
namespace DiscordChatExporter.Core.Discord.Data;
|
||||||
|
|
||||||
// https://discord.com/developers/docs/resources/channel#message-object
|
// https://discord.com/developers/docs/resources/channel#message-object
|
||||||
public record Message(
|
public partial record Message(
|
||||||
Snowflake Id,
|
Snowflake Id,
|
||||||
MessageKind Kind,
|
MessageKind Kind,
|
||||||
MessageFlags Flags,
|
MessageFlags Flags,
|
||||||
@@ -26,7 +26,27 @@ public record Message(
|
|||||||
IReadOnlyList<Reaction> Reactions,
|
IReadOnlyList<Reaction> Reactions,
|
||||||
IReadOnlyList<User> MentionedUsers,
|
IReadOnlyList<User> MentionedUsers,
|
||||||
MessageReference? Reference,
|
MessageReference? Reference,
|
||||||
Message? ReferencedMessage) : IHasId
|
Message? ReferencedMessage,
|
||||||
|
Interaction? Interaction) : IHasId
|
||||||
|
{
|
||||||
|
public bool IsReplyLike => Kind == MessageKind.Reply || Interaction is not null;
|
||||||
|
|
||||||
|
public IEnumerable<User> GetReferencedUsers()
|
||||||
|
{
|
||||||
|
yield return Author;
|
||||||
|
|
||||||
|
foreach (var user in MentionedUsers)
|
||||||
|
yield return user;
|
||||||
|
|
||||||
|
if (ReferencedMessage is not null)
|
||||||
|
yield return ReferencedMessage.Author;
|
||||||
|
|
||||||
|
if (Interaction is not null)
|
||||||
|
yield return Interaction.User;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial record Message
|
||||||
{
|
{
|
||||||
private static IReadOnlyList<Embed> NormalizeEmbeds(IReadOnlyList<Embed> embeds)
|
private static IReadOnlyList<Embed> NormalizeEmbeds(IReadOnlyList<Embed> embeds)
|
||||||
{
|
{
|
||||||
@@ -124,6 +144,7 @@ public record Message(
|
|||||||
|
|
||||||
var messageReference = json.GetPropertyOrNull("message_reference")?.Pipe(MessageReference.Parse);
|
var messageReference = json.GetPropertyOrNull("message_reference")?.Pipe(MessageReference.Parse);
|
||||||
var referencedMessage = json.GetPropertyOrNull("referenced_message")?.Pipe(Parse);
|
var referencedMessage = json.GetPropertyOrNull("referenced_message")?.Pipe(Parse);
|
||||||
|
var interaction = json.GetPropertyOrNull("interaction")?.Pipe(Interaction.Parse);
|
||||||
|
|
||||||
return new Message(
|
return new Message(
|
||||||
id,
|
id,
|
||||||
@@ -141,7 +162,8 @@ public record Message(
|
|||||||
reactions,
|
reactions,
|
||||||
mentionedUsers,
|
mentionedUsers,
|
||||||
messageReference,
|
messageReference,
|
||||||
referencedMessage
|
referencedMessage,
|
||||||
|
interaction
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using DiscordChatExporter.Core.Discord;
|
using DiscordChatExporter.Core.Discord;
|
||||||
@@ -33,8 +32,8 @@ public class ChannelExporter
|
|||||||
progress,
|
progress,
|
||||||
cancellationToken))
|
cancellationToken))
|
||||||
{
|
{
|
||||||
// Resolve members for the author and mentioned users
|
// Resolve members for referenced users
|
||||||
foreach (var user in message.MentionedUsers.Prepend(message.Author))
|
foreach (var user in message.GetReferencedUsers())
|
||||||
await context.PopulateMemberAsync(user.Id, cancellationToken);
|
await context.PopulateMemberAsync(user.Id, cancellationToken);
|
||||||
|
|
||||||
// Export the message
|
// Export the message
|
||||||
|
|||||||
@@ -35,16 +35,23 @@ internal class JsonMessageWriter : MessageWriter
|
|||||||
? await PlainTextMarkdownVisitor.FormatAsync(Context, markdown, cancellationToken)
|
? await PlainTextMarkdownVisitor.FormatAsync(Context, markdown, cancellationToken)
|
||||||
: markdown;
|
: markdown;
|
||||||
|
|
||||||
private async ValueTask WriteAttachmentAsync(
|
private async ValueTask WriteUserAsync(
|
||||||
Attachment attachment,
|
User user,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
_writer.WriteStartObject();
|
_writer.WriteStartObject();
|
||||||
|
|
||||||
_writer.WriteString("id", attachment.Id.ToString());
|
_writer.WriteString("id", user.Id.ToString());
|
||||||
_writer.WriteString("url", await Context.ResolveAssetUrlAsync(attachment.Url, cancellationToken));
|
_writer.WriteString("name", user.Name);
|
||||||
_writer.WriteString("fileName", attachment.FileName);
|
_writer.WriteString("discriminator", user.DiscriminatorFormatted);
|
||||||
_writer.WriteNumber("fileSizeBytes", attachment.FileSize.TotalBytes);
|
_writer.WriteString("nickname", Context.TryGetMember(user.Id)?.Nick ?? user.Name);
|
||||||
|
_writer.WriteString("color", Context.TryGetUserColor(user.Id)?.ToHex());
|
||||||
|
_writer.WriteBoolean("isBot", user.IsBot);
|
||||||
|
|
||||||
|
_writer.WriteString(
|
||||||
|
"avatarUrl",
|
||||||
|
await Context.ResolveAssetUrlAsync(user.AvatarUrl, cancellationToken)
|
||||||
|
);
|
||||||
|
|
||||||
_writer.WriteEndObject();
|
_writer.WriteEndObject();
|
||||||
await _writer.FlushAsync(cancellationToken);
|
await _writer.FlushAsync(cancellationToken);
|
||||||
@@ -184,58 +191,6 @@ internal class JsonMessageWriter : MessageWriter
|
|||||||
await _writer.FlushAsync(cancellationToken);
|
await _writer.FlushAsync(cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async ValueTask WriteStickerAsync(
|
|
||||||
Sticker sticker,
|
|
||||||
CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
_writer.WriteStartObject();
|
|
||||||
|
|
||||||
_writer.WriteString("id", sticker.Id.ToString());
|
|
||||||
_writer.WriteString("name", sticker.Name);
|
|
||||||
_writer.WriteString("format", sticker.Format.ToString());
|
|
||||||
_writer.WriteString("sourceUrl", await Context.ResolveAssetUrlAsync(sticker.SourceUrl, cancellationToken));
|
|
||||||
|
|
||||||
_writer.WriteEndObject();
|
|
||||||
await _writer.FlushAsync(cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async ValueTask WriteReactionAsync(
|
|
||||||
Reaction reaction,
|
|
||||||
CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
_writer.WriteStartObject();
|
|
||||||
|
|
||||||
// Emoji
|
|
||||||
_writer.WriteStartObject("emoji");
|
|
||||||
_writer.WriteString("id", reaction.Emoji.Id.ToString());
|
|
||||||
_writer.WriteString("name", reaction.Emoji.Name);
|
|
||||||
_writer.WriteString("code", reaction.Emoji.Code);
|
|
||||||
_writer.WriteBoolean("isAnimated", reaction.Emoji.IsAnimated);
|
|
||||||
_writer.WriteString("imageUrl", await Context.ResolveAssetUrlAsync(reaction.Emoji.ImageUrl, cancellationToken));
|
|
||||||
_writer.WriteEndObject();
|
|
||||||
|
|
||||||
_writer.WriteNumber("count", reaction.Count);
|
|
||||||
|
|
||||||
_writer.WriteEndObject();
|
|
||||||
await _writer.FlushAsync(cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async ValueTask WriteMentionAsync(
|
|
||||||
User mentionedUser,
|
|
||||||
CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
_writer.WriteStartObject();
|
|
||||||
|
|
||||||
_writer.WriteString("id", mentionedUser.Id.ToString());
|
|
||||||
_writer.WriteString("name", mentionedUser.Name);
|
|
||||||
_writer.WriteString("discriminator", mentionedUser.DiscriminatorFormatted);
|
|
||||||
_writer.WriteString("nickname", Context.TryGetMember(mentionedUser.Id)?.Nick ?? mentionedUser.Name);
|
|
||||||
_writer.WriteBoolean("isBot", mentionedUser.IsBot);
|
|
||||||
|
|
||||||
_writer.WriteEndObject();
|
|
||||||
await _writer.FlushAsync(cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async ValueTask WritePreambleAsync(CancellationToken cancellationToken = default)
|
public override async ValueTask WritePreambleAsync(CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
// Root object (start)
|
// Root object (start)
|
||||||
@@ -310,26 +265,23 @@ internal class JsonMessageWriter : MessageWriter
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Author
|
// Author
|
||||||
_writer.WriteStartObject("author");
|
_writer.WritePropertyName("author");
|
||||||
_writer.WriteString("id", message.Author.Id.ToString());
|
await WriteUserAsync(message.Author, cancellationToken);
|
||||||
_writer.WriteString("name", message.Author.Name);
|
|
||||||
_writer.WriteString("discriminator", message.Author.DiscriminatorFormatted);
|
|
||||||
_writer.WriteString("nickname", Context.TryGetMember(message.Author.Id)?.Nick ?? message.Author.Name);
|
|
||||||
_writer.WriteString("color", Context.TryGetUserColor(message.Author.Id)?.ToHex());
|
|
||||||
_writer.WriteBoolean("isBot", message.Author.IsBot);
|
|
||||||
|
|
||||||
_writer.WriteString(
|
|
||||||
"avatarUrl",
|
|
||||||
await Context.ResolveAssetUrlAsync(message.Author.AvatarUrl, cancellationToken)
|
|
||||||
);
|
|
||||||
|
|
||||||
_writer.WriteEndObject();
|
|
||||||
|
|
||||||
// Attachments
|
// Attachments
|
||||||
_writer.WriteStartArray("attachments");
|
_writer.WriteStartArray("attachments");
|
||||||
|
|
||||||
foreach (var attachment in message.Attachments)
|
foreach (var attachment in message.Attachments)
|
||||||
await WriteAttachmentAsync(attachment, cancellationToken);
|
{
|
||||||
|
_writer.WriteStartObject();
|
||||||
|
|
||||||
|
_writer.WriteString("id", attachment.Id.ToString());
|
||||||
|
_writer.WriteString("url", await Context.ResolveAssetUrlAsync(attachment.Url, cancellationToken));
|
||||||
|
_writer.WriteString("fileName", attachment.FileName);
|
||||||
|
_writer.WriteNumber("fileSizeBytes", attachment.FileSize.TotalBytes);
|
||||||
|
|
||||||
|
_writer.WriteEndObject();
|
||||||
|
}
|
||||||
|
|
||||||
_writer.WriteEndArray();
|
_writer.WriteEndArray();
|
||||||
|
|
||||||
@@ -345,7 +297,16 @@ internal class JsonMessageWriter : MessageWriter
|
|||||||
_writer.WriteStartArray("stickers");
|
_writer.WriteStartArray("stickers");
|
||||||
|
|
||||||
foreach (var sticker in message.Stickers)
|
foreach (var sticker in message.Stickers)
|
||||||
await WriteStickerAsync(sticker, cancellationToken);
|
{
|
||||||
|
_writer.WriteStartObject();
|
||||||
|
|
||||||
|
_writer.WriteString("id", sticker.Id.ToString());
|
||||||
|
_writer.WriteString("name", sticker.Name);
|
||||||
|
_writer.WriteString("format", sticker.Format.ToString());
|
||||||
|
_writer.WriteString("sourceUrl", await Context.ResolveAssetUrlAsync(sticker.SourceUrl, cancellationToken));
|
||||||
|
|
||||||
|
_writer.WriteEndObject();
|
||||||
|
}
|
||||||
|
|
||||||
_writer.WriteEndArray();
|
_writer.WriteEndArray();
|
||||||
|
|
||||||
@@ -353,15 +314,30 @@ internal class JsonMessageWriter : MessageWriter
|
|||||||
_writer.WriteStartArray("reactions");
|
_writer.WriteStartArray("reactions");
|
||||||
|
|
||||||
foreach (var reaction in message.Reactions)
|
foreach (var reaction in message.Reactions)
|
||||||
await WriteReactionAsync(reaction, cancellationToken);
|
{
|
||||||
|
_writer.WriteStartObject();
|
||||||
|
|
||||||
|
// Emoji
|
||||||
|
_writer.WriteStartObject("emoji");
|
||||||
|
_writer.WriteString("id", reaction.Emoji.Id.ToString());
|
||||||
|
_writer.WriteString("name", reaction.Emoji.Name);
|
||||||
|
_writer.WriteString("code", reaction.Emoji.Code);
|
||||||
|
_writer.WriteBoolean("isAnimated", reaction.Emoji.IsAnimated);
|
||||||
|
_writer.WriteString("imageUrl", await Context.ResolveAssetUrlAsync(reaction.Emoji.ImageUrl, cancellationToken));
|
||||||
|
_writer.WriteEndObject();
|
||||||
|
|
||||||
|
_writer.WriteNumber("count", reaction.Count);
|
||||||
|
|
||||||
|
_writer.WriteEndObject();
|
||||||
|
}
|
||||||
|
|
||||||
_writer.WriteEndArray();
|
_writer.WriteEndArray();
|
||||||
|
|
||||||
// Mentions
|
// Mentions
|
||||||
_writer.WriteStartArray("mentions");
|
_writer.WriteStartArray("mentions");
|
||||||
|
|
||||||
foreach (var mention in message.MentionedUsers)
|
foreach (var user in message.MentionedUsers)
|
||||||
await WriteMentionAsync(mention, cancellationToken);
|
await WriteUserAsync(user, cancellationToken);
|
||||||
|
|
||||||
_writer.WriteEndArray();
|
_writer.WriteEndArray();
|
||||||
|
|
||||||
@@ -375,6 +351,20 @@ internal class JsonMessageWriter : MessageWriter
|
|||||||
_writer.WriteEndObject();
|
_writer.WriteEndObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Interaction
|
||||||
|
if (message.Interaction is not null)
|
||||||
|
{
|
||||||
|
_writer.WriteStartObject("interaction");
|
||||||
|
|
||||||
|
_writer.WriteString("id", message.Interaction.Id.ToString());
|
||||||
|
_writer.WriteString("name", message.Interaction.Name);
|
||||||
|
|
||||||
|
_writer.WritePropertyName("user");
|
||||||
|
await WriteUserAsync(message.Interaction.User, cancellationToken);
|
||||||
|
|
||||||
|
_writer.WriteEndObject();
|
||||||
|
}
|
||||||
|
|
||||||
_writer.WriteEndObject();
|
_writer.WriteEndObject();
|
||||||
await _writer.FlushAsync(cancellationToken);
|
await _writer.FlushAsync(cancellationToken);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,30 +31,6 @@
|
|||||||
Context.Request.ShouldFormatMarkdown
|
Context.Request.ShouldFormatMarkdown
|
||||||
? await HtmlMarkdownVisitor.FormatAsync(Context, markdown, false, CancellationToken)
|
? await HtmlMarkdownVisitor.FormatAsync(Context, markdown, false, CancellationToken)
|
||||||
: markdown;
|
: markdown;
|
||||||
|
|
||||||
var firstMessage = Messages.First();
|
|
||||||
|
|
||||||
var userMember = Context.TryGetMember(firstMessage.Author.Id);
|
|
||||||
|
|
||||||
var userColor = Context.TryGetUserColor(firstMessage.Author.Id);
|
|
||||||
|
|
||||||
var userNick = firstMessage.Author.IsBot
|
|
||||||
? firstMessage.Author.Name
|
|
||||||
: userMember?.Nick ?? firstMessage.Author.Name;
|
|
||||||
|
|
||||||
var referencedUserMember = firstMessage.ReferencedMessage is not null
|
|
||||||
? Context.TryGetMember(firstMessage.ReferencedMessage.Author.Id)
|
|
||||||
: null;
|
|
||||||
|
|
||||||
var referencedUserColor = firstMessage.ReferencedMessage is not null
|
|
||||||
? Context.TryGetUserColor(firstMessage.ReferencedMessage.Author.Id)
|
|
||||||
: null;
|
|
||||||
|
|
||||||
var referencedUserNick = firstMessage.ReferencedMessage is not null
|
|
||||||
? firstMessage.ReferencedMessage.Author.IsBot
|
|
||||||
? firstMessage.ReferencedMessage.Author.Name
|
|
||||||
: referencedUserMember?.Nick ?? firstMessage.ReferencedMessage.Author.Name
|
|
||||||
: null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<div class="chatlog__message-group">
|
<div class="chatlog__message-group">
|
||||||
@@ -62,19 +38,17 @@
|
|||||||
{
|
{
|
||||||
var isFirst = i == 0;
|
var isFirst = i == 0;
|
||||||
|
|
||||||
|
var authorMember = Context.TryGetMember(message.Author.Id);
|
||||||
|
var authorColor = Context.TryGetUserColor(message.Author.Id);
|
||||||
|
var authorNick = message.Author.IsBot
|
||||||
|
? message.Author.Name
|
||||||
|
: authorMember?.Nick ?? message.Author.Name;
|
||||||
|
|
||||||
<div id="chatlog__message-container-@message.Id" class="chatlog__message-container @(message.IsPinned ? "chatlog__message-container--pinned" : null)" data-message-id="@message.Id">
|
<div id="chatlog__message-container-@message.Id" class="chatlog__message-container @(message.IsPinned ? "chatlog__message-container--pinned" : null)" data-message-id="@message.Id">
|
||||||
<div class="chatlog__message">
|
<div class="chatlog__message">
|
||||||
@{/* System notification */}
|
@{/* System notification */}
|
||||||
@if (message.Kind.IsSystemNotification())
|
@if (message.Kind.IsSystemNotification())
|
||||||
{
|
{
|
||||||
// System notifications are grouped even if the message author is different.
|
|
||||||
// That's why we have to update the user values with the author of the current message.
|
|
||||||
userMember = Context.TryGetMember(message.Author.Id);
|
|
||||||
userColor = Context.TryGetUserColor(message.Author.Id);
|
|
||||||
userNick = message.Author.IsBot
|
|
||||||
? message.Author.Name
|
|
||||||
: userMember?.Nick ?? message.Author.Name;
|
|
||||||
|
|
||||||
<div class="chatlog__message-aside">
|
<div class="chatlog__message-aside">
|
||||||
<svg class="chatlog__system-notification-icon">
|
<svg class="chatlog__system-notification-icon">
|
||||||
@{
|
@{
|
||||||
@@ -97,7 +71,7 @@
|
|||||||
|
|
||||||
<div class="chatlog__message-primary">
|
<div class="chatlog__message-primary">
|
||||||
@{/* Author name */}
|
@{/* Author name */}
|
||||||
<span class="chatlog__system-notification-author" style="@(userColor is not null ? $"color: rgb({userColor.Value.R}, {userColor.Value.G}, {userColor.Value.B})" : null)" title="@message.Author.FullName" data-user-id="@message.Author.Id">@userNick</span>
|
<span class="chatlog__system-notification-author" style="@(authorColor is not null ? $"color: rgb({authorColor.Value.R}, {authorColor.Value.G}, {authorColor.Value.B})" : null)" title="@message.Author.FullName" data-user-id="@message.Author.Id">@authorNick</span>
|
||||||
|
|
||||||
@{/* Space out the content */}
|
@{/* Space out the content */}
|
||||||
<span> </span>
|
<span> </span>
|
||||||
@@ -169,7 +143,7 @@
|
|||||||
@if (isFirst)
|
@if (isFirst)
|
||||||
{
|
{
|
||||||
// Reply symbol
|
// Reply symbol
|
||||||
if (message.Kind == MessageKind.Reply)
|
if (message.IsReplyLike)
|
||||||
{
|
{
|
||||||
<div class="chatlog__reply-symbol"></div>
|
<div class="chatlog__reply-symbol"></div>
|
||||||
}
|
}
|
||||||
@@ -186,12 +160,18 @@
|
|||||||
<div class="chatlog__message-primary">
|
<div class="chatlog__message-primary">
|
||||||
@if (isFirst)
|
@if (isFirst)
|
||||||
{
|
{
|
||||||
// Reply
|
// Message referenced by the reply
|
||||||
if (message.Kind == MessageKind.Reply && message.Reference is not null)
|
if (message.IsReplyLike)
|
||||||
{
|
{
|
||||||
<div class="chatlog__reply">
|
<div class="chatlog__reply">
|
||||||
@if (message.ReferencedMessage is not null)
|
@if (message.ReferencedMessage is not null)
|
||||||
{
|
{
|
||||||
|
var referencedUserMember = Context.TryGetMember(message.ReferencedMessage.Author.Id);
|
||||||
|
var referencedUserColor = Context.TryGetUserColor(message.ReferencedMessage.Author.Id);
|
||||||
|
var referencedUserNick = message.ReferencedMessage.Author.IsBot
|
||||||
|
? message.ReferencedMessage.Author.Name
|
||||||
|
: referencedUserMember?.Nick ?? message.ReferencedMessage.Author.Name;
|
||||||
|
|
||||||
<img class="chatlog__reply-avatar" src="@await ResolveAssetUrlAsync(message.ReferencedMessage.Author.AvatarUrl)" alt="Avatar" loading="lazy">
|
<img class="chatlog__reply-avatar" src="@await ResolveAssetUrlAsync(message.ReferencedMessage.Author.AvatarUrl)" alt="Avatar" loading="lazy">
|
||||||
<div class="chatlog__reply-author" style="@(referencedUserColor is not null ? $"color: rgb({referencedUserColor.Value.R}, {referencedUserColor.Value.G}, {referencedUserColor.Value.B})" : null)" title="@message.ReferencedMessage.Author.FullName">@referencedUserNick</div>
|
<div class="chatlog__reply-author" style="@(referencedUserColor is not null ? $"color: rgb({referencedUserColor.Value.R}, {referencedUserColor.Value.G}, {referencedUserColor.Value.B})" : null)" title="@message.ReferencedMessage.Author.FullName">@referencedUserNick</div>
|
||||||
<div class="chatlog__reply-content">
|
<div class="chatlog__reply-content">
|
||||||
@@ -217,6 +197,20 @@
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
else if (message.Interaction is not null)
|
||||||
|
{
|
||||||
|
var interactionUserMember = Context.TryGetMember(message.Interaction.User.Id);
|
||||||
|
var interactionUserColor = Context.TryGetUserColor(message.Interaction.User.Id);
|
||||||
|
var interactionUserNick = message.Interaction.User.IsBot
|
||||||
|
? message.Interaction.User.Name
|
||||||
|
: interactionUserMember?.Nick ?? message.Interaction.User.Name;
|
||||||
|
|
||||||
|
<img class="chatlog__reply-avatar" src="@await ResolveAssetUrlAsync(message.Interaction.User.AvatarUrl)" alt="Avatar" loading="lazy">
|
||||||
|
<div class="chatlog__reply-author" style="@(interactionUserColor is not null ? $"color: rgb({interactionUserColor.Value.R}, {interactionUserColor.Value.G}, {interactionUserColor.Value.B})" : null)" title="@message.Interaction.User.FullName">@interactionUserNick</div>
|
||||||
|
<div class="chatlog__reply-content">
|
||||||
|
used /@message.Interaction.Name
|
||||||
|
</div>
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<div class="chatlog__reply-unknown">
|
<div class="chatlog__reply-unknown">
|
||||||
@@ -229,7 +223,7 @@
|
|||||||
// Header
|
// Header
|
||||||
<div class="chatlog__header">
|
<div class="chatlog__header">
|
||||||
@{/* Author name */}
|
@{/* Author name */}
|
||||||
<span class="chatlog__author" style="@(userColor is not null ? $"color: rgb({userColor.Value.R}, {userColor.Value.G}, {userColor.Value.B})" : null)" title="@message.Author.FullName" data-user-id="@message.Author.Id">@userNick</span>
|
<span class="chatlog__author" style="@(authorColor is not null ? $"color: rgb({authorColor.Value.R}, {authorColor.Value.G}, {authorColor.Value.B})" : null)" title="@message.Author.FullName" data-user-id="@message.Author.Id">@authorNick</span>
|
||||||
|
|
||||||
@{/* Bot tag */}
|
@{/* Bot tag */}
|
||||||
@if (message.Author.IsBot)
|
@if (message.Author.IsBot)
|
||||||
|
|||||||
Reference in New Issue
Block a user