Realm post

This commit is contained in:
2025-08-15 02:42:35 +08:00
parent 6211f546b1
commit cb420c2262
5 changed files with 2049 additions and 2 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,49 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace DysonNetwork.Sphere.Migrations
{
/// <inheritdoc />
public partial class AddRealmPost : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<Guid>(
name: "realm_id",
table: "posts",
type: "uuid",
nullable: true);
migrationBuilder.CreateIndex(
name: "ix_posts_realm_id",
table: "posts",
column: "realm_id");
migrationBuilder.AddForeignKey(
name: "fk_posts_realms_realm_id",
table: "posts",
column: "realm_id",
principalTable: "realms",
principalColumn: "id");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "fk_posts_realms_realm_id",
table: "posts");
migrationBuilder.DropIndex(
name: "ix_posts_realm_id",
table: "posts");
migrationBuilder.DropColumn(
name: "realm_id",
table: "posts");
}
}
}

View File

@@ -575,6 +575,10 @@ namespace DysonNetwork.Sphere.Migrations
.HasColumnType("uuid") .HasColumnType("uuid")
.HasColumnName("publisher_id"); .HasColumnName("publisher_id");
b.Property<Guid?>("RealmId")
.HasColumnType("uuid")
.HasColumnName("realm_id");
b.Property<Guid?>("RepliedPostId") b.Property<Guid?>("RepliedPostId")
.HasColumnType("uuid") .HasColumnType("uuid")
.HasColumnName("replied_post_id"); .HasColumnName("replied_post_id");
@@ -629,6 +633,9 @@ namespace DysonNetwork.Sphere.Migrations
b.HasIndex("PublisherId") b.HasIndex("PublisherId")
.HasDatabaseName("ix_posts_publisher_id"); .HasDatabaseName("ix_posts_publisher_id");
b.HasIndex("RealmId")
.HasDatabaseName("ix_posts_realm_id");
b.HasIndex("RepliedPostId") b.HasIndex("RepliedPostId")
.HasDatabaseName("ix_posts_replied_post_id"); .HasDatabaseName("ix_posts_replied_post_id");
@@ -1652,6 +1659,11 @@ namespace DysonNetwork.Sphere.Migrations
.IsRequired() .IsRequired()
.HasConstraintName("fk_posts_publishers_publisher_id"); .HasConstraintName("fk_posts_publishers_publisher_id");
b.HasOne("DysonNetwork.Sphere.Realm.Realm", "Realm")
.WithMany()
.HasForeignKey("RealmId")
.HasConstraintName("fk_posts_realms_realm_id");
b.HasOne("DysonNetwork.Sphere.Post.Post", "RepliedPost") b.HasOne("DysonNetwork.Sphere.Post.Post", "RepliedPost")
.WithMany() .WithMany()
.HasForeignKey("RepliedPostId") .HasForeignKey("RepliedPostId")
@@ -1662,6 +1674,8 @@ namespace DysonNetwork.Sphere.Migrations
b.Navigation("Publisher"); b.Navigation("Publisher");
b.Navigation("Realm");
b.Navigation("RepliedPost"); b.Navigation("RepliedPost");
}); });

View File

@@ -2,7 +2,6 @@ using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using DysonNetwork.Shared.Data; using DysonNetwork.Shared.Data;
using DysonNetwork.Shared.Proto;
using DysonNetwork.Sphere.Activity; using DysonNetwork.Sphere.Activity;
using NodaTime; using NodaTime;
using NpgsqlTypes; using NpgsqlTypes;
@@ -54,6 +53,9 @@ public class Post : ModelBase, IIdentifiedResource, IActivity
public Guid? ForwardedPostId { get; set; } public Guid? ForwardedPostId { get; set; }
public Post? ForwardedPost { get; set; } public Post? ForwardedPost { get; set; }
public Guid? RealmId { get; set; }
public Realm.Realm? Realm { get; set; }
[Column(TypeName = "jsonb")] public List<CloudFileReferenceObject> Attachments { get; set; } = []; [Column(TypeName = "jsonb")] public List<CloudFileReferenceObject> Attachments { get; set; } = [];
[JsonIgnore] public NpgsqlTsVector SearchVector { get; set; } = null!; [JsonIgnore] public NpgsqlTsVector SearchVector { get; set; } = null!;

