From 8612d2c84a5cd28ab57534a97f5ba9122b4c00f8 Mon Sep 17 00:00:00 2001 From: gan-of-culture <53971163+gan-of-culture@users.noreply.github.com> Date: Tue, 13 Sep 2022 22:51:10 +0200 Subject: [PATCH] Add HTML formatting for system messages (#926) --- .gitignore | 1 + .../Discord/Data/MessageKind.cs | 14 +++- .../Writers/Html/MessageGroupTemplate.cshtml | 70 +++++++++++++++---- .../Writers/Html/PreambleTemplate.cshtml | 43 ++++++++++-- .../Exporting/Writers/HtmlMessageWriter.cs | 21 +++++- 5 files changed, 123 insertions(+), 26 deletions(-) diff --git a/.gitignore b/.gitignore index 1923141..33e5fdf 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ *.sln.docstates .idea/ .vs/ +.vscode/ # Build results [Dd]ebug/ diff --git a/DiscordChatExporter.Core/Discord/Data/MessageKind.cs b/DiscordChatExporter.Core/Discord/Data/MessageKind.cs index c64fdac..67fb609 100644 --- a/DiscordChatExporter.Core/Discord/Data/MessageKind.cs +++ b/DiscordChatExporter.Core/Discord/Data/MessageKind.cs @@ -1,4 +1,6 @@ -namespace DiscordChatExporter.Core.Discord.Data; +using System.Text.RegularExpressions; + +namespace DiscordChatExporter.Core.Discord.Data; // https://discord.com/developers/docs/resources/channel#message-object-message-types public enum MessageKind @@ -12,4 +14,14 @@ public enum MessageKind ChannelPinnedMessage = 6, GuildMemberJoin = 7, Reply = 19 +} + +public static class MessageKindExtensions +{ + public static bool IsSystemMessage(this MessageKind c) => + c is not MessageKind.Default and not MessageKind.Reply; + + public static string ToCssIdFormat(this MessageKind c) => + string.Join("-", Regex.Split(c.ToString(), @"(? @foreach (var (message, i) in Model.Messages.WithIndex()) { + var isSystemMessage = message.Kind.IsSystemMessage(); + var isFirst = i == 0;
@{/* Left side */}
- @if (isFirst) + @if (isSystemMessage) + { + + } + else if(isFirst) { // Reference symbol if (message.Reference is not null) @@ -71,7 +77,38 @@ @{/* Right side */}
- @if (isFirst) + @if (isSystemMessage) + { + + // system messages 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); + + userNick = message.Author.IsBot + ? message.Author.Name + : userMember?.Nick ?? message.Author.Name; + +
+ @{/* Author name */} + @userNick + + @{/* System message content */} + @if(message.Kind == MessageKind.ChannelPinnedMessage) + { + pinned a message to this channel. + } + else + { + @Raw(FormatMarkdown(Char.ToLowerInvariant(message.Content[0]) + message.Content.Substring(1))) + } + + @{/* Timestamp */} + @FormatDate(message.Timestamp) +
+ } + else if (isFirst) { // Reference if (message.Reference is not null) @@ -130,21 +167,24 @@ } @{/* Content */} - @if (!string.IsNullOrWhiteSpace(message.Content) || message.EditedTimestamp is not null) + @if (!isSystemMessage) { -
- @{/* Text */} - @if (!message.IsContentHidden()) - { - @Raw(FormatMarkdown(message.Content)) - } + @if (!string.IsNullOrWhiteSpace(message.Content) || message.EditedTimestamp is not null) + { +
+ @{/* Text */} + @if (!message.IsContentHidden()) + { + @Raw(FormatMarkdown(message.Content)) + } - @{/* Edited timestamp */} - @if (message.EditedTimestamp is not null) - { - (edited) - } -
+ @{/* Edited timestamp */} + @if (message.EditedTimestamp is not null) + { + (edited) + } +
+ } } @{/* Attachments */} diff --git a/DiscordChatExporter.Core/Exporting/Writers/Html/PreambleTemplate.cshtml b/DiscordChatExporter.Core/Exporting/Writers/Html/PreambleTemplate.cshtml index e71f87f..b7dc92c 100644 --- a/DiscordChatExporter.Core/Exporting/Writers/Html/PreambleTemplate.cshtml +++ b/DiscordChatExporter.Core/Exporting/Writers/Html/PreambleTemplate.cshtml @@ -254,6 +254,21 @@ unicode-bidi: bidi-override; } + .chatlog__system-message{ + color: #96989D + } + + .chatlog__system-message-reference-link{ + font-weight: 500; + color: #ffffff + } + + .chatlog__system-message-icon{ + width: 18px; + height: 18px; + margin-right: 0.25rem; + } + .chatlog__header { margin-bottom: 0.1rem; } @@ -786,13 +801,27 @@ @{/* Icons */} - - - - - - - + + + + + + + + + + + + + + + + + + + + + diff --git a/DiscordChatExporter.Core/Exporting/Writers/HtmlMessageWriter.cs b/DiscordChatExporter.Core/Exporting/Writers/HtmlMessageWriter.cs index 5d70355..afb26dc 100644 --- a/DiscordChatExporter.Core/Exporting/Writers/HtmlMessageWriter.cs +++ b/DiscordChatExporter.Core/Exporting/Writers/HtmlMessageWriter.cs @@ -25,9 +25,23 @@ internal class HtmlMessageWriter : MessageWriter _themeName = themeName; } - private bool CanJoinGroup(Message message) => + private bool CanJoinGroup(Message message) + { // First message in the group can always join - _messageGroup.LastOrDefault() is not { } lastMessage || + if(_messageGroup.LastOrDefault() is not { } lastMessage) + { + return true; + } + + // Group system messages with other system messages, regardless of author + if (message.Kind.IsSystemMessage()) + { + return lastMessage.Kind.IsSystemMessage(); + } + + return + // Must be a non system message + !message.Kind.IsSystemMessage() && // Must be from the same author lastMessage.Author.Id == message.Author.Id && // Author's name must not have changed between messages @@ -36,6 +50,7 @@ internal class HtmlMessageWriter : MessageWriter (message.Timestamp - lastMessage.Timestamp).Duration().TotalMinutes <= 7 && // Other message must not be a reply message.Reference is null; + } // Use to preserve blocks of code inside the templates private string Minify(string html) => _minifier @@ -77,7 +92,7 @@ internal class HtmlMessageWriter : MessageWriter await base.WriteMessageAsync(message, cancellationToken); // If the message can be grouped, buffer it for now - if (CanJoinGroup( message)) + if (CanJoinGroup(message)) { _messageGroup.Add(message); }