feat: clientside language filter and recipe language selector
This commit is contained in:
parent
2224fe1f51
commit
b130381154
11 changed files with 168 additions and 2 deletions
87
client/src/main/java/client/scenes/LanguageFilterCtrl.java
Normal file
87
client/src/main/java/client/scenes/LanguageFilterCtrl.java
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
package client.scenes;
|
||||||
|
|
||||||
|
import client.utils.ConfigService;
|
||||||
|
import client.utils.LocaleAware;
|
||||||
|
import client.utils.LocaleManager;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.scene.control.CheckMenuItem;
|
||||||
|
import javafx.scene.control.MenuButton;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class LanguageFilterCtrl implements LocaleAware {
|
||||||
|
private final LocaleManager manager;
|
||||||
|
private final ConfigService configService;
|
||||||
|
private final FoodpalApplicationCtrl appCtrl;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public LanguageFilterCtrl(LocaleManager manager, ConfigService configService, FoodpalApplicationCtrl appCtrl) {
|
||||||
|
this.manager = manager;
|
||||||
|
this.configService = configService;
|
||||||
|
this.appCtrl = appCtrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
MenuButton langFilterMenu;
|
||||||
|
|
||||||
|
List<String> selectedLanguages = new ArrayList<>();
|
||||||
|
|
||||||
|
private String getSelectedLanguagesDisplay() {
|
||||||
|
String joined = String.join(", ", selectedLanguages);
|
||||||
|
if (joined.isEmpty()) {
|
||||||
|
return "none";
|
||||||
|
} else {
|
||||||
|
return joined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateMenuButtonDisplay() {
|
||||||
|
langFilterMenu.setText(getLocaleString("menu.label.selected-langs") + ": " + this.getSelectedLanguagesDisplay());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateText() {
|
||||||
|
this.updateMenuButtonDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LocaleManager getLocaleManager() {
|
||||||
|
return this.manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initializeComponents() {
|
||||||
|
var items = this.langFilterMenu.getItems();
|
||||||
|
|
||||||
|
final List<String> languages = List.of("en", "nl", "pl");
|
||||||
|
this.selectedLanguages = this.configService.getConfig().getRecipeLanguages();
|
||||||
|
this.updateMenuButtonDisplay();
|
||||||
|
|
||||||
|
items.clear();
|
||||||
|
|
||||||
|
languages.forEach(lang -> {
|
||||||
|
CheckMenuItem it = new CheckMenuItem(lang);
|
||||||
|
|
||||||
|
if (selectedLanguages.contains(it.getText())) {
|
||||||
|
it.setSelected(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
it.selectedProperty().addListener((observable, _, value) -> {
|
||||||
|
if (value) {
|
||||||
|
selectedLanguages.add(it.getText());
|
||||||
|
} else {
|
||||||
|
selectedLanguages.remove(it.getText());
|
||||||
|
}
|
||||||
|
|
||||||
|
configService.save();
|
||||||
|
selectedLanguages.sort(String::compareTo);
|
||||||
|
appCtrl.refresh();
|
||||||
|
|
||||||
|
this.updateMenuButtonDisplay();
|
||||||
|
});
|
||||||
|
|
||||||
|
items.add(it);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -19,6 +19,7 @@ import javafx.scene.control.Button;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.control.ListView;
|
import javafx.scene.control.ListView;
|
||||||
import javafx.scene.control.TextField;
|
import javafx.scene.control.TextField;
|
||||||
|
import javafx.scene.control.ComboBox;
|
||||||
import javafx.scene.input.KeyCode;
|
import javafx.scene.input.KeyCode;
|
||||||
import javafx.scene.layout.HBox;
|
import javafx.scene.layout.HBox;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
|
|
@ -77,6 +78,9 @@ public class RecipeDetailCtrl implements LocaleAware {
|
||||||
@FXML
|
@FXML
|
||||||
private Button favouriteButton;
|
private Button favouriteButton;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private ComboBox<String> langSelector;
|
||||||
|
|
||||||
private ListView<Recipe> getParentRecipeList() {
|
private ListView<Recipe> getParentRecipeList() {
|
||||||
return this.appCtrl.recipeList;
|
return this.appCtrl.recipeList;
|
||||||
}
|
}
|
||||||
|
|
@ -138,6 +142,7 @@ public class RecipeDetailCtrl implements LocaleAware {
|
||||||
this.showName(recipe.getName());
|
this.showName(recipe.getName());
|
||||||
this.ingredientListController.refetchFromRecipe(recipe);
|
this.ingredientListController.refetchFromRecipe(recipe);
|
||||||
this.stepListController.refetchFromRecipe(recipe);
|
this.stepListController.refetchFromRecipe(recipe);
|
||||||
|
this.langSelector.setValue(recipe.getLocale());
|
||||||
this.refreshFavouriteButton();
|
this.refreshFavouriteButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -294,6 +299,20 @@ public class RecipeDetailCtrl implements LocaleAware {
|
||||||
editableTitleArea.getChildren().add(nameLabel);
|
editableTitleArea.getChildren().add(nameLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Switch the recipe's language.
|
||||||
|
*/
|
||||||
|
@FXML
|
||||||
|
void changeLanguage() {
|
||||||
|
recipe.setLocale(this.langSelector.getValue());
|
||||||
|
|
||||||
|
try {
|
||||||
|
server.updateRecipe(this.recipe);
|
||||||
|
} catch (IOException | InterruptedException e) {
|
||||||
|
throw new UpdateException("Error occurred when updating recipe locale!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateText() {
|
public void updateText() {
|
||||||
editRecipeTitleButton.setText(getLocaleString("menu.button.edit"));
|
editRecipeTitleButton.setText(getLocaleString("menu.button.edit"));
|
||||||
|
|
@ -309,5 +328,7 @@ public class RecipeDetailCtrl implements LocaleAware {
|
||||||
@Override
|
@Override
|
||||||
public void initializeComponents() {
|
public void initializeComponents() {
|
||||||
initStepsIngredientsList();
|
initStepsIngredientsList();
|
||||||
|
|
||||||
|
langSelector.getItems().addAll("en", "nl", "pl");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ public class Config {
|
||||||
|
|
||||||
|
|
||||||
private String language = "en";
|
private String language = "en";
|
||||||
|
private List<String> recipeLanguages = new ArrayList<>();
|
||||||
private String serverUrl = "http://localhost:8080";
|
private String serverUrl = "http://localhost:8080";
|
||||||
|
|
||||||
private List<Long> favourites = new ArrayList<>();
|
private List<Long> favourites = new ArrayList<>();
|
||||||
|
|
@ -66,5 +67,28 @@ public class Config {
|
||||||
public void removeFavourite(long recipeId) {
|
public void removeFavourite(long recipeId) {
|
||||||
getFavourites().remove(recipeId);
|
getFavourites().remove(recipeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of languages that should filter the displayed recipes.
|
||||||
|
*
|
||||||
|
* @return The desired languages the user would like to see.
|
||||||
|
*/
|
||||||
|
public List<String> getRecipeLanguages() {
|
||||||
|
return this.recipeLanguages;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a language to the list of filtering languages.
|
||||||
|
*/
|
||||||
|
public void addRecipeLanguage(String lang) {
|
||||||
|
this.recipeLanguages.add(lang);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a language from the list of filtering languages.
|
||||||
|
*/
|
||||||
|
public void removeRecipeLanguage(String lang) {
|
||||||
|
this.recipeLanguages.remove(lang);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,11 @@ public class ServerUtils {
|
||||||
private final HttpClient client;
|
private final HttpClient client;
|
||||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||||
private final int statusOK = 200;
|
private final int statusOK = 200;
|
||||||
|
private final ConfigService configService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ServerUtils() {
|
public ServerUtils(ConfigService configService) {
|
||||||
|
this.configService = configService;
|
||||||
client = HttpClient.newHttpClient();
|
client = HttpClient.newHttpClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -40,8 +42,15 @@ public class ServerUtils {
|
||||||
* @return a JSON string with all the recipes
|
* @return a JSON string with all the recipes
|
||||||
*/
|
*/
|
||||||
public List<Recipe> getRecipes() throws IOException, InterruptedException {
|
public List<Recipe> getRecipes() throws IOException, InterruptedException {
|
||||||
|
|
||||||
|
String uri =
|
||||||
|
SERVER +
|
||||||
|
"/recipes" +
|
||||||
|
"?locales=" +
|
||||||
|
String.join(",", this.configService.getConfig().getRecipeLanguages());
|
||||||
|
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
.uri(URI.create(SERVER + "/recipes"))
|
.uri(URI.create(uri))
|
||||||
.GET()
|
.GET()
|
||||||
.build();
|
.build();
|
||||||
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@
|
||||||
</font></Label>
|
</font></Label>
|
||||||
|
|
||||||
<fx:include source="SearchBar.fxml" fx:id="searchBar" />
|
<fx:include source="SearchBar.fxml" fx:id="searchBar" />
|
||||||
|
<fx:include source="LanguageFilter.fxml" fx:id="langFilter" />
|
||||||
|
|
||||||
<ListView fx:id="recipeList" />
|
<ListView fx:id="recipeList" />
|
||||||
|
|
||||||
|
|
|
||||||
12
client/src/main/resources/client/scenes/LanguageFilter.fxml
Normal file
12
client/src/main/resources/client/scenes/LanguageFilter.fxml
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<?import javafx.scene.control.MenuButton?>
|
||||||
|
|
||||||
|
<MenuButton
|
||||||
|
mnemonicParsing="false"
|
||||||
|
text="Languages"
|
||||||
|
xmlns:fx="http://javafx.com/fxml/1"
|
||||||
|
xmlns="http://javafx.com/javafx/25"
|
||||||
|
fx:controller="client.scenes.LanguageFilterCtrl"
|
||||||
|
fx:id="langFilterMenu"
|
||||||
|
/>
|
||||||
|
|
@ -27,6 +27,8 @@
|
||||||
<Button fx:id="favouriteButton" onAction="#toggleFavourite" text="☆" />
|
<Button fx:id="favouriteButton" onAction="#toggleFavourite" text="☆" />
|
||||||
</HBox>
|
</HBox>
|
||||||
|
|
||||||
|
<ComboBox fx:id="langSelector" onAction="#changeLanguage" />
|
||||||
|
|
||||||
<!-- Ingredients -->
|
<!-- Ingredients -->
|
||||||
<fx:include source="IngredientList.fxml" fx:id="ingredientList" />
|
<fx:include source="IngredientList.fxml" fx:id="ingredientList" />
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@ menu.button.edit=Edit
|
||||||
menu.button.clone=Clone
|
menu.button.clone=Clone
|
||||||
menu.button.print=Print recipe
|
menu.button.print=Print recipe
|
||||||
|
|
||||||
|
menu.label.selected-langs=Languages
|
||||||
|
|
||||||
lang.en.display=English
|
lang.en.display=English
|
||||||
lang.nl.display=Dutch
|
lang.nl.display=Dutch
|
||||||
lang.pl.display=Polish
|
lang.pl.display=Polish
|
||||||
|
|
@ -26,6 +26,9 @@ menu.button.clone=Clone
|
||||||
menu.button.print=Print recipe
|
menu.button.print=Print recipe
|
||||||
|
|
||||||
menu.search=Search...
|
menu.search=Search...
|
||||||
|
|
||||||
|
menu.label.selected-langs=Languages
|
||||||
|
|
||||||
lang.en.display=English
|
lang.en.display=English
|
||||||
lang.nl.display=Nederlands
|
lang.nl.display=Nederlands
|
||||||
lang.pl.display=Polski
|
lang.pl.display=Polski
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@ menu.button.edit=Bewerken
|
||||||
menu.button.clone=Dupliceren
|
menu.button.clone=Dupliceren
|
||||||
menu.button.print=Recept afdrukken
|
menu.button.print=Recept afdrukken
|
||||||
|
|
||||||
|
menu.label.selected-langs=Talen
|
||||||
|
|
||||||
menu.search=Zoeken...
|
menu.search=Zoeken...
|
||||||
lang.en.display=English
|
lang.en.display=English
|
||||||
lang.nl.display=Nederlands
|
lang.nl.display=Nederlands
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,9 @@ menu.button.clone=Duplikuj
|
||||||
menu.button.print=Drukuj przepis
|
menu.button.print=Drukuj przepis
|
||||||
|
|
||||||
menu.search=Szukaj...
|
menu.search=Szukaj...
|
||||||
|
|
||||||
|
menu.label.selected-langs=J?zyki
|
||||||
|
|
||||||
lang.en.display=English
|
lang.en.display=English
|
||||||
lang.nl.display=Nederlands
|
lang.nl.display=Nederlands
|
||||||
lang.pl.display=Polski
|
lang.pl.display=Polski
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue