feat(i18n): add Japanese UI support#2285
Conversation
📝 WalkthroughWalkthrough本 PR 为应用引入日语:新增日语 .po 资源,扩展 i18n 工具与语言检测,添加配置枚举项并在初始化中同步模型语言;同时将大量 UI 与若干业务文案替换为 gt(...),并更新编译脚本以生成日语 mo 文件。 变更日语本地化支持实现
🎯 4 (Complex) | ⏱️ ~60 minutes
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
src/zzz_od/gui/view/devtools/icon_editor_dialog.py (1)
202-225: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win补齐本次变更方法签名的类型注解。
_on_selection_changed、_on_item_changed、_on_save_clicked在变更范围内仍缺少完整类型注解,和仓库 Python 规范不一致。建议修改
+from PySide6.QtWidgets import QTableWidgetItem @@ - def _on_selection_changed(self): + def _on_selection_changed(self) -> None: @@ - def _on_item_changed(self, item): + def _on_item_changed(self, item: QTableWidgetItem) -> None: @@ - def _on_save_clicked(self): + def _on_save_clicked(self) -> None:As per coding guidelines
**/*.py: "All functions and methods must include type hints (Type Hints)",且src/**/*.py: "All function signatures and class member variables must have type annotations"。🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/zzz_od/gui/view/devtools/icon_editor_dialog.py` around lines 202 - 225, Add explicit type hints to the three methods in icon_editor_dialog: change _on_selection_changed to declare its return type (e.g., def _on_selection_changed(self) -> None), change _on_item_changed to accept a typed item parameter (e.g., def _on_item_changed(self, item: QTableWidgetItem) -> None) and change _on_save_clicked to declare its return type (e.g., def _on_save_clicked(self) -> None); import QTableWidgetItem (from PyQt5.QtWidgets or PySide equivalent) and typing helpers if needed and update any related stub/annotation for self.current_icon_list or signals only if your linter requires explicit attribute types. Ensure signatures use the same Qt class names used elsewhere in the module so imports remain consistent.src/one_dragon_qt/app/directory_picker.py (1)
90-99:⚠️ Potential issue | 🟡 Minor | ⚡ Quick win语言检测分支建议仅捕获预期异常。
Line 98 使用
except Exception过宽,建议改为except locale.Error(或你们明确的异常集合),避免掩盖真实故障。Based on learnings: "never use a bare
except:for this logic—narrow it toexcept locale.Error:(or otherwise catch the specific expected exception type)."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/one_dragon_qt/app/directory_picker.py` around lines 90 - 99, The detect_language function currently swallows all exceptions via "except Exception", which is too broad; change the exception handler to catch only the expected locale-related errors (e.g., "except locale.Error:" or a small explicit tuple of exceptions) around the call to locale.getlocale() so other bugs aren't masked, and keep the existing fallback return 'zh' behavior; refer to the detect_language function and the locale.getlocale() call when making this change.src/one_dragon/devtools/compile_po.py (1)
8-8: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win补全函数返回类型注解。
Line 8 与 Line 26 的函数签名建议显式标注
-> None,与仓库 Python 类型规范保持一致。💡 建议修改
-def compile_lang(model: str, lang: str): +def compile_lang(model: str, lang: str) -> None: @@ -def compile_po_files(): +def compile_po_files() -> None:As per coding guidelines: "
**/*.py: All functions and methods must include type hints (Type Hints)".Also applies to: 26-26
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/one_dragon/devtools/compile_po.py` at line 8, Add explicit return type annotations "-> None" to the function signatures in this file—at minimum update compile_lang(model: str, lang: str) to compile_lang(model: str, lang: str) -> None; also update the other function signature flagged on line 26 in the same module to include "-> None" so all functions conform to the repository's Python type-hinting guidelines.src/zzz_od/operation/compendium/compendium_choose_mission_type.py (1)
129-129: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win为
handle_go_button的screen参数补充类型标注。Line 129 的
screen参数当前无类型提示,不满足本仓库对src/**/*.py的函数签名标注要求。建议至少标为Any(或项目内更准确的图像类型)。建议修改
+from typing import Any ... - def handle_go_button(self, screen, target_point: Point) -> OperationRoundResult: + def handle_go_button(self, screen: Any, target_point: Point) -> OperationRoundResult:As per coding guidelines:
All functions and methods must include type hints (Type Hints)且src/**/*.py下All function signatures ... must have type annotations。🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/zzz_od/operation/compendium/compendium_choose_mission_type.py` at line 129, The method handle_go_button is missing a type annotation for its screen parameter; update the signature of handle_go_button(self, screen, target_point: Point) -> OperationRoundResult to include a type for screen (e.g., screen: Any or a more specific image/screen type used in the repo) and add the corresponding import (typing.Any or the concrete type) at the top of the file so the function signature in compendium_choose_mission_type.py complies with the project's type-hinting requirements.
🧹 Nitpick comments (1)
src/zzz_od/gui/view/home/home_interface.py (1)
638-638: ⚡ Quick win建议将数量+文案改为整句翻译模板
Line 638 当前把数字与文本拆开翻译,日语等语言下词序不够灵活。建议把整句作为翻译键并使用占位符。
可参考的修改
- self.start_button.setText(f"{len(issues)} {gt('项待配置')} ") + self.start_button.setText(gt('{count}项待配置').format(count=len(issues)))🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/zzz_od/gui/view/home/home_interface.py` at line 638, The UI text currently concatenates a number and a translated fragment via start_button.setText(f"{len(issues)} {gt('项待配置')} "), which breaks word order in other languages; change to use a single translation template with a placeholder (e.g., gt("有 {count} 项待配置") or similar) and pass/format len(issues) into that template so the entire sentence is localized as one unit (update the call around start_button.setText and gt to use the placeholder and formatting with len(issues)).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/one_dragon/utils/i18_utils.py`:
- Around line 23-24: Narrow the broad exception handler that currently does
"except Exception: return 'zh'" to only catch locale-related errors (use "except
locale.Error:"), so replace the generic except in
src/one_dragon/utils/i18_utils.py with an except locale.Error that returns 'zh'
and let any other exceptions propagate; ensure the module imports the locale
module or the specific exception type so the new handler compiles.
- Around line 87-95: Annotate the module-level mapping and the function return
type: add a type annotation declaring _model_lang as dict[str, str] and change
the signature of update_model_lang to include an explicit return type -> None;
keep get_model_lang as is (it already returns str) and ensure the annotations
use the same names (_model_lang, update_model_lang, get_model_lang) so the type
checker recognizes the mapping and the void return.
In `@src/zzz_od/gui/view/devtools/icon_editor_dialog.py`:
- Around line 238-239: Replace the fragmented translation strings with a single
parameterized translation key: instead of concatenating gt('确定要删除图标') + icon
name + template id + gt('吗?') + gt('此操作不可撤销。'), call gt once with placeholders
(e.g. gt('确定要删除图标 "{name}" ({id}) 吗?此操作不可撤销。')) and pass icon.icon_name and
icon.template_id into the placeholder interpolation so the entire confirmation
message for the delete dialog in icon_editor_dialog.py is translated as one
unit.
In `@src/zzz_od/gui/view/world_patrol/route_operation_editor_dialog.py`:
- Around line 169-173: The confirmation message is built by concatenating
multiple gt(...) calls which breaks i18n for languages with different word
order; replace the concatenation around QMessageBox.question by using a single
formatable translation template (call gt once with a placeholder e.g.
"确定要删除第{index}个操作吗?") and inject current_row into that template (use the
existing gt function + .format or equivalent) in the QMessageBox.question call;
apply the same change to the other similar concatenations referenced around the
current file (the occurrences at the blocks using gt and current_row on lines
near 204-205 and 211-212) so all deletion/confirmation strings use one gt(...)
template with a parameter.
---
Outside diff comments:
In `@src/one_dragon_qt/app/directory_picker.py`:
- Around line 90-99: The detect_language function currently swallows all
exceptions via "except Exception", which is too broad; change the exception
handler to catch only the expected locale-related errors (e.g., "except
locale.Error:" or a small explicit tuple of exceptions) around the call to
locale.getlocale() so other bugs aren't masked, and keep the existing fallback
return 'zh' behavior; refer to the detect_language function and the
locale.getlocale() call when making this change.
In `@src/one_dragon/devtools/compile_po.py`:
- Line 8: Add explicit return type annotations "-> None" to the function
signatures in this file—at minimum update compile_lang(model: str, lang: str) to
compile_lang(model: str, lang: str) -> None; also update the other function
signature flagged on line 26 in the same module to include "-> None" so all
functions conform to the repository's Python type-hinting guidelines.
In `@src/zzz_od/gui/view/devtools/icon_editor_dialog.py`:
- Around line 202-225: Add explicit type hints to the three methods in
icon_editor_dialog: change _on_selection_changed to declare its return type
(e.g., def _on_selection_changed(self) -> None), change _on_item_changed to
accept a typed item parameter (e.g., def _on_item_changed(self, item:
QTableWidgetItem) -> None) and change _on_save_clicked to declare its return
type (e.g., def _on_save_clicked(self) -> None); import QTableWidgetItem (from
PyQt5.QtWidgets or PySide equivalent) and typing helpers if needed and update
any related stub/annotation for self.current_icon_list or signals only if your
linter requires explicit attribute types. Ensure signatures use the same Qt
class names used elsewhere in the module so imports remain consistent.
In `@src/zzz_od/operation/compendium/compendium_choose_mission_type.py`:
- Line 129: The method handle_go_button is missing a type annotation for its
screen parameter; update the signature of handle_go_button(self, screen,
target_point: Point) -> OperationRoundResult to include a type for screen (e.g.,
screen: Any or a more specific image/screen type used in the repo) and add the
corresponding import (typing.Any or the concrete type) at the top of the file so
the function signature in compendium_choose_mission_type.py complies with the
project's type-hinting requirements.
---
Nitpick comments:
In `@src/zzz_od/gui/view/home/home_interface.py`:
- Line 638: The UI text currently concatenates a number and a translated
fragment via start_button.setText(f"{len(issues)} {gt('项待配置')} "), which breaks
word order in other languages; change to use a single translation template with
a placeholder (e.g., gt("有 {count} 项待配置") or similar) and pass/format
len(issues) into that template so the entire sentence is localized as one unit
(update the call around start_button.setText and gt to use the placeholder and
formatting with len(issues)).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 996366d7-038f-477b-b348-6a61cf504b5f
📒 Files selected for processing (31)
assets/text/game/ja.poassets/text/output/ja/LC_MESSAGES/game.moassets/text/output/ja/LC_MESSAGES/ui.moassets/text/ui/ja.posrc/one_dragon/base/config/custom_config.pysrc/one_dragon/base/config/game_account_config.pysrc/one_dragon/base/operation/one_dragon_context.pysrc/one_dragon/devtools/compile_po.pysrc/one_dragon/utils/i18_utils.pysrc/one_dragon_qt/app/directory_picker.pysrc/one_dragon_qt/view/setting/setting_push_interface.pysrc/one_dragon_qt/widgets/base_interface.pysrc/one_dragon_qt/widgets/icon_button.pysrc/one_dragon_qt/widgets/setting_card/app_run_card.pysrc/one_dragon_qt/widgets/setting_card/combo_box_setting_card.pysrc/one_dragon_qt/widgets/setting_card/help_card.pysrc/one_dragon_qt/widgets/setting_card/setting_card_base.pysrc/one_dragon_qt/windows/window.pysrc/zzz_od/application/notify/notify_app.pysrc/zzz_od/gui/app.pysrc/zzz_od/gui/view/devtools/icon_editor_dialog.pysrc/zzz_od/gui/view/devtools/template_card_widget.pysrc/zzz_od/gui/view/hollow_zero/lost_void_challenge_config_interface.pysrc/zzz_od/gui/view/hollow_zero/lost_void_setting_interface.pysrc/zzz_od/gui/view/home/home_interface.pysrc/zzz_od/gui/view/one_dragon/charge_plan_interface.pysrc/zzz_od/gui/view/world_patrol/route_operation_editor_dialog.pysrc/zzz_od/gui/view/world_patrol/world_patrol_large_map_recorder_interface.pysrc/zzz_od/gui/view/world_patrol/world_patrol_route_list_interface.pysrc/zzz_od/gui/view/world_patrol/world_patrol_route_recorder_interface.pysrc/zzz_od/operation/compendium/compendium_choose_mission_type.py
|
已处理 CodeRabbit 的审查意见:
验证:
|
There was a problem hiding this comment.
♻️ Duplicate comments (1)
src/zzz_od/gui/view/world_patrol/route_operation_editor_dialog.py (1)
172-172:⚠️ Potential issue | 🟡 Minor | ⚡ Quick win修正序号展示的 off-by-one(用户会看到“第0个”)
Line 172、Line 204、Line 211 目前传入的是 0 基索引,首项会显示为“第0个操作”。建议展示为 1 基序号。
💡 建议修改
- gt('确定要删除第{index}个操作吗?').format(index=current_row), + gt('确定要删除第{index}个操作吗?').format(index=current_row + 1), @@ - QMessageBox.warning(self, gt('数据错误'), gt('第{index}个操作的数据不完整').format(index=i)) + QMessageBox.warning(self, gt('数据错误'), gt('第{index}个操作的数据不完整').format(index=i + 1)) @@ - QMessageBox.warning(self, gt('数据错误'), gt('第{index}个操作的坐标数据必须是数字').format(index=i)) + QMessageBox.warning(self, gt('数据错误'), gt('第{index}个操作的坐标数据必须是数字').format(index=i + 1))Also applies to: 204-205, 211-212
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/zzz_od/gui/view/world_patrol/route_operation_editor_dialog.py` at line 172, The displayed operation index is using a 0-based value (current_row) which causes "第0个" to appear; update each gt(...).format(index=current_row) usage to pass a 1-based index (e.g., format(index=current_row + 1)). Locate the occurrences where gt('确定要删除第{index}个操作吗?').format(index=current_row) and the similar gt(...) calls at the other two sites (the strings around deletion/position messages) and change their format argument to current_row + 1 so the UI shows 1-based ordinal numbers.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Duplicate comments:
In `@src/zzz_od/gui/view/world_patrol/route_operation_editor_dialog.py`:
- Line 172: The displayed operation index is using a 0-based value (current_row)
which causes "第0个" to appear; update each gt(...).format(index=current_row)
usage to pass a 1-based index (e.g., format(index=current_row + 1)). Locate the
occurrences where gt('确定要删除第{index}个操作吗?').format(index=current_row) and the
similar gt(...) calls at the other two sites (the strings around
deletion/position messages) and change their format argument to current_row + 1
so the UI shows 1-based ordinal numbers.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 8184c117-cae5-41f1-99ca-acb581812b7c
📒 Files selected for processing (9)
assets/text/output/ja/LC_MESSAGES/ui.moassets/text/ui/ja.posrc/one_dragon/devtools/compile_po.pysrc/one_dragon/utils/i18_utils.pysrc/one_dragon_qt/app/directory_picker.pysrc/zzz_od/gui/view/devtools/icon_editor_dialog.pysrc/zzz_od/gui/view/home/home_interface.pysrc/zzz_od/gui/view/world_patrol/route_operation_editor_dialog.pysrc/zzz_od/operation/compendium/compendium_choose_mission_type.py
Summary
.pofiles to.mooutputs.Note
This PR is split out from #2262 based on review feedback, so it only contains the Japanese UI/i18n changes. The Discord screenshot notification changes will be submitted separately.
Test
python -m py_compile src\one_dragon\utils\i18_utils.py src\one_dragon\devtools\compile_po.py src\one_dragon_qt\view\setting\setting_push_interface.py src\zzz_od\application\notify\notify_app.pySummary by CodeRabbit
New Features
Localization
Chores