Skip to content

Commit eb542c9

Browse files
author
sheepzh
committed
Support optional locales for development
1 parent 8aa7c19 commit eb542c9

File tree

6 files changed

+47
-45
lines changed

6 files changed

+47
-45
lines changed

global.d.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -190,15 +190,20 @@ declare namespace timer {
190190
* @since 1.4.0
191191
*/
192192
type SourceLocale = 'en'
193-
194193
/**
195-
* @since 0.8.0
194+
* The locale must be translated with code
195+
*
196+
* @since 1.5.3
196197
*/
197-
type Locale = SourceLocale
198-
| 'zh_CN'
198+
type RequiredLocale = SourceLocale | 'zh_CN'
199+
type OptionalLocale =
199200
| 'ja'
200201
// @since 0.9.0
201202
| 'zh_TW'
203+
/**
204+
* @since 0.8.0
205+
*/
206+
type Locale = RequiredLocale | OptionalLocale
202207

203208
/**
204209
* Translating locales
@@ -575,4 +580,13 @@ declare type ChromeAlarm = chrome.alarms.Alarm
575580
// chrome.runtime
576581
declare type ChromeOnInstalledReason = chrome.runtime.OnInstalledReason
577582
declare type ChromeMessageSender = chrome.runtime.MessageSender
578-
declare type ChromeMessageHandler<T = any, R = any> = (req: timer.mq.Request<T>, sender: ChromeMessageSender) => Promise<timer.mq.Response<R>>
583+
declare type ChromeMessageHandler<T = any, R = any> = (req: timer.mq.Request<T>, sender: ChromeMessageSender) => Promise<timer.mq.Response<R>>
584+
585+
// Embedded partial
586+
declare type EmbeddedPartial<T> = {
587+
[P in keyof T]?: T[P] extends Array<infer U>
588+
? Array<EmbeddedPartial<U>>
589+
: T[P] extends ReadonlyArray<infer U>
590+
? ReadonlyArray<EmbeddedPartial<U>>
591+
: EmbeddedPartial<T[P]>;
592+
}

script/crowdin/common.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ export async function readAllMessages(dir: Dir): Promise<Record<string, Messages
7171
return result
7272
}
7373

74-
7574
/**
7675
* Merge crowdin message into locale codes
7776
*/

src/app/components/option/common.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ import { OptionMessage } from "@i18n/message/app/option"
1818
* @param label label
1919
* @param defaultValue default value
2020
*/
21-
export function renderOptionItem(input: VNode | { [key: string]: VNode }, label: (msg: OptionMessage) => string, defaultValue?: string | number) {
21+
export function renderOptionItem(
22+
input: VNode | { [key: string]: VNode },
23+
label: (msg: OptionMessage | EmbeddedPartial<OptionMessage>) => string,
24+
defaultValue?: string | number
25+
) {
2226
const param = isVNode(input) ? { input } : input
2327
const labelArcher = h('a', { class: 'option-label' }, tN(msg => label(msg.option), param))
2428
const content = [labelArcher]

src/i18n/i18n.d.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1+
type RequiredMessages<M> = {
2+
[locale in timer.RequiredLocale]: M
3+
}
14

2-
type Messages<M> = {
3-
[locale in timer.Locale]: M
5+
type OptionalMessages<M> = {
6+
[locale in timer.OptionalLocale]?: EmbeddedPartial<M>
47
}
8+
9+
type Messages<M> = RequiredMessages<M> & OptionalMessages<M>

src/i18n/index.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,24 @@ export async function initLocale() {
109109

110110
optionService.addOptionChangeListener(handleLocaleOption)
111111

112+
function tryGetOriginalI18nVal<MessageType>(
113+
messages: Messages<MessageType>,
114+
keyPath: I18nKey<MessageType>,
115+
specLocale?: timer.Locale
116+
) {
117+
try {
118+
return keyPath(messages[specLocale || locale])
119+
} catch (ignore) {
120+
return undefined
121+
}
122+
}
123+
112124
export function getI18nVal<MessageType>(
113125
messages: Messages<MessageType>,
114126
keyPath: I18nKey<MessageType>,
115127
specLocale?: timer.Locale
116128
): string {
117-
const result = keyPath(messages[specLocale || locale])
129+
const result = tryGetOriginalI18nVal(messages, keyPath, specLocale)
118130
|| keyPath(messages[FEEDBACK_LOCALE])
119131
|| ''
120132
return typeof result === 'string' ? result : JSON.stringify(result)
@@ -141,4 +153,4 @@ export function t<MessageType>(messages: Messages<MessageType>, props: Translate
141153
return param ? fillWithParam(result, param) : result
142154
}
143155

144-
export type I18nKey<MessageType> = (messages: MessageType) => any
156+
export type I18nKey<MessageType> = (messages: MessageType | EmbeddedPartial<MessageType>) => any

src/i18n/message/app/help-us.ts

Lines changed: 2 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const _default: Messages<HelpUsMessage> = {
2525
l1: '由于作者的语言能力,该扩展原生只支持简体中文和英语,其他语言要么缺失,要么就严重依赖机器翻译。',
2626
l2: '为了能够提供更好的用户体验,我将其他语言的翻译任务托管在了 Crowdin 上。Crowdin 是一个对开源软件免费的翻译管理系统。',
2727
l3: '如果您觉得这个扩展对您有用,并且您愿意完善它的文本翻译的话,可以点击下方按钮前往 Crowdin 上的项目主页。',
28-
l4: '当某种语言的翻译进度达到 80% 之后,我将会考虑在扩展中支持它。',
28+
l4: '当某种语言的翻译进度达到 50% 之后,我将会考虑在扩展中支持它。',
2929
},
3030
button: '前往 Crowdin',
3131
loading: '正在查询翻译进度...',
@@ -41,39 +41,7 @@ const _default: Messages<HelpUsMessage> = {
4141
Crowdin is a translation management system free for open source software.',
4242
l3: 'If you find this extension useful to you and you are willing to improve its translation, \
4343
you can click the button below to go to the project home page on Crowdin.',
44-
l4: 'When the translation progress of a language reaches 80%, I will consider supporting it in this extension.',
45-
},
46-
button: 'Go Crowdin',
47-
loading: 'Checking translation progress...',
48-
},
49-
ja: {
50-
title: 'Feel free to help improve the extension\'s localization translations!',
51-
alert: {
52-
l1: 'Due to the author\'s language ability, \
53-
the extension only supports Simplified Chinese and English natively, \
54-
and other languages are either missing or rely heavily on machine translation.',
55-
l2: 'In order to provide a better user experience, \
56-
I host the translation tasks for other languages on Crowdin. \
57-
Crowdin is a translation management system free for open source software.',
58-
l3: 'If you find this extension useful to you and you are willing to improve its translation, \
59-
you can click the button below to go to the project home page on Crowdin.',
60-
l4: 'When the translation progress of a language reaches 80%, I will consider supporting it in this extension.',
61-
},
62-
button: 'Go Crowdin',
63-
loading: 'Checking translation progress...',
64-
},
65-
zh_TW: {
66-
title: 'Feel free to help improve the extension\'s localization translations!',
67-
alert: {
68-
l1: 'Due to the author\'s language ability, \
69-
the extension only supports Simplified Chinese and English natively, \
70-
and other languages are either missing or rely heavily on machine translation.',
71-
l2: 'In order to provide a better user experience, \
72-
I host the translation tasks for other languages on Crowdin. \
73-
Crowdin is a translation management system free for open source software.',
74-
l3: 'If you find this extension useful to you and you are willing to improve its translation, \
75-
you can click the button below to go to the project home page on Crowdin.',
76-
l4: 'When the translation progress of a language reaches 80%, I will consider supporting it in this extension.',
44+
l4: 'When the translation progress of a language reaches 50%, I will consider supporting it in this extension.',
7745
},
7846
button: 'Go Crowdin',
7947
loading: 'Checking translation progress...',

0 commit comments

Comments
 (0)