Skip to content

Conversation

@agrofx1
Copy link

@agrofx1 agrofx1 commented Dec 31, 2025

Resolves #1043

Description:

This commit translates the flag names into users selected language. The translations are in /lang/flags/*.json files. This commits includes a ru.json demo file with a few translations to test out

Before:
Screenshot_20260101_015026
After:
Screenshot_20260101_014850

Please complete the following:

  • I have added screenshots for all UI updates
  • I process any text displayed to the user through translateText() and I've added it to the en.json file
  • I have added relevant tests to the test directory
  • I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced

Please put your Discord username so you can be contacted if a bug or regression is found:

agrofx

@agrofx1 agrofx1 requested review from a team as code owners December 31, 2025 22:51
@CLAassistant
Copy link

CLAassistant commented Dec 31, 2025

CLA assistant check
All committers have signed the CLA.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 31, 2025

Walkthrough

This PR adds Russian translations for flag names by introducing a new translation resource file, updating the flag input modal to display localized flag names, and modifying the language loader to merge flag translations into the main language dictionary.

Changes

Cohort / File(s) Summary
Russian flag translations
resources/lang/flags/ru.json
New translation file containing 4 Russian flag name entries, including "Без флага" (None), "Аббасидский халифат" (Abbasid Caliphate), and regional empires.
Flag display localization
src/client/FlagInputModal.ts
Modified to pass country names through translateText() function, enabling the UI to render localized flag names instead of raw English text.
Language loader enhancement
src/client/LangSelector.ts
Updated to import Russian flag translations and merge them into the language dictionary via flagsLanguageMap, allowing flag-specific translations to extend base language translations.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • mls (v4.9) #2487: Modifies Russian localization resources and updates LangSelector.ts language/flags merging behavior with direct code-level overlap.
  • mls (v4.4) #1753: Changes LangSelector.ts to add and import language resources in a similar localization pattern.
  • Minor changes to the flag-input-modal #1975: Updates FlagInputModal.ts to use translateText() for flag name localization, mirroring this PR's UI changes.

Suggested labels

Bug Fix, Translation - New, Feature - Flags

Suggested reviewers

  • evanpelle

Poem

🚩 Flags now speak in Russian tongue,

Локализация, freshly sung!

From East to West, empires translate,

No more English walls to create. ✨

Pre-merge checks

✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix: display flags in local language' clearly and concisely describes the main change—enabling flag names to be displayed in the user's selected language.
Description check ✅ Passed The description is well-related to the changeset, explaining the purpose of translating flag names, mentioning the file structure, providing before/after screenshots, and confirming completion of all checklist items.
Linked Issues check ✅ Passed The pull request meets the requirement of issue #1043 by implementing flag name translation based on user locale through a new /lang/flags/*.json structure and integrating it into the language loading system.
Out of Scope Changes check ✅ Passed All changes are scoped to the stated objective: adding Russian flag translations, updating FlagInputModal to use translateText, and modifying LangSelector to merge flag translations with language translations. No unrelated changes detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/client/LangSelector.ts (1)

90-92: Consider scalability for additional languages.

Currently only Russian flag translations are loaded. As more languages add flag translations, each will need a manual entry here. This works fine for now as a demo.

If many languages will eventually have flag translations, consider a dynamic loader or document the pattern for contributors.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 59b9cf5 and beb977f.

📒 Files selected for processing (3)
  • resources/lang/flags/ru.json
  • src/client/FlagInputModal.ts
  • src/client/LangSelector.ts
🧰 Additional context used
🧠 Learnings (9)
📓 Common learnings
Learnt from: andrewNiziolek
Repo: openfrontio/OpenFrontIO PR: 1007
File: resources/lang/de.json:115-115
Timestamp: 2025-06-02T14:27:37.609Z
Learning: For OpenFrontIO project: When localization keys are renamed in language JSON files, the maintainers separate technical changes from translation content updates. They wait for community translators to update the actual translation values rather than attempting to translate in the same PR. This allows technical changes to proceed while ensuring accurate translations from native speakers.
Learnt from: VariableVince
Repo: openfrontio/OpenFrontIO PR: 1655
File: resources/maps/giantworldmap/manifest.json:165-174
Timestamp: 2025-07-31T12:03:08.052Z
Learning: In OpenFrontIO draft PRs, flag names in map manifest files may be placeholders that will be updated to match the actual SVG flag file names when the assets are received. The final naming depends on the actual flag SVG files provided, not code naming conventions.
Learnt from: VariableVince
Repo: openfrontio/OpenFrontIO PR: 959
File: resources/maps/GatewayToTheAtlantic.json:124-124
Timestamp: 2025-05-30T18:11:56.014Z
Learning: In OpenFrontIO, flag names in map JSON files can use spaces (like "Amazigh flag") and don't need to follow slug format. Flag assets are stored with matching filenames including spaces (e.g., "Amazigh flag.svg"). Nation names and flag names are not translated/localized in the translation files.
Learnt from: TheGiraffe3
Repo: openfrontio/OpenFrontIO PR: 884
File: resources/lang/en.json:456-461
Timestamp: 2025-08-16T10:52:08.292Z
Learning: In OpenFrontIO, translation files in resources/lang/*.json (except en.json) should not be updated in regular PRs. Only dedicated translation PRs titled "mls" and made by Aotumori should update non-English locale files. Regular PRs should only update en.json when adding or modifying translation keys.
Learnt from: TheGiraffe3
Repo: openfrontio/OpenFrontIO PR: 1864
File: resources/maps/arabianpeninsula/manifest.json:13-170
Timestamp: 2025-08-19T11:00:55.422Z
Learning: In OpenFrontIO, nation names in map manifests are displayed directly in the UI without translation. They do not need to be added to resources/lang/en.json or processed through translateText(). This is the established pattern across all existing maps including Europe, World, Asia, Africa, and others.
Learnt from: Aotumuri
Repo: openfrontio/OpenFrontIO PR: 1357
File: resources/lang/de.json:523-540
Timestamp: 2025-07-12T08:41:35.101Z
Learning: In OpenFrontIO project localization files, always check the en.json source file before flagging potential spelling errors in other language files, as some keys may intentionally use non-standard spellings that need to be consistent across all translations.
Learnt from: VariableVince
Repo: openfrontio/OpenFrontIO PR: 957
File: resources/maps/GatewayToTheAtlantic.json:175-179
Timestamp: 2025-05-30T16:16:27.118Z
Learning: In OpenFrontIO project, flag values in map JSON files (like GatewayToTheAtlantic.json) should match the actual flag file names in the resources directory (e.g., "French foreign legion" corresponds to "French foreign legion.svg"). The naming convention follows the file naming system rather than code naming conventions.
Learnt from: VariableVince
Repo: openfrontio/OpenFrontIO PR: 959
File: resources/maps/GatewayToTheAtlantic.json:124-124
Timestamp: 2025-05-30T18:11:56.014Z
Learning: OpenFrontIO flag naming uses mixed conventions: short country codes (like "cu", "ar"), space-separated names (like "Amazigh flag", "Aztec Empire", "French foreign legion"), underscores (like "santa_claus"), and hyphens (like "gb-eng"). Flag asset filenames match these conventions exactly, including spaces. No translation system exists for flag names or nation names.
Learnt from: scottanderson
Repo: openfrontio/OpenFrontIO PR: 949
File: resources/lang/en.json:8-10
Timestamp: 2025-05-30T03:53:52.231Z
Learning: For the OpenFrontIO project, do not suggest updating translation files in resources/lang/*.json except for en.json. The project has a dedicated translation team that handles all other locale files.
Learnt from: mokizzz
Repo: openfrontio/OpenFrontIO PR: 1940
File: resources/lang/en.json:763-766
Timestamp: 2025-08-27T08:12:19.610Z
Learning: In OpenFrontIO, some country entries in src/client/data/countries.json may have similar names but different codes (e.g., "Empire of Japan" vs "Empire of Japan1"). Each unique code requires its own translation key in resources/lang/en.json after normalization. Always verify against countries.json before suggesting removal of translation keys.
📚 Learning: 2025-08-27T08:12:19.610Z
Learnt from: mokizzz
Repo: openfrontio/OpenFrontIO PR: 1940
File: resources/lang/en.json:763-766
Timestamp: 2025-08-27T08:12:19.610Z
Learning: In OpenFrontIO, some country entries in src/client/data/countries.json may have similar names but different codes (e.g., "Empire of Japan" vs "Empire of Japan1"). Each unique code requires its own translation key in resources/lang/en.json after normalization. Always verify against countries.json before suggesting removal of translation keys.

Applied to files:

  • src/client/FlagInputModal.ts
  • resources/lang/flags/ru.json
📚 Learning: 2025-08-19T11:00:55.422Z
Learnt from: TheGiraffe3
Repo: openfrontio/OpenFrontIO PR: 1864
File: resources/maps/arabianpeninsula/manifest.json:13-170
Timestamp: 2025-08-19T11:00:55.422Z
Learning: In OpenFrontIO, nation names in map manifests are displayed directly in the UI without translation. They do not need to be added to resources/lang/en.json or processed through translateText(). This is the established pattern across all existing maps including Europe, World, Asia, Africa, and others.

Applied to files:

  • src/client/FlagInputModal.ts
  • resources/lang/flags/ru.json
📚 Learning: 2025-06-02T14:27:37.609Z
Learnt from: andrewNiziolek
Repo: openfrontio/OpenFrontIO PR: 1007
File: resources/lang/de.json:115-115
Timestamp: 2025-06-02T14:27:37.609Z
Learning: For OpenFrontIO project: When localization keys are renamed in language JSON files, the maintainers separate technical changes from translation content updates. They wait for community translators to update the actual translation values rather than attempting to translate in the same PR. This allows technical changes to proceed while ensuring accurate translations from native speakers.

Applied to files:

  • src/client/FlagInputModal.ts
📚 Learning: 2025-07-23T12:36:35.354Z
Learnt from: Aotumuri
Repo: openfrontio/OpenFrontIO PR: 1534
File: src/client/LangSelector.ts:97-106
Timestamp: 2025-07-23T12:36:35.354Z
Learning: In OpenFrontIO's LangSelector.ts, the getClosestSupportedLang method always joins language code parts with underscores ("_") because all keys in the languageMap use underscore format (e.g., pt_BR, sv_SE, zh_CN). This normalization ensures consistency regardless of whether the input language code uses hyphens or underscores as delimiters.

Applied to files:

  • src/client/LangSelector.ts
📚 Learning: 2025-05-30T18:11:56.014Z
Learnt from: VariableVince
Repo: openfrontio/OpenFrontIO PR: 959
File: resources/maps/GatewayToTheAtlantic.json:124-124
Timestamp: 2025-05-30T18:11:56.014Z
Learning: In OpenFrontIO, flag names in map JSON files can use spaces (like "Amazigh flag") and don't need to follow slug format. Flag assets are stored with matching filenames including spaces (e.g., "Amazigh flag.svg"). Nation names and flag names are not translated/localized in the translation files.

Applied to files:

  • resources/lang/flags/ru.json
📚 Learning: 2025-05-30T16:16:27.118Z
Learnt from: VariableVince
Repo: openfrontio/OpenFrontIO PR: 957
File: resources/maps/GatewayToTheAtlantic.json:175-179
Timestamp: 2025-05-30T16:16:27.118Z
Learning: In OpenFrontIO project, flag values in map JSON files (like GatewayToTheAtlantic.json) should match the actual flag file names in the resources directory (e.g., "French foreign legion" corresponds to "French foreign legion.svg"). The naming convention follows the file naming system rather than code naming conventions.

Applied to files:

  • resources/lang/flags/ru.json
📚 Learning: 2025-09-02T04:13:07.073Z
Learnt from: TheGiraffe3
Repo: openfrontio/OpenFrontIO PR: 1958
File: resources/maps/northamerica/manifest.json:230-235
Timestamp: 2025-09-02T04:13:07.073Z
Learning: In OpenFrontIO, flag additions do not require updating an ATTRIBUTIONS.md file, as demonstrated by PR #1577 which added Circassia flag without any attribution file updates. The repository does not maintain an ATTRIBUTIONS.md file.

Applied to files:

  • resources/lang/flags/ru.json
📚 Learning: 2025-05-30T18:11:56.014Z
Learnt from: VariableVince
Repo: openfrontio/OpenFrontIO PR: 959
File: resources/maps/GatewayToTheAtlantic.json:124-124
Timestamp: 2025-05-30T18:11:56.014Z
Learning: OpenFrontIO flag naming uses mixed conventions: short country codes (like "cu", "ar"), space-separated names (like "Amazigh flag", "Aztec Empire", "French foreign legion"), underscores (like "santa_claus"), and hyphens (like "gb-eng"). Flag asset filenames match these conventions exactly, including spaces. No translation system exists for flag names or nation names.

Applied to files:

  • resources/lang/flags/ru.json
🧬 Code graph analysis (1)
src/client/FlagInputModal.ts (1)
src/client/LangSelector.ts (1)
  • translateText (266-286)
🪛 GitHub Actions: 🧪 CI
src/client/FlagInputModal.ts

[warning] 1-1: Prettier formatting issues detected in file. Run 'npx prettier --write src/client/FlagInputModal.ts' to fix.

src/client/LangSelector.ts

[warning] 1-1: Prettier formatting issues detected in file. Run 'npx prettier --write src/client/LangSelector.ts' to fix.

resources/lang/flags/ru.json

[warning] 1-1: Prettier formatting issues detected in file. Run 'npx prettier --write resources/lang/flags/ru.json' to fix.

🔇 Additional comments (2)
resources/lang/flags/ru.json (2)

2-2: No action needed—"None" translation is valid and in use.

The "None" key correctly maps to the country code "xx" defined in src/client/data/countries.json. This translation is required for the flag system, which validates flags against valid country codes before rendering.


1-6: All translation keys are correctly matched to countries.json.

Verified: "None", "Abbasid Caliphate", "Achaemenid Empire", and "United Arab Emirates" all exist as name values in countries.json. The Russian translations are accurate and the file structure is correct.

}}
/>
<span class="country-name">${country.name}</span>
<span class="country-name">${translateText(country.name)}</span>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Search won't work for localized flag names.

While the flag name now displays in the user's language, the search function at lines 76-81 still compares the input against the raw English country.name from the JSON. A user viewing "Аббасидский халифат" cannot search for it by typing Russian text.

🔎 Proposed fix: Search against translated text

Update includedInSearch to search against the translated name:

 private includedInSearch(country: { name: string; code: string }): boolean {
+  const translatedName = translateText(country.name);
   return (
-    country.name.toLowerCase().includes(this.search.toLowerCase()) ||
+    translatedName.toLowerCase().includes(this.search.toLowerCase()) ||
     country.code.toLowerCase().includes(this.search.toLowerCase())
   );
 }
🤖 Prompt for AI Agents
In src/client/FlagInputModal.ts around line 66, the displayed country name uses
translateText(country.name) but the search logic (lines ~76-81) still matches
the user's input against the raw English country.name, so localized names won't
be found; change includedInSearch to compare the lowercased input against the
translated name by calling translateText(country.name) (and normalizing
case/whitespace) instead of country.name, so the search matches the UI-visible,
localized string.

Comment on lines +144 to +147
const flagsLanguage = this.flagsLanguageMap[lang] ?? {};
const flatLanguage = flattenTranslations(language);
const flagFlagsLanguage = flattenTranslations(flagsLanguage);
return {...flatLanguage, ...flagFlagsLanguage};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix typo and clarify merge precedence.

Line 146 has a typo: flagFlagsLanguage should be flatFlagsLanguage.

Additionally, the merge order {...flatLanguage, ...flagFlagsLanguage} gives precedence to flag translations (the rightmost spread wins). This means a flag translation key would overwrite a base translation key if they collide. If flags should extend (not override) base translations, swap the order to {...flagFlagsLanguage, ...flatLanguage}.

🔎 Proposed fix

Fix the typo:

 private loadLanguage(lang: string): Record<string, string> {
   const language = this.languageMap[lang] ?? {};
   const flagsLanguage = this.flagsLanguageMap[lang] ?? {};
   const flatLanguage = flattenTranslations(language);
-  const flagFlagsLanguage = flattenTranslations(flagsLanguage);
+  const flatFlagsLanguage = flattenTranslations(flagsLanguage);
-  return {...flatLanguage, ...flagFlagsLanguage};
+  return {...flatLanguage, ...flatFlagsLanguage};
 }

If base translations should take precedence over flags, reverse the merge:

-  return {...flatLanguage, ...flatFlagsLanguage};
+  return {...flatFlagsLanguage, ...flatLanguage};
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const flagsLanguage = this.flagsLanguageMap[lang] ?? {};
const flatLanguage = flattenTranslations(language);
const flagFlagsLanguage = flattenTranslations(flagsLanguage);
return {...flatLanguage, ...flagFlagsLanguage};
const flagsLanguage = this.flagsLanguageMap[lang] ?? {};
const flatLanguage = flattenTranslations(language);
const flatFlagsLanguage = flattenTranslations(flagsLanguage);
return {...flatLanguage, ...flatFlagsLanguage};
🤖 Prompt for AI Agents
In src/client/LangSelector.ts around lines 144 to 147, fix the typo and adjust
merge precedence: rename the variable flagFlagsLanguage to flatFlagsLanguage
(line 146) and swap the spread order so base translations win by returning
{...flatFlagsLanguage, ...flatLanguage} (i.e., ensure flags extend but do not
override base translations).

Copy link
Member

@Aotumuri Aotumuri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, but if we put all the flag files into Crowdin, there’s a high chance we’ll hit the character limit. Since flags are not expected to change very often, how about saving them outside of en.json in a separate file?
For example, we could store them under something like lang/flag/.... or lang/{lang_code}/main.json - flag.jsom

sorry...

@agrofx1
Copy link
Author

agrofx1 commented Jan 2, 2026

I already store all flag translation in separate file its in /resources/lang/flags/*.json

@iiamlewis
Copy link
Contributor

We are going to look at how we can solve this via our current solution before we start having to do PRs to bring all flags up to date via PRs

@iiamlewis iiamlewis closed this Jan 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🌐 i18n - Translate flag names

4 participants