♻️ Replaced the SetCultureInfo with the new localization engine

This commit is contained in:
2026-02-05 16:28:31 +08:00
parent 3c6ccba74f
commit 0051740cb0
10 changed files with 60 additions and 106 deletions

View File

@@ -40,7 +40,7 @@ public class ChatRoomController(
if (chatRoom.Type != ChatRoomType.DirectMessage) return Ok(chatRoom); if (chatRoom.Type != ChatRoomType.DirectMessage) return Ok(chatRoom);
chatRoom = await crs.LoadChatRealms(chatRoom); chatRoom = await crs.LoadChatRealms(chatRoom);
if (HttpContext.Items["CurrentUser"] is Account currentUser) if (HttpContext.Items["CurrentUser"] is Account currentUser)
chatRoom = await crs.LoadDirectMessageMembers(chatRoom, Guid.Parse(currentUser.Id)); chatRoom = await crs.LoadDirectMessageMembers(chatRoom, Guid.Parse(currentUser.Id));
@@ -142,7 +142,7 @@ public class ChatRoomController(
var invitedMember = dmRoom.Members.First(m => m.AccountId == request.RelatedUserId); var invitedMember = dmRoom.Members.First(m => m.AccountId == request.RelatedUserId);
invitedMember.ChatRoom = dmRoom; invitedMember.ChatRoom = dmRoom;
await _SendInviteNotify(invitedMember, currentUser); await SendInviteNotify(invitedMember, currentUser);
return Ok(dmRoom); return Ok(dmRoom);
} }
@@ -168,7 +168,7 @@ public class ChatRoomController(
public class ChatRoomRequest public class ChatRoomRequest
{ {
[Required] [MaxLength(1024)] public string? Name { get; set; } [Required][MaxLength(1024)] public string? Name { get; set; }
[MaxLength(4096)] public string? Description { get; set; } [MaxLength(4096)] public string? Description { get; set; }
[MaxLength(32)] public string? PictureId { get; set; } [MaxLength(32)] public string? PictureId { get; set; }
[MaxLength(32)] public string? BackgroundId { get; set; } [MaxLength(32)] public string? BackgroundId { get; set; }
@@ -583,7 +583,7 @@ public class ChatRoomController(
existingMember.JoinedAt = null; existingMember.JoinedAt = null;
db.ChatMembers.Update(existingMember); db.ChatMembers.Update(existingMember);
await db.SaveChangesAsync(); await db.SaveChangesAsync();
await _SendInviteNotify(existingMember, currentUser); await SendInviteNotify(existingMember, currentUser);
_ = als.CreateActionLogAsync(new CreateActionLogRequest _ = als.CreateActionLogAsync(new CreateActionLogRequest
{ {
@@ -612,7 +612,7 @@ public class ChatRoomController(
await db.SaveChangesAsync(); await db.SaveChangesAsync();
newMember.ChatRoom = chatRoom; newMember.ChatRoom = chatRoom;
await _SendInviteNotify(newMember, currentUser); await SendInviteNotify(newMember, currentUser);
_ = als.CreateActionLogAsync(new CreateActionLogRequest _ = als.CreateActionLogAsync(new CreateActionLogRequest
{ {
@@ -814,7 +814,7 @@ public class ChatRoomController(
return NoContent(); return NoContent();
} }
[HttpDelete("{roomId:guid}/members/{memberId:guid}/timeout")] [HttpDelete("{roomId:guid}/members/{memberId:guid}/timeout")]
[Authorize] [Authorize]
public async Task<ActionResult> RemoveChatMemberTimeout(Guid roomId, Guid memberId) public async Task<ActionResult> RemoveChatMemberTimeout(Guid roomId, Guid memberId)
@@ -1003,14 +1003,13 @@ public class ChatRoomController(
return NoContent(); return NoContent();
} }
private async Task _SendInviteNotify(SnChatMember member, Account sender) private async Task SendInviteNotify(SnChatMember member, Account sender)
{ {
var account = await accounts.GetAccountAsync(new GetAccountRequest { Id = member.AccountId.ToString() }); var account = await accounts.GetAccountAsync(new GetAccountRequest { Id = member.AccountId.ToString() });
CultureService.SetCultureInfo(account); var title = "Chat Invite";
var title = "Chat Invite"; var body = member.ChatRoom.Type == ChatRoomType.DirectMessage
var body = member.ChatRoom.Type == ChatRoomType.DirectMessage ? $"{sender.Nick} sent you a direct message"
? $"{sender.Nick} sent you a direct message" : $"You have been invited to {member.ChatRoom.Name ?? "Unnamed"}";
: $"You have been invited to {member.ChatRoom.Name ?? "Unnamed"}";
await pusher.SendPushNotificationToUserAsync( await pusher.SendPushNotificationToUserAsync(
@@ -1031,4 +1030,4 @@ public class ChatRoomController(
} }
); );
} }
} }

View File

@@ -302,9 +302,9 @@ public class AccountEventService(
private const string CheckInLockKey = "checkin:lock:"; private const string CheckInLockKey = "checkin:lock:";
public async Task<SnCheckInResult> CheckInDaily(SnAccount user, Instant? backdated = null) public async Task<SnCheckInResult> CheckInDaily(SnAccount account, Instant? backdated = null)
{ {
var lockKey = $"{CheckInLockKey}{user.Id}"; var lockKey = $"{CheckInLockKey}{account.Id}";
try try
{ {
@@ -322,12 +322,9 @@ public class AccountEventService(
await using var lockObj = await using var lockObj =
await cache.AcquireLockAsync(lockKey, TimeSpan.FromMinutes(1), TimeSpan.FromSeconds(5)) ?? await cache.AcquireLockAsync(lockKey, TimeSpan.FromMinutes(1), TimeSpan.FromSeconds(5)) ??
throw new InvalidOperationException("Check-in was in progress."); throw new InvalidOperationException("Check-in was in progress.");
var cultureInfo = new CultureInfo(user.Language, false);
CultureInfo.CurrentCulture = cultureInfo;
CultureInfo.CurrentUICulture = cultureInfo;
var accountProfile = await db.AccountProfiles var accountProfile = await db.AccountProfiles
.Where(x => x.AccountId == user.Id) .Where(x => x.AccountId == account.Id)
.Select(x => new { x.Birthday, x.TimeZone }) .Select(x => new { x.Birthday, x.TimeZone })
.FirstOrDefaultAsync(); .FirstOrDefaultAsync();
@@ -360,7 +357,7 @@ public class AccountEventService(
{ {
IsPositive = true, IsPositive = true,
Title = localizer.Get("fortuneTipSpecialTitleBirthday"), Title = localizer.Get("fortuneTipSpecialTitleBirthday"),
Content = localizer.Get("fortuneTipSpecialContentBirthday", args: new { user.Nick }), Content = localizer.Get("fortuneTipSpecialContentBirthday", args: new { account.Nick }),
} }
]; ];
} }
@@ -374,8 +371,8 @@ public class AccountEventService(
tips = positiveIndices.Select(index => new CheckInFortuneTip tips = positiveIndices.Select(index => new CheckInFortuneTip
{ {
IsPositive = true, IsPositive = true,
Title = localizer.Get($"fortuneTipPositiveTitle{index}"), Title = localizer.Get($"fortuneTipPositiveTitle{index}", account.Language),
Content = localizer.Get($"fortuneTipPositiveContent{index}") Content = localizer.Get($"fortuneTipPositiveContent{index}", account.Language)
}).ToList(); }).ToList();
// Generate 2 negative tips // Generate 2 negative tips
@@ -387,8 +384,8 @@ public class AccountEventService(
tips.AddRange(negativeIndices.Select(index => new CheckInFortuneTip tips.AddRange(negativeIndices.Select(index => new CheckInFortuneTip
{ {
IsPositive = false, IsPositive = false,
Title = localizer.Get($"fortuneTipNegativeTitle{index}"), Title = localizer.Get($"fortuneTipNegativeTitle{index}", account.Language),
Content = localizer.Get($"fortuneTipNegativeContent{index}") Content = localizer.Get($"fortuneTipNegativeContent{index}", account.Language)
})); }));
// The 5 is specialized, keep it alone. // The 5 is specialized, keep it alone.
@@ -409,7 +406,7 @@ public class AccountEventService(
{ {
Tips = tips, Tips = tips,
Level = checkInLevel, Level = checkInLevel,
AccountId = user.Id, AccountId = account.Id,
RewardExperience = 100, RewardExperience = 100,
RewardPoints = backdated.HasValue ? null : 10, RewardPoints = backdated.HasValue ? null : 10,
BackdatedFrom = backdated.HasValue ? SystemClock.Instance.GetCurrentInstant() : null, BackdatedFrom = backdated.HasValue ? SystemClock.Instance.GetCurrentInstant() : null,
@@ -421,7 +418,7 @@ public class AccountEventService(
if (result.RewardPoints.HasValue) if (result.RewardPoints.HasValue)
await payment.CreateTransactionWithAccount( await payment.CreateTransactionWithAccount(
null, null,
user.Id.ToString(), account.Id.ToString(),
WalletCurrency.SourcePoint, WalletCurrency.SourcePoint,
result.RewardPoints.Value.ToString(CultureInfo.InvariantCulture), result.RewardPoints.Value.ToString(CultureInfo.InvariantCulture),
$"Check-in reward on {now:yyyy/MM/dd}" $"Check-in reward on {now:yyyy/MM/dd}"
@@ -439,7 +436,7 @@ public class AccountEventService(
"check-in", "check-in",
$"Check-in reward on {now:yyyy/MM/dd}", $"Check-in reward on {now:yyyy/MM/dd}",
result.RewardExperience.Value, result.RewardExperience.Value,
user.Id account.Id
); );
// The lock will be automatically released by the await using statement // The lock will be automatically released by the await using statement

View File

@@ -34,18 +34,6 @@ public class AccountService(
INatsConnection nats INatsConnection nats
) )
{ {
public static void SetCultureInfo(SnAccount account)
{
SetCultureInfo(account.Language);
}
public static void SetCultureInfo(string? languageCode)
{
var info = new CultureInfo(languageCode ?? "en-us", false);
CultureInfo.CurrentCulture = info;
CultureInfo.CurrentUICulture = info;
}
public const string AccountCachePrefix = "account:"; public const string AccountCachePrefix = "account:";
public async Task PurgeAccountCache(SnAccount account) public async Task PurgeAccountCache(SnAccount account)
@@ -123,7 +111,7 @@ public class AccountService(
).CountAsync(); ).CountAsync();
if (dupeEmailCount > 0) if (dupeEmailCount > 0)
throw new InvalidOperationException("Account email has already been used."); throw new InvalidOperationException("Account email has already been used.");
var account = new SnAccount var account = new SnAccount
{ {
Name = name, Name = name,
@@ -432,8 +420,8 @@ public class AccountService(
Notification = new PushNotification Notification = new PushNotification
{ {
Topic = "auth.verification", Topic = "auth.verification",
Title = localizer.Get("authCodeTitle", account.Language), Title = localizer.Get("authCodeTitle", account.Language),
Body = localizer.Get("authCodeBody", locale: account.Language, args: new { code }), Body = localizer.Get("authCodeBody", locale: account.Language, args: new { code }),
IsSavable = false IsSavable = false
} }
} }
@@ -554,7 +542,7 @@ public class AccountService(
{ {
if (!await IsDeviceActive(session.ClientId.Value)) if (!await IsDeviceActive(session.ClientId.Value))
await pusher.UnsubscribePushNotificationsAsync(new UnsubscribePushNotificationsRequest() await pusher.UnsubscribePushNotificationsAsync(new UnsubscribePushNotificationsRequest()
{ DeviceId = session.Client!.DeviceId } { DeviceId = session.Client!.DeviceId }
); );
} }
@@ -790,11 +778,11 @@ public class AccountService(
{ {
var accountIds = accounts.Select(a => a.Id).ToList(); var accountIds = accounts.Select(a => a.Id).ToList();
var subscriptions = await remoteSubscription.GetPerkSubscriptions(accountIds); var subscriptions = await remoteSubscription.GetPerkSubscriptions(accountIds);
var subscriptionDict = subscriptions var subscriptionDict = subscriptions
.Where(s => s != null) .Where(s => s != null)
.ToDictionary( .ToDictionary(
s => Guid.Parse(s.AccountId), s => Guid.Parse(s.AccountId),
s => SnWalletSubscription.FromProtoValue(s).ToReference() s => SnWalletSubscription.FromProtoValue(s).ToReference()
); );

View File

@@ -87,7 +87,6 @@ public class MagicSpellService(
.Where(a => a.Id == spell.AccountId) .Where(a => a.Id == spell.AccountId)
.Select(a => a.Language) .Select(a => a.Language)
.FirstOrDefaultAsync(); .FirstOrDefaultAsync();
AccountService.SetCultureInfo(accountLanguage);
try try
{ {

View File

@@ -2,7 +2,6 @@ using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using NodaTime; using NodaTime;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using DysonNetwork.Pass.Localization;
using DysonNetwork.Shared.Geometry; using DysonNetwork.Shared.Geometry;
using DysonNetwork.Shared.Proto; using DysonNetwork.Shared.Proto;
using DysonNetwork.Shared.Localization; using DysonNetwork.Shared.Localization;
@@ -31,8 +30,8 @@ public class AuthController(
public class ChallengeRequest public class ChallengeRequest
{ {
[Required] public Shared.Models.ClientPlatform Platform { get; set; } [Required] public Shared.Models.ClientPlatform Platform { get; set; }
[Required] [MaxLength(256)] public string Account { get; set; } = null!; [Required][MaxLength(256)] public string Account { get; set; } = null!;
[Required] [MaxLength(512)] public string DeviceId { get; set; } = null!; [Required][MaxLength(512)] public string DeviceId { get; set; } = null!;
[MaxLength(1024)] public string? DeviceName { get; set; } [MaxLength(1024)] public string? DeviceName { get; set; }
public List<string> Audiences { get; set; } = []; public List<string> Audiences { get; set; } = [];
public List<string> Scopes { get; set; } = []; public List<string> Scopes { get; set; } = [];
@@ -231,16 +230,15 @@ public class AuthController(
if (challenge.StepRemain == 0) if (challenge.StepRemain == 0)
{ {
AccountService.SetCultureInfo(challenge.Account);
await pusher.SendPushNotificationToUserAsync(new SendPushNotificationToUserRequest await pusher.SendPushNotificationToUserAsync(new SendPushNotificationToUserRequest
{
Notification = new PushNotification
{ {
Notification = new PushNotification Topic = "auth.login",
{ Title = localizer.Get("newLoginTitle", challenge.Account.Language),
Topic = "auth.login", Body = localizer.Get("newLoginBody", locale: challenge.Account.Language, args: new { deviceName = challenge.DeviceName ?? "unknown", ipAddress = challenge.IpAddress ?? "unknown" }),
Title = localizer.Get("newLoginTitle", challenge.Account.Language), IsSavable = true
Body = localizer.Get("newLoginBody", locale: challenge.Account.Language, args: new { deviceName = challenge.DeviceName ?? "unknown", ipAddress = challenge.IpAddress ?? "unknown" }), },
IsSavable = true
},
UserId = challenge.AccountId.ToString() UserId = challenge.AccountId.ToString()
}); });
als.CreateActionLogFromRequest(ActionLogType.NewLogin, als.CreateActionLogFromRequest(ActionLogType.NewLogin,
@@ -270,7 +268,7 @@ public class AuthController(
public class NewSessionRequest public class NewSessionRequest
{ {
[Required] [MaxLength(512)] public string DeviceId { get; set; } = null!; [Required][MaxLength(512)] public string DeviceId { get; set; } = null!;
[MaxLength(1024)] public string? DeviceName { get; set; } [MaxLength(1024)] public string? DeviceName { get; set; }
[Required] public Shared.Models.ClientPlatform Platform { get; set; } [Required] public Shared.Models.ClientPlatform Platform { get; set; }
public Instant? ExpiredAt { get; set; } public Instant? ExpiredAt { get; set; }
@@ -357,4 +355,4 @@ public class AuthController(
return Ok(new TokenExchangeResponse { Token = tk }); return Ok(new TokenExchangeResponse { Token = tk });
} }
} }

View File

@@ -17,7 +17,7 @@ public class RealmService(
) )
{ {
private const string CacheKeyPrefix = "account:realms:"; private const string CacheKeyPrefix = "account:realms:";
public async Task<List<Guid>> GetUserRealms(Guid accountId) public async Task<List<Guid>> GetUserRealms(Guid accountId)
{ {
var cacheKey = $"{CacheKeyPrefix}{accountId}"; var cacheKey = $"{CacheKeyPrefix}{accountId}";
@@ -34,19 +34,17 @@ public class RealmService(
// Cache the result for 5 minutes // Cache the result for 5 minutes
await cache.SetAsync(cacheKey, realms, TimeSpan.FromMinutes(5)); await cache.SetAsync(cacheKey, realms, TimeSpan.FromMinutes(5));
return realms; return realms;
} }
public async Task SendInviteNotify(SnRealmMember member) public async Task SendInviteNotify(SnRealmMember member)
{ {
var account = await db.Accounts var account = await db.Accounts
.Include(a => a.Profile) .Include(a => a.Profile)
.FirstOrDefaultAsync(a => a.Id == member.AccountId); .FirstOrDefaultAsync(a => a.Id == member.AccountId);
if (account == null) throw new InvalidOperationException("Account not found"); if (account == null) throw new InvalidOperationException("Account not found");
CultureService.SetCultureInfo(account.Language);
await pusher.SendPushNotificationToUserAsync( await pusher.SendPushNotificationToUserAsync(
new SendPushNotificationToUserRequest new SendPushNotificationToUserRequest

View File

@@ -118,8 +118,6 @@ public class RealmServiceGrpc(
if (account == null) throw new RpcException(new Status(StatusCode.NotFound, "Account not found")); if (account == null) throw new RpcException(new Status(StatusCode.NotFound, "Account not found"));
CultureService.SetCultureInfo(account.Language);
await pusher.SendPushNotificationToUserAsync( await pusher.SendPushNotificationToUserAsync(
new SendPushNotificationToUserRequest new SendPushNotificationToUserRequest
{ {
@@ -188,4 +186,4 @@ public class RealmServiceGrpc(
return response; return response;
} }
} }

View File

@@ -1,19 +0,0 @@
using System.Globalization;
using DysonNetwork.Shared.Proto;
namespace DysonNetwork.Shared;
public static class CultureService
{
public static void SetCultureInfo(string? languageCode)
{
var info = new CultureInfo(languageCode ?? "en-us", false);
CultureInfo.CurrentCulture = info;
CultureInfo.CurrentUICulture = info;
}
public static void SetCultureInfo(Account account)
{
SetCultureInfo(account.Language);
}
}

View File

@@ -222,7 +222,6 @@ public partial class PostService(
foreach (var member in queryResponse.Accounts) foreach (var member in queryResponse.Accounts)
{ {
if (member is null) continue; if (member is null) continue;
CultureService.SetCultureInfo(member);
await nty.SendPushNotificationToUserAsync( await nty.SendPushNotificationToUserAsync(
new SendPushNotificationToUserRequest new SendPushNotificationToUserRequest
{ {
@@ -230,7 +229,7 @@ public partial class PostService(
Notification = new PushNotification Notification = new PushNotification
{ {
Topic = "post.replies", Topic = "post.replies",
Title = localizer.Get("postReplyTitle", args: new { user = sender!.Nick }), Title = localizer.Get("postReplyTitle", locale: member.Language, args: new { user = sender!.Nick }),
Body = ChopPostForNotification(post).content, Body = ChopPostForNotification(post).content,
IsSavable = true, IsSavable = true,
ActionUri = $"/posts/{post.Id}" ActionUri = $"/posts/{post.Id}"
@@ -695,7 +694,6 @@ public partial class PostService(
foreach (var member in queryResponse.Accounts) foreach (var member in queryResponse.Accounts)
{ {
if (member is null) continue; if (member is null) continue;
CultureService.SetCultureInfo(member);
await nty.SendPushNotificationToUserAsync( await nty.SendPushNotificationToUserAsync(
new SendPushNotificationToUserRequest new SendPushNotificationToUserRequest
@@ -704,10 +702,10 @@ public partial class PostService(
Notification = new PushNotification Notification = new PushNotification
{ {
Topic = "posts.reactions.new", Topic = "posts.reactions.new",
Title = localizer.Get("postReactTitle", args: new { user = sender.Nick }), Title = localizer.Get("postReactTitle", locale: member.Language, args: new { user = sender.Nick }),
Body = string.IsNullOrWhiteSpace(post.Title) Body = string.IsNullOrWhiteSpace(post.Title)
? localizer.Get("postReactBody", args: new { user = sender.Nick, reaction = reaction.Symbol }) ? localizer.Get("postReactBody", locale: member.Language, args: new { user = sender.Nick, reaction = reaction.Symbol })
: localizer.Get("postReactContentBody", args: new { user = sender.Nick, reaction = reaction.Symbol, title = post.Title }), : localizer.Get("postReactContentBody", locale: member.Language, args: new { user = sender.Nick, reaction = reaction.Symbol, title = post.Title }),
IsSavable = true, IsSavable = true,
ActionUri = $"/posts/{post.Id}" ActionUri = $"/posts/{post.Id}"
} }
@@ -884,7 +882,7 @@ public partial class PostService(
if (currentUser is not null) if (currentUser is not null)
{ {
var friendsResponse = await accounts.ListFriendsAsync(new ListRelationshipSimpleRequest var friendsResponse = await accounts.ListFriendsAsync(new ListRelationshipSimpleRequest
{ AccountId = currentUser.Id }); { AccountId = currentUser.Id });
userFriends = friendsResponse.AccountsId.Select(Guid.Parse).ToList(); userFriends = friendsResponse.AccountsId.Select(Guid.Parse).ToList();
publishers = await ps.GetUserPublishers(Guid.Parse(currentUser.Id)); publishers = await ps.GetUserPublishers(Guid.Parse(currentUser.Id));
} }
@@ -961,7 +959,7 @@ public partial class PostService(
return false; return false;
if (post.Visibility == Shared.Models.PostVisibility.Friends && if (post.Visibility == Shared.Models.PostVisibility.Friends &&
!(post.Publisher.AccountId.HasValue && userFriends.Contains(post.Publisher.AccountId.Value) || isMember)) !(post.Publisher is not null && post.Publisher.AccountId.HasValue && userFriends.Contains(post.Publisher.AccountId.Value) || isMember))
return false; return false;
// Public and Unlisted are allowed // Public and Unlisted are allowed
@@ -1148,7 +1146,6 @@ public partial class PostService(
foreach (var member in queryResponse.Accounts) foreach (var member in queryResponse.Accounts)
{ {
if (member is null) continue; if (member is null) continue;
CultureService.SetCultureInfo(member);
await nty.SendPushNotificationToUserAsync( await nty.SendPushNotificationToUserAsync(
new SendPushNotificationToUserRequest new SendPushNotificationToUserRequest
@@ -1157,10 +1154,10 @@ public partial class PostService(
Notification = new PushNotification Notification = new PushNotification
{ {
Topic = "posts.awards.new", Topic = "posts.awards.new",
Title = localizer.Get("postAwardedTitle", args: new { user = sender.Nick }), Title = localizer.Get("postAwardedTitle", locale: member.Language, args: new { user = sender.Nick }),
Body = string.IsNullOrWhiteSpace(post.Title) Body = string.IsNullOrWhiteSpace(post.Title)
? localizer.Get("postAwardedBody", args: new { user = sender.Nick, amount }) ? localizer.Get("postAwardedBody", locale: member.Language, args: new { user = sender.Nick, amount })
: localizer.Get("postAwardedContentBody", args: new { user = sender.Nick, amount, title = post.Title }), : localizer.Get("postAwardedContentBody", locale: member.Language, args: new { user = sender.Nick, amount, title = post.Title }),
IsSavable = true, IsSavable = true,
ActionUri = $"/posts/{post.Id}" ActionUri = $"/posts/{post.Id}"
} }
@@ -1209,9 +1206,9 @@ public static class PostQueryExtensions
.Where(e => (e.PublishedAt != null && now >= e.PublishedAt) || .Where(e => (e.PublishedAt != null && now >= e.PublishedAt) ||
(e.PublisherId.HasValue && publishersId.Contains(e.PublisherId.Value))) (e.PublisherId.HasValue && publishersId.Contains(e.PublisherId.Value)))
.Where(e => e.Visibility != Shared.Models.PostVisibility.Private || .Where(e => e.Visibility != Shared.Models.PostVisibility.Private ||
publishersId.Contains(e.PublisherId.Value)) publishersId.Contains(e.PublisherId!.Value))
.Where(e => e.Visibility != Shared.Models.PostVisibility.Friends || .Where(e => e.Visibility != Shared.Models.PostVisibility.Friends ||
(e.Publisher.AccountId != null && userFriends.Contains(e.Publisher.AccountId.Value)) || (e.Publisher!.AccountId != null && userFriends.Contains(e.Publisher.AccountId.Value)) ||
publishersId.Contains(e.PublisherId.Value)); publishersId.Contains(e.PublisherId!.Value));
} }
} }

View File

@@ -114,11 +114,10 @@ public class PublisherSubscriptionService(
{ {
try try
{ {
CultureService.SetCultureInfo(target.Key);
var notification = new PushNotification var notification = new PushNotification
{ {
Topic = "posts.new", Topic = "posts.new",
Title = localizer.Get("postSubscriptionTitle", args: new { publisher = post.Publisher!.Nick, title }), Title = localizer.Get("postSubscriptionTitle", locale: target.Key, args: new { publisher = post.Publisher!.Nick, title }),
Body = message, Body = message,
Meta = GrpcTypeHelper.ConvertObjectToByteString(data), Meta = GrpcTypeHelper.ConvertObjectToByteString(data),
IsSavable = true, IsSavable = true,
@@ -215,4 +214,4 @@ public class PublisherSubscriptionService(
return true; return true;
} }
} }