Render server cross-posts properly

Closes #633
This commit is contained in:
Tyrrrz 2023-02-09 18:44:24 +02:00
parent 93799eb231
commit 049338009e
22 changed files with 96 additions and 43 deletions

View file

@ -0,0 +1,8 @@
using Xunit;
namespace DiscordChatExporter.Cli.Tests.Fixtures;
[CollectionDefinition(nameof(ExportWrapperCollection))]
public class ExportWrapperCollection : ICollectionFixture<ExportWrapperFixture>
{
}

View file

@ -6,7 +6,8 @@ using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs;
public class CsvContentSpecs : IClassFixture<ExportWrapperFixture>
[Collection(nameof(ExportWrapperCollection))]
public class CsvContentSpecs
{
private readonly ExportWrapperFixture _exportWrapper;

View file

@ -15,6 +15,7 @@ using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs;
[Collection(nameof(ExportWrapperCollection))]
public class DateRangeSpecs : IClassFixture<TempOutputFixture>
{
private readonly TempOutputFixture _tempOutput;

View file

@ -14,6 +14,7 @@ using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs;
[Collection(nameof(ExportWrapperCollection))]
public class FilterSpecs : IClassFixture<TempOutputFixture>
{
private readonly TempOutputFixture _tempOutput;

View file

@ -9,7 +9,8 @@ using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs;
public class HtmlAttachmentSpecs : IClassFixture<ExportWrapperFixture>
[Collection(nameof(ExportWrapperCollection))]
public class HtmlAttachmentSpecs
{
private readonly ExportWrapperFixture _exportWrapper;

View file

@ -3,12 +3,14 @@ using System.Threading.Tasks;
using AngleSharp.Dom;
using DiscordChatExporter.Cli.Tests.Fixtures;
using DiscordChatExporter.Cli.Tests.TestData;
using DiscordChatExporter.Core.Discord;
using FluentAssertions;
using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs;
public class HtmlContentSpecs : IClassFixture<ExportWrapperFixture>
[Collection(nameof(ExportWrapperCollection))]
public class HtmlContentSpecs
{
private readonly ExportWrapperFixture _exportWrapper;
@ -46,4 +48,21 @@ public class HtmlContentSpecs : IClassFixture<ExportWrapperFixture>
"Yeet"
);
}
[Fact]
public async Task Messages_cross_posted_from_other_guilds_are_rendered_with_the_server_tag()
{
// https://github.com/Tyrrrz/DiscordChatExporter/issues/633
// Act
var message = await _exportWrapper.GetMessageAsHtmlAsync(
ChannelIds.ReplyTestCases,
Snowflake.Parse("1072165330853576876")
);
// Assert
message.Text().Should().Contain("This is a test message from an announcement channel on another server");
message.Text().Should().Contain("SERVER");
message.QuerySelector(".chatlog__reply-link").Should().BeNull();
}
}

View file

@ -9,7 +9,8 @@ using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs;
public class HtmlEmbedSpecs : IClassFixture<ExportWrapperFixture>
[Collection(nameof(ExportWrapperCollection))]
public class HtmlEmbedSpecs
{
private readonly ExportWrapperFixture _exportWrapper;

View file

@ -13,6 +13,7 @@ using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs;
[Collection(nameof(ExportWrapperCollection))]
public class HtmlGroupingSpecs : IClassFixture<TempOutputFixture>
{
private readonly TempOutputFixture _tempOutput;

View file

@ -8,7 +8,8 @@ using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs;
public class HtmlMentionSpecs : IClassFixture<ExportWrapperFixture>
[Collection(nameof(ExportWrapperCollection))]
public class HtmlMentionSpecs
{
private readonly ExportWrapperFixture _exportWrapper;

View file

@ -8,7 +8,8 @@ using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs;
public class HtmlReplySpecs : IClassFixture<ExportWrapperFixture>
[Collection(nameof(ExportWrapperCollection))]
public class HtmlReplySpecs
{
private readonly ExportWrapperFixture _exportWrapper;
@ -28,7 +29,7 @@ public class HtmlReplySpecs : IClassFixture<ExportWrapperFixture>
// Assert
message.Text().Should().Contain("reply to original");
message.QuerySelector(".chatlog__reference-link")?.Text().Should().Contain("original");
message.QuerySelector(".chatlog__reply-link")?.Text().Should().Contain("original");
}
[Fact]
@ -44,7 +45,7 @@ public class HtmlReplySpecs : IClassFixture<ExportWrapperFixture>
// Assert
message.Text().Should().Contain("reply to deleted");
message.QuerySelector(".chatlog__reference-link")?.Text().Should().Contain(
message.QuerySelector(".chatlog__reply-link")?.Text().Should().Contain(
"Original message was deleted or could not be loaded."
);
}
@ -62,6 +63,6 @@ public class HtmlReplySpecs : IClassFixture<ExportWrapperFixture>
// Assert
message.Text().Should().Contain("reply to attachment");
message.QuerySelector(".chatlog__reference-link")?.Text().Should().Contain("Click to see attachment");
message.QuerySelector(".chatlog__reply-link")?.Text().Should().Contain("Click to see attachment");
}
}

View file

@ -7,7 +7,8 @@ using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs;
public class HtmlStickerSpecs : IClassFixture<ExportWrapperFixture>
[Collection(nameof(ExportWrapperCollection))]
public class HtmlStickerSpecs
{
private readonly ExportWrapperFixture _exportWrapper;

View file

@ -8,7 +8,8 @@ using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs;
public class JsonAttachmentSpecs : IClassFixture<ExportWrapperFixture>
[Collection(nameof(ExportWrapperCollection))]
public class JsonAttachmentSpecs
{
private readonly ExportWrapperFixture _exportWrapper;

View file

@ -7,7 +7,8 @@ using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs;
public class JsonContentSpecs : IClassFixture<ExportWrapperFixture>
[Collection(nameof(ExportWrapperCollection))]
public class JsonContentSpecs
{
private readonly ExportWrapperFixture _exportWrapper;

View file

@ -8,7 +8,8 @@ using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs;
public class JsonEmbedSpecs : IClassFixture<ExportWrapperFixture>
[Collection(nameof(ExportWrapperCollection))]
public class JsonEmbedSpecs
{
private readonly ExportWrapperFixture _exportWrapper;

View file

@ -8,7 +8,8 @@ using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs;
public class JsonMentionSpecs : IClassFixture<ExportWrapperFixture>
[Collection(nameof(ExportWrapperCollection))]
public class JsonMentionSpecs
{
private readonly ExportWrapperFixture _exportWrapper;

View file

@ -8,7 +8,8 @@ using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs;
public class JsonStickerSpecs : IClassFixture<ExportWrapperFixture>
[Collection(nameof(ExportWrapperCollection))]
public class JsonStickerSpecs
{
private readonly ExportWrapperFixture _exportWrapper;

View file

@ -12,6 +12,7 @@ using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs;
[Collection(nameof(ExportWrapperCollection))]
public class PartitioningSpecs : IClassFixture<TempOutputFixture>
{
private readonly TempOutputFixture _tempOutput;

View file

@ -6,7 +6,8 @@ using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs;
public class PlainTextContentSpecs : IClassFixture<ExportWrapperFixture>
[Collection(nameof(ExportWrapperCollection))]
public class PlainTextContentSpecs
{
private readonly ExportWrapperFixture _exportWrapper;

View file

@ -13,6 +13,7 @@ using Xunit;
namespace DiscordChatExporter.Cli.Tests.Specs;
[Collection(nameof(ExportWrapperCollection))]
public class SelfContainedSpecs : IClassFixture<TempOutputFixture>
{
private readonly TempOutputFixture _tempOutput;

View file

@ -1,5 +1,6 @@
{
"$schema": "https://xunit.net/schema/current/xunit.runner.schema.json",
"methodDisplayOptions": "all",
"methodDisplay": "method"
"methodDisplay": "method",
"parallelizeTestCollections": true
}

View file

@ -104,10 +104,10 @@
<div class="chatlog__message-aside">
@if (isFirst)
{
// Reference symbol
if (message.Reference is not null)
// Reply symbol
if (message.Kind == MessageKind.Reply)
{
<div class="chatlog__reference-symbol"></div>
<div class="chatlog__reply-symbol"></div>
}
// Avatar
@ -122,16 +122,16 @@
<div class="chatlog__message-primary">
@if (isFirst)
{
// Reference
if (message.Reference is not null)
// Reply
if (message.Kind == MessageKind.Reply && message.Reference is not null)
{
<div class="chatlog__reference">
<div class="chatlog__reply">
@if (message.ReferencedMessage is not null)
{
<img class="chatlog__reference-avatar" src="@await ResolveAssetUrlAsync(message.ReferencedMessage.Author.AvatarUrl)" alt="Avatar" loading="lazy">
<div class="chatlog__reference-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__reference-content">
<span class="chatlog__reference-link" onclick="scrollToMessage(event, '@message.ReferencedMessage.Id')">
<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-content">
<span class="chatlog__reply-link" onclick="scrollToMessage(event, '@message.ReferencedMessage.Id')">
@if (!string.IsNullOrWhiteSpace(message.ReferencedMessage.Content) && !message.ReferencedMessage.IsContentHidden())
{
<!--wmm:ignore-->@Html.Raw(await FormatEmbedMarkdownAsync(message.ReferencedMessage.Content))<!--/wmm:ignore-->
@ -149,13 +149,13 @@
@if (message.ReferencedMessage.EditedTimestamp is not null)
{
<span class="chatlog__reference-edited-timestamp" title="@FormatDate(message.ReferencedMessage.EditedTimestamp.Value)">(edited)</span>
<span class="chatlog__reply-edited-timestamp" title="@FormatDate(message.ReferencedMessage.EditedTimestamp.Value)">(edited)</span>
}
</div>
}
else
{
<div class="chatlog__reference-unknown">
<div class="chatlog__reply-unknown">
Original message was deleted or could not be loaded.
</div>
}
@ -170,7 +170,15 @@
@{/* Bot label */}
@if (message.Author.IsBot)
{
<span class="chatlog__bot-label">BOT</span>
// For cross-posts, the BOT tag is replaced with the SERVER tag
if (message.Kind != MessageKind.Reply && message.Reference is not null && message.Reference.GuildId != ExportContext.Request.Guild.Id)
{
<span class="chatlog__author-tag">SERVER</span>
}
else
{
<span class="chatlog__author-tag">BOT</span>
}
}
@{/* Timestamp */}

View file

@ -173,7 +173,7 @@
text-align: center;
}
.chatlog__reference-symbol {
.chatlog__reply-symbol {
height: 10px;
margin: 6px 4px 4px 36px;
border-left: 2px solid @Themed("#4f545c", "#c7ccd1");
@ -201,7 +201,7 @@
min-width: 0;
}
.chatlog__reference {
.chatlog__reply {
display: flex;
margin-bottom: 0.15rem;
align-items: center;
@ -212,49 +212,49 @@
text-overflow: ellipsis;
}
.chatlog__reference-avatar {
.chatlog__reply-avatar {
width: 16px;
height: 16px;
margin-right: 0.25rem;
border-radius: 50%;
}
.chatlog__reference-author {
.chatlog__reply-author {
margin-right: 0.3rem;
font-weight: 600;
}
.chatlog__reference-content {
.chatlog__reply-content {
overflow: hidden;
text-overflow: ellipsis;
}
.chatlog__reference-link {
.chatlog__reply-link {
cursor: pointer;
}
.chatlog__reference-link * {
.chatlog__reply-link * {
display: inline;
pointer-events: none;
}
.chatlog__reference-link .chatlog__markdown-quote {
.chatlog__reply-link .chatlog__markdown-quote {
display: inline;
}
.chatlog__reference-link .chatlog__markdown-pre {
.chatlog__reply-link .chatlog__markdown-pre {
display: inline;
}
.chatlog__reference-link:hover {
.chatlog__reply-link:hover {
color: @Themed("#ffffff", "#2f3136");
}
.chatlog__reference-link:hover *:not(.chatlog__markdown-spoiler) {
.chatlog__reply-link:hover *:not(.chatlog__markdown-spoiler) {
color: inherit;
}
.chatlog__reference-edited-timestamp {
.chatlog__reply-edited-timestamp {
margin-left: 0.25rem;
color: @Themed("#a3a6aa", "#5e6772");
font-size: 0.75rem;
@ -304,7 +304,7 @@
color: @Themed("#ffffff", "#2f3136");
}
.chatlog__bot-label {
.chatlog__author-tag {
position: relative;
top: -0.1rem;
margin-left: 0.3rem;