Merge branch 'searchbar-fix' into 'main'

added searching multiple things

Closes #82

See merge request cse1105/2025-2026/teams/csep-team-76!91
This commit is contained in:
Aysegul Aydinlik 2026-01-23 00:33:57 +01:00
commit b82a8f7d33
2 changed files with 72 additions and 1 deletions

View file

@ -14,8 +14,11 @@ import javafx.scene.input.KeyCode;
import javafx.util.Duration; import javafx.util.Duration;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.stream.Collectors;
/** /**
* Controller for the search bar component. * Controller for the search bar component.
@ -100,7 +103,11 @@ public class SearchBarCtrl implements LocaleAware {
currentSearchTask = new Task<>() { currentSearchTask = new Task<>() {
@Override @Override
protected List<Recipe> call() throws IOException, InterruptedException { protected List<Recipe> call() throws IOException, InterruptedException {
return serverUtils.getRecipesFiltered(filter, configService.getConfig().getRecipeLanguages()); var recipes = serverUtils.getRecipesFiltered(
"",
configService.getConfig().getRecipeLanguages()
);
return applyMultiTermAndFilter(recipes, filter);
} }
}; };
@ -156,4 +163,52 @@ public class SearchBarCtrl implements LocaleAware {
this.searchDebounce.playFromStart(); this.searchDebounce.playFromStart();
}); });
} }
private List<Recipe> applyMultiTermAndFilter(List<Recipe> recipes, String query) {
if (recipes == null) {
return List.of();
}
if (query == null || query.isBlank()) {
return recipes;
}
var tokens = Arrays.stream(query.toLowerCase(Locale.ROOT).split("[\\s,]+"))
.map(String::trim)
.filter(s -> !s.isBlank())
.filter(s -> !s.equals("and"))
.toList();
if (tokens.isEmpty()) {
return recipes;
}
return recipes.stream()
.filter(r -> {
var sb = new StringBuilder();
if (r.getName() != null) {
sb.append(r.getName()).append(' ');
}
if (r.getIngredients() != null) {
r.getIngredients().forEach(i -> {
if (i != null) {
sb.append(i).append(' ');
}
});
}
if (r.getPreparationSteps() != null) {
r.getPreparationSteps().forEach(s -> {
if (s != null) {
sb.append(s).append(' ');
}
});
}
var haystack = sb.toString().toLowerCase(Locale.ROOT);
return tokens.stream().allMatch(haystack::contains);
})
.collect(Collectors.toList());
}
} }

View file

@ -4,7 +4,9 @@ import client.utils.ConfigService;
import com.google.inject.Inject; import com.google.inject.Inject;
import java.net.URI; import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpRequest; import java.net.http.HttpRequest;
import java.nio.charset.StandardCharsets;
import java.util.List; import java.util.List;
public class Endpoints { public class Endpoints {
@ -81,9 +83,23 @@ public class Endpoints {
} }
public HttpRequest.Builder getRecipesWith(String params) { public HttpRequest.Builder getRecipesWith(String params) {
if (params != null && params.contains("search=")) {
int start = params.indexOf("search=") + "search=".length();
int end = params.indexOf('&', start);
if (end == -1) {
end = params.length();
}
String rawValue = params.substring(start, end);
String encodedValue = URLEncoder.encode(rawValue, StandardCharsets.UTF_8);
params = params.substring(0, start) + encodedValue + params.substring(end);
}
return this.http(this.createApiUrl("/recipes?" + params)).GET(); return this.http(this.createApiUrl("/recipes?" + params)).GET();
} }
public HttpRequest.Builder createIngredient(HttpRequest.BodyPublisher body) { public HttpRequest.Builder createIngredient(HttpRequest.BodyPublisher body) {
String url = this.createApiUrl("/ingredients"); String url = this.createApiUrl("/ingredients");