Skip to content

Localize the remaining hard-coded UI strings and add the missing keys - #379

Open
Z2549 wants to merge 5 commits into
Floogen:developmentfrom
Z2549:development
Open

Z2549 wants to merge 5 commits into
Floogen:developmentfrom
Z2549:development

Conversation

@Z2549

@Z2549 Z2549 commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Summary

A few UI strings were still hard-coded in the C# source, so they stayed English in every locale. The Nexus server names had no translation keys at all. This adds the missing keys, moves those strings into the translation files, and brings all 16 locales to full coverage of the 13 new keys (380 each), with none missing and none empty.

bg.json, zh.json, default.json and the 14 remaining locales each gained exactly these 13 keys.

New translation keys (13)

Key default.json
ui.profile_editor.dialogs.open_profile Open Mod Profile
ui.profile_editor.dialogs.json_filter JSON files
ui.settings_window.dialogs.select_mod_folder Select the mod folder
ui.settings_window.dialogs.select_mod_install_folder Select the output folder for mods installed via Stardrop
ui.settings_window.dialogs.select_collection_install_folder Select the folder that collections install their mods to
ui.settings_window.nexus_servers.nexus_cdn Nexus CDN
ui.settings_window.nexus_servers.chicago Chicago
ui.settings_window.nexus_servers.paris Paris
ui.settings_window.nexus_servers.amsterdam Amsterdam
ui.settings_window.nexus_servers.prague Prague
ui.settings_window.nexus_servers.los_angeles Los Angeles
ui.settings_window.nexus_servers.miami Miami
ui.settings_window.nexus_servers.singapore Singapore

Source changes

  • ProfileEditor.axaml — the in-window header was a literal Text="Profiles", so it never followed the language even though the window Title did. It now uses {i18n:Translate ui.window.profiles.name}, the same key the title uses. CollectionsWindow.axaml was already doing this correctly.
  • ProfileEditor.axaml.cs, ProfileExportWindow.axaml.cs — replaced the hard-coded file dialog Title / filter Name strings with Program.translation.Get(...). Left the other new FileDialogFilter { Name = "JSON" } alone, since that one is language-neutral.
  • SettingsWindow.axaml.cs — the preferred server combo previously keyed its items by EnumParser.GetDescription(server). Those [Description] values are not translatable by design: they are the serverName argument handed to the Nexus API (see the GetFileDownloadLink / GetCollectionArchiveLink calls). The combo now follows the pattern the mod grouping combo next to it already uses — the enum goes in ComboBoxItem.Tag and only Content is translated — so localizing the label cannot change the persisted setting or the value sent to the API. A server added upstream still shows up, falling back to its [Description].

Translations

City names follow each language's own Wikipedia article title rather than a literal transliteration, so they read the way speakers of that language expect: de uses Prag, es accents Ámsterdam, uk and ru spell the same city differently, and ja/ko/th use their own forms. Three Wikipedia titles carry a disambiguation suffix that is not part of the place name, and it is dropped: ko Paris is listed as 파리 (프랑스), hu Miami as Miami (Florida), and th Singapore as a country article. Nexus CDN stays in English everywhere, matching default.json.

The UI strings reuse each locale's existing vocabulary for mod, folder and profile — read out of the parts of those files that were already translated — rather than introducing new terms.

The Bulgarian strings were contributed by @AcTePuKc, who wrote bg.json and offered them in a comment here instead of opening a separate PR. Thanks!

Notes

  • NexusServers.cs is untouched; its [Description] values remain the API values.
  • Each file keeps its own formatting, which is not uniform across this repo: fr.json indents with four spaces and tr.json with tabs, while the others use two. All of them stay CRLF with no BOM, as before. The changes are additions only — no existing key was removed or edited, including the stale keys some files still carry from older upstream versions.
  • NexusServers is read from settings without a JsonStringEnumConverter, so a hand-edited settings file could hold a value outside the enum. The preselection uses FirstOrDefault rather than First, so that case leaves the box unselected instead of throwing while the settings window opens — the tolerance the previous description-based lookup had.
  • dotnet build Stardrop/Stardrop.csproj -c Release → 0 errors. The remaining warnings are pre-existing and none of them point at the changed lines.

Z2549 added 3 commits October 9, 2026 10:39
The window title already used {i18n:Translate ui.window.profiles.name}, but the
in-window header next to the menu bar was hard-coded to the literal string
"Profiles", so it stayed English in every non-English locale.

CollectionsWindow already routes its equivalent header through the translation
extension:

    <TextBlock Text="{i18n:Translate ui.window.collections.name}" ... />

Do the same here. The key ui.window.profiles.name already exists in all 17
locale files (zh: "配置方案"), so no new translations are needed.
Two kinds of user-facing text still bypassed the translation system, so they
stayed English in every locale.

File / folder picker dialogs
  The native dialogs opened from the Profile Editor, the Profile Export window
  and the Settings window had hard-coded titles:
    "Open Mod Profile", "Export Profile",
    "Select the mod folder",
    "Select the output folder for mods installed via Stardrop",
    "Select the folder that collections install their mods to"
  and the profile import filter was hard-coded to "JSON files".
  "Export Profile" reuses the existing ui.window.profiles_export.name key; the
  rest got new ui.*.dialogs.* keys. The bare "JSON" filter in the export dialog
  is language neutral and was left alone.

