mirror of
https://github.com/Tyrrrz/DiscordChatExporter.git
synced 2025-06-03 08:08:40 -04:00
Migrate from MiniRazor to RazorBlade
This commit is contained in:
parent
5b1b720503
commit
e752269467
9 changed files with 109 additions and 125 deletions
|
@ -7,14 +7,14 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="Gress" Version="2.0.1" />
|
||||
<PackageReference Include="JsonExtensions" Version="1.2.0" />
|
||||
<PackageReference Include="MiniRazor.CodeGen" Version="2.2.2" />
|
||||
<PackageReference Include="Polly" Version="7.2.3" />
|
||||
<PackageReference Include="RazorBlade" Version="0.2.0" />
|
||||
<PackageReference Include="Superpower" Version="3.0.0" />
|
||||
<PackageReference Include="WebMarkupMin.Core" Version="2.12.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AdditionalFiles Include="Exporting\Writers\Html\*.cshtml" IsRazorTemplate="true" />
|
||||
<RazorBlade Include="Exporting\Writers\Html\*.cshtml" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -1,43 +1,56 @@
|
|||
@using System
|
||||
@using System.Collections.Generic
|
||||
@using System.Linq
|
||||
@using System.Threading
|
||||
@using System.Threading.Tasks
|
||||
@using DiscordChatExporter.Core.Discord.Data
|
||||
@using DiscordChatExporter.Core.Discord.Data.Embeds
|
||||
@using DiscordChatExporter.Core.Exporting.Writers.Html;
|
||||
@using DiscordChatExporter.Core.Exporting
|
||||
@using DiscordChatExporter.Core.Exporting.Writers.Html
|
||||
@using DiscordChatExporter.Core.Exporting.Writers.MarkdownVisitors
|
||||
@using DiscordChatExporter.Core.Utils.Extensions
|
||||
|
||||
@namespace DiscordChatExporter.Core.Exporting.Writers.Html
|
||||
@inherits MiniRazor.TemplateBase<MessageGroupTemplateContext>
|
||||
@inherits RazorBlade.HtmlTemplate
|
||||
|
||||
@functions {
|
||||
// RazorBlade does not provide built-in support for cancellation
|
||||
// https://github.com/ltrzesniewski/RazorBlade/issues/2
|
||||
public CancellationToken CancellationToken { get; init; }
|
||||
|
||||
public ExportContext ExportContext { get; init; } = default!;
|
||||
|
||||
public IReadOnlyList<Message> Messages { get; init; } = Array.Empty<Message>();
|
||||
}
|
||||
|
||||
@{
|
||||
ValueTask<string> ResolveAssetUrlAsync(string url) =>
|
||||
Model.ExportContext.ResolveAssetUrlAsync(url);
|
||||
ExportContext.ResolveAssetUrlAsync(url, CancellationToken);
|
||||
|
||||
string FormatDate(DateTimeOffset date) =>
|
||||
Model.ExportContext.FormatDate(date);
|
||||
ExportContext.FormatDate(date);
|
||||
|
||||
ValueTask<string> FormatMarkdownAsync(string markdown) =>
|
||||
Model.FormatMarkdownAsync(markdown);
|
||||
HtmlMarkdownVisitor.FormatAsync(ExportContext, markdown);
|
||||
|
||||
ValueTask<string> FormatEmbedMarkdownAsync(string markdown) =>
|
||||
Model.FormatMarkdownAsync(markdown, false);
|
||||
HtmlMarkdownVisitor.FormatAsync(ExportContext, markdown, false);
|
||||
|
||||
var firstMessage = Model.Messages.First();
|
||||
var firstMessage = Messages.First();
|
||||
|
||||
var userMember = Model.ExportContext.TryGetMember(firstMessage.Author.Id);
|
||||
var userMember = ExportContext.TryGetMember(firstMessage.Author.Id);
|
||||
|
||||
var userColor = Model.ExportContext.TryGetUserColor(firstMessage.Author.Id);
|
||||
var userColor = ExportContext.TryGetUserColor(firstMessage.Author.Id);
|
||||
|
||||
var userNick = firstMessage.Author.IsBot
|
||||
? firstMessage.Author.Name
|
||||
: userMember?.Nick ?? firstMessage.Author.Name;
|
||||
|
||||
var referencedUserMember = firstMessage.ReferencedMessage is not null
|
||||
? Model.ExportContext.TryGetMember(firstMessage.ReferencedMessage.Author.Id)
|
||||
? ExportContext.TryGetMember(firstMessage.ReferencedMessage.Author.Id)
|
||||
: null;
|
||||
|
||||
var referencedUserColor = firstMessage.ReferencedMessage is not null
|
||||
? Model.ExportContext.TryGetUserColor(firstMessage.ReferencedMessage.Author.Id)
|
||||
? ExportContext.TryGetUserColor(firstMessage.ReferencedMessage.Author.Id)
|
||||
: null;
|
||||
|
||||
var referencedUserNick = firstMessage.ReferencedMessage is not null
|
||||
|
@ -48,7 +61,7 @@
|
|||
}
|
||||
|
||||
<div class="chatlog__message-group">
|
||||
@foreach (var (message, i) in Model.Messages.WithIndex())
|
||||
@foreach (var (message, i) in Messages.WithIndex())
|
||||
{
|
||||
var isFirst = i == 0;
|
||||
|
||||
|
@ -59,8 +72,8 @@
|
|||
{
|
||||
// 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 = Model.ExportContext.TryGetMember(message.Author.Id);
|
||||
userColor = Model.ExportContext.TryGetUserColor(message.Author.Id);
|
||||
userMember = ExportContext.TryGetMember(message.Author.Id);
|
||||
userColor = ExportContext.TryGetUserColor(message.Author.Id);
|
||||
userNick = message.Author.IsBot
|
||||
? message.Author.Name
|
||||
: userMember?.Nick ?? message.Author.Name;
|
||||
|
@ -129,7 +142,7 @@
|
|||
<span class="chatlog__reference-link" onclick="scrollToMessage(event, '@message.ReferencedMessage.Id')">
|
||||
@if (!string.IsNullOrWhiteSpace(message.ReferencedMessage.Content) && !message.ReferencedMessage.IsContentHidden())
|
||||
{
|
||||
<!--wmm:ignore-->@Raw(await FormatEmbedMarkdownAsync(message.ReferencedMessage.Content))<!--/wmm:ignore-->
|
||||
<!--wmm:ignore-->@Html.Raw(await FormatEmbedMarkdownAsync(message.ReferencedMessage.Content))<!--/wmm:ignore-->
|
||||
}
|
||||
else if (message.ReferencedMessage.Attachments.Any() || message.ReferencedMessage.Embeds.Any())
|
||||
{
|
||||
|
@ -180,7 +193,7 @@
|
|||
@{/* Text */}
|
||||
@if (!string.IsNullOrWhiteSpace(message.Content) && !message.IsContentHidden())
|
||||
{
|
||||
<span class="chatlog__markdown-preserve"><!--wmm:ignore-->@Raw(await FormatMarkdownAsync(message.Content))<!--/wmm:ignore--></span>
|
||||
<span class="chatlog__markdown-preserve"><!--wmm:ignore-->@Html.Raw(await FormatMarkdownAsync(message.Content))<!--/wmm:ignore--></span>
|
||||
}
|
||||
|
||||
@{/* Edited timestamp */}
|
||||
|
@ -300,12 +313,12 @@
|
|||
@if (!string.IsNullOrWhiteSpace(embed.Url))
|
||||
{
|
||||
<a class="chatlog__embed-title-link" href="@embed.Url">
|
||||
<div class="chatlog__markdown chatlog__markdown-preserve"><!--wmm:ignore-->@Raw(await FormatEmbedMarkdownAsync(embed.Title))<!--/wmm:ignore--></div>
|
||||
<div class="chatlog__markdown chatlog__markdown-preserve"><!--wmm:ignore-->@Html.Raw(await FormatEmbedMarkdownAsync(embed.Title))<!--/wmm:ignore--></div>
|
||||
</a>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="chatlog__markdown chatlog__markdown-preserve"><!--wmm:ignore-->@Raw(await FormatEmbedMarkdownAsync(embed.Title))<!--/wmm:ignore--></div>
|
||||
<div class="chatlog__markdown chatlog__markdown-preserve"><!--wmm:ignore-->@Html.Raw(await FormatEmbedMarkdownAsync(embed.Title))<!--/wmm:ignore--></div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
@ -386,12 +399,12 @@
|
|||
@if (!string.IsNullOrWhiteSpace(embed.Url))
|
||||
{
|
||||
<a class="chatlog__embed-title-link" href="@embed.Url">
|
||||
<div class="chatlog__markdown chatlog__markdown-preserve"><!--wmm:ignore-->@Raw(await FormatEmbedMarkdownAsync(embed.Title))<!--/wmm:ignore--></div>
|
||||
<div class="chatlog__markdown chatlog__markdown-preserve"><!--wmm:ignore-->@Html.Raw(await FormatEmbedMarkdownAsync(embed.Title))<!--/wmm:ignore--></div>
|
||||
</a>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="chatlog__markdown chatlog__markdown-preserve"><!--wmm:ignore-->@Raw(await FormatEmbedMarkdownAsync(embed.Title))<!--/wmm:ignore--></div>
|
||||
<div class="chatlog__markdown chatlog__markdown-preserve"><!--wmm:ignore-->@Html.Raw(await FormatEmbedMarkdownAsync(embed.Title))<!--/wmm:ignore--></div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
@ -400,7 +413,7 @@
|
|||
@if (!string.IsNullOrWhiteSpace(embed.Description))
|
||||
{
|
||||
<div class="chatlog__embed-description">
|
||||
<div class="chatlog__markdown chatlog__markdown-preserve"><!--wmm:ignore-->@Raw(await FormatEmbedMarkdownAsync(embed.Description))<!--/wmm:ignore--></div>
|
||||
<div class="chatlog__markdown chatlog__markdown-preserve"><!--wmm:ignore-->@Html.Raw(await FormatEmbedMarkdownAsync(embed.Description))<!--/wmm:ignore--></div>
|
||||
</div>
|
||||
}
|
||||
|
||||
|
@ -414,14 +427,14 @@
|
|||
@if (!string.IsNullOrWhiteSpace(field.Name))
|
||||
{
|
||||
<div class="chatlog__embed-field-name">
|
||||
<div class="chatlog__markdown chatlog__markdown-preserve"><!--wmm:ignore-->@Raw(await FormatEmbedMarkdownAsync(field.Name))<!--/wmm:ignore--></div>
|
||||
<div class="chatlog__markdown chatlog__markdown-preserve"><!--wmm:ignore-->@Html.Raw(await FormatEmbedMarkdownAsync(field.Name))<!--/wmm:ignore--></div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (!string.IsNullOrWhiteSpace(field.Value))
|
||||
{
|
||||
<div class="chatlog__embed-field-value">
|
||||
<div class="chatlog__markdown chatlog__markdown-preserve"><!--wmm:ignore-->@Raw(await FormatEmbedMarkdownAsync(field.Value))<!--/wmm:ignore--></div>
|
||||
<div class="chatlog__markdown chatlog__markdown-preserve"><!--wmm:ignore-->@Html.Raw(await FormatEmbedMarkdownAsync(field.Value))<!--/wmm:ignore--></div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using DiscordChatExporter.Core.Discord.Data;
|
||||
using DiscordChatExporter.Core.Exporting.Writers.MarkdownVisitors;
|
||||
|
||||
namespace DiscordChatExporter.Core.Exporting.Writers.Html;
|
||||
|
||||
internal class MessageGroupTemplateContext
|
||||
{
|
||||
public ExportContext ExportContext { get; }
|
||||
|
||||
public IReadOnlyList<Message> Messages { get; }
|
||||
|
||||
public MessageGroupTemplateContext(ExportContext exportContext, IReadOnlyList<Message> messages)
|
||||
{
|
||||
ExportContext = exportContext;
|
||||
Messages = messages;
|
||||
}
|
||||
|
||||
public ValueTask<string> FormatMarkdownAsync(string? markdown, bool isJumboAllowed = true) =>
|
||||
HtmlMarkdownVisitor.FormatAsync(ExportContext, markdown ?? "", isJumboAllowed);
|
||||
}
|
|
@ -1,15 +1,27 @@
|
|||
@using DiscordChatExporter.Core.Exporting.Writers.Html;
|
||||
@using System.Threading
|
||||
@using DiscordChatExporter.Core.Exporting
|
||||
|
||||
@namespace DiscordChatExporter.Core.Exporting.Writers.Html
|
||||
@inherits MiniRazor.TemplateBase<PostambleTemplateContext>
|
||||
@inherits RazorBlade.HtmlTemplate
|
||||
|
||||
@{/* Close elements opened by preamble */}
|
||||
@functions {
|
||||
// RazorBlade does not provide built-in support for cancellation
|
||||
// https://github.com/ltrzesniewski/RazorBlade/issues/2
|
||||
public CancellationToken CancellationToken { get; init; }
|
||||
|
||||
public ExportContext ExportContext { get; init; } = default!;
|
||||
|
||||
public long MessagesWritten { get; init; }
|
||||
}
|
||||
|
||||
@{
|
||||
/* 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>
|
||||
<div class="postamble__entry">Exported @MessagesWritten.ToString("N0") message(s)</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
namespace DiscordChatExporter.Core.Exporting.Writers.Html;
|
||||
|
||||
internal class PostambleTemplateContext
|
||||
{
|
||||
public ExportContext ExportContext { get; }
|
||||
|
||||
public long MessagesWritten { get; }
|
||||
|
||||
public PostambleTemplateContext(ExportContext exportContext, long messagesWritten)
|
||||
{
|
||||
ExportContext = exportContext;
|
||||
MessagesWritten = messagesWritten;
|
||||
}
|
||||
}
|
|
@ -1,13 +1,24 @@
|
|||
@using System
|
||||
@using System.Threading
|
||||
@using System.Threading.Tasks
|
||||
@using DiscordChatExporter.Core.Exporting.Writers.Html;
|
||||
@using DiscordChatExporter.Core.Exporting
|
||||
@using DiscordChatExporter.Core.Exporting.Writers.MarkdownVisitors
|
||||
|
||||
@namespace DiscordChatExporter.Core.Exporting.Writers.Html
|
||||
@inherits MiniRazor.TemplateBase<PreambleTemplateContext>
|
||||
@inherits RazorBlade.HtmlTemplate
|
||||
|
||||
@functions {
|
||||
// RazorBlade does not provide built-in support for cancellation
|
||||
// https://github.com/ltrzesniewski/RazorBlade/issues/2
|
||||
public CancellationToken CancellationToken { get; init; }
|
||||
|
||||
public ExportContext ExportContext { get; init; } = default!;
|
||||
|
||||
public string ThemeName { get; init; } = "Dark";
|
||||
}
|
||||
|
||||
@{
|
||||
string Themed(string darkVariant, string lightVariant) =>
|
||||
string.Equals(Model.ThemeName, "Dark", StringComparison.OrdinalIgnoreCase)
|
||||
string.Equals(ThemeName, "Dark", StringComparison.OrdinalIgnoreCase)
|
||||
? darkVariant
|
||||
: lightVariant;
|
||||
|
||||
|
@ -15,20 +26,20 @@
|
|||
$"https://cdn.jsdelivr.net/gh/Tyrrrz/DiscordFonts@master/whitney-{weight}.woff";
|
||||
|
||||
ValueTask<string> ResolveAssetUrlAsync(string url) =>
|
||||
Model.ExportContext.ResolveAssetUrlAsync(url, CancellationToken);
|
||||
ExportContext.ResolveAssetUrlAsync(url, CancellationToken);
|
||||
|
||||
string FormatDate(DateTimeOffset date) =>
|
||||
Model.ExportContext.FormatDate(date);
|
||||
ExportContext.FormatDate(date);
|
||||
|
||||
ValueTask<string> FormatMarkdownAsync(string markdown) =>
|
||||
Model.FormatMarkdownAsync(markdown);
|
||||
HtmlMarkdownVisitor.FormatAsync(ExportContext, markdown);
|
||||
}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<title>@Model.ExportContext.Request.Guild.Name - @Model.ExportContext.Request.Channel.Name</title>
|
||||
<title>@ExportContext.Request.Guild.Name - @ExportContext.Request.Channel.Name</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
|
||||
|
@ -755,7 +766,7 @@
|
|||
</style>
|
||||
|
||||
@{/* Syntax highlighting */}
|
||||
<link rel="stylesheet" href="@await ResolveAssetUrlAsync($"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.6/styles/solarized-{Model.ThemeName.ToLowerInvariant()}.min.css")">
|
||||
<link rel="stylesheet" href="@await ResolveAssetUrlAsync($"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.6/styles/solarized-{ThemeName.ToLowerInvariant()}.min.css")">
|
||||
<script src="@await ResolveAssetUrlAsync("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.6/highlight.min.js")"></script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
|
@ -846,31 +857,31 @@
|
|||
|
||||
<div class="preamble">
|
||||
<div class="preamble__guild-icon-container">
|
||||
<img class="preamble__guild-icon" src="@await ResolveAssetUrlAsync(Model.ExportContext.Request.Guild.IconUrl)" alt="Guild icon" loading="lazy">
|
||||
<img class="preamble__guild-icon" src="@await ResolveAssetUrlAsync(ExportContext.Request.Guild.IconUrl)" alt="Guild icon" loading="lazy">
|
||||
</div>
|
||||
<div class="preamble__entries-container">
|
||||
<div class="preamble__entry">@Model.ExportContext.Request.Guild.Name</div>
|
||||
<div class="preamble__entry">@Model.ExportContext.Request.Channel.Category.Name / @Model.ExportContext.Request.Channel.Name</div>
|
||||
<div class="preamble__entry">@ExportContext.Request.Guild.Name</div>
|
||||
<div class="preamble__entry">@ExportContext.Request.Channel.Category.Name / @ExportContext.Request.Channel.Name</div>
|
||||
|
||||
@if (!string.IsNullOrWhiteSpace(Model.ExportContext.Request.Channel.Topic))
|
||||
@if (!string.IsNullOrWhiteSpace(ExportContext.Request.Channel.Topic))
|
||||
{
|
||||
<div class="preamble__entry preamble__entry--small">@Raw(await FormatMarkdownAsync(Model.ExportContext.Request.Channel.Topic))</div>
|
||||
<div class="preamble__entry preamble__entry--small">@Html.Raw(await FormatMarkdownAsync(ExportContext.Request.Channel.Topic))</div>
|
||||
}
|
||||
|
||||
@if (Model.ExportContext.Request.After is not null || Model.ExportContext.Request.Before is not null)
|
||||
@if (ExportContext.Request.After is not null || ExportContext.Request.Before is not null)
|
||||
{
|
||||
<div class="preamble__entry preamble__entry--small">
|
||||
@if (Model.ExportContext.Request.After is not null && Model.ExportContext.Request.Before is not null)
|
||||
@if (ExportContext.Request.After is not null && ExportContext.Request.Before is not null)
|
||||
{
|
||||
@($"Between {FormatDate(Model.ExportContext.Request.After.Value.ToDate())} and {FormatDate(Model.ExportContext.Request.Before.Value.ToDate())}")
|
||||
@($"Between {FormatDate(ExportContext.Request.After.Value.ToDate())} and {FormatDate(ExportContext.Request.Before.Value.ToDate())}")
|
||||
}
|
||||
else if (Model.ExportContext.Request.After is not null)
|
||||
else if (ExportContext.Request.After is not null)
|
||||
{
|
||||
@($"After {FormatDate(Model.ExportContext.Request.After.Value.ToDate())}")
|
||||
@($"After {FormatDate(ExportContext.Request.After.Value.ToDate())}")
|
||||
}
|
||||
else if (Model.ExportContext.Request.Before is not null)
|
||||
else if (ExportContext.Request.Before is not null)
|
||||
{
|
||||
@($"Before {FormatDate(Model.ExportContext.Request.Before.Value.ToDate())}")
|
||||
@($"Before {FormatDate(ExportContext.Request.Before.Value.ToDate())}")
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
using System.Threading.Tasks;
|
||||
using DiscordChatExporter.Core.Exporting.Writers.MarkdownVisitors;
|
||||
|
||||
namespace DiscordChatExporter.Core.Exporting.Writers.Html;
|
||||
|
||||
internal class PreambleTemplateContext
|
||||
{
|
||||
public ExportContext ExportContext { get; }
|
||||
|
||||
public string ThemeName { get; }
|
||||
|
||||
public PreambleTemplateContext(ExportContext exportContext, string themeName)
|
||||
{
|
||||
ExportContext = exportContext;
|
||||
ThemeName = themeName;
|
||||
}
|
||||
|
||||
public ValueTask<string> FormatMarkdownAsync(string? markdown, bool isJumboAllowed = true) =>
|
||||
HtmlMarkdownVisitor.FormatAsync(ExportContext, markdown ?? "", isJumboAllowed);
|
||||
}
|
|
@ -71,15 +71,17 @@ internal class HtmlMessageWriter : MessageWriter
|
|||
.Minify(html, false)
|
||||
.MinifiedContent;
|
||||
|
||||
public override async ValueTask WritePreambleAsync(CancellationToken cancellationToken = default)
|
||||
public override async ValueTask WritePreambleAsync(
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var templateContext = new PreambleTemplateContext(Context, _themeName);
|
||||
|
||||
// We are not writing directly to output because Razor
|
||||
// does not actually do asynchronous writes to stream.
|
||||
await _writer.WriteLineAsync(
|
||||
Minify(
|
||||
await PreambleTemplate.RenderAsync(templateContext, cancellationToken)
|
||||
await new PreambleTemplate
|
||||
{
|
||||
CancellationToken = cancellationToken,
|
||||
ExportContext = Context,
|
||||
ThemeName = _themeName
|
||||
}.RenderAsync()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -88,13 +90,14 @@ internal class HtmlMessageWriter : MessageWriter
|
|||
IReadOnlyList<Message> messages,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var templateContext = new MessageGroupTemplateContext(Context, messages);
|
||||
|
||||
// We are not writing directly to output because Razor
|
||||
// does not actually do asynchronous writes to stream.
|
||||
await _writer.WriteLineAsync(
|
||||
Minify(
|
||||
await MessageGroupTemplate.RenderAsync(templateContext, cancellationToken)
|
||||
await new MessageGroupTemplate
|
||||
{
|
||||
CancellationToken = cancellationToken,
|
||||
ExportContext = Context,
|
||||
Messages = messages
|
||||
}.RenderAsync()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -126,13 +129,14 @@ internal class HtmlMessageWriter : MessageWriter
|
|||
if (_messageGroup.Any())
|
||||
await WriteMessageGroupAsync(_messageGroup, cancellationToken);
|
||||
|
||||
var templateContext = new PostambleTemplateContext(Context, MessagesWritten);
|
||||
|
||||
// We are not writing directly to output because Razor
|
||||
// does not actually do asynchronous writes to stream.
|
||||
await _writer.WriteLineAsync(
|
||||
Minify(
|
||||
await PostambleTemplate.RenderAsync(templateContext, cancellationToken)
|
||||
await new PostambleTemplate
|
||||
{
|
||||
CancellationToken = cancellationToken,
|
||||
ExportContext = Context,
|
||||
MessagesWritten = MessagesWritten
|
||||
}.RenderAsync()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue