🐛 Fix some issues in moving realm service
This commit is contained in:
@@ -35,6 +35,15 @@ public class RealmServiceGrpc(
|
|||||||
: realm.ToProtoValue();
|
: realm.ToProtoValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override async Task<GetRealmBatchResponse> GetRealmBatch(GetRealmBatchRequest request, ServerCallContext context)
|
||||||
|
{
|
||||||
|
var ids = request.Ids.Select(Guid.Parse).ToList();
|
||||||
|
var realms = await db.Realms.Where(r => ids.Contains(r.Id)).ToListAsync();
|
||||||
|
var response = new GetRealmBatchResponse();
|
||||||
|
response.Realms.AddRange(realms.Select(r => r.ToProtoValue()));
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
public override async Task<GetUserRealmsResponse> GetUserRealms(GetUserRealmsRequest request,
|
public override async Task<GetUserRealmsResponse> GetUserRealms(GetUserRealmsRequest request,
|
||||||
ServerCallContext context)
|
ServerCallContext context)
|
||||||
{
|
{
|
||||||
@@ -48,6 +57,7 @@ public class RealmServiceGrpc(
|
|||||||
.Include(m => m.Realm)
|
.Include(m => m.Realm)
|
||||||
.Where(m => m.AccountId == accountId)
|
.Where(m => m.AccountId == accountId)
|
||||||
.Where(m => m.JoinedAt != null && m.LeaveAt == null)
|
.Where(m => m.JoinedAt != null && m.LeaveAt == null)
|
||||||
|
.Where(m => m.Realm != null)
|
||||||
.Select(m => m.Realm!.Id)
|
.Select(m => m.Realm!.Id)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
@@ -57,6 +67,14 @@ public class RealmServiceGrpc(
|
|||||||
return new GetUserRealmsResponse { RealmIds = { realms.Select(g => g.ToString()) } };
|
return new GetUserRealmsResponse { RealmIds = { realms.Select(g => g.ToString()) } };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override async Task<GetPublicRealmsResponse> GetPublicRealms(Empty request, ServerCallContext context)
|
||||||
|
{
|
||||||
|
var realms = await db.Realms.Where(r => r.IsPublic).ToListAsync();
|
||||||
|
var response = new GetPublicRealmsResponse();
|
||||||
|
response.Realms.AddRange(realms.Select(r => r.ToProtoValue()));
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
public override async Task<Empty> SendInviteNotify(SendInviteNotifyRequest request, ServerCallContext context)
|
public override async Task<Empty> SendInviteNotify(SendInviteNotifyRequest request, ServerCallContext context)
|
||||||
{
|
{
|
||||||
var member = request.Member;
|
var member = request.Member;
|
||||||
|
|||||||
@@ -32,8 +32,12 @@ message RealmMember {
|
|||||||
service RealmService {
|
service RealmService {
|
||||||
// Get realm by id or slug
|
// Get realm by id or slug
|
||||||
rpc GetRealm(GetRealmRequest) returns (Realm) {}
|
rpc GetRealm(GetRealmRequest) returns (Realm) {}
|
||||||
|
// Get realm batch by ids
|
||||||
|
rpc GetRealmBatch(GetRealmBatchRequest) returns (GetRealmBatchResponse) {}
|
||||||
// Get realms for a user
|
// Get realms for a user
|
||||||
rpc GetUserRealms(GetUserRealmsRequest) returns (GetUserRealmsResponse) {}
|
rpc GetUserRealms(GetUserRealmsRequest) returns (GetUserRealmsResponse) {}
|
||||||
|
// Get public realms
|
||||||
|
rpc GetPublicRealms(google.protobuf.Empty) returns (GetPublicRealmsResponse) {}
|
||||||
// Send invitation notification
|
// Send invitation notification
|
||||||
rpc SendInviteNotify(SendInviteNotifyRequest) returns (google.protobuf.Empty) {}
|
rpc SendInviteNotify(SendInviteNotifyRequest) returns (google.protobuf.Empty) {}
|
||||||
// Check if member has required role
|
// Check if member has required role
|
||||||
@@ -57,10 +61,22 @@ message GetUserRealmsRequest {
|
|||||||
string account_id = 1;
|
string account_id = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message GetRealmBatchRequest {
|
||||||
|
repeated string ids = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetRealmBatchResponse {
|
||||||
|
repeated Realm realms = 1;
|
||||||
|
}
|
||||||
|
|
||||||
message GetUserRealmsResponse {
|
message GetUserRealmsResponse {
|
||||||
repeated string realm_ids = 1;
|
repeated string realm_ids = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message GetPublicRealmsResponse {
|
||||||
|
repeated Realm realms = 1;
|
||||||
|
}
|
||||||
|
|
||||||
message SendInviteNotifyRequest {
|
message SendInviteNotifyRequest {
|
||||||
RealmMember member = 1;
|
RealmMember member = 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using DysonNetwork.Shared.Models;
|
using DysonNetwork.Shared.Models;
|
||||||
using DysonNetwork.Shared.Proto;
|
using DysonNetwork.Shared.Proto;
|
||||||
|
using Google.Protobuf.WellKnownTypes;
|
||||||
|
|
||||||
namespace DysonNetwork.Shared.Registry;
|
namespace DysonNetwork.Shared.Registry;
|
||||||
|
|
||||||
@@ -26,6 +27,20 @@ public class RemoteRealmService(RealmService.RealmServiceClient realms)
|
|||||||
return response.RealmIds.Select(Guid.Parse).ToList();
|
return response.RealmIds.Select(Guid.Parse).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<List<SnRealm>> GetPublicRealms()
|
||||||
|
{
|
||||||
|
var response = await realms.GetPublicRealmsAsync(new Empty());
|
||||||
|
return response.Realms.Select(SnRealm.FromProtoValue).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<SnRealm>> GetRealmBatch(List<string> ids)
|
||||||
|
{
|
||||||
|
var request = new GetRealmBatchRequest();
|
||||||
|
request.Ids.AddRange(ids);
|
||||||
|
var response = await realms.GetRealmBatchAsync(request);
|
||||||
|
return response.Realms.Select(SnRealm.FromProtoValue).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
public async Task SendInviteNotify(SnRealmMember member)
|
public async Task SendInviteNotify(SnRealmMember member)
|
||||||
{
|
{
|
||||||
var protoMember = member.ToProtoValue();
|
var protoMember = member.ToProtoValue();
|
||||||
|
|||||||
@@ -40,19 +40,23 @@ public class ActivityService(
|
|||||||
debugInclude ??= new HashSet<string>();
|
debugInclude ??= new HashSet<string>();
|
||||||
|
|
||||||
// Get and process posts
|
// Get and process posts
|
||||||
|
var publicRealms = await rs.GetPublicRealms();
|
||||||
|
var publicRealmIds = publicRealms.Select(r => r.Id).ToList();
|
||||||
|
|
||||||
var postsQuery = db.Posts
|
var postsQuery = db.Posts
|
||||||
.Include(e => e.RepliedPost)
|
.Include(e => e.RepliedPost)
|
||||||
.Include(e => e.ForwardedPost)
|
.Include(e => e.ForwardedPost)
|
||||||
.Include(e => e.Categories)
|
.Include(e => e.Categories)
|
||||||
.Include(e => e.Tags)
|
.Include(e => e.Tags)
|
||||||
.Include(e => e.Realm)
|
|
||||||
.Where(e => e.RepliedPostId == null)
|
.Where(e => e.RepliedPostId == null)
|
||||||
.Where(p => cursor == null || p.PublishedAt < cursor)
|
.Where(p => cursor == null || p.PublishedAt < cursor)
|
||||||
|
.Where(p => p.RealmId == null || publicRealmIds.Contains(p.RealmId.Value))
|
||||||
.OrderByDescending(p => p.PublishedAt)
|
.OrderByDescending(p => p.PublishedAt)
|
||||||
.FilterWithVisibility(null, [], [], isListing: true)
|
.FilterWithVisibility(null, [], [], isListing: true)
|
||||||
.Take(take * 5);
|
.Take(take * 5);
|
||||||
|
|
||||||
var posts = await GetAndProcessPosts(postsQuery);
|
var posts = await GetAndProcessPosts(postsQuery);
|
||||||
|
await LoadPostsRealmsAsync(posts, rs);
|
||||||
posts = RankPosts(posts, take);
|
posts = RankPosts(posts, take);
|
||||||
|
|
||||||
var interleaved = new List<SnActivity>();
|
var interleaved = new List<SnActivity>();
|
||||||
@@ -122,6 +126,9 @@ public class ActivityService(
|
|||||||
userPublishers,
|
userPublishers,
|
||||||
trackViews: true);
|
trackViews: true);
|
||||||
|
|
||||||
|
if (currentUser != null)
|
||||||
|
await LoadPostsRealmsAsync(posts, rs);
|
||||||
|
|
||||||
posts = RankPosts(posts, take);
|
posts = RankPosts(posts, take);
|
||||||
|
|
||||||
var interleaved = new List<SnActivity>();
|
var interleaved = new List<SnActivity>();
|
||||||
@@ -219,15 +226,19 @@ public class ActivityService(
|
|||||||
|
|
||||||
private async Task<SnActivity?> GetShuffledPostsActivity(int count = 5)
|
private async Task<SnActivity?> GetShuffledPostsActivity(int count = 5)
|
||||||
{
|
{
|
||||||
|
var publicRealms = await rs.GetPublicRealms();
|
||||||
|
var publicRealmIds = publicRealms.Select(r => r.Id).ToList();
|
||||||
|
|
||||||
var postsQuery = db.Posts
|
var postsQuery = db.Posts
|
||||||
.Include(p => p.Categories)
|
.Include(p => p.Categories)
|
||||||
.Include(p => p.Tags)
|
.Include(p => p.Tags)
|
||||||
.Include(p => p.Realm)
|
|
||||||
.Where(p => p.RepliedPostId == null)
|
.Where(p => p.RepliedPostId == null)
|
||||||
|
.Where(p => p.RealmId == null || publicRealmIds.Contains(p.RealmId.Value))
|
||||||
.OrderBy(_ => EF.Functions.Random())
|
.OrderBy(_ => EF.Functions.Random())
|
||||||
.Take(count);
|
.Take(count);
|
||||||
|
|
||||||
var posts = await GetAndProcessPosts(postsQuery, trackViews: false);
|
var posts = await GetAndProcessPosts(postsQuery, trackViews: false);
|
||||||
|
await LoadPostsRealmsAsync(posts, rs);
|
||||||
|
|
||||||
return posts.Count == 0
|
return posts.Count == 0
|
||||||
? null
|
? null
|
||||||
@@ -306,7 +317,6 @@ public class ActivityService(
|
|||||||
.Include(e => e.ForwardedPost)
|
.Include(e => e.ForwardedPost)
|
||||||
.Include(e => e.Categories)
|
.Include(e => e.Categories)
|
||||||
.Include(e => e.Tags)
|
.Include(e => e.Tags)
|
||||||
.Include(e => e.Realm)
|
|
||||||
.Where(e => e.RepliedPostId == null)
|
.Where(e => e.RepliedPostId == null)
|
||||||
.Where(p => cursor == null || p.PublishedAt < cursor)
|
.Where(p => cursor == null || p.PublishedAt < cursor)
|
||||||
.OrderByDescending(p => p.PublishedAt)
|
.OrderByDescending(p => p.PublishedAt)
|
||||||
@@ -315,10 +325,14 @@ public class ActivityService(
|
|||||||
if (filteredPublishersId != null && filteredPublishersId.Count != 0)
|
if (filteredPublishersId != null && filteredPublishersId.Count != 0)
|
||||||
query = query.Where(p => filteredPublishersId.Contains(p.PublisherId));
|
query = query.Where(p => filteredPublishersId.Contains(p.PublisherId));
|
||||||
if (userRealms == null)
|
if (userRealms == null)
|
||||||
query = query.Where(p => p.Realm == null || p.Realm.IsPublic);
|
{
|
||||||
|
// For anonymous users, only show public realm posts or posts without realm
|
||||||
|
// Get public realm ids in the caller and pass them
|
||||||
|
query = query.Where(p => p.RealmId == null); // Modify in caller
|
||||||
|
}
|
||||||
else
|
else
|
||||||
query = query.Where(p =>
|
query = query.Where(p =>
|
||||||
p.Realm == null || p.Realm.IsPublic || p.RealmId == null || userRealms.Contains(p.RealmId.Value));
|
p.RealmId == null || userRealms.Contains(p.RealmId.Value));
|
||||||
|
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
@@ -339,6 +353,23 @@ public class ActivityService(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static async Task LoadPostsRealmsAsync(List<SnPost> posts, RemoteRealmService rs)
|
||||||
|
{
|
||||||
|
var postRealmIds = posts.Where(p => p.RealmId != null).Select(p => p.RealmId.Value).Distinct().ToList();
|
||||||
|
if (!postRealmIds.Any()) return;
|
||||||
|
|
||||||
|
var realms = await rs.GetRealmBatch(postRealmIds.Select(id => id.ToString()).ToList());
|
||||||
|
var realmDict = realms.ToDictionary(r => r.Id, r => r);
|
||||||
|
|
||||||
|
foreach (var post in posts.Where(p => p.RealmId != null))
|
||||||
|
{
|
||||||
|
if (post.RealmId != null && realmDict.TryGetValue(post.RealmId.Value, out var realm))
|
||||||
|
{
|
||||||
|
post.Realm = realm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static double CalculatePopularity(List<SnPost> posts)
|
private static double CalculatePopularity(List<SnPost> posts)
|
||||||
{
|
{
|
||||||
var score = posts.Sum(p => p.Upvotes - p.Downvotes);
|
var score = posts.Sum(p => p.Upvotes - p.Downvotes);
|
||||||
|
|||||||
@@ -35,9 +35,12 @@ public class ChatRoomController(
|
|||||||
{
|
{
|
||||||
var chatRoom = await db.ChatRooms
|
var chatRoom = await db.ChatRooms
|
||||||
.Where(c => c.Id == id)
|
.Where(c => c.Id == id)
|
||||||
.Include(e => e.Realm)
|
|
||||||
.FirstOrDefaultAsync();
|
.FirstOrDefaultAsync();
|
||||||
if (chatRoom is null) return NotFound();
|
if (chatRoom is null) return NotFound();
|
||||||
|
|
||||||
|
if (chatRoom.RealmId != null)
|
||||||
|
chatRoom.Realm = await rs.GetRealm(chatRoom.RealmId.Value.ToString());
|
||||||
|
|
||||||
if (chatRoom.Type != ChatRoomType.DirectMessage) return Ok(chatRoom);
|
if (chatRoom.Type != ChatRoomType.DirectMessage) return Ok(chatRoom);
|
||||||
|
|
||||||
if (HttpContext.Items["CurrentUser"] is Account currentUser)
|
if (HttpContext.Items["CurrentUser"] is Account currentUser)
|
||||||
|
|||||||
@@ -105,7 +105,10 @@ public class PostController(
|
|||||||
|
|
||||||
var accountId = currentUser is null ? Guid.Empty : 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 userPublishers = currentUser is null ? [] : await pub.GetUserPublishers(accountId);
|
||||||
var userRealms = currentUser is null ? [] : await rs.GetUserRealms(accountId);
|
var userRealms = currentUser is null ? new List<Guid>() : await rs.GetUserRealms(accountId);
|
||||||
|
var publicRealms = await rs.GetPublicRealms();
|
||||||
|
var publicRealmIds = publicRealms.Select(r => r.Id).ToList();
|
||||||
|
var visibleRealmIds = userRealms.Concat(publicRealmIds).Distinct().ToList();
|
||||||
|
|
||||||
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 : (realmName != null ? await rs.GetRealmBySlug(realmName) : null);
|
var realm = realmName == null ? null : (realmName != null ? await rs.GetRealmBySlug(realmName) : null);
|
||||||
@@ -115,7 +118,6 @@ public class PostController(
|
|||||||
.Include(e => e.Tags)
|
.Include(e => e.Tags)
|
||||||
.Include(e => e.RepliedPost)
|
.Include(e => e.RepliedPost)
|
||||||
.Include(e => e.ForwardedPost)
|
.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);
|
||||||
@@ -131,8 +133,7 @@ public class PostController(
|
|||||||
query = query.Where(e => e.Attachments.Count > 0);
|
query = query.Where(e => e.Attachments.Count > 0);
|
||||||
|
|
||||||
if (realm == null)
|
if (realm == null)
|
||||||
query = query.Where(p =>
|
query = query.Where(p => p.RealmId == null || visibleRealmIds.Contains(p.RealmId.Value));
|
||||||
p.RealmId == null || p.Realm == null || userRealms.Contains(p.RealmId.Value) || p.Realm.IsPublic);
|
|
||||||
|
|
||||||
switch (pinned)
|
switch (pinned)
|
||||||
{
|
{
|
||||||
@@ -185,11 +186,31 @@ public class PostController(
|
|||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
posts = await ps.LoadPostInfo(posts, currentUser, true);
|
posts = await ps.LoadPostInfo(posts, currentUser, true);
|
||||||
|
|
||||||
|
// Load realm data for posts that have realm
|
||||||
|
await LoadPostsRealmsAsync(posts, rs);
|
||||||
|
|
||||||
Response.Headers["X-Total"] = totalCount.ToString();
|
Response.Headers["X-Total"] = totalCount.ToString();
|
||||||
|
|
||||||
return Ok(posts);
|
return Ok(posts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static async Task LoadPostsRealmsAsync(List<SnPost> posts, RemoteRealmService rs)
|
||||||
|
{
|
||||||
|
var postRealmIds = posts.Where(p => p.RealmId != null).Select(p => p.RealmId.Value).Distinct().ToList();
|
||||||
|
if (!postRealmIds.Any()) return;
|
||||||
|
|
||||||
|
var realms = await rs.GetRealmBatch(postRealmIds.Select(id => id.ToString()).ToList());
|
||||||
|
var realmDict = realms.GroupBy(r => r.Id).ToDictionary(g => g.Key, g => g.FirstOrDefault());
|
||||||
|
|
||||||
|
foreach (var post in posts.Where(p => p.RealmId != null))
|
||||||
|
{
|
||||||
|
if (post.RealmId != null && realmDict.TryGetValue(post.RealmId.Value, out var realm))
|
||||||
|
{
|
||||||
|
post.Realm = realm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[HttpGet("{publisherName}/{slug}")]
|
[HttpGet("{publisherName}/{slug}")]
|
||||||
public async Task<ActionResult<SnPost>> GetPost(string publisherName, string slug)
|
public async Task<ActionResult<SnPost>> GetPost(string publisherName, string slug)
|
||||||
{
|
{
|
||||||
@@ -208,7 +229,6 @@ public class PostController(
|
|||||||
var post = await db.Posts
|
var post = await db.Posts
|
||||||
.Include(e => e.Publisher)
|
.Include(e => e.Publisher)
|
||||||
.Where(e => e.Slug == slug && e.Publisher.Name == publisherName)
|
.Where(e => e.Slug == slug && e.Publisher.Name == publisherName)
|
||||||
.Include(e => e.Realm)
|
|
||||||
.Include(e => e.Tags)
|
.Include(e => e.Tags)
|
||||||
.Include(e => e.Categories)
|
.Include(e => e.Categories)
|
||||||
.Include(e => e.RepliedPost)
|
.Include(e => e.RepliedPost)
|
||||||
@@ -217,6 +237,8 @@ public class PostController(
|
|||||||
.FirstOrDefaultAsync();
|
.FirstOrDefaultAsync();
|
||||||
if (post is null) return NotFound();
|
if (post is null) return NotFound();
|
||||||
post = await ps.LoadPostInfo(post, currentUser);
|
post = await ps.LoadPostInfo(post, currentUser);
|
||||||
|
if (post.RealmId != null)
|
||||||
|
post.Realm = await rs.GetRealm(post.RealmId.Value.ToString());
|
||||||
|
|
||||||
return Ok(post);
|
return Ok(post);
|
||||||
}
|
}
|
||||||
@@ -239,7 +261,6 @@ public class PostController(
|
|||||||
var post = await db.Posts
|
var post = await db.Posts
|
||||||
.Where(e => e.Id == id)
|
.Where(e => e.Id == id)
|
||||||
.Include(e => e.Publisher)
|
.Include(e => e.Publisher)
|
||||||
.Include(e => e.Realm)
|
|
||||||
.Include(e => e.Tags)
|
.Include(e => e.Tags)
|
||||||
.Include(e => e.Categories)
|
.Include(e => e.Categories)
|
||||||
.Include(e => e.RepliedPost)
|
.Include(e => e.RepliedPost)
|
||||||
@@ -248,6 +269,10 @@ public class PostController(
|
|||||||
.FirstOrDefaultAsync();
|
.FirstOrDefaultAsync();
|
||||||
if (post is null) return NotFound();
|
if (post is null) return NotFound();
|
||||||
post = await ps.LoadPostInfo(post, currentUser);
|
post = await ps.LoadPostInfo(post, currentUser);
|
||||||
|
if (post.RealmId != null)
|
||||||
|
{
|
||||||
|
post.Realm = await rs.GetRealm(post.RealmId.Value.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
return Ok(post);
|
return Ok(post);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user