feat(quota): add support for hour-based window duration and update translations for multiple locales

This commit is contained in:
Supra4E8C
2026-10-15 00:56:32 +08:00
parent eaf7201195
commit 080970ccfc
8 changed files with 21 additions and 4 deletions
@@ -49,7 +49,9 @@ export function MetaQuotaBody({ quota, classes }: QuotaBodyProps<MetaQuotaState>
const soon = window.id === soonestRowId;
const label =
window.id === 'window' && window.durationMinutes
? t('meta_quota.window_duration', { minutes: window.durationMinutes })
? window.durationMinutes % 60 === 0
? t('meta_quota.window_duration_hours', { hours: window.durationMinutes / 60 })
: t('meta_quota.window_duration', { minutes: window.durationMinutes })
: t(`meta_quota.${window.id}`);
return (
<div key={window.id} className={classes.quotaRow}>
+1
View File
@@ -610,6 +610,7 @@
"inactive": "Subscription inactive",
"window": "Usage window",
"window_duration": "{{minutes}}-minute window",
"window_duration_hours": "{{hours}}-hour window",
"weekly": "Weekly quota",
"unknown": "Unknown",
"remaining": "{{percent}}% remaining"
+1
View File
@@ -610,6 +610,7 @@
"inactive": "구독 비활성",
"window": "사용 주기",
"window_duration": "{{minutes}}분 주기",
"window_duration_hours": "{{hours}}시간 주기",
"weekly": "주간 할당량",
"unknown": "알 수 없음",
"remaining": "{{percent}}% 남음"
+1
View File
@@ -600,6 +600,7 @@
"inactive": "Подписка неактивна",
"window": "Квота за период",
"window_duration": "Период: {{minutes}} мин.",
"window_duration_hours": "Период: {{hours}} ч.",
"weekly": "Недельная квота",
"unknown": "Неизвестно",
"remaining": "Осталось {{percent}}%"
+1
View File
@@ -2242,6 +2242,7 @@
"inactive": "Đăng ký không hoạt động",
"window": "Chu kỳ sử dụng",
"window_duration": "Chu kỳ {{minutes}} phút",
"window_duration_hours": "Chu kỳ {{hours}} giờ",
"weekly": "Quota hàng tuần",
"unknown": "Không rõ",
"remaining": "Còn lại {{percent}}%"
+1
View File
@@ -596,6 +596,7 @@
"inactive": "订阅未激活",
"window": "周期额度",
"window_duration": "{{minutes}} 分钟周期",
"window_duration_hours": "{{hours}} 小时周期",
"weekly": "每周额度",
"unknown": "未知",
"remaining": "剩余 {{percent}}%"
+1
View File
@@ -596,6 +596,7 @@
"inactive": "訂閱未啟用",
"window": "週期額度",
"window_duration": "{{minutes}} 分鐘週期",
"window_duration_hours": "{{hours}} 小時週期",
"weekly": "每週額度",
"unknown": "未知",
"remaining": "剩餘 {{percent}}%"
+12 -3
View File
@@ -36,8 +36,8 @@ const snapshot = (): MetaQuotaState => ({
afterEach(() => useQuotaStore.getState().clearQuotaCache());
describe('Muse quota UI integration', () => {
test('provides quota labels in all four locales', () => {
for (const locale of ['en', 'zh-CN', 'zh-TW', 'ru']) {
test('provides quota labels in all six locales', () => {
for (const locale of ['en', 'zh-CN', 'zh-TW', 'ru', 'vi', 'ko']) {
const translations = JSON.parse(readFileSync(`src/i18n/locales/${locale}.json`, 'utf8'));
for (const key of [
'title',
@@ -60,6 +60,7 @@ describe('Muse quota UI integration', () => {
'inactive',
'window',
'window_duration',
'window_duration_hours',
'weekly',
'unknown',
'remaining',
@@ -83,7 +84,8 @@ describe('Muse quota UI integration', () => {
);
expect(markup).toContain('Muse fixture plan');
expect(markup).toContain(i18n.t('meta_quota.active'));
expect(markup).toContain(i18n.t('meta_quota.window_duration', { minutes: 300 }));
expect(markup).toContain(i18n.t('meta_quota.window_duration_hours', { hours: 5 }));
expect(markup).not.toContain(i18n.t('meta_quota.window_duration', { minutes: 300 }));
expect(markup).toContain(i18n.t('meta_quota.weekly'));
expect(markup.match(/role="meter"/g)).toHaveLength(2);
expect(markup).toContain('aria-valuenow="100"');
@@ -92,6 +94,13 @@ describe('Muse quota UI integration', () => {
expect(markup).toContain('width:99%');
});
test('keeps minutes for a window that is not a whole number of hours', () => {
const quota = snapshot();
quota.data!.windows[0].durationMinutes = 90;
const markup = renderToStaticMarkup(createElement(MetaQuotaBody, { quota, classes }));
expect(markup).toContain(i18n.t('meta_quota.window_duration', { minutes: 90 }));
});
test('distinguishes unknown and exhausted quotas', () => {
const quota = snapshot();
quota.data!.windows[0].usedPercent = null;