Compare commits

...

2 Commits

Author SHA1 Message Date
LilleBRG
12427a85f8 merge 2025-05-13 15:14:54 +02:00
LilleBRG
00cc8101f1 need to merge but trying to add recipe to shoppinglist 2025-05-13 15:11:57 +02:00
7 changed files with 197 additions and 18 deletions

View File

@ -3,6 +3,9 @@ package tech.mercantec.easyeat.helpers
import android.content.Context import android.content.Context
import android.util.Log import android.util.Log
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import tech.mercantec.easyeat.models.CreateIngredient
import tech.mercantec.easyeat.models.CreateRecipe
import tech.mercantec.easyeat.models.Ingredient
@Serializable @Serializable
data class LoginRequest(val emailUsr: String, val password: String) data class LoginRequest(val emailUsr: String, val password: String)
@ -109,3 +112,35 @@ fun changePassword(ctx: Context, oldPassword: String, newPassword: String) {
return requestJson<ChangePasswordRequest, Unit>(ctx, "PUT", "/api/User/change-password", request) return requestJson<ChangePasswordRequest, Unit>(ctx, "PUT", "/api/User/change-password", request)
} }
@Serializable
data class CreateRecipeRequest(val name: String, val description: String, val directions: List<String>, val ingredients: List<CreateIngredient>)
fun createRecipe(ctx: Context, recipe: CreateRecipe) {
val request = CreateRecipeRequest(recipe.name, recipe.description, recipe.directions, recipe.ingredients)
requestJson<CreateRecipeRequest, Boolean>(ctx, "POST", "/api/recipe/create", request)
}
@Serializable
data class GetAllRecipesResponse(val id: Int, val name: String, val description: String)
fun getAllRecipies(ctx: Context): List<GetAllRecipesResponse> {
return requestJson<Unit, List<GetAllRecipesResponse>>(ctx, "GET", "/api/Recipe/getall", null)
}
@Serializable
data class RecipeDetailsResponse(val id: Int, val name: String, val description: String, val directions: List<String>, val ingredients: List<Ingredient>)
fun getRecipeDetails(ctx: Context, id: Int): RecipeDetailsResponse {
return requestJson<Unit, RecipeDetailsResponse>(ctx, "GET", "/api/Recipe/get/$id", null)
}
@Serializable
data class ShoppingListAddRecipeRequest(val id: Int, val multiplier: Int)
fun AddRecipeToShoppingList(ctx: Context, id: Int, multiplier: Int) {
val request = ShoppingListAddRecipeRequest(id, multiplier)
return requestJson<ShoppingListAddRecipeRequest, Unit>(ctx, "ADD", "/api/ShoppingList/recipeadd", request)
}

View File

@ -15,6 +15,9 @@ import androidx.appcompat.app.AppCompatActivity
import tech.mercantec.easyeat.R import tech.mercantec.easyeat.R
import tech.mercantec.easyeat.helpers.ApiRequestException import tech.mercantec.easyeat.helpers.ApiRequestException
import tech.mercantec.easyeat.helpers.createRecipe import tech.mercantec.easyeat.helpers.createRecipe
import tech.mercantec.easyeat.helpers.request
import tech.mercantec.easyeat.models.CreateIngredient
import tech.mercantec.easyeat.models.CreateRecipe
import tech.mercantec.easyeat.models.Ingredient import tech.mercantec.easyeat.models.Ingredient
import tech.mercantec.easyeat.models.Recipe import tech.mercantec.easyeat.models.Recipe
import kotlin.concurrent.thread import kotlin.concurrent.thread

View File

