🐛 Bug fixes within the new localization engine

This commit is contained in:
2026-02-05 15:53:25 +08:00
parent 541956d0e9
commit 769b0e0e9c
14 changed files with 283 additions and 46 deletions

View File

@@ -330,11 +330,11 @@ public class AccountEventService(
.Where(x => x.AccountId == user.Id)
.Select(x => new { x.Birthday, x.TimeZone })
.FirstOrDefaultAsync();
var accountBirthday = accountProfile?.Birthday;
var now = SystemClock.Instance.GetCurrentInstant();
var userTimeZone = DateTimeZone.Utc;
if (!string.IsNullOrEmpty(accountProfile?.TimeZone))
{
@@ -343,9 +343,9 @@ public class AccountEventService(
var todayInUserTz = now.InZone(userTimeZone).Date;
var birthdayDate = accountBirthday?.InZone(userTimeZone).Date;
var isBirthday = birthdayDate.HasValue &&
birthdayDate.Value.Month == todayInUserTz.Month &&
var isBirthday = birthdayDate.HasValue &&
birthdayDate.Value.Month == todayInUserTz.Month &&
birthdayDate.Value.Day == todayInUserTz.Day;
List<CheckInFortuneTip> tips;
@@ -561,7 +561,7 @@ public class AccountEventService(
{
var userActivities = activitiesByUser.GetValueOrDefault(userId, new List<SnPresenceActivity>());
results[userId] = userActivities;
// Update cache for this user
var cacheKey = $"{ActivityCacheKey}{userId}";
await cache.SetWithGroupsAsync(cacheKey, userActivities, [$"{AccountService.AccountCachePrefix}{userId}"],

View File

@@ -432,8 +432,8 @@ public class AccountService(
Notification = new PushNotification
{
Topic = "auth.verification",
Title = localizer.Get("authCodeTitle"),
Body = localizer.Get("authCodeBody", args: new { code }),
Title = localizer.Get("authCodeTitle", account.Language),
Body = localizer.Get("authCodeBody", locale: account.Language, args: new { code }),
IsSavable = false
}
}
@@ -464,8 +464,9 @@ public class AccountService(
.SendRazorTemplateEmailAsync<VerificationEmailModel>(
account.Nick,
contact.Content,
localizer.Get("codeEmailTitle"),
localizer.Get("codeEmailTitle", account.Language),
"FactorCode",
account.Language,
new VerificationEmailModel
{
Name = account.Name,

View File

@@ -97,8 +97,9 @@ public class MagicSpellService(
await email.SendRazorTemplateEmailAsync<LandingEmailModel>(
contact.Account.Nick,
contact.Content,
localizer.Get("regConfirmTitle"),
localizer.Get("regConfirmTitle", accountLanguage),
"Welcome",
accountLanguage,
new LandingEmailModel
{
Name = contact.Account.Name,
@@ -110,8 +111,9 @@ public class MagicSpellService(
await email.SendRazorTemplateEmailAsync<AccountDeletionEmailModel>(
contact.Account.Nick,
contact.Content,
localizer.Get("accountDeletionTitle"),
localizer.Get("accountDeletionTitle", accountLanguage),
"AccountDeletion",
accountLanguage,
new AccountDeletionEmailModel
{
Name = contact.Account.Name,
@@ -123,8 +125,9 @@ public class MagicSpellService(
await email.SendRazorTemplateEmailAsync<PasswordResetEmailModel>(
contact.Account.Nick,
contact.Content,
localizer.Get("passwordResetTitle"),
localizer.Get("passwordResetTitle", accountLanguage),
"PasswordReset",
accountLanguage,
new PasswordResetEmailModel
{
Name = contact.Account.Name,
@@ -138,8 +141,9 @@ public class MagicSpellService(
await email.SendRazorTemplateEmailAsync<ContactVerificationEmailModel>(
contact.Account.Nick,
contactMethod!,
localizer.Get("contractMethodVerificationTitle"),
localizer.Get("contractMethodVerificationTitle", accountLanguage),
"ContactVerification",
accountLanguage,
new ContactVerificationEmailModel
{
Name = contact.Account.Name,

View File

@@ -117,8 +117,8 @@ public class RelationshipService(
Notification = new PushNotification
{
Topic = "relationships.friends.request",
Title = localizer.Get("friendRequestTitle", args: new { sender.Nick }),
Body = localizer.Get("friendRequestBody"),
Title = localizer.Get("friendRequestTitle", locale: sender.Language, args: new { sender.Nick }),
Body = localizer.Get("friendRequestBody", locale: sender.Language),
ActionUri = "/account/relationships",
IsSavable = true
}

View File

@@ -233,14 +233,14 @@ public class AuthController(
{
AccountService.SetCultureInfo(challenge.Account);
await pusher.SendPushNotificationToUserAsync(new SendPushNotificationToUserRequest
{
Notification = new PushNotification
{
Topic = "auth.login",
Title = localizer.Get("newLoginTitle"),
Body = localizer.Get("newLoginBody", args: new { deviceName = challenge.DeviceName ?? "unknown", ipAddress = challenge.IpAddress ?? "unknown" }),
IsSavable = true
},
Notification = new PushNotification
{
Topic = "auth.login",
Title = localizer.Get("newLoginTitle", challenge.Account.Language),
Body = localizer.Get("newLoginBody", locale: challenge.Account.Language, args: new { deviceName = challenge.DeviceName ?? "unknown", ipAddress = challenge.IpAddress ?? "unknown" }),
IsSavable = true
},
UserId = challenge.AccountId.ToString()
});
als.CreateActionLogFromRequest(ActionLogType.NewLogin,

View File

@@ -55,8 +55,8 @@ public class RealmService(
Notification = new PushNotification
{
Topic = "invites.realms",
Title = localizer.Get("realmInviteTitle"),
Body = localizer.Get("realmInviteBody", args: new { realmName = member.Realm.Name }),
Title = localizer.Get("realmInviteTitle", account.Language),
Body = localizer.Get("realmInviteBody", locale: account.Language, args: new { realmName = member.Realm.Name }),
ActionUri = "/realms",
IsSavable = true
}

View File

@@ -127,8 +127,8 @@ public class RealmServiceGrpc(
Notification = new PushNotification
{
Topic = "invites.realms",
Title = localizer.Get("realmInviteTitle"),
Body = localizer.Get("realmInviteBody", args: new { realmName = member.Realm?.Name ?? "Unknown Realm" }),
Title = localizer.Get("realmInviteTitle", account.Language),
Body = localizer.Get("realmInviteBody", locale: account.Language, args: new { realmName = member?.Name ?? "Unknown Realm" }),
ActionUri = "/realms",
IsSavable = true
}

View File

@@ -23,5 +23,94 @@
"emailAccountDeletionTitle": "Confirm your account deletion",
"passwordResetTitle": "Reset your password",
"contractMethodVerificationTitle": "Verify Contact Method",
"codeEmailTitle": "Your email one-time-password"
"codeEmailTitle": "Your email one-time-password",
"friendRequestTitle": "{sender} requested to be your friend",
"friendRequestBody": "You can go to relationships page and decide accept their request or not.",
"newLoginTitle": "New login detected",
"newLoginBody": "Your account logged on to a device named {deviceName} at {ipAddress}",
"chatInviteTitle": "New Chat Invitation",
"chatInviteBody": "You just got invited to join {channel}",
"chatInviteDirectBody": "{user} sent an direct message invitation to you",
"postSubscriptionTitle": "{publisher}: {title}",
"postReplyTitle": "{user} replied your post",
"postReactTitle": "{user} reacted to your post",
"postReactBody": "{user} reacted with {reaction}",
"postReactContentBody": "{user} reacted with {reaction} to \"{title}\"",
"postAwardedTitle": "{user} awarded your post",
"postAwardedBody": "{user} awarded {amount} points",
"postAwardedContentBody": "{user} awarded {amount} points to \"{title}\"",
"realmInviteTitle": "Realm Invitation",
"realmInviteBody": "You have been invited to join {realm}",
"authCodeTitle": "Disposable Verification Code",
"authCodeBody": "{code} is your disposable code, it will expires in 5 minutes",
"subscriptionAppliedTitle": "Subscription {plan} just activated for your account",
"subscriptionAppliedBody": "Thank for supporting Solar Network! Your {days} days {plan} subscription just begun, feel free to explore the newly unlocked features!",
"orderPaidTitle": "Order {orderId} recipient",
"orderPaidBody": "Paid {amount} {currency} for {remark}",
"orderReceivedTitle": "Order {orderId} recipient",
"orderReceivedBody": "Received {amount} {currency} for {remark}",
"giftClaimedTitle": "Gift Claimed",
"giftClaimedBody": "Your gift {subscription} has been claimed by {user}",
"fortuneTipSpecialTitleBirthday": "Have a Birthday Party",
"fortuneTipSpecialContentBirthday": "Happy Birthday, {user}!",
"fortuneTipPositiveTitle1": "Gacha",
"fortuneTipPositiveContent1": "Comes at your first roll",
"fortuneTipPositiveTitle2": "Gaming",
"fortuneTipPositiveContent2": "Ranking up as god",
"fortuneTipPositiveTitle3": "Lottery",
"fortuneTipPositiveContent3": "Never miss a first",
"fortuneTipPositiveTitle4": "Speech",
"fortuneTipPositiveContent4": "Flowing at precision",
"fortuneTipPositiveTitle5": "Drawing",
"fortuneTipPositiveContent5": "Expectation is envisioned",
"fortuneTipPositiveTitle6": "Coding",
"fortuneTipPositiveContent6": "0 error(s), 0 warning(s)",
"fortuneTipPositiveTitle7": "Shopping",
"fortuneTipPositiveContent7": "No taxes and extra fees",
"fortuneTipPositiveTitle8": "Studying",
"fortuneTipPositiveContent8": "Efficiency X",
"fortuneTipPositiveTitle9": "Music composing",
"fortuneTipPositiveContent9": "No need to re-listen",
"fortuneTipPositiveTitle10": "Imaging",
"fortuneTipPositiveContent10": "Perfect every shot",
"fortuneTipPositiveTitle11": "PCB welding",
"fortuneTipPositiveContent11": "Solders, fluxes, GO!",
"fortuneTipPositiveTitle12": "After Effects",
"fortuneTipPositiveContent12": "@ 60 fps",
"fortuneTipPositiveTitle13": "Drone shot",
"fortuneTipPositiveContent13": "Ready to Go",
"fortuneTipPositiveTitle14": "Color grading",
"fortuneTipPositiveContent14": "In this format, at this color",
"fortuneTipPositiveTitle15": "Waterlogging",
"fortuneTipPositiveContent15": "0 waterlogging",
"fortuneTipNegativeTitle1": "Gacha",
"fortuneTipNegativeContent1": "Won't get at 80, but 200",
"fortuneTipNegativeTitle2": "Gaming",
"fortuneTipNegativeContent2": "Ground's limit",
"fortuneTipNegativeTitle3": "Lottery",
"fortuneTipNegativeContent3": "Zero in multiple ten",
"fortuneTipNegativeTitle4": "Speech",
"fortuneTipNegativeContent4": "Be careful what you say",
"fortuneTipNegativeTitle5": "Drawing",
"fortuneTipNegativeContent5": "Your pen is sticky",
"fortuneTipNegativeTitle6": "Coding",
"fortuneTipNegativeContent6": "114 error(s), 514 warning(s)",
"fortuneTipNegativeTitle7": "Shopping",
"fortuneTipNegativeContent7": "245% tariff",
"fortuneTipNegativeTitle8": "Studying",
"fortuneTipNegativeContent8": "Studying Fatigue III",
"fortuneTipNegativeTitle9": "Music composing",
"fortuneTipNegativeContent9": "FL Studio is not responding",
"fortuneTipNegativeTitle10": "Imaging",
"fortuneTipNegativeContent10": "Card cannot be accessed",
"fortuneTipNegativeTitle11": "PCB welding",
"fortuneTipNegativeContent11": "Hand welding",
"fortuneTipNegativeTitle12": "After Effects",
"fortuneTipNegativeContent12": "Baaah!",
"fortuneTipNegativeTitle13": "Drone shot",
"fortuneTipNegativeContent13": "Low battery level, Auto Landing in 16s",
"fortuneTipNegativeTitle14": "Color grading",
"fortuneTipNegativeContent14": "Crummy screen now",
"fortuneTipNegativeTitle15": "Washing film",
"fortuneTipNegativeContent15": "Why is there still something in the box"
}

View File

@@ -23,5 +23,94 @@
"emailAccountDeletionTitle": "确认删除您的账户",
"passwordResetTitle": "重置您的密码",
"contractMethodVerificationTitle": "验证联系方式",
"codeEmailTitle": "您的邮箱一次性密码"
"codeEmailTitle": "您的邮箱一次性密码",
"friendRequestTitle": "{sender} 请求成为您的朋友",
"friendRequestBody": "您可以前往关系页面决定接受或拒绝其请求。",
"newLoginTitle": "检测到新登录",
"newLoginBody": "您的账户已在名为 {deviceName} 的设备上登录,位置为 {ipAddress}",
"chatInviteTitle": "新聊天邀请",
"chatInviteBody": "您刚刚被邀请加入 {channel}",
"chatInviteDirectBody": "{user} 向您发送了私信邀请",
"postSubscriptionTitle": "{publisher}: {title}",
"postReplyTitle": "{user} 回复了您的帖子",
"postReactTitle": "{user} 对您的帖子做出了反应",
"postReactBody": "{user} 用 {reaction} 做出了反应",
"postReactContentBody": "{user} 用 {reaction} 对 \"{title}\" 做出了反应",
"postAwardedTitle": "{user} 打赏了您的帖子",
"postAwardedBody": "{user} 打赏了 {amount} 积分",
"postAwardedContentBody": "{user} 打赏了 {amount} 积分给 \"{title}\"",
"realmInviteTitle": "领域邀请",
"realmInviteBody": "您被邀请加入 {realm}",
"authCodeTitle": "一次性验证码",
"authCodeBody": "{code} 是您的一次性验证码将在5分钟后过期",
"subscriptionAppliedTitle": "订阅 {plan} 刚刚为您的账户激活",
"subscriptionAppliedBody": "感谢您支持 Solar Network您的 {days} 天 {plan} 订阅刚刚开始,请尽情探索新解锁的功能!",
"orderPaidTitle": "订单 {orderId} 收件人",
"orderPaidBody": "支付了 {amount} {currency} 用于 {remark}",
"orderReceivedTitle": "订单 {orderId} 收件人",
"orderReceivedBody": "收到了 {amount} {currency} 用于 {remark}",
"giftClaimedTitle": "礼物已领取",
"giftClaimedBody": "您的 {subscription} 礼物已被 {user} 领取",
"fortuneTipSpecialTitleBirthday": "举办生日派对",
"fortuneTipSpecialContentBirthday": "生日快乐,{user}",
"fortuneTipPositiveTitle1": "抽卡",
"fortuneTipPositiveContent1": "一抽就中",
"fortuneTipPositiveTitle2": "游戏",
"fortuneTipPositiveContent2": "封神",
"fortuneTipPositiveTitle3": "抽奖",
"fortuneTipPositiveContent3": "绝不错过首抽",
"fortuneTipPositiveTitle4": "配音",
"fortuneTipPositiveContent4": "行云流水",
"fortuneTipPositiveTitle5": "作画",
"fortuneTipPositiveContent5": "预期被实现",
"fortuneTipPositiveTitle6": "编程",
"fortuneTipPositiveContent6": "0个错误0个警告",
"fortuneTipPositiveTitle7": "购物",
"fortuneTipPositiveContent7": "无税,无额外费用",
"fortuneTipPositiveTitle8": "学习",
"fortuneTipPositiveContent8": "效率X",
"fortuneTipPositiveTitle9": "音乐创作",
"fortuneTipPositiveContent9": "无需重新上线",
"fortuneTipPositiveTitle10": "图像处理",
"fortuneTipPositiveContent10": "每张都很完美",
"fortuneTipPositiveTitle11": "手工焊接",
"fortuneTipPositiveContent11": "焊工、焊料、起飞!",
"fortuneTipPositiveTitle12": "后期",
"fortuneTipPositiveContent12": "@ 60帧",
"fortuneTipPositiveTitle13": "云台",
"fortuneTipPositiveContent13": "准备出发",
"fortuneTipPositiveTitle14": "调色",
"fortuneTipPositiveContent14": "在此格式,进行调色",
"fortuneTipPositiveTitle15": "无水纹",
"fortuneTipPositiveContent15": "0个水印",
"fortuneTipNegativeTitle1": "抽卡",
"fortuneTipNegativeContent1": "保底80却出200",
"fortuneTipNegativeTitle2": "游戏",
"fortuneTipNegativeContent2": "地板",
"fortuneTipNegativeTitle3": "抽奖",
"fortuneTipNegativeContent3": "十连没出",
"fortuneTipNegativeTitle4": "配音",
"fortuneTipNegativeContent4": "慎言",
"fortuneTipNegativeTitle5": "作画",
"fortuneTipNegativeContent5": "笔尖不顺畅",
"fortuneTipNegativeTitle6": "编程",
"fortuneTipNegativeContent6": "114个错误514个警告",
"fortuneTipNegativeTitle7": "购物",
"fortuneTipNegativeContent7": "245%关税",
"fortuneTipNegativeTitle8": "学习",
"fortuneTipNegativeContent8": "学习疲劳III",
"fortuneTipNegativeTitle9": "音乐创作",
"fortuneTipNegativeContent9": "FL Studio没有响应",
"fortuneTipNegativeTitle10": "图像处理",
"fortuneTipNegativeContent10": "无法读取SD卡",
"fortuneTipNegativeTitle11": "手工焊接",
"fortuneTipNegativeContent11": "手工焊接",
"fortuneTipNegativeTitle12": "后期",
"fortuneTipNegativeContent12": "啊啊啊!",
"fortuneTipNegativeTitle13": "云台",
"fortuneTipNegativeContent13": "电量低自动降落16秒",
"fortuneTipNegativeTitle14": "调色",
"fortuneTipNegativeContent14": "屏幕现在很烂",
"fortuneTipNegativeTitle15": "洗胶片",
"fortuneTipNegativeContent15": "为什么盒子里还有东西?"
}