[backend/masto-client] Paginate likes & bookmarks based on their identifier (instead of the note identifier)

This commit is contained in:
Laura Hausmann 2024-06-15 15:41:05 +02:00
parent 9f3bbe6c08
commit 8b36f1aecf
No known key found for this signature in database
GPG key ID: D044E84C5BE01605
3 changed files with 49 additions and 14 deletions

View file

@ -504,13 +504,18 @@ public class AccountController(
public async Task<IActionResult> GetLikedNotes(MastodonPaginationQuery query) public async Task<IActionResult> GetLikedNotes(MastodonPaginationQuery query)
{ {
var user = HttpContext.GetUserOrFail(); var user = HttpContext.GetUserOrFail();
var res = await db.Notes var likes = await db.NoteLikes
.Where(p => db.Users.First(u => u == user).HasLiked(p)) .Where(p => p.User == user)
.IncludeCommonProperties() .IncludeCommonProperties()
.Paginate(query, ControllerContext) .Select(p => new EntityWrapper<Note>
.PrecomputeVisibilities(user) {
.RenderAllForMastodonAsync(noteRenderer, user); Id = p.Id, Entity = p.Note.WithPrecomputedVisibilities(user)
})
.Paginate(query, ControllerContext)
.ToListAsync();
HttpContext.SetPaginationData(likes);
var res = await noteRenderer.RenderManyAsync(likes.Select(p => p.Entity).EnforceRenoteReplyVisibility(), user);
return Ok(res); return Ok(res);
} }
@ -522,13 +527,19 @@ public class AccountController(
public async Task<IActionResult> GetBookmarkedNotes(MastodonPaginationQuery query) public async Task<IActionResult> GetBookmarkedNotes(MastodonPaginationQuery query)
{ {
var user = HttpContext.GetUserOrFail(); var user = HttpContext.GetUserOrFail();
var res = await db.Notes var bookmarks = await db.NoteBookmarks
.Where(p => db.Users.First(u => u == user).HasBookmarked(p)) .Where(p => p.User == user)
.IncludeCommonProperties() .IncludeCommonProperties()
.Paginate(query, ControllerContext) .Select(p => new EntityWrapper<Note>
.PrecomputeVisibilities(user) {
.RenderAllForMastodonAsync(noteRenderer, user); Id = p.Id, Entity = p.Note.WithPrecomputedVisibilities(user)
})
.Paginate(query, ControllerContext)
.ToListAsync();
HttpContext.SetPaginationData(bookmarks);
var res =
await noteRenderer.RenderManyAsync(bookmarks.Select(p => p.Entity).EnforceRenoteReplyVisibility(), user);
return Ok(res); return Ok(res);
} }

View file

@ -329,6 +329,14 @@ public class Note : IEntity
return this; return this;
} }
[Projectable]
[SuppressMessage("ReSharper", "MergeIntoPattern", Justification = "Projectables")]
[SuppressMessage("ReSharper", "MergeSequentialChecks", Justification = "Projectables")]
public Note WithPrecomputedVisibilities(User user)
=> WithPrecomputedVisibilities(Reply != null && Reply.IsVisibleFor(user),
Renote != null && Renote.IsVisibleFor(user),
Renote != null && Renote.Renote != null && Renote.Renote.IsVisibleFor(user));
public string GetPublicUri(Config.InstanceSection config) => UserHost == null public string GetPublicUri(Config.InstanceSection config) => UserHost == null
? $"https://{config.WebDomain}/notes/{Id}" ? $"https://{config.WebDomain}/notes/{Id}"
: throw new Exception("Cannot access PublicUri for remote note"); : throw new Exception("Cannot access PublicUri for remote note");

View file

@ -643,6 +643,22 @@ public static class QueryableExtensions
.Include(p => p.Followee.UserProfile); .Include(p => p.Followee.UserProfile);
} }
public static IQueryable<NoteLike> IncludeCommonProperties(this IQueryable<NoteLike> query)
{
return query.Include(p => p.Note.User.UserProfile)
.Include(p => p.Note.Renote.User.UserProfile)
.Include(p => p.Note.Renote.Renote.User.UserProfile)
.Include(p => p.Note.Reply.User.UserProfile);
}
public static IQueryable<NoteBookmark> IncludeCommonProperties(this IQueryable<NoteBookmark> query)
{
return query.Include(p => p.Note.User.UserProfile)
.Include(p => p.Note.Renote.User.UserProfile)
.Include(p => p.Note.Renote.Renote.User.UserProfile)
.Include(p => p.Note.Reply.User.UserProfile);
}
public static IQueryable<Notification> IncludeCommonProperties(this IQueryable<Notification> query) public static IQueryable<Notification> IncludeCommonProperties(this IQueryable<Notification> query)
{ {
return query.Include(p => p.Notifiee.UserProfile) return query.Include(p => p.Notifiee.UserProfile)