mirror of
https://github.com/Tyrrrz/DiscordChatExporter.git
synced 2025-05-22 10:55:15 -04:00
Support GIF embeds when exporting to HTML (#919)
This commit is contained in:
parent
a405ab184e
commit
f28d662a71
4 changed files with 66 additions and 1 deletions
|
@ -11,6 +11,7 @@ namespace DiscordChatExporter.Core.Discord.Data.Embeds;
|
||||||
// https://discord.com/developers/docs/resources/channel#embed-object
|
// https://discord.com/developers/docs/resources/channel#embed-object
|
||||||
public partial record Embed(
|
public partial record Embed(
|
||||||
string? Title,
|
string? Title,
|
||||||
|
string? Type,
|
||||||
string? Url,
|
string? Url,
|
||||||
DateTimeOffset? Timestamp,
|
DateTimeOffset? Timestamp,
|
||||||
Color? Color,
|
Color? Color,
|
||||||
|
@ -19,6 +20,7 @@ public partial record Embed(
|
||||||
IReadOnlyList<EmbedField> Fields,
|
IReadOnlyList<EmbedField> Fields,
|
||||||
EmbedImage? Thumbnail,
|
EmbedImage? Thumbnail,
|
||||||
IReadOnlyList<EmbedImage> Images,
|
IReadOnlyList<EmbedImage> Images,
|
||||||
|
EmbedVideo? Video,
|
||||||
EmbedFooter? Footer)
|
EmbedFooter? Footer)
|
||||||
{
|
{
|
||||||
public PlainImageEmbedProjection? TryGetPlainImage() =>
|
public PlainImageEmbedProjection? TryGetPlainImage() =>
|
||||||
|
@ -29,6 +31,9 @@ public partial record Embed(
|
||||||
|
|
||||||
public YouTubeVideoEmbedProjection? TryGetYouTubeVideo() =>
|
public YouTubeVideoEmbedProjection? TryGetYouTubeVideo() =>
|
||||||
YouTubeVideoEmbedProjection.TryResolve(this);
|
YouTubeVideoEmbedProjection.TryResolve(this);
|
||||||
|
|
||||||
|
public GifvEmbedProjection? TryGetGifv() =>
|
||||||
|
GifvEmbedProjection.TryResolve(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public partial record Embed
|
public partial record Embed
|
||||||
|
@ -36,6 +41,7 @@ public partial record Embed
|
||||||
public static Embed Parse(JsonElement json)
|
public static Embed Parse(JsonElement json)
|
||||||
{
|
{
|
||||||
var title = json.GetPropertyOrNull("title")?.GetStringOrNull();
|
var title = json.GetPropertyOrNull("title")?.GetStringOrNull();
|
||||||
|
var type = json.GetPropertyOrNull("type")?.GetStringOrNull();
|
||||||
var url = json.GetPropertyOrNull("url")?.GetNonWhiteSpaceStringOrNull();
|
var url = json.GetPropertyOrNull("url")?.GetNonWhiteSpaceStringOrNull();
|
||||||
var timestamp = json.GetPropertyOrNull("timestamp")?.GetDateTimeOffset();
|
var timestamp = json.GetPropertyOrNull("timestamp")?.GetDateTimeOffset();
|
||||||
var color = json.GetPropertyOrNull("color")?.GetInt32OrNull()?.Pipe(System.Drawing.Color.FromArgb).ResetAlpha();
|
var color = json.GetPropertyOrNull("color")?.GetInt32OrNull()?.Pipe(System.Drawing.Color.FromArgb).ResetAlpha();
|
||||||
|
@ -59,10 +65,13 @@ public partial record Embed
|
||||||
json.GetPropertyOrNull("image")?.Pipe(EmbedImage.Parse).Enumerate().ToArray() ??
|
json.GetPropertyOrNull("image")?.Pipe(EmbedImage.Parse).Enumerate().ToArray() ??
|
||||||
Array.Empty<EmbedImage>();
|
Array.Empty<EmbedImage>();
|
||||||
|
|
||||||
|
var video = json.GetPropertyOrNull("video")?.Pipe(EmbedVideo.Parse);
|
||||||
|
|
||||||
var footer = json.GetPropertyOrNull("footer")?.Pipe(EmbedFooter.Parse);
|
var footer = json.GetPropertyOrNull("footer")?.Pipe(EmbedFooter.Parse);
|
||||||
|
|
||||||
return new Embed(
|
return new Embed(
|
||||||
title,
|
title,
|
||||||
|
type,
|
||||||
url,
|
url,
|
||||||
timestamp,
|
timestamp,
|
||||||
color,
|
color,
|
||||||
|
@ -71,6 +80,7 @@ public partial record Embed
|
||||||
fields,
|
fields,
|
||||||
thumbnail,
|
thumbnail,
|
||||||
images,
|
images,
|
||||||
|
video,
|
||||||
footer
|
footer
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
22
DiscordChatExporter.Core/Discord/Data/Embeds/EmbedVideo.cs
Normal file
22
DiscordChatExporter.Core/Discord/Data/Embeds/EmbedVideo.cs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
using JsonExtensions.Reading;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
|
namespace DiscordChatExporter.Core.Discord.Data.Embeds;
|
||||||
|
|
||||||
|
// https://discord.com/developers/docs/resources/channel#embed-object-embed-video-structure
|
||||||
|
public record EmbedVideo(
|
||||||
|
string? Url,
|
||||||
|
string? ProxyUrl,
|
||||||
|
int? Width,
|
||||||
|
int? Height)
|
||||||
|
{
|
||||||
|
public static EmbedVideo Parse(JsonElement json)
|
||||||
|
{
|
||||||
|
var url = json.GetPropertyOrNull("url")?.GetNonWhiteSpaceStringOrNull();
|
||||||
|
var proxyUrl = json.GetPropertyOrNull("proxy_url")?.GetNonWhiteSpaceStringOrNull();
|
||||||
|
var width = json.GetPropertyOrNull("width")?.GetInt32OrNull();
|
||||||
|
var height = json.GetPropertyOrNull("height")?.GetInt32OrNull();
|
||||||
|
|
||||||
|
return new EmbedVideo(url, proxyUrl, width, height);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
using System;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace DiscordChatExporter.Core.Discord.Data.Embeds;
|
||||||
|
|
||||||
|
public partial record GifvEmbedProjection(string Url)
|
||||||
|
{
|
||||||
|
public static GifvEmbedProjection? TryResolve(Embed embed)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(embed.Url))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (embed.Video is null || string.IsNullOrWhiteSpace(embed.Video.Url))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (!string.Equals(embed.Type, "gifv", StringComparison.OrdinalIgnoreCase))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return new GifvEmbedProjection(embed.Url);
|
||||||
|
}
|
||||||
|
}
|
|
@ -208,8 +208,20 @@
|
||||||
@{/* Embeds */}
|
@{/* Embeds */}
|
||||||
@foreach (var embed in message.Embeds)
|
@foreach (var embed in message.Embeds)
|
||||||
{
|
{
|
||||||
|
// Gifv embed
|
||||||
|
if (embed.TryGetGifv() is { } gifvEmbed)
|
||||||
|
{
|
||||||
|
@if (embed.Video is not null && !string.IsNullOrWhiteSpace(embed.Video.Url) && embed.Thumbnail is not null)
|
||||||
|
{
|
||||||
|
<div class="chatlog__attachment">
|
||||||
|
<video class="chatlog__attachment-media" poster="@await ResolveUrlAsync(embed.Thumbnail.ProxyUrl ?? embed.Thumbnail.Url)" loop="" controls="" aria-label="GIF" width="@(embed.Video.Width)" height="@(embed.Video.Height)">
|
||||||
|
<source src="@await ResolveUrlAsync(embed.Video.ProxyUrl ?? embed.Video.Url)" alt="@(embed.Description ?? "Tenor GIF")" title="@embed.Title">
|
||||||
|
</video>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
// Plain image embed
|
// Plain image embed
|
||||||
if (embed.TryGetPlainImage() is { } plainImageEmbed)
|
else if (embed.TryGetPlainImage() is { } plainImageEmbed)
|
||||||
{
|
{
|
||||||
<div class="chatlog__embed">
|
<div class="chatlog__embed">
|
||||||
<a href="@await ResolveUrlAsync(plainImageEmbed.Url)">
|
<a href="@await ResolveUrlAsync(plainImageEmbed.Url)">
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue