diff --git a/src/main/java/com/faforever/client/config/PreferencesConfig.java b/src/main/java/com/faforever/client/config/PreferencesConfig.java index 9545ae862a..08920649e5 100644 --- a/src/main/java/com/faforever/client/config/PreferencesConfig.java +++ b/src/main/java/com/faforever/client/config/PreferencesConfig.java @@ -10,6 +10,7 @@ import com.faforever.client.preferences.GeneralPrefs; import com.faforever.client.preferences.GeneratorPrefs; import com.faforever.client.preferences.LastGamePrefs; +import com.faforever.client.preferences.LiveReplaySearchPrefs; import com.faforever.client.preferences.LocalizationPrefs; import com.faforever.client.preferences.LoginPrefs; import com.faforever.client.preferences.MatchmakerPrefs; @@ -154,6 +155,11 @@ public VaultPrefs vault() { return preferences().getVault(); } + @Bean + public LiveReplaySearchPrefs liveReplaySearchPrefs() { + return preferences().getVault().getLiveReplaySearch(); + } + @Bean public UserPrefs user() { return preferences().getUser(); diff --git a/src/main/java/com/faforever/client/filter/LiveGamesFilterController.java b/src/main/java/com/faforever/client/filter/LiveGamesFilterController.java index a07872d0fb..dd3c65567f 100644 --- a/src/main/java/com/faforever/client/filter/LiveGamesFilterController.java +++ b/src/main/java/com/faforever/client/filter/LiveGamesFilterController.java @@ -11,6 +11,7 @@ import com.faforever.client.i18n.I18n; import com.faforever.client.map.generator.MapGeneratorService; import com.faforever.client.player.PlayerService; +import com.faforever.client.preferences.LiveReplaySearchPrefs; import com.faforever.client.social.SocialService; import com.faforever.client.theme.UiService; import com.faforever.commons.lobby.GameType; @@ -33,39 +34,58 @@ public class LiveGamesFilterController extends AbstractFilterController hideModdedGamesFilter; + private FilterCheckboxController hideSingleGamesFilter; + private FilterCheckboxController onlyGamesWithFriendsFilter; + private FilterCheckboxController onlyGeneratedMapsFilter; + + private FilterMultiCheckboxController gameTypeFilter; + private FilterMultiCheckboxController featuredModFilter; + + private FilterTextFieldController playerFilter; + + public LiveGamesFilterController(UiService uiService, I18n i18n, FeaturedModService featuredModService, PlayerService playerService, MapGeneratorService mapGeneratorService, FxApplicationThreadExecutor fxApplicationThreadExecutor, - SocialService socialService) { + SocialService socialService, + LiveReplaySearchPrefs liveReplaySearchPrefs) { super(uiService, i18n, fxApplicationThreadExecutor); this.featuredModService = featuredModService; this.playerService = playerService; this.mapGeneratorService = mapGeneratorService; this.socialService = socialService; + this.liveReplaySearchPrefs = liveReplaySearchPrefs; } @Override protected void build(FilterBuilder filterBuilder) { - filterBuilder.checkbox(i18n.get("moddedGames"), new SimModsFilterFunction()); + hideModdedGamesFilter = filterBuilder.checkbox(i18n.get("moddedGames"), new SimModsFilterFunction()); - filterBuilder.checkbox(i18n.get("hideSingleGames"), (selected, game) -> !selected || game.getNumActivePlayers() != 1); + hideSingleGamesFilter = filterBuilder.checkbox(i18n.get("hideSingleGames"), + (selected, game) -> !selected || game.getNumActivePlayers() != 1); - filterBuilder.checkbox(i18n.get("showGamesWithFriends"), - (selected, game) -> !selected || socialService.areFriendsInGame(game)); + onlyGamesWithFriendsFilter = filterBuilder.checkbox(i18n.get("showGamesWithFriends"), + (selected, game) -> !selected || socialService.areFriendsInGame( + game)); - filterBuilder.checkbox(i18n.get("showGeneratedMaps"), (selected, game) -> !selected || mapGeneratorService.isGeneratedMap(game.getMapFolderName())); + onlyGeneratedMapsFilter = filterBuilder.checkbox(i18n.get("showGeneratedMaps"), + (selected, game) -> !selected || mapGeneratorService.isGeneratedMap( + game.getMapFolderName())); - filterBuilder.multiCheckbox(i18n.get("gameType"), List.of(GameType.CUSTOM, GameType.MATCHMAKER, GameType.COOP), gameTypeConverter, + gameTypeFilter = filterBuilder.multiCheckbox(i18n.get("gameType"), List.of(GameType.CUSTOM, GameType.MATCHMAKER, GameType.COOP), gameTypeConverter, (selectedGameTypes, game) -> selectedGameTypes.isEmpty() || selectedGameTypes.contains(game.getGameType())); - FilterMultiCheckboxController featuredModFilter = filterBuilder.multiCheckbox( + featuredModFilter = filterBuilder.multiCheckbox( i18n.get("featuredMod.displayName"), new ToStringOnlyConverter<>(FeaturedMod::displayName), new FeaturedModFilterFunction()); featuredModService.getFeaturedMods().collectList().subscribe(featuredModFilter::setItems); - filterBuilder.textField(i18n.get("game.player.username"), (text, game) -> text.isEmpty() || game.getTeams() + playerFilter = filterBuilder.textField(i18n.get("game.player.username"), (text, game) -> text.isEmpty() || game.getTeams() .values() .stream() .flatMap(Collection::stream) @@ -90,4 +110,16 @@ public GameType fromString(String string) { throw new UnsupportedOperationException("Not supported"); } }; + + @Override + protected void afterBuilt() { + hideModdedGamesFilter.valueProperty().bindBidirectional(liveReplaySearchPrefs.hideModdedGamesProperty()); + hideSingleGamesFilter.valueProperty().bindBidirectional(liveReplaySearchPrefs.hideSingleGamesProperty()); + onlyGamesWithFriendsFilter.valueProperty().bindBidirectional(liveReplaySearchPrefs.onlyGamesWithFriendsProperty()); + onlyGeneratedMapsFilter.valueProperty().bindBidirectional(liveReplaySearchPrefs.onlyGeneratedMapsProperty()); + gameTypeFilter.valueProperty().bindBidirectional(liveReplaySearchPrefs.gameTypesProperty()); + featuredModFilter.valueProperty().bindBidirectional(liveReplaySearchPrefs.modNameProperty()); + playerFilter.valueProperty().bindBidirectional(liveReplaySearchPrefs.playerNameProperty()); + } + } diff --git a/src/main/java/com/faforever/client/preferences/LiveReplaySearchPrefs.java b/src/main/java/com/faforever/client/preferences/LiveReplaySearchPrefs.java new file mode 100644 index 0000000000..705c247b76 --- /dev/null +++ b/src/main/java/com/faforever/client/preferences/LiveReplaySearchPrefs.java @@ -0,0 +1,74 @@ +package com.faforever.client.preferences; + +import com.faforever.client.domain.api.FeaturedMod; +import com.faforever.commons.lobby.GameType; +import javafx.beans.property.BooleanProperty; +import javafx.beans.property.ListProperty; +import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.property.SimpleListProperty; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; + + +public class LiveReplaySearchPrefs { + + private final BooleanProperty hideModdedGames = new SimpleBooleanProperty(false); + private final BooleanProperty hideSingleGames = new SimpleBooleanProperty(false); + private final BooleanProperty onlyGamesWithFriends = new SimpleBooleanProperty(false); + private final BooleanProperty onlyGeneratedMaps = new SimpleBooleanProperty(false); + + private final ListProperty gameTypes = new SimpleListProperty<>(FXCollections.observableArrayList()); + private final ListProperty modName = new SimpleListProperty<>(FXCollections.observableArrayList()); + + private final StringProperty playerName = new SimpleStringProperty(""); + + public boolean getHideModdedGames() {return hideModdedGames.get();} + + public void setHideModdedGames(Boolean hideModdedGames) {this.hideModdedGames.set(hideModdedGames);} + + public BooleanProperty hideModdedGamesProperty() {return hideModdedGames;} + + + public boolean getHideSingleGames() {return hideSingleGames.get();} + + public void setHideSingleGames(Boolean hideSingleGames) {this.hideSingleGames.set(hideSingleGames);} + + public BooleanProperty hideSingleGamesProperty() {return hideSingleGames;} + + + public boolean getOnlyGamesWithFriends() {return onlyGamesWithFriends.get();} + + public void setOnlyGamesWithFriends(Boolean onlyGamesWithFriends) {this.onlyGamesWithFriends.set(onlyGamesWithFriends);} + + public BooleanProperty onlyGamesWithFriendsProperty() {return onlyGamesWithFriends;} + + + public boolean getOnlyGeneratedMaps() {return onlyGeneratedMaps.get();} + + public void setOnlyGeneratedMaps(Boolean onlyGeneratedMaps) {this.onlyGeneratedMaps.set(onlyGeneratedMaps);} + + public BooleanProperty onlyGeneratedMapsProperty() {return onlyGeneratedMaps;} + + + public ObservableList getGameTypes() {return gameTypes.get();} + + public void setGameTypes(ObservableList gameTypes) {this.gameTypes.set(gameTypes);} + + public ListProperty gameTypesProperty() {return gameTypes;} + + + public ObservableList getModName() {return modName.get();} + + public void setModName(ObservableList modName) {this.modName.set(modName);} + + public ListProperty modNameProperty() {return modName;} + + + public String getPlayerName() {return playerName.get();} + + public void setPlayerName(String playerName) {this.playerName.set(playerName);} + + public StringProperty playerNameProperty() {return playerName;} +} diff --git a/src/main/java/com/faforever/client/preferences/VaultPrefs.java b/src/main/java/com/faforever/client/preferences/VaultPrefs.java index c9a3f8461c..e5a8f472a1 100644 --- a/src/main/java/com/faforever/client/preferences/VaultPrefs.java +++ b/src/main/java/com/faforever/client/preferences/VaultPrefs.java @@ -29,6 +29,9 @@ public class VaultPrefs { private final ReplaySearchPrefs replaySearch = new ReplaySearchPrefs(); @JsonMerge @Getter + private final LiveReplaySearchPrefs liveReplaySearch = new LiveReplaySearchPrefs(); + @JsonMerge + @Getter private final MapSearchPrefs mapSearch = new MapSearchPrefs(); @JsonMerge @Getter diff --git a/src/test/java/com/faforever/client/filter/LiveGamesFilterControllerTest.java b/src/test/java/com/faforever/client/filter/LiveGamesFilterControllerTest.java index 21ef30be33..a4e903c355 100644 --- a/src/test/java/com/faforever/client/filter/LiveGamesFilterControllerTest.java +++ b/src/test/java/com/faforever/client/filter/LiveGamesFilterControllerTest.java @@ -1,21 +1,27 @@ package com.faforever.client.filter; import com.faforever.client.builders.PlayerInfoBuilder; +import com.faforever.client.domain.api.FeaturedMod; import com.faforever.client.domain.server.GameInfo; import com.faforever.client.domain.server.PlayerInfo; import com.faforever.client.featuredmod.FeaturedModService; import com.faforever.client.i18n.I18n; import com.faforever.client.map.generator.MapGeneratorService; import com.faforever.client.player.PlayerService; +import com.faforever.client.preferences.LiveReplaySearchPrefs; import com.faforever.client.social.SocialService; import com.faforever.client.test.PlatformTest; import com.faforever.client.theme.UiService; import com.faforever.commons.lobby.GameType; +import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.property.SimpleListProperty; +import javafx.beans.property.SimpleStringProperty; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import org.mockito.Mock; +import org.mockito.Spy; import reactor.core.publisher.Flux; import java.util.Collections; @@ -28,7 +34,6 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -48,34 +53,53 @@ public class LiveGamesFilterControllerTest extends PlatformTest { @Mock private MapGeneratorService mapGeneratorService; + @Spy + private LiveReplaySearchPrefs liveReplaySearchPrefs; + + @Mock + private FilterCheckboxController hideModdedGamesFilter; @Mock - private FilterCheckboxController singleGamesController; + private FilterCheckboxController hideSingleGamesFilter; @Mock - private FilterCheckboxController gamesWithFriendsController; + private FilterCheckboxController onlyGamesWithFriendsFilter; @Mock - private FilterMultiCheckboxController gameTypeController; + private FilterCheckboxController onlyGeneratedMapsFilter; + @Mock - private FilterTextFieldController playerNameController; + private FilterMultiCheckboxController gameTypeFilter; + @Mock + private FilterMultiCheckboxController featuredModFilter; + @Mock - private FilterCheckboxController generatedMapsController; + private FilterTextFieldController playerNameFilter; + @InjectMocks private LiveGamesFilterController instance; @BeforeEach public void setUp() throws Exception { - // Order is important when(uiService.loadFxml(anyString())).thenReturn( - mock(FilterCheckboxController.class), // Sim mods - singleGamesController, - gamesWithFriendsController, - generatedMapsController, - gameTypeController, - mock(FilterMultiCheckboxController.class), // Featured mods - playerNameController + hideModdedGamesFilter, // Sim mods + hideSingleGamesFilter, + onlyGamesWithFriendsFilter, + onlyGeneratedMapsFilter, + gameTypeFilter, + featuredModFilter, + playerNameFilter ); when(featuredModService.getFeaturedMods()).thenReturn(Flux.empty()); + when(hideModdedGamesFilter.valueProperty()).thenReturn(new SimpleBooleanProperty()); + when(hideSingleGamesFilter.valueProperty()).thenReturn(new SimpleBooleanProperty()); + when(onlyGamesWithFriendsFilter.valueProperty()).thenReturn(new SimpleBooleanProperty()); + when(onlyGeneratedMapsFilter.valueProperty()).thenReturn(new SimpleBooleanProperty()); + + when(gameTypeFilter.valueProperty()).thenReturn(new SimpleListProperty<>()); + when(featuredModFilter.valueProperty()).thenReturn(new SimpleListProperty<>()); + + when(playerNameFilter.valueProperty()).thenReturn(new SimpleStringProperty()); + loadFxml("theme/filter/filter.fxml", clazz -> instance, instance); } @@ -83,7 +107,7 @@ public void setUp() throws Exception { public void testGameTypeFilter() { ArgumentCaptor, GameInfo, Boolean>> argumentCaptor = ArgumentCaptor.forClass( BiFunction.class); - verify(gameTypeController).registerListener(argumentCaptor.capture()); + verify(gameTypeFilter).registerListener(argumentCaptor.capture()); BiFunction, GameInfo, Boolean> filter = argumentCaptor.getValue(); @@ -99,7 +123,7 @@ public void testGameTypeFilter() { @Test public void testPlayerNameFilter() { ArgumentCaptor> argumentCaptor = ArgumentCaptor.forClass(BiFunction.class); - verify(playerNameController).registerListener(argumentCaptor.capture()); + verify(playerNameFilter).registerListener(argumentCaptor.capture()); PlayerInfo player1 = PlayerInfoBuilder.create().defaultValues().id(1).username("player1").get(); PlayerInfo player2 = PlayerInfoBuilder.create().defaultValues().id(2).username("player2").get(); @@ -122,7 +146,7 @@ public void testPlayerNameFilter() { @Test public void testSingleGamesFilter() { ArgumentCaptor> argumentCaptor = ArgumentCaptor.forClass(BiFunction.class); - verify(singleGamesController).registerListener(argumentCaptor.capture()); + verify(hideSingleGamesFilter).registerListener(argumentCaptor.capture()); BiFunction filter = argumentCaptor.getValue(); @@ -135,7 +159,7 @@ public void testSingleGamesFilter() { @Test public void testGameWithFriendsFilter() { ArgumentCaptor> argumentCaptor = ArgumentCaptor.forClass(BiFunction.class); - verify(gamesWithFriendsController).registerListener(argumentCaptor.capture()); + verify(onlyGamesWithFriendsFilter).registerListener(argumentCaptor.capture()); GameInfo game = create().defaultValues().get(); @@ -151,7 +175,7 @@ public void testGameWithFriendsFilter() { @Test public void testGeneratedMapsFilter() { ArgumentCaptor> argumentCaptor = ArgumentCaptor.forClass(BiFunction.class); - verify(generatedMapsController).registerListener(argumentCaptor.capture()); + verify(onlyGeneratedMapsFilter).registerListener(argumentCaptor.capture()); GameInfo game = create().defaultValues().get(); @@ -163,4 +187,4 @@ public void testGeneratedMapsFilter() { assertFalse(filter.apply(true, game)); assertTrue(filter.apply(true, game)); } -} \ No newline at end of file +}