[backend/database] Add generic versions of EnsureNoteVisibilityFor & FilterBlocked
This commit is contained in:
parent
340ca21629
commit
85073fc871
2 changed files with 61 additions and 4 deletions
27
Iceshrimp.Backend/Core/Extensions/ExpressionExtensions.cs
Normal file
27
Iceshrimp.Backend/Core/Extensions/ExpressionExtensions.cs
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
|
||||||
|
namespace Iceshrimp.Backend.Core.Extensions;
|
||||||
|
|
||||||
|
public static class ExpressionExtensions {
|
||||||
|
public static Expression<Func<TFirstParam, TResult>> Compose<TFirstParam, TIntermediate, TResult>(
|
||||||
|
this Expression<Func<TFirstParam, TIntermediate>> first,
|
||||||
|
Expression<Func<TIntermediate, TResult>> second
|
||||||
|
) {
|
||||||
|
var param = Expression.Parameter(typeof(TFirstParam), "param");
|
||||||
|
|
||||||
|
var newFirst = first.Body.Replace(first.Parameters[0], param);
|
||||||
|
var newSecond = second.Body.Replace(second.Parameters[0], newFirst);
|
||||||
|
|
||||||
|
return Expression.Lambda<Func<TFirstParam, TResult>>(newSecond, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Expression Replace(this Expression expression, Expression searchEx, Expression replaceEx) {
|
||||||
|
return new ReplaceVisitor(searchEx, replaceEx).Visit(expression) ?? throw new NullReferenceException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ReplaceVisitor(Expression from, Expression to) : ExpressionVisitor {
|
||||||
|
public override Expression? Visit(Expression? node) {
|
||||||
|
return node == from ? to : base.Visit(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
using System.Linq.Expressions;
|
||||||
using Iceshrimp.Backend.Controllers.Attributes;
|
using Iceshrimp.Backend.Controllers.Attributes;
|
||||||
using Iceshrimp.Backend.Controllers.Mastodon.Renderers;
|
using Iceshrimp.Backend.Controllers.Mastodon.Renderers;
|
||||||
using Iceshrimp.Backend.Controllers.Mastodon.Schemas;
|
using Iceshrimp.Backend.Controllers.Mastodon.Schemas;
|
||||||
|
@ -100,11 +101,17 @@ public static class QueryableExtensions {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IQueryable<Note> EnsureVisibleFor(this IQueryable<Note> query, User? user) {
|
public static IQueryable<Note> EnsureVisibleFor(this IQueryable<Note> query, User? user) {
|
||||||
if (user == null)
|
return user == null
|
||||||
return query.Where(note => note.VisibilityIsPublicOrHome)
|
? query.Where(note => note.VisibilityIsPublicOrHome && !note.LocalOnly)
|
||||||
.Where(note => !note.LocalOnly);
|
: query.Where(note => note.IsVisibleFor(user));
|
||||||
|
}
|
||||||
|
|
||||||
return query.Where(note => note.IsVisibleFor(user));
|
public static IQueryable<TSource> EnsureNoteVisibilityFor<TSource>(
|
||||||
|
this IQueryable<TSource> query, Expression<Func<TSource, Note?>> predicate, User? user
|
||||||
|
) {
|
||||||
|
return query.Where(user == null
|
||||||
|
? predicate.Compose(p => p == null || (p.VisibilityIsPublicOrHome && !p.LocalOnly))
|
||||||
|
: predicate.Compose(p => p == null || p.IsVisibleFor(user)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IQueryable<Note> PrecomputeVisibilities(this IQueryable<Note> query, User? user) {
|
public static IQueryable<Note> PrecomputeVisibilities(this IQueryable<Note> query, User? user) {
|
||||||
|
@ -128,6 +135,29 @@ public static class QueryableExtensions {
|
||||||
(!note.Reply.User.IsBlockedBy(user) && !note.Reply.User.IsBlocking(user)));
|
(!note.Reply.User.IsBlockedBy(user) && !note.Reply.User.IsBlocking(user)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IQueryable<TSource> FilterBlocked<TSource>(
|
||||||
|
this IQueryable<TSource> query, Expression<Func<TSource, User?>> predicate, User? user
|
||||||
|
) {
|
||||||
|
return user == null ? query : query.Where(predicate.Compose(p => p == null || !p.IsBlocking(user)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IQueryable<TSource> FilterBlocked<TSource>(
|
||||||
|
this IQueryable<TSource> query, Expression<Func<TSource, Note?>> predicate, User? user
|
||||||
|
) {
|
||||||
|
if (user == null)
|
||||||
|
return query;
|
||||||
|
|
||||||
|
return query.Where(predicate.Compose(note => note == null ||
|
||||||
|
(!note.User.IsBlocking(user) &&
|
||||||
|
!note.User.IsBlockedBy(user) &&
|
||||||
|
(note.Renote == null ||
|
||||||
|
(!note.Renote.User.IsBlockedBy(user) &&
|
||||||
|
!note.Renote.User.IsBlocking(user))) &&
|
||||||
|
(note.Reply == null ||
|
||||||
|
(!note.Reply.User.IsBlockedBy(user) &&
|
||||||
|
!note.Reply.User.IsBlocking(user))))));
|
||||||
|
}
|
||||||
|
|
||||||
public static IQueryable<Note> FilterMuted(this IQueryable<Note> query, User user) {
|
public static IQueryable<Note> FilterMuted(this IQueryable<Note> query, User user) {
|
||||||
//TODO: handle muted instances
|
//TODO: handle muted instances
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue