Add HTML minification

Closes #345
Closes #743
pull/882/head
Oleksii Holub 2 years ago
parent 94ef4b6981
commit 4283ef22b1

@ -10,6 +10,7 @@
<PackageReference Include="MiniRazor.CodeGen" Version="2.2.1" />
<PackageReference Include="Polly" Version="7.2.3" />
<PackageReference Include="Superpower" Version="3.0.0" />
<PackageReference Include="WebMarkupMin.Core" Version="2.9.0" />
</ItemGroup>
<ItemGroup>

@ -85,7 +85,7 @@
<span class="chatlog__reference-link" onclick="scrollToMessage(event, '@message.ReferencedMessage.Id')">
@if (!string.IsNullOrWhiteSpace(message.ReferencedMessage.Content))
{
@Raw(FormatEmbedMarkdown(message.ReferencedMessage.Content))
<!--wmm:ignore-->@Raw(FormatEmbedMarkdown(message.ReferencedMessage.Content))<!--/wmm:ignore-->
}
else if (message.ReferencedMessage.Attachments.Any() || message.ReferencedMessage.Embeds.Any())
{
@ -134,7 +134,7 @@
{
<div class="chatlog__content chatlog__markdown">
@{/* Text */}
<span class="chatlog__markdown-preserve">@Raw(FormatMarkdown(message.Content))</span>
<span class="chatlog__markdown-preserve"><!--wmm:ignore-->@Raw(FormatMarkdown(message.Content))<!--/wmm:ignore--></span>
@{/* Edited timestamp */}
@if (message.EditedTimestamp is not null)
@ -262,12 +262,12 @@
@if (!string.IsNullOrWhiteSpace(embed.Url))
{
<a class="chatlog__embed-title-link" href="@embed.Url">
<div class="chatlog__markdown chatlog__markdown-preserve">@Raw(FormatEmbedMarkdown(embed.Title))</div>
<div class="chatlog__markdown chatlog__markdown-preserve"><!--wmm:ignore-->@Raw(FormatEmbedMarkdown(embed.Title))<!--/wmm:ignore--></div>
</a>
}
else
{
<div class="chatlog__markdown chatlog__markdown-preserve">@Raw(FormatEmbedMarkdown(embed.Title))</div>
<div class="chatlog__markdown chatlog__markdown-preserve"><!--wmm:ignore-->@Raw(FormatEmbedMarkdown(embed.Title))<!--/wmm:ignore--></div>
}
</div>
}
@ -330,12 +330,12 @@
@if (!string.IsNullOrWhiteSpace(embed.Url))
{
<a class="chatlog__embed-title-link" href="@embed.Url">
<div class="chatlog__markdown chatlog__markdown-preserve">@Raw(FormatEmbedMarkdown(embed.Title))</div>
<div class="chatlog__markdown chatlog__markdown-preserve"><!--wmm:ignore-->@Raw(FormatEmbedMarkdown(embed.Title))<!--/wmm:ignore--></div>
</a>
}
else
{
<div class="chatlog__markdown chatlog__markdown-preserve">@Raw(FormatEmbedMarkdown(embed.Title))</div>
<div class="chatlog__markdown chatlog__markdown-preserve"><!--wmm:ignore-->@Raw(FormatEmbedMarkdown(embed.Title))<!--/wmm:ignore--></div>
}
</div>
}
@ -344,7 +344,7 @@
@if (!string.IsNullOrWhiteSpace(embed.Description))
{
<div class="chatlog__embed-description">
<div class="chatlog__markdown chatlog__markdown-preserve">@Raw(FormatEmbedMarkdown(embed.Description))</div>
<div class="chatlog__markdown chatlog__markdown-preserve"><!--wmm:ignore-->@Raw(FormatEmbedMarkdown(embed.Description))<!--/wmm:ignore--></div>
</div>
}
@ -358,14 +358,14 @@
@if (!string.IsNullOrWhiteSpace(field.Name))
{
<div class="chatlog__embed-field-name">
<div class="chatlog__markdown chatlog__markdown-preserve">@Raw(FormatEmbedMarkdown(field.Name))</div>
<div class="chatlog__markdown chatlog__markdown-preserve"><!--wmm:ignore-->@Raw(FormatEmbedMarkdown(field.Name))<!--/wmm:ignore--></div>
</div>
}
@if (!string.IsNullOrWhiteSpace(field.Value))
{
<div class="chatlog__embed-field-value">
<div class="chatlog__markdown chatlog__markdown-preserve">@Raw(FormatEmbedMarkdown(field.Value))</div>
<div class="chatlog__markdown chatlog__markdown-preserve"><!--wmm:ignore-->@Raw(FormatEmbedMarkdown(field.Value))<!--/wmm:ignore--></div>
</div>
}
</div>
@ -462,4 +462,4 @@
</div>
</div>
}
</div>
</div>

