diff --git a/DiscordChatExporter.Core/Discord/Data/Embed.cs b/DiscordChatExporter.Core/Discord/Data/Embed.cs index b1c53b5..9a72679 100644 --- a/DiscordChatExporter.Core/Discord/Data/Embed.cs +++ b/DiscordChatExporter.Core/Discord/Data/Embed.cs @@ -55,6 +55,8 @@ namespace DiscordChatExporter.Core.Discord.Data Footer = footer; } + public YouTubeVideoEmbedProjection? TryGetYouTubeVideo() => YouTubeVideoEmbedProjection.TryResolve(this); + public override string ToString() => Title ?? ""; } diff --git a/DiscordChatExporter.Core/Discord/Data/YouTubeVideoEmbedProjection.cs b/DiscordChatExporter.Core/Discord/Data/YouTubeVideoEmbedProjection.cs new file mode 100644 index 0000000..ea65354 --- /dev/null +++ b/DiscordChatExporter.Core/Discord/Data/YouTubeVideoEmbedProjection.cs @@ -0,0 +1,61 @@ +using System.Text.RegularExpressions; + +namespace DiscordChatExporter.Core.Discord.Data +{ + public partial class YouTubeVideoEmbedProjection + { + public string VideoId { get; } + + public string Url { get; } + + public YouTubeVideoEmbedProjection(string videoId, string url) + { + VideoId = videoId; + Url = url; + } + + public override string ToString() => Url; + } + + public partial class YouTubeVideoEmbedProjection + { + // Adapted from YoutubeExplode + // https://github.com/Tyrrrz/YoutubeExplode/blob/5be164be20019783913f76fcc98f18c65aebe9f0/YoutubeExplode/Videos/VideoId.cs#L34-L64 + private static string? TryParseVideoId(string embedUrl) + { + // Regular URL + // https://www.youtube.com/watch?v=yIVRs6YSbOM + var regularMatch = Regex.Match(embedUrl, @"youtube\..+?/watch.*?v=(.*?)(?:&|/|$)").Groups[1].Value; + if (!string.IsNullOrWhiteSpace(regularMatch)) + return regularMatch; + + // Short URL + // https://youtu.be/yIVRs6YSbOM + var shortMatch = Regex.Match(embedUrl, @"youtu\.be/(.*?)(?:\?|&|/|$)").Groups[1].Value; + if (!string.IsNullOrWhiteSpace(shortMatch)) + return shortMatch; + + // Embed URL + // https://www.youtube.com/embed/yIVRs6YSbOM + var embedMatch = Regex.Match(embedUrl, @"youtube\..+?/embed/(.*?)(?:\?|&|/|$)").Groups[1].Value; + if (!string.IsNullOrWhiteSpace(embedMatch)) + return embedMatch; + + return null; + } + + public static YouTubeVideoEmbedProjection? TryResolve(Embed embed) + { + if (string.IsNullOrWhiteSpace(embed.Url)) + return null; + + var videoId = TryParseVideoId(embed.Url); + if (string.IsNullOrWhiteSpace(videoId)) + return null; + + var url = $"https://www.youtube.com/embed/{videoId}"; + + return new YouTubeVideoEmbedProjection(videoId, url); + } + } +} \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/Writers/Html/Core.css b/DiscordChatExporter.Core/Exporting/Writers/Html/Core.css index b7eef66..7afc74e 100644 --- a/DiscordChatExporter.Core/Exporting/Writers/Html/Core.css +++ b/DiscordChatExporter.Core/Exporting/Writers/Html/Core.css @@ -458,10 +458,6 @@ img { border-radius: 3px; } -.chatlog__embed-youtube-container { - margin-top: 0.6em; -} - .chatlog__embed-image-container { margin-top: 0.6em; } @@ -490,6 +486,15 @@ img { font-weight: 500; } +.chatlog__embed-youtube-container { + margin-top: 0.6em; +} + +.chatlog__embed-youtube { + border: 0; + border-radius: 3px; +} + .chatlog__reactions { display: flex; } diff --git a/DiscordChatExporter.Core/Exporting/Writers/Html/MessageGroupTemplate.cshtml b/DiscordChatExporter.Core/Exporting/Writers/Html/MessageGroupTemplate.cshtml index 0f3c47f..63e8951 100644 --- a/DiscordChatExporter.Core/Exporting/Writers/Html/MessageGroupTemplate.cshtml +++ b/DiscordChatExporter.Core/Exporting/Writers/Html/MessageGroupTemplate.cshtml @@ -161,6 +161,8 @@ @foreach (var embed in message.Embeds) { + var youTubeVideo = embed.TryGetYouTubeVideo(); +
@if (embed.Color is not null) { @@ -214,17 +216,12 @@ }
} - @if (!string.IsNullOrWhiteSpace(embed.Url) && embed.Url.IndexOf("youtube.com/watch?v=") != -1) - { - if (embed.Thumbnail is not null && !string.IsNullOrWhiteSpace(embed.Thumbnail.Url)) - { -
- -
- } + @if (youTubeVideo is not null) + { +
+ +
} else if (!string.IsNullOrWhiteSpace(embed.Description)) { @@ -260,16 +257,13 @@ } - @if (embed.Thumbnail is not null && !string.IsNullOrWhiteSpace(embed.Thumbnail.Url)) + @if (embed.Thumbnail is not null && !string.IsNullOrWhiteSpace(embed.Thumbnail.Url) && youTubeVideo is null) { - if (string.IsNullOrWhiteSpace(embed.Url) || embed.Url.IndexOf("youtube.com/watch?v=") == -1) - { -
- - Thumbnail - -
- } +
+ + Thumbnail + +
}