Skip to content

Conversation

@FloPinguin
Copy link
Contributor

@FloPinguin FloPinguin commented Jan 1, 2026

Description:

  • Renamed "Difficulty" -> "Nation difficulty" to make clear that the "difficulty" only changes the nations
  • If nations are disabled, the difficulty gets blurred now. And a "not-allowed" cursor is shown on hover.
Screenshot 2026-01-01 225108
  • Also did a small CSS fix to allow word breaks

Before:

Screenshot 2026-01-01 231332

After:

Screenshot 2026-01-01 231306

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:

FloPinguin

@FloPinguin FloPinguin requested a review from a team as a code owner January 1, 2026 22:02
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 1, 2026

Walkthrough

Difficulty option cards are now disabled when disableNations is true (visual, ARIA, and click-guard changes). The localization key label was changed from "Difficulty" to "Nation difficulty". No other behavior or control flow was modified.

Changes

Cohort / File(s) Summary
Translation Updates
resources/lang/en.json
Changed "difficulty": "Difficulty""difficulty": "Nation difficulty".
Host lobby & Single-player UI
src/client/HostLobbyModal.ts, src/client/SinglePlayerModal.ts
Difficulty option cards gain class="disabled" and aria-disabled="true" when disableNations is true; click handlers now guard selection to skip when disabled; difficulty-display gets disabled-parent class when appropriate.
Styles / Visuals
src/client/styles.css, src/client/components/Difficulties.ts
Added .option-card.disabled { opacity: 0.3; cursor: not-allowed }; hover rules scoped to avoid applying when disabled; .option-card-title updated to allow wrapping; added lighter shadow/translation for active skulls under .disabled-parent.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

UI/UX, Translation

Suggested reviewers

  • evanpelle

Poem

Disabled cards in gentle light,
A label changed to set things right.
Clicks that pause, visuals mild,
Nation difficulty, softly styled.
Small edits, tidy and bright.

Pre-merge checks

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Title check ⚠️ Warning The title mentions the main label change (Difficulty → Nation difficulty) but significantly undersells the broader scope, which includes disability states, visual feedback, and CSS improvements across multiple components. Update the title to reflect the complete scope, such as: 'Disable difficulty selection when nations are disabled and rename to Nation difficulty' or similar.
✅ Passed checks (2 passed)
Check name Status Explanation
Description check ✅ Passed The description accurately covers all three major aspects: label rename, disabled state styling/interaction, and CSS word-break fix, with supporting screenshots and checklists completed.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fb8c4cc and 259f879.

📒 Files selected for processing (4)
  • src/client/HostLobbyModal.ts
  • src/client/SinglePlayerModal.ts
  • src/client/components/Difficulties.ts
  • src/client/styles.css
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/client/SinglePlayerModal.ts
  • src/client/styles.css
🧰 Additional context used
🧠 Learnings (3)
📓 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: 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.
📚 Learning: 2025-06-09T02:20:43.637Z
Learnt from: VariableVince
Repo: openfrontio/OpenFrontIO PR: 1110
File: src/client/Main.ts:293-295
Timestamp: 2025-06-09T02:20:43.637Z
Learning: In src/client/Main.ts, during game start in the handleJoinLobby callback, UI elements are hidden using direct DOM manipulation with classList.add("hidden") for consistency. This includes modals, buttons, and error divs. The codebase follows this pattern rather than using component APIs for hiding elements during game transitions.

Applied to files:

  • src/client/components/Difficulties.ts
  • src/client/HostLobbyModal.ts
📚 Learning: 2025-10-21T20:06:04.823Z
Learnt from: Saphereye
Repo: openfrontio/OpenFrontIO PR: 2233
File: src/client/HostLobbyModal.ts:891-891
Timestamp: 2025-10-21T20:06:04.823Z
Learning: For the HumansVsNations game mode in `src/client/HostLobbyModal.ts` and related files, the implementation strategy is to generate all nations and adjust their strength for balancing, rather than limiting lobby size based on the number of available nations on the map.

Applied to files:

  • src/client/HostLobbyModal.ts
🔇 Additional comments (2)
src/client/components/Difficulties.ts (1)

41-46: LGTM! Disabled state styling is correct.

The CSS properly locks the active skull styling when the parent is disabled, preventing the hover enhancement from applying. The disabled state maintains the base active appearance (4px shadow, -1px translation) regardless of hover, which provides clear visual feedback that interaction is disabled.

