diff --git a/DiscordChatExporter.Core/Discord/Data/Message.cs b/DiscordChatExporter.Core/Discord/Data/Message.cs index 330c5686..19e6f99e 100644 --- a/DiscordChatExporter.Core/Discord/Data/Message.cs +++ b/DiscordChatExporter.Core/Discord/Data/Message.cs @@ -99,20 +99,7 @@ public record Message( .GetDateTimeOffset(); var isPinned = json.GetPropertyOrNull("pinned")?.GetBooleanOrNull() ?? false; - - var content = kind switch - { - MessageKind.RecipientAdd => "Added a recipient.", - MessageKind.RecipientRemove => "Removed a recipient.", - MessageKind.Call => - $"Started a call that lasted {callEndedTimestamp?.Pipe(t => t - timestamp).Pipe(t => (int)t.TotalMinutes) ?? 0} minutes.", - MessageKind.ChannelNameChange => "Changed the channel name.", - MessageKind.ChannelIconChange => "Changed the channel icon.", - MessageKind.ChannelPinnedMessage => "Pinned a message.", - MessageKind.ThreadCreated => "Started a thread.", - MessageKind.GuildMemberJoin => "Joined the server.", - _ => json.GetPropertyOrNull("content")?.GetStringOrNull() ?? "" - }; + var content = json.GetPropertyOrNull("content")?.GetStringOrNull() ?? ""; var attachments = json.GetPropertyOrNull("attachments")?.EnumerateArrayOrNull()?.Select(Attachment.Parse).ToArray() ?? diff --git a/DiscordChatExporter.Core/Exporting/CsvMessageWriter.cs b/DiscordChatExporter.Core/Exporting/CsvMessageWriter.cs index 29e1f830..43f264b2 100644 --- a/DiscordChatExporter.Core/Exporting/CsvMessageWriter.cs +++ b/DiscordChatExporter.Core/Exporting/CsvMessageWriter.cs @@ -85,7 +85,15 @@ internal partial class CsvMessageWriter : MessageWriter await _writer.WriteAsync(','); // Message content - await _writer.WriteAsync(CsvEncode(await FormatMarkdownAsync(message.Content, cancellationToken))); + if (message.Kind.IsSystemNotification()) + { + await _writer.WriteAsync(CsvEncode(message.GetFallbackContent())); + } + else + { + await _writer.WriteAsync(CsvEncode(await FormatMarkdownAsync(message.Content, cancellationToken))); + } + await _writer.WriteAsync(','); // Attachments diff --git a/DiscordChatExporter.Core/Exporting/JsonMessageWriter.cs b/DiscordChatExporter.Core/Exporting/JsonMessageWriter.cs index d57ab199..514e4315 100644 --- a/DiscordChatExporter.Core/Exporting/JsonMessageWriter.cs +++ b/DiscordChatExporter.Core/Exporting/JsonMessageWriter.cs @@ -299,7 +299,14 @@ internal class JsonMessageWriter : MessageWriter _writer.WriteBoolean("isPinned", message.IsPinned); // Content - _writer.WriteString("content", await FormatMarkdownAsync(message.Content, cancellationToken)); + if (message.Kind.IsSystemNotification()) + { + _writer.WriteString("content", message.GetFallbackContent()); + } + else + { + _writer.WriteString("content", await FormatMarkdownAsync(message.Content, cancellationToken)); + } // Author _writer.WriteStartObject("author"); diff --git a/DiscordChatExporter.Core/Exporting/MessageGroupTemplate.cshtml b/DiscordChatExporter.Core/Exporting/MessageGroupTemplate.cshtml index 5bd3f682..7b336e67 100644 --- a/DiscordChatExporter.Core/Exporting/MessageGroupTemplate.cshtml +++ b/DiscordChatExporter.Core/Exporting/MessageGroupTemplate.cshtml @@ -71,7 +71,21 @@ : userMember?.Nick ?? message.Author.Name;
- + + @{ + var icon = message.Kind switch { + MessageKind.RecipientAdd => "join-icon", + MessageKind.RecipientRemove => "leave-icon", + MessageKind.Call => "call-icon", + MessageKind.ChannelNameChange => "pencil-icon", + MessageKind.ChannelIconChange => "pencil-icon", + MessageKind.ChannelPinnedMessage => "pin-icon", + _ => "pencil-icon" + }; + } + + +
@@ -80,14 +94,55 @@ @{/* System notification content */} - @if (message.Kind == MessageKind.ChannelPinnedMessage && message.Reference is not null) + @if (message.Kind == MessageKind.RecipientAdd && message.MentionedUsers.Any()) + { + added + @message.MentionedUsers.First().Name + to the group. + } + else if (message.Kind == MessageKind.RecipientRemove && message.MentionedUsers.Any()) + { + if (message.Author.Id == message.MentionedUsers.First().Id) + { + left the group. + } + else + { + removed + @message.MentionedUsers.First().Name + from the group. + } + } + else if (message.Kind == MessageKind.Call) + { + started a call that lasted @(((message.CallEndedTimestamp ?? message.Timestamp) - message.Timestamp).TotalMinutes) minutes + } + else if (message.Kind == MessageKind.ChannelNameChange) + { + changed the channel name: + @message.Content + } + else if (message.Kind == MessageKind.ChannelIconChange) + { + changed the channel icon. + } + else if (message.Kind == MessageKind.ChannelPinnedMessage && message.Reference is not null) { pinned a message to this channel. } + else if (message.Kind == MessageKind.ThreadCreated) + { + started a thread. + } + else if (message.Kind == MessageKind.GuildMemberJoin) + { + joined the server. + } else { + @message.Content.ToLowerInvariant() } diff --git a/DiscordChatExporter.Core/Exporting/PlainTextMessageExtensions.cs b/DiscordChatExporter.Core/Exporting/PlainTextMessageExtensions.cs new file mode 100644 index 00000000..625dc1b9 --- /dev/null +++ b/DiscordChatExporter.Core/Exporting/PlainTextMessageExtensions.cs @@ -0,0 +1,36 @@ +using System.Linq; +using DiscordChatExporter.Core.Discord.Data; +using DiscordChatExporter.Core.Utils.Extensions; + +namespace DiscordChatExporter.Core.Exporting; + +internal static class PlainTextMessageExtensions +{ + public static string GetFallbackContent(this Message message) => message.Kind switch + { + MessageKind.RecipientAdd => message.MentionedUsers.Any() + ? $"Added {message.MentionedUsers.First().Name} to the group." + : "Added a recipient.", + + MessageKind.RecipientRemove => message.MentionedUsers.Any() + ? message.Author.Id == message.MentionedUsers.First().Id + ? "Left the group." + : $"Removed {message.MentionedUsers.First().Name} from the group." + : "Removed a recipient.", + + MessageKind.Call => + $"Started a call that lasted {message.CallEndedTimestamp?.Pipe(t => t - message.Timestamp).Pipe(t => (int)t.TotalMinutes) ?? 0} minutes.", + + MessageKind.ChannelNameChange => + !string.IsNullOrWhiteSpace(message.Content) + ? $"Changed the channel name: {message.Content}" + : "Changed the channel name.", + + MessageKind.ChannelIconChange => "Changed the channel icon.", + MessageKind.ChannelPinnedMessage => "Pinned a message.", + MessageKind.ThreadCreated => "Started a thread.", + MessageKind.GuildMemberJoin => "Joined the server.", + + _ => message.Content + }; +} \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/PlainTextMessageWriter.cs b/DiscordChatExporter.Core/Exporting/PlainTextMessageWriter.cs index 5d7cbf57..90474dfb 100644 --- a/DiscordChatExporter.Core/Exporting/PlainTextMessageWriter.cs +++ b/DiscordChatExporter.Core/Exporting/PlainTextMessageWriter.cs @@ -222,7 +222,11 @@ internal class PlainTextMessageWriter : MessageWriter await WriteMessageHeaderAsync(message); // Content - if (!string.IsNullOrWhiteSpace(message.Content)) + if (message.Kind.IsSystemNotification()) + { + await _writer.WriteLineAsync(message.GetFallbackContent()); + } + else { await _writer.WriteLineAsync( await FormatMarkdownAsync(message.Content, cancellationToken) diff --git a/DiscordChatExporter.Core/Exporting/PreambleTemplate.cshtml b/DiscordChatExporter.Core/Exporting/PreambleTemplate.cshtml index 7eaba158..431e7dc9 100644 --- a/DiscordChatExporter.Core/Exporting/PreambleTemplate.cshtml +++ b/DiscordChatExporter.Core/Exporting/PreambleTemplate.cshtml @@ -835,15 +835,21 @@ - + + + + + + + + + + - - - diff --git a/DiscordChatExporter.Core/Utils/Extensions/StringExtensions.cs b/DiscordChatExporter.Core/Utils/Extensions/StringExtensions.cs index d2c24705..711b5e17 100644 --- a/DiscordChatExporter.Core/Utils/Extensions/StringExtensions.cs +++ b/DiscordChatExporter.Core/Utils/Extensions/StringExtensions.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Text; -using System.Text.RegularExpressions; namespace DiscordChatExporter.Core.Utils.Extensions; @@ -27,9 +26,6 @@ public static class StringExtensions } } - public static string ToDashCase(this string str) => - Regex.Replace(str, @"(\p{Ll})(\p{Lu})", "$1-$2"); - public static T? ParseEnumOrNull(this string str, bool ignoreCase = true) where T : struct, Enum => Enum.TryParse(str, ignoreCase, out var result) ? result