@ -4,7 +4,9 @@
@inherits MiniRazor.TemplateBase<PostambleTemplateContext>
@{/* Close elements opened by preamble */}
<!--wmm:ignore-->
</div>
<!--/wmm:ignore-->
<div class="postamble">
<div class="postamble__entry">Exported @Model.MessagesWritten.ToString("N0") message(s)</div>

@ -807,4 +807,6 @@
</div>
@{/* Preamble cuts off at this point */}
<!--wmm:ignore-->
<div class="chatlog">
<!--/wmm:ignore-->

@ -6,6 +6,7 @@ using System.Threading;
using System.Threading.Tasks;
using DiscordChatExporter.Core.Discord.Data;
using DiscordChatExporter.Core.Exporting.Writers.Html;
using WebMarkupMin.Core;
namespace DiscordChatExporter.Core.Exporting.Writers;
@ -14,6 +15,7 @@ internal class HtmlMessageWriter : MessageWriter
private readonly TextWriter _writer;
private readonly string _themeName;
private readonly HtmlMinifier _minifier = new();
private readonly List<Message> _messageGroup = new();
public HtmlMessageWriter(Stream stream, ExportContext context, string themeName)
@ -23,22 +25,22 @@ internal class HtmlMessageWriter : MessageWriter
_themeName = themeName;
}
private bool CanJoinGroup(Message message)
{
var lastMessage = _messageGroup.LastOrDefault();
if (lastMessage is null)
return true;
return
// Must be from the same author
lastMessage.Author.Id == message.Author.Id &&
// Author's name must not have changed between messages
string.Equals(lastMessage.Author.FullName, message.Author.FullName, StringComparison.Ordinal) &&
// Duration between messages must be 7 minutes or less
(message.Timestamp - lastMessage.Timestamp).Duration().TotalMinutes <= 7 &&
// Other message must not be a reply
message.Reference is null;
}
private bool CanJoinGroup(Message message) =>
// First message in the group can always join
_messageGroup.LastOrDefault() is not { } lastMessage ||
// Must be from the same author
lastMessage.Author.Id == message.Author.Id &&
// Author's name must not have changed between messages
string.Equals(lastMessage.Author.FullName, message.Author.FullName, StringComparison.Ordinal) &&
// Duration between messages must be 7 minutes or less
(message.Timestamp - lastMessage.Timestamp).Duration().TotalMinutes <= 7 &&
// Other message must not be a reply
message.Reference is null;
// Use <!--wmm:ignore--> to preserve blocks of code inside the templates
private string Minify(string html) => _minifier
.Minify(html, false)
.MinifiedContent;
public override async ValueTask WritePreambleAsync(CancellationToken cancellationToken = default)
{
@ -47,7 +49,9 @@ internal class HtmlMessageWriter : MessageWriter
// We are not writing directly to output because Razor
// does not actually do asynchronous writes to stream.
await _writer.WriteLineAsync(
await PreambleTemplate.RenderAsync(templateContext, cancellationToken)
Minify(
await PreambleTemplate.RenderAsync(templateContext, cancellationToken)
)
);
}
@ -60,7 +64,9 @@ internal class HtmlMessageWriter : MessageWriter
// We are not writing directly to output because Razor
// does not actually do asynchronous writes to stream.
await _writer.WriteLineAsync(
await MessageGroupTemplate.RenderAsync(templateContext, cancellationToken)
Minify(
await MessageGroupTemplate.RenderAsync(templateContext, cancellationToken)
)
);
}
@ -96,7 +102,9 @@ internal class HtmlMessageWriter : MessageWriter
// We are not writing directly to output because Razor
// does not actually do asynchronous writes to stream.
await _writer.WriteLineAsync(
await PostambleTemplate.RenderAsync(templateContext, cancellationToken)
Minify(
await PostambleTemplate.RenderAsync(templateContext, cancellationToken)
)
);
}

Loading…
Cancel
Save