View File

@@ -4,6 +4,7 @@ using DysonNetwork.Shared.Content;
using DysonNetwork.Shared.Data; using DysonNetwork.Shared.Data;
using DysonNetwork.Shared.Proto; using DysonNetwork.Shared.Proto;
using DysonNetwork.Sphere.Poll; using DysonNetwork.Sphere.Poll;
using DysonNetwork.Sphere.Realm;
using DysonNetwork.Sphere.WebReader; using DysonNetwork.Sphere.WebReader;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@@ -21,7 +22,8 @@ public class PostController(
PublisherService pub, PublisherService pub,
AccountService.AccountServiceClient accounts, AccountService.AccountServiceClient accounts,
ActionLogService.ActionLogServiceClient als, ActionLogService.ActionLogServiceClient als,
PollService polls PollService polls,
RealmService rs
) )
: ControllerBase : ControllerBase
{ {
@@ -322,6 +324,7 @@ public class PostController(
public Instant? PublishedAt { get; set; } public Instant? PublishedAt { get; set; }
public Guid? RepliedPostId { get; set; } public Guid? RepliedPostId { get; set; }
public Guid? ForwardedPostId { get; set; } public Guid? ForwardedPostId { get; set; }
public Guid? RealmId { get; set; }
public Guid? PollId { get; set; } public Guid? PollId { get; set; }
} }
@@ -385,6 +388,15 @@ public class PostController(
post.ForwardedPostId = forwardedPost.Id; post.ForwardedPostId = forwardedPost.Id;
} }
if (request.RealmId is not null)
{
var realm = await db.Realms.FindAsync(request.RealmId.Value);
if (realm is null) return BadRequest("Realm was not found.");
if (!await rs.IsMemberWithRole(realm.Id, accountId, RealmMemberRole.Normal))
return StatusCode(403, "You are not a member of this realm.");
post.RealmId = realm.Id;
}
if (request.PollId.HasValue) if (request.PollId.HasValue)
{ {
try try
@@ -537,6 +549,8 @@ public class PostController(
if (request.Type is not null) post.Type = request.Type.Value; if (request.Type is not null) post.Type = request.Type.Value;
if (request.Meta is not null) post.Meta = request.Meta; if (request.Meta is not null) post.Meta = request.Meta;
// All the fields are updated when the request contains the specific fields
// But the Poll can be null, so it will be updated whatever it included in requests or not
if (request.PollId.HasValue) if (request.PollId.HasValue)
{ {
try try
@@ -557,6 +571,30 @@ public class PostController(
return BadRequest(ex.Message); return BadRequest(ex.Message);
} }
} }
else
{
post.Meta ??= new Dictionary<string, object>();
if (!post.Meta.TryGetValue("embeds", out var existingEmbeds) ||
existingEmbeds is not List<EmbeddableBase>)
post.Meta["embeds"] = new List<Dictionary<string, object>>();
var embeds = (List<Dictionary<string, object>>)post.Meta["embeds"];
// Remove all old poll embeds
embeds.RemoveAll(e => e.TryGetValue("type", out var type) && type.ToString() == "poll");
}
// The realm is the same as well as the poll
if (request.RealmId is not null)
{
var realm = await db.Realms.FindAsync(request.RealmId.Value);
if (realm is null) return BadRequest("Realm was not found.");
if (!await rs.IsMemberWithRole(realm.Id, accountId, RealmMemberRole.Normal))
return StatusCode(403, "You are not a member of this realm.");
post.RealmId = realm.Id;
}
else
{
post.RealmId = null;
}
try try
{ {