feat: add korean localization toggle#561
feat: add korean localization toggle#561gracefully91 wants to merge 3 commits intorealproject7:mainfrom
Conversation
realproject7
left a comment
There was a problem hiding this comment.
Thanks for the Korean localization work @gracefully91 — the translations are natural and well done!
However, requesting changes before this can be merged:
Bug
- Duplicate span in SetupWizard.tsx: The original English "Custom ports"
<span>is left in alongside the new translated<span>, so both render side by side. The original should be replaced, not duplicated.
Code quality
- Inline ternary pattern doesn't scale. Currently every string uses
locale === "ko" ? "한글" : "English"directly in JSX — this is repeated hundreds of times across 18 files. Your ownSettingsPage.tsxalready uses a much cleaner dictionary (COPY) pattern. Could you refactor the other components to use the same approach? For example:
// Per-component or shared dictionary
const COPY = {
en: { title: "Settings", save: "Save" },
ko: { title: "설정", save: "저장" },
};
const t = COPY[locale];
// Then in JSX:
<h1>{t.title}</h1>This keeps components readable and makes adding a third language trivial.
Minor
\n-in the welcome message headline ("QuadWork에 오신 걸 환영합니다\n- 첫 AI 개발 팀을 설정해볼까요") looks like a formatting artifact.
Happy to merge once these are addressed!
|
Hi @realproject7! I've addressed all three points: Bug — Removed the duplicate for "Custom ports" in SetupWizard.tsx Ready for re-review! 🍊 |
realproject7
left a comment
There was a problem hiding this comment.
Thanks for addressing the duplicate span and the \n- artifact — both are fixed!
The COPY dictionary refactor is partially done but 49 inline locale === "ko" ternaries still remain in JSX across 17 files. These need to be moved into the COPY dictionaries for consistency and maintainability.
What needs to change
Rule: Every user-visible string must live in the COPY dictionary
No inline ternaries in JSX. Every locale === "ko" ? "한글" : "English" in rendering code should be replaced by a COPY key. The only place locale should appear in a component is:
const { locale } = useLocale();
const t = COPY[locale];After that, JSX should only reference t.someKey — never locale directly.
How to handle strings with interpolation
Some inline ternaries were left because the string contains dynamic values like ${count}. Use a function in the COPY dictionary:
// ❌ Current (inline ternary with interpolation)
<span>{locale === "ko" ? `${count}개 항목` : `${count} items`}</span>
// ✅ Correct (function in COPY)
const COPY = {
en: {
itemCount: (n: number) => `${n} items`,
},
ko: {
itemCount: (n: number) => `${n}개 항목`,
},
};
// In JSX:
<span>{t.itemCount(count)}</span>How to handle JSX elements inside translated strings
For strings that contain inline <code>, <strong>, etc., split the COPY entry into parts:
// ❌ Current (fragile string split)
t.cleanupIntro.split("~/.quadwork/{id}/agentchattr")
// ✅ Correct (structured COPY entries)
const COPY = {
en: {
cleanupBefore: "Per-project clones are necessary so multiple projects can run AgentChattr simultaneously without port conflicts. Existing v1 users are auto-migrated to per-project clones on the next ",
cleanupCode: "~/.quadwork/{id}/agentchattr",
cleanupAfter: "; once every project has a working clone, the legacy shared install can be removed safely via ",
},
ko: {
cleanupBefore: "프로젝트별 클론은 ...",
cleanupCode: "~/.quadwork/{id}/agentchattr",
cleanupAfter: "; 모든 프로젝트에 ...",
},
};
// In JSX:
<p>{t.cleanupBefore}<code>{t.cleanupCode}</code>{t.cleanupAfter}</p>Files with remaining inline ternaries (all must be fixed)
High priority (many ternaries)
-
SetupWizard.tsx — 13 inline ternaries
getInitialSteps()function has 12 ternaries for step labels and subtitles. Move all steplabelandsubtitlestrings into COPY:// ❌ Current { label: locale === "ko" ? "필수 도구" : "Prerequisites", subtitle: locale === "ko" ? "필수 도구 확인" : "Check required tools" } // ✅ Move to COPY const COPY = { en: { stepPrereqLabel: "Prerequisites", stepPrereqSubtitle: "Check required tools", // ... all other steps }, ko: { stepPrereqLabel: "필수 도구", stepPrereqSubtitle: "필수 도구 확인", }, }; // Then: { label: t.stepPrereqLabel, subtitle: t.stepPrereqSubtitle }
- Also fix the remaining JSX ternaries ("auto-detected", "no local clone found", branch protection text)
-
GitHubPanel.tsx — 7 inline ternaries
- Rate limit messages, Issues/PRs headers with counts, tooltip bodies
- Use function pattern for count interpolations:
issuesHeader: (n: number) => \ISSUES (${n})``
-
BatchProgressPanel.tsx — 5 inline ternaries
- Batch number display, items count, tooltip text
-
HomeDashboard.tsx — 5 inline ternaries
- Project count display
timeAgo()function has 4 ternaries for time units — move all into COPY as functions:minutesAgo: (n: number) => \${n}분 전``
Medium priority (1-2 ternaries each)
- ControlBar.tsx — 2 (tooltip help text for Keep Mac Awake and Notification Sound)
- AgentModelsWidget.tsx — 1-2
- AgentTerminalsGrid.tsx — 1-2
- DiscordBridgeWidget.tsx — 1-2
- TelegramBridgeWidget.tsx — 1-2
- LoopGuardWidget.tsx — 1-2
- OperatorFeaturesPanel.tsx — 1-2
- ProjectDashboard.tsx — 1-2
- ProjectHistoryWidget.tsx — 1-2
- ScheduledTriggerWidget.tsx — 1-2
For all of these: move the remaining tooltip bodies and dynamic labels into each file's COPY dictionary.
Other fixes needed
-
Remove unnecessary type casts in SetupWizard.tsx —
locale as "en" | "ko"is redundant sinceuseLocale()already returnsLocalewhich is"en" | "ko". Just useCOPY[locale]directly. -
SettingsPage.tsx cleanup text — replace the fragile
.split("~/.quadwork/{id}/agentchattr")approach with structured COPY entries (see example above).
Checklist before re-requesting review
- Zero
locale === "ko"ternaries remain in any JSX/rendering code - All user-visible strings live in COPY dictionaries
- Strings with dynamic values use function entries in COPY
- Strings with JSX elements use structured COPY entries (before/after pattern)
- No
as "en" | "ko"type casts -
npm run buildpasses cleanly
|
All 49 inline locale === "ko" ternaries have been moved into COPY dictionaries across all 17 files. Removed the as "en" | "ko" type casts and replaced the .split() pattern in SettingsPage with structured before/code/after entries. Thanks for the detailed breakdown! |
|
Hi @gracefully91! The localization work looks great — translations are natural and the COPY dictionary refactor is clean. Two things needed before we can merge: 1. Rebase on current
|
|
Good Night @realproject7! I’ve updated the PR to address all your feedback:
Everything should be ready for review now. Thanks! 🙏 |
한글화 해봤습니다~~
설정에 언어 선택 버튼도 넣었는데 확인해보세유~~