Skip to content

Add Public Achivements UI#3530

Draft
Aotumuri wants to merge 2 commits intomainfrom
public-achivements-ui
Draft

Add Public Achivements UI#3530
Aotumuri wants to merge 2 commits intomainfrom
public-achivements-ui

Conversation

@Aotumuri
Copy link
Copy Markdown
Member

If this PR fixes an issue, link it below. If not, delete these two lines.
Resolves #(issue number)

Description:

Describe the PR.

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:

DISCORD_USERNAME

@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 29, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4dd35dad-85c0-48b2-9539-acb6fa2badbb

📥 Commits

Reviewing files that changed from the base of the PR and between a5c2d4f and 3c4d1f9.

📒 Files selected for processing (2)
  • resources/lang/en.json
  • src/client/components/baseComponents/stats/PlayerAchievements.ts
✅ Files skipped from review due to trivial changes (1)
  • resources/lang/en.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/client/components/baseComponents/stats/PlayerAchievements.ts

Walkthrough

Added player achievements: new English translation strings, a player achievement metadata JSON, API schema updates to support heterogeneous achievement payloads, a new player-achievements Lit component that renders achievement cards, and integration of that component into the account modal.

Changes

Cohort / File(s) Summary
Language and UI Strings
resources/lang/en.json
Added translation keys for achievements UI labels, statuses, empty state, and a specific achievement title/description.
Achievement Metadata
resources/playerAchievementMetadata.json
New JSON file registering achievement metadata (e.g., win_no_nukes with difficulty: "Hard").
Account Modal Integration
src/client/AccountModal.ts
Account modal now imports/renders player-achievements, passing this.userMeResponse?.player?.achievements (defaulting to []) as achievementGroups.
Achievements Component
src/client/components/baseComponents/stats/PlayerAchievements.ts
New LitElement player-achievements component: accepts achievementGroups, filters player-type achievements, sorts by achievedAt desc, merges with static metadata, renders cards with translated title/desc, difficulty badges, and achieved dates, and shows an empty state when none unlocked. Renders into light DOM.
API Schema Updates
src/core/ApiSchemas.ts
Added PlayerAchievementSchema, AchievementsResponseSchema (discriminated union), and inferred types. Updated UserMeResponseSchema.user.player.achievements to AchievementsResponseSchema.optional() and added optional achievements to PlayerProfileSchema.

Sequence Diagram

sequenceDiagram
    participant User as User
    participant Modal as AccountModal
    participant Component as PlayerAchievements
    participant Metadata as PlayerAchievementMetadata
    participant Formatter as Intl.DateTimeFormat

    User->>Modal: Open account modal
    Modal->>Modal: Read userMeResponse.player.achievements
    Modal->>Component: Pass achievementGroups array
    Component->>Component: Filter entries where type == "player"
    Component->>Component: Sort unlocked by achievedAt (desc)
    Component->>Metadata: Lookup metadata by achievement key
    Metadata-->>Component: Return difficulty & description
    Component->>Formatter: Format achievedAt timestamp
    Formatter-->>Component: Return formatted date or raw value
    Component->>User: Render achievement cards or empty state
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🏆 New badges gleam on the account wall,
Locked and unlocked — a card for them all,
Metadata, dates, and labels align,
Players’ triumphs shown, tidy and fine,
Cheers for features that make moments small ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is a template with placeholder guidance and uncompleted checklist items; it does not contain any concrete description of the actual changes implemented in the changeset. Replace the template with a real description explaining the achievement UI feature, confirming test coverage, and providing Discord username for contact.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add Public Achivements UI' refers to the main change in the changeset (adding achievement UI components), but contains a typo ('Achivements' instead of 'Achievements'), making it slightly unclear.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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
Copy Markdown
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/AccountModal.ts (1)

179-186: Consider adding an emoji for visual consistency with other sections.

The Stats Overview section uses 📊 and Recent Games uses 🎮. The Achievements section heading lacks an icon, which creates visual inconsistency.

✨ Suggested enhancement
           <div class="bg-white/5 rounded-xl border border-white/10 p-6">
-            <h3 class="text-lg font-bold text-white mb-4">
+            <h3
+              class="text-lg font-bold text-white mb-4 flex items-center gap-2"
+            >
+              <span class="text-blue-400">🏆</span>
               ${translateText("account_modal.achievements")}
             </h3>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/client/AccountModal.ts` around lines 179 - 186, Add an emoji to the
Achievements header to match other sections: update the string passed to
translateText("account_modal.achievements") (or prepend the emoji when rendering
in the h3) so the heading includes an icon (e.g., "🏆") and keep the rest of the
markup unchanged (the h3 element containing translateText and the
<player-achievements .achievementGroups=${achievements}> component).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@resources/lang/en.json`:
- Around line 245-248: Rename the misspelled translation object "achivements" to
"achievements" in en.json and update all lookup sites to use the corrected key;
specifically change the en.json top-level key from "achivements" to
"achievements" and update the translation lookups in PlayerAchievements.ts (the
lines that build the translation key using achievementKey) from
"achivements.${achievementKey}" to "achievements.${achievementKey}" so the i18n
lookup uses the corrected path.

