Support GIF embeds when exporting to HTML (#919)

pull/925/head
gan-of-culture 2 years ago committed by GitHub
parent a405ab184e
commit f28d662a71
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -11,6 +11,7 @@ namespace DiscordChatExporter.Core.Discord.Data.Embeds;
// https://discord.com/developers/docs/resources/channel#embed-object
public partial record Embed(
string? Title,
string? Type,
string? Url,
DateTimeOffset? Timestamp,
Color? Color,
@ -19,6 +20,7 @@ public partial record Embed(
IReadOnlyList<EmbedField> Fields,
EmbedImage? Thumbnail,
IReadOnlyList<EmbedImage> Images,
EmbedVideo? Video,
EmbedFooter? Footer)
{
public PlainImageEmbedProjection? TryGetPlainImage() =>
@ -29,6 +31,9 @@ public partial record Embed(
public YouTubeVideoEmbedProjection? TryGetYouTubeVideo() =>
YouTubeVideoEmbedProjection.TryResolve(this);
public GifvEmbedProjection? TryGetGifv() =>
GifvEmbedProjection.TryResolve(this);
}
public partial record Embed
@ -36,6 +41,7 @@ public partial record Embed
public static Embed Parse(JsonElement json)
{
var title = json.GetPropertyOrNull("title")?.GetStringOrNull();
var type = json.GetPropertyOrNull("type")?.GetStringOrNull();
var url = json.GetPropertyOrNull("url")?.GetNonWhiteSpaceStringOrNull();
var timestamp = json.GetPropertyOrNull("timestamp")?.GetDateTimeOffset();
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() ??
Array.Empty<EmbedImage>();
var video = json.GetPropertyOrNull("video")?.Pipe(EmbedVideo.Parse);
var footer = json.GetPropertyOrNull("footer")?.Pipe(EmbedFooter.Parse);
return new Embed(
title,
type,
url,
timestamp,
color,
@ -71,6 +80,7 @@ public partial record Embed
fields,
thumbnail,
images,
video,
footer
);
}

@ -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 */}
@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
if (embed.TryGetPlainImage() is { } plainImageEmbed)
else if (embed.TryGetPlainImage() is { } plainImageEmbed)
{
<div class="chatlog__embed">
<a href="@await ResolveUrlAsync(plainImageEmbed.Url)">

Loading…
Cancel
Save