From 5315fe3df491ecc97f7db9033cdd9beac9b17cdb Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Wed, 21 Jan 2026 13:38:02 +0100 Subject: [PATCH 1/4] feat(client/nutrition-model): init modules for shopping list; missing impl but it has interface :) --- client/src/main/java/client/MyModule.java | 5 ++ .../NonFunctionalShoppingListService.java | 63 +++++++++++++++++++ .../client/service/ShoppingListService.java | 30 +++++++++ .../client/service/ShoppingListViewModel.java | 22 +++++++ 4 files changed, 120 insertions(+) create mode 100644 client/src/main/java/client/service/NonFunctionalShoppingListService.java create mode 100644 client/src/main/java/client/service/ShoppingListService.java create mode 100644 client/src/main/java/client/service/ShoppingListViewModel.java diff --git a/client/src/main/java/client/MyModule.java b/client/src/main/java/client/MyModule.java index 4d027ca..e40e613 100644 --- a/client/src/main/java/client/MyModule.java +++ b/client/src/main/java/client/MyModule.java @@ -21,6 +21,9 @@ import client.scenes.nutrition.NutritionDetailsCtrl; import client.scenes.nutrition.NutritionViewCtrl; import client.scenes.recipe.IngredientListCtrl; import client.scenes.recipe.RecipeStepListCtrl; +import client.service.NonFunctionalShoppingListService; +import client.service.ShoppingListService; +import client.service.ShoppingListViewModel; import client.utils.ConfigService; import client.utils.LocaleManager; import client.utils.server.ServerUtils; @@ -57,6 +60,8 @@ public class MyModule implements Module { binder.bind(new TypeLiteral>() {}).toInstance( new WebSocketDataService<>() ); + binder.bind(ShoppingListViewModel.class).toInstance(new ShoppingListViewModel()); + binder.bind(ShoppingListService.class).to(NonFunctionalShoppingListService.class); binder.bind(new TypeLiteral>() {}).toInstance( new WebSocketDataService<>() ); diff --git a/client/src/main/java/client/service/NonFunctionalShoppingListService.java b/client/src/main/java/client/service/NonFunctionalShoppingListService.java new file mode 100644 index 0000000..f5638ed --- /dev/null +++ b/client/src/main/java/client/service/NonFunctionalShoppingListService.java @@ -0,0 +1,63 @@ +package client.service; + +import com.google.inject.Inject; +import commons.FormalIngredient; +import commons.Recipe; +import commons.RecipeIngredient; +import javafx.util.Pair; +import org.apache.commons.lang3.NotImplementedException; + +import java.util.List; +import java.util.Optional; + +public class NonFunctionalShoppingListService extends ShoppingListService { + @Inject + public NonFunctionalShoppingListService(ShoppingListViewModel viewModel) { + super(viewModel); + } + + @Override + public void putIngredient(RecipeIngredient ingredient) { + throw new NotImplementedException(); + } + + @Override + public void putIngredient(RecipeIngredient ingredient, Recipe recipe) { + throw new NotImplementedException(); + } + + @Override + public void putIngredient(RecipeIngredient ingredient, String recipeName) { + throw new NotImplementedException(); + } + + @Override + public void putArbitraryItem(String name) { + throw new NotImplementedException(); + } + + @Override + public FormalIngredient purgeIngredient(Long id) { + throw new NotImplementedException(); + } + + @Override + public FormalIngredient purgeIngredient(String ingredientName) { + throw new NotImplementedException(); + } + + @Override + public void reset() { + throw new NotImplementedException(); + } + + @Override + public List>> getItems() { + throw new NotImplementedException(); + } + + @Override + public String makePrintable() { + throw new NotImplementedException(); + } +} diff --git a/client/src/main/java/client/service/ShoppingListService.java b/client/src/main/java/client/service/ShoppingListService.java new file mode 100644 index 0000000..c212750 --- /dev/null +++ b/client/src/main/java/client/service/ShoppingListService.java @@ -0,0 +1,30 @@ +package client.service; + +import com.google.inject.Inject; +import commons.FormalIngredient; +import commons.Recipe; +import commons.RecipeIngredient; +import javafx.util.Pair; + +import java.util.List; +import java.util.Optional; + +public abstract class ShoppingListService { + private ShoppingListViewModel viewModel; + @Inject + public ShoppingListService(ShoppingListViewModel viewModel) { + this.viewModel = viewModel; + } + public abstract void putIngredient(FormalIngredient ingredient); + public abstract void putIngredient(FormalIngredient ingredient, Recipe recipe); + public abstract void putIngredient(FormalIngredient ingredient, String recipeName); + public abstract void putArbitraryItem(String name); + + public abstract FormalIngredient purgeIngredient(Long id); + public abstract FormalIngredient purgeIngredient(String ingredientName); + + public abstract void reset(); + + public abstract List>> getItems(); + public abstract String makePrintable(); +} diff --git a/client/src/main/java/client/service/ShoppingListViewModel.java b/client/src/main/java/client/service/ShoppingListViewModel.java new file mode 100644 index 0000000..30e03df --- /dev/null +++ b/client/src/main/java/client/service/ShoppingListViewModel.java @@ -0,0 +1,22 @@ +package client.service; + +import commons.FormalIngredient; +import javafx.beans.property.ListProperty; +import javafx.beans.property.SimpleListProperty; +import javafx.collections.FXCollections; +import javafx.util.Pair; +import org.apache.commons.lang3.NotImplementedException; + +import java.util.Optional; + +public class ShoppingListViewModel { + /** + * The formal ingredient provides the ingredient and its amount, + * and the string (optional) describes the recipe where it came from. + */ + private final ListProperty>> listItems = new SimpleListProperty<>(FXCollections.observableArrayList()); + public void addArbitrary() { + throw new NotImplementedException(); + } + +} From 70dfc7e983f4949df27445c59530f715afb05f55 Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Wed, 21 Jan 2026 13:47:54 +0100 Subject: [PATCH 2/4] fix: non-functional API --- .../client/service/NonFunctionalShoppingListService.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/src/main/java/client/service/NonFunctionalShoppingListService.java b/client/src/main/java/client/service/NonFunctionalShoppingListService.java index f5638ed..82dad5c 100644 --- a/client/src/main/java/client/service/NonFunctionalShoppingListService.java +++ b/client/src/main/java/client/service/NonFunctionalShoppingListService.java @@ -17,17 +17,17 @@ public class NonFunctionalShoppingListService extends ShoppingListService { } @Override - public void putIngredient(RecipeIngredient ingredient) { + public void putIngredient(FormalIngredient ingredient) { throw new NotImplementedException(); } @Override - public void putIngredient(RecipeIngredient ingredient, Recipe recipe) { + public void putIngredient(FormalIngredient ingredient, Recipe recipe) { throw new NotImplementedException(); } @Override - public void putIngredient(RecipeIngredient ingredient, String recipeName) { + public void putIngredient(FormalIngredient ingredient, String recipeName) { throw new NotImplementedException(); } From 6cfd6ab82cd73ceb4edaf751b21e0a66356b70a2 Mon Sep 17 00:00:00 2001 From: Natalia Cholewa Date: Thu, 22 Jan 2026 17:21:40 +0100 Subject: [PATCH 3/4] feat: shopping list view --- .../client/scenes/FoodpalApplicationCtrl.java | 13 ++++ .../scenes/shopping/ShoppingListCtrl.java | 66 +++++++++++++++++++ .../client/scenes/FoodpalApplication.fxml | 3 + .../client/scenes/shopping/ShoppingList.fxml | 15 +++++ .../main/resources/locale/lang_en.properties | 2 + .../main/resources/locale/lang_nl.properties | 2 + .../main/resources/locale/lang_pl.properties | 2 + .../main/resources/locale/lang_tok.properties | 2 + .../main/resources/locale/lang_tr.properties | 2 + 9 files changed, 107 insertions(+) create mode 100644 client/src/main/java/client/scenes/shopping/ShoppingListCtrl.java create mode 100644 client/src/main/resources/client/scenes/shopping/ShoppingList.fxml diff --git a/client/src/main/java/client/scenes/FoodpalApplicationCtrl.java b/client/src/main/java/client/scenes/FoodpalApplicationCtrl.java index 3242d21..327941c 100644 --- a/client/src/main/java/client/scenes/FoodpalApplicationCtrl.java +++ b/client/src/main/java/client/scenes/FoodpalApplicationCtrl.java @@ -33,6 +33,9 @@ import commons.ws.messages.UpdateRecipeMessage; import jakarta.inject.Inject; import javafx.application.Platform; import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; import javafx.scene.control.Alert; import javafx.scene.control.Button; import javafx.scene.control.Label; @@ -41,6 +44,7 @@ import javafx.scene.control.ListView; import javafx.scene.control.TextInputDialog; import javafx.scene.control.ToggleButton; import javafx.scene.paint.Color; +import javafx.stage.Stage; import org.apache.commons.lang3.NotImplementedException; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; @@ -611,6 +615,15 @@ public class FoodpalApplicationCtrl implements LocaleAware { updatedBadgeTimer.playFromStart(); } + public void openShoppingListWindow() throws IOException { + FXMLLoader loader = new FXMLLoader(getClass().getResource("shopping/ShoppingList.fxml")); + Parent root = (Parent)loader.load(); + Stage stage = new Stage(); + stage.setTitle(this.getLocaleString("menu.shopping.title")); + stage.setScene(new Scene(root)); + stage.show(); + } + } diff --git a/client/src/main/java/client/scenes/shopping/ShoppingListCtrl.java b/client/src/main/java/client/scenes/shopping/ShoppingListCtrl.java new file mode 100644 index 0000000..b73ec9d --- /dev/null +++ b/client/src/main/java/client/scenes/shopping/ShoppingListCtrl.java @@ -0,0 +1,66 @@ +package client.scenes.shopping; + +import client.service.ShoppingListService; +import client.utils.LocaleAware; +import client.utils.LocaleManager; +import com.google.inject.Inject; +import commons.FormalIngredient; +import javafx.fxml.FXML; +import javafx.scene.control.ListCell; +import javafx.scene.control.ListView; +import javafx.util.Pair; + +import java.util.Optional; + +public class ShoppingListCtrl implements LocaleAware { + ShoppingListService shopping; + + LocaleManager localeManager; + + @FXML + private ListView>> shoppingListView; + + @Inject + public ShoppingListCtrl( + ShoppingListService shopping, + LocaleManager localeManager + ) { + this.shopping = shopping; + this.localeManager = localeManager; + } + + @Override + public void updateText() { + + } + + @Override + public LocaleManager getLocaleManager() { + return this.localeManager; + } + + public void initializeComponents() { + this.shoppingListView.setCellFactory(l -> new ListCell<>() { + @Override + protected void updateItem(Pair> item, boolean empty) { + super.updateItem(item, empty); + + if (empty) { + this.setText(""); + return; + } + + String display = item.getKey().toString() + + item.getValue().map(recipe -> { + return " (" + recipe + ")"; + }).orElse(""); + + this.setText(display); + } + }); + + this.shoppingListView.getItems().setAll( + this.shopping.getItems() + ); + } +} diff --git a/client/src/main/resources/client/scenes/FoodpalApplication.fxml b/client/src/main/resources/client/scenes/FoodpalApplication.fxml index c777543..adfffba 100644 --- a/client/src/main/resources/client/scenes/FoodpalApplication.fxml +++ b/client/src/main/resources/client/scenes/FoodpalApplication.fxml @@ -70,6 +70,9 @@ +