♻️ Refactor activitypub content storage
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using DysonNetwork.Shared.Proto;
|
||||
|
||||
namespace DysonNetwork.Shared.Models;
|
||||
@@ -22,6 +23,7 @@ public enum ContentSensitiveMark
|
||||
/// <summary>
|
||||
/// The class that used in jsonb columns which referenced the cloud file.
|
||||
/// The aim of this class is to store some properties that won't change to a file to reduce the database load.
|
||||
/// Supports both local cloud files (with Id) and external/fediverse files (with Url).
|
||||
/// </summary>
|
||||
public class SnCloudFileReferenceObject : ModelBase, ICloudFile
|
||||
{
|
||||
@@ -34,6 +36,11 @@ public class SnCloudFileReferenceObject : ModelBase, ICloudFile
|
||||
public string? Hash { get; set; }
|
||||
public long Size { get; set; }
|
||||
public bool HasCompression { get; set; } = false;
|
||||
|
||||
[MaxLength(2048)] public string? Url { get; set; }
|
||||
public int? Width { get; set; }
|
||||
public int? Height { get; set; }
|
||||
[MaxLength(64)] public string? Blurhash { get; set; }
|
||||
|
||||
public static SnCloudFileReferenceObject FromProtoValue(Proto.CloudFile proto)
|
||||
{
|
||||
@@ -49,7 +56,11 @@ public class SnCloudFileReferenceObject : ModelBase, ICloudFile
|
||||
MimeType = proto.MimeType,
|
||||
Hash = proto.Hash,
|
||||
Size = proto.Size,
|
||||
HasCompression = proto.HasCompression
|
||||
HasCompression = proto.HasCompression,
|
||||
Url = string.IsNullOrEmpty(proto.Url) ? null : proto.Url,
|
||||
Width = proto.HasWidth ? proto.Width : null,
|
||||
Height = proto.HasHeight ? proto.Height : null,
|
||||
Blurhash = proto.HasBlurhash ? proto.Blurhash : null
|
||||
};
|
||||
}
|
||||
|
||||
@@ -67,10 +78,11 @@ public class SnCloudFileReferenceObject : ModelBase, ICloudFile
|
||||
Size = Size,
|
||||
HasCompression = HasCompression,
|
||||
ContentType = MimeType ?? string.Empty,
|
||||
Url = string.Empty,
|
||||
// Convert file metadata
|
||||
Url = Url ?? string.Empty,
|
||||
Width = Width ?? 0,
|
||||
Height = Height ?? 0,
|
||||
Blurhash = Blurhash ?? string.Empty,
|
||||
FileMeta = GrpcTypeHelper.ConvertObjectToByteString(FileMeta),
|
||||
// Convert user metadata
|
||||
UserMeta = GrpcTypeHelper.ConvertObjectToByteString(UserMeta),
|
||||
SensitiveMarks = GrpcTypeHelper.ConvertObjectToByteString(SensitiveMarks)
|
||||
};
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text.Json.Serialization;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NodaTime;
|
||||
|
||||
namespace DysonNetwork.Shared.Models;
|
||||
|
||||
public class SnFediverseActivity : ModelBase
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
|
||||
[MaxLength(2048)]
|
||||
public string Uri { get; set; } = null!;
|
||||
|
||||
public FediverseActivityType Type { get; set; }
|
||||
|
||||
[MaxLength(2048)]
|
||||
public string? ObjectUri { get; set; }
|
||||
|
||||
[MaxLength(2048)]
|
||||
public string? TargetUri { get; set; }
|
||||
|
||||
public Instant? PublishedAt { get; set; }
|
||||
|
||||
public bool IsLocal { get; set; }
|
||||
|
||||
[Column(TypeName = "jsonb")]
|
||||
public Dictionary<string, object>? RawData { get; set; }
|
||||
|
||||
public Guid ActorId { get; set; }
|
||||
[JsonIgnore]
|
||||
public SnFediverseActor Actor { get; set; } = null!;
|
||||
|
||||
public Guid? ContentId { get; set; }
|
||||
[JsonIgnore]
|
||||
public SnFediverseContent? Content { get; set; }
|
||||
|
||||
public Guid? TargetActorId { get; set; }
|
||||
[JsonIgnore]
|
||||
public SnFediverseActor? TargetActor { get; set; }
|
||||
|
||||
public Guid? LocalPostId { get; set; }
|
||||
public Guid? LocalAccountId { get; set; }
|
||||
|
||||
public ActivityStatus Status { get; set; } = ActivityStatus.Pending;
|
||||
|
||||
[MaxLength(4096)]
|
||||
public string? ErrorMessage { get; set; }
|
||||
}
|
||||
|
||||
public enum FediverseActivityType
|
||||
{
|
||||
Create,
|
||||
Update,
|
||||
Delete,
|
||||
Follow,
|
||||
Unfollow,
|
||||
Like,
|
||||
Announce,
|
||||
Undo,
|
||||
Accept,
|
||||
Reject,
|
||||
Add,
|
||||
Remove,
|
||||
Block,
|
||||
Unblock,
|
||||
Flag,
|
||||
Move
|
||||
}
|
||||
|
||||
public enum ActivityStatus
|
||||
{
|
||||
Pending,
|
||||
Processing,
|
||||
Completed,
|
||||
Failed
|
||||
}
|
||||
@@ -34,8 +34,6 @@ public class SnFediverseActor : ModelBase
|
||||
public Guid InstanceId { get; set; }
|
||||
public SnFediverseInstance Instance { get; set; } = null!;
|
||||
|
||||
[JsonIgnore] public ICollection<SnFediverseContent> Contents { get; set; } = [];
|
||||
[JsonIgnore] public ICollection<SnFediverseActivity> Activities { get; set; } = [];
|
||||
[JsonIgnore] public ICollection<SnFediverseRelationship> FollowingRelationships { get; set; } = [];
|
||||
[JsonIgnore] public ICollection<SnFediverseRelationship> FollowerRelationships { get; set; } = [];
|
||||
|
||||
|
||||
@@ -1,143 +0,0 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text.Json.Serialization;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NodaTime;
|
||||
|
||||
namespace DysonNetwork.Shared.Models;
|
||||
|
||||
[Index(nameof(Uri), IsUnique = true)]
|
||||
public class SnFediverseContent : ModelBase
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
|
||||
[MaxLength(2048)]
|
||||
public string Uri { get; set; } = null!;
|
||||
|
||||
public FediverseContentType Type { get; set; }
|
||||
|
||||
[MaxLength(1024)]
|
||||
public string? Title { get; set; }
|
||||
|
||||
[MaxLength(4096)]
|
||||
public string? Summary { get; set; }
|
||||
|
||||
public string? Content { get; set; }
|
||||
|
||||
public string? ContentHtml { get; set; }
|
||||
|
||||
[MaxLength(2048)]
|
||||
public string? Language { get; set; }
|
||||
|
||||
[MaxLength(2048)]
|
||||
public string? InReplyTo { get; set; }
|
||||
|
||||
[MaxLength(2048)]
|
||||
public string? AnnouncedContentUri { get; set; }
|
||||
|
||||
public Instant? PublishedAt { get; set; }
|
||||
public Instant? EditedAt { get; set; }
|
||||
|
||||
public bool IsSensitive { get; set; } = false;
|
||||
|
||||
[Column(TypeName = "jsonb")]
|
||||
public List<ContentAttachment>? Attachments { get; set; }
|
||||
|
||||
[Column(TypeName = "jsonb")]
|
||||
public List<ContentMention>? Mentions { get; set; }
|
||||
|
||||
[Column(TypeName = "jsonb")]
|
||||
public List<ContentTag>? Tags { get; set; }
|
||||
|
||||
[Column(TypeName = "jsonb")]
|
||||
public List<ContentEmoji>? Emojis { get; set; }
|
||||
|
||||
[Column(TypeName = "jsonb")]
|
||||
public Dictionary<string, object>? Metadata { get; set; }
|
||||
|
||||
public Guid ActorId { get; set; }
|
||||
[JsonIgnore]
|
||||
public SnFediverseActor Actor { get; set; } = null!;
|
||||
|
||||
public Guid InstanceId { get; set; }
|
||||
[JsonIgnore]
|
||||
public SnFediverseInstance Instance { get; set; } = null!;
|
||||
|
||||
[JsonIgnore]
|
||||
public ICollection<SnFediverseActivity> Activities { get; set; } = [];
|
||||
|
||||
[JsonIgnore]
|
||||
public ICollection<SnFediverseReaction> Reactions { get; set; } = [];
|
||||
|
||||
public int ReplyCount { get; set; }
|
||||
public int BoostCount { get; set; }
|
||||
public int LikeCount { get; set; }
|
||||
|
||||
public Guid? LocalPostId { get; set; }
|
||||
[NotMapped]
|
||||
public SnPost? LocalPost { get; set; }
|
||||
}
|
||||
|
||||
public enum FediverseContentType
|
||||
{
|
||||
Note,
|
||||
Article,
|
||||
Image,
|
||||
Video,
|
||||
Audio,
|
||||
Page,
|
||||
Question,
|
||||
Event,
|
||||
Document
|
||||
}
|
||||
|
||||
public class ContentAttachment
|
||||
{
|
||||
[MaxLength(2048)]
|
||||
public string? Url { get; set; }
|
||||
|
||||
[MaxLength(2048)]
|
||||
public string? MediaType { get; set; }
|
||||
|
||||
[MaxLength(1024)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
public int? Width { get; set; }
|
||||
public int? Height { get; set; }
|
||||
|
||||
[MaxLength(64)]
|
||||
public string? Blurhash { get; set; }
|
||||
}
|
||||
|
||||
public class ContentMention
|
||||
{
|
||||
[MaxLength(256)]
|
||||
public string? Username { get; set; }
|
||||
|
||||
[MaxLength(2048)]
|
||||
public string? Url { get; set; }
|
||||
|
||||
[MaxLength(2048)]
|
||||
public string? ActorUri { get; set; }
|
||||
}
|
||||
|
||||
public class ContentTag
|
||||
{
|
||||
[MaxLength(256)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[MaxLength(2048)]
|
||||
public string? Url { get; set; }
|
||||
}
|
||||
|
||||
public class ContentEmoji
|
||||
{
|
||||
[MaxLength(64)]
|
||||
public string? Shortcode { get; set; }
|
||||
|
||||
[MaxLength(2048)]
|
||||
public string? StaticUrl { get; set; }
|
||||
|
||||
[MaxLength(2048)]
|
||||
public string? Url { get; set; }
|
||||
}
|
||||
@@ -28,7 +28,6 @@ public class SnFediverseInstance : ModelBase
|
||||
|
||||
[MaxLength(2048)] public string? BlockReason { get; set; }
|
||||
[JsonIgnore] public ICollection<SnFediverseActor> Actors { get; set; } = [];
|
||||
[JsonIgnore] public ICollection<SnFediverseContent> Contents { get; set; } = [];
|
||||
|
||||
public Instant? LastFetchedAt { get; set; }
|
||||
public Instant? LastActivityAt { get; set; }
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text.Json.Serialization;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NodaTime;
|
||||
|
||||
namespace DysonNetwork.Shared.Models;
|
||||
|
||||
public class SnFediverseReaction : ModelBase
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
|
||||
[MaxLength(2048)]
|
||||
public string Uri { get; set; } = null!;
|
||||
|
||||
public FediverseReactionType Type { get; set; }
|
||||
|
||||
[MaxLength(64)]
|
||||
public string? Emoji { get; set; }
|
||||
|
||||
public bool IsLocal { get; set; }
|
||||
|
||||
public Guid ContentId { get; set; }
|
||||
[JsonIgnore]
|
||||
public SnFediverseContent Content { get; set; } = null!;
|
||||
|
||||
public Guid ActorId { get; set; }
|
||||
[JsonIgnore]
|
||||
public SnFediverseActor Actor { get; set; } = null!;
|
||||
|
||||
public Guid? LocalAccountId { get; set; }
|
||||
public Guid? LocalReactionId { get; set; }
|
||||
}
|
||||
|
||||
public enum FediverseReactionType
|
||||
{
|
||||
Like,
|
||||
Emoji,
|
||||
Dislike
|
||||
}
|
||||
@@ -21,6 +21,12 @@ public enum PostVisibility
|
||||
Private,
|
||||
}
|
||||
|
||||
public enum PostContentType
|
||||
{
|
||||
Markdown,
|
||||
Html,
|
||||
}
|
||||
|
||||
public enum PostPinMode
|
||||
{
|
||||
PublisherPage,
|
||||
@@ -28,6 +34,39 @@ public enum PostPinMode
|
||||
ReplyPage,
|
||||
}
|
||||
|
||||
public class ContentMention
|
||||
{
|
||||
[MaxLength(256)]
|
||||
public string? Username { get; set; }
|
||||
|
||||
[MaxLength(2048)]
|
||||
public string? Url { get; set; }
|
||||
|
||||
[MaxLength(2048)]
|
||||
public string? ActorUri { get; set; }
|
||||
}
|
||||
|
||||
public class ContentTag
|
||||
{
|
||||
[MaxLength(256)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[MaxLength(2048)]
|
||||
public string? Url { get; set; }
|
||||
}
|
||||
|
||||
public class ContentEmoji
|
||||
{
|
||||
[MaxLength(64)]
|
||||
public string? Shortcode { get; set; }
|
||||
|
||||
[MaxLength(2048)]
|
||||
public string? StaticUrl { get; set; }
|
||||
|
||||
[MaxLength(2048)]
|
||||
public string? Url { get; set; }
|
||||
}
|
||||
|
||||
public class SnPost : ModelBase, IIdentifiedResource, ITimelineEvent
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
@@ -47,11 +86,13 @@ public class SnPost : ModelBase, IIdentifiedResource, ITimelineEvent
|
||||
// ReSharper disable once EntityFramework.ModelValidation.UnlimitedStringLength
|
||||
public string? Content { get; set; }
|
||||
|
||||
public PostContentType ContentType { get; set; } = PostContentType.Markdown;
|
||||
|
||||
public PostType Type { get; set; }
|
||||
public PostPinMode? PinMode { get; set; }
|
||||
|
||||
[Column(TypeName = "jsonb")]
|
||||
public Dictionary<string, object>? Meta { get; set; }
|
||||
public Dictionary<string, object>? Metadata { get; set; }
|
||||
|
||||
[Column(TypeName = "jsonb")]
|
||||
public List<ContentSensitiveMark>? SensitiveMarks { get; set; } = [];
|
||||
@@ -59,17 +100,28 @@ public class SnPost : ModelBase, IIdentifiedResource, ITimelineEvent
|
||||
[Column(TypeName = "jsonb")]
|
||||
public PostEmbedView? EmbedView { get; set; }
|
||||
|
||||
[MaxLength(8192)] public string? FediverseUri { get; set; }
|
||||
public FediverseContentType? FediverseType { get; set; }
|
||||
[MaxLength(2048)] public string? Language { get; set; }
|
||||
[Column(TypeName = "jsonb")]
|
||||
public List<ContentMention>? Mentions { get; set; }
|
||||
|
||||
public int BoostCount { get; set; }
|
||||
public int LikeCount { get; set; }
|
||||
|
||||
public Guid? ActorId { get; set; }
|
||||
public SnFediverseActor? Actor { get; set; }
|
||||
|
||||
public int ViewsUnique { get; set; }
|
||||
public int ViewsTotal { get; set; }
|
||||
public int Upvotes { get; set; }
|
||||
public int Downvotes { get; set; }
|
||||
public decimal AwardedScore { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public Dictionary<string, int> ReactionsCount { get; set; } = new();
|
||||
public int RepliesCount { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public int RepliesCount { get; set; }
|
||||
public Dictionary<string, int> ReactionsCount { get; set; } = new();
|
||||
|
||||
[NotMapped]
|
||||
public Dictionary<string, bool>? ReactionsMade { get; set; }
|
||||
@@ -90,8 +142,8 @@ public class SnPost : ModelBase, IIdentifiedResource, ITimelineEvent
|
||||
[Column(TypeName = "jsonb")]
|
||||
public List<SnCloudFileReferenceObject> Attachments { get; set; } = [];
|
||||
|
||||
public Guid PublisherId { get; set; }
|
||||
public SnPublisher Publisher { get; set; } = null!;
|
||||
public Guid? PublisherId { get; set; }
|
||||
public SnPublisher? Publisher { get; set; }
|
||||
|
||||
public List<SnPostAward> Awards { get; set; } = [];
|
||||
|
||||
@@ -133,7 +185,7 @@ public class SnPost : ModelBase, IIdentifiedResource, ITimelineEvent
|
||||
RepliedGone = RepliedGone,
|
||||
ForwardedGone = ForwardedGone,
|
||||
PublisherId = PublisherId.ToString(),
|
||||
Publisher = Publisher.ToProtoValue(),
|
||||
Publisher = Publisher?.ToProtoValue(),
|
||||
CreatedAt = Timestamp.FromDateTimeOffset(CreatedAt.ToDateTimeOffset()),
|
||||
UpdatedAt = Timestamp.FromDateTimeOffset(UpdatedAt.ToDateTimeOffset()),
|
||||
};
|
||||
@@ -147,11 +199,13 @@ public class SnPost : ModelBase, IIdentifiedResource, ITimelineEvent
|
||||
if (Content != null)
|
||||
proto.Content = Content;
|
||||
|
||||
proto.ContentType = (Proto.PostContentType)((int)ContentType + 1);
|
||||
|
||||
if (PinMode.HasValue)
|
||||
proto.PinMode = (Proto.PostPinMode)((int)PinMode.Value + 1);
|
||||
|
||||
if (Meta != null)
|
||||
proto.Meta = GrpcTypeHelper.ConvertObjectToByteString(Meta);
|
||||
if (Metadata != null)
|
||||
proto.Meta = GrpcTypeHelper.ConvertObjectToByteString(Metadata);
|
||||
|
||||
if (SensitiveMarks != null)
|
||||
proto.SensitiveMarks = GrpcTypeHelper.ConvertObjectToByteString(SensitiveMarks);
|
||||
@@ -159,6 +213,30 @@ public class SnPost : ModelBase, IIdentifiedResource, ITimelineEvent
|
||||
if (EmbedView != null)
|
||||
proto.EmbedView = EmbedView.ToProtoValue();
|
||||
|
||||
if (!string.IsNullOrEmpty(FediverseUri))
|
||||
proto.FediverseUri = FediverseUri;
|
||||
|
||||
if (FediverseType.HasValue)
|
||||
proto.FediverseType = (Proto.FediverseContentType)((int)FediverseType.Value + 1);
|
||||
|
||||
if (!string.IsNullOrEmpty(Language))
|
||||
proto.Language = Language;
|
||||
|
||||
if (Mentions != null)
|
||||
proto.Mentions.AddRange(Mentions.Select(m => new Proto.ContentMention
|
||||
{
|
||||
Username = m.Username,
|
||||
Url = m.Url,
|
||||
ActorUri = m.ActorUri
|
||||
}));
|
||||
|
||||
proto.RepliesCount = RepliesCount;
|
||||
proto.BoostCount = BoostCount;
|
||||
proto.LikeCount = LikeCount;
|
||||
|
||||
if (ActorId.HasValue)
|
||||
proto.ActorId = ActorId.Value.ToString();
|
||||
|
||||
if (RepliedPostId.HasValue)
|
||||
{
|
||||
proto.RepliedPostId = RepliedPostId.Value.ToString();
|
||||
@@ -220,7 +298,7 @@ public class SnPost : ModelBase, IIdentifiedResource, ITimelineEvent
|
||||
RepliedGone = proto.RepliedGone,
|
||||
ForwardedGone = proto.ForwardedGone,
|
||||
PublisherId = Guid.Parse(proto.PublisherId),
|
||||
Publisher = SnPublisher.FromProtoValue(proto.Publisher),
|
||||
Publisher = proto.Publisher != null ? SnPublisher.FromProtoValue(proto.Publisher) : null,
|
||||
CreatedAt = Instant.FromDateTimeOffset(proto.CreatedAt.ToDateTimeOffset()),
|
||||
UpdatedAt = Instant.FromDateTimeOffset(proto.UpdatedAt.ToDateTimeOffset()),
|
||||
};
|
||||
@@ -234,11 +312,13 @@ public class SnPost : ModelBase, IIdentifiedResource, ITimelineEvent
|
||||
if (!string.IsNullOrEmpty(proto.Content))
|
||||
post.Content = proto.Content;
|
||||
|
||||
post.ContentType = (PostContentType)((int)proto.ContentType - 1);
|
||||
|
||||
if (proto is { HasPinMode: true, PinMode: > 0 })
|
||||
post.PinMode = (PostPinMode)(proto.PinMode - 1);
|
||||
|
||||
if (proto.Meta != null)
|
||||
post.Meta = GrpcTypeHelper.ConvertByteStringToObject<Dictionary<string, object>>(
|
||||
post.Metadata = GrpcTypeHelper.ConvertByteStringToObject<Dictionary<string, object>>(
|
||||
proto.Meta
|
||||
);
|
||||
|
||||
@@ -250,6 +330,30 @@ public class SnPost : ModelBase, IIdentifiedResource, ITimelineEvent
|
||||
if (proto.EmbedView is not null)
|
||||
post.EmbedView = PostEmbedView.FromProtoValue(proto.EmbedView);
|
||||
|
||||
if (!string.IsNullOrEmpty(proto.FediverseUri))
|
||||
post.FediverseUri = proto.FediverseUri;
|
||||
|
||||
if (proto.HasFediverseType && proto.FediverseType > 0)
|
||||
post.FediverseType = (FediverseContentType)((int)proto.FediverseType - 1);
|
||||
|
||||
if (!string.IsNullOrEmpty(proto.Language))
|
||||
post.Language = proto.Language;
|
||||
|
||||
if (proto.Mentions != null && proto.Mentions.Count > 0)
|
||||
post.Mentions = proto.Mentions.Select(m => new ContentMention
|
||||
{
|
||||
Username = m.Username,
|
||||
Url = m.Url,
|
||||
ActorUri = m.ActorUri
|
||||
}).ToList();
|
||||
|
||||
post.RepliesCount = proto.RepliesCount;
|
||||
post.BoostCount = proto.BoostCount;
|
||||
post.LikeCount = proto.LikeCount;
|
||||
|
||||
if (!string.IsNullOrEmpty(proto.ActorId))
|
||||
post.ActorId = Guid.Parse(proto.ActorId);
|
||||
|
||||
if (!string.IsNullOrEmpty(proto.RepliedPostId))
|
||||
{
|
||||
post.RepliedPostId = Guid.Parse(proto.RepliedPostId);
|
||||
@@ -487,13 +591,17 @@ public class SnPostReaction : ModelBase
|
||||
public PostReactionAttitude Attitude { get; set; }
|
||||
|
||||
public Guid PostId { get; set; }
|
||||
[JsonIgnore] public SnPost Post { get; set; } = null!;
|
||||
|
||||
public Guid? AccountId { get; set; }
|
||||
[NotMapped] public SnAccount? Account { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public SnPost Post { get; set; } = null!;
|
||||
public Guid AccountId { get; set; }
|
||||
[MaxLength(2048)] public string? FediverseUri { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public SnAccount? Account { get; set; }
|
||||
public Guid? ActorId { get; set; }
|
||||
public SnFediverseActor? Actor { get; set; }
|
||||
|
||||
public bool IsLocal { get; set; } = true;
|
||||
|
||||
public PostReaction ToProtoValue()
|
||||
{
|
||||
@@ -503,7 +611,10 @@ public class SnPostReaction : ModelBase
|
||||
Symbol = Symbol,
|
||||
Attitude = (Proto.PostReactionAttitude)((int)Attitude + 1),
|
||||
PostId = PostId.ToString(),
|
||||
AccountId = AccountId.ToString(),
|
||||
AccountId = AccountId?.ToString() ?? string.Empty,
|
||||
FediverseUri = FediverseUri ?? string.Empty,
|
||||
IsLocal = IsLocal,
|
||||
ActorId = ActorId?.ToString() ?? string.Empty,
|
||||
CreatedAt = Timestamp.FromDateTimeOffset(CreatedAt.ToDateTimeOffset()),
|
||||
UpdatedAt = Timestamp.FromDateTimeOffset(UpdatedAt.ToDateTimeOffset()),
|
||||
};
|
||||
@@ -515,7 +626,7 @@ public class SnPostReaction : ModelBase
|
||||
return proto;
|
||||
}
|
||||
|
||||
public static SnPostReaction FromProtoValue(Proto.PostReaction proto)
|
||||
public static SnPostReaction FromProtoValue(PostReaction proto)
|
||||
{
|
||||
return new SnPostReaction
|
||||
{
|
||||
@@ -523,8 +634,11 @@ public class SnPostReaction : ModelBase
|
||||
Symbol = proto.Symbol,
|
||||
Attitude = (PostReactionAttitude)((int)proto.Attitude - 1),
|
||||
PostId = Guid.Parse(proto.PostId),
|
||||
AccountId = Guid.Parse(proto.AccountId),
|
||||
AccountId = !string.IsNullOrEmpty(proto.AccountId) ? Guid.Parse(proto.AccountId) : null,
|
||||
Account = proto.Account != null ? SnAccount.FromProtoValue(proto.Account) : null,
|
||||
FediverseUri = !string.IsNullOrEmpty(proto.FediverseUri) ? proto.FediverseUri : null,
|
||||
ActorId = !string.IsNullOrEmpty(proto.ActorId) ? Guid.Parse(proto.ActorId) : null,
|
||||
IsLocal = proto.IsLocal,
|
||||
CreatedAt = Instant.FromDateTimeOffset(proto.CreatedAt.ToDateTimeOffset()),
|
||||
UpdatedAt = Instant.FromDateTimeOffset(proto.UpdatedAt.ToDateTimeOffset()),
|
||||
};
|
||||
|
||||
@@ -45,6 +45,15 @@ message CloudFile {
|
||||
|
||||
// When the file was uploaded
|
||||
google.protobuf.Timestamp uploaded_at = 11;
|
||||
|
||||
// Image/Video width (optional, for media files)
|
||||
optional int32 width = 13;
|
||||
|
||||
// Image/Video height (optional, for media files)
|
||||
optional int32 height = 14;
|
||||
|
||||
// Blurhash for placeholder (optional, for images)
|
||||
optional string blurhash = 15;
|
||||
}
|
||||
|
||||
// Service for file operations
|
||||
|
||||
@@ -61,8 +61,33 @@ enum PostEmbedViewRenderer {
|
||||
WEBVIEW = 1;
|
||||
}
|
||||
|
||||
enum PostContentType {
|
||||
POST_CONTENT_TYPE_UNSPECIFIED = 0;
|
||||
MARKDOWN = 1;
|
||||
HTML = 2;
|
||||
}
|
||||
|
||||
enum FediverseContentType {
|
||||
FEDIVERSE_CONTENT_TYPE_UNSPECIFIED = 0;
|
||||
FEDIVERSE_NOTE = 1;
|
||||
FEDIVERSE_ARTICLE = 2;
|
||||
FEDIVERSE_IMAGE = 3;
|
||||
FEDIVERSE_VIDEO = 4;
|
||||
FEDIVERSE_AUDIO = 5;
|
||||
FEDIVERSE_PAGE = 6;
|
||||
FEDIVERSE_QUESTION = 7;
|
||||
FEDIVERSE_EVENT = 8;
|
||||
FEDIVERSE_DOCUMENT = 9;
|
||||
}
|
||||
|
||||
// Messages
|
||||
|
||||
message ContentMention {
|
||||
optional string username = 1;
|
||||
optional string url = 2;
|
||||
optional string actor_uri = 3;
|
||||
}
|
||||
|
||||
message PostEmbedView {
|
||||
string uri = 1;
|
||||
optional double aspect_ratio = 2;
|
||||
@@ -110,7 +135,16 @@ message Post {
|
||||
repeated CloudFile attachments = 30; // List<SnCloudFileReferenceObject>
|
||||
|
||||
string publisher_id = 31;
|
||||
Publisher publisher = 32;
|
||||
optional Publisher publisher = 32;
|
||||
|
||||
optional string fediverse_uri = 41;
|
||||
optional FediverseContentType fediverse_type = 42;
|
||||
optional string language = 43;
|
||||
optional PostContentType content_type = 44;
|
||||
repeated ContentMention mentions = 48;
|
||||
int32 boost_count = 50;
|
||||
int32 like_count = 51;
|
||||
optional string actor_id = 53;
|
||||
|
||||
repeated PostAward awards = 33;
|
||||
repeated PostReaction reactions = 34;
|
||||
@@ -189,6 +223,10 @@ message PostReaction {
|
||||
string account_id = 5;
|
||||
optional Account account = 6; // optional full account
|
||||
|
||||
optional string fediverse_uri = 9;
|
||||
optional string actor_id = 11;
|
||||
bool is_local = 10;
|
||||
|
||||
google.protobuf.Timestamp created_at = 7;
|
||||
google.protobuf.Timestamp updated_at = 8;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user