[backend/core] Denormalize like counts (ISH-110)
This commit is contained in:
parent
fe06c64242
commit
e42812d2b0
9 changed files with 6228 additions and 21 deletions
|
@ -33,8 +33,6 @@ public class NoteRenderer(
|
|||
text += $"\n\nRE: {quoteUri}"; //TODO: render as inline quote
|
||||
}
|
||||
|
||||
var likeCount = data?.LikeCounts?.GetValueOrDefault(note.Id, 0) ??
|
||||
await db.NoteLikes.CountAsync(p => p.Note == note);
|
||||
var liked = data?.LikedNotes?.Contains(note.Id) ??
|
||||
await db.NoteLikes.AnyAsync(p => p.Note == note && p.User == user);
|
||||
var renoted = data?.Renotes?.Contains(note.Id) ??
|
||||
|
@ -82,7 +80,7 @@ public class NoteRenderer(
|
|||
EditedAt = note.UpdatedAt?.ToStringIso8601Like(),
|
||||
RepliesCount = note.RepliesCount,
|
||||
RenoteCount = note.RenoteCount,
|
||||
FavoriteCount = likeCount,
|
||||
FavoriteCount = note.LikeCount,
|
||||
IsFavorited = liked,
|
||||
IsRenoted = renoted,
|
||||
IsBookmarked = false, //FIXME
|
||||
|
@ -133,14 +131,6 @@ public class NoteRenderer(
|
|||
return (await userRenderer.RenderManyAsync(users.DistinctBy(p => p.Id))).ToList();
|
||||
}
|
||||
|
||||
private async Task<Dictionary<string, int>> GetLikeCounts(IEnumerable<Note> notes)
|
||||
{
|
||||
return await db.NoteLikes.Where(p => notes.Contains(p.Note))
|
||||
.Select(p => p.NoteId)
|
||||
.GroupBy(p => p)
|
||||
.ToDictionaryAsync(p => p.First(), p => p.Count());
|
||||
}
|
||||
|
||||
private async Task<List<string>> GetLikedNotes(IEnumerable<Note> notes, User? user)
|
||||
{
|
||||
if (user == null) return [];
|
||||
|
@ -193,7 +183,6 @@ public class NoteRenderer(
|
|||
Accounts = accounts ?? await GetAccounts(noteList.Select(p => p.User)),
|
||||
Mentions = await GetMentions(noteList),
|
||||
Attachments = await GetAttachments(noteList),
|
||||
LikeCounts = await GetLikeCounts(noteList),
|
||||
LikedNotes = await GetLikedNotes(noteList, user),
|
||||
Renotes = await GetRenotes(noteList, user),
|
||||
Emoji = await GetEmoji(noteList)
|
||||
|
@ -204,13 +193,12 @@ public class NoteRenderer(
|
|||
|
||||
public class NoteRendererDto
|
||||
{
|
||||
public List<AccountEntity>? Accounts;
|
||||
public List<MentionEntity>? Mentions;
|
||||
public List<AttachmentEntity>? Attachments;
|
||||
public Dictionary<string, int>? LikeCounts;
|
||||
public List<string>? LikedNotes;
|
||||
public List<string>? Renotes;
|
||||
public List<EmojiEntity>? Emoji;
|
||||
public bool Source;
|
||||
public List<AccountEntity>? Accounts;
|
||||
public List<MentionEntity>? Mentions;
|
||||
public List<AttachmentEntity>? Attachments;
|
||||
public List<string>? LikedNotes;
|
||||
public List<string>? Renotes;
|
||||
public List<EmojiEntity>? Emoji;
|
||||
public bool Source;
|
||||
}
|
||||
}
|
|
@ -96,6 +96,7 @@ public class StatusController(
|
|||
throw GracefulException.RecordNotFound();
|
||||
|
||||
await noteSvc.LikeNoteAsync(note, user);
|
||||
note.LikeCount++; // we do not want to call save changes after this point
|
||||
return await GetNote(id);
|
||||
}
|
||||
|
||||
|
@ -113,6 +114,7 @@ public class StatusController(
|
|||
throw GracefulException.RecordNotFound();
|
||||
|
||||
await noteSvc.UnlikeNoteAsync(note, user);
|
||||
note.LikeCount--; // we do not want to call save changes after this point
|
||||
return await GetNote(id);
|
||||
}
|
||||
|
||||
|
|
|
@ -609,6 +609,7 @@ public class DatabaseContext(DbContextOptions<DatabaseContext> options)
|
|||
entity.Property(e => e.Emojis).HasDefaultValueSql("'{}'::character varying[]");
|
||||
entity.Property(e => e.FileIds).HasDefaultValueSql("'{}'::character varying[]");
|
||||
entity.Property(e => e.HasPoll).HasDefaultValue(false);
|
||||
entity.Property(e => e.LikeCount).HasDefaultValue(0);
|
||||
entity.Property(e => e.LocalOnly).HasDefaultValue(false);
|
||||
entity.Property(e => e.MentionedRemoteUsers).HasDefaultValueSql("'[]'::jsonb");
|
||||
entity.Property(e => e.Mentions).HasDefaultValueSql("'{}'::character varying[]");
|
||||
|
|
6170
Iceshrimp.Backend/Core/Database/Migrations/20240304013243_AddNoteLikeCountColumn.Designer.cs
generated
Normal file
6170
Iceshrimp.Backend/Core/Database/Migrations/20240304013243_AddNoteLikeCountColumn.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,29 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Iceshrimp.Backend.Core.Database.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddNoteLikeCountColumn : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "likeCount",
|
||||
table: "note",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "likeCount",
|
||||
table: "note");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2457,6 +2457,12 @@ namespace Iceshrimp.Backend.Core.Database.Migrations
|
|||
.HasDefaultValue(false)
|
||||
.HasColumnName("hasPoll");
|
||||
|
||||
b.Property<int>("LikeCount")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
.HasDefaultValue(0)
|
||||
.HasColumnName("likeCount");
|
||||
|
||||
b.Property<bool>("LocalOnly")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("boolean")
|
||||
|
|
|
@ -86,6 +86,8 @@ public class Note : IEntity
|
|||
|
||||
[Column("repliesCount")] public short RepliesCount { get; set; }
|
||||
|
||||
[Column("likeCount")] public int LikeCount { get; set; }
|
||||
|
||||
[Column("reactions", TypeName = "jsonb")]
|
||||
public Dictionary<string, long> Reactions { get; set; } = null!;
|
||||
|
||||
|
|
|
@ -10,7 +10,9 @@ public class DatabaseMaintenanceService(DatabaseContext db)
|
|||
await db.Notes.ExecuteUpdateAsync(p => p.SetProperty(n => n.RenoteCount,
|
||||
n => db.Notes.Count(r => r.IsPureRenote && r.Renote == n))
|
||||
.SetProperty(n => n.RepliesCount,
|
||||
n => db.Notes.Count(r => r.Reply == n)));
|
||||
n => db.Notes.Count(r => r.Reply == n))
|
||||
.SetProperty(n => n.LikeCount,
|
||||
n => db.NoteLikes.Count(r => r.Note == n)));
|
||||
//TODO: update reaction counts as well? (can likely not be done database-side :/)
|
||||
}
|
||||
|
||||
|
|
|
@ -727,6 +727,9 @@ public class NoteService(
|
|||
|
||||
await db.NoteLikes.AddAsync(like);
|
||||
await db.SaveChangesAsync();
|
||||
await db.Notes.Where(p => p.Id == note.Id)
|
||||
.ExecuteUpdateAsync(p => p.SetProperty(n => n.LikeCount, n => n.LikeCount + 1));
|
||||
|
||||
if (user.Host == null && note.UserHost != null)
|
||||
{
|
||||
var activity = activityRenderer.RenderLike(note, user);
|
||||
|
@ -742,6 +745,10 @@ public class NoteService(
|
|||
{
|
||||
var count = await db.NoteLikes.Where(p => p.Note == note && p.User == actor).ExecuteDeleteAsync();
|
||||
if (count == 0) return;
|
||||
|
||||
await db.Notes.Where(p => p.Id == note.Id)
|
||||
.ExecuteUpdateAsync(p => p.SetProperty(n => n.LikeCount, n => n.LikeCount - count));
|
||||
|
||||
if (actor.Host == null && note.UserHost != null)
|
||||
{
|
||||
var activity = activityRenderer.RenderUndo(userRenderer.RenderLite(actor),
|
||||
|
|
Loading…
Add table
Reference in a new issue