From 3fa6b06ad10a6539500cc1121a8c42e9443044d7 Mon Sep 17 00:00:00 2001 From: Karim <35817819+Kimo-s@users.noreply.github.com> Date: Mon, 20 Nov 2023 23:09:01 -0500 Subject: [PATCH 1/6] Add search bar for coop leaderboard #2880 --- .../faforever/client/coop/CoopController.java | 25 ++++++++++++++++++- src/main/resources/theme/play/coop/coop.fxml | 5 ++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/faforever/client/coop/CoopController.java b/src/main/java/com/faforever/client/coop/CoopController.java index 0b7417a25f..926d7fe7aa 100644 --- a/src/main/java/com/faforever/client/coop/CoopController.java +++ b/src/main/java/com/faforever/client/coop/CoopController.java @@ -58,9 +58,11 @@ import java.util.Collection; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -96,10 +98,12 @@ public class CoopController extends AbstractViewController { public Pane gameViewContainer; public TextField titleTextField; public Button playButton; + public TextField leaderboardSearchTextField; public PasswordField passwordTextField; public ImageView mapPreviewImageView; public Region leaderboardInfoIcon; public TableView leaderboardTable; + public FilteredList leaderboardFilteredTable; public ComboBox numberOfPlayersComboBox; public TableColumn rankColumn; public TableColumn playerCountColumn; @@ -125,6 +129,8 @@ public void initialize() { numberOfPlayersComboBox.getSelectionModel().select(0); numberOfPlayersComboBox.getSelectionModel().selectedItemProperty().addListener(observable -> loadLeaderboard()); + leaderboardSearchTextField.textProperty().addListener((observable, oldValue, newValue) -> onSearchFieldChange(newValue)); + rankColumn.setCellValueFactory(param -> param.getValue().rankingProperty().asObject()); rankColumn.setCellFactory(param -> new StringCell<>(String::valueOf)); @@ -194,6 +200,20 @@ public void initialize() { }); } + private void onSearchFieldChange(String newvalue){ + leaderboardFilteredTable.setPredicate(coopResultBean -> { + String teamstring = ""; + for(Map.Entry> entry : coopResultBean.getReplay().getTeams().entrySet()){ + teamstring = entry.getValue().stream().collect(Collectors.joining(i18n.get("textSeparator"))); + } + if(newvalue.isEmpty() || teamstring.equalsIgnoreCase("")){ + return true; + } + return teamstring.toLowerCase().contains(newvalue.toLowerCase()); + }); + leaderboardTable.setItems(observableList(leaderboardFilteredTable)); + } + private String coopMissionFromFolderNamer(List coopMaps, String mapFolderName) { return coopMaps.stream() .filter(coopMission -> coopMission.getMapFolderName().equalsIgnoreCase(mapFolderName)) @@ -243,7 +263,10 @@ private void loadLeaderboard() { .thenAccept(coopLeaderboardEntries -> { AtomicInteger ranking = new AtomicInteger(); coopLeaderboardEntries.forEach(coopResult -> coopResult.setRanking(ranking.incrementAndGet())); - fxApplicationThreadExecutor.execute(() -> leaderboardTable.setItems(observableList(coopLeaderboardEntries))); + fxApplicationThreadExecutor.execute(() -> { + leaderboardTable.setItems(observableList(coopLeaderboardEntries)); + leaderboardFilteredTable = new FilteredList<>(observableList(coopLeaderboardEntries)); + }); }) .exceptionally(throwable -> { log.warn("Could not load coop leaderboard", throwable); diff --git a/src/main/resources/theme/play/coop/coop.fxml b/src/main/resources/theme/play/coop/coop.fxml index fd24429c69..96363278a2 100644 --- a/src/main/resources/theme/play/coop/coop.fxml +++ b/src/main/resources/theme/play/coop/coop.fxml @@ -91,6 +91,11 @@ + + + + + From 7be868f22cef6ea25e89436b6b6f58615c1512d6 Mon Sep 17 00:00:00 2001 From: Karim <35817819+Kimo-s@users.noreply.github.com> Date: Sun, 26 Nov 2023 18:41:02 -0500 Subject: [PATCH 2/6] fixed wrong search on teams --- .../faforever/client/coop/CoopController.java | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/faforever/client/coop/CoopController.java b/src/main/java/com/faforever/client/coop/CoopController.java index 926d7fe7aa..dcfa2b2617 100644 --- a/src/main/java/com/faforever/client/coop/CoopController.java +++ b/src/main/java/com/faforever/client/coop/CoopController.java @@ -29,6 +29,9 @@ import com.faforever.commons.lobby.GameStatus; import com.faforever.commons.lobby.GameType; import com.google.common.base.Strings; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.collections.ObservableSet; import javafx.collections.transformation.FilteredList; import javafx.geometry.Pos; import javafx.scene.Node; @@ -55,6 +58,7 @@ import java.time.Duration; import java.time.OffsetDateTime; +import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; @@ -62,7 +66,6 @@ import java.util.Optional; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -91,6 +94,7 @@ public class CoopController extends AbstractViewController { private final WebViewConfigurer webViewConfigurer; private final ModService modService; private final FxApplicationThreadExecutor fxApplicationThreadExecutor; + private FilteredList leaderboardFilteredList = new FilteredList<>(FXCollections.observableArrayList()); public GridPane coopRoot; public ComboBox missionComboBox; @@ -103,7 +107,6 @@ public class CoopController extends AbstractViewController { public ImageView mapPreviewImageView; public Region leaderboardInfoIcon; public TableView leaderboardTable; - public FilteredList leaderboardFilteredTable; public ComboBox numberOfPlayersComboBox; public TableColumn rankColumn; public TableColumn playerCountColumn; @@ -129,7 +132,8 @@ public void initialize() { numberOfPlayersComboBox.getSelectionModel().select(0); numberOfPlayersComboBox.getSelectionModel().selectedItemProperty().addListener(observable -> loadLeaderboard()); - leaderboardSearchTextField.textProperty().addListener((observable, oldValue, newValue) -> onSearchFieldChange(newValue)); + leaderboardSearchTextField.textProperty().subscribe(this::onSearchFieldChange); + leaderboardTable.setItems(observableList(leaderboardFilteredList)); rankColumn.setCellValueFactory(param -> param.getValue().rankingProperty().asObject()); rankColumn.setCellFactory(param -> new StringCell<>(String::valueOf)); @@ -200,18 +204,20 @@ public void initialize() { }); } - private void onSearchFieldChange(String newvalue){ - leaderboardFilteredTable.setPredicate(coopResultBean -> { - String teamstring = ""; + private void onSearchFieldChange(String newValue){ + leaderboardFilteredList.setPredicate(coopResultBean -> { + boolean foundmatch = false; for(Map.Entry> entry : coopResultBean.getReplay().getTeams().entrySet()){ - teamstring = entry.getValue().stream().collect(Collectors.joining(i18n.get("textSeparator"))); + foundmatch = entry.getValue().stream().anyMatch((s) -> s.toLowerCase().contains(newValue.toLowerCase())); + if(foundmatch) + break; } - if(newvalue.isEmpty() || teamstring.equalsIgnoreCase("")){ + if(newValue.isEmpty()){ return true; } - return teamstring.toLowerCase().contains(newvalue.toLowerCase()); + return foundmatch; }); - leaderboardTable.setItems(observableList(leaderboardFilteredTable)); + leaderboardTable.setItems(observableList(leaderboardFilteredList)); } private String coopMissionFromFolderNamer(List coopMaps, String mapFolderName) { @@ -264,8 +270,8 @@ private void loadLeaderboard() { AtomicInteger ranking = new AtomicInteger(); coopLeaderboardEntries.forEach(coopResult -> coopResult.setRanking(ranking.incrementAndGet())); fxApplicationThreadExecutor.execute(() -> { - leaderboardTable.setItems(observableList(coopLeaderboardEntries)); - leaderboardFilteredTable = new FilteredList<>(observableList(coopLeaderboardEntries)); + leaderboardFilteredList = new FilteredList<>(observableList(coopLeaderboardEntries)); + leaderboardTable.setItems(observableList(leaderboardFilteredList)); }); }) .exceptionally(throwable -> { From 9bdae87be72be26d7fbda01b98093beff7e4f294 Mon Sep 17 00:00:00 2001 From: Karim <35817819+Kimo-s@users.noreply.github.com> Date: Mon, 27 Nov 2023 15:28:44 -0500 Subject: [PATCH 3/6] Changes to verbose search call back. (This does not run) --- .../faforever/client/coop/CoopController.java | 36 ++++++++++++------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/faforever/client/coop/CoopController.java b/src/main/java/com/faforever/client/coop/CoopController.java index dcfa2b2617..0c6cef04bb 100644 --- a/src/main/java/com/faforever/client/coop/CoopController.java +++ b/src/main/java/com/faforever/client/coop/CoopController.java @@ -21,6 +21,7 @@ import com.faforever.client.map.MapService.PreviewSize; import com.faforever.client.mod.ModService; import com.faforever.client.notification.NotificationService; +import com.faforever.client.player.SocialStatus; import com.faforever.client.replay.ReplayService; import com.faforever.client.theme.UiService; import com.faforever.client.util.ConcurrentUtil; @@ -133,6 +134,8 @@ public void initialize() { numberOfPlayersComboBox.getSelectionModel().selectedItemProperty().addListener(observable -> loadLeaderboard()); leaderboardSearchTextField.textProperty().subscribe(this::onSearchFieldChange); + leaderboardFilteredList.predicateProperty().bind(leaderboardSearchTextField.textProperty().map(this::onSearchCreatePredict)); + leaderboardTable.setItems(observableList(leaderboardFilteredList)); rankColumn.setCellValueFactory(param -> param.getValue().rankingProperty().asObject()); @@ -204,19 +207,25 @@ public void initialize() { }); } - private void onSearchFieldChange(String newValue){ - leaderboardFilteredList.setPredicate(coopResultBean -> { - boolean foundmatch = false; - for(Map.Entry> entry : coopResultBean.getReplay().getTeams().entrySet()){ - foundmatch = entry.getValue().stream().anyMatch((s) -> s.toLowerCase().contains(newValue.toLowerCase())); - if(foundmatch) - break; - } - if(newValue.isEmpty()){ - return true; + private Predicate onSearchCreatePredict(String newValue){ + leaderboardTable.setItems(observableList(leaderboardFilteredList)); + return new Predicate<>() { + @Override + public boolean test(CoopResultBean coopResultBean) { + if (newValue.isEmpty()) { + return true; + } + return coopResultBean.getReplay() + .getTeams() + .values() + .stream() + .flatMap(Collection::stream) + .anyMatch(name -> name.toLowerCase().contains(newValue.toLowerCase())); } - return foundmatch; - }); + }; + } + + private void onSearchFieldChange(String newValue){ leaderboardTable.setItems(observableList(leaderboardFilteredList)); } @@ -270,7 +279,8 @@ private void loadLeaderboard() { AtomicInteger ranking = new AtomicInteger(); coopLeaderboardEntries.forEach(coopResult -> coopResult.setRanking(ranking.incrementAndGet())); fxApplicationThreadExecutor.execute(() -> { - leaderboardFilteredList = new FilteredList<>(observableList(coopLeaderboardEntries)); +// leaderboardFilteredList = new FilteredList<>(observableList(coopLeaderboardEntries)); + leaderboardFilteredList.setAll(observableList(coopLeaderboardEntries)); //Gives null error leaderboardTable.setItems(observableList(leaderboardFilteredList)); }); }) From bad10dab0b6d263a43bf497c180b3f6a3e74b88b Mon Sep 17 00:00:00 2001 From: Karim <35817819+Kimo-s@users.noreply.github.com> Date: Mon, 27 Nov 2023 15:49:55 -0500 Subject: [PATCH 4/6] Fixed null error from filtered list --- .../faforever/client/coop/CoopController.java | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/faforever/client/coop/CoopController.java b/src/main/java/com/faforever/client/coop/CoopController.java index 0c6cef04bb..4df4e1a198 100644 --- a/src/main/java/com/faforever/client/coop/CoopController.java +++ b/src/main/java/com/faforever/client/coop/CoopController.java @@ -21,7 +21,6 @@ import com.faforever.client.map.MapService.PreviewSize; import com.faforever.client.mod.ModService; import com.faforever.client.notification.NotificationService; -import com.faforever.client.player.SocialStatus; import com.faforever.client.replay.ReplayService; import com.faforever.client.theme.UiService; import com.faforever.client.util.ConcurrentUtil; @@ -32,7 +31,6 @@ import com.google.common.base.Strings; import javafx.collections.FXCollections; import javafx.collections.ObservableList; -import javafx.collections.ObservableSet; import javafx.collections.transformation.FilteredList; import javafx.geometry.Pos; import javafx.scene.Node; @@ -59,11 +57,9 @@ import java.time.Duration; import java.time.OffsetDateTime; -import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; @@ -95,7 +91,8 @@ public class CoopController extends AbstractViewController { private final WebViewConfigurer webViewConfigurer; private final ModService modService; private final FxApplicationThreadExecutor fxApplicationThreadExecutor; - private FilteredList leaderboardFilteredList = new FilteredList<>(FXCollections.observableArrayList()); + private final ObservableList leaderboardUnFilteredList = FXCollections.observableArrayList(); + private final FilteredList leaderboardFilteredList = new FilteredList<>(leaderboardUnFilteredList); public GridPane coopRoot; public ComboBox missionComboBox; @@ -133,11 +130,8 @@ public void initialize() { numberOfPlayersComboBox.getSelectionModel().select(0); numberOfPlayersComboBox.getSelectionModel().selectedItemProperty().addListener(observable -> loadLeaderboard()); - leaderboardSearchTextField.textProperty().subscribe(this::onSearchFieldChange); leaderboardFilteredList.predicateProperty().bind(leaderboardSearchTextField.textProperty().map(this::onSearchCreatePredict)); - leaderboardTable.setItems(observableList(leaderboardFilteredList)); - rankColumn.setCellValueFactory(param -> param.getValue().rankingProperty().asObject()); rankColumn.setCellFactory(param -> new StringCell<>(String::valueOf)); @@ -225,10 +219,6 @@ public boolean test(CoopResultBean coopResultBean) { }; } - private void onSearchFieldChange(String newValue){ - leaderboardTable.setItems(observableList(leaderboardFilteredList)); - } - private String coopMissionFromFolderNamer(List coopMaps, String mapFolderName) { return coopMaps.stream() .filter(coopMission -> coopMission.getMapFolderName().equalsIgnoreCase(mapFolderName)) @@ -279,8 +269,7 @@ private void loadLeaderboard() { AtomicInteger ranking = new AtomicInteger(); coopLeaderboardEntries.forEach(coopResult -> coopResult.setRanking(ranking.incrementAndGet())); fxApplicationThreadExecutor.execute(() -> { -// leaderboardFilteredList = new FilteredList<>(observableList(coopLeaderboardEntries)); - leaderboardFilteredList.setAll(observableList(coopLeaderboardEntries)); //Gives null error + leaderboardUnFilteredList.setAll(coopLeaderboardEntries); leaderboardTable.setItems(observableList(leaderboardFilteredList)); }); }) From 059779e2cfa840545483569be4f01e52b3fd5e62 Mon Sep 17 00:00:00 2001 From: Karim <35817819+Kimo-s@users.noreply.github.com> Date: Mon, 27 Nov 2023 21:01:02 -0500 Subject: [PATCH 5/6] refactored onSearchCreatePredict into initialize --- .../faforever/client/coop/CoopController.java | 34 ++++++++----------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/faforever/client/coop/CoopController.java b/src/main/java/com/faforever/client/coop/CoopController.java index 4df4e1a198..26ea450be4 100644 --- a/src/main/java/com/faforever/client/coop/CoopController.java +++ b/src/main/java/com/faforever/client/coop/CoopController.java @@ -28,6 +28,7 @@ import com.faforever.client.util.TimeService; import com.faforever.commons.lobby.GameStatus; import com.faforever.commons.lobby.GameType; +import com.github.benmanes.caffeine.cache.CacheLoader; import com.google.common.base.Strings; import javafx.collections.FXCollections; import javafx.collections.ObservableList; @@ -130,7 +131,20 @@ public void initialize() { numberOfPlayersComboBox.getSelectionModel().select(0); numberOfPlayersComboBox.getSelectionModel().selectedItemProperty().addListener(observable -> loadLeaderboard()); - leaderboardFilteredList.predicateProperty().bind(leaderboardSearchTextField.textProperty().map(this::onSearchCreatePredict)); + leaderboardSearchTextField.textProperty().subscribe(s -> { + leaderboardTable.setItems(leaderboardFilteredList); + }); + leaderboardFilteredList.predicateProperty().bind(leaderboardSearchTextField.textProperty().map(newValue -> coopResultBean -> { + if (newValue.isEmpty()) { + return true; + } + return coopResultBean.getReplay() + .getTeams() + .values() + .stream() + .flatMap(Collection::stream) + .anyMatch(name -> name.toLowerCase().contains(newValue.toLowerCase())); + })); rankColumn.setCellValueFactory(param -> param.getValue().rankingProperty().asObject()); rankColumn.setCellFactory(param -> new StringCell<>(String::valueOf)); @@ -201,24 +215,6 @@ public void initialize() { }); } - private Predicate onSearchCreatePredict(String newValue){ - leaderboardTable.setItems(observableList(leaderboardFilteredList)); - return new Predicate<>() { - @Override - public boolean test(CoopResultBean coopResultBean) { - if (newValue.isEmpty()) { - return true; - } - return coopResultBean.getReplay() - .getTeams() - .values() - .stream() - .flatMap(Collection::stream) - .anyMatch(name -> name.toLowerCase().contains(newValue.toLowerCase())); - } - }; - } - private String coopMissionFromFolderNamer(List coopMaps, String mapFolderName) { return coopMaps.stream() .filter(coopMission -> coopMission.getMapFolderName().equalsIgnoreCase(mapFolderName)) From 3fbd3f3d9f5917b55d04cb625c83fc95dbc756f8 Mon Sep 17 00:00:00 2001 From: Karim <35817819+Kimo-s@users.noreply.github.com> Date: Mon, 27 Nov 2023 21:32:25 -0500 Subject: [PATCH 6/6] Removed setItesm from loadboardtable() --- .../java/com/faforever/client/coop/CoopController.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/faforever/client/coop/CoopController.java b/src/main/java/com/faforever/client/coop/CoopController.java index 26ea450be4..e7cfd43d0d 100644 --- a/src/main/java/com/faforever/client/coop/CoopController.java +++ b/src/main/java/com/faforever/client/coop/CoopController.java @@ -131,9 +131,6 @@ public void initialize() { numberOfPlayersComboBox.getSelectionModel().select(0); numberOfPlayersComboBox.getSelectionModel().selectedItemProperty().addListener(observable -> loadLeaderboard()); - leaderboardSearchTextField.textProperty().subscribe(s -> { - leaderboardTable.setItems(leaderboardFilteredList); - }); leaderboardFilteredList.predicateProperty().bind(leaderboardSearchTextField.textProperty().map(newValue -> coopResultBean -> { if (newValue.isEmpty()) { return true; @@ -145,6 +142,7 @@ public void initialize() { .flatMap(Collection::stream) .anyMatch(name -> name.toLowerCase().contains(newValue.toLowerCase())); })); + leaderboardTable.setItems(leaderboardFilteredList); rankColumn.setCellValueFactory(param -> param.getValue().rankingProperty().asObject()); rankColumn.setCellFactory(param -> new StringCell<>(String::valueOf)); @@ -264,10 +262,7 @@ private void loadLeaderboard() { .thenAccept(coopLeaderboardEntries -> { AtomicInteger ranking = new AtomicInteger(); coopLeaderboardEntries.forEach(coopResult -> coopResult.setRanking(ranking.incrementAndGet())); - fxApplicationThreadExecutor.execute(() -> { - leaderboardUnFilteredList.setAll(coopLeaderboardEntries); - leaderboardTable.setItems(observableList(leaderboardFilteredList)); - }); + fxApplicationThreadExecutor.execute(() -> leaderboardUnFilteredList.setAll(coopLeaderboardEntries)); }) .exceptionally(throwable -> { log.warn("Could not load coop leaderboard", throwable);