Skip to content

Commit bb99170

Browse files
authored
feat: add i18n supports (#168)
添加界面的 i18n 支持。 /kind feature Fixes #167 ```release-note 添加界面的 i18n 支持。 ```
1 parent db660bb commit bb99170

24 files changed

+746
-34
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,6 @@ build {
4141
}
4242

4343
halo {
44-
version = "2.18.0"
44+
version = "2.20"
4545
debug = true
4646
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"$schema": "https://raw.githubusercontent.com/lit/lit/main/packages/localize-tools/config.schema.json",
3+
"sourceLocale": "en",
4+
"targetLocales": [
5+
"es",
6+
"zh-CN",
7+
"zh-TW"
8+
],
9+
"tsConfig": "./tsconfig.json",
10+
"output": {
11+
"mode": "runtime",
12+
"outputDir": "./src/generated/locales",
13+
"localeCodesModule": "./src/generated/locale-codes.ts"
14+
},
15+
"interchange": {
16+
"format": "xliff",
17+
"xliffDir": "./xliff/"
18+
}
19+
}

packages/comment-widget/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,15 @@
3636
"@emoji-mart/data": "^1.1.2",
3737
"@halo-dev/api-client": "^2.14.0",
3838
"@lit/context": "^1.1.0",
39+
"@lit/localize": "^0.12.2",
3940
"dayjs": "^1.11.10",
4041
"emoji-mart": "^5.5.2",
4142
"javascript-time-ago": "^2.5.9",
4243
"lit": "^3.1.2",
4344
"lodash-es": "^4.17.21"
4445
},
4546
"devDependencies": {
47+
"@lit/localize-tools": "^0.8.0",
4648
"@types/lodash-es": "^4.17.12",
4749
"lit-analyzer": "^2.0.3"
4850
}

packages/comment-widget/src/base-comment-item.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { property } from 'lit/decorators.js';
44
import { formatDate, timeAgo } from './utils/date';
55
import baseStyles from './styles/base';
66
import varStyles from './styles/var';
7+
import { msg } from '@lit/localize';
78