@ -1,7 +1,12 @@
package tech.mercantec.easyeat.ui.dishes package tech.mercantec.easyeat.ui.dishes
import android.app.Activity
import android.app.ProgressDialog
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.View
import android.widget.Button
import android.widget.LinearLayout
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import tech.mercantec.easyeat.R import tech.mercantec.easyeat.R
@ -9,14 +14,22 @@ import tech.mercantec.easyeat.helpers.ApiRequestException
import tech.mercantec.easyeat.helpers.RecipeDetailsResponse import tech.mercantec.easyeat.helpers.RecipeDetailsResponse
import tech.mercantec.easyeat.helpers.getRecipeDetails import tech.mercantec.easyeat.helpers.getRecipeDetails
import kotlin.concurrent.thread import kotlin.concurrent.thread
import android.widget.ListView import android.widget.EditText
import android.widget.TextView import android.widget.TextView
import androidx.core.widget.doAfterTextChanged
import tech.mercantec.easyeat.helpers.AddRecipeToShoppingList
import tech.mercantec.easyeat.helpers.createRecipe
import tech.mercantec.easyeat.models.CreateRecipe
import tech.mercantec.easyeat.models.Ingredient
class DishDetailsActivity : AppCompatActivity() { class DishDetailsActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_dish_details) setContentView(R.layout.activity_dish_details)
val ingredientsContainer = findViewById<LinearLayout>(R.id.dishDetailIngredients)
val multiplierEditText = findViewById<EditText>(R.id.ingredientMultiplier)
val dishId = intent.getIntExtra("dish_id", -1) val dishId = intent.getIntExtra("dish_id", -1)
if (dishId == -1) { if (dishId == -1) {
Toast.makeText(this, "No dish ID provided", Toast.LENGTH_SHORT).show() Toast.makeText(this, "No dish ID provided", Toast.LENGTH_SHORT).show()
@ -24,6 +37,8 @@ class DishDetailsActivity : AppCompatActivity() {
return return
} }
thread { thread {
val recipe: RecipeDetailsResponse val recipe: RecipeDetailsResponse
try { try {
@ -35,20 +50,101 @@ class DishDetailsActivity : AppCompatActivity() {
return@thread return@thread
} }
Log.i("DISH", recipe.ingredients.toString()) Log.i("DISH", recipe.ingredients.toString())
val ingredientsLayout = findViewById<LinearLayout>(R.id.dishDetailIngredients)
val instructionsLayout = findViewById<LinearLayout>(R.id.dishDetailInstructions)
// Example data: recipe.ingredients and recipe.directions
runOnUiThread { runOnUiThread {
// Set title and description
findViewById<TextView>(R.id.dishDetailName).text = recipe.name findViewById<TextView>(R.id.dishDetailName).text = recipe.name
findViewById<TextView>(R.id.dishDetailDescription).text = recipe.description findViewById<TextView>(R.id.dishDetailDescription).text = recipe.description
// Populate Ingredients
recipe.ingredients.forEach { ingredient ->
val textView = TextView(this).apply {
text = "${ingredient.name} ${ingredient.amount ?: ""} ${ingredient.unit ?: ""}"
textSize = 18f
}
textView.textAlignment = View.TEXT_ALIGNMENT_CENTER
ingredientsLayout.addView(textView)
}
// Set up the ingredient list // Populate Instructions (if directions are strings)
val ingredientListView = findViewById<ListView>(R.id.dishDetailIngredients) recipe.directions.forEachIndexed { index, direction ->
val ingredientAdapter = IngredientAdapter(this, recipe.ingredients) val textView = TextView(this).apply {
ingredientListView.adapter = ingredientAdapter text = "${index + 1}. $direction"
textSize = 18f
}
textView.textAlignment = View.TEXT_ALIGNMENT_CENTER
instructionsLayout.addView(textView)
}
}
fun displayIngredients(ingredients: List<Ingredient>, multiplier: Int, container: LinearLayout) {
container.removeAllViews() // clear previous views
for (ingredient in ingredients) {
val row = TextView(this)
val amount = (ingredient.amount ?: 0.0) * multiplier
row.text = "${ingredient.name}: ${"%.2f".format(amount)} ${ingredient.unit ?: ""}"
row.textSize = 18f
row.setPadding(0, 8, 0, 8)
row.textAlignment = View.TEXT_ALIGNMENT_CENTER
container.addView(row)
}
}
runOnUiThread {
val nameView = findViewById<TextView>(R.id.dishDetailName)
val descView = findViewById<TextView>(R.id.dishDetailDescription)
nameView.text = recipe.name
descView.text = recipe.description
// Default multiplier
var multiplier = 1
// Initial display
displayIngredients(recipe.ingredients, multiplier, ingredientsContainer)
// Listen for user input changes
multiplierEditText.doAfterTextChanged {
multiplier = it.toString().toIntOrNull() ?: 1
displayIngredients(recipe.ingredients, multiplier, ingredientsContainer)
}
// You can do the same for directions if needed
}
val saveButton: Button = findViewById(R.id.saveDishButton)
saveButton.setOnClickListener {
val progressDialog = ProgressDialog(this)
progressDialog.setMessage("Loading...")
progressDialog.show()
thread {
try {
AddRecipeToShoppingList(this, dishId, multiplierEditText.text.toString().toIntOrNull() ?: 1)
} catch (e: ApiRequestException) {
runOnUiThread {
Toast.makeText(this, e.message, Toast.LENGTH_LONG).show()
}
return@thread
} finally {
runOnUiThread {
progressDialog.hide()
}
}
runOnUiThread {
Toast.makeText(this, "Password changed successfully", Toast.LENGTH_LONG).show()
}
setResult(Activity.RESULT_OK)
finish()
}
}
val instructionsListView = findViewById<ListView>(R.id.dishDetailInstructions)
val instructionsAdapter = InstructionsAdapter(this, recipe.directions)
instructionsListView.adapter = instructionsAdapter
}
} }
} }
} }

