Add support for replies (#455)

pull/479/head
Sanqui 4 years ago committed by GitHub
parent 097a75e326
commit 07ac805677
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -18,7 +18,8 @@ namespace DiscordChatExporter.Domain.Discord.Models
ChannelNameChange, ChannelNameChange,
ChannelIconChange, ChannelIconChange,
ChannelPinnedMessage, ChannelPinnedMessage,
GuildMemberJoin GuildMemberJoin,
Reply = 19
} }
// https://discord.com/developers/docs/resources/channel#message-object // https://discord.com/developers/docs/resources/channel#message-object
@ -48,6 +49,10 @@ namespace DiscordChatExporter.Domain.Discord.Models
public IReadOnlyList<User> MentionedUsers { get; } public IReadOnlyList<User> MentionedUsers { get; }
public MessageReference? Reference {get; }
public Message? ReferencedMessage {get; }
public Message( public Message(
Snowflake id, Snowflake id,
MessageType type, MessageType type,
@ -60,7 +65,9 @@ namespace DiscordChatExporter.Domain.Discord.Models
IReadOnlyList<Attachment> attachments, IReadOnlyList<Attachment> attachments,
IReadOnlyList<Embed> embeds, IReadOnlyList<Embed> embeds,
IReadOnlyList<Reaction> reactions, IReadOnlyList<Reaction> reactions,
IReadOnlyList<User> mentionedUsers) IReadOnlyList<User> mentionedUsers,
MessageReference? messageReference,
Message? referencedMessage)
{ {
Id = id; Id = id;
Type = type; Type = type;
@ -74,6 +81,8 @@ namespace DiscordChatExporter.Domain.Discord.Models
Embeds = embeds; Embeds = embeds;
Reactions = reactions; Reactions = reactions;
MentionedUsers = mentionedUsers; MentionedUsers = mentionedUsers;
Reference = messageReference;
ReferencedMessage = referencedMessage;
} }
public override string ToString() => Content; public override string ToString() => Content;
@ -90,6 +99,8 @@ namespace DiscordChatExporter.Domain.Discord.Models
var callEndedTimestamp = json.GetPropertyOrNull("call")?.GetPropertyOrNull("ended_timestamp")?.GetDateTimeOffset(); var callEndedTimestamp = json.GetPropertyOrNull("call")?.GetPropertyOrNull("ended_timestamp")?.GetDateTimeOffset();
var type = (MessageType) json.GetProperty("type").GetInt32(); var type = (MessageType) json.GetProperty("type").GetInt32();
var isPinned = json.GetPropertyOrNull("pinned")?.GetBoolean() ?? false; var isPinned = json.GetPropertyOrNull("pinned")?.GetBoolean() ?? false;
var messageReference = json.GetPropertyOrNull("message_reference")?.Pipe(MessageReference.Parse);
var referencedMessage = json.GetPropertyOrNull("referenced_message")?.Pipe(Message.Parse);
var content = type switch var content = type switch
{ {
@ -132,7 +143,9 @@ namespace DiscordChatExporter.Domain.Discord.Models
attachments, attachments,
embeds, embeds,
reactions, reactions,
mentionedUsers mentionedUsers,
messageReference,
referencedMessage
); );
} }
} }

@ -0,0 +1,37 @@
using System.Text.Json;
using JsonExtensions.Reading;
namespace DiscordChatExporter.Domain.Discord.Models
{
// reference data sent with crossposted messages and replies
// https://discord.com/developers/docs/resources/channel#message-object-message-reference-structure
public partial class MessageReference
{
public string? MessageId { get; }
public string? ChannelId { get; }
public string? GuildId { get; }
public MessageReference(string? message_id, string? channel_id, string? guild_id)
{
MessageId = message_id;
ChannelId = channel_id;
GuildId = guild_id;
}
public override string ToString() => MessageId ?? "?";
}
public partial class MessageReference
{
public static MessageReference Parse(JsonElement json)
{
var message_id = json.GetPropertyOrNull("message_id")?.GetString();
var channel_id = json.GetPropertyOrNull("channel_id")?.GetString();
var guild_id = json.GetPropertyOrNull("guild_id")?.GetString();
return new MessageReference(message_id, channel_id, guild_id);
}
}
}

