✨ Filtered realm posts
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
using DysonNetwork.Shared.Proto;
|
using DysonNetwork.Shared.Proto;
|
||||||
using DysonNetwork.Sphere.Discovery;
|
using DysonNetwork.Sphere.Discovery;
|
||||||
using DysonNetwork.Sphere.Post;
|
using DysonNetwork.Sphere.Post;
|
||||||
|
using DysonNetwork.Sphere.Realm;
|
||||||
using DysonNetwork.Sphere.WebReader;
|
using DysonNetwork.Sphere.WebReader;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using NodaTime;
|
using NodaTime;
|
||||||
@@ -11,6 +12,7 @@ public class ActivityService(
|
|||||||
AppDatabase db,
|
AppDatabase db,
|
||||||
Publisher.PublisherService pub,
|
Publisher.PublisherService pub,
|
||||||
PostService ps,
|
PostService ps,
|
||||||
|
RealmService rs,
|
||||||
DiscoveryService ds,
|
DiscoveryService ds,
|
||||||
AccountService.AccountServiceClient accounts
|
AccountService.AccountServiceClient accounts
|
||||||
)
|
)
|
||||||
@@ -123,8 +125,10 @@ public class ActivityService(
|
|||||||
var filteredPublishers = await GetFilteredPublishers(filter, currentUser, userFriends);
|
var filteredPublishers = await GetFilteredPublishers(filter, currentUser, userFriends);
|
||||||
var filteredPublishersId = filteredPublishers?.Select(e => e.Id).ToList();
|
var filteredPublishersId = filteredPublishers?.Select(e => e.Id).ToList();
|
||||||
|
|
||||||
|
var userRealms = await rs.GetUserRealms(Guid.Parse(currentUser.Id));
|
||||||
|
|
||||||
// Build and execute the posts query
|
// Build and execute the posts query
|
||||||
var postsQuery = BuildPostsQuery(cursor, filteredPublishersId);
|
var postsQuery = BuildPostsQuery(cursor, filteredPublishersId, userRealms);
|
||||||
|
|
||||||
// Apply visibility filtering and execute
|
// Apply visibility filtering and execute
|
||||||
postsQuery = postsQuery
|
postsQuery = postsQuery
|
||||||
@@ -206,7 +210,8 @@ public class ActivityService(
|
|||||||
{
|
{
|
||||||
var popularPublishers = await GetPopularPublishers(count);
|
var popularPublishers = await GetPopularPublishers(count);
|
||||||
return popularPublishers.Count > 0
|
return popularPublishers.Count > 0
|
||||||
? new DiscoveryActivity(popularPublishers.Select(x => new DiscoveryItem("publisher", x)).ToList()).ToActivity()
|
? new DiscoveryActivity(popularPublishers.Select(x => new DiscoveryItem("publisher", x)).ToList())
|
||||||
|
.ToActivity()
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,7 +271,11 @@ public class ActivityService(
|
|||||||
return posts;
|
return posts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IQueryable<Post.Post> BuildPostsQuery(Instant? cursor, List<Guid>? filteredPublishersId = null)
|
private IQueryable<Post.Post> BuildPostsQuery(
|
||||||
|
Instant? cursor,
|
||||||
|
List<Guid>? filteredPublishersId = null,
|
||||||
|
List<Guid>? userRealms = null
|
||||||
|
)
|
||||||
{
|
{
|
||||||
var query = db.Posts
|
var query = db.Posts
|
||||||
.Include(e => e.RepliedPost)
|
.Include(e => e.RepliedPost)
|
||||||
@@ -280,9 +289,12 @@ public class ActivityService(
|
|||||||
.AsQueryable();
|
.AsQueryable();
|
||||||
|
|
||||||
if (filteredPublishersId != null && filteredPublishersId.Any())
|
if (filteredPublishersId != null && filteredPublishersId.Any())
|
||||||
{
|
|
||||||
query = query.Where(p => filteredPublishersId.Contains(p.PublisherId));
|
query = query.Where(p => filteredPublishersId.Contains(p.PublisherId));
|
||||||
}
|
if (userRealms == null)
|
||||||
|
query = query.Where(p => p.Realm == null || p.Realm.IsPublic);
|
||||||
|
else
|
||||||
|
query = query.Where(p =>
|
||||||
|
p.Realm == null || p.Realm.IsPublic || p.RealmId == null || userRealms.Contains(p.RealmId.Value));
|
||||||
|
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
@@ -98,7 +98,9 @@ public class PostController(
|
|||||||
userFriends = friendsResponse.AccountsId.Select(Guid.Parse).ToList();
|
userFriends = friendsResponse.AccountsId.Select(Guid.Parse).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
var userPublishers = currentUser is null ? [] : await pub.GetUserPublishers(Guid.Parse(currentUser.Id));
|
var accountId = currentUser is null ? Guid.Empty : Guid.Parse(currentUser.Id);
|
||||||
|
var userPublishers = currentUser is null ? [] : await pub.GetUserPublishers(accountId);
|
||||||
|
var userRealms = currentUser is null ? [] : await rs.GetUserRealms(accountId);
|
||||||
|
|
||||||
var publisher = pubName == null ? null : await db.Publishers.FirstOrDefaultAsync(p => p.Name == pubName);
|
var publisher = pubName == null ? null : await db.Publishers.FirstOrDefaultAsync(p => p.Name == pubName);
|
||||||
var realm = realmName == null ? null : await db.Realms.FirstOrDefaultAsync(r => r.Slug == realmName);
|
var realm = realmName == null ? null : await db.Realms.FirstOrDefaultAsync(r => r.Slug == realmName);
|
||||||
@@ -106,6 +108,9 @@ public class PostController(
|
|||||||
var query = db.Posts
|
var query = db.Posts
|
||||||
.Include(e => e.Categories)
|
.Include(e => e.Categories)
|
||||||
.Include(e => e.Tags)
|
.Include(e => e.Tags)
|
||||||
|
.Include(e => e.RepliedPost)
|
||||||
|
.Include(e => e.ForwardedPost)
|
||||||
|
.Include(e => e.Realm)
|
||||||
.AsQueryable();
|
.AsQueryable();
|
||||||
if (publisher != null)
|
if (publisher != null)
|
||||||
query = query.Where(p => p.PublisherId == publisher.Id);
|
query = query.Where(p => p.PublisherId == publisher.Id);
|
||||||
@@ -120,6 +125,9 @@ public class PostController(
|
|||||||
if (onlyMedia)
|
if (onlyMedia)
|
||||||
query = query.Where(e => e.Attachments.Count > 0);
|
query = query.Where(e => e.Attachments.Count > 0);
|
||||||
|
|
||||||
|
if (realm == null)
|
||||||
|
query = query.Where(p => p.RealmId == null || p.Realm == null || userRealms.Contains(p.RealmId.Value) || p.Realm.IsPublic);
|
||||||
|
|
||||||
switch (pinned)
|
switch (pinned)
|
||||||
{
|
{
|
||||||
case true when realm != null:
|
case true when realm != null:
|
||||||
@@ -166,9 +174,6 @@ public class PostController(
|
|||||||
: query.OrderByDescending(e => e.PublishedAt ?? e.CreatedAt);
|
: query.OrderByDescending(e => e.PublishedAt ?? e.CreatedAt);
|
||||||
|
|
||||||
var posts = await query
|
var posts = await query
|
||||||
.Include(e => e.RepliedPost)
|
|
||||||
.Include(e => e.ForwardedPost)
|
|
||||||
.Include(e => e.Realm)
|
|
||||||
.Skip(offset)
|
.Skip(offset)
|
||||||
.Take(take)
|
.Take(take)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
using DysonNetwork.Shared;
|
using DysonNetwork.Shared;
|
||||||
|
using DysonNetwork.Shared.Cache;
|
||||||
using DysonNetwork.Shared.Proto;
|
using DysonNetwork.Shared.Proto;
|
||||||
using DysonNetwork.Shared.Registry;
|
using DysonNetwork.Shared.Registry;
|
||||||
using DysonNetwork.Sphere.Localization;
|
using DysonNetwork.Sphere.Localization;
|
||||||
@@ -12,9 +13,31 @@ public class RealmService(
|
|||||||
PusherService.PusherServiceClient pusher,
|
PusherService.PusherServiceClient pusher,
|
||||||
AccountService.AccountServiceClient accounts,
|
AccountService.AccountServiceClient accounts,
|
||||||
IStringLocalizer<NotificationResource> localizer,
|
IStringLocalizer<NotificationResource> localizer,
|
||||||
AccountClientHelper accountsHelper
|
AccountClientHelper accountsHelper,
|
||||||
|
ICacheService cache
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
private const string CacheKeyPrefix = "account:realms:";
|
||||||
|
|
||||||
|
public async Task<List<Guid>> GetUserRealms(Guid accountId)
|
||||||
|
{
|
||||||
|
var cacheKey = $"{CacheKeyPrefix}{accountId}";
|
||||||
|
var (found, cachedRealms) = await cache.GetAsyncWithStatus<List<Guid>>(cacheKey);
|
||||||
|
if (found && cachedRealms != null)
|
||||||
|
return cachedRealms;
|
||||||
|
|
||||||
|
var realms = await db.RealmMembers
|
||||||
|
.Include(m => m.Realm)
|
||||||
|
.Where(m => m.AccountId == accountId)
|
||||||
|
.Select(m => m.Realm!.Id)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
// Cache the result for 5 minutes
|
||||||
|
await cache.SetAsync(cacheKey, realms, TimeSpan.FromMinutes(5));
|
||||||
|
|
||||||
|
return realms;
|
||||||
|
}
|
||||||
|
|
||||||
public async Task SendInviteNotify(RealmMember member)
|
public async Task SendInviteNotify(RealmMember member)
|
||||||
{
|
{
|
||||||
var account = await accounts.GetAccountAsync(new GetAccountRequest { Id = member.AccountId.ToString() });
|
var account = await accounts.GetAccountAsync(new GetAccountRequest { Id = member.AccountId.ToString() });
|
||||||
|
Reference in New Issue
Block a user