View File

@ -10,6 +10,7 @@ import tech.mercantec.easyeat.R
import tech.mercantec.easyeat.helpers.ApiRequestException import tech.mercantec.easyeat.helpers.ApiRequestException
import tech.mercantec.easyeat.helpers.createRecipe import tech.mercantec.easyeat.helpers.createRecipe
import tech.mercantec.easyeat.helpers.generateRecipeWithAI import tech.mercantec.easyeat.helpers.generateRecipeWithAI
import tech.mercantec.easyeat.models.Recipe
import java.util.Locale import java.util.Locale
import kotlin.concurrent.thread import kotlin.concurrent.thread
@ -26,6 +27,7 @@ class GenerateRecipeActivity : AppCompatActivity() {
progressDialog.show() progressDialog.show()
thread { thread {
val response: GenerateRecipeResponse
try { try {
val recipe = generateRecipeWithAI(this, name, Locale.getDefault().displayLanguage) val recipe = generateRecipeWithAI(this, name, Locale.getDefault().displayLanguage)

View File

@ -43,7 +43,9 @@
<EditText <EditText
android:id="@+id/ingredientAmountEditText" android:id="@+id/ingredientAmountEditText"
android:layout_width="173dp" android:layout_width="173dp"
android:layout_height="48dp" /> android:layout_height="48dp"
android:inputType="numberDecimal"
/>
</LinearLayout> </LinearLayout>
<!-- Measurement field --> <!-- Measurement field -->

View File

@ -19,13 +19,16 @@
android:textSize="30sp" android:textSize="30sp"
android:textAlignment="center" android:textAlignment="center"
android:layout_marginBottom="10dp" android:layout_marginBottom="10dp"
android:textStyle="bold" /> android:textStyle="bold"
android:layout_marginHorizontal="10sp"/>
/>
<TextView <TextView
android:id="@+id/dishDetailDescription" android:id="@+id/dishDetailDescription"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textSize="20sp" android:textSize="20sp"
android:textAlignment="center" /> android:textAlignment="center"
android:layout_marginHorizontal="10sp"/>
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
@ -34,11 +37,37 @@
android:textAlignment="center" android:textAlignment="center"
android:textStyle="bold" android:textStyle="bold"
android:text="Ingredients"/> android:text="Ingredients"/>
<ListView <LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="18sp"
android:layout_marginLeft="10sp"
android:text="Food for how many people?"
android:layout_weight="0.7"/>
<EditText
android:id="@+id/ingredientMultiplier"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="number"
android:layout_weight="1"
android:layout_marginRight="10sp"/>
</LinearLayout>
<LinearLayout
android:id="@+id/dishDetailIngredients" android:id="@+id/dishDetailIngredients"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
/> android:orientation="vertical"
android:layout_marginHorizontal="10sp">
</LinearLayout>
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
@ -49,10 +78,21 @@
android:textStyle="bold" android:textStyle="bold"
android:text="Instructions"/> android:text="Instructions"/>
<ListView <LinearLayout
android:id="@+id/dishDetailInstructions" android:id="@+id/dishDetailInstructions"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
/> android:orientation="vertical"
android:layout_marginHorizontal="10sp"/>
<Button
android:id="@+id/add_dish"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="16dp"
android:backgroundTint="@color/cyan"
android:text="@string/add_ingredients_to_shopping_list"
android:tint="@android:color/white"/>
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>

View File

@ -45,6 +45,7 @@
<string name="ai_generate_recipe_title">Generate recipe with AI</string> <string name="ai_generate_recipe_title">Generate recipe with AI</string>
<string name="dish_title_label">Name of dish</string> <string name="dish_title_label">Name of dish</string>
<string name="generate_recipe_label">Generate</string> <string name="generate_recipe_label">Generate</string>
<string name="add_ingredients_to_shopping_list">Add ingredients to Shopping List</string>
<string name="ingredients_label">Ingredients</string> <string name="ingredients_label">Ingredients</string>
<string name="directions_label">Directions</string> <string name="directions_label">Directions</string>
<string name="create_manually_label">Create manually</string> <string name="create_manually_label">Create manually</string>