From 602a132c0c0a42d43876d2ef919b938740e74ca5 Mon Sep 17 00:00:00 2001 From: Matt Roberts Date: Thu, 28 Nov 2024 20:31:58 +0000 Subject: [PATCH] Added Chinese (Simplified) --- app/pkg/i18n/i18n.go | 1 + locale/locales.ts | 3 + locale/zh-CN/client.json | 160 +++++++++++++++++++++++++++++++++++++++ locale/zh-CN/server.json | 62 +++++++++++++++ package.json | 1 + public/services/i18n.ts | 3 +- public/ssr.tsx | 1 + 7 files changed, 230 insertions(+), 1 deletion(-) create mode 100644 locale/zh-CN/client.json create mode 100644 locale/zh-CN/server.json diff --git a/app/pkg/i18n/i18n.go b/app/pkg/i18n/i18n.go index 28753aca8..ccf155880 100644 --- a/app/pkg/i18n/i18n.go +++ b/app/pkg/i18n/i18n.go @@ -28,6 +28,7 @@ var localeToPlurals = map[string]string{ "sk": "sk", "it": "it", "tr": "tr", + "zh-CN": "zh", } type Params map[string]any diff --git a/locale/locales.ts b/locale/locales.ts index 51f957583..e4a54b2fa 100644 --- a/locale/locales.ts +++ b/locale/locales.ts @@ -45,6 +45,9 @@ const locales: { [key: string]: Locale } = { ar: { text: "Arabic", }, + "zh-CN": { + text: "Chinese (Simplified)", + }, } export default locales diff --git a/locale/zh-CN/client.json b/locale/zh-CN/client.json new file mode 100644 index 000000000..951d84ac9 --- /dev/null +++ b/locale/zh-CN/client.json @@ -0,0 +1,160 @@ +{ + "action.cancel": "取消", + "action.change": "修改", + "action.close": "关闭", + "action.confirm": "确认", + "action.copylink": "复制链接", + "action.delete": "删除", + "action.edit": "编辑", + "action.markallasread": "将全部标记为已读", + "action.ok": "确定", + "action.respond": "回复/标记", + "action.save": "保存", + "action.signin": "登录", + "action.submit": "提交", + "enum.poststatus.completed": "完成", + "enum.poststatus.declined": "拒绝", + "enum.poststatus.deleted": "删除", + "enum.poststatus.duplicate": "重复", + "enum.poststatus.open": "开启", + "enum.poststatus.planned": "计划中", + "enum.poststatus.started": "进行中", + "error.expired.text": "您点击的链接已过期.", + "error.expired.title": "过期", + "error.forbidden.text": "您无权查看此页面.", + "error.forbidden.title": "被禁止的", + "error.internalerror.text": "发生错误,我们正在努力解决问题!我们很快就会投入运行.", + "error.internalerror.title": "哇!好吧,这太出乎意料了…", + "error.pagenotfound.text": "您点击的链接可能已断开,或者页面可能已被删除.", + "error.pagenotfound.title": "未找到页面", + "error.unauthorized.text": "您无权查看此页面.", + "error.unauthorized.title": "未经授权", + "home.form.defaultinvitation": "在此处输入您的建议...", + "home.form.defaultwelcomemessage": "我们很想听听你在想什么。\n\n我们能做得更好吗?这是您投票、讨论和分享想法的地方.", + "home.lonely.suggestion": "建议您在共享此网站之前,在此处创建<0>至少3个建议。初始内容对于开始吸引观众很重要.", + "home.lonely.text": "尚未创建任何帖子.", + "home.postfilter.label.view": "看板", + "home.postfilter.option.mostdiscussed": "讨论最多", + "home.postfilter.option.mostwanted": "投票最多", + "home.postfilter.option.myvotes": "我的投票", + "home.postfilter.option.recent": "最近", + "home.postfilter.option.trending": "趋势", + "home.postinput.description.placeholder": "描述你的建议(可选)", + "home.postscontainer.label.noresults": "没有与您的搜索匹配的结果,请尝试其他搜索.", + "home.postscontainer.label.viewmore": "查看更多帖子", + "home.postscontainer.query.placeholder": "搜索", + "home.similar.subtitle": "考虑对现有内容进行投票.", + "home.similar.title": "类似帖子", + "home.tagsfilter.label.with": "关于", + "home.tagsfilter.selected.none": "任何标签", + "label.actions": "行动", + "label.avatar": "Avatar", + "label.custom": "自定义", + "label.description": "说明", + "label.discussion": "讨论", + "label.email": "邮箱", + "label.gravatar": "Gravatar", + "label.letter": "稍后", + "label.moderation": "管理", + "label.name": "名称", + "label.none": "None", + "label.notifications": "通知", + "label.or": "或者", + "label.subscribe": "订阅", + "label.tags": "标签", + "label.unread": "未读", + "label.unsubscribe": "取消订阅", + "label.voters": "投票者", + "legal.agreement": "我已阅读并同意 <0/> 和 <1/>.", + "legal.notice": "登录即表示您同意 <0/> and <1/>.", + "legal.privacypolicy": "隐私政策", + "legal.termsofservice": "服务条款", + "menu.administration": "管理", + "menu.mysettings": "我的设置", + "menu.signout": "退出", + "menu.sitesettings": "站点设置", + "modal.changeemail.header": "确认你的新邮箱", + "modal.changeemail.text": "我们刚刚向发送了一个确认链接 <0>{0}. <1/> 点击链接更新您的电子邮件.", + "modal.completeprofile.header": "填写您的个人资料", + "modal.completeprofile.name.placeholder": "名称", + "modal.completeprofile.text": "因为这是您第一次登录,请输入您的姓名.", + "modal.deleteaccount.header": "删除帐户", + "modal.deleteaccount.text": "<0>当您选择删除您的帐户时,我们将永远删除您的所有个人信息。您发布的内容将保留,但将匿名.<1>这个过程是不可逆转的. <2>你确定吗?", + "modal.deletecomment.header": "删除评论", + "modal.deletecomment.text": "这个过程是不可逆转的. <0>你确定吗?", + "modal.notifications.nonew": "无新通知", + "modal.notifications.previous": "以前的通知", + "modal.notifications.unread": "未读通知", + "modal.showvotes.message.zeromatches": "未找到匹配的用户 <0>{0}.", + "modal.showvotes.query.placeholder": "按名称搜索用户...", + "modal.signin.header": "登录参与投票", + "mynotifications.label.readrecently": "过去30天阅读.", + "mynotifications.message.nounread": "无未读通知.", + "mynotifications.page.subtitle": "及时了解正在发生的事情", + "mynotifications.page.title": "通知", + "mysettings.apikey.documentation": "要了解如何使用API,请阅读 <0>官方文档.", + "mysettings.apikey.generate": "重新生成API密钥", + "mysettings.apikey.newkey": "您的新API密钥是: <0>{0}", + "mysettings.apikey.newkeynotice": "将其安全地存储在服务器上,切勿将其存储在应用程序的客户端.", + "mysettings.apikey.notice": "API密钥仅在生成时显示。如果您的密钥丢失或已被泄露,请生成一个新的密钥并记录下来.", + "mysettings.apikey.title": "API 密钥", + "mysettings.dangerzone.delete": "删除我的帐户", + "mysettings.dangerzone.notice": "这个过程是不可逆转的. 请确定.", + "mysettings.dangerzone.text": "当您选择删除您的帐户时,我们将永远删除您的所有个人信息。您发布的内容将保留,但将匿名.", + "mysettings.dangerzone.title": "删除帐户", + "mysettings.message.avatar.custom": "我们接受小于100KB、纵横比为1:1、最小尺寸为50x50像素的JPG、GIF和PNG图像.", + "mysettings.message.avatar.gravatar": "一个 <0>Gravatar 将根据您的电子邮件使用。如果你没有Gravatar,系统会为你生成一个基于你首字母的字母头像.", + "mysettings.message.avatar.letter": "根据您的首字母为您生成一个字母头像.", + "mysettings.message.noemail": "您的帐户没有电子邮件.", + "mysettings.message.privateemail": "您的电子邮件是私人的,永远不会公开显示.", + "mysettings.notification.channelemail": "电子邮件", + "mysettings.notification.channelweb": "网站", + "mysettings.notification.event.discussion": "讨论", + "mysettings.notification.event.discussion.staff": "对所有帖子发表评论,除非单独取消订阅", + "mysettings.notification.event.discussion.visitors": "对您订阅的帖子的评论", + "mysettings.notification.event.newpost": "新帖子", + "mysettings.notification.event.newpost.staff": "本网站上的新帖子", + "mysettings.notification.event.newpost.visitors": "本网站上的新帖子", + "mysettings.notification.event.statuschanged": "状态已更改", + "mysettings.notification.event.statuschanged.staff": "除非单独取消订阅,否则所有帖子的状态都会发生变化", + "mysettings.notification.event.statuschanged.visitors": "您订阅的帖子的状态更改", + "mysettings.notification.message.emailonly": "您将收到 <0>电子邮件 相关的通知 {about}.", + "mysettings.notification.message.none": "您将 <0>不会 收到有关此事件的任何通知.", + "mysettings.notification.message.webandemail": "您将收到关于以下内容的<0>网络和<1>电子邮件通知 {about}.", + "mysettings.notification.message.webonly": "您将收到有关以下内容的<0>网络通知 {about}.", + "mysettings.notification.title": "使用以下面板选择要接收通知的事件", + "mysettings.page.subtitle": "管理您的个人资料设置", + "mysettings.page.title": "设置", + "page.backhome": "带我回到<0>{0}主页.", + "page.notinvited.text": "我们找不到您电子邮件地址的帐户.", + "page.notinvited.title": "未被邀请", + "page.pendingactivation.text": "我们向您发送了一封确认电子邮件,其中包含激活您账户的网站链接.", + "page.pendingactivation.text2": "请检查您的收件箱以激活它.", + "page.pendingactivation.title": "您的帐户正在等待激活", + "showpost.comment.copylink.error": "复制评论链接失败,请复制页面URL", + "showpost.comment.copylink.success": "评论链接已复制到剪贴板", + "showpost.comment.unknownhighlighted": "无效的评论ID #{id}", + "showpost.commentinput.placeholder": "发表评论", + "showpost.discussionpanel.emptymessage": "还没有人发表评论.", + "showpost.label.author": "发表者 <0/> · <1/>", + "showpost.message.nodescription": "未提供描述.", + "showpost.moderationpanel.text.help": "此操作<0>无法撤消.", + "showpost.moderationpanel.text.placeholder": "你为什么要删除这篇内容?(可选)", + "showpost.notificationspanel.message.subscribed": "您正在收到有关此帖子活动的通知.", + "showpost.notificationspanel.message.unsubscribed": "您将不会收到有关此帖子的任何通知.", + "showpost.postsearch.numofvotes": "{0} 投票", + "showpost.postsearch.query.placeholder": "搜索原始帖子...", + "showpost.responseform.message.mergedvotes": "此帖子的投票将合并到原始帖子中.", + "showpost.responseform.text.placeholder": "这篇文章怎么了?让你的用户知道你的计划是什么...", + "showpost.votespanel.more": "+{extraVotesCount} 更多", + "showpost.votespanel.seedetails": "查看详细信息", + "signin.message.email": "输入您的电子邮件地址以登录", + "signin.message.emaildisabled": "管理员已禁用电子邮件身份验证。如果您有管理员帐户并且需要绕过此限制,请 <0>点击这里.", + "signin.message.emailsent": "我们刚刚向发送了一个确认链接 <0>{email}. 单击链接,您将登录.", + "signin.message.locked.text": "要重新激活此网站,请使用管理员帐户登录并更新所需的设置.", + "signin.message.locked.title": "<0>{0} 当前已锁定.", + "signin.message.onlyadmins": "目前只允许登录管理员帐户", + "signin.message.private.text": "如果您有帐户或邀请,您可以使用以下选项登录.", + "signin.message.private.title": "<0>{0} 这是一个私人空间,您必须登录才能参与和投票.", + "{count, plural, one {# tag} other {# tags}}": "{count, plural, one {# tag} other {# tags}}" +} \ No newline at end of file diff --git a/locale/zh-CN/server.json b/locale/zh-CN/server.json new file mode 100644 index 000000000..9fef03c40 --- /dev/null +++ b/locale/zh-CN/server.json @@ -0,0 +1,62 @@ +{ + "property.avatarType": "头像类型", + "property.name": "名称", + "property.image": "图片", + "property.customdomain": "自定义域名", + "property.key": "密码", + "property.email": "电子邮件", + "property.title": "标题", + "property.comment": "评论", + "property.status": "状态", + "validation.required": "{name} 是必需的.", + "validation.invalid": "{name} 无效.", + "validation.invalidvalue": "{name} 具有无效值 '{value}'.", + "validation.maxstringlen": "{name} 必须小于 {len} 字符.", + "validation.custom.maxattachments": "每篇帖子允许添加最多 {number} 个附件.", + "validation.custom.differentemail": "选择其他电子邮件.", + "validation.custom.emailtaken": "此电子邮件已被其他人使用", + "validation.custom.descriptivetitle": "标题需要更具描述性.", + "validation.custom.duplicatetitle": "这已经发布过了.", + "validation.custom.selfduplicate": "不能与自身重复.", + "validation.custom.originalpostnotfound": "未找到原始帖子.", + "validation.custom.cannotdeleteduplicatepost": "无法删除此帖子,因为它被重复的帖子引用.", + "validation.custom.unknownsettings": "未知的设置 '{name}'", + "validation.custom.invalidemail": "'{email}' 不是有效的电子邮件地址.", + "validation.custom.invalidurl": "'{url}' 不是有效的URL.", + "validation.custom.invalidcustomdomain": "'{domain}' 不是有效的自定义域.", + "validation.custom.customdomaintaken": "此自定义域已被其他人使用.", + "validation.custom.unsupportedfileformat": "不支持此文件格式.", + "validation.custom.minimagedimensions": "图像的最小尺寸必须为 {width}x{height} 像素.", + "validation.custom.imagesquareratio": "图像的纵横比必须为 1:1.", + "validation.custom.maximagesize": "图像大小必须小于 {kilobytes}KB.", + "enum.poststatus.open": "打开", + "enum.poststatus.started": "启动", + "enum.poststatus.completed": "完成", + "enum.poststatus.declined": "拒绝", + "enum.poststatus.planned": "计划中", + "enum.poststatus.duplicate": "重复", + "enum.poststatus.deleted": "删除", + "email.change_emailaddress.subject": "确认您的新电子邮件", + "email.change_emailaddress.request": "您已请求更改电子邮件 {oldEmail} 为 {newEmail}.", + "email.subscription.view": "在浏览器上查看", + "email.subscription.change": "更改您的通知首选项", + "email.subscription.unsubscribe": "取消订阅", + "email.greetings": "Hello!", + "email.greetings_name": "Hello, {name}!", + "email.operation_confirmation": "单击下面的链接确认此操作.", + "email.footer.noreply": "此电子邮件是从无法接受传入电子邮件的仅通知地址发送的。请不要回复此消息.", + "email.change_status.duplicate": "{title} ({postLink}) 已作为一个已关闭的 复制品 关于 {duplicate}.", + "email.change_status.others": "状态 {title} ({postLink}) 已更改为 {status}.", + "email.delete_post.text": "{title} 已经 删除了.", + "email.new_comment.text": "{userName} 发表评论 {title} ({postLink}).", + "email.new_post.text": "{userName} 创建了一个新帖子 {title} ({postLink}).", + "email.signin_email.subject": "登录到 {siteName}", + "email.signin_email.text": "您要求我们向您发送登录链接,现在是.", + "email.signin_email.confirmation": "单击下面的链接登录 {siteName}.", + "email.signup_email.subject": "您的新 Fider 网站", + "email.signup_email.text": "您距离激活 Fider 网站仅一步之遥.", + "email.signup_email.confirmation": "通过下面的链接,您可以验证您的电子邮件地址并完成激活过程.", + "email.footer.subscription_notice": "您收到此电子邮件是因为您订阅了此帖子。你可以 {view}, {unsubscribe} 或者 {change}.", + "email.footer.subscription_notice2": "您收到此电子邮件是因为您订阅了此帖子。你可以 {change}.", + "email.footer.subscription_notice3": "您收到此电子邮件是因为您订阅了此帖子。你可以 {view} 或者 {change}." +} diff --git a/package.json b/package.json index 87fffd7ce..62d2f2b42 100644 --- a/package.json +++ b/package.json @@ -89,6 +89,7 @@ "sk", "tr", "it", + "zh-CN", "el" ] }, diff --git a/public/services/i18n.ts b/public/services/i18n.ts index 27be3864e..c721e154b 100644 --- a/public/services/i18n.ts +++ b/public/services/i18n.ts @@ -1,5 +1,5 @@ import { i18n, I18n } from "@lingui/core" -import { en, pt, fr, el, de, se, pl, ru, sk, nl, es, tr, it } from "make-plural/plurals" +import { en, pt, fr, el, de, se, pl, ru, sk, nl, es, tr, it, zh } from "make-plural/plurals" export function activateI18NSync(locale: string, messages?: any): I18n { i18n.loadLocaleData("en", { plurals: en }) @@ -15,6 +15,7 @@ export function activateI18NSync(locale: string, messages?: any): I18n { i18n.loadLocaleData("ru", { plurals: ru }) i18n.loadLocaleData("sk", { plurals: sk }) i18n.loadLocaleData("tr", { plurals: tr }) + i18n.loadLocaleData("zh-CH", { plurals: zh }) i18n.load(locale, messages) i18n.activate(locale) return i18n diff --git a/public/ssr.tsx b/public/ssr.tsx index 6c3936008..d418aacd9 100644 --- a/public/ssr.tsx +++ b/public/ssr.tsx @@ -14,6 +14,7 @@ const messages: { [key: string]: any } = { "sv-SE": require(`../locale/sv-SE/client`), it: require(`../locale/it/client`), "es-ES": require(`../locale/es-ES/client`), + "zh-CN": require(`../locale/zh-CN/client`), el: require(`../locale/el/client`), nl: require(`../locale/nl/client`), de: require(`../locale/de/client`),