From 086b8539c3ab94dd9955132dd49022528f7d4a08 Mon Sep 17 00:00:00 2001 From: Aysegul Aydinlik Date: Fri, 19 Dec 2025 21:19:24 +0100 Subject: [PATCH] added highlighting fav recipes + list --- .../client/scenes/FoodpalApplicationCtrl.java | 88 ++++++++++++++----- .../client/scenes/FoodpalApplication.fxml | 2 + 2 files changed, 70 insertions(+), 20 deletions(-) diff --git a/client/src/main/java/client/scenes/FoodpalApplicationCtrl.java b/client/src/main/java/client/scenes/FoodpalApplicationCtrl.java index b260357..727d1bc 100644 --- a/client/src/main/java/client/scenes/FoodpalApplicationCtrl.java +++ b/client/src/main/java/client/scenes/FoodpalApplicationCtrl.java @@ -2,8 +2,10 @@ package client.scenes; import java.io.IOException; +import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; import client.exception.UpdateException; import client.scenes.recipe.IngredientListCtrl; @@ -29,6 +31,7 @@ import javafx.scene.control.Label; import javafx.scene.control.ListCell; import javafx.scene.control.ListView; import javafx.scene.control.TextField; +import javafx.scene.control.ToggleButton; import javafx.scene.input.KeyCode; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; @@ -65,6 +68,7 @@ public class FoodpalApplicationCtrl implements LocaleAware { @FXML private Button favouriteButton; + // stores the users favourites and load and saves them private Config config; private final ConfigService configService; @@ -80,6 +84,12 @@ public class FoodpalApplicationCtrl implements LocaleAware { @FXML public Button printRecipeButton; + @FXML + private ToggleButton favouritesOnlyToggle; + + private List allRecipes = new ArrayList<>(); + + @Inject public FoodpalApplicationCtrl( ServerUtils server, @@ -105,7 +115,12 @@ public class FoodpalApplicationCtrl implements LocaleAware { @Override protected void updateItem(Recipe item, boolean empty) { super.updateItem(item, empty); - setText(empty || item == null ? "" : item.getName()); + if (empty || item == null) { + setText(""); + return; + } //gives star in front fav items + boolean fav = config.isFavourite(item.getId()); + setText((fav ? "★ " : "") + item.getName()); } }); // When your selection changes, update details in the panel @@ -172,13 +187,11 @@ public class FoodpalApplicationCtrl implements LocaleAware { // Initialize callback for ingredient list updates this.ingredientListCtrl.setUpdateCallback(newList -> { Recipe selectedRecipe = recipeList.getSelectionModel().getSelectedItem(); - if (selectedRecipe == null) { - // edge case error for NPE. + if (selectedRecipe == null) { // edge case error for NPE. throw new NullPointerException("Null recipe whereas ingredients are edited"); } selectedRecipe.setIngredients(newList); - try { - // propagate changes to server + try { // propagate changes to server server.updateRecipe(selectedRecipe); } catch (IOException | InterruptedException e) { throw new UpdateException("Unable to update recipe to server for " + selectedRecipe); @@ -186,13 +199,11 @@ public class FoodpalApplicationCtrl implements LocaleAware { }); this.stepListCtrl.setUpdateCallback(newList -> { Recipe selectedRecipe = recipeList.getSelectionModel().getSelectedItem(); - if (selectedRecipe == null) { - // edge case error for NPE. + if (selectedRecipe == null) { // edge case error for NPE. throw new NullPointerException("Null recipe whereas ingredients are edited"); } selectedRecipe.setPreparationSteps(newList); - try { - // propagate changes to server + try { // propagate changes to server server.updateRecipe(selectedRecipe); } catch (IOException | InterruptedException e) { throw new UpdateException("Unable to update recipe to server for " + selectedRecipe); @@ -216,7 +227,6 @@ public class FoodpalApplicationCtrl implements LocaleAware { refresh(); updateFavouriteButton(recipeList.getSelectionModel().getSelectedItem()); } - private void showName(String name) { final int NAME_FONT_SIZE = 20; editableTitleArea.getChildren().clear(); @@ -224,17 +234,14 @@ public class FoodpalApplicationCtrl implements LocaleAware { nameLabel.setFont(new Font("System Bold", NAME_FONT_SIZE)); editableTitleArea.getChildren().add(nameLabel); } - @Override public void updateText() { addRecipeButton.setText(getLocaleString("menu.button.add.recipe")); removeRecipeButton.setText(getLocaleString("menu.button.remove.recipe")); cloneRecipeButton.setText(getLocaleString("menu.button.clone")); - editRecipeTitleButton.setText(getLocaleString("menu.button.edit")); removeRecipeButton2.setText(getLocaleString("menu.button.remove.recipe")); printRecipeButton.setText(getLocaleString("menu.button.print")); - recipesLabel.setText(getLocaleString("menu.label.recipes")); } @@ -263,13 +270,8 @@ public class FoodpalApplicationCtrl implements LocaleAware { System.err.println("Failed to load recipes: " + e.getMessage()); } - recipeList.getItems().setAll(recipes); - - // Select first recipe in the list by default - if (!recipes.isEmpty()) { - recipeList.getSelectionModel().selectFirst(); - } - detailsScreen.visibleProperty().set(!recipes.isEmpty()); + allRecipes = new ArrayList<>(recipes); + applyRecipeFilterAndKeepSelection(); } private void printError(String msg) { @@ -408,12 +410,58 @@ public class FoodpalApplicationCtrl implements LocaleAware { } configService.save(); + + //instant ui update + applyRecipeFilterAndKeepSelection(); + recipeList.refresh(); updateFavouriteButton(selected); } + @FXML + private void toggleFavouritesView() { + applyRecipeFilterAndKeepSelection(); + } + private void applyRecipeFilterAndKeepSelection() { + Recipe selected = recipeList.getSelectionModel().getSelectedItem(); + Long selectedId = selected == null ? null : selected.getId(); + + List view = allRecipes; + + if (favouritesOnlyToggle != null && favouritesOnlyToggle.isSelected()) { + view = allRecipes.stream() + .filter(r -> config.isFavourite(r.getId())) + .collect(Collectors.toList()); + } + + recipeList.getItems().setAll(view); + + // restore selection if possible + if (selectedId != null) { + Recipe match = view.stream() + .filter(r -> r.getId().equals(selectedId)) + .findFirst() + .orElse(null); + + if (match != null) { + recipeList.getSelectionModel().select(match); + } else if (!view.isEmpty()) { + recipeList.getSelectionModel().selectFirst(); + } + } else if (!view.isEmpty()) { + recipeList.getSelectionModel().selectFirst(); + } + + updateFavouriteButton(recipeList.getSelectionModel().getSelectedItem()); + detailsScreen.visibleProperty().set(!recipeList.getItems().isEmpty()); + } } + + + + + diff --git a/client/src/main/resources/client/scenes/FoodpalApplication.fxml b/client/src/main/resources/client/scenes/FoodpalApplication.fxml index 5063d40..6b8750b 100644 --- a/client/src/main/resources/client/scenes/FoodpalApplication.fxml +++ b/client/src/main/resources/client/scenes/FoodpalApplication.fxml @@ -14,6 +14,7 @@ + @@ -53,6 +54,7 @@