What's fixed
🏅 Equipped badges showed English titles after language change
Server-side bug I missed. GetEquippedBadges was bypassing BadgeLocalizer — it cloned profile.Badges and returned them with whatever Title/Description was stored at unlock time (always English from the definitions). So switching to Portuguese/French/etc. flipped everything else in the UI but the equipped row stayed "Daily Viewer" / "Getting Comfortable" / etc.
Fix: every clone now goes through BadgeLocalizer.Localize(clone, profile.Preferences.Language). Same fix applied to BuildEquippedPreview (the projection used by leaderboard dots, compare-header dots, and the public /profiles/{id}/equipped endpoint).
🌍 Admin page translations really work this time
Symptoms: French/Portuguese admin, all section headers ("Webhook notifications (admin)", "Visual badge editor (admin)", etc.) stay English.
Root cause candidates I hardened against:
- ApiClient timing — poll every 80 ms for up to 5 s instead of 100 ms for 2.5 s.
- Reverse-proxy subpath — fetch now goes through
apiClient.getUrl()once ApiClient is ready, so/jellyfin/Plugins/...routes work instead of 404'ing on/Plugins/.... - Auth token missing — added
X-Emby-Tokenheader to the/translationsfetch viaapiClient.accessToken()so the endpoint accepts the request. - First-paint flash — localStorage-seeded dict applied immediately while the server round-trip is in flight, so the admin sees their saved language instantly, not after a 500-1000 ms delay.
MD5: 915BBE73EA159D855CC753D565E5D916