Nexus preferred server dropdown
  The combo was populated from each server's [Description] attribute, which is
  English-only. It now builds ComboBoxItem entries the same way the mod grouping
  combo already does: the enum stays on Tag (so the stored setting is unaffected
  by localization) and the visible label comes from translation.

  This deliberately does *not* translate NexusServers' [Description] values.
  Those strings are not just labels - they are the serverName argument handed to
  the Nexus API, e.g. in MainWindow's GetFileDownloadLink calls - so localizing
  them would break downloads. Only the display label is localized, via the new
  ui.settings_window.nexus_servers.* keys, and the code falls back to the
  [Description] for any server that has no display key yet.

Key coverage: default.json and zh.json both at 380 keys, no missing, obsolete or
empty entries, and every key referenced from C#/XAML resolves. Builds clean with
0 errors.
Settings are read without a JsonStringEnumConverter, so System.Text.Json
does not validate the numeric value of NexusServers. A settings file that
holds a value outside the enum (hand-edited, or written by a future build)
previously produced an undefined enum value here.

Replace First with FirstOrDefault when preselecting the combo box: an
unmatched value now leaves the box unselected, matching the tolerance of
the previous description-based lookup, instead of throwing
InvalidOperationException while the settings window is opening.
@AcTePuKc

Copy link
Copy Markdown
Contributor

Hi! Nice catch on the localization improvements!

I originally contributed the Bulgarian translation (bg.json), and rather than opening a separate PR, I've included the translations for all 13 new keys below. Feel free to add them to this PR as well!

I've prepared Bulgarian translations for all of them. Would you mind including them in this PR as well? That would bring the Bulgarian translation to 380/380 keys, without needing a separate PR.

Here are the translations:

  // Profile Editor Window - Dialogs
  "ui.profile_editor.dialogs.open_profile": "Отваряне на профил за модове",
  "ui.profile_editor.dialogs.json_filter": "JSON файлове",

  // Settings Window - Dialogs
  "ui.settings_window.dialogs.select_mod_folder": "Избери папката с модове",
  "ui.settings_window.dialogs.select_mod_install_folder": "Избери папката, в която Stardrop инсталира модовете",
  "ui.settings_window.dialogs.select_collection_install_folder": "Избери папката, в която колекциите инсталират модовете си",

  // Settings Window - Nexus Servers
  "ui.settings_window.nexus_servers.nexus_cdn": "Nexus CDN",
  "ui.settings_window.nexus_servers.chicago": "Чикаго",
  "ui.settings_window.nexus_servers.paris": "Париж",
  "ui.settings_window.nexus_servers.amsterdam": "Амстердам",
  "ui.settings_window.nexus_servers.prague": "Прага",
  "ui.settings_window.nexus_servers.los_angeles": "Лос Анджелис",
  "ui.settings_window.nexus_servers.miami": "Маями",
  "ui.settings_window.nexus_servers.singapore": "Сингапур",

Thanks!

Contributed by AcTePuKc, who wrote bg.json (see PR Floogen#371) and offered the
translations in a comment on this PR rather than opening a separate one.

bg.json was at 367 keys against default.json's 380; it is now at 380/380
with no missing, extra or empty keys. Only bg.json is touched, and it keeps
its existing CRLF line endings and no-BOM convention.
@Z2549

Z2549 commented Oct 12, 2026

Copy link
Copy Markdown
Contributor Author

Done! I've added all 13 Bulgarian translations to bg.json in this PR, so it now sits at 380/380 keys. Thanks for preparing them, and for the kind words about the localization work.

A few notes on what I did:

  • I placed them under the same section comments you used (// Profile Editor Window - Dialogs, // Settings Window - Dialogs, // Settings Window - Nexus Servers), so bg.json's grouping now matches default.json's.
  • bg.json keeps its existing CRLF line endings and no-BOM convention, so the diff is a pure content addition.
  • I verified bg.json's key set is now identical to default.json's — no missing, no extra, no empty values, no duplicate keys.
  • I left Nexus CDN untranslated, same as default.json, since it reads as a product name rather than a place.

The push also refreshes this PR automatically, so no separate PR is needed on your side. Thanks again!

Every locale was missing exactly these 13 keys, so all of them are now at
380 keys with no missing, extra or empty entries.

City names follow each language's own Wikipedia article title rather than a
literal transliteration, so they match what speakers of that language expect
(de Prag not Prague, es Amsterdam with the accent, uk and ru spelled
differently, th and ja/ko transliterated). Three Wikipedia titles carried a
disambiguation suffix that is not part of the place name, and that suffix is
dropped: ko Paris is listed as "파리 (프랑스)", hu Miami as "Miami (Florida)"
and th Singapore as a country article. Nexus CDN stays in English everywhere,
same as default.json.

The UI strings reuse each locale's existing vocabulary for mod, folder and
profile, which I read out of the files that were already translated, instead
of inventing new terms.

Each file keeps its own conventions, which are not uniform across the repo:
fr.json indents with four spaces and tr.json with tabs, while the rest use
two. All of them stay CRLF with no BOM, matching what they were before. Only
additions - no existing key was removed or edited, including the stale keys
that some files still carry from older upstream versions.
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.

2 participants