89
export class BaseCommentItem extends LitElement {
910
@property({ type: String })
@@ -45,7 +46,7 @@ export class BaseCommentItem extends LitElement {
4546
<div class="item__meta-info" title=${formatDate(this.creationTime)}>
4647
${timeAgo(this.creationTime)}
4748
</div>
48-
${!this.approved ? html`<div class="item__meta-info">审核中</div>` : ''}
49+
${!this.approved ? html`<div class="item__meta-info">${msg('Reviewing')}</div>` : ''}
4950
</div>
5051
5152
<div class="item__content">

packages/comment-widget/src/base-form.ts

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import './icons/icon-loading';
1919
import { ToastManager } from './lit-toast';
2020
import baseStyles from './styles/base';
2121
import varStyles from './styles/var';
22+
import { msg } from '@lit/localize';
2223

2324
export class BaseForm extends LitElement {
2425
@consume({ context: baseUrlContext })
@@ -99,7 +100,7 @@ export class BaseForm extends LitElement {
99100
const response = await fetch(`/apis/api.commentwidget.halo.run/v1alpha1/captcha/-/generate`);
100101

101102
if (!response.ok) {
102-
this.toastManager?.error('获取验证码失败');
103+
this.toastManager?.error(msg('Failed to obtain verification code'));
103104
return;
104105
}
105106

@@ -111,7 +112,13 @@ export class BaseForm extends LitElement {
111112
}
112113

113114
async handleLogout() {
114-
if (window.confirm('点击确定将跳转至退出登录页面,请确保正在编辑的内容已保存。')) {
115+
if (
116+
window.confirm(
117+
msg(
118+
'Click OK to jump to the logout page, Please make sure the content being edited has been saved.'
119+
)
120+
)
121+
) {
115122
try {
116123
window.location.href = '/logout';
117124
} catch (error) {
@@ -125,7 +132,7 @@ export class BaseForm extends LitElement {
125132
${this.currentUser?.spec.avatar ? html`<img src=${this.currentUser.spec.avatar} />` : ''}
126133
<span> ${this.currentUser?.spec.displayName || this.currentUser?.metadata.name} </span>
127134
<button @click=${this.handleLogout} type="button" class="form__button--logout">
128-
退出登录
135+
${msg('Logout')}
129136
</button>
130137
</div>`;
131138
}
@@ -169,7 +176,7 @@ export class BaseForm extends LitElement {
169176
<textarea
170177
class="form__editor"
171178
${ref(this.textareaRef)}
172-
placeholder="编写评论"
179+
placeholder=${msg('Write a comment')}
173180
rows="4"
174181
name="content"
175182
required
@@ -182,23 +189,23 @@ export class BaseForm extends LitElement {
182189
name="displayName"
183190
value=${this.customAccount.displayName}
184191
type="text"
185-
placeholder="昵称"
192+
placeholder=${msg('Nicename')}
186193
required
187194
/>
188195
<input
189196
name="email"
190197
value=${this.customAccount.email}
191198
type="email"
192-
placeholder="电子邮件"
199+
placeholder=${msg('Email')}
193200
required
194201
/>
195202
<input
196203
name="website"
197204
value=${this.customAccount.website}
198205
type="url"
199-
placeholder="网站"
206+
placeholder=${msg('Website')}
200207
/>
201-
<a href=${this.loginUrl} rel="nofollow">(或登录账号)</a>
208+
<a href=${this.loginUrl} rel="nofollow">${msg('(Or login)')}</a>
202209
</div>`
203210
: ''}
204211
@@ -210,14 +217,18 @@ export class BaseForm extends LitElement {
210217
class="form__button--login"
211218
type="button"
212219
>
213-
登录
220+
${msg('Login')}
214221
</button> `
215222
: ''}
216223
<div class="form__actions">
217224
${this.showCaptcha
218225
? html`
219226
<div class="form__action--captcha">
220-
<input name="captchaCode" type="text" placeholder="请输入验证码" />
227+
<input
228+
name="captchaCode"
229+
type="text"
230+
placeholder=${msg('Please enter the verification code')}
231+
/>
221232
<img
222233
@click=${this.handleFetchCaptcha}
223234
src="${this.captcha}"
@@ -243,7 +254,7 @@ export class BaseForm extends LitElement {
243254
d="M8 7.71L18 12L8 16.29v-3.34l7.14-.95L8 11.05V7.71M12 2a10 10 0 0 1 10 10a10 10 0 0 1-10 10A10 10 0 0 1 2 12A10 10 0 0 1 12 2m0 2a8 8 0 0 0-8 8a8 8 0 0 0 8 8a8 8 0 0 0 8-8a8 8 0 0 0-8-8Z"
244255
></path>
245256
</svg>`}
246-
提交评论
257+
${msg('Submit')}
247258
</button>
248259
</div>
249260
</div>

packages/comment-widget/src/comment-form.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
} from './context';
1818
import { ToastManager } from './lit-toast';
1919
import { getCaptchaCodeHeader, isRequireCaptcha } from './utils/captcha';
20+
import { msg } from '@lit/localize';
2021

2122
export class CommentForm extends LitElement {
2223
@consume({ context: baseUrlContext })
@@ -91,14 +92,14 @@ export class CommentForm extends LitElement {
9192
};
9293

9394
if (!this.currentUser && !this.allowAnonymousComments) {
94-
this.toastManager?.warn('请先登录');
95+
this.toastManager?.warn(msg('Please login first'));
9596
this.submitting = false;
9697
return;
9798
}
9899

99100
if (!this.currentUser && this.allowAnonymousComments) {
100101
if (!displayName || !email) {
101-
this.toastManager?.warn('请先登录或者完善信息');
102+
this.toastManager?.warn(msg('Please log in or complete the information first'));
102103
this.submitting = false;
103104
return;
104105
} else {
@@ -130,15 +131,15 @@ export class CommentForm extends LitElement {
130131
this.baseFormRef.value?.handleFetchCaptcha();
131132

132133
if (!response.ok) {
133-
throw new Error('评论失败,请稍后重试');
134+
throw new Error(msg('Comment failed, please try again later'));
134135
}
135136

136137
const newComment = (await response.json()) as Comment;
137138

138139
if (newComment.spec.approved) {
139-
this.toastManager?.success('评论成功');
140+
this.toastManager?.success(msg('Comment submitted successfully'));
140141
} else {
141-
this.toastManager?.success('评论成功,等待审核');
142+
this.toastManager?.success(msg('Comment submitted successfully, pending review'));
142143
}
143144

144145
this.dispatchEvent(new CustomEvent('reload'));

packages/comment-widget/src/comment-item.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import varStyles from './styles/var';
1313
import { Ref, createRef, ref } from 'lit/directives/ref.js';
1414
import { CommentReplies } from './comment-replies';
1515
import { getPolicyInstance } from './avatar/avatar-policy';
16+
import { msg } from '@lit/localize';
1617

1718
export class CommentItem extends LitElement {
1819
@consume({ context: baseUrlContext })
@@ -178,7 +179,7 @@ export class CommentItem extends LitElement {
178179
${this.withReplies
179180
? html` <base-comment-item-action
180181
slot="action"
181-
.text=${this.showReplyForm ? '取消回复' : '加入回复'}
182+
.text=${this.showReplyForm ? msg('Cancel reply') : msg('Add reply')}
182183
@click="${() => (this.showReplyForm = !this.showReplyForm)}"
183184
>
184185
<svg

packages/comment-widget/src/comment-pagination.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { LitElement, css, html } from 'lit';
22
import { property } from 'lit/decorators.js';
33
import baseStyles from './styles/base';
44
import varStyles from './styles/var';
5+
import { msg } from '@lit/localize';
56

67
export class CommentPagination extends LitElement {
78
@property({ type: Number })
@@ -107,7 +108,7 @@ export class CommentPagination extends LitElement {
107108
d="m15 6l-6 6l6 6"
108109
/>
109110
</svg>
110-
上一页
111+
${msg('Previous')}
111112
</button>
112113
</li>
113114
${this.renderPageNumbers()}
@@ -116,7 +117,7 @@ export class CommentPagination extends LitElement {
116117
@click=${() => this.gotoPage(this.page + 1)}
117118
?disabled=${this.page === this.totalPages}
118119
>
119-
下一页
120+
${msg('Next')}
120121
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24">
121122
<path
122123
fill="none"

packages/comment-widget/src/comment-replies.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import './reply-form';
1010
import varStyles from './styles/var';
1111
import baseStyles from './styles/base';
1212
import { ToastManager } from './lit-toast';
13+
import { msg } from '@lit/localize';
1314

1415
export class CommentReplies extends LitElement {
1516
@consume({ context: baseUrlContext })
@@ -73,7 +74,7 @@ export class CommentReplies extends LitElement {
7374
${this.loading ? html` <loading-block></loading-block>` : ''}
7475
${this.hasNext && !this.loading
7576
? html` <div class="replies__next-wrapper">
76-
<button @click=${this.fetchNext}>加载更多</button>
77+
<button @click=${this.fetchNext}>${msg('Load more')}</button>
7778
</div>`
7879
: ''}
7980
</div>`;
@@ -99,7 +100,7 @@ export class CommentReplies extends LitElement {
99100
);
100101

101102
if (!response.ok) {
102-
throw new Error('加载回复列表失败,请稍后重试');
103+
throw new Error(msg('Failed to load reply list, please try again later'));
103104
}
104105

105106
const data = (await response.json()) as ReplyVoList;

packages/comment-widget/src/comment-widget.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import {
3535
import { ToastManager } from './lit-toast';
3636
import baseStyles from './styles/base';
3737
import varStyles from './styles/var';
38+
import { msg } from '@lit/localize';
3839

3940
export class CommentWidget extends LitElement {
4041
@provide({ context: baseUrlContext })
@@ -141,7 +142,7 @@ export class CommentWidget extends LitElement {
141142
: html`
142143
<div class="comment-widget__wrapper">
143144
<div class="comment-widget__stats">
144-
<span>${this.comments.total} 条评论</span>
145+
<span>${msg(html`${this.comments.total} Comments`)}</span>
145146
</div>
146147
147148
<div class="comment-widget__list">
@@ -213,7 +214,7 @@ export class CommentWidget extends LitElement {
213214
);
214215

215216
if (!response.ok) {
216-
throw new Error('评论列表加载失败,请稍后重试');
217+
throw new Error(msg('Failed to load comment list, please try again later'));
217218
}
218219

219220
this.comments = await response.json();

packages/comment-widget/src/emoji-button.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,21 @@ import varStyles from './styles/var';
1212
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
1313
//@ts-ignore
1414
import zh from '@emoji-mart/data/i18n/zh.json';
15+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
16+
//@ts-ignore
17+
import en from '@emoji-mart/data/i18n/en.json';
18+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
19+
//@ts-ignore
20+
import es from '@emoji-mart/data/i18n/es.json';
21+
import { msg } from '@lit/localize';
22+
import { getLocale } from './locale';
23+
24+
const localeMap = {
25+
'zh-CN': zh,
26+
'zh-TW': zh,
27+
en: en,
28+
es: es,
29+
};
1530

1631
export class EmojiButton extends LitElement {
1732
@state()
@@ -72,7 +87,7 @@ export class EmojiButton extends LitElement {
7287
onEmojiSelect: ({ native }: { native: string }) => {
7388
this.dispatchEvent(new CustomEvent('emoji-select', { detail: { native } }));
7489
},
75-
i18n: zh,
90+
i18n: localeMap[getLocale()],
7691
});
7792

7893
// TODO: fix this ts error
@@ -83,7 +98,7 @@ export class EmojiButton extends LitElement {
8398
}
8499

85100
override render() {
86-
return html`<button class="emoji-button" type="button" aria-label="选择表情">
101+
return html`<button class="emoji-button" type="button" aria-label=${msg('Select emoticon')}>
87102
${this.emojiLoading
88103
? html`<icon-loading></icon-loading>`
89104
: html`<icon-emoji @click=${this.handleOpenEmojiPicker}></icon-emoji>`}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Do not modify this file by hand!
2+
// Re-generate this file by running lit-localize.
3+
4+
/**
5+
* The locale code that templates in this source code are written in.
6+
*/
7+
export const sourceLocale = `en`;
8+
9+
/**
10+
* The other locale codes that this application is localized into. Sorted
11+
* lexicographically.
12+
*/
13+
export const targetLocales = [
14+
`es`,
15+
`zh-CN`,
16+
`zh-TW`,
17+
] as const;
18+
19+
/**
20+
* All valid project locale codes. Sorted lexicographically.
21+
*/
22+
export const allLocales = [
23+
`en`,
24+
`es`,
25+
`zh-CN`,
26+
`zh-TW`,
27+
] as const;

0 commit comments

Comments
 (0)