diff --git a/DysonNetwork.Sphere/Activity/ActivityService.cs b/DysonNetwork.Sphere/Activity/ActivityService.cs index e2d1583..43c32b2 100644 --- a/DysonNetwork.Sphere/Activity/ActivityService.cs +++ b/DysonNetwork.Sphere/Activity/ActivityService.cs @@ -30,6 +30,7 @@ public class ActivityService(AppDatabase db) .Include(e => e.Tags) .FilterWithVisibility(currentUser, userFriends) .ToListAsync(); + posts = PostService.TruncatePostContent(posts); var postsDict = posts.ToDictionary(p => p.Id); diff --git a/DysonNetwork.Sphere/Post/Post.cs b/DysonNetwork.Sphere/Post/Post.cs index 8ab8b3c..df4e3e5 100644 --- a/DysonNetwork.Sphere/Post/Post.cs +++ b/DysonNetwork.Sphere/Post/Post.cs @@ -51,7 +51,7 @@ public class Post : ModelBase public Post? ForwardedPost { get; set; } public ICollection Attachments { get; set; } = new List(); - public NpgsqlTsVector SearchVector { get; set; } + [JsonIgnore] public NpgsqlTsVector SearchVector { get; set; } public Publisher Publisher { get; set; } = null!; public ICollection Reactions { get; set; } = new List(); @@ -59,7 +59,8 @@ public class Post : ModelBase public ICollection Categories { get; set; } = new List(); public ICollection Collections { get; set; } = new List(); - public bool Empty => Content == null && Attachments.Count == 0 && ForwardedPostId == null; + [JsonIgnore] public bool Empty => Content == null && Attachments.Count == 0 && ForwardedPostId == null; + [NotMapped] public bool IsTruncated = false; } public class PostTag : ModelBase diff --git a/DysonNetwork.Sphere/Post/PostController.cs b/DysonNetwork.Sphere/Post/PostController.cs index 28e5ff5..411347b 100644 --- a/DysonNetwork.Sphere/Post/PostController.cs +++ b/DysonNetwork.Sphere/Post/PostController.cs @@ -38,6 +38,7 @@ public class PostController(AppDatabase db, PostService ps, RelationshipService .Skip(offset) .Take(take) .ToListAsync(); + posts = PostService.TruncatePostContent(posts); Response.Headers["X-Total"] = totalCount.ToString(); @@ -101,6 +102,7 @@ public class PostController(AppDatabase db, PostService ps, RelationshipService .Skip(offset) .Take(take) .ToListAsync(); + posts = PostService.TruncatePostContent(posts); Response.Headers["X-Total"] = totalCount.ToString(); diff --git a/DysonNetwork.Sphere/Post/PostService.cs b/DysonNetwork.Sphere/Post/PostService.cs index 35ebc1b..6160f46 100644 --- a/DysonNetwork.Sphere/Post/PostService.cs +++ b/DysonNetwork.Sphere/Post/PostService.cs @@ -1,3 +1,4 @@ +using System.Text.Json; using DysonNetwork.Sphere.Activity; using DysonNetwork.Sphere.Storage; using Microsoft.EntityFrameworkCore; @@ -7,6 +8,64 @@ namespace DysonNetwork.Sphere.Post; public class PostService(AppDatabase db, FileService fs, ActivityService act) { + public static List TruncatePostContent(List input) + { + // This truncate post content is designed for quill delta + const int maxLength = 256; + foreach (var item in input) + { + if (item.Content is not { RootElement: var rootElement }) continue; + + if (rootElement.ValueKind != JsonValueKind.Array) continue; + var totalLength = 0; + var truncatedArrayElements = new List(); + + foreach (var element in rootElement.EnumerateArray()) + { + if (element is { ValueKind: JsonValueKind.Object } && + element.TryGetProperty("insert", out var insertProperty)) + { + if (insertProperty is { ValueKind: JsonValueKind.String }) + { + var textContent = insertProperty.GetString()!; + if (totalLength + textContent.Length <= maxLength) + { + truncatedArrayElements.Add(element); + totalLength += textContent.Length; + } + else + { + var remainingLength = maxLength - totalLength; + if (remainingLength > 0) + { + using var truncatedElementDocument = + JsonDocument.Parse( + $@"{{ ""insert"": ""{textContent.Substring(0, remainingLength)}"" }}" + ); + truncatedArrayElements.Add(truncatedElementDocument.RootElement.Clone()); + totalLength = maxLength; + } + + break; + } + } + else + truncatedArrayElements.Add(element); + } + else + truncatedArrayElements.Add(element); + + if (totalLength >= maxLength) + break; + } + + using var newDocument = JsonDocument.Parse(JsonSerializer.Serialize(truncatedArrayElements)); + item.Content = newDocument; + } + + return input; + } + public async Task PostAsync( Account.Account user, Post post, diff --git a/DysonNetwork.Sphere/Realm/Realm.cs b/DysonNetwork.Sphere/Realm/Realm.cs new file mode 100644 index 0000000..6e8da29 --- /dev/null +++ b/DysonNetwork.Sphere/Realm/Realm.cs @@ -0,0 +1,18 @@ +using System.ComponentModel.DataAnnotations; +using System.Text.Json.Serialization; +using DysonNetwork.Sphere.Storage; + +namespace DysonNetwork.Sphere.Realm; + +public class Realm : ModelBase +{ + public long Id { get; set; } + [MaxLength(1024)] public string Name { get; set; } = string.Empty; + [MaxLength(4096)] public string Description { get; set; } = string.Empty; + + public CloudFile? Picture { get; set; } + public CloudFile? Background { get; set; } + + public long? AccountId { get; set; } + [JsonIgnore] public Account.Account? Account { get; set; } +} \ No newline at end of file