🐛 Post reaction fixes

This commit is contained in:
LittleSheep 2025-05-05 13:12:20 +08:00
parent 2206676214
commit 02aee07116
6 changed files with 2512 additions and 24 deletions

View File

@ -55,6 +55,7 @@ public class AppDatabase(
public DbSet<Chat.ChatMember> ChatMembers { get; set; }
public DbSet<Chat.Message> ChatMessages { get; set; }
public DbSet<Chat.MessageStatus> ChatStatuses { get; set; }
public DbSet<Chat.MessageReaction> ChatReactions { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
@ -80,7 +81,7 @@ public class AppDatabase(
Nodes =
{
PermissionService.NewPermissionNode("group:default", "global", "posts.create", true),
PermissionService.NewPermissionNode("group:default", "global", "posts.reactions.create", true),
PermissionService.NewPermissionNode("group:default", "global", "posts.react", true),
PermissionService.NewPermissionNode("group:default", "global", "publishers.create", true),
PermissionService.NewPermissionNode("group:default", "global", "files.create", true),
PermissionService.NewPermissionNode("group:default", "global", "chat.create", true)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,112 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace DysonNetwork.Sphere.Migrations
{
/// <inheritdoc />
public partial class NoIdeaHowToNameThis : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "fk_message_reaction_chat_members_sender_id",
table: "message_reaction");
migrationBuilder.DropForeignKey(
name: "fk_message_reaction_chat_messages_message_id",
table: "message_reaction");
migrationBuilder.DropPrimaryKey(
name: "pk_message_reaction",
table: "message_reaction");
migrationBuilder.RenameTable(
name: "message_reaction",
newName: "chat_reactions");
migrationBuilder.RenameIndex(
name: "ix_message_reaction_sender_id",
table: "chat_reactions",
newName: "ix_chat_reactions_sender_id");
migrationBuilder.RenameIndex(
name: "ix_message_reaction_message_id",
table: "chat_reactions",
newName: "ix_chat_reactions_message_id");
migrationBuilder.AddPrimaryKey(
name: "pk_chat_reactions",
table: "chat_reactions",
column: "id");
migrationBuilder.AddForeignKey(
name: "fk_chat_reactions_chat_members_sender_id",
table: "chat_reactions",
column: "sender_id",
principalTable: "chat_members",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_chat_reactions_chat_messages_message_id",
table: "chat_reactions",
column: "message_id",
principalTable: "chat_messages",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "fk_chat_reactions_chat_members_sender_id",
table: "chat_reactions");
migrationBuilder.DropForeignKey(
name: "fk_chat_reactions_chat_messages_message_id",
table: "chat_reactions");
migrationBuilder.DropPrimaryKey(
name: "pk_chat_reactions",
table: "chat_reactions");
migrationBuilder.RenameTable(
name: "chat_reactions",
newName: "message_reaction");
migrationBuilder.RenameIndex(
name: "ix_chat_reactions_sender_id",
table: "message_reaction",
newName: "ix_message_reaction_sender_id");
migrationBuilder.RenameIndex(
name: "ix_chat_reactions_message_id",
table: "message_reaction",
newName: "ix_message_reaction_message_id");
migrationBuilder.AddPrimaryKey(
name: "pk_message_reaction",
table: "message_reaction",
column: "id");
migrationBuilder.AddForeignKey(
name: "fk_message_reaction_chat_members_sender_id",
table: "message_reaction",
column: "sender_id",
principalTable: "chat_members",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_message_reaction_chat_messages_message_id",
table: "message_reaction",
column: "message_id",
principalTable: "chat_messages",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
}
}
}

View File

@ -888,15 +888,15 @@ namespace DysonNetwork.Sphere.Migrations
.HasColumnName("updated_at");
b.HasKey("Id")
.HasName("pk_message_reaction");
.HasName("pk_chat_reactions");
b.HasIndex("MessageId")
.HasDatabaseName("ix_message_reaction_message_id");
.HasDatabaseName("ix_chat_reactions_message_id");
b.HasIndex("SenderId")
.HasDatabaseName("ix_message_reaction_sender_id");
.HasDatabaseName("ix_chat_reactions_sender_id");
b.ToTable("message_reaction", (string)null);
b.ToTable("chat_reactions", (string)null);
});
modelBuilder.Entity("DysonNetwork.Sphere.Chat.MessageStatus", b =>
@ -2003,14 +2003,14 @@ namespace DysonNetwork.Sphere.Migrations
.HasForeignKey("MessageId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_message_reaction_chat_messages_message_id");
.HasConstraintName("fk_chat_reactions_chat_messages_message_id");
b.HasOne("DysonNetwork.Sphere.Chat.ChatMember", "Sender")
.WithMany()
.HasForeignKey("SenderId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_message_reaction_chat_members_sender_id");
.HasConstraintName("fk_chat_reactions_chat_members_sender_id");
b.Navigation("Message");

View File

@ -216,8 +216,8 @@ public class PostController(AppDatabase db, PostService ps, RelationshipService
[HttpPost("{id:long}/reactions")]
[Authorize]
[RequiredPermission("global", "posts.reactions.create")]
public async Task<ActionResult<PostReaction>> CreatePostReaction(long id, [FromBody] PostReactionRequest request)
[RequiredPermission("global", "posts.react")]
public async Task<ActionResult<PostReaction>> ReactPost(long id, [FromBody] PostReactionRequest request)
{
HttpContext.Items.TryGetValue("CurrentUser", out var currentUserValue);
if (currentUserValue is not Account.Account currentUser) return Unauthorized();
@ -241,9 +241,9 @@ public class PostController(AppDatabase db, PostService ps, RelationshipService
PostId = post.Id,
AccountId = currentUser.Id
};
await ps.ModifyPostVotes(post, reaction, isExistingReaction);
var isRemoving = await ps.ModifyPostVotes(post, reaction, isExistingReaction);
if (isExistingReaction) return NoContent();
if (isRemoving) return NoContent();
return Ok(reaction);
}

View File

@ -174,27 +174,39 @@ public class PostService(AppDatabase db, FileService fs, ActivityService act)
/// <param name="post">Post that modifying</param>
/// <param name="reaction">The new / target reaction adding / removing</param>
/// <param name="isRemoving">Indicate this operation is adding / removing</param>
public async Task ModifyPostVotes(Post post, PostReaction reaction, bool isRemoving)
public async Task<bool> ModifyPostVotes(Post post, PostReaction reaction, bool isRemoving)
{
var isExistingReaction = await db.Set<PostReaction>()
.AnyAsync(r => r.PostId == post.Id && r.AccountId == reaction.AccountId);
if (isExistingReaction) return;
if (!isRemoving)
if (isRemoving)
await db.PostReactions
.Where(r => r.PostId == post.Id && r.Symbol == reaction.Symbol && r.AccountId == reaction.AccountId)
.ExecuteDeleteAsync();
else
db.PostReactions.Add(reaction);
if (isExistingReaction)
{
db.Add(reaction);
switch (reaction.Attitude)
{
case PostReactionAttitude.Positive:
post.Upvotes++;
break;
case PostReactionAttitude.Negative:
post.Downvotes++;
break;
}
if (!isRemoving)
await db.SaveChangesAsync();
return isRemoving;
}
switch (reaction.Attitude)
{
case PostReactionAttitude.Positive:
if (isRemoving) post.Upvotes--;
else post.Upvotes++;
break;
case PostReactionAttitude.Negative:
if (isRemoving) post.Downvotes--;
else post.Downvotes++;
break;
}
await db.SaveChangesAsync();
return isRemoving;
}
public async Task<Dictionary<string, int>> GetPostReactionMap(long postId)