@ -211,6 +211,39 @@ img {
grid-template-columns: auto 1fr; grid-template-columns: auto 1fr;
} }
.chatlog__reference-symbol {
grid-column: 1;
border-style: solid;
border-width: 2px 0 0 2px;
border-radius: 8px 0 0 0;
margin-left: 16px;
margin-top: 8px;
}
.chatlog__reference {
grid-column: 2;
margin-left: 1.2em;
font-size: smaller;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.chatlog__reference-avatar {
border-radius: 50%;
height: 16px;
width: 16px;
vertical-align: middle;
}
.chatlog__reference-name {
font-weight: 500;
}
.chatlog__reference-content {
margin-left: .2em;
}
.chatlog__author-avatar-container { .chatlog__author-avatar-container {
grid-column: 1; grid-column: 1;
width: 40px; width: 40px;

@ -46,6 +46,14 @@ a {
border-color: rgba(255, 255, 255, 0.1); border-color: rgba(255, 255, 255, 0.1);
} }
.chatlog__reference-symbol {
border-color: #4f545c;
}
.chatlog__reference {
color: #b5b6b8;
}
.chatlog__author-name { .chatlog__author-name {
color: #ffffff; color: #ffffff;
} }

@ -47,6 +47,14 @@ a {
border-color: #eceeef; border-color: #eceeef;
} }
.chatlog__reference-symbol {
border-color: #c7ccd1;
}
.chatlog__reference {
color: #5f5f60;
}
.chatlog__author-name { .chatlog__author-name {
font-weight: 600; font-weight: 600;
color: #2f3136; color: #2f3136;

@ -14,10 +14,21 @@ namespace DiscordChatExporter.Domain.Exporting.Writers.Html
public IReadOnlyList<Message> Messages { get; } public IReadOnlyList<Message> Messages { get; }
public MessageGroup(User author, DateTimeOffset timestamp, IReadOnlyList<Message> messages) public MessageReference? Reference { get; }
public Message? ReferencedMessage {get; }
public MessageGroup(
User author,
DateTimeOffset timestamp,
MessageReference? reference,
Message? referenced_message,
IReadOnlyList<Message> messages)
{ {
Author = author; Author = author;
Timestamp = timestamp; Timestamp = timestamp;
Reference = reference;
ReferencedMessage = referenced_message;
Messages = messages; Messages = messages;
} }
} }
@ -27,7 +38,8 @@ namespace DiscordChatExporter.Domain.Exporting.Writers.Html
public static bool CanJoin(Message message1, Message message2) => public static bool CanJoin(Message message1, Message message2) =>
message1.Author.Id == message2.Author.Id && message1.Author.Id == message2.Author.Id &&
string.Equals(message1.Author.FullName, message2.Author.FullName, StringComparison.Ordinal) && string.Equals(message1.Author.FullName, message2.Author.FullName, StringComparison.Ordinal) &&
(message2.Timestamp - message1.Timestamp).Duration().TotalMinutes <= 7; (message2.Timestamp - message1.Timestamp).Duration().TotalMinutes <= 7 &&
message2.Reference is null;
public static MessageGroup Join(IReadOnlyList<Message> messages) public static MessageGroup Join(IReadOnlyList<Message> messages)
{ {
@ -36,6 +48,8 @@ namespace DiscordChatExporter.Domain.Exporting.Writers.Html
return new MessageGroup( return new MessageGroup(
first.Author, first.Author,
first.Timestamp, first.Timestamp,
first.Reference,
first.ReferencedMessage,
messages messages
); );
} }

@ -16,6 +16,7 @@
var userMember = Model.ExportContext.TryGetMember(Model.MessageGroup.Author.Id); var userMember = Model.ExportContext.TryGetMember(Model.MessageGroup.Author.Id);
var userColor = Model.ExportContext.TryGetUserColor(Model.MessageGroup.Author.Id); var userColor = Model.ExportContext.TryGetUserColor(Model.MessageGroup.Author.Id);
var userNick = Model.MessageGroup.Author.IsBot ? Model.MessageGroup.Author.Name : userMember?.Nick ?? Model.MessageGroup.Author.Name; var userNick = Model.MessageGroup.Author.IsBot ? Model.MessageGroup.Author.Name : userMember?.Nick ?? Model.MessageGroup.Author.Name;
var referencedUserNick = Model.MessageGroup.Author.IsBot ? Model.MessageGroup.Author.Name : userMember?.Nick ?? Model.MessageGroup.Author.Name;
var userColorStyle = userColor != null var userColorStyle = userColor != null
? $"color: rgb({userColor?.R},{userColor?.G},{userColor?.B})" ? $"color: rgb({userColor?.R},{userColor?.G},{userColor?.B})"
@ -23,6 +24,27 @@
} }
<div class="chatlog__message-group"> <div class="chatlog__message-group">
@if (Model.MessageGroup.Reference != null)
{
<div class="chatlog__reference-symbol">
</div>
<div class="chatlog__reference">
@if (Model.MessageGroup.ReferencedMessage != null)
{
<img class="chatlog__reference-avatar" src="@await ResolveUrlAsync(Model.MessageGroup.ReferencedMessage.Author.AvatarUrl)" alt="Avatar">
<span class="chatlog__reference-name" title="@Model.MessageGroup.ReferencedMessage.Author.FullName" data-user-id="@Model.MessageGroup.ReferencedMessage.Author.Id">@Model.MessageGroup.ReferencedMessage.Author.FullName</span>
<span class="chatlog__reference-content">
@Raw(FormatMarkdown(Model.MessageGroup.ReferencedMessage.Content))
</span>
}
else
{
<span class="chatlog__reference-unknown">
In reply to an unknown message
</span>
}
</div>
}
<div class="chatlog__author-avatar-container"> <div class="chatlog__author-avatar-container">
<img class="chatlog__author-avatar" src="@await ResolveUrlAsync(Model.MessageGroup.Author.AvatarUrl)" alt="Avatar"> <img class="chatlog__author-avatar" src="@await ResolveUrlAsync(Model.MessageGroup.Author.AvatarUrl)" alt="Avatar">
</div> </div>

@ -263,6 +263,17 @@ namespace DiscordChatExporter.Domain.Exporting.Writers
_writer.WriteEndArray(); _writer.WriteEndArray();
// Reference
if (message.Reference is not null)
{
_writer.WriteStartObject("reference");
_writer.WriteString("messageId", message.Reference.MessageId);
_writer.WriteString("channelId", message.Reference.ChannelId);
_writer.WriteString("guildId", message.Reference.GuildId);
_writer.WriteEndObject();
}
_writer.WriteEndObject(); _writer.WriteEndObject();
await _writer.FlushAsync(); await _writer.FlushAsync();

Loading…
Cancel
Save