♻️ Refactor activitypub content storage
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using DysonNetwork.Shared.Proto;
|
using DysonNetwork.Shared.Proto;
|
||||||
|
|
||||||
namespace DysonNetwork.Shared.Models;
|
namespace DysonNetwork.Shared.Models;
|
||||||
@@ -22,6 +23,7 @@ public enum ContentSensitiveMark
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The class that used in jsonb columns which referenced the cloud file.
|
/// 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.
|
/// 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>
|
/// </summary>
|
||||||
public class SnCloudFileReferenceObject : ModelBase, ICloudFile
|
public class SnCloudFileReferenceObject : ModelBase, ICloudFile
|
||||||
{
|
{
|
||||||
@@ -34,6 +36,11 @@ public class SnCloudFileReferenceObject : ModelBase, ICloudFile
|
|||||||
public string? Hash { get; set; }
|
public string? Hash { get; set; }
|
||||||
public long Size { get; set; }
|
public long Size { get; set; }
|
||||||
public bool HasCompression { get; set; } = false;
|
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)
|
public static SnCloudFileReferenceObject FromProtoValue(Proto.CloudFile proto)
|
||||||
{
|
{
|
||||||
@@ -49,7 +56,11 @@ public class SnCloudFileReferenceObject : ModelBase, ICloudFile
|
|||||||
MimeType = proto.MimeType,
|
MimeType = proto.MimeType,
|
||||||
Hash = proto.Hash,
|
Hash = proto.Hash,
|
||||||
Size = proto.Size,
|
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,
|
Size = Size,
|
||||||
HasCompression = HasCompression,
|
HasCompression = HasCompression,
|
||||||
ContentType = MimeType ?? string.Empty,
|
ContentType = MimeType ?? string.Empty,
|
||||||
Url = string.Empty,
|
Url = Url ?? string.Empty,
|
||||||
// Convert file metadata
|
Width = Width ?? 0,
|
||||||
|
Height = Height ?? 0,
|
||||||
|
Blurhash = Blurhash ?? string.Empty,
|
||||||
FileMeta = GrpcTypeHelper.ConvertObjectToByteString(FileMeta),
|
FileMeta = GrpcTypeHelper.ConvertObjectToByteString(FileMeta),
|
||||||
// Convert user metadata
|
|
||||||
UserMeta = GrpcTypeHelper.ConvertObjectToByteString(UserMeta),
|
UserMeta = GrpcTypeHelper.ConvertObjectToByteString(UserMeta),
|
||||||
SensitiveMarks = GrpcTypeHelper.ConvertObjectToByteString(SensitiveMarks)
|
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 Guid InstanceId { get; set; }
|
||||||
public SnFediverseInstance Instance { get; set; } = null!;
|
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> FollowingRelationships { get; set; } = [];
|
||||||
[JsonIgnore] public ICollection<SnFediverseRelationship> FollowerRelationships { 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; }
|
[MaxLength(2048)] public string? BlockReason { get; set; }
|
||||||
[JsonIgnore] public ICollection<SnFediverseActor> Actors { get; set; } = [];
|
[JsonIgnore] public ICollection<SnFediverseActor> Actors { get; set; } = [];
|
||||||
[JsonIgnore] public ICollection<SnFediverseContent> Contents { get; set; } = [];
|
|
||||||
|
|
||||||
public Instant? LastFetchedAt { get; set; }
|
public Instant? LastFetchedAt { get; set; }
|
||||||
public Instant? LastActivityAt { 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,
|
Private,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum PostContentType
|
||||||
|
{
|
||||||
|
Markdown,
|
||||||
|
Html,
|
||||||
|
}
|
||||||
|
|
||||||
public enum PostPinMode
|
public enum PostPinMode
|
||||||
{
|
{
|
||||||
PublisherPage,
|
PublisherPage,
|
||||||
@@ -28,6 +34,39 @@ public enum PostPinMode
|
|||||||
ReplyPage,
|
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 class SnPost : ModelBase, IIdentifiedResource, ITimelineEvent
|
||||||
{
|
{
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
@@ -47,11 +86,13 @@ public class SnPost : ModelBase, IIdentifiedResource, ITimelineEvent
|
|||||||
// ReSharper disable once EntityFramework.ModelValidation.UnlimitedStringLength
|
// ReSharper disable once EntityFramework.ModelValidation.UnlimitedStringLength
|
||||||
public string? Content { get; set; }
|
public string? Content { get; set; }
|
||||||
|
|
||||||
|
public PostContentType ContentType { get; set; } = PostContentType.Markdown;
|
||||||
|
|
||||||
public PostType Type { get; set; }
|
public PostType Type { get; set; }
|
||||||
public PostPinMode? PinMode { get; set; }
|
public PostPinMode? PinMode { get; set; }
|
||||||
|
|
||||||
[Column(TypeName = "jsonb")]
|
[Column(TypeName = "jsonb")]
|
||||||
public Dictionary<string, object>? Meta { get; set; }
|
public Dictionary<string, object>? Metadata { get; set; }
|
||||||
|
|
||||||
[Column(TypeName = "jsonb")]
|
[Column(TypeName = "jsonb")]
|
||||||
public List<ContentSensitiveMark>? SensitiveMarks { get; set; } = [];
|
public List<ContentSensitiveMark>? SensitiveMarks { get; set; } = [];
|
||||||
@@ -59,17 +100,28 @@ public class SnPost : ModelBase, IIdentifiedResource, ITimelineEvent
|
|||||||
[Column(TypeName = "jsonb")]
|
[Column(TypeName = "jsonb")]
|
||||||
public PostEmbedView? EmbedView { get; set; }
|
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 ViewsUnique { get; set; }
|
||||||
public int ViewsTotal { get; set; }
|
public int ViewsTotal { get; set; }
|
||||||
public int Upvotes { get; set; }
|
public int Upvotes { get; set; }
|
||||||
public int Downvotes { get; set; }
|
public int Downvotes { get; set; }
|
||||||
public decimal AwardedScore { get; set; }
|
public decimal AwardedScore { get; set; }
|
||||||
|
|
||||||
[NotMapped]
|
public int RepliesCount { get; set; }
|
||||||
public Dictionary<string, int> ReactionsCount { get; set; } = new();
|
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public int RepliesCount { get; set; }
|
public Dictionary<string, int> ReactionsCount { get; set; } = new();
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public Dictionary<string, bool>? ReactionsMade { get; set; }
|
public Dictionary<string, bool>? ReactionsMade { get; set; }
|
||||||
@@ -90,8 +142,8 @@ public class SnPost : ModelBase, IIdentifiedResource, ITimelineEvent
|
|||||||
[Column(TypeName = "jsonb")]
|
[Column(TypeName = "jsonb")]
|
||||||
public List<SnCloudFileReferenceObject> Attachments { get; set; } = [];
|
public List<SnCloudFileReferenceObject> Attachments { get; set; } = [];
|
||||||
|
|
||||||
public Guid PublisherId { get; set; }
|
public Guid? PublisherId { get; set; }
|
||||||
public SnPublisher Publisher { get; set; } = null!;
|
public SnPublisher? Publisher { get; set; }
|
||||||
|
|
||||||
public List<SnPostAward> Awards { get; set; } = [];
|
public List<SnPostAward> Awards { get; set; } = [];
|
||||||
|
|
||||||
@@ -133,7 +185,7 @@ public class SnPost : ModelBase, IIdentifiedResource, ITimelineEvent
|
|||||||
RepliedGone = RepliedGone,
|
RepliedGone = RepliedGone,
|
||||||
ForwardedGone = ForwardedGone,
|
ForwardedGone = ForwardedGone,
|
||||||
PublisherId = PublisherId.ToString(),
|
PublisherId = PublisherId.ToString(),
|
||||||
Publisher = Publisher.ToProtoValue(),
|
Publisher = Publisher?.ToProtoValue(),
|
||||||
CreatedAt = Timestamp.FromDateTimeOffset(CreatedAt.ToDateTimeOffset()),
|
CreatedAt = Timestamp.FromDateTimeOffset(CreatedAt.ToDateTimeOffset()),
|
||||||
UpdatedAt = Timestamp.FromDateTimeOffset(UpdatedAt.ToDateTimeOffset()),
|
UpdatedAt = Timestamp.FromDateTimeOffset(UpdatedAt.ToDateTimeOffset()),
|
||||||
};
|
};
|
||||||
@@ -147,11 +199,13 @@ public class SnPost : ModelBase, IIdentifiedResource, ITimelineEvent
|
|||||||
if (Content != null)
|
if (Content != null)
|
||||||
proto.Content = Content;
|
proto.Content = Content;
|
||||||
|
|
||||||
|
proto.ContentType = (Proto.PostContentType)((int)ContentType + 1);
|
||||||
|
|
||||||
if (PinMode.HasValue)
|
if (PinMode.HasValue)
|
||||||
proto.PinMode = (Proto.PostPinMode)((int)PinMode.Value + 1);
|
proto.PinMode = (Proto.PostPinMode)((int)PinMode.Value + 1);
|
||||||
|
|
||||||
if (Meta != null)
|
if (Metadata != null)
|
||||||
proto.Meta = GrpcTypeHelper.ConvertObjectToByteString(Meta);
|
proto.Meta = GrpcTypeHelper.ConvertObjectToByteString(Metadata);
|
||||||
|
|
||||||
if (SensitiveMarks != null)
|
if (SensitiveMarks != null)
|
||||||
proto.SensitiveMarks = GrpcTypeHelper.ConvertObjectToByteString(SensitiveMarks);
|
proto.SensitiveMarks = GrpcTypeHelper.ConvertObjectToByteString(SensitiveMarks);
|
||||||
@@ -159,6 +213,30 @@ public class SnPost : ModelBase, IIdentifiedResource, ITimelineEvent
|
|||||||
if (EmbedView != null)
|
if (EmbedView != null)
|
||||||
proto.EmbedView = EmbedView.ToProtoValue();
|
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)
|
if (RepliedPostId.HasValue)
|
||||||
{
|
{
|
||||||
proto.RepliedPostId = RepliedPostId.Value.ToString();
|
proto.RepliedPostId = RepliedPostId.Value.ToString();
|
||||||
@@ -220,7 +298,7 @@ public class SnPost : ModelBase, IIdentifiedResource, ITimelineEvent
|
|||||||
RepliedGone = proto.RepliedGone,
|
RepliedGone = proto.RepliedGone,
|
||||||
ForwardedGone = proto.ForwardedGone,
|
ForwardedGone = proto.ForwardedGone,
|
||||||
PublisherId = Guid.Parse(proto.PublisherId),
|
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()),
|
CreatedAt = Instant.FromDateTimeOffset(proto.CreatedAt.ToDateTimeOffset()),
|
||||||
UpdatedAt = Instant.FromDateTimeOffset(proto.UpdatedAt.ToDateTimeOffset()),
|
UpdatedAt = Instant.FromDateTimeOffset(proto.UpdatedAt.ToDateTimeOffset()),
|
||||||
};
|
};
|
||||||
@@ -234,11 +312,13 @@ public class SnPost : ModelBase, IIdentifiedResource, ITimelineEvent
|
|||||||
if (!string.IsNullOrEmpty(proto.Content))
|
if (!string.IsNullOrEmpty(proto.Content))
|
||||||
post.Content = proto.Content;
|
post.Content = proto.Content;
|
||||||
|
|
||||||
|
post.ContentType = (PostContentType)((int)proto.ContentType - 1);
|
||||||
|
|
||||||
if (proto is { HasPinMode: true, PinMode: > 0 })
|
if (proto is { HasPinMode: true, PinMode: > 0 })
|
||||||
post.PinMode = (PostPinMode)(proto.PinMode - 1);
|
post.PinMode = (PostPinMode)(proto.PinMode - 1);
|
||||||
|
|
||||||
if (proto.Meta != null)
|
if (proto.Meta != null)
|
||||||
post.Meta = GrpcTypeHelper.ConvertByteStringToObject<Dictionary<string, object>>(
|
post.Metadata = GrpcTypeHelper.ConvertByteStringToObject<Dictionary<string, object>>(
|
||||||
proto.Meta
|
proto.Meta
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -250,6 +330,30 @@ public class SnPost : ModelBase, IIdentifiedResource, ITimelineEvent
|
|||||||
if (proto.EmbedView is not null)
|
if (proto.EmbedView is not null)
|
||||||
post.EmbedView = PostEmbedView.FromProtoValue(proto.EmbedView);
|
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))
|
if (!string.IsNullOrEmpty(proto.RepliedPostId))
|
||||||
{
|
{
|
||||||
post.RepliedPostId = Guid.Parse(proto.RepliedPostId);
|
post.RepliedPostId = Guid.Parse(proto.RepliedPostId);
|
||||||
@@ -487,13 +591,17 @@ public class SnPostReaction : ModelBase
|
|||||||
public PostReactionAttitude Attitude { get; set; }
|
public PostReactionAttitude Attitude { get; set; }
|
||||||
|
|
||||||
public Guid PostId { 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]
|
[MaxLength(2048)] public string? FediverseUri { get; set; }
|
||||||
public SnPost Post { get; set; } = null!;
|
|
||||||
public Guid AccountId { get; set; }
|
|
||||||
|
|
||||||
[NotMapped]
|
public Guid? ActorId { get; set; }
|
||||||
public SnAccount? Account { get; set; }
|
public SnFediverseActor? Actor { get; set; }
|
||||||
|
|
||||||
|
public bool IsLocal { get; set; } = true;
|
||||||
|
|
||||||
public PostReaction ToProtoValue()
|
public PostReaction ToProtoValue()
|
||||||
{
|
{
|
||||||
@@ -503,7 +611,10 @@ public class SnPostReaction : ModelBase
|
|||||||
Symbol = Symbol,
|
Symbol = Symbol,
|
||||||
Attitude = (Proto.PostReactionAttitude)((int)Attitude + 1),
|
Attitude = (Proto.PostReactionAttitude)((int)Attitude + 1),
|
||||||
PostId = PostId.ToString(),
|
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()),
|
CreatedAt = Timestamp.FromDateTimeOffset(CreatedAt.ToDateTimeOffset()),
|
||||||
UpdatedAt = Timestamp.FromDateTimeOffset(UpdatedAt.ToDateTimeOffset()),
|
UpdatedAt = Timestamp.FromDateTimeOffset(UpdatedAt.ToDateTimeOffset()),
|
||||||
};
|
};
|
||||||
@@ -515,7 +626,7 @@ public class SnPostReaction : ModelBase
|
|||||||
return proto;
|
return proto;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SnPostReaction FromProtoValue(Proto.PostReaction proto)
|
public static SnPostReaction FromProtoValue(PostReaction proto)
|
||||||
{
|
{
|
||||||
return new SnPostReaction
|
return new SnPostReaction
|
||||||
{
|
{
|
||||||
@@ -523,8 +634,11 @@ public class SnPostReaction : ModelBase
|
|||||||
Symbol = proto.Symbol,
|
Symbol = proto.Symbol,
|
||||||
Attitude = (PostReactionAttitude)((int)proto.Attitude - 1),
|
Attitude = (PostReactionAttitude)((int)proto.Attitude - 1),
|
||||||
PostId = Guid.Parse(proto.PostId),
|
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,
|
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()),
|
CreatedAt = Instant.FromDateTimeOffset(proto.CreatedAt.ToDateTimeOffset()),
|
||||||
UpdatedAt = Instant.FromDateTimeOffset(proto.UpdatedAt.ToDateTimeOffset()),
|
UpdatedAt = Instant.FromDateTimeOffset(proto.UpdatedAt.ToDateTimeOffset()),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -45,6 +45,15 @@ message CloudFile {
|
|||||||
|
|
||||||
// When the file was uploaded
|
// When the file was uploaded
|
||||||
google.protobuf.Timestamp uploaded_at = 11;
|
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
|
// Service for file operations
|
||||||
|
|||||||
@@ -61,8 +61,33 @@ enum PostEmbedViewRenderer {
|
|||||||
WEBVIEW = 1;
|
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
|
// Messages
|
||||||
|
|
||||||
|
message ContentMention {
|
||||||
|
optional string username = 1;
|
||||||
|
optional string url = 2;
|
||||||
|
optional string actor_uri = 3;
|
||||||
|
}
|
||||||
|
|
||||||
message PostEmbedView {
|
message PostEmbedView {
|
||||||
string uri = 1;
|
string uri = 1;
|
||||||
optional double aspect_ratio = 2;
|
optional double aspect_ratio = 2;
|
||||||
@@ -110,7 +135,16 @@ message Post {
|
|||||||
repeated CloudFile attachments = 30; // List<SnCloudFileReferenceObject>
|
repeated CloudFile attachments = 30; // List<SnCloudFileReferenceObject>
|
||||||
|
|
||||||
string publisher_id = 31;
|
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 PostAward awards = 33;
|
||||||
repeated PostReaction reactions = 34;
|
repeated PostReaction reactions = 34;
|
||||||
@@ -189,6 +223,10 @@ message PostReaction {
|
|||||||
string account_id = 5;
|
string account_id = 5;
|
||||||
optional Account account = 6; // optional full account
|
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 created_at = 7;
|
||||||
google.protobuf.Timestamp updated_at = 8;
|
google.protobuf.Timestamp updated_at = 8;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,12 @@ using DysonNetwork.Shared.Models;
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using NodaTime;
|
using NodaTime;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using DysonNetwork.Shared.Proto;
|
||||||
|
using ContentMention = DysonNetwork.Shared.Models.ContentMention;
|
||||||
|
using PostContentType = DysonNetwork.Shared.Models.PostContentType;
|
||||||
|
using PostReactionAttitude = DysonNetwork.Shared.Models.PostReactionAttitude;
|
||||||
|
using PostType = DysonNetwork.Shared.Models.PostType;
|
||||||
|
using PostVisibility = DysonNetwork.Shared.Models.PostVisibility;
|
||||||
|
|
||||||
namespace DysonNetwork.Sphere.ActivityPub;
|
namespace DysonNetwork.Sphere.ActivityPub;
|
||||||
|
|
||||||
@@ -246,14 +252,13 @@ public class ActivityPubActivityProcessor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
var actor = await GetOrCreateActorAsync(actorUri);
|
var actor = await GetOrCreateActorAsync(actorUri);
|
||||||
var instance = await GetOrCreateInstanceAsync(actorUri);
|
|
||||||
|
|
||||||
var contentUri = objectDict.GetValueOrDefault("id")?.ToString();
|
var contentUri = objectDict.GetValueOrDefault("id")?.ToString();
|
||||||
if (string.IsNullOrEmpty(contentUri))
|
if (string.IsNullOrEmpty(contentUri))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var existingContent = await db.FediverseContents
|
var existingContent = await db.Posts
|
||||||
.FirstOrDefaultAsync(c => c.Uri == contentUri);
|
.FirstOrDefaultAsync(c => c.FediverseUri == contentUri);
|
||||||
|
|
||||||
if (existingContent != null)
|
if (existingContent != null)
|
||||||
{
|
{
|
||||||
@@ -261,26 +266,28 @@ public class ActivityPubActivityProcessor(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var content = new SnFediverseContent
|
var content = new SnPost
|
||||||
{
|
{
|
||||||
Uri = contentUri,
|
FediverseUri = contentUri,
|
||||||
Type = objectType == "Article" ? FediverseContentType.Article : FediverseContentType.Note,
|
FediverseType = objectType == "Article" ? FediverseContentType.FediverseArticle : FediverseContentType.FediverseNote,
|
||||||
Title = objectDict.GetValueOrDefault("name")?.ToString(),
|
Title = objectDict.GetValueOrDefault("name")?.ToString(),
|
||||||
Summary = objectDict.GetValueOrDefault("summary")?.ToString(),
|
Description = objectDict.GetValueOrDefault("summary")?.ToString(),
|
||||||
Content = objectDict.GetValueOrDefault("content")?.ToString(),
|
Content = objectDict.GetValueOrDefault("content")?.ToString(),
|
||||||
ContentHtml = objectDict.GetValueOrDefault("contentMap")?.ToString(),
|
ContentType = objectDict.GetValueOrDefault("contentMap") != null ? PostContentType.Html : PostContentType.Markdown,
|
||||||
PublishedAt = ParseInstant(objectDict.GetValueOrDefault("published")),
|
PublishedAt = ParseInstant(objectDict.GetValueOrDefault("published")),
|
||||||
EditedAt = ParseInstant(objectDict.GetValueOrDefault("updated")),
|
EditedAt = ParseInstant(objectDict.GetValueOrDefault("updated")),
|
||||||
IsSensitive = bool.TryParse(objectDict.GetValueOrDefault("sensitive")?.ToString(), out var sensitive) && sensitive,
|
|
||||||
ActorId = actor.Id,
|
ActorId = actor.Id,
|
||||||
InstanceId = instance.Id,
|
Language = objectDict.GetValueOrDefault("language")?.ToString(),
|
||||||
Attachments = ParseAttachments(objectDict.GetValueOrDefault("attachment")),
|
|
||||||
Mentions = ParseMentions(objectDict.GetValueOrDefault("tag")),
|
Mentions = ParseMentions(objectDict.GetValueOrDefault("tag")),
|
||||||
Tags = ParseTags(objectDict.GetValueOrDefault("tag")),
|
Attachments = ParseAttachments(objectDict.GetValueOrDefault("attachment")) ?? [],
|
||||||
InReplyTo = objectDict.GetValueOrDefault("inReplyTo")?.ToString()
|
Type = objectType == "Article" ? PostType.Article : PostType.Moment,
|
||||||
|
Visibility = PostVisibility.Public,
|
||||||
|
CreatedAt = SystemClock.Instance.GetCurrentInstant(),
|
||||||
|
UpdatedAt = SystemClock.Instance.GetCurrentInstant(),
|
||||||
|
Metadata = BuildMetadataFromActivity(objectDict)
|
||||||
};
|
};
|
||||||
|
|
||||||
db.FediverseContents.Add(content);
|
db.Posts.Add(content);
|
||||||
await db.SaveChangesAsync();
|
await db.SaveChangesAsync();
|
||||||
|
|
||||||
logger.LogInformation("Created federated content: {Uri}", contentUri);
|
logger.LogInformation("Created federated content: {Uri}", contentUri);
|
||||||
@@ -294,8 +301,8 @@ public class ActivityPubActivityProcessor(
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
var actor = await GetOrCreateActorAsync(actorUri);
|
var actor = await GetOrCreateActorAsync(actorUri);
|
||||||
var content = await db.FediverseContents
|
var content = await db.Posts
|
||||||
.FirstOrDefaultAsync(c => c.Uri == objectUri);
|
.FirstOrDefaultAsync(c => c.FediverseUri == objectUri);
|
||||||
|
|
||||||
if (content == null)
|
if (content == null)
|
||||||
{
|
{
|
||||||
@@ -303,11 +310,11 @@ public class ActivityPubActivityProcessor(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var existingReaction = await db.FediverseReactions
|
var existingReaction = await db.PostReactions
|
||||||
.FirstOrDefaultAsync(r =>
|
.FirstOrDefaultAsync(r =>
|
||||||
r.ActorId == actor.Id &&
|
r.ActorId == actor.Id &&
|
||||||
r.ContentId == content.Id &&
|
r.PostId == content.Id &&
|
||||||
r.Type == FediverseReactionType.Like);
|
r.Symbol == "❤️");
|
||||||
|
|
||||||
if (existingReaction != null)
|
if (existingReaction != null)
|
||||||
{
|
{
|
||||||
@@ -315,16 +322,20 @@ public class ActivityPubActivityProcessor(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var reaction = new SnFediverseReaction
|
var reaction = new SnPostReaction
|
||||||
{
|
{
|
||||||
Uri = activity.GetValueOrDefault("id")?.ToString() ?? Guid.NewGuid().ToString(),
|
FediverseUri = activity.GetValueOrDefault("id")?.ToString() ?? Guid.NewGuid().ToString(),
|
||||||
Type = FediverseReactionType.Like,
|
Symbol = "❤️",
|
||||||
|
Attitude = PostReactionAttitude.Positive,
|
||||||
IsLocal = false,
|
IsLocal = false,
|
||||||
ContentId = content.Id,
|
PostId = content.Id,
|
||||||
ActorId = actor.Id
|
ActorId = actor.Id,
|
||||||
|
Actor = actor,
|
||||||
|
CreatedAt = SystemClock.Instance.GetCurrentInstant(),
|
||||||
|
UpdatedAt = SystemClock.Instance.GetCurrentInstant()
|
||||||
};
|
};
|
||||||
|
|
||||||
db.FediverseReactions.Add(reaction);
|
db.PostReactions.Add(reaction);
|
||||||
content.LikeCount++;
|
content.LikeCount++;
|
||||||
|
|
||||||
await db.SaveChangesAsync();
|
await db.SaveChangesAsync();
|
||||||
@@ -340,8 +351,8 @@ public class ActivityPubActivityProcessor(
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
var actor = await GetOrCreateActorAsync(actorUri);
|
var actor = await GetOrCreateActorAsync(actorUri);
|
||||||
var content = await db.FediverseContents
|
var content = await db.Posts
|
||||||
.FirstOrDefaultAsync(c => c.Uri == objectUri);
|
.FirstOrDefaultAsync(c => c.FediverseUri == objectUri);
|
||||||
|
|
||||||
if (content != null)
|
if (content != null)
|
||||||
{
|
{
|
||||||
@@ -359,8 +370,8 @@ public class ActivityPubActivityProcessor(
|
|||||||
if (string.IsNullOrEmpty(objectUri))
|
if (string.IsNullOrEmpty(objectUri))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var content = await db.FediverseContents
|
var content = await db.Posts
|
||||||
.FirstOrDefaultAsync(c => c.Uri == objectUri);
|
.FirstOrDefaultAsync(c => c.FediverseUri == objectUri);
|
||||||
|
|
||||||
if (content != null)
|
if (content != null)
|
||||||
{
|
{
|
||||||
@@ -378,8 +389,8 @@ public class ActivityPubActivityProcessor(
|
|||||||
if (string.IsNullOrEmpty(objectUri))
|
if (string.IsNullOrEmpty(objectUri))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var content = await db.FediverseContents
|
var content = await db.Posts
|
||||||
.FirstOrDefaultAsync(c => c.Uri == objectUri);
|
.FirstOrDefaultAsync(c => c.FediverseUri == objectUri);
|
||||||
|
|
||||||
if (content != null)
|
if (content != null)
|
||||||
{
|
{
|
||||||
@@ -416,18 +427,18 @@ public class ActivityPubActivityProcessor(
|
|||||||
{
|
{
|
||||||
var actor = await GetOrCreateActorAsync(actorUri);
|
var actor = await GetOrCreateActorAsync(actorUri);
|
||||||
|
|
||||||
var reactions = await db.FediverseReactions
|
var reactions = await db.PostReactions
|
||||||
.Where(r => r.ActorId == actor.Id && r.Type == FediverseReactionType.Like)
|
.Where(r => r.ActorId == actor.Id && r.Symbol == "❤️")
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
foreach (var reaction in reactions)
|
foreach (var reaction in reactions)
|
||||||
{
|
{
|
||||||
var content = await db.FediverseContents.FindAsync(reaction.ContentId);
|
var content = await db.Posts.FindAsync(reaction.PostId);
|
||||||
if (content != null)
|
if (content != null)
|
||||||
{
|
{
|
||||||
content.LikeCount--;
|
content.LikeCount--;
|
||||||
}
|
}
|
||||||
db.FediverseReactions.Remove(reaction);
|
db.PostReactions.Remove(reaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
await db.SaveChangesAsync();
|
await db.SaveChangesAsync();
|
||||||
@@ -436,8 +447,8 @@ public class ActivityPubActivityProcessor(
|
|||||||
|
|
||||||
private async Task<bool> UndoAnnounceAsync(string actorUri, string? activityId)
|
private async Task<bool> UndoAnnounceAsync(string actorUri, string? activityId)
|
||||||
{
|
{
|
||||||
var content = await db.FediverseContents
|
var content = await db.Posts
|
||||||
.FirstOrDefaultAsync(c => c.Uri == activityId);
|
.FirstOrDefaultAsync(c => c.FediverseUri == activityId);
|
||||||
|
|
||||||
if (content != null)
|
if (content != null)
|
||||||
{
|
{
|
||||||
@@ -518,32 +529,35 @@ public class ActivityPubActivityProcessor(
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ContentAttachment>? ParseAttachments(object? value)
|
private static List<SnCloudFileReferenceObject>? ParseAttachments(object? value)
|
||||||
{
|
{
|
||||||
if (value == null)
|
if (value is JsonElement { ValueKind: JsonValueKind.Array } element)
|
||||||
return null;
|
|
||||||
|
|
||||||
if (value is JsonElement element && element.ValueKind == JsonValueKind.Array)
|
|
||||||
{
|
{
|
||||||
return element.EnumerateArray()
|
return element.EnumerateArray()
|
||||||
.Select(attachment => new ContentAttachment
|
.Select(attachment => new SnCloudFileReferenceObject
|
||||||
{
|
{
|
||||||
|
Id = Guid.NewGuid().ToString(),
|
||||||
|
Name = attachment.GetProperty("name").GetString() ?? string.Empty,
|
||||||
Url = attachment.GetProperty("url").GetString(),
|
Url = attachment.GetProperty("url").GetString(),
|
||||||
MediaType = attachment.GetProperty("mediaType").GetString(),
|
MimeType = attachment.GetProperty("mediaType").GetString(),
|
||||||
Name = attachment.GetProperty("name").GetString()
|
Width = attachment.GetProperty("width").GetInt32(),
|
||||||
|
Height = attachment.GetProperty("height").GetInt32(),
|
||||||
|
Blurhash = attachment.GetProperty("blurhash").GetString(),
|
||||||
|
FileMeta = new Dictionary<string, object?>(),
|
||||||
|
UserMeta = new Dictionary<string, object?>(),
|
||||||
|
Size = 0,
|
||||||
|
CreatedAt = SystemClock.Instance.GetCurrentInstant(),
|
||||||
|
UpdatedAt = SystemClock.Instance.GetCurrentInstant()
|
||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ContentMention>? ParseMentions(object? value)
|
private static List<ContentMention>? ParseMentions(object? value)
|
||||||
{
|
{
|
||||||
if (value == null)
|
if (value is JsonElement { ValueKind: JsonValueKind.Array } element)
|
||||||
return null;
|
|
||||||
|
|
||||||
if (value is JsonElement element && element.ValueKind == JsonValueKind.Array)
|
|
||||||
{
|
{
|
||||||
return element.EnumerateArray()
|
return element.EnumerateArray()
|
||||||
.Where(e => e.GetProperty("type").GetString() == "Mention")
|
.Where(e => e.GetProperty("type").GetString() == "Mention")
|
||||||
@@ -554,27 +568,46 @@ public class ActivityPubActivityProcessor(
|
|||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ContentTag>? ParseTags(object? value)
|
private static Dictionary<string, object> BuildMetadataFromActivity(Dictionary<string, object> objectDict)
|
||||||
{
|
{
|
||||||
if (value == null)
|
var metadata = new Dictionary<string, object>();
|
||||||
return null;
|
|
||||||
|
var tagsValue = objectDict.GetValueOrDefault("tag");
|
||||||
if (value is JsonElement element && element.ValueKind == JsonValueKind.Array)
|
if (tagsValue is JsonElement { ValueKind: JsonValueKind.Array } tagsElement)
|
||||||
{
|
{
|
||||||
return element.EnumerateArray()
|
var fediverseTags = tagsElement.EnumerateArray()
|
||||||
.Where(e => e.GetProperty("type").GetString() == "Hashtag")
|
.Where(e => e.GetProperty("type").GetString() == "Hashtag")
|
||||||
.Select(tag => new ContentTag
|
.Select(e => e.GetProperty("name").GetString())
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
if (fediverseTags.Count > 0)
|
||||||
|
{
|
||||||
|
metadata["fediverseTags"] = fediverseTags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var emojiValue = objectDict.GetValueOrDefault("emoji");
|
||||||
|
if (emojiValue is not JsonElement { ValueKind: JsonValueKind.Array } emojiElement) return metadata;
|
||||||
|
{
|
||||||
|
var emojis = emojiElement.EnumerateArray()
|
||||||
|
.Select(e => new
|
||||||
{
|
{
|
||||||
Name = tag.GetProperty("name").GetString(),
|
Shortcode = e.GetProperty("shortcode").GetString(),
|
||||||
Url = tag.GetProperty("href").GetString()
|
StaticUrl = e.GetProperty("static_url").GetString(),
|
||||||
|
Url = e.GetProperty("url").GetString()
|
||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
if (emojis.Count > 0)
|
||||||
|
{
|
||||||
|
metadata["fediverseEmojis"] = emojis;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return metadata;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,10 +50,7 @@ public class AppDatabase(
|
|||||||
|
|
||||||
public DbSet<SnFediverseInstance> FediverseInstances { get; set; } = null!;
|
public DbSet<SnFediverseInstance> FediverseInstances { get; set; } = null!;
|
||||||
public DbSet<SnFediverseActor> FediverseActors { get; set; } = null!;
|
public DbSet<SnFediverseActor> FediverseActors { get; set; } = null!;
|
||||||
public DbSet<SnFediverseContent> FediverseContents { get; set; } = null!;
|
|
||||||
public DbSet<SnFediverseActivity> FediverseActivities { get; set; } = null!;
|
|
||||||
public DbSet<SnFediverseRelationship> FediverseRelationships { get; set; } = null!;
|
public DbSet<SnFediverseRelationship> FediverseRelationships { get; set; } = null!;
|
||||||
public DbSet<SnFediverseReaction> FediverseReactions { get; set; } = null!;
|
|
||||||
|
|
||||||
public DbSet<WebArticle> WebArticles { get; set; } = null!;
|
public DbSet<WebArticle> WebArticles { get; set; } = null!;
|
||||||
public DbSet<WebFeed> WebFeeds { get; set; } = null!;
|
public DbSet<WebFeed> WebFeeds { get; set; } = null!;
|
||||||
@@ -155,28 +152,6 @@ public class AppDatabase(
|
|||||||
.HasForeignKey(a => a.InstanceId)
|
.HasForeignKey(a => a.InstanceId)
|
||||||
.OnDelete(DeleteBehavior.Cascade);
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
modelBuilder.Entity<SnFediverseContent>()
|
|
||||||
.HasOne(c => c.Actor)
|
|
||||||
.WithMany(a => a.Contents)
|
|
||||||
.HasForeignKey(c => c.ActorId)
|
|
||||||
.OnDelete(DeleteBehavior.Cascade);
|
|
||||||
modelBuilder.Entity<SnFediverseContent>()
|
|
||||||
.HasOne(c => c.Instance)
|
|
||||||
.WithMany(i => i.Contents)
|
|
||||||
.HasForeignKey(c => c.InstanceId)
|
|
||||||
.OnDelete(DeleteBehavior.Cascade);
|
|
||||||
|
|
||||||
modelBuilder.Entity<SnFediverseActivity>()
|
|
||||||
.HasOne(a => a.Actor)
|
|
||||||
.WithMany(actor => actor.Activities)
|
|
||||||
.HasForeignKey(a => a.ActorId)
|
|
||||||
.OnDelete(DeleteBehavior.Cascade);
|
|
||||||
modelBuilder.Entity<SnFediverseActivity>()
|
|
||||||
.HasOne(a => a.Content)
|
|
||||||
.WithMany(c => c.Activities)
|
|
||||||
.HasForeignKey(a => a.ContentId)
|
|
||||||
.OnDelete(DeleteBehavior.Cascade);
|
|
||||||
|
|
||||||
modelBuilder.Entity<SnFediverseRelationship>()
|
modelBuilder.Entity<SnFediverseRelationship>()
|
||||||
.HasOne(r => r.Actor)
|
.HasOne(r => r.Actor)
|
||||||
.WithMany(a => a.FollowingRelationships)
|
.WithMany(a => a.FollowingRelationships)
|
||||||
@@ -188,17 +163,6 @@ public class AppDatabase(
|
|||||||
.HasForeignKey(r => r.TargetActorId)
|
.HasForeignKey(r => r.TargetActorId)
|
||||||
.OnDelete(DeleteBehavior.Cascade);
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
modelBuilder.Entity<SnFediverseReaction>()
|
|
||||||
.HasOne(r => r.Content)
|
|
||||||
.WithMany(c => c.Reactions)
|
|
||||||
.HasForeignKey(r => r.ContentId)
|
|
||||||
.OnDelete(DeleteBehavior.Cascade);
|
|
||||||
modelBuilder.Entity<SnFediverseReaction>()
|
|
||||||
.HasOne(r => r.Actor)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey(r => r.ActorId)
|
|
||||||
.OnDelete(DeleteBehavior.Cascade);
|
|
||||||
|
|
||||||
modelBuilder.ApplySoftDeleteFilters();
|
modelBuilder.ApplySoftDeleteFilters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -543,9 +543,9 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("character varying(2048)")
|
.HasColumnType("character varying(2048)")
|
||||||
.HasColumnName("announced_content_uri");
|
.HasColumnName("announced_content_uri");
|
||||||
|
|
||||||
b.Property<List<ContentAttachment>>("Attachments")
|
// b.Property<List<ContentAttachment>>("Attachments")
|
||||||
.HasColumnType("jsonb")
|
// .HasColumnType("jsonb")
|
||||||
.HasColumnName("attachments");
|
// .HasColumnName("attachments");
|
||||||
|
|
||||||
b.Property<int>("BoostCount")
|
b.Property<int>("BoostCount")
|
||||||
.HasColumnType("integer")
|
.HasColumnType("integer")
|
||||||
@@ -571,9 +571,9 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("timestamp with time zone")
|
.HasColumnType("timestamp with time zone")
|
||||||
.HasColumnName("edited_at");
|
.HasColumnName("edited_at");
|
||||||
|
|
||||||
b.Property<List<ContentEmoji>>("Emojis")
|
// b.Property<List<ContentEmoji>>("Emojis")
|
||||||
.HasColumnType("jsonb")
|
// .HasColumnType("jsonb")
|
||||||
.HasColumnName("emojis");
|
// .HasColumnName("emojis");
|
||||||
|
|
||||||
b.Property<string>("InReplyTo")
|
b.Property<string>("InReplyTo")
|
||||||
.HasMaxLength(2048)
|
.HasMaxLength(2048)
|
||||||
@@ -601,9 +601,9 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("local_post_id");
|
.HasColumnName("local_post_id");
|
||||||
|
|
||||||
b.Property<List<ContentMention>>("Mentions")
|
// b.Property<List<ContentMention>>("Mentions")
|
||||||
.HasColumnType("jsonb")
|
// .HasColumnType("jsonb")
|
||||||
.HasColumnName("mentions");
|
// .HasColumnName("mentions");
|
||||||
|
|
||||||
b.Property<Dictionary<string, object>>("Metadata")
|
b.Property<Dictionary<string, object>>("Metadata")
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
@@ -622,9 +622,9 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("character varying(4096)")
|
.HasColumnType("character varying(4096)")
|
||||||
.HasColumnName("summary");
|
.HasColumnName("summary");
|
||||||
|
|
||||||
b.Property<List<ContentTag>>("Tags")
|
// b.Property<List<ContentTag>>("Tags")
|
||||||
.HasColumnType("jsonb")
|
// .HasColumnType("jsonb")
|
||||||
.HasColumnName("tags");
|
// .HasColumnName("tags");
|
||||||
|
|
||||||
b.Property<string>("Title")
|
b.Property<string>("Title")
|
||||||
.HasMaxLength(1024)
|
.HasMaxLength(1024)
|
||||||
|
|||||||
@@ -102,10 +102,10 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
published_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
published_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||||
edited_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
edited_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||||
is_sensitive = table.Column<bool>(type: "boolean", nullable: false),
|
is_sensitive = table.Column<bool>(type: "boolean", nullable: false),
|
||||||
attachments = table.Column<List<ContentAttachment>>(type: "jsonb", nullable: true),
|
// attachments = table.Column<List<ContentAttachment>>(type: "jsonb", nullable: true),
|
||||||
mentions = table.Column<List<ContentMention>>(type: "jsonb", nullable: true),
|
// mentions = table.Column<List<ContentMention>>(type: "jsonb", nullable: true),
|
||||||
tags = table.Column<List<ContentTag>>(type: "jsonb", nullable: true),
|
// tags = table.Column<List<ContentTag>>(type: "jsonb", nullable: true),
|
||||||
emojis = table.Column<List<ContentEmoji>>(type: "jsonb", nullable: true),
|
// emojis = table.Column<List<ContentEmoji>>(type: "jsonb", nullable: true),
|
||||||
metadata = table.Column<Dictionary<string, object>>(type: "jsonb", nullable: true),
|
metadata = table.Column<Dictionary<string, object>>(type: "jsonb", nullable: true),
|
||||||
actor_id = table.Column<Guid>(type: "uuid", nullable: false),
|
actor_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
instance_id = table.Column<Guid>(type: "uuid", nullable: false),
|
instance_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
|||||||
@@ -549,9 +549,9 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("character varying(2048)")
|
.HasColumnType("character varying(2048)")
|
||||||
.HasColumnName("announced_content_uri");
|
.HasColumnName("announced_content_uri");
|
||||||
|
|
||||||
b.Property<List<ContentAttachment>>("Attachments")
|
// b.Property<List<ContentAttachment>>("Attachments")
|
||||||
.HasColumnType("jsonb")
|
// .HasColumnType("jsonb")
|
||||||
.HasColumnName("attachments");
|
// .HasColumnName("attachments");
|
||||||
|
|
||||||
b.Property<int>("BoostCount")
|
b.Property<int>("BoostCount")
|
||||||
.HasColumnType("integer")
|
.HasColumnType("integer")
|
||||||
@@ -577,9 +577,9 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("timestamp with time zone")
|
.HasColumnType("timestamp with time zone")
|
||||||
.HasColumnName("edited_at");
|
.HasColumnName("edited_at");
|
||||||
|
|
||||||
b.Property<List<ContentEmoji>>("Emojis")
|
// b.Property<List<ContentEmoji>>("Emojis")
|
||||||
.HasColumnType("jsonb")
|
// .HasColumnType("jsonb")
|
||||||
.HasColumnName("emojis");
|
// .HasColumnName("emojis");
|
||||||
|
|
||||||
b.Property<string>("InReplyTo")
|
b.Property<string>("InReplyTo")
|
||||||
.HasMaxLength(2048)
|
.HasMaxLength(2048)
|
||||||
@@ -607,9 +607,9 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("local_post_id");
|
.HasColumnName("local_post_id");
|
||||||
|
|
||||||
b.Property<List<ContentMention>>("Mentions")
|
// b.Property<List<ContentMention>>("Mentions")
|
||||||
.HasColumnType("jsonb")
|
// .HasColumnType("jsonb")
|
||||||
.HasColumnName("mentions");
|
// .HasColumnName("mentions");
|
||||||
|
|
||||||
b.Property<Dictionary<string, object>>("Metadata")
|
b.Property<Dictionary<string, object>>("Metadata")
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
@@ -628,9 +628,9 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("character varying(4096)")
|
.HasColumnType("character varying(4096)")
|
||||||
.HasColumnName("summary");
|
.HasColumnName("summary");
|
||||||
|
|
||||||
b.Property<List<ContentTag>>("Tags")
|
// b.Property<List<ContentTag>>("Tags")
|
||||||
.HasColumnType("jsonb")
|
// .HasColumnType("jsonb")
|
||||||
.HasColumnName("tags");
|
// .HasColumnName("tags");
|
||||||
|
|
||||||
b.Property<string>("Title")
|
b.Property<string>("Title")
|
||||||
.HasMaxLength(1024)
|
.HasMaxLength(1024)
|
||||||
|
|||||||
@@ -549,9 +549,9 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("character varying(2048)")
|
.HasColumnType("character varying(2048)")
|
||||||
.HasColumnName("announced_content_uri");
|
.HasColumnName("announced_content_uri");
|
||||||
|
|
||||||
b.Property<List<ContentAttachment>>("Attachments")
|
// b.Property<List<ContentAttachment>>("Attachments")
|
||||||
.HasColumnType("jsonb")
|
// .HasColumnType("jsonb")
|
||||||
.HasColumnName("attachments");
|
// .HasColumnName("attachments");
|
||||||
|
|
||||||
b.Property<int>("BoostCount")
|
b.Property<int>("BoostCount")
|
||||||
.HasColumnType("integer")
|
.HasColumnType("integer")
|
||||||
@@ -577,9 +577,9 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("timestamp with time zone")
|
.HasColumnType("timestamp with time zone")
|
||||||
.HasColumnName("edited_at");
|
.HasColumnName("edited_at");
|
||||||
|
|
||||||
b.Property<List<ContentEmoji>>("Emojis")
|
// b.Property<List<ContentEmoji>>("Emojis")
|
||||||
.HasColumnType("jsonb")
|
// .HasColumnType("jsonb")
|
||||||
.HasColumnName("emojis");
|
// .HasColumnName("emojis");
|
||||||
|
|
||||||
b.Property<string>("InReplyTo")
|
b.Property<string>("InReplyTo")
|
||||||
.HasMaxLength(2048)
|
.HasMaxLength(2048)
|
||||||
@@ -607,9 +607,9 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("local_post_id");
|
.HasColumnName("local_post_id");
|
||||||
|
|
||||||
b.Property<List<ContentMention>>("Mentions")
|
// b.Property<List<ContentMention>>("Mentions")
|
||||||
.HasColumnType("jsonb")
|
// .HasColumnType("jsonb")
|
||||||
.HasColumnName("mentions");
|
// .HasColumnName("mentions");
|
||||||
|
|
||||||
b.Property<Dictionary<string, object>>("Metadata")
|
b.Property<Dictionary<string, object>>("Metadata")
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
@@ -628,9 +628,9 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("character varying(4096)")
|
.HasColumnType("character varying(4096)")
|
||||||
.HasColumnName("summary");
|
.HasColumnName("summary");
|
||||||
|
|
||||||
b.Property<List<ContentTag>>("Tags")
|
// b.Property<List<ContentTag>>("Tags")
|
||||||
.HasColumnType("jsonb")
|
// .HasColumnType("jsonb")
|
||||||
.HasColumnName("tags");
|
// .HasColumnName("tags");
|
||||||
|
|
||||||
b.Property<string>("Title")
|
b.Property<string>("Title")
|
||||||
.HasMaxLength(1024)
|
.HasMaxLength(1024)
|
||||||
|
|||||||
@@ -553,9 +553,9 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("character varying(2048)")
|
.HasColumnType("character varying(2048)")
|
||||||
.HasColumnName("announced_content_uri");
|
.HasColumnName("announced_content_uri");
|
||||||
|
|
||||||
b.Property<List<ContentAttachment>>("Attachments")
|
// b.Property<List<ContentAttachment>>("Attachments")
|
||||||
.HasColumnType("jsonb")
|
// .HasColumnType("jsonb")
|
||||||
.HasColumnName("attachments");
|
// .HasColumnName("attachments");
|
||||||
|
|
||||||
b.Property<int>("BoostCount")
|
b.Property<int>("BoostCount")
|
||||||
.HasColumnType("integer")
|
.HasColumnType("integer")
|
||||||
@@ -581,9 +581,9 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("timestamp with time zone")
|
.HasColumnType("timestamp with time zone")
|
||||||
.HasColumnName("edited_at");
|
.HasColumnName("edited_at");
|
||||||
|
|
||||||
b.Property<List<ContentEmoji>>("Emojis")
|
// b.Property<List<ContentEmoji>>("Emojis")
|
||||||
.HasColumnType("jsonb")
|
// .HasColumnType("jsonb")
|
||||||
.HasColumnName("emojis");
|
// .HasColumnName("emojis");
|
||||||
|
|
||||||
b.Property<string>("InReplyTo")
|
b.Property<string>("InReplyTo")
|
||||||
.HasMaxLength(2048)
|
.HasMaxLength(2048)
|
||||||
@@ -611,9 +611,9 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("local_post_id");
|
.HasColumnName("local_post_id");
|
||||||
|
|
||||||
b.Property<List<ContentMention>>("Mentions")
|
// b.Property<List<ContentMention>>("Mentions")
|
||||||
.HasColumnType("jsonb")
|
// .HasColumnType("jsonb")
|
||||||
.HasColumnName("mentions");
|
// .HasColumnName("mentions");
|
||||||
|
|
||||||
b.Property<Dictionary<string, object>>("Metadata")
|
b.Property<Dictionary<string, object>>("Metadata")
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
@@ -632,9 +632,9 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("character varying(4096)")
|
.HasColumnType("character varying(4096)")
|
||||||
.HasColumnName("summary");
|
.HasColumnName("summary");
|
||||||
|
|
||||||
b.Property<List<ContentTag>>("Tags")
|
// b.Property<List<ContentTag>>("Tags")
|
||||||
.HasColumnType("jsonb")
|
// .HasColumnType("jsonb")
|
||||||
.HasColumnName("tags");
|
// .HasColumnName("tags");
|
||||||
|
|
||||||
b.Property<string>("Title")
|
b.Property<string>("Title")
|
||||||
.HasMaxLength(1024)
|
.HasMaxLength(1024)
|
||||||
|
|||||||
@@ -553,9 +553,9 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("character varying(2048)")
|
.HasColumnType("character varying(2048)")
|
||||||
.HasColumnName("announced_content_uri");
|
.HasColumnName("announced_content_uri");
|
||||||
|
|
||||||
b.Property<List<ContentAttachment>>("Attachments")
|
// b.Property<List<ContentAttachment>>("Attachments")
|
||||||
.HasColumnType("jsonb")
|
// .HasColumnType("jsonb")
|
||||||
.HasColumnName("attachments");
|
// .HasColumnName("attachments");
|
||||||
|
|
||||||
b.Property<int>("BoostCount")
|
b.Property<int>("BoostCount")
|
||||||
.HasColumnType("integer")
|
.HasColumnType("integer")
|
||||||
@@ -581,9 +581,9 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("timestamp with time zone")
|
.HasColumnType("timestamp with time zone")
|
||||||
.HasColumnName("edited_at");
|
.HasColumnName("edited_at");
|
||||||
|
|
||||||
b.Property<List<ContentEmoji>>("Emojis")
|
// b.Property<List<ContentEmoji>>("Emojis")
|
||||||
.HasColumnType("jsonb")
|
// .HasColumnType("jsonb")
|
||||||
.HasColumnName("emojis");
|
// .HasColumnName("emojis");
|
||||||
|
|
||||||
b.Property<string>("InReplyTo")
|
b.Property<string>("InReplyTo")
|
||||||
.HasMaxLength(2048)
|
.HasMaxLength(2048)
|
||||||
@@ -611,9 +611,9 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("local_post_id");
|
.HasColumnName("local_post_id");
|
||||||
|
|
||||||
b.Property<List<ContentMention>>("Mentions")
|
// b.Property<List<ContentMention>>("Mentions")
|
||||||
.HasColumnType("jsonb")
|
// .HasColumnType("jsonb")
|
||||||
.HasColumnName("mentions");
|
// .HasColumnName("mentions");
|
||||||
|
|
||||||
b.Property<Dictionary<string, object>>("Metadata")
|
b.Property<Dictionary<string, object>>("Metadata")
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
@@ -632,9 +632,9 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("character varying(4096)")
|
.HasColumnType("character varying(4096)")
|
||||||
.HasColumnName("summary");
|
.HasColumnName("summary");
|
||||||
|
|
||||||
b.Property<List<ContentTag>>("Tags")
|
// b.Property<List<ContentTag>>("Tags")
|
||||||
.HasColumnType("jsonb")
|
// .HasColumnType("jsonb")
|
||||||
.HasColumnName("tags");
|
// .HasColumnName("tags");
|
||||||
|
|
||||||
b.Property<string>("Title")
|
b.Property<string>("Title")
|
||||||
.HasMaxLength(1024)
|
.HasMaxLength(1024)
|
||||||
|
|||||||
2385
DysonNetwork.Sphere/Migrations/20251230153545_MergeFediverseDataClass.Designer.cs
generated
Normal file
2385
DysonNetwork.Sphere/Migrations/20251230153545_MergeFediverseDataClass.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,433 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using DysonNetwork.Shared.Models;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using NodaTime;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace DysonNetwork.Sphere.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class MergeFediverseDataClass : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "fk_posts_publishers_publisher_id",
|
||||||
|
table: "posts");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "fediverse_activities");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "fediverse_reactions");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "fediverse_contents");
|
||||||
|
|
||||||
|
migrationBuilder.RenameColumn(
|
||||||
|
name: "meta",
|
||||||
|
table: "posts",
|
||||||
|
newName: "metadata");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<Guid>(
|
||||||
|
name: "publisher_id",
|
||||||
|
table: "posts",
|
||||||
|
type: "uuid",
|
||||||
|
nullable: true,
|
||||||
|
oldClrType: typeof(Guid),
|
||||||
|
oldType: "uuid");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<Guid>(
|
||||||
|
name: "actor_id",
|
||||||
|
table: "posts",
|
||||||
|
type: "uuid",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "boost_count",
|
||||||
|
table: "posts",
|
||||||
|
type: "integer",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "content_type",
|
||||||
|
table: "posts",
|
||||||
|
type: "integer",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "fediverse_type",
|
||||||
|
table: "posts",
|
||||||
|
type: "integer",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "fediverse_uri",
|
||||||
|
table: "posts",
|
||||||
|
type: "character varying(8192)",
|
||||||
|
maxLength: 8192,
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "language",
|
||||||
|
table: "posts",
|
||||||
|
type: "character varying(2048)",
|
||||||
|
maxLength: 2048,
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "like_count",
|
||||||
|
table: "posts",
|
||||||
|
type: "integer",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<List<ContentMention>>(
|
||||||
|
name: "mentions",
|
||||||
|
table: "posts",
|
||||||
|
type: "jsonb",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "replies_count",
|
||||||
|
table: "posts",
|
||||||
|
type: "integer",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0);
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<Guid>(
|
||||||
|
name: "account_id",
|
||||||
|
table: "post_reactions",
|
||||||
|
type: "uuid",
|
||||||
|
nullable: true,
|
||||||
|
oldClrType: typeof(Guid),
|
||||||
|
oldType: "uuid");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<Guid>(
|
||||||
|
name: "actor_id",
|
||||||
|
table: "post_reactions",
|
||||||
|
type: "uuid",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "fediverse_uri",
|
||||||
|
table: "post_reactions",
|
||||||
|
type: "character varying(2048)",
|
||||||
|
maxLength: 2048,
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
name: "is_local",
|
||||||
|
table: "post_reactions",
|
||||||
|
type: "boolean",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_posts_actor_id",
|
||||||
|
table: "posts",
|
||||||
|
column: "actor_id");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_post_reactions_actor_id",
|
||||||
|
table: "post_reactions",
|
||||||
|
column: "actor_id");
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "fk_post_reactions_fediverse_actors_actor_id",
|
||||||
|
table: "post_reactions",
|
||||||
|
column: "actor_id",
|
||||||
|
principalTable: "fediverse_actors",
|
||||||
|
principalColumn: "id");
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "fk_posts_fediverse_actors_actor_id",
|
||||||
|
table: "posts",
|
||||||
|
column: "actor_id",
|
||||||
|
principalTable: "fediverse_actors",
|
||||||
|
principalColumn: "id");
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "fk_posts_publishers_publisher_id",
|
||||||
|
table: "posts",
|
||||||
|
column: "publisher_id",
|
||||||
|
principalTable: "publishers",
|
||||||
|
principalColumn: "id");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "fk_post_reactions_fediverse_actors_actor_id",
|
||||||
|
table: "post_reactions");
|
||||||
|
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "fk_posts_fediverse_actors_actor_id",
|
||||||
|
table: "posts");
|
||||||
|
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "fk_posts_publishers_publisher_id",
|
||||||
|
table: "posts");
|
||||||
|
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "ix_posts_actor_id",
|
||||||
|
table: "posts");
|
||||||
|
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "ix_post_reactions_actor_id",
|
||||||
|
table: "post_reactions");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "actor_id",
|
||||||
|
table: "posts");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "boost_count",
|
||||||
|
table: "posts");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "content_type",
|
||||||
|
table: "posts");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "fediverse_type",
|
||||||
|
table: "posts");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "fediverse_uri",
|
||||||
|
table: "posts");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "language",
|
||||||
|
table: "posts");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "like_count",
|
||||||
|
table: "posts");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "mentions",
|
||||||
|
table: "posts");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "replies_count",
|
||||||
|
table: "posts");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "actor_id",
|
||||||
|
table: "post_reactions");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "fediverse_uri",
|
||||||
|
table: "post_reactions");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "is_local",
|
||||||
|
table: "post_reactions");
|
||||||
|
|
||||||
|
migrationBuilder.RenameColumn(
|
||||||
|
name: "metadata",
|
||||||
|
table: "posts",
|
||||||
|
newName: "meta");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<Guid>(
|
||||||
|
name: "publisher_id",
|
||||||
|
table: "posts",
|
||||||
|
type: "uuid",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"),
|
||||||
|
oldClrType: typeof(Guid),
|
||||||
|
oldType: "uuid",
|
||||||
|
oldNullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<Guid>(
|
||||||
|
name: "account_id",
|
||||||
|
table: "post_reactions",
|
||||||
|
type: "uuid",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"),
|
||||||
|
oldClrType: typeof(Guid),
|
||||||
|
oldType: "uuid",
|
||||||
|
oldNullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "fediverse_contents",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
actor_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
instance_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
announced_content_uri = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
||||||
|
boost_count = table.Column<int>(type: "integer", nullable: false),
|
||||||
|
content = table.Column<string>(type: "text", nullable: true),
|
||||||
|
content_html = table.Column<string>(type: "text", nullable: true),
|
||||||
|
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||||
|
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||||
|
edited_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||||
|
in_reply_to = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
||||||
|
is_sensitive = table.Column<bool>(type: "boolean", nullable: false),
|
||||||
|
language = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
||||||
|
like_count = table.Column<int>(type: "integer", nullable: false),
|
||||||
|
local_post_id = table.Column<Guid>(type: "uuid", nullable: true),
|
||||||
|
metadata = table.Column<Dictionary<string, object>>(type: "jsonb", nullable: true),
|
||||||
|
published_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||||
|
reply_count = table.Column<int>(type: "integer", nullable: false),
|
||||||
|
summary = table.Column<string>(type: "character varying(4096)", maxLength: 4096, nullable: true),
|
||||||
|
title = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: true),
|
||||||
|
type = table.Column<int>(type: "integer", nullable: false),
|
||||||
|
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||||
|
uri = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_fediverse_contents", x => x.id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_fediverse_contents_fediverse_actors_actor_id",
|
||||||
|
column: x => x.actor_id,
|
||||||
|
principalTable: "fediverse_actors",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_fediverse_contents_fediverse_instances_instance_id",
|
||||||
|
column: x => x.instance_id,
|
||||||
|
principalTable: "fediverse_instances",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "fediverse_activities",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
actor_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
content_id = table.Column<Guid>(type: "uuid", nullable: true),
|
||||||
|
target_actor_id = table.Column<Guid>(type: "uuid", nullable: true),
|
||||||
|
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||||
|
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||||
|
error_message = table.Column<string>(type: "character varying(4096)", maxLength: 4096, nullable: true),
|
||||||
|
is_local = table.Column<bool>(type: "boolean", nullable: false),
|
||||||
|
local_account_id = table.Column<Guid>(type: "uuid", nullable: true),
|
||||||
|
local_post_id = table.Column<Guid>(type: "uuid", nullable: true),
|
||||||
|
object_uri = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
||||||
|
published_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||||
|
raw_data = table.Column<Dictionary<string, object>>(type: "jsonb", nullable: true),
|
||||||
|
status = table.Column<int>(type: "integer", nullable: false),
|
||||||
|
target_uri = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
||||||
|
type = table.Column<int>(type: "integer", nullable: false),
|
||||||
|
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||||
|
uri = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_fediverse_activities", x => x.id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_fediverse_activities_fediverse_actors_actor_id",
|
||||||
|
column: x => x.actor_id,
|
||||||
|
principalTable: "fediverse_actors",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_fediverse_activities_fediverse_actors_target_actor_id",
|
||||||
|
column: x => x.target_actor_id,
|
||||||
|
principalTable: "fediverse_actors",
|
||||||
|
principalColumn: "id");
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_fediverse_activities_fediverse_contents_content_id",
|
||||||
|
column: x => x.content_id,
|
||||||
|
principalTable: "fediverse_contents",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "fediverse_reactions",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
actor_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
content_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||||
|
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||||
|
emoji = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
||||||
|
is_local = table.Column<bool>(type: "boolean", nullable: false),
|
||||||
|
local_account_id = table.Column<Guid>(type: "uuid", nullable: true),
|
||||||
|
local_reaction_id = table.Column<Guid>(type: "uuid", nullable: true),
|
||||||
|
type = table.Column<int>(type: "integer", nullable: false),
|
||||||
|
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||||
|
uri = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_fediverse_reactions", x => x.id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_fediverse_reactions_fediverse_actors_actor_id",
|
||||||
|
column: x => x.actor_id,
|
||||||
|
principalTable: "fediverse_actors",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_fediverse_reactions_fediverse_contents_content_id",
|
||||||
|
column: x => x.content_id,
|
||||||
|
principalTable: "fediverse_contents",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_fediverse_activities_actor_id",
|
||||||
|
table: "fediverse_activities",
|
||||||
|
column: "actor_id");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_fediverse_activities_content_id",
|
||||||
|
table: "fediverse_activities",
|
||||||
|
column: "content_id");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_fediverse_activities_target_actor_id",
|
||||||
|
table: "fediverse_activities",
|
||||||
|
column: "target_actor_id");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_fediverse_contents_actor_id",
|
||||||
|
table: "fediverse_contents",
|
||||||
|
column: "actor_id");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_fediverse_contents_instance_id",
|
||||||
|
table: "fediverse_contents",
|
||||||
|
column: "instance_id");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_fediverse_contents_uri",
|
||||||
|
table: "fediverse_contents",
|
||||||
|
column: "uri",
|
||||||
|
unique: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_fediverse_reactions_actor_id",
|
||||||
|
table: "fediverse_reactions",
|
||||||
|
column: "actor_id");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_fediverse_reactions_content_id",
|
||||||
|
table: "fediverse_reactions",
|
||||||
|
column: "content_id");
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "fk_posts_publishers_publisher_id",
|
||||||
|
table: "posts",
|
||||||
|
column: "publisher_id",
|
||||||
|
principalTable: "publishers",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -302,101 +302,6 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
b.ToTable("chat_rooms", (string)null);
|
b.ToTable("chat_rooms", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnFediverseActivity", b =>
|
|
||||||
{
|
|
||||||
b.Property<Guid>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("id");
|
|
||||||
|
|
||||||
b.Property<Guid>("ActorId")
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("actor_id");
|
|
||||||
|
|
||||||
b.Property<Guid?>("ContentId")
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("content_id");
|
|
||||||
|
|
||||||
b.Property<Instant>("CreatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("created_at");
|
|
||||||
|
|
||||||
b.Property<Instant?>("DeletedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("deleted_at");
|
|
||||||
|
|
||||||
b.Property<string>("ErrorMessage")
|
|
||||||
.HasMaxLength(4096)
|
|
||||||
.HasColumnType("character varying(4096)")
|
|
||||||
.HasColumnName("error_message");
|
|
||||||
|
|
||||||
b.Property<bool>("IsLocal")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("is_local");
|
|
||||||
|
|
||||||
b.Property<Guid?>("LocalAccountId")
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("local_account_id");
|
|
||||||
|
|
||||||
b.Property<Guid?>("LocalPostId")
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("local_post_id");
|
|
||||||
|
|
||||||
b.Property<string>("ObjectUri")
|
|
||||||
.HasMaxLength(2048)
|
|
||||||
.HasColumnType("character varying(2048)")
|
|
||||||
.HasColumnName("object_uri");
|
|
||||||
|
|
||||||
b.Property<Instant?>("PublishedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("published_at");
|
|
||||||
|
|
||||||
b.Property<Dictionary<string, object>>("RawData")
|
|
||||||
.HasColumnType("jsonb")
|
|
||||||
.HasColumnName("raw_data");
|
|
||||||
|
|
||||||
b.Property<int>("Status")
|
|
||||||
.HasColumnType("integer")
|
|
||||||
.HasColumnName("status");
|
|
||||||
|
|
||||||
b.Property<Guid?>("TargetActorId")
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("target_actor_id");
|
|
||||||
|
|
||||||
b.Property<string>("TargetUri")
|
|
||||||
.HasMaxLength(2048)
|
|
||||||
.HasColumnType("character varying(2048)")
|
|
||||||
.HasColumnName("target_uri");
|
|
||||||
|
|
||||||
b.Property<int>("Type")
|
|
||||||
.HasColumnType("integer")
|
|
||||||
.HasColumnName("type");
|
|
||||||
|
|
||||||
b.Property<Instant>("UpdatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("updated_at");
|
|
||||||
|
|
||||||
b.Property<string>("Uri")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(2048)
|
|
||||||
.HasColumnType("character varying(2048)")
|
|
||||||
.HasColumnName("uri");
|
|
||||||
|
|
||||||
b.HasKey("Id")
|
|
||||||
.HasName("pk_fediverse_activities");
|
|
||||||
|
|
||||||
b.HasIndex("ActorId")
|
|
||||||
.HasDatabaseName("ix_fediverse_activities_actor_id");
|
|
||||||
|
|
||||||
b.HasIndex("ContentId")
|
|
||||||
.HasDatabaseName("ix_fediverse_activities_content_id");
|
|
||||||
|
|
||||||
b.HasIndex("TargetActorId")
|
|
||||||
.HasDatabaseName("ix_fediverse_activities_target_actor_id");
|
|
||||||
|
|
||||||
b.ToTable("fediverse_activities", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnFediverseActor", b =>
|
modelBuilder.Entity("DysonNetwork.Shared.Models.SnFediverseActor", b =>
|
||||||
{
|
{
|
||||||
b.Property<Guid>("Id")
|
b.Property<Guid>("Id")
|
||||||
@@ -534,140 +439,6 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
b.ToTable("fediverse_actors", (string)null);
|
b.ToTable("fediverse_actors", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnFediverseContent", b =>
|
|
||||||
{
|
|
||||||
b.Property<Guid>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("id");
|
|
||||||
|
|
||||||
b.Property<Guid>("ActorId")
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("actor_id");
|
|
||||||
|
|
||||||
b.Property<string>("AnnouncedContentUri")
|
|
||||||
.HasMaxLength(2048)
|
|
||||||
.HasColumnType("character varying(2048)")
|
|
||||||
.HasColumnName("announced_content_uri");
|
|
||||||
|
|
||||||
b.Property<List<ContentAttachment>>("Attachments")
|
|
||||||
.HasColumnType("jsonb")
|
|
||||||
.HasColumnName("attachments");
|
|
||||||
|
|
||||||
b.Property<int>("BoostCount")
|
|
||||||
.HasColumnType("integer")
|
|
||||||
.HasColumnName("boost_count");
|
|
||||||
|
|
||||||
b.Property<string>("Content")
|
|
||||||
.HasColumnType("text")
|
|
||||||
.HasColumnName("content");
|
|
||||||
|
|
||||||
b.Property<string>("ContentHtml")
|
|
||||||
.HasColumnType("text")
|
|
||||||
.HasColumnName("content_html");
|
|
||||||
|
|
||||||
b.Property<Instant>("CreatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("created_at");
|
|
||||||
|
|
||||||
b.Property<Instant?>("DeletedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("deleted_at");
|
|
||||||
|
|
||||||
b.Property<Instant?>("EditedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("edited_at");
|
|
||||||
|
|
||||||
b.Property<List<ContentEmoji>>("Emojis")
|
|
||||||
.HasColumnType("jsonb")
|
|
||||||
.HasColumnName("emojis");
|
|
||||||
|
|
||||||
b.Property<string>("InReplyTo")
|
|
||||||
.HasMaxLength(2048)
|
|
||||||
.HasColumnType("character varying(2048)")
|
|
||||||
.HasColumnName("in_reply_to");
|
|
||||||
|
|
||||||
b.Property<Guid>("InstanceId")
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("instance_id");
|
|
||||||
|
|
||||||
b.Property<bool>("IsSensitive")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("is_sensitive");
|
|
||||||
|
|
||||||
b.Property<string>("Language")
|
|
||||||
.HasMaxLength(2048)
|
|
||||||
.HasColumnType("character varying(2048)")
|
|
||||||
.HasColumnName("language");
|
|
||||||
|
|
||||||
b.Property<int>("LikeCount")
|
|
||||||
.HasColumnType("integer")
|
|
||||||
.HasColumnName("like_count");
|
|
||||||
|
|
||||||
b.Property<Guid?>("LocalPostId")
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("local_post_id");
|
|
||||||
|
|
||||||
b.Property<List<ContentMention>>("Mentions")
|
|
||||||
.HasColumnType("jsonb")
|
|
||||||
.HasColumnName("mentions");
|
|
||||||
|
|
||||||
b.Property<Dictionary<string, object>>("Metadata")
|
|
||||||
.HasColumnType("jsonb")
|
|
||||||
.HasColumnName("metadata");
|
|
||||||
|
|
||||||
b.Property<Instant?>("PublishedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("published_at");
|
|
||||||
|
|
||||||
b.Property<int>("ReplyCount")
|
|
||||||
.HasColumnType("integer")
|
|
||||||
.HasColumnName("reply_count");
|
|
||||||
|
|
||||||
b.Property<string>("Summary")
|
|
||||||
.HasMaxLength(4096)
|
|
||||||
.HasColumnType("character varying(4096)")
|
|
||||||
.HasColumnName("summary");
|
|
||||||
|
|
||||||
b.Property<List<ContentTag>>("Tags")
|
|
||||||
.HasColumnType("jsonb")
|
|
||||||
.HasColumnName("tags");
|
|
||||||
|
|
||||||
b.Property<string>("Title")
|
|
||||||
.HasMaxLength(1024)
|
|
||||||
.HasColumnType("character varying(1024)")
|
|
||||||
.HasColumnName("title");
|
|
||||||
|
|
||||||
b.Property<int>("Type")
|
|
||||||
.HasColumnType("integer")
|
|
||||||
.HasColumnName("type");
|
|
||||||
|
|
||||||
b.Property<Instant>("UpdatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("updated_at");
|
|
||||||
|
|
||||||
b.Property<string>("Uri")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(2048)
|
|
||||||
.HasColumnType("character varying(2048)")
|
|
||||||
.HasColumnName("uri");
|
|
||||||
|
|
||||||
b.HasKey("Id")
|
|
||||||
.HasName("pk_fediverse_contents");
|
|
||||||
|
|
||||||
b.HasIndex("ActorId")
|
|
||||||
.HasDatabaseName("ix_fediverse_contents_actor_id");
|
|
||||||
|
|
||||||
b.HasIndex("InstanceId")
|
|
||||||
.HasDatabaseName("ix_fediverse_contents_instance_id");
|
|
||||||
|
|
||||||
b.HasIndex("Uri")
|
|
||||||
.IsUnique()
|
|
||||||
.HasDatabaseName("ix_fediverse_contents_uri");
|
|
||||||
|
|
||||||
b.ToTable("fediverse_contents", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnFediverseInstance", b =>
|
modelBuilder.Entity("DysonNetwork.Shared.Models.SnFediverseInstance", b =>
|
||||||
{
|
{
|
||||||
b.Property<Guid>("Id")
|
b.Property<Guid>("Id")
|
||||||
@@ -776,72 +547,6 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
b.ToTable("fediverse_instances", (string)null);
|
b.ToTable("fediverse_instances", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnFediverseReaction", b =>
|
|
||||||
{
|
|
||||||
b.Property<Guid>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("id");
|
|
||||||
|
|
||||||
b.Property<Guid>("ActorId")
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("actor_id");
|
|
||||||
|
|
||||||
b.Property<Guid>("ContentId")
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("content_id");
|
|
||||||
|
|
||||||
b.Property<Instant>("CreatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("created_at");
|
|
||||||
|
|
||||||
b.Property<Instant?>("DeletedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("deleted_at");
|
|
||||||
|
|
||||||
b.Property<string>("Emoji")
|
|
||||||
.HasMaxLength(64)
|
|
||||||
.HasColumnType("character varying(64)")
|
|
||||||
.HasColumnName("emoji");
|
|
||||||
|
|
||||||
b.Property<bool>("IsLocal")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("is_local");
|
|
||||||
|
|
||||||
b.Property<Guid?>("LocalAccountId")
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("local_account_id");
|
|
||||||
|
|
||||||
b.Property<Guid?>("LocalReactionId")
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("local_reaction_id");
|
|
||||||
|
|
||||||
b.Property<int>("Type")
|
|
||||||
.HasColumnType("integer")
|
|
||||||
.HasColumnName("type");
|
|
||||||
|
|
||||||
b.Property<Instant>("UpdatedAt")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("updated_at");
|
|
||||||
|
|
||||||
b.Property<string>("Uri")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(2048)
|
|
||||||
.HasColumnType("character varying(2048)")
|
|
||||||
.HasColumnName("uri");
|
|
||||||
|
|
||||||
b.HasKey("Id")
|
|
||||||
.HasName("pk_fediverse_reactions");
|
|
||||||
|
|
||||||
b.HasIndex("ActorId")
|
|
||||||
.HasDatabaseName("ix_fediverse_reactions_actor_id");
|
|
||||||
|
|
||||||
b.HasIndex("ContentId")
|
|
||||||
.HasDatabaseName("ix_fediverse_reactions_content_id");
|
|
||||||
|
|
||||||
b.ToTable("fediverse_reactions", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnFediverseRelationship", b =>
|
modelBuilder.Entity("DysonNetwork.Shared.Models.SnFediverseRelationship", b =>
|
||||||
{
|
{
|
||||||
b.Property<Guid>("Id")
|
b.Property<Guid>("Id")
|
||||||
@@ -1071,6 +776,10 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("id");
|
.HasColumnName("id");
|
||||||
|
|
||||||
|
b.Property<Guid?>("ActorId")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("actor_id");
|
||||||
|
|
||||||
b.Property<List<SnCloudFileReferenceObject>>("Attachments")
|
b.Property<List<SnCloudFileReferenceObject>>("Attachments")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
@@ -1080,10 +789,18 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("numeric")
|
.HasColumnType("numeric")
|
||||||
.HasColumnName("awarded_score");
|
.HasColumnName("awarded_score");
|
||||||
|
|
||||||
|
b.Property<int>("BoostCount")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("boost_count");
|
||||||
|
|
||||||
b.Property<string>("Content")
|
b.Property<string>("Content")
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("content");
|
.HasColumnName("content");
|
||||||
|
|
||||||
|
b.Property<int>("ContentType")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("content_type");
|
||||||
|
|
||||||
b.Property<Instant>("CreatedAt")
|
b.Property<Instant>("CreatedAt")
|
||||||
.HasColumnType("timestamp with time zone")
|
.HasColumnType("timestamp with time zone")
|
||||||
.HasColumnName("created_at");
|
.HasColumnName("created_at");
|
||||||
@@ -1109,6 +826,15 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
.HasColumnName("embed_view");
|
.HasColumnName("embed_view");
|
||||||
|
|
||||||
|
b.Property<int?>("FediverseType")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("fediverse_type");
|
||||||
|
|
||||||
|
b.Property<string>("FediverseUri")
|
||||||
|
.HasMaxLength(8192)
|
||||||
|
.HasColumnType("character varying(8192)")
|
||||||
|
.HasColumnName("fediverse_uri");
|
||||||
|
|
||||||
b.Property<bool>("ForwardedGone")
|
b.Property<bool>("ForwardedGone")
|
||||||
.HasColumnType("boolean")
|
.HasColumnType("boolean")
|
||||||
.HasColumnName("forwarded_gone");
|
.HasColumnName("forwarded_gone");
|
||||||
@@ -1117,9 +843,22 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("forwarded_post_id");
|
.HasColumnName("forwarded_post_id");
|
||||||
|
|
||||||
b.Property<Dictionary<string, object>>("Meta")
|
b.Property<string>("Language")
|
||||||
|
.HasMaxLength(2048)
|
||||||
|
.HasColumnType("character varying(2048)")
|
||||||
|
.HasColumnName("language");
|
||||||
|
|
||||||
|
b.Property<int>("LikeCount")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("like_count");
|
||||||
|
|
||||||
|
b.Property<List<ContentMention>>("Mentions")
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
.HasColumnName("meta");
|
.HasColumnName("mentions");
|
||||||
|
|
||||||
|
b.Property<Dictionary<string, object>>("Metadata")
|
||||||
|
.HasColumnType("jsonb")
|
||||||
|
.HasColumnName("metadata");
|
||||||
|
|
||||||
b.Property<int?>("PinMode")
|
b.Property<int?>("PinMode")
|
||||||
.HasColumnType("integer")
|
.HasColumnType("integer")
|
||||||
@@ -1129,7 +868,7 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("timestamp with time zone")
|
.HasColumnType("timestamp with time zone")
|
||||||
.HasColumnName("published_at");
|
.HasColumnName("published_at");
|
||||||
|
|
||||||
b.Property<Guid>("PublisherId")
|
b.Property<Guid?>("PublisherId")
|
||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("publisher_id");
|
.HasColumnName("publisher_id");
|
||||||
|
|
||||||
@@ -1145,6 +884,10 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("replied_post_id");
|
.HasColumnName("replied_post_id");
|
||||||
|
|
||||||
|
b.Property<int>("RepliesCount")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("replies_count");
|
||||||
|
|
||||||
b.PrimitiveCollection<string>("SensitiveMarks")
|
b.PrimitiveCollection<string>("SensitiveMarks")
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
.HasColumnName("sensitive_marks");
|
.HasColumnName("sensitive_marks");
|
||||||
@@ -1186,6 +929,9 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
b.HasKey("Id")
|
b.HasKey("Id")
|
||||||
.HasName("pk_posts");
|
.HasName("pk_posts");
|
||||||
|
|
||||||
|
b.HasIndex("ActorId")
|
||||||
|
.HasDatabaseName("ix_posts_actor_id");
|
||||||
|
|
||||||
b.HasIndex("ForwardedPostId")
|
b.HasIndex("ForwardedPostId")
|
||||||
.HasDatabaseName("ix_posts_forwarded_post_id");
|
.HasDatabaseName("ix_posts_forwarded_post_id");
|
||||||
|
|
||||||
@@ -1421,10 +1167,14 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("id");
|
.HasColumnName("id");
|
||||||
|
|
||||||
b.Property<Guid>("AccountId")
|
b.Property<Guid?>("AccountId")
|
||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("account_id");
|
.HasColumnName("account_id");
|
||||||
|
|
||||||
|
b.Property<Guid?>("ActorId")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("actor_id");
|
||||||
|
|
||||||
b.Property<int>("Attitude")
|
b.Property<int>("Attitude")
|
||||||
.HasColumnType("integer")
|
.HasColumnType("integer")
|
||||||
.HasColumnName("attitude");
|
.HasColumnName("attitude");
|
||||||
@@ -1437,6 +1187,15 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.HasColumnType("timestamp with time zone")
|
.HasColumnType("timestamp with time zone")
|
||||||
.HasColumnName("deleted_at");
|
.HasColumnName("deleted_at");
|
||||||
|
|
||||||
|
b.Property<string>("FediverseUri")
|
||||||
|
.HasMaxLength(2048)
|
||||||
|
.HasColumnType("character varying(2048)")
|
||||||
|
.HasColumnName("fediverse_uri");
|
||||||
|
|
||||||
|
b.Property<bool>("IsLocal")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("is_local");
|
||||||
|
|
||||||
b.Property<Guid>("PostId")
|
b.Property<Guid>("PostId")
|
||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("post_id");
|
.HasColumnName("post_id");
|
||||||
@@ -1454,6 +1213,9 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
b.HasKey("Id")
|
b.HasKey("Id")
|
||||||
.HasName("pk_post_reactions");
|
.HasName("pk_post_reactions");
|
||||||
|
|
||||||
|
b.HasIndex("ActorId")
|
||||||
|
.HasDatabaseName("ix_post_reactions_actor_id");
|
||||||
|
|
||||||
b.HasIndex("PostId")
|
b.HasIndex("PostId")
|
||||||
.HasDatabaseName("ix_post_reactions_post_id");
|
.HasDatabaseName("ix_post_reactions_post_id");
|
||||||
|
|
||||||
@@ -2198,33 +1960,6 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
b.Navigation("Sender");
|
b.Navigation("Sender");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnFediverseActivity", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("DysonNetwork.Shared.Models.SnFediverseActor", "Actor")
|
|
||||||
.WithMany("Activities")
|
|
||||||
.HasForeignKey("ActorId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired()
|
|
||||||
.HasConstraintName("fk_fediverse_activities_fediverse_actors_actor_id");
|
|
||||||
|
|
||||||
b.HasOne("DysonNetwork.Shared.Models.SnFediverseContent", "Content")
|
|
||||||
.WithMany("Activities")
|
|
||||||
.HasForeignKey("ContentId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.HasConstraintName("fk_fediverse_activities_fediverse_contents_content_id");
|
|
||||||
|
|
||||||
b.HasOne("DysonNetwork.Shared.Models.SnFediverseActor", "TargetActor")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("TargetActorId")
|
|
||||||
.HasConstraintName("fk_fediverse_activities_fediverse_actors_target_actor_id");
|
|
||||||
|
|
||||||
b.Navigation("Actor");
|
|
||||||
|
|
||||||
b.Navigation("Content");
|
|
||||||
|
|
||||||
b.Navigation("TargetActor");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnFediverseActor", b =>
|
modelBuilder.Entity("DysonNetwork.Shared.Models.SnFediverseActor", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("DysonNetwork.Shared.Models.SnFediverseInstance", "Instance")
|
b.HasOne("DysonNetwork.Shared.Models.SnFediverseInstance", "Instance")
|
||||||
@@ -2237,48 +1972,6 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
b.Navigation("Instance");
|
b.Navigation("Instance");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnFediverseContent", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("DysonNetwork.Shared.Models.SnFediverseActor", "Actor")
|
|
||||||
.WithMany("Contents")
|
|
||||||
.HasForeignKey("ActorId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired()
|
|
||||||
.HasConstraintName("fk_fediverse_contents_fediverse_actors_actor_id");
|
|
||||||
|
|
||||||
b.HasOne("DysonNetwork.Shared.Models.SnFediverseInstance", "Instance")
|
|
||||||
.WithMany("Contents")
|
|
||||||
.HasForeignKey("InstanceId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired()
|
|
||||||
.HasConstraintName("fk_fediverse_contents_fediverse_instances_instance_id");
|
|
||||||
|
|
||||||
b.Navigation("Actor");
|
|
||||||
|
|
||||||
b.Navigation("Instance");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnFediverseReaction", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("DysonNetwork.Shared.Models.SnFediverseActor", "Actor")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("ActorId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired()
|
|
||||||
.HasConstraintName("fk_fediverse_reactions_fediverse_actors_actor_id");
|
|
||||||
|
|
||||||
b.HasOne("DysonNetwork.Shared.Models.SnFediverseContent", "Content")
|
|
||||||
.WithMany("Reactions")
|
|
||||||
.HasForeignKey("ContentId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired()
|
|
||||||
.HasConstraintName("fk_fediverse_reactions_fediverse_contents_content_id");
|
|
||||||
|
|
||||||
b.Navigation("Actor");
|
|
||||||
|
|
||||||
b.Navigation("Content");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnFediverseRelationship", b =>
|
modelBuilder.Entity("DysonNetwork.Shared.Models.SnFediverseRelationship", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("DysonNetwork.Shared.Models.SnFediverseActor", "Actor")
|
b.HasOne("DysonNetwork.Shared.Models.SnFediverseActor", "Actor")
|
||||||
@@ -2338,6 +2031,11 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnPost", b =>
|
modelBuilder.Entity("DysonNetwork.Shared.Models.SnPost", b =>
|
||||||
{
|
{
|
||||||
|
b.HasOne("DysonNetwork.Shared.Models.SnFediverseActor", "Actor")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ActorId")
|
||||||
|
.HasConstraintName("fk_posts_fediverse_actors_actor_id");
|
||||||
|
|
||||||
b.HasOne("DysonNetwork.Shared.Models.SnPost", "ForwardedPost")
|
b.HasOne("DysonNetwork.Shared.Models.SnPost", "ForwardedPost")
|
||||||
.WithMany()
|
.WithMany()
|
||||||
.HasForeignKey("ForwardedPostId")
|
.HasForeignKey("ForwardedPostId")
|
||||||
@@ -2347,8 +2045,6 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
b.HasOne("DysonNetwork.Shared.Models.SnPublisher", "Publisher")
|
b.HasOne("DysonNetwork.Shared.Models.SnPublisher", "Publisher")
|
||||||
.WithMany("Posts")
|
.WithMany("Posts")
|
||||||
.HasForeignKey("PublisherId")
|
.HasForeignKey("PublisherId")
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired()
|
|
||||||
.HasConstraintName("fk_posts_publishers_publisher_id");
|
.HasConstraintName("fk_posts_publishers_publisher_id");
|
||||||
|
|
||||||
b.HasOne("DysonNetwork.Shared.Models.SnPost", "RepliedPost")
|
b.HasOne("DysonNetwork.Shared.Models.SnPost", "RepliedPost")
|
||||||
@@ -2357,6 +2053,8 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.OnDelete(DeleteBehavior.Restrict)
|
.OnDelete(DeleteBehavior.Restrict)
|
||||||
.HasConstraintName("fk_posts_posts_replied_post_id");
|
.HasConstraintName("fk_posts_posts_replied_post_id");
|
||||||
|
|
||||||
|
b.Navigation("Actor");
|
||||||
|
|
||||||
b.Navigation("ForwardedPost");
|
b.Navigation("ForwardedPost");
|
||||||
|
|
||||||
b.Navigation("Publisher");
|
b.Navigation("Publisher");
|
||||||
@@ -2419,6 +2117,11 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnPostReaction", b =>
|
modelBuilder.Entity("DysonNetwork.Shared.Models.SnPostReaction", b =>
|
||||||
{
|
{
|
||||||
|
b.HasOne("DysonNetwork.Shared.Models.SnFediverseActor", "Actor")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ActorId")
|
||||||
|
.HasConstraintName("fk_post_reactions_fediverse_actors_actor_id");
|
||||||
|
|
||||||
b.HasOne("DysonNetwork.Shared.Models.SnPost", "Post")
|
b.HasOne("DysonNetwork.Shared.Models.SnPost", "Post")
|
||||||
.WithMany("Reactions")
|
.WithMany("Reactions")
|
||||||
.HasForeignKey("PostId")
|
.HasForeignKey("PostId")
|
||||||
@@ -2426,6 +2129,8 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasConstraintName("fk_post_reactions_posts_post_id");
|
.HasConstraintName("fk_post_reactions_posts_post_id");
|
||||||
|
|
||||||
|
b.Navigation("Actor");
|
||||||
|
|
||||||
b.Navigation("Post");
|
b.Navigation("Post");
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -2621,27 +2326,14 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnFediverseActor", b =>
|
modelBuilder.Entity("DysonNetwork.Shared.Models.SnFediverseActor", b =>
|
||||||
{
|
{
|
||||||
b.Navigation("Activities");
|
|
||||||
|
|
||||||
b.Navigation("Contents");
|
|
||||||
|
|
||||||
b.Navigation("FollowerRelationships");
|
b.Navigation("FollowerRelationships");
|
||||||
|
|
||||||
b.Navigation("FollowingRelationships");
|
b.Navigation("FollowingRelationships");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnFediverseContent", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Activities");
|
|
||||||
|
|
||||||
b.Navigation("Reactions");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnFediverseInstance", b =>
|
modelBuilder.Entity("DysonNetwork.Shared.Models.SnFediverseInstance", b =>
|
||||||
{
|
{
|
||||||
b.Navigation("Actors");
|
b.Navigation("Actors");
|
||||||
|
|
||||||
b.Navigation("Contents");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnPoll", b =>
|
modelBuilder.Entity("DysonNetwork.Shared.Models.SnPoll", b =>
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ public class PostActionController(
|
|||||||
Visibility = request.Visibility ?? Shared.Models.PostVisibility.Public,
|
Visibility = request.Visibility ?? Shared.Models.PostVisibility.Public,
|
||||||
PublishedAt = request.PublishedAt,
|
PublishedAt = request.PublishedAt,
|
||||||
Type = request.Type ?? Shared.Models.PostType.Moment,
|
Type = request.Type ?? Shared.Models.PostType.Moment,
|
||||||
Meta = request.Meta,
|
Metadata = request.Meta,
|
||||||
EmbedView = request.EmbedView,
|
EmbedView = request.EmbedView,
|
||||||
Publisher = publisher,
|
Publisher = publisher,
|
||||||
};
|
};
|
||||||
@@ -161,15 +161,15 @@ public class PostActionController(
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var pollEmbed = await polls.MakePollEmbed(request.PollId.Value);
|
var pollEmbed = await polls.MakePollEmbed(request.PollId.Value);
|
||||||
post.Meta ??= new Dictionary<string, object>();
|
post.Metadata ??= new Dictionary<string, object>();
|
||||||
if (
|
if (
|
||||||
!post.Meta.TryGetValue("embeds", out var existingEmbeds)
|
!post.Metadata.TryGetValue("embeds", out var existingEmbeds)
|
||||||
|| existingEmbeds is not List<EmbeddableBase>
|
|| existingEmbeds is not List<EmbeddableBase>
|
||||||
)
|
)
|
||||||
post.Meta["embeds"] = new List<Dictionary<string, object>>();
|
post.Metadata["embeds"] = new List<Dictionary<string, object>>();
|
||||||
var embeds = (List<Dictionary<string, object>>)post.Meta["embeds"];
|
var embeds = (List<Dictionary<string, object>>)post.Metadata["embeds"];
|
||||||
embeds.Add(EmbeddableBase.ToDictionary(pollEmbed));
|
embeds.Add(EmbeddableBase.ToDictionary(pollEmbed));
|
||||||
post.Meta["embeds"] = embeds;
|
post.Metadata["embeds"] = embeds;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -191,15 +191,15 @@ public class PostActionController(
|
|||||||
return BadRequest("You can only share funds that you created.");
|
return BadRequest("You can only share funds that you created.");
|
||||||
|
|
||||||
var fundEmbed = new FundEmbed { Id = request.FundId.Value };
|
var fundEmbed = new FundEmbed { Id = request.FundId.Value };
|
||||||
post.Meta ??= new Dictionary<string, object>();
|
post.Metadata ??= new Dictionary<string, object>();
|
||||||
if (
|
if (
|
||||||
!post.Meta.TryGetValue("embeds", out var existingEmbeds)
|
!post.Metadata.TryGetValue("embeds", out var existingEmbeds)
|
||||||
|| existingEmbeds is not List<EmbeddableBase>
|
|| existingEmbeds is not List<EmbeddableBase>
|
||||||
)
|
)
|
||||||
post.Meta["embeds"] = new List<Dictionary<string, object>>();
|
post.Metadata["embeds"] = new List<Dictionary<string, object>>();
|
||||||
var embeds = (List<Dictionary<string, object>>)post.Meta["embeds"];
|
var embeds = (List<Dictionary<string, object>>)post.Metadata["embeds"];
|
||||||
embeds.Add(EmbeddableBase.ToDictionary(fundEmbed));
|
embeds.Add(EmbeddableBase.ToDictionary(fundEmbed));
|
||||||
post.Meta["embeds"] = embeds;
|
post.Metadata["embeds"] = embeds;
|
||||||
}
|
}
|
||||||
catch (RpcException ex) when (ex.StatusCode == Grpc.Core.StatusCode.NotFound)
|
catch (RpcException ex) when (ex.StatusCode == Grpc.Core.StatusCode.NotFound)
|
||||||
{
|
{
|
||||||
@@ -213,8 +213,8 @@ public class PostActionController(
|
|||||||
|
|
||||||
if (request.ThumbnailId is not null)
|
if (request.ThumbnailId is not null)
|
||||||
{
|
{
|
||||||
post.Meta ??= new Dictionary<string, object>();
|
post.Metadata ??= new Dictionary<string, object>();
|
||||||
post.Meta["thumbnail"] = request.ThumbnailId;
|
post.Metadata["thumbnail"] = request.ThumbnailId;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -454,7 +454,7 @@ public class PostActionController(
|
|||||||
return NotFound();
|
return NotFound();
|
||||||
|
|
||||||
var accountId = Guid.Parse(currentUser.Id);
|
var accountId = Guid.Parse(currentUser.Id);
|
||||||
if (!await pub.IsMemberWithRole(post.PublisherId, accountId, PublisherMemberRole.Editor))
|
if (post.PublisherId == null || !await pub.IsMemberWithRole(post.PublisherId.Value, accountId, PublisherMemberRole.Editor))
|
||||||
return StatusCode(403, "You are not an editor of this publisher");
|
return StatusCode(403, "You are not an editor of this publisher");
|
||||||
|
|
||||||
if (request.Mode == Shared.Models.PostPinMode.RealmPage && post.RealmId != null)
|
if (request.Mode == Shared.Models.PostPinMode.RealmPage && post.RealmId != null)
|
||||||
@@ -518,7 +518,7 @@ public class PostActionController(
|
|||||||
return NotFound();
|
return NotFound();
|
||||||
|
|
||||||
var accountId = Guid.Parse(currentUser.Id);
|
var accountId = Guid.Parse(currentUser.Id);
|
||||||
if (!await pub.IsMemberWithRole(post.PublisherId, accountId, PublisherMemberRole.Editor))
|
if (post.PublisherId == null || !await pub.IsMemberWithRole(post.PublisherId.Value, accountId, PublisherMemberRole.Editor))
|
||||||
return StatusCode(403, "You are not an editor of this publisher");
|
return StatusCode(403, "You are not an editor of this publisher");
|
||||||
|
|
||||||
if (post is { PinMode: Shared.Models.PostPinMode.RealmPage, RealmId: not null })
|
if (post is { PinMode: Shared.Models.PostPinMode.RealmPage, RealmId: not null })
|
||||||
@@ -622,7 +622,7 @@ public class PostActionController(
|
|||||||
if (request.Type is not null)
|
if (request.Type is not null)
|
||||||
post.Type = request.Type.Value;
|
post.Type = request.Type.Value;
|
||||||
if (request.Meta is not null)
|
if (request.Meta is not null)
|
||||||
post.Meta = request.Meta;
|
post.Metadata = request.Meta;
|
||||||
|
|
||||||
// The same, this field can be null, so update it anyway.
|
// The same, this field can be null, so update it anyway.
|
||||||
post.EmbedView = request.EmbedView;
|
post.EmbedView = request.EmbedView;
|
||||||
@@ -634,19 +634,19 @@ public class PostActionController(
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var pollEmbed = await polls.MakePollEmbed(request.PollId.Value);
|
var pollEmbed = await polls.MakePollEmbed(request.PollId.Value);
|
||||||
post.Meta ??= new Dictionary<string, object>();
|
post.Metadata ??= new Dictionary<string, object>();
|
||||||
if (
|
if (
|
||||||
!post.Meta.TryGetValue("embeds", out var existingEmbeds)
|
!post.Metadata.TryGetValue("embeds", out var existingEmbeds)
|
||||||
|| existingEmbeds is not List<EmbeddableBase>
|
|| existingEmbeds is not List<EmbeddableBase>
|
||||||
)
|
)
|
||||||
post.Meta["embeds"] = new List<Dictionary<string, object>>();
|
post.Metadata["embeds"] = new List<Dictionary<string, object>>();
|
||||||
var embeds = (List<Dictionary<string, object>>)post.Meta["embeds"];
|
var embeds = (List<Dictionary<string, object>>)post.Metadata["embeds"];
|
||||||
// Remove all old poll embeds
|
// Remove all old poll embeds
|
||||||
embeds.RemoveAll(e =>
|
embeds.RemoveAll(e =>
|
||||||
e.TryGetValue("type", out var type) && type.ToString() == "poll"
|
e.TryGetValue("type", out var type) && type.ToString() == "poll"
|
||||||
);
|
);
|
||||||
embeds.Add(EmbeddableBase.ToDictionary(pollEmbed));
|
embeds.Add(EmbeddableBase.ToDictionary(pollEmbed));
|
||||||
post.Meta["embeds"] = embeds;
|
post.Metadata["embeds"] = embeds;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -655,13 +655,13 @@ public class PostActionController(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
post.Meta ??= new Dictionary<string, object>();
|
post.Metadata ??= new Dictionary<string, object>();
|
||||||
if (
|
if (
|
||||||
!post.Meta.TryGetValue("embeds", out var existingEmbeds)
|
!post.Metadata.TryGetValue("embeds", out var existingEmbeds)
|
||||||
|| existingEmbeds is not List<EmbeddableBase>
|
|| existingEmbeds is not List<EmbeddableBase>
|
||||||
)
|
)
|
||||||
post.Meta["embeds"] = new List<Dictionary<string, object>>();
|
post.Metadata["embeds"] = new List<Dictionary<string, object>>();
|
||||||
var embeds = (List<Dictionary<string, object>>)post.Meta["embeds"];
|
var embeds = (List<Dictionary<string, object>>)post.Metadata["embeds"];
|
||||||
// Remove all old poll embeds
|
// Remove all old poll embeds
|
||||||
embeds.RemoveAll(e => e.TryGetValue("type", out var type) && type.ToString() == "poll");
|
embeds.RemoveAll(e => e.TryGetValue("type", out var type) && type.ToString() == "poll");
|
||||||
}
|
}
|
||||||
@@ -681,19 +681,19 @@ public class PostActionController(
|
|||||||
return BadRequest("You can only share funds that you created.");
|
return BadRequest("You can only share funds that you created.");
|
||||||
|
|
||||||
var fundEmbed = new FundEmbed { Id = request.FundId.Value };
|
var fundEmbed = new FundEmbed { Id = request.FundId.Value };
|
||||||
post.Meta ??= new Dictionary<string, object>();
|
post.Metadata ??= new Dictionary<string, object>();
|
||||||
if (
|
if (
|
||||||
!post.Meta.TryGetValue("embeds", out var existingEmbeds)
|
!post.Metadata.TryGetValue("embeds", out var existingEmbeds)
|
||||||
|| existingEmbeds is not List<EmbeddableBase>
|
|| existingEmbeds is not List<EmbeddableBase>
|
||||||
)
|
)
|
||||||
post.Meta["embeds"] = new List<Dictionary<string, object>>();
|
post.Metadata["embeds"] = new List<Dictionary<string, object>>();
|
||||||
var embeds = (List<Dictionary<string, object>>)post.Meta["embeds"];
|
var embeds = (List<Dictionary<string, object>>)post.Metadata["embeds"];
|
||||||
// Remove all old fund embeds
|
// Remove all old fund embeds
|
||||||
embeds.RemoveAll(e =>
|
embeds.RemoveAll(e =>
|
||||||
e.TryGetValue("type", out var type) && type.ToString() == "fund"
|
e.TryGetValue("type", out var type) && type.ToString() == "fund"
|
||||||
);
|
);
|
||||||
embeds.Add(EmbeddableBase.ToDictionary(fundEmbed));
|
embeds.Add(EmbeddableBase.ToDictionary(fundEmbed));
|
||||||
post.Meta["embeds"] = embeds;
|
post.Metadata["embeds"] = embeds;
|
||||||
}
|
}
|
||||||
catch (RpcException ex) when (ex.StatusCode == Grpc.Core.StatusCode.NotFound)
|
catch (RpcException ex) when (ex.StatusCode == Grpc.Core.StatusCode.NotFound)
|
||||||
{
|
{
|
||||||
@@ -706,26 +706,26 @@ public class PostActionController(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
post.Meta ??= new Dictionary<string, object>();
|
post.Metadata ??= new Dictionary<string, object>();
|
||||||
if (
|
if (
|
||||||
!post.Meta.TryGetValue("embeds", out var existingEmbeds)
|
!post.Metadata.TryGetValue("embeds", out var existingEmbeds)
|
||||||
|| existingEmbeds is not List<EmbeddableBase>
|
|| existingEmbeds is not List<EmbeddableBase>
|
||||||
)
|
)
|
||||||
post.Meta["embeds"] = new List<Dictionary<string, object>>();
|
post.Metadata["embeds"] = new List<Dictionary<string, object>>();
|
||||||
var embeds = (List<Dictionary<string, object>>)post.Meta["embeds"];
|
var embeds = (List<Dictionary<string, object>>)post.Metadata["embeds"];
|
||||||
// Remove all old fund embeds
|
// Remove all old fund embeds
|
||||||
embeds.RemoveAll(e => e.TryGetValue("type", out var type) && type.ToString() == "fund");
|
embeds.RemoveAll(e => e.TryGetValue("type", out var type) && type.ToString() == "fund");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request.ThumbnailId is not null)
|
if (request.ThumbnailId is not null)
|
||||||
{
|
{
|
||||||
post.Meta ??= new Dictionary<string, object>();
|
post.Metadata ??= new Dictionary<string, object>();
|
||||||
post.Meta["thumbnail"] = request.ThumbnailId;
|
post.Metadata["thumbnail"] = request.ThumbnailId;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
post.Meta ??= new Dictionary<string, object>();
|
post.Metadata ??= new Dictionary<string, object>();
|
||||||
post.Meta.Remove("thumbnail");
|
post.Metadata.Remove("thumbnail");
|
||||||
}
|
}
|
||||||
|
|
||||||
// The realm is the same as well as the poll
|
// The realm is the same as well as the poll
|
||||||
|
|||||||
@@ -336,7 +336,7 @@ public class PostController(
|
|||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
var accountsProto = await remoteAccountsHelper.GetAccountBatch(
|
var accountsProto = await remoteAccountsHelper.GetAccountBatch(
|
||||||
reactions.Select(r => r.AccountId).ToList()
|
reactions.Where(r => r.AccountId.HasValue).Select(r => r.AccountId!.Value).ToList()
|
||||||
);
|
);
|
||||||
var accounts = accountsProto.ToDictionary(
|
var accounts = accountsProto.ToDictionary(
|
||||||
a => Guid.Parse(a.Id),
|
a => Guid.Parse(a.Id),
|
||||||
@@ -344,7 +344,7 @@ public class PostController(
|
|||||||
);
|
);
|
||||||
|
|
||||||
foreach (var reaction in reactions)
|
foreach (var reaction in reactions)
|
||||||
if (accounts.TryGetValue(reaction.AccountId, out var account))
|
if (reaction.AccountId.HasValue && accounts.TryGetValue(reaction.AccountId.Value, out var account))
|
||||||
reaction.Account = account;
|
reaction.Account = account;
|
||||||
|
|
||||||
return Ok(reactions);
|
return Ok(reactions);
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ public partial class PostService(
|
|||||||
var accounts = scope.ServiceProvider.GetRequiredService<AccountService.AccountServiceClient>();
|
var accounts = scope.ServiceProvider.GetRequiredService<AccountService.AccountServiceClient>();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var members = await pub.GetPublisherMembers(post.RepliedPost.PublisherId);
|
var members = await pub.GetPublisherMembers(post.RepliedPost.PublisherId!.Value);
|
||||||
var queryRequest = new GetAccountBatchRequest();
|
var queryRequest = new GetAccountBatchRequest();
|
||||||
queryRequest.Id.AddRange(members.Select(m => m.AccountId.ToString()));
|
queryRequest.Id.AddRange(members.Select(m => m.AccountId.ToString()));
|
||||||
var queryResponse = await accounts.GetAccountBatchAsync(queryRequest);
|
var queryResponse = await accounts.GetAccountBatchAsync(queryRequest);
|
||||||
@@ -301,15 +301,10 @@ public partial class PostService(
|
|||||||
return item;
|
return item;
|
||||||
|
|
||||||
// Initialize meta dictionary if null
|
// Initialize meta dictionary if null
|
||||||
item.Meta ??= new Dictionary<string, object>();
|
item.Metadata ??= new Dictionary<string, object>();
|
||||||
|
if (!item.Metadata.TryGetValue("embeds", out var existingEmbeds) || existingEmbeds is not List<EmbeddableBase>)
|
||||||
// Initialize the embeds' array if it doesn't exist
|
item.Metadata["embeds"] = new List<Dictionary<string, object>>();
|
||||||
if (!item.Meta.TryGetValue("embeds", out var existingEmbeds) || existingEmbeds is not List<EmbeddableBase>)
|
var embeds = (List<Dictionary<string, object>>)item.Metadata["embeds"];
|
||||||
{
|
|
||||||
item.Meta["embeds"] = new List<Dictionary<string, object>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
||||||
const int maxLinks = 3;
|
const int maxLinks = 3;
|
||||||
@@ -340,13 +335,12 @@ public partial class PostService(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
item.Meta["embeds"] = embeds;
|
item.Metadata["embeds"] = embeds;
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Process link previews for a post in the background
|
/// Process link previews for a post in background
|
||||||
/// This method is designed to be called from a background task
|
/// This method is designed to be called from a background task
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="post">The post to process link previews for</param>
|
/// <param name="post">The post to process link previews for</param>
|
||||||
@@ -362,17 +356,17 @@ public partial class PostService(
|
|||||||
var updatedPost = await PreviewPostLinkAsync(post);
|
var updatedPost = await PreviewPostLinkAsync(post);
|
||||||
|
|
||||||
// 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.Metadata != null &&
|
||||||
updatedPost.Meta.TryGetValue("embeds", out var embeds) &&
|
updatedPost.Metadata.TryGetValue("embeds", out var embeds) &&
|
||||||
embeds is List<Dictionary<string, object>> { Count: > 0 } embedsList)
|
embeds is List<Dictionary<string, object>> { 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);
|
||||||
if (dbPost != null)
|
if (dbPost != null)
|
||||||
{
|
{
|
||||||
// Update the meta field with the new embeds
|
// Update the metadata field with the new embeds
|
||||||
dbPost.Meta ??= new Dictionary<string, object>();
|
dbPost.Metadata ??= new Dictionary<string, object>();
|
||||||
dbPost.Meta["embeds"] = embedsList;
|
dbPost.Metadata["embeds"] = embedsList;
|
||||||
|
|
||||||
// Save changes to the database
|
// Save changes to the database
|
||||||
dbContext.Update(dbPost);
|
dbContext.Update(dbPost);
|
||||||
@@ -431,7 +425,7 @@ public partial class PostService(
|
|||||||
throw new InvalidOperationException("Replies can only be pinned in the reply page.");
|
throw new InvalidOperationException("Replies can only be pinned in the reply page.");
|
||||||
if (post.RepliedPost == null) throw new ArgumentNullException(nameof(post.RepliedPost));
|
if (post.RepliedPost == null) throw new ArgumentNullException(nameof(post.RepliedPost));
|
||||||
|
|
||||||
if (!await ps.IsMemberWithRole(post.RepliedPost.PublisherId, accountId,
|
if (!await ps.IsMemberWithRole(post.RepliedPost.PublisherId!.Value, accountId,
|
||||||
Shared.Models.PublisherMemberRole.Editor))
|
Shared.Models.PublisherMemberRole.Editor))
|
||||||
throw new InvalidOperationException("Only editors of original post can pin replies.");
|
throw new InvalidOperationException("Only editors of original post can pin replies.");
|
||||||
|
|
||||||
@@ -439,7 +433,7 @@ public partial class PostService(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!await ps.IsMemberWithRole(post.PublisherId, accountId, Shared.Models.PublisherMemberRole.Editor))
|
if (post.PublisherId == null || !await ps.IsMemberWithRole(post.PublisherId.Value, accountId, Shared.Models.PublisherMemberRole.Editor))
|
||||||
throw new InvalidOperationException("Only editors can pin replies.");
|
throw new InvalidOperationException("Only editors can pin replies.");
|
||||||
|
|
||||||
post.PinMode = pinMode;
|
post.PinMode = pinMode;
|
||||||
@@ -458,13 +452,13 @@ public partial class PostService(
|
|||||||
{
|
{
|
||||||
if (post.RepliedPost == null) throw new ArgumentNullException(nameof(post.RepliedPost));
|
if (post.RepliedPost == null) throw new ArgumentNullException(nameof(post.RepliedPost));
|
||||||
|
|
||||||
if (!await ps.IsMemberWithRole(post.RepliedPost.PublisherId, accountId,
|
if (!await ps.IsMemberWithRole(post.RepliedPost.PublisherId!.Value, accountId,
|
||||||
Shared.Models.PublisherMemberRole.Editor))
|
Shared.Models.PublisherMemberRole.Editor))
|
||||||
throw new InvalidOperationException("Only editors of original post can unpin replies.");
|
throw new InvalidOperationException("Only editors of original post can unpin replies.");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!await ps.IsMemberWithRole(post.PublisherId, accountId, Shared.Models.PublisherMemberRole.Editor))
|
if (post.PublisherId == null || !await ps.IsMemberWithRole(post.PublisherId.Value, accountId, Shared.Models.PublisherMemberRole.Editor))
|
||||||
throw new InvalidOperationException("Only editors can unpin posts.");
|
throw new InvalidOperationException("Only editors can unpin posts.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -493,12 +487,14 @@ public partial class PostService(
|
|||||||
bool isSelfReact
|
bool isSelfReact
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
var isExistingReaction = await db.Set<SnPostReaction>()
|
var isExistingReaction = reaction.AccountId.HasValue &&
|
||||||
.AnyAsync(r => r.PostId == post.Id && r.AccountId == reaction.AccountId);
|
await db.Set<SnPostReaction>()
|
||||||
|
.AnyAsync(r => r.PostId == post.Id && r.AccountId == reaction.AccountId.Value);
|
||||||
|
|
||||||
if (isRemoving)
|
if (isRemoving)
|
||||||
await db.PostReactions
|
await db.PostReactions
|
||||||
.Where(r => r.PostId == post.Id && r.Symbol == reaction.Symbol && r.AccountId == reaction.AccountId)
|
.Where(r => r.PostId == post.Id && r.Symbol == reaction.Symbol &&
|
||||||
|
reaction.AccountId.HasValue && r.AccountId == reaction.AccountId.Value)
|
||||||
.ExecuteDeleteAsync();
|
.ExecuteDeleteAsync();
|
||||||
else
|
else
|
||||||
db.PostReactions.Add(reaction);
|
db.PostReactions.Add(reaction);
|
||||||
@@ -539,7 +535,8 @@ public partial class PostService(
|
|||||||
var accounts = scope.ServiceProvider.GetRequiredService<AccountService.AccountServiceClient>();
|
var accounts = scope.ServiceProvider.GetRequiredService<AccountService.AccountServiceClient>();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var members = await pub.GetPublisherMembers(post.PublisherId);
|
if (post.PublisherId == null) return;
|
||||||
|
var members = await pub.GetPublisherMembers(post.PublisherId.Value);
|
||||||
var queryRequest = new GetAccountBatchRequest();
|
var queryRequest = new GetAccountBatchRequest();
|
||||||
queryRequest.Id.AddRange(members.Select(m => m.AccountId.ToString()));
|
queryRequest.Id.AddRange(members.Select(m => m.AccountId.ToString()));
|
||||||
var queryResponse = await accounts.GetAccountBatchAsync(queryRequest);
|
var queryResponse = await accounts.GetAccountBatchAsync(queryRequest);
|
||||||
@@ -675,15 +672,15 @@ public partial class PostService(
|
|||||||
|
|
||||||
foreach (var post in posts)
|
foreach (var post in posts)
|
||||||
{
|
{
|
||||||
if (publishers.TryGetValue(post.PublisherId, out var publisher))
|
if (post.PublisherId.HasValue && publishers.TryGetValue(post.PublisherId.Value, out var publisher))
|
||||||
post.Publisher = publisher;
|
post.Publisher = publisher;
|
||||||
|
|
||||||
if (post.RepliedPost?.PublisherId != null &&
|
if (post.RepliedPost?.PublisherId != null &&
|
||||||
publishers.TryGetValue(post.RepliedPost.PublisherId, out var repliedPublisher))
|
publishers.TryGetValue(post.RepliedPost.PublisherId.Value, out var repliedPublisher))
|
||||||
post.RepliedPost.Publisher = repliedPublisher;
|
post.RepliedPost.Publisher = repliedPublisher;
|
||||||
|
|
||||||
if (post.ForwardedPost?.PublisherId != null &&
|
if (post.ForwardedPost?.PublisherId != null &&
|
||||||
publishers.TryGetValue(post.ForwardedPost.PublisherId, out var forwardedPublisher))
|
publishers.TryGetValue(post.ForwardedPost.PublisherId.Value, out var forwardedPublisher))
|
||||||
post.ForwardedPost.Publisher = forwardedPublisher;
|
post.ForwardedPost.Publisher = forwardedPublisher;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -780,7 +777,7 @@ public partial class PostService(
|
|||||||
|
|
||||||
// Check publication status - either published or user is member
|
// Check publication status - either published or user is member
|
||||||
var isPublished = post.PublishedAt != null && now >= post.PublishedAt;
|
var isPublished = post.PublishedAt != null && now >= post.PublishedAt;
|
||||||
var isMember = publishersId.Contains(post.PublisherId);
|
var isMember = post.PublisherId.HasValue && publishersId.Contains(post.PublisherId.Value);
|
||||||
if (!isPublished && !isMember)
|
if (!isPublished && !isMember)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -967,7 +964,8 @@ public partial class PostService(
|
|||||||
{
|
{
|
||||||
var sender = await accountsHelper.GetAccount(accountId);
|
var sender = await accountsHelper.GetAccount(accountId);
|
||||||
|
|
||||||
var members = await pub.GetPublisherMembers(post.PublisherId);
|
if (post.PublisherId == null) return;
|
||||||
|
var members = await pub.GetPublisherMembers(post.PublisherId.Value);
|
||||||
var queryRequest = new GetAccountBatchRequest();
|
var queryRequest = new GetAccountBatchRequest();
|
||||||
queryRequest.Id.AddRange(members.Select(m => m.AccountId.ToString()));
|
queryRequest.Id.AddRange(members.Select(m => m.AccountId.ToString()));
|
||||||
var queryResponse = await accounts.GetAccountBatchAsync(queryRequest);
|
var queryResponse = await accounts.GetAccountBatchAsync(queryRequest);
|
||||||
@@ -1021,7 +1019,7 @@ public static class PostQueryExtensions
|
|||||||
source = isListing switch
|
source = isListing switch
|
||||||
{
|
{
|
||||||
true when currentUser is not null => source.Where(e =>
|
true when currentUser is not null => source.Where(e =>
|
||||||
e.Visibility != Shared.Models.PostVisibility.Unlisted || publishersId.Contains(e.PublisherId)),
|
e.Visibility != Shared.Models.PostVisibility.Unlisted || (e.PublisherId.HasValue && publishersId.Contains(e.PublisherId.Value))),
|
||||||
true => source.Where(e => e.Visibility != Shared.Models.PostVisibility.Unlisted),
|
true => source.Where(e => e.Visibility != Shared.Models.PostVisibility.Unlisted),
|
||||||
_ => source
|
_ => source
|
||||||
};
|
};
|
||||||
@@ -1032,10 +1030,10 @@ public static class PostQueryExtensions
|
|||||||
.Where(e => e.Visibility == Shared.Models.PostVisibility.Public);
|
.Where(e => e.Visibility == Shared.Models.PostVisibility.Public);
|
||||||
|
|
||||||
return source
|
return source
|
||||||
.Where(e => (e.PublishedAt != null && now >= e.PublishedAt) || publishersId.Contains(e.PublisherId))
|
.Where(e => (e.PublishedAt != null && now >= e.PublishedAt) || (e.PublisherId.HasValue && publishersId.Contains(e.PublisherId.Value)))
|
||||||
.Where(e => e.Visibility != Shared.Models.PostVisibility.Private || publishersId.Contains(e.PublisherId))
|
.Where(e => e.Visibility != Shared.Models.PostVisibility.Private || publishersId.Contains(e.PublisherId.Value))
|
||||||
.Where(e => e.Visibility != Shared.Models.PostVisibility.Friends ||
|
.Where(e => e.Visibility != Shared.Models.PostVisibility.Friends ||
|
||||||
(e.Publisher.AccountId != null && userFriends.Contains(e.Publisher.AccountId.Value)) ||
|
(e.Publisher.AccountId != null && userFriends.Contains(e.Publisher.AccountId.Value)) ||
|
||||||
publishersId.Contains(e.PublisherId));
|
publishersId.Contains(e.PublisherId.Value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -556,9 +556,12 @@ public class PublisherService(
|
|||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
// Group stats by publisher id
|
// Group stats by publisher id
|
||||||
var postIdToPublisher = postsInPeriod.ToDictionary(p => p.Id, p => p.PublisherId);
|
var postIdToPublisher = postsInPeriod
|
||||||
|
.Where(p => p.PublisherId.HasValue)
|
||||||
|
.ToDictionary(p => p.Id, p => p.PublisherId!.Value);
|
||||||
var publisherStats = postsInPeriod
|
var publisherStats = postsInPeriod
|
||||||
.GroupBy(p => p.PublisherId)
|
.Where(p => p.PublisherId.HasValue)
|
||||||
|
.GroupBy(p => p.PublisherId!.Value)
|
||||||
.ToDictionary(g => g.Key,
|
.ToDictionary(g => g.Key,
|
||||||
g => new
|
g => new
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ public class SphereRewindServiceGrpc(
|
|||||||
var mostLovedPublisherClue = await db
|
var mostLovedPublisherClue = await db
|
||||||
.PostReactions.Where(a => a.CreatedAt >= startDate && a.CreatedAt < endDate)
|
.PostReactions.Where(a => a.CreatedAt >= startDate && a.CreatedAt < endDate)
|
||||||
.Where(p => p.AccountId == accountId && p.Attitude == PostReactionAttitude.Positive)
|
.Where(p => p.AccountId == accountId && p.Attitude == PostReactionAttitude.Positive)
|
||||||
.GroupBy(p => p.Post.PublisherId)
|
.Where(p => p.Post.PublisherId.HasValue)
|
||||||
|
.GroupBy(p => p.Post.PublisherId!.Value)
|
||||||
.OrderByDescending(g => g.Count())
|
.OrderByDescending(g => g.Count())
|
||||||
.Select(g => new { PublisherId = g.Key, ReactionCount = g.Count() })
|
.Select(g => new { PublisherId = g.Key, ReactionCount = g.Count() })
|
||||||
.FirstOrDefaultAsync();
|
.FirstOrDefaultAsync();
|
||||||
@@ -51,9 +52,11 @@ public class SphereRewindServiceGrpc(
|
|||||||
.PostReactions.Where(a => a.CreatedAt >= startDate && a.CreatedAt < endDate)
|
.PostReactions.Where(a => a.CreatedAt >= startDate && a.CreatedAt < endDate)
|
||||||
.Where(pr =>
|
.Where(pr =>
|
||||||
pr.Attitude == PostReactionAttitude.Positive
|
pr.Attitude == PostReactionAttitude.Positive
|
||||||
&& publishers.Contains(pr.Post.PublisherId)
|
&& pr.AccountId.HasValue
|
||||||
|
&& pr.Post.PublisherId.HasValue
|
||||||
|
&& publishers.Contains(pr.Post.PublisherId.Value)
|
||||||
)
|
)
|
||||||
.GroupBy(pr => pr.AccountId)
|
.GroupBy(pr => pr.AccountId!.Value)
|
||||||
.OrderByDescending(g => g.Count())
|
.OrderByDescending(g => g.Count())
|
||||||
.Select(g => new { AccountId = g.Key, ReactionCount = g.Count() })
|
.Select(g => new { AccountId = g.Key, ReactionCount = g.Count() })
|
||||||
.FirstOrDefaultAsync();
|
.FirstOrDefaultAsync();
|
||||||
@@ -63,12 +66,12 @@ public class SphereRewindServiceGrpc(
|
|||||||
|
|
||||||
var posts = db
|
var posts = db
|
||||||
.Posts.Where(a => a.CreatedAt >= startDate && a.CreatedAt < endDate)
|
.Posts.Where(a => a.CreatedAt >= startDate && a.CreatedAt < endDate)
|
||||||
.Where(p => publishers.Contains(p.PublisherId))
|
.Where(p => p.PublisherId.HasValue && publishers.Contains(p.PublisherId.Value))
|
||||||
.AsQueryable();
|
.AsQueryable();
|
||||||
var postTotalCount = await posts.CountAsync();
|
var postTotalCount = await posts.CountAsync();
|
||||||
var postTotalUpvotes = await db
|
var postTotalUpvotes = await db
|
||||||
.PostReactions.Where(a => a.CreatedAt >= startDate && a.CreatedAt < endDate)
|
.PostReactions.Where(a => a.CreatedAt >= startDate && a.CreatedAt < endDate)
|
||||||
.Where(p => publishers.Contains(p.Post.PublisherId))
|
.Where(p => p.Post.PublisherId.HasValue && publishers.Contains(p.Post.PublisherId.Value))
|
||||||
.Where(r => r.Attitude == PostReactionAttitude.Positive)
|
.Where(r => r.Attitude == PostReactionAttitude.Positive)
|
||||||
.CountAsync();
|
.CountAsync();
|
||||||
var mostPopularPost = await posts
|
var mostPopularPost = await posts
|
||||||
|
|||||||
@@ -318,7 +318,7 @@ public class TimelineService(
|
|||||||
.AsQueryable();
|
.AsQueryable();
|
||||||
|
|
||||||
if (filteredPublishersId != null && filteredPublishersId.Count != 0)
|
if (filteredPublishersId != null && filteredPublishersId.Count != 0)
|
||||||
query = query.Where(p => filteredPublishersId.Contains(p.PublisherId));
|
query = query.Where(p => p.PublisherId.HasValue && filteredPublishersId.Contains(p.PublisherId.Value));
|
||||||
if (userRealms == null)
|
if (userRealms == null)
|
||||||
{
|
{
|
||||||
// For anonymous users, only show public realm posts or posts without realm
|
// For anonymous users, only show public realm posts or posts without realm
|
||||||
|
|||||||
Reference in New Issue
Block a user