src/client/HostLobbyModal.ts (1)

247-254: Good implementation of disabled state with proper accessibility.

The disabled state is correctly implemented with:

  • Conditional disabled class for styling (with opacity: 0.3 and cursor: not-allowed in CSS)
  • aria-disabled attribute for screen readers
  • Click guard preventing interaction when disabled
  • disabled-parent class communicating state to child component

The CSS in src/client/styles.css properly handles the .option-card.disabled class with opacity and cursor styling. The click handler guard (!this.disableNations) provides sufficient protection—pointer-events: none is not present in CSS but is not critical since the handler itself cannot execute when disabled.


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: 0

🧹 Nitpick comments (2)
src/client/HostLobbyModal.ts (1)

248-255: Implementation works correctly.

The disabled state for difficulty selection when nations are disabled is properly implemented with clear visual feedback (reduced opacity and cursor change) and a guarded click handler.

Optional: Consider adding semantic accessibility and cleaner styling

1. Accessibility enhancement: Add aria-disabled attribute to help screen readers:

 <div
   class="option-card ${this.selectedDifficulty === value
     ? "selected"
     : ""}"
   style="opacity: ${this.disableNations
     ? "0.3"
     : "1"}; cursor: ${this.disableNations
     ? "not-allowed"
     : "pointer"};"
+  aria-disabled="${this.disableNations}"
   @click=${() =>
     !this.disableNations &&
     this.handleDifficultySelection(value)}
 >

2. Code style improvement: Consider using conditional class binding for cleaner code:

Add CSS classes:

.option-card.disabled {
  opacity: 0.3;
  cursor: not-allowed;
}

Then simplify the template:

 <div
-  class="option-card ${this.selectedDifficulty === value
-    ? "selected"
-    : ""}"
-  style="opacity: ${this.disableNations
-    ? "0.3"
-    : "1"}; cursor: ${this.disableNations
-    ? "not-allowed"
-    : "pointer"};"
+  class="option-card ${this.selectedDifficulty === value ? "selected" : ""} ${this.disableNations ? "disabled" : ""}"
+  aria-disabled="${this.disableNations}"
   @click=${() =>
     !this.disableNations &&
     this.handleDifficultySelection(value)}
 >
src/client/SinglePlayerModal.ts (1)

151-158: Consistent implementation, works correctly.

The disabled state logic here matches the implementation in HostLobbyModal.ts, which is good for consistency. The visual feedback and click handler guard work as intended.

The same optional accessibility and code style improvements suggested for HostLobbyModal.ts (Lines 248-255) would apply here:

  1. Add aria-disabled="${this.disableNations}" for screen reader support
  2. Consider using conditional CSS classes instead of inline styles for cleaner code
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ad7c30e and 5705d65.

📒 Files selected for processing (3)
  • resources/lang/en.json
  • src/client/HostLobbyModal.ts
  • src/client/SinglePlayerModal.ts
🧰 Additional context used
🧠 Learnings (5)
📓 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: 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: Saphereye
Repo: openfrontio/OpenFrontIO PR: 2233
File: src/client/HostLobbyModal.ts:891-891
Timestamp: 2025-10-21T20:06:04.823Z
Learning: For the HumansVsNations game mode in `src/client/HostLobbyModal.ts` and related files, the implementation strategy is to generate all nations and adjust their strength for balancing, rather than limiting lobby size based on the number of available nations on the map.
📚 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:

  • resources/lang/en.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:

  • resources/lang/en.json
📚 Learning: 2025-10-21T20:06:04.823Z
Learnt from: Saphereye
Repo: openfrontio/OpenFrontIO PR: 2233
File: src/client/HostLobbyModal.ts:891-891
Timestamp: 2025-10-21T20:06:04.823Z
Learning: For the HumansVsNations game mode in `src/client/HostLobbyModal.ts` and related files, the implementation strategy is to generate all nations and adjust their strength for balancing, rather than limiting lobby size based on the number of available nations on the map.

Applied to files:

  • src/client/SinglePlayerModal.ts
  • src/client/HostLobbyModal.ts
📚 Learning: 2025-06-09T02:20:43.637Z
Learnt from: VariableVince
Repo: openfrontio/OpenFrontIO PR: 1110
File: src/client/Main.ts:293-295
Timestamp: 2025-06-09T02:20:43.637Z
Learning: In src/client/Main.ts, during game start in the handleJoinLobby callback, UI elements are hidden using direct DOM manipulation with classList.add("hidden") for consistency. This includes modals, buttons, and error divs. The codebase follows this pattern rather than using component APIs for hiding elements during game transitions.

