Skip to content

Conversation

@JJ173
Copy link

@JJ173 JJ173 commented Nov 20, 2025

The coop tab has been updated with the following changes:

  • Added new selection list for scenarios (UEF, Aeon, Cybran, etc...)
  • Added new link to the mission scripting wiki.
  • Added new button to the mission scripting Discord.
  • Added new icon (wrench) for custom missions.

Summary by CodeRabbit

  • New Features

    • Missions now organized by scenarios with a scenario selection dropdown
    • Cached coop scenarios for faster loading
    • Expanded faction/type support for coop content
  • UI Improvements

    • Reorganized coop interface with a description pane, scenario/mission lists, and updated leaderboard layout
    • Added Wiki and Discord actions and an informational label with coop tips
    • Mission entries now show consolidated names/versions
  • Style

    • New wrench icon/style for theming and UI buttons

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Nov 20, 2025

Walkthrough

Refactors coop to be scenario-driven: adds CoopScenario/CoopFaction/CoopType types, scenario loading and caching, UI wiring for scenario→missions, mapper support, cache entry, FXML layout updates, theme/icon and i18n additions, and removes the old CoopCategory enum from coop package.

Changes

Cohort / File(s) Change Summary
Cache & Config
src/main/java/com/faforever/client/config/CacheNames.java, src/main/java/com/faforever/client/config/CacheConfig.java
Added COOP_SCENARIOS constant and registered a COOP_SCENARIOS cache with the same expiration/size semantics as other caches.
Coop types (new/removed)
src/main/java/com/faforever/client/coop/CoopFaction.java, src/main/java/com/faforever/client/coop/CoopType.java, src/main/java/com/faforever/client/coop/CoopCategory.java
Added CoopFaction enum and CoopType enum; removed old public CoopCategory enum from the coop package.
API domain records
src/main/java/com/faforever/client/domain/api/CoopScenario.java, src/main/java/com/faforever/client/domain/api/CoopCategory.java, src/main/java/com/faforever/client/domain/api/CoopMission.java
Added CoopScenario record (id,name,description,order,faction,type,maps) with compact constructor normalizing maps; added API CoopCategory record; updated CoopMission to remove category and add concatName() method.
Mapping
src/main/java/com/faforever/client/mapstruct/CoopMapper.java
Added DTO ↔ domain mapping methods for CoopScenario.
Service layer
src/main/java/com/faforever/client/coop/CoopService.java
Added public Flux<CoopScenario> getScenarios() which fetches, maps, and caches scenarios (including maps).
Controller & UI logic
src/main/java/com/faforever/client/coop/CoopController.java
Replaced category-driven flow with scenario-driven flow: added scenarioComboBox, wired getScenarios() to populate scenarios, added populateMissionList(CoopScenario), updated mission population/cell rendering, and added external-link handlers (onWikiButtonClicked, onDiscordHyperLinkClicked) and helper desktopBrowserNavigateToURI.
Theming & icons
src/main/java/com/faforever/client/theme/ThemeService.java, src/main/resources/theme/icons.css
Added MOD_ICON_STYLE_CLASS and WRENCH_STYLE_CLASS constants; added .wrench-icon CSS class with -fx-shape vector.
I18n
src/main/resources/i18n/messages.properties
Added coop.wiki.button, coop.discord.button, and coop.info.label translation keys.
FXML / Layout
src/main/resources/theme/play/coop/coop.fxml
Restructured layout: nested VBox/HBox, added WebView for descriptions, wiki/Discord/info panel, reorganized leaderboard and table columns, and formatting/constraint adjustments.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CoopController
    participant CoopService
    participant CoopMapper
    participant Cache

    User->>CoopController: Open Coop view
    CoopController->>CoopService: getScenarios()
    CoopService->>Cache: lookup COOP_SCENARIOS
    alt cache hit
        Cache-->>CoopService: cached Flux<CoopScenario>
    else cache miss
        CoopService->>CoopService: request API (includes maps)
        CoopService->>CoopMapper: map DTO -> CoopScenario
        CoopService->>Cache: store COOP_SCENARIOS
    end
    CoopService-->>CoopController: Flux<CoopScenario>
    CoopController->>CoopController: populate scenarioComboBox

    User->>CoopController: select scenario
    CoopController->>CoopController: populateMissionList(selectedScenario)
    CoopController-->>User: update missions, map preview, leaderboard
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Focus review on:
    • CoopController: scenario→mission wiring, cell factories, and external-link handling.
    • CoopService & caching: correct key usage and that maps are included in cached payload.
    • Mapper & domain records: alignment with DTO shapes (CoopScenario, CoopMission, CoopCategory).
    • FXML: IDs/bindings and layout changes (WebView, new controls).

