Skip to content

Commit

Permalink
refactor: remove i18next-browser-languagedetector dependency
Browse files Browse the repository at this point in the history
fix: resolve bug with Chinese translation not displaying
refactor: optimize Chinese translations
  • Loading branch information
dangehub committed Feb 11, 2025
1 parent 5488ab3 commit 51aab54
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 75 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,6 @@ yarn-error.log

# Backup files.
*.bak

# VS code config
.vscode/
2 changes: 0 additions & 2 deletions contributing/Translation/Overview of the translation setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ publish: true

- [i18next](https://www.i18next.com)
- i18next is an **internationalization-framework** written in and for JavaScript.
- [i18next-browser-languagedetector](https://github.com/i18next/i18next-browser-languageDetector)
- This is an i18next language detection plugin used to detect the user's language automatically.
- [i18next-parser](https://github.com/i18next/i18next-parser)
- When translating an application, maintaining the translation catalog by hand is painful. This package parses your code and automates this process, making sure that every locale file contains all the translation strings in the application.
- WebStorm
Expand Down
7 changes: 0 additions & 7 deletions esbuild.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -150,13 +150,6 @@ The MIT License (MIT)
Copyright (c) 2025 i18next
*/
/*
License i18next-browser-languagedetector (included library):
The MIT License (MIT)
Copyright (c) 2024 i18next
*/
/*
License mustache (included library):
Expand Down
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ module.exports = {
'^.+\\.ts$': 'ts-jest',
},
moduleFileExtensions: ['js', 'ts', 'svelte'],
testEnvironment: 'jsdom',

// A list of paths to modules that run some code to configure or
// set up the testing framework before each test.
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@
"eventemitter2": "^6.4.5",
"flatpickr": "^4.6.13",
"i18next": "^24.2.1",
"i18next-browser-languagedetector": "^8.0.2",
"mustache": "^4.2.0",
"mustache-validator": "^0.2.0",
"rrule": "^2.7.2"
Expand Down
33 changes: 18 additions & 15 deletions src/i18n/i18n.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,30 @@
import i18next from 'i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import en from './locales/en.json';
import zh_cn from './locales/zh_cn.json';

let isInitialized = false;

// Get Obsidian language settings
const getObsidianLanguage = (): string => {
return localStorage.getItem('language')?.toLowerCase() || 'en';
};

// Define a function to initialize i18next
export const initializeI18n = async () => {
if (!isInitialized) {
await i18next
.use(LanguageDetector) // Use language detector to determine user's language
.init({
// lng: 'zh_cn', // for testing, hard-code the language and remove the `use(LanguageDetector)` line
fallbackLng: 'en', // Fallback language if detection fails or translation is missing
returnEmptyString: false, // Use fallback language if i18next-parser put in empty value for untranslated text
resources: {
en: { translation: en },
zh_cn: { translation: zh_cn },
},
interpolation: {
escapeValue: false, // Disable escaping of strings, like '&' -> '&'
},
});
await i18next.init({
lng: getObsidianLanguage(),
fallbackLng: 'en', // Fallback language if detection fails or translation is missing
returnEmptyString: false, // Use fallback language if i18next-parser put in empty value for untranslated text
resources: {
en: { translation: en },
zh: { translation: zh_cn }, //Enter `localStorage.getItem("language")` in the console to check the current language code.
},
interpolation: {
escapeValue: false, // Disable escaping of strings, like '&' -> '&'
},
});

isInitialized = true;
}
};
Expand Down
86 changes: 43 additions & 43 deletions src/i18n/locales/zh_cn.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,23 @@
"modals": {
"customStatusModal": {
"editAvailableAsCommand": {
"description": "如果启用,此状态将作为命令可用,因此您可以指定热键并使用它切换状态.",
"description": "如果启用此状态将作为命令可用,因此您可以指定快捷键并使用它切换状态。",
"name": "可用作命令"
},
"editNextStatusSymbol": {
"description": "单击时,这是下一步应该使用的符号.",
"description": "单击时这是下一步应该使用的符号",
"name": "任务下一个状态符号"
},
"editStatusName": {
"description": "这是任务状态的友好名称.",
"name": "任务状态名称"
},
"editStatusSymbol": {
"description": "这是方括号中的字符.(仅可编辑自定义状态,不可编辑核心状态.)",
"description": "这是方括号中的字符。(仅可编辑自定义状态,不可编辑核心状态。)",
"name": "任务状态符号"
},
"editStatusType": {
"description": "控制搜索和切换状态的行为.",
"description": "控制搜索和切换状态的行为",
"name": "任务状态类型"
},
"fixErrorsBeforeSaving": "在保存前修复错误。"
Expand All @@ -31,13 +31,13 @@
"reports": {
"statusRegistry": {
"about": {
"createdBy": "此文件由黑曜石任务插件(版本 ${n})创建,以帮助可视化此保管库中的任务状态.",
"createdBy": "此文件由 Obsidian tasks 插件(version {{version}})创建,以帮助可视化此仓库中的任务状态.",
"deleteFileAnyTime": "您可以随时删除此文件.",
"title": "关于此文件",
"updateReport": {
"line1": "如果更改“任务”状态设置,则可以通过以下方式获取更新的报告:",
"line2": "\\`设置\\` -> \\`Tasks\\`.",
"line3": "点击 \\`查看并检查您的状态\\"
"line1": "如果更改 Tasks 状态设置,则可以通过以下方式获取更新后的报告:",
"line2": "前往 `设置` -> `Tasks`。",
"line3": "点击 `查看并检查您的状态`。"
}
},
"columnHeadings": {
Expand All @@ -48,7 +48,7 @@
"statusType": "状态类型"
},
"loadedSettings": {
"settingsActuallyUsed": "这些是任务实际使用的设置.",
"settingsActuallyUsed": "这些是 Tasks 实际使用的设置.",
"switchToLivePreview": "切换到实时预览或阅读模式以查看图表.",
"title": "已加载设置"
},
Expand Down Expand Up @@ -79,30 +79,30 @@
"autoSuggest": {
"heading": "自动建议",
"maxSuggestions": {
"description": "当自动建议菜单弹出时,应显示多少条建议 (包含 \"\\u23CE\" 选项).",
"description": "当自动建议菜单弹出时应显示多少条建议 (包含 \"\" 选项)",
"name": "要显示的最大自动建议数"
},
"minLength": {
"description": "如果高于0,则只有在识别出任何支持的关键字的开头时才会触发自动建议.",
"description": "如果高于0则只有在识别出任何支持的关键字的开头时才会触发自动建议",
"name": "自动建议的最小匹配长度"
},
"toggle": {
"description": "启用此选项将打开一个智能建议菜单,同时在已识别的任务行中键入.",
"description": "启用此功能将在识别的任务行内输入时打开智能建议菜单。",
"name": "自动建议任务内容"
}
},
"changeRequiresRestart": "更改任何设置都需要重新启动Obsidian.",
"changeRequiresRestart": "更改任何设置都需要重新启动Obsidian",
"dates": {
"cancelledDate": {
"description": "启用此功能将添加时间戳 ❌ YYYY-MM-DD 在结尾,当任务切换为取消时.",
"name": "为每个已取消的任务设置已取消的日期"
"description": "启用此功能将在任务设置为取消时,在其末尾添加时间戳 ❌ YYYY-MM-DD",
"name": "设置每个已取消的任务的取消日期"
},
"createdDate": {
"description": "启用此功能将添加时间戳 ➕ YYYY-MM-DD 在其他日期值之前,当使用“创建或编辑任务”创建任务时,或通过完成定期任务创建任务时.",
"name": "设置每个添加任务的创建日期"
"description": "启用此功能将在通过“Create or edit task”命令或完成重复任务时,在其他日期值之前添加时间戳➕YYYY-MM-DD",
"name": "设置每个已添加任务的创建日期"
},
"doneDate": {
"description": "启用此功能将添加时间戳 ✅ YYYY-MM-DD 在任务切换为已完成时结束.",
"description": "启用此功能将在任务被设置为完成时,在其末尾添加时间戳 ✅ YYYY-MM-DD",
"name": "设置每个已完成任务的完成日期"
},
"heading": "日期"
Expand All @@ -112,38 +112,38 @@
"scheduledDate": {
"extraFormat": {
"description": {
"line1": "当使用文件名作为未注明日期的任务的计划日期时,任务插件将识别的另一种日期格式.",
"line1": "任务插件在将文件名用作未注明日期任务的计划日期时,将识别的附加日期格式。",
"line2": "语法参考"
},
"name": "为无日期任务添加文件名日期格式作为计划日期",
"placeholder": "示例:MMM DD YYYY"
"placeholder": "示例MMM DD YYYY"
},
"folders": {
"description": "如果要处处使用默认的“计划日期”,请保留为空,或者输入以逗号分隔的文件夹列表",
"description": "如果要在全局使用默认的计划日期,请保留为空,或者输入以逗号分隔的文件夹列表",
"name": "具有默认计划日期的文件夹"
},
"toggle": {
"description": {
"line1": "输入计划 (⏳) 日期节省时间",
"line2": "如果启用此选项,则任何未注明日期的任务都将获得从其文件名中提取的默认“计划日期”.",
"line3": "默认情况下,tasks 插件将匹配 <code>YYYY-MM-DD</code> 和 <code>YYYYMMDD</code> 两种日期格式。",
"line4": "未定日期的任务没有截止日期 (📅 ), 计划日期 (⏳) 和开始日期(🛫) 。"
"line1": "用于节省输入计划 (⏳) 日期的时间。",
"line2": "如果启用此选项,则任何未注明日期的任务都将被赋予从其文件名中提取的默认“计划日期”",
"line3": "默认情况下,Tasks 插件将匹配 <code>YYYY-MM-DD</code> 和 <code>YYYYMMDD</code> 两种日期格式。",
"line4": "未注明日期的任务指没有截止日期 (📅 ), 计划日期 (⏳) 和开始日期(🛫) 的任务"
},
"name": "将文件名用作未注明日期的任务的计划日期"
}
}
},
"dialogs": {
"accessKeys": {
"description": "如果对话框中各种控件的访问键(键盘快捷键)与系统键盘快捷键或对您很重要的辅助技术功能相冲突,您可能需要在此处停用它们.",
"name": "在对话框中提供访问密钥"
"description": "如果对话框中各种控件的快捷键与系统快捷键发生冲突,您可以在这里停用它们。",
"name": "在对话框中使用快捷键"
},
"heading": "对话框"
},
"format": {
"description": {
"line1": "任务用于读取和写入任务的格式.",
"line2": "<b>重点:</b> 任务当前一次只支持一种格式.选择数据视图当前将 <b>停止Tasks读取自己的表情符号</b>"
"line1": "Tasks 用于读取和写入任务的格式.",
"line2": "<b>重点:</b> 目前 Tasks 只支持同时使用一种格式。选择 dataview 将 <b>使 Tasks 停止读取自有的表情符号格式</b>"
},
"displayName": {
"dataview": "Dataview 格式",
Expand All @@ -154,10 +154,10 @@
"globalFilter": {
"filter": {
"description": {
"line1": "建议:如果您希望仓库中的所有检查表项目都是由此插件管理的任务,请保留为空",
"line2": "如果您希望“任务”仅作用于 \"<code>- [ ]</code>\" 检查表项的子集,请使用全局筛选器,以便检查表项必须在其描述中包含指定的字符串才能被视为任务.",
"line3": "例如,如果将全局筛选器设置为 <code>#task</code>,则Tasks插件将仅处理标记为 <code>#task</code> 的检查表项.",
"line4": "其他检查表项目将保持正常的检查表项目,不会出现在查询中或设置完成日期."
"line1": "建议:如果您希望仓库中的所有任务列表项都由此插件管理,请留空。",
"line2": "如果您希望 Tasks 仅作用于 \"<code>- [ ]</code>\" 任务列表项的子集,请使用全局筛选器,以便只有在其描述中包含指定的字符串的任务列表项才被视为任务。",
"line3": "例如如果将全局筛选器设置为 <code>#task</code>,则 Tasks 插件将仅处理标记为 <code>#task</code> 的任务列表项。",
"line4": "其他任务列表项将保持正常,不会出现在查询中或设置完成日期"
},
"name": "全局筛选器",
"placeholder": "例如:#task 或 TODO"
Expand All @@ -171,18 +171,18 @@
"globalQuery": {
"heading": "全局查询",
"query": {
"description": "自动包含在库中每个“任务”块开头的查询.用于添加默认过滤器或布局选项.",
"description": "自动包含在库中每个 Tasks 块开头的查询语句.用于添加默认过滤器或布局选项",
"placeholder": "例如...\npath does not include _templates/\nlimit 300\nshow urgency"
}
},
"recurringTasks": {
"heading": "重复性任务",
"nextLine": {
"description": "启用此选项将使任务的下一个重复出现在已完成任务下方的行中.否则,下一次重复将出现在已完成的重复之前.",
"name": "下一个重复出现在下一行"
"description": "启用此功能后,任务的下一次重复将显示在已完成任务的下一行。若关闭此功能,则下一次重复将出现在已完成任务的上一行。",
"name": "把任务的下一次重复放在下一行"
}
},
"seeTheDocumentation": "请参阅文档",
"seeTheDocumentation": "参阅文档",
"statuses": {
"collections": {
"anuppuccinTheme": "AnuPpuccin 主题",
Expand All @@ -207,8 +207,8 @@
}
},
"description": {
"line1": "这些是Tasks本机支持的核心状态,不需要自定义CSS样式或主题.",
"line2": "您可以在下面的部分中添加编辑和添加自己的自定义状态."
"line1": "这些是 Tasks 原生支持的核心状态,不需要自定义CSS样式或主题",
"line2": "您可以在下面编辑和添加自定义状态。"
},
"heading": "核心状态"
},
Expand All @@ -225,10 +225,10 @@
}
},
"description": {
"line1": "您应该首先<b>选择并安装CSS代码段或主题<b>以设置自定义复选框的样式",
"line2": "然后,使用下面的按钮设置您的自定义状态,以匹配您选择的CSS复选框.",
"line3": "<b>注意</b>任何与任何早期状态具有相同符号的状态都将被忽略.您可以通过运行“创建或编辑任务”命令并查看“状态”下拉列表来确认实际加载的状态.",
"line4": "查看文档以开始"
"line1": "您应该首先<b>选择并安装 CSS代码段或主题<b>以设置自定义复选框的样式",
"line2": "然后使用下面的按钮设置您的自定义状态,以匹配您选择的CSS复选框.",
"line3": "<b>注意</b>任何与更早的状态具有相同符号的状态都将被忽略.您可以通过运行“Create or edit task”命令并查看“Status”下拉列表来确认实际加载的状态",
"line4": "参阅文档"
},
"heading": "自定义状态"
},
Expand Down
7 changes: 0 additions & 7 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3764,13 +3764,6 @@ human-signals@^2.1.0:
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==

i18next-browser-languagedetector@^8.0.2:
version "8.0.2"
resolved "https://registry.yarnpkg.com/i18next-browser-languagedetector/-/i18next-browser-languagedetector-8.0.2.tgz#037ca25c26877cad778f060a9e177054d9f8eaa3"
integrity sha512-shBvPmnIyZeD2VU5jVGIOWP7u9qNG3Lj7mpaiPFpbJ3LVfHZJvVzKR4v1Cb91wAOFpNw442N+LGPzHOHsten2g==
dependencies:
"@babel/runtime" "^7.23.2"

i18next-parser@^9.1.0:
version "9.1.0"
resolved "https://registry.yarnpkg.com/i18next-parser/-/i18next-parser-9.1.0.tgz#e1cc3f42c4b2e1b1013f1ad30e69f076a280af72"
Expand Down

0 comments on commit 51aab54

Please sign in to comment.