🐛 Bug fixes in post embed links

This commit is contained in:
LittleSheep 2025-06-21 14:30:19 +08:00
parent d385abbf57
commit eadf25f389
4 changed files with 53 additions and 34 deletions

View File

@ -0,0 +1,44 @@
using System.Reflection;
using System.Text.Json.Serialization;
namespace DysonNetwork.Sphere.Connection.WebReader;
/// <summary>
/// The embeddable can be used in the post or messages' meta's embeds fields
/// To render a richer type of content.
///
/// A simple example of using link preview embed:
/// <code>
/// {
/// // ... post content
/// "meta": {
/// "embeds": [
/// {
/// "type": "link",
/// "title: "...",
/// /// ...
/// }
/// ]
/// }
/// }
/// </code>
/// </summary>
public abstract class EmbeddableBase
{
public abstract string Type { get; }
public Dictionary<string, object> ToDictionary()
{
var dict = new Dictionary<string, object>();
foreach (var prop in GetType().GetProperties())
{
if (prop.GetCustomAttribute<JsonIgnoreAttribute>() is not null)
continue;
var value = prop.GetValue(this);
if (value is null) continue;
dict[prop.Name] = value;
}
return dict;
}
}

View File

@ -1,26 +0,0 @@
namespace DysonNetwork.Sphere.Connection.WebReader;
/// <summary>
/// The embeddable can be used in the post or messages' meta's embeds fields
/// To render richer type of content.
///
/// A simple example of using link preview embed:
/// <code>
/// {
/// // ... post content
/// "meta": {
/// "embeds": [
/// {
/// "type": "link",
/// "title: "...",
/// /// ...
/// }
/// ]
/// }
/// }
/// </code>
/// </summary>
public interface IEmbeddable
{
public string Type { get; }
}

View File

@ -4,9 +4,9 @@ namespace DysonNetwork.Sphere.Connection.WebReader;
/// The link embed is a part of the embeddable implementations /// The link embed is a part of the embeddable implementations
/// It can be used in the post or messages' meta's embeds fields /// It can be used in the post or messages' meta's embeds fields
/// </summary> /// </summary>
public class LinkEmbed : IEmbeddable public class LinkEmbed : EmbeddableBase
{ {
public string Type => "link"; public override string Type => "link";
/// <summary> /// <summary>
/// The original URL that was processed /// The original URL that was processed

View File

@ -283,12 +283,12 @@ public partial class PostService(
item.Meta ??= new Dictionary<string, object>(); item.Meta ??= new Dictionary<string, object>();
// Initialize the embeds' array if it doesn't exist // Initialize the embeds' array if it doesn't exist
if (!item.Meta.TryGetValue("embeds", out var existingEmbeds) || existingEmbeds is not List<IEmbeddable>) if (!item.Meta.TryGetValue("embeds", out var existingEmbeds) || existingEmbeds is not List<EmbeddableBase>)
{ {
item.Meta["embeds"] = new List<IEmbeddable>(); item.Meta["embeds"] = new List<Dictionary<string, object>>();
} }
var embeds = (List<IEmbeddable>)item.Meta["embeds"]; var embeds = (List<Dictionary<string, object>>)item.Meta["embeds"];
// Process up to 3 links to avoid excessive processing // Process up to 3 links to avoid excessive processing
var processedLinks = 0; var processedLinks = 0;
@ -302,13 +302,14 @@ public partial class PostService(
try try
{ {
// Check if this URL is already in the embed list // Check if this URL is already in the embed list
var urlAlreadyEmbedded = embeds.OfType<LinkEmbed>().Any(e => e.Url == url); var urlAlreadyEmbedded = embeds.Any(e =>
e.TryGetValue("Url", out var originalUrl) && (string)originalUrl == url);
if (urlAlreadyEmbedded) if (urlAlreadyEmbedded)
continue; continue;
// Preview the link // Preview the link
var linkEmbed = await reader.GetLinkPreviewAsync(url); var linkEmbed = await reader.GetLinkPreviewAsync(url);
embeds.Add(linkEmbed); embeds.Add(linkEmbed.ToDictionary());
processedLinks++; processedLinks++;
} }
catch catch
@ -341,7 +342,7 @@ public partial class PostService(
// If embeds were added, update the post in the database // If embeds were added, update the post in the database
if (updatedPost.Meta != null && if (updatedPost.Meta != null &&
updatedPost.Meta.TryGetValue("embeds", out var embeds) && updatedPost.Meta.TryGetValue("embeds", out var embeds) &&
embeds is List<IEmbeddable> { Count: > 0 } embedsList) embeds is List<EmbeddableBase> { Count: > 0 } embedsList)
{ {
// Get a fresh copy of the post from the database // Get a fresh copy of the post from the database
var dbPost = await dbContext.Posts.FindAsync(post.Id); var dbPost = await dbContext.Posts.FindAsync(post.Id);