Applied to files:

  • src/client/SinglePlayerModal.ts
  • src/client/HostLobbyModal.ts
🔇 Additional comments (1)
resources/lang/en.json (1)

347-347: LGTM! Clear label improvement.

The label change from "Difficulty" to "Nation difficulty" effectively clarifies that this setting only affects nations, which improves user understanding.

coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 1, 2026
coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 1, 2026
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: 1

🧹 Nitpick comments (2)
src/client/SinglePlayerModal.ts (1)

147-163: Disabled state implementation looks good.

The logic correctly prevents difficulty selection when nations are disabled by using short-circuit evaluation in the click handler. The visual styling via the "disabled" class and aria-disabled attribute provide clear feedback to users and screen readers.

Optional: Enhance keyboard accessibility

Currently, disabled cards remain keyboard-focusable. Users can still tab to them and press Enter/Space, though the click handler won't fire. For better accessibility, consider making disabled cards non-focusable:

                  ([key, value]) => html`
                    <div
                      class="option-card ${this.selectedDifficulty === value
                        ? "selected"
                        : ""} ${this.disableNations ? "disabled" : ""}"
                      aria-disabled="${this.disableNations}"
+                     tabindex="${this.disableNations ? "-1" : "0"}"
                      @click=${() =>
                        !this.disableNations &&
                        this.handleDifficultySelection(value)}
                    >

This prevents keyboard users from reaching non-functional elements.

src/client/styles.css (1)

110-117: Text wrapping improvement works well.

Adding word-break and overflow-wrap ensures long option titles wrap properly within their cards, improving the layout.

Optional: Simplify property usage

Both word-break: break-word and overflow-wrap: break-word are present. Since overflow-wrap is the standard property that handles this, you could simplify to just use that one:

 .option-card-title {
   font-size: 14px;
   color: #aaa;
   text-align: center;
   margin: 0 0 4px 0;
-  word-break: break-word;
   overflow-wrap: break-word;
 }

Keeping both provides extra compatibility but isn't strictly necessary.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5705d65 and fb8c4cc.

📒 Files selected for processing (3)
  • src/client/HostLobbyModal.ts
  • src/client/SinglePlayerModal.ts
  • src/client/styles.css
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/client/HostLobbyModal.ts
🧰 Additional context used
🧠 Learnings (3)
📓 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: 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.
📚 Learning: 2025-10-21T20:06:04.823Z
Learnt from: Saphereye
Repo: openfrontio/OpenFrontIO PR: 2233
File: src/client/HostLobbyModal.ts:891-891
Timestamp: 2025-10-21T20:06:04.823Z
Learning: For the HumansVsNations game mode in `src/client/HostLobbyModal.ts` and related files, the implementation strategy is to generate all nations and adjust their strength for balancing, rather than limiting lobby size based on the number of available nations on the map.

Applied to files:

  • src/client/SinglePlayerModal.ts
📚 Learning: 2025-06-09T02:20:43.637Z
Learnt from: VariableVince
Repo: openfrontio/OpenFrontIO PR: 1110
File: src/client/Main.ts:293-295
Timestamp: 2025-06-09T02:20:43.637Z
Learning: In src/client/Main.ts, during game start in the handleJoinLobby callback, UI elements are hidden using direct DOM manipulation with classList.add("hidden") for consistency. This includes modals, buttons, and error divs. The codebase follows this pattern rather than using component APIs for hiding elements during game transitions.

Applied to files:

  • src/client/SinglePlayerModal.ts

@iiamlewis iiamlewis added the Bug label Jan 2, 2026
@iiamlewis iiamlewis added this to the v29 milestone Jan 2, 2026
@iiamlewis iiamlewis moved this from Triage to Peer Review in OpenFront Release Management Jan 2, 2026
Copy link
Collaborator

@evanpelle evanpelle left a comment

Choose a reason for hiding this comment

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

Thanks!

@github-project-automation github-project-automation bot moved this from Peer Review to Final Review in OpenFront Release Management Jan 2, 2026
@evanpelle evanpelle merged commit 7d9a61a into openfrontio:main Jan 2, 2026
8 of 9 checks passed
@github-project-automation github-project-automation bot moved this from Final Review to Complete in OpenFront Release Management Jan 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Complete

Development

Successfully merging this pull request may close these issues.

3 participants