In `@src/client/components/baseComponents/stats/PlayerAchievements.ts`:
- Around line 97-107: In resolveTitle and resolveDescription change the
translation key prefix from "achivements." to the correct "achievements." (i.e.,
update the template strings in resolveTitle(achievementKey) and
resolveDescription(achievementKey)); also update the corresponding keys in the
en.json translations to use "achievements" instead of "achivements" so the
translateText lookups resolve correctly.

---

Nitpick comments:
In `@src/client/AccountModal.ts`:
- Around line 179-186: Add an emoji to the Achievements header to match other
sections: update the string passed to
translateText("account_modal.achievements") (or prepend the emoji when rendering
in the h3) so the heading includes an icon (e.g., "🏆") and keep the rest of the
markup unchanged (the h3 element containing translateText and the
<player-achievements .achievementGroups=${achievements}> component).
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ba849722-0822-4752-a33d-f23a7b060909

📥 Commits

Reviewing files that changed from the base of the PR and between 217a2c4 and a5c2d4f.

📒 Files selected for processing (5)
  • resources/lang/en.json
  • resources/playerAchievementMetadata.json
  • src/client/AccountModal.ts
  • src/client/components/baseComponents/stats/PlayerAchievements.ts
  • src/core/ApiSchemas.ts

Comment on lines +245 to +248
"achivements": {
"win_no_nukes": "Win Without Nukes",
"win_no_nukes_desc": "Win a free-for-all match without launching any nukes."
},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Typo in translation key: achivements should be achievements.

The key is misspelled (missing 'e'). While the code in PlayerAchievements.ts uses the same misspelling so translations will work, fixing this now avoids confusion and prevents the typo from spreading further.

✏️ Suggested fix
-  "achivements": {
+  "achievements": {
     "win_no_nukes": "Win Without Nukes",
     "win_no_nukes_desc": "Win a free-for-all match without launching any nukes."
   },

Also update PlayerAchievements.ts lines 98 and 104 to use achievements.${achievementKey} instead of achivements.${achievementKey}.

📝 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
"achivements": {
"win_no_nukes": "Win Without Nukes",
"win_no_nukes_desc": "Win a free-for-all match without launching any nukes."
},
"achievements": {
"win_no_nukes": "Win Without Nukes",
"win_no_nukes_desc": "Win a free-for-all match without launching any nukes."
},
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@resources/lang/en.json` around lines 245 - 248, Rename the misspelled
translation object "achivements" to "achievements" in en.json and update all
lookup sites to use the corrected key; specifically change the en.json top-level
key from "achivements" to "achievements" and update the translation lookups in
PlayerAchievements.ts (the lines that build the translation key using
achievementKey) from "achivements.${achievementKey}" to
"achievements.${achievementKey}" so the i18n lookup uses the corrected path.

Comment on lines +97 to +107
private resolveTitle(achievementKey: string): string {
const translationKey = `achivements.${achievementKey}`;
const translated = translateText(translationKey);
return translated === translationKey ? achievementKey : translated;
}

private resolveDescription(achievementKey: string): string | null {
const translationKey = `achivements.${achievementKey}_desc`;
const translated = translateText(translationKey);
return translated === translationKey ? null : translated;
}
Copy link
Copy Markdown
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 the typo: achivements should be achievements.

This mirrors the typo in en.json. Both should be fixed together.

✏️ Suggested fix
   private resolveTitle(achievementKey: string): string {
-    const translationKey = `achivements.${achievementKey}`;
+    const translationKey = `achievements.${achievementKey}`;
     const translated = translateText(translationKey);
     return translated === translationKey ? achievementKey : translated;
   }

   private resolveDescription(achievementKey: string): string | null {
-    const translationKey = `achivements.${achievementKey}_desc`;
+    const translationKey = `achievements.${achievementKey}_desc`;
     const translated = translateText(translationKey);
     return translated === translationKey ? null : translated;
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/client/components/baseComponents/stats/PlayerAchievements.ts` around
lines 97 - 107, In resolveTitle and resolveDescription change the translation
key prefix from "achivements." to the correct "achievements." (i.e., update the
template strings in resolveTitle(achievementKey) and
resolveDescription(achievementKey)); also update the corresponding keys in the
en.json translations to use "achievements" instead of "achivements" so the
translateText lookups resolve correctly.

@github-project-automation github-project-automation bot moved this from Triage to Development in OpenFront Release Management Mar 29, 2026
@Aotumuri Aotumuri linked an issue Mar 29, 2026 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Development

Development

Successfully merging this pull request may close these issues.

Add public achievements support (API + UI)

2 participants