[backend/mastodon] Add filter support to GetUserStatusees (ISH-13)

This commit is contained in:
Laura Hausmann 2024-02-08 00:30:19 +01:00
parent 46820efbea
commit 48b78de6a3
No known key found for this signature in database
GPG key ID: D044E84C5BE01605
4 changed files with 49 additions and 10 deletions

View file

@ -1,3 +1,4 @@
using EntityFrameworkCore.Projectables;
using Iceshrimp.Backend.Controllers.Attributes;
using Iceshrimp.Backend.Controllers.Mastodon.Attributes;
using Iceshrimp.Backend.Controllers.Mastodon.Schemas;
@ -231,12 +232,15 @@ public class AccountController(
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IEnumerable<Status>))]
[ProducesResponseType(StatusCodes.Status401Unauthorized, Type = typeof(MastodonErrorResponse))]
[ProducesResponseType(StatusCodes.Status403Forbidden, Type = typeof(MastodonErrorResponse))]
public async Task<IActionResult> GetHomeTimeline(string id, PaginationQuery query) {
//TODO: there's a lot more query params to implement here
public async Task<IActionResult> GetUserStatuses(string id, AccountSchemas.AccountStatusesRequest request,
PaginationQuery query) {
var user = HttpContext.GetUserOrFail();
var account = await db.Users.FirstOrDefaultAsync(p => p.Id == id) ?? throw GracefulException.RecordNotFound();
var res = await db.Notes
.IncludeCommonProperties()
.FilterByUser(id)
.FilterByUser(account)
.FilterByAccountStatusesRequest(request, account)
.EnsureVisibleFor(user)
.Paginate(query, ControllerContext)
.PrecomputeVisibilities(user)

View file

@ -0,0 +1,13 @@
using Microsoft.AspNetCore.Mvc;
namespace Iceshrimp.Backend.Controllers.Mastodon.Schemas;
public abstract class AccountSchemas {
public class AccountStatusesRequest {
[FromQuery(Name = "only_media")] public bool OnlyMedia { get; set; } = false;
[FromQuery(Name = "exclude_replies")] public bool ExcludeReplies { get; set; } = false;
[FromQuery(Name = "exclude_reblogs")] public bool ExcludeRenotes { get; set; } = false;
[FromQuery(Name = "pinned")] public bool Pinned { get; set; } = false;
[FromQuery(Name = "tagged")] public string? Tagged { get; set; }
}
}

View file

@ -445,6 +445,8 @@ public class User : IEntity {
[InverseProperty(nameof(UserNotePin.User))]
public virtual ICollection<UserNotePin> UserNotePins { get; set; } = new List<UserNotePin>();
[Projectable] public virtual IEnumerable<Note> PinnedNotes => UserNotePins.Select(p => p.Note);
[InverseProperty(nameof(Tables.UserProfile.User))]
public virtual UserProfile? UserProfile { get; set; }
@ -506,6 +508,9 @@ public class User : IEntity {
[Projectable]
public bool IsMuting(User user) => Muting.Contains(user);
[Projectable]
public bool HasPinned(Note note) => PinnedNotes.Contains(note);
public User WithPrecomputedBlockStatus(bool blocking, bool blockedBy) {
PrecomputedIsBlocking = blocking;
PrecomputedIsBlockedBy = blockedBy;

View file

@ -151,4 +151,21 @@ public static class NoteQueryableExtensions {
var list = await users.ToListAsync();
return (await renderer.RenderManyAsync(list)).ToList();
}
public static IQueryable<Note> FilterByAccountStatusesRequest(this IQueryable<Note> query,
AccountSchemas.AccountStatusesRequest request,
User account) {
if (request.ExcludeReplies)
query = query.Where(p => p.Reply == null);
if (request.ExcludeRenotes)
query = query.Where(p => p.Renote == null);
if (request.Tagged != null)
query = query.Where(p => p.Tags.Contains(request.Tagged.ToLowerInvariant()));
if (request.OnlyMedia)
query = query.Where(p => p.FileIds.Count != 0);
if (request.Pinned)
query = query.Where(note => account.HasPinned(note));
return query;
}
}