Suggested reviewers

  • Sheikah45

Poem

🐰 I hopped through bytes where scenarios hide,

New maps nest tidy, old enums stepped aside.
Icons sharpen, caches hum in tune,
A rabbit's cheer beneath the coding moon.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main changes: UI updates to the coop tab including scenarios selection, wiki/Discord links, and a new icon.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 917033d and e81b1f4.

📒 Files selected for processing (1)
  • src/main/resources/theme/play/coop/coop.fxml (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/resources/theme/play/coop/coop.fxml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Codacy Static Code Analysis

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

@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: 4

🧹 Nitpick comments (7)
src/main/java/com/faforever/client/theme/ThemeService.java (1)

102-104: Consider alphabetical ordering of constants.

The new constants MOD_ICON_STYLE_CLASS and WRENCH_STYLE_CLASS are placed between faction icon constants, which disrupts the grouping pattern. Consider either:

  • Grouping all faction icons together (AEON, CYBRAN, SERAPHIM, UEF) followed by other icons (MOD, WRENCH), or
  • Ordering all icon constants alphabetically

This improves maintainability and makes it easier to locate specific constants.

src/main/java/com/faforever/client/coop/CoopType.java (1)

3-5: Consider adding documentation for enum values.

The enum values SC, SCFA, and CUSTOM would benefit from Javadoc comments explaining what they represent. This improves code clarity, especially for new contributors who may not be familiar with the abbreviations.

Example:

 public enum CoopType {
+  /** Supreme Commander base game scenarios */
   SC, 
+  /** Supreme Commander: Forged Alliance expansion scenarios */
   SCFA, 
+  /** Custom user-created scenarios */
   CUSTOM
 }
src/main/java/com/faforever/client/domain/api/CoopCategory.java (1)

5-8: Consider clarifying the purpose and naming of this record.

The CoopCategory record has a field named coopCategory of type CoopFaction, which creates naming ambiguity. Additionally, having both categoryName (String) and coopCategory (CoopFaction) suggests potential redundancy.

Consider:

  1. If categoryName is a display name while coopCategory is the enum value, rename the field to displayName for clarity
  2. If they serve different purposes, add Javadoc to explain the distinction
  3. Verify if both fields are necessary or if one can be derived from the other

Example:

/**
 * Represents a cooperative scenario category.
 * @param displayName The human-readable category name
 * @param faction The faction associated with this category
 */
public record CoopCategory(
    String displayName,
    CoopFaction faction
) {}
src/main/resources/theme/play/coop/coop.fxml (1)

3-3: Remove unnecessary import.

The <?import java.lang.*?> import is unnecessary as java.lang is automatically imported in Java. This import serves no purpose in FXML.

Apply this diff:

-<?import java.lang.*?>
 <?import javafx.collections.*?>
src/main/java/com/faforever/client/coop/CoopController.java (3)

33-33: Remove unused import.

The javafx.application.HostServices import is not used in this file.

Apply this diff:

-import javafx.application.HostServices;
 import javafx.collections.FXCollections;

55-55: Remove unused import.

The jdk.jfr.Category import is not used in this file.

Apply this diff:

 import javafx.util.StringConverter;
-import jdk.jfr.Category;
 import lombok.RequiredArgsConstructor;

212-215: Consider using streams for better readability.

The explicit loop can be replaced with a more idiomatic stream operation using flatMap.

Apply this diff:

-                 List<CoopMission> coopMissions = new ArrayList<>();
-                 for (CoopScenario coopScenario : coopScenarios) {
-                   coopMissions.addAll(coopScenario.maps());
-                 }
+                 List<CoopMission> coopMissions = coopScenarios.stream()
+                     .flatMap(scenario -> scenario.maps().stream())
+                     .toList();
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5456695 and 540c382.

📒 Files selected for processing (17)
  • .idea/codeStyles/Project.xml (1 hunks)
  • .idea/runConfigurations/Main.xml (1 hunks)
  • src/main/java/com/faforever/client/config/CacheConfig.java (2 hunks)
  • src/main/java/com/faforever/client/config/CacheNames.java (1 hunks)
  • src/main/java/com/faforever/client/coop/CoopCategory.java (0 hunks)
  • src/main/java/com/faforever/client/coop/CoopController.java (10 hunks)
  • src/main/java/com/faforever/client/coop/CoopFaction.java (1 hunks)
  • src/main/java/com/faforever/client/coop/CoopService.java (2 hunks)
  • src/main/java/com/faforever/client/coop/CoopType.java (1 hunks)
  • src/main/java/com/faforever/client/domain/api/CoopCategory.java (1 hunks)
  • src/main/java/com/faforever/client/domain/api/CoopMission.java (1 hunks)
  • src/main/java/com/faforever/client/domain/api/CoopScenario.java (1 hunks)
  • src/main/java/com/faforever/client/mapstruct/CoopMapper.java (2 hunks)
  • src/main/java/com/faforever/client/theme/ThemeService.java (1 hunks)
  • src/main/resources/i18n/messages.properties (1 hunks)
  • src/main/resources/theme/icons.css (1 hunks)
  • src/main/resources/theme/play/coop/coop.fxml (1 hunks)
💤 Files with no reviewable changes (1)
  • src/main/java/com/faforever/client/coop/CoopCategory.java
🧰 Additional context used
🧬 Code graph analysis (2)
src/main/java/com/faforever/client/config/CacheConfig.java (1)
src/main/java/com/faforever/client/config/CacheNames.java (1)
  • CacheNames (3-50)
src/main/java/com/faforever/client/coop/CoopService.java (1)
src/main/java/com/faforever/client/config/CacheNames.java (1)
  • CacheNames (3-50)
🪛 Biome (2.1.2)
src/main/resources/theme/icons.css

[error] 403-403: Unknown property is not allowed.

See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.

(lint/correctness/noUnknownProperty)

🔇 Additional comments (12)
.idea/codeStyles/Project.xml (1)

28-30: Verify intent of EditorConfig disabling.

This change disables EditorConfig in the IDE project configuration, which appears unrelated to the stated PR objectives (Coop Tab UI updates, scenario selection, wiki/Discord links). Confirm whether this was intentional or a stray modification that should be excluded from this PR.

.idea/runConfigurations/Main.xml (1)

1-18: Original review comment is based on incorrect assumptions about repository practices and should be disregarded.

The change is not problematic:

  1. Repository intentionally tracks .idea/ files: Despite the root .gitignore having .idea/*, the repository deliberately commits .idea/ configuration files. Files like .idea/runConfigurations/Main.xml, .idea/codeStyles/Project.xml, and .idea/vcs.xml are tracked in version control, indicating this is standard practice for the project.

  2. Java 25 is already the build target: The build.gradle file already specifies sourceCompatibility = JavaVersion.VERSION_25 and targetCompatibility = JavaVersion.VERSION_25. This IDE configuration change merely aligns with the existing build configuration rather than introducing an unverified upgrade.

  3. No compatibility issues detected: The codebase has only 7 deprecation warnings, which is normal and not blocking for Java 25 adoption.

The IDE run configuration update is a straightforward synchronization with the project's existing Java 25 build configuration, not a risky or undiscussed change.

Likely an incorrect or invalid review comment.

src/main/resources/theme/icons.css (1)

402-404: LGTM! Static analysis warning is a false positive.

The .wrench-icon class is correctly implemented following the same pattern as other icon classes in this file. The static analysis tool (Biome) incorrectly flags -fx-shape as an unknown property, but this is a valid JavaFX CSS property used throughout this file.

src/main/java/com/faforever/client/config/CacheConfig.java (1)

95-95: LGTM!

The COOP_SCENARIOS cache is properly configured with the same expiration and size semantics as the related COOP_MAPS cache. The placement next to COOP_MAPS is logical and maintains good organization.

src/main/resources/i18n/messages.properties (1)

46-46: LGTM!

The new translation key coop.wiki.button is properly placed within the coop section and follows the existing naming conventions. The value "Visit Wiki" is clear and appropriate for a button label.

src/main/java/com/faforever/client/config/CacheNames.java (1)

34-34: LGTM!

The COOP_SCENARIOS constant is correctly defined and placed logically next to the related COOP_MAPS constant. The naming convention is consistent with other cache names in the file.

src/main/java/com/faforever/client/coop/CoopService.java (1)

43-48: LGTM!

The getScenarios() method is well-implemented, following the same pattern as the existing getMissions() method. The caching annotation, ElideNavigator configuration with addInclude("maps") to fetch related missions, and the use of reactive streams are all appropriate.

The page size of 1000 matches getMissions() and should be sufficient for coop scenarios, but consider monitoring if the number of scenarios approaches this limit in the future.

src/main/java/com/faforever/client/coop/CoopFaction.java (1)

3-5: LGTM!

The enum is well-defined and covers the required faction types for the coop scenario feature.

src/main/java/com/faforever/client/mapstruct/CoopMapper.java (1)

21-25: LGTM!

The CoopScenario mapping methods follow the established MapStruct patterns in this mapper interface and provide proper bidirectional conversion between DTOs and domain objects.

src/main/java/com/faforever/client/domain/api/CoopScenario.java (1)

16-18: LGTM!

The compact constructor provides good defensive programming by ensuring the maps field is never null and always immutable, which prevents accidental mutations and null pointer exceptions.

src/main/java/com/faforever/client/coop/CoopController.java (2)

127-129: LGTM!

The scenario selection binding properly drives the mission list population, establishing a clean data flow from scenario selection to mission availability.


310-318: LGTM!

The populateMissionList method correctly handles null scenarios and properly updates the mission combo box with the selected scenario's maps.

Copy link

@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 (4)
src/main/java/com/faforever/client/coop/CoopController.java (2)

33-33: Remove unused imports.

The following imports are not used in this file:

  • Line 33: HostServices
  • Line 54: StringConverter
  • Line 55: jdk.jfr.Category (incorrect import, unrelated to the domain model)
  • Line 65: URISyntaxException
  • Line 69: Arrays

Apply this diff to remove the unused imports:

-import javafx.application.HostServices;
-import javafx.util.StringConverter;
-import jdk.jfr.Category;
-import java.net.URISyntaxException;
-import java.util.Arrays;

Also applies to: 54-55, 65-65, 69-69


258-276: Improve naming consistency for scenario-based architecture.

The method correctly implements faction-based icons for scenarios, including the new wrench icon for custom missions. However, there are naming inconsistencies:

  1. Line 259: The lambda parameter is named category but should be scenario to match the new scenario-based model.
  2. Line 275: The style class "coop-category" should be "coop-scenario" to align with the architectural change.

Apply this diff to improve naming consistency:

-  private ListCell<CoopScenario> scenarioListCell() {
-    return new StringListCell<>(fxApplicationThreadExecutor, CoopScenario::name, category -> {
+  private ListCell<CoopScenario> scenarioListCell() {
+    return new StringListCell<>(fxApplicationThreadExecutor, CoopScenario::name, scenario -> {
       Label label = new Label();
       Region iconRegion = new Region();
       label.setGraphic(iconRegion);
       iconRegion.getStyleClass().add(ThemeService.CSS_CLASS_ICON);
-      switch (category.faction()) {
+      switch (scenario.faction()) {
         case AEON -> iconRegion.getStyleClass().add(ThemeService.AEON_STYLE_CLASS);
         case CYBRAN -> iconRegion.getStyleClass().add(ThemeService.CYBRAN_STYLE_CLASS);
         case UEF -> iconRegion.getStyleClass().add(ThemeService.UEF_STYLE_CLASS);
         case SERAPHIM -> iconRegion.getStyleClass().add(ThemeService.SERAPHIM_STYLE_CLASS);
         case CUSTOM -> iconRegion.getStyleClass().add(ThemeService.WRENCH_STYLE_CLASS);
         default -> {
           return null;
         }
       }
       return label;
-    }, Pos.CENTER_LEFT, "coop-category");
+    }, Pos.CENTER_LEFT, "coop-scenario");
   }
src/main/resources/theme/play/coop/coop.fxml (2)

3-3: Remove unnecessary import.

The java.lang.* package is automatically imported and does not need to be explicitly declared.

Apply this diff:

-<?import java.lang.*?>

64-65: Consider adding prompt text for better UX.

The scenario and mission ComboBoxes lack promptText attributes, which could help users understand their purpose when empty.

Consider adding prompt text to guide users:

-                            <ComboBox fx:id="scenarioComboBox" prefHeight="25.0" prefWidth="200.0" />
-                            <ComboBox fx:id="missionComboBox" prefHeight="25.0" prefWidth="200.0" />
+                            <ComboBox fx:id="scenarioComboBox" prefHeight="25.0" prefWidth="200.0" promptText="%coop.scenario.prompt" />
+                            <ComboBox fx:id="missionComboBox" prefHeight="25.0" prefWidth="200.0" promptText="%coop.mission.prompt" />

Then add the corresponding keys to your i18n properties files (e.g., "Select Scenario" and "Select Mission").

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 540c382 and 40c029e.

📒 Files selected for processing (4)
  • src/main/java/com/faforever/client/coop/CoopController.java (10 hunks)
  • src/main/java/com/faforever/client/domain/api/CoopMission.java (1 hunks)
  • src/main/resources/i18n/messages.properties (2 hunks)
  • src/main/resources/theme/play/coop/coop.fxml (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/main/resources/i18n/messages.properties
  • src/main/java/com/faforever/client/domain/api/CoopMission.java
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (11)
src/main/java/com/faforever/client/coop/CoopController.java (7)

127-129: LGTM!

The scenarioComboBox initialization is correctly configured with appropriate cell factories and selection listener.


131-133: LGTM!

The missionComboBox cell factory configuration is correct and consistent with the new architecture.


205-231: LGTM!

The transition from mission-based to scenario-based data loading is well-implemented. The aggregation of missions from all scenarios provides the necessary data for the games table while maintaining the new scenario-centric UI model.


278-280: LGTM!

The missionListCell factory is correctly implemented using the concatName method reference.


310-318: LGTM!

The mission list population logic correctly clears and repopulates the mission combo box based on the selected scenario, with appropriate null handling and default selection.


333-346: LGTM! Past review issues addressed.

The browser navigation implementation now correctly addresses all the issues raised in the previous review:

  • Proper Desktop support checking using isDesktopSupported() and isSupported(Desktop.Action.BROWSE)
  • User notifications for unsupported platforms and errors
  • Direct URI usage without unnecessary reconstruction
  • No silent failures

353-359: LGTM!

The new action methods for wiki and Discord navigation are correctly implemented and properly delegate to the browser navigation helper.

src/main/resources/theme/play/coop/coop.fxml (4)

11-11: Past issue resolved.

The gridLinesVisible="true" debug attribute has been successfully removed as requested in the previous review.


57-57: Past issue resolved.

The hard-coded English text has been successfully replaced with the i18n key %coop.info.label as requested in the previous review.


67-69: LGTM!

The clickable overlay pattern for the map preview ImageView is implemented correctly, allowing mouse interaction while preserving the image's visual properties.


115-127: LGTM!

The leaderboard TableView is properly configured with explicit columns, i18n keys for all text labels, and appropriate resize policy.

Copy link

@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/main/resources/theme/play/coop/coop.fxml (2)

3-9: Consider using specific imports instead of wildcards.

Wildcard imports (e.g., <?import javafx.scene.layout.*?>) import all classes from a package, which can reduce clarity and potentially cause naming conflicts. Specific imports make it clearer which components are actually used in the FXML.


36-38: Consider using "Infinity" for unbounded maximum width.

The value 1.7976931348623157E308 represents Double.MAX_VALUE and is used to specify unbounded maximum width. For better readability and maintainability, consider using the more idiomatic Infinity value or the constant MAX_VALUE.

Apply this diff for improved readability:

-                                        <TextField fx:id="titleTextField" maxWidth="1.7976931348623157E308" minWidth="100.0" prefWidth="400.0" promptText="%game.create.title" />
-                                        <PasswordField fx:id="passwordTextField" maxWidth="1.7976931348623157E308" minWidth="100.0" prefWidth="350.0" promptText="%game.create.password" />
+                                        <TextField fx:id="titleTextField" maxWidth="Infinity" minWidth="100.0" prefWidth="400.0" promptText="%game.create.title" />
+                                        <PasswordField fx:id="passwordTextField" maxWidth="Infinity" minWidth="100.0" prefWidth="350.0" promptText="%game.create.password" />

Note: Similar occurrences exist elsewhere in the file (e.g., lines 78, 88, 90, 116).

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 40c029e and 917033d.

📒 Files selected for processing (2)
  • src/main/resources/i18n/messages.properties (2 hunks)
  • src/main/resources/theme/play/coop/coop.fxml (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/resources/i18n/messages.properties
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (4)
src/main/resources/theme/play/coop/coop.fxml (4)

11-18: LGTM: Root layout structure.

The GridPane root element and responsive column constraints (55%/45% split) provide a good foundation for the two-panel layout. The debug attribute gridLinesVisible has been correctly removed from previous versions.


47-52: LGTM: Discord button accessibility addressed.

The Discord button now includes a tooltip with the i18n key %coop.discord.button, which addresses the accessibility concern raised in previous reviews. This ensures screen reader users can understand the button's purpose.


64-71: LGTM: Scenario selection structure.

The scenario and mission combo boxes, along with the map preview StackPane, are well-structured and align with the PR objectives to add scenario-based selection. The use of a Pane overlay on the ImageView for click handling is a standard JavaFX pattern.


116-129: LGTM: TableView configuration.

The explicit TableColumn definitions with individual width constraints and i18n keys are well-configured. The use of CONSTRAINED_RESIZE_POLICY ensures proper column sizing behavior for the leaderboard table.

Comment on lines +334 to +345
if (!Desktop.isDesktopSupported() || !Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
log.warn("Desktop browsing is not supported on this platform.");
notificationService.addImmediateWarnNotification("coop.browser.notSupported");
return;
}

try {
Desktop.getDesktop().browse(uri);
} catch (IOException e) {
log.error("Could not open browser.", e);
notificationService.addImmediateErrorNotification(e, "coop.browser.error");
}
Copy link
Member

Choose a reason for hiding this comment

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

Use the platformService.showDocument for opening a browser

@Cacheable(value = CacheNames.COOP_SCENARIOS, sync = true)
public Flux<CoopScenario> getScenarios() {
ElideNavigatorOnCollection<com.faforever.commons.api.dto.CoopScenario> navigator = ElideNavigator.of(
com.faforever.commons.api.dto.CoopScenario.class).collection().addInclude("maps").pageSize(1000);
Copy link
Member

Choose a reason for hiding this comment

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

The max page size in the api is now 100 so 1000 won't do anything.

Also instead of specifying the include here it should be specified in the type map in the fafApiAccessor. GetMany also handles the page size


public record CoopCategory(
String categoryName,
CoopFaction coopCategory
Copy link
Member

Choose a reason for hiding this comment

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

The variable naming here is a bit confusing. What exactly is the category?

Comment on lines +16 to +18
public String concatName() {
return name + " - V" + version;
}
Copy link
Member

Choose a reason for hiding this comment

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

Can this method be moved to the controller?

Comment on lines +16 to +18
public CoopScenario {
maps = maps == null ? List.of() : List.copyOf(maps);
}
Copy link
Member

Choose a reason for hiding this comment

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

We should make sure to not pass in null for the maps

@InheritInverseConfiguration
com.faforever.commons.api.dto.CoopMission map(CoopMission bean);

@Mapping(target = ".", source = "dto")
Copy link
Member

Choose a reason for hiding this comment

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

I don't think this annotation is necessary since there is only one parameter

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