Finish generating recipe, refactor directions property and request helpers

This commit is contained in:
Reimar 2025-05-13 12:59:18 +02:00
parent 4772c0ef26
commit 1c085a4262
Signed by: Reimar
GPG Key ID: 93549FA07F0AE268
10 changed files with 52 additions and 91 deletions

View File

@ -45,7 +45,7 @@
android:exported="false" /> android:exported="false" />
<activity <activity
android:name=".ui.dishes.CreateDishAIActivity" android:name=".ui.dishes.GenerateRecipeActivity"
android:exported="false" /> android:exported="false" />
<activity <activity

View File

@ -3,11 +3,6 @@ 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.CreateDirection
import tech.mercantec.easyeat.models.CreateIngredient
import tech.mercantec.easyeat.models.CreateRecipe
import tech.mercantec.easyeat.models.Direction
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)
@ -20,7 +15,7 @@ fun login(ctx: Context, email: String, password: String) {
val response = requestJson<LoginRequest, LoginResponse>(ctx, "POST", "/api/User/login", request) val response = requestJson<LoginRequest, LoginResponse>(ctx, "POST", "/api/User/login", request)
with (ctx.getSharedPreferences("easyeat", Context.MODE_PRIVATE).edit()) { with(ctx.getSharedPreferences("easyeat", Context.MODE_PRIVATE).edit()) {
putInt("user-id", response.id) putInt("user-id", response.id)
putString("username", response.userName) putString("username", response.userName)
putString("auth-token", response.token) putString("auth-token", response.token)
@ -30,7 +25,7 @@ fun login(ctx: Context, email: String, password: String) {
} }
fun logout(ctx: Context) { fun logout(ctx: Context) {
with (ctx.getSharedPreferences("easyeat", Context.MODE_PRIVATE).edit()) { with(ctx.getSharedPreferences("easyeat", Context.MODE_PRIVATE).edit()) {
remove("user-id") remove("user-id")
remove("username") remove("username")
remove("auth-token") remove("auth-token")
@ -114,26 +109,3 @@ 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<CreateDirection>, 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<Direction>, val ingredients: List<Ingredient>)
fun getRecipeDetails(ctx: Context, id: Int): RecipeDetailsResponse {
return requestJson<Unit, RecipeDetailsResponse>(ctx, "GET", "/api/Recipe/get/$id", null)
}

View File

@ -2,6 +2,7 @@ package tech.mercantec.easyeat.helpers
import android.content.Context import android.content.Context
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import tech.mercantec.easyeat.models.Ingredient
import tech.mercantec.easyeat.models.Recipe import tech.mercantec.easyeat.models.Recipe
@Serializable @Serializable
@ -10,3 +11,21 @@ data class GenerateRecipeRequest(val dish: String, val language: String, val num
fun generateRecipeWithAI(ctx: Context, title: String, language: String): Recipe { fun generateRecipeWithAI(ctx: Context, title: String, language: String): Recipe {
return requestJson<GenerateRecipeRequest, Recipe>(ctx, "POST", "/api/Recipe/chatbot", GenerateRecipeRequest(title, language, 1, arrayOf())) return requestJson<GenerateRecipeRequest, Recipe>(ctx, "POST", "/api/Recipe/chatbot", GenerateRecipeRequest(title, language, 1, arrayOf()))
} }
fun createRecipe(ctx: Context, recipe: Recipe) {
requestJson<Recipe, Boolean>(ctx, "POST", "/api/recipe/create", recipe)
}
@Serializable
data class GetAllRecipesResponse(val id: Int, val name: String, val description: String)
fun getAllRecipes(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)
}

View File

@ -1,24 +0,0 @@
package tech.mercantec.easyeat.models
import kotlinx.serialization.Serializable
@Serializable
data class CreateRecipe(
val name: String,
val description: String,
val directions: List<CreateDirection>,
val ingredients: List<CreateIngredient>
)
@Serializable
data class CreateDirection(
val instructions: String
)
@Serializable
data class CreateIngredient(
val amount: Double?,
val unit: String?,
val name: String
)

View File

@ -2,10 +2,9 @@ package tech.mercantec.easyeat.models
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@Serializable @Serializable
data class Recipe( data class Recipe(
val id: Int, val id: Int? = null,
val name: String, val name: String,
val description: String, val description: String,
val directions: List<String>, val directions: List<String>,
@ -14,7 +13,7 @@ data class Recipe(
@Serializable @Serializable
data class Ingredient( data class Ingredient(
val id: Int, val id: Int? = null,
val amount: Double?, val amount: Double?,
val unit: String?, val unit: String?,
val name: String val name: String

View File

@ -2,9 +2,7 @@ package tech.mercantec.easyeat.ui.dishes
import android.app.Activity import android.app.Activity
import android.app.ProgressDialog import android.app.ProgressDialog
import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
import android.widget.Button import android.widget.Button
@ -14,15 +12,11 @@ import android.widget.LinearLayout
import android.widget.Spinner import android.widget.Spinner
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContentProviderCompat.requireContext
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.changePassword
import tech.mercantec.easyeat.helpers.createRecipe import tech.mercantec.easyeat.helpers.createRecipe
import tech.mercantec.easyeat.helpers.request import tech.mercantec.easyeat.models.Ingredient
import tech.mercantec.easyeat.models.CreateDirection import tech.mercantec.easyeat.models.Recipe
import tech.mercantec.easyeat.models.CreateIngredient
import tech.mercantec.easyeat.models.CreateRecipe
import kotlin.concurrent.thread import kotlin.concurrent.thread
class CreateDishActivity : AppCompatActivity() { class CreateDishActivity : AppCompatActivity() {
@ -53,7 +47,7 @@ class CreateDishActivity : AppCompatActivity() {
.map { line -> line.trim() } .map { line -> line.trim() }
.filter { it.isNotEmpty() } .filter { it.isNotEmpty() }
val recipe = CreateRecipe( val recipe = Recipe(
name = findViewById<EditText>(R.id.dishName).text.toString().trim(), name = findViewById<EditText>(R.id.dishName).text.toString().trim(),
description = findViewById<EditText>(R.id.dishDescription).text.toString().trim(), description = findViewById<EditText>(R.id.dishDescription).text.toString().trim(),
directions = directions, directions = directions,
@ -107,8 +101,8 @@ class CreateDishActivity : AppCompatActivity() {
ingredientContainer.addView(ingredientRow) ingredientContainer.addView(ingredientRow)
} }
private fun collectIngredients(): List<CreateIngredient> { private fun collectIngredients(): List<Ingredient> {
val ingredients = mutableListOf<CreateIngredient>() val ingredients = mutableListOf<Ingredient>()
for (i in 0 until ingredientContainer.childCount) { for (i in 0 until ingredientContainer.childCount) {
val ingredientView = ingredientContainer.getChildAt(i) val ingredientView = ingredientContainer.getChildAt(i)
@ -125,7 +119,7 @@ class CreateDishActivity : AppCompatActivity() {
// Optional: Only add non-empty rows // Optional: Only add non-empty rows
if (element.isNotEmpty() && amount.isNotEmpty()) { if (element.isNotEmpty() && amount.isNotEmpty()) {
ingredients.add(CreateIngredient(name = element, amount = amount.toDouble(), unit = unit)) ingredients.add(Ingredient(name = element, amount = amount.toDouble(), unit = unit))
} }
} }

View File

@ -15,7 +15,7 @@ import tech.mercantec.easyeat.R
import tech.mercantec.easyeat.databinding.FragmentDishesBinding import tech.mercantec.easyeat.databinding.FragmentDishesBinding
import tech.mercantec.easyeat.helpers.ApiRequestException import tech.mercantec.easyeat.helpers.ApiRequestException
import tech.mercantec.easyeat.helpers.GetAllRecipesResponse import tech.mercantec.easyeat.helpers.GetAllRecipesResponse
import tech.mercantec.easyeat.helpers.getAllRecipies import tech.mercantec.easyeat.helpers.getAllRecipes
import tech.mercantec.easyeat.models.DishListItem import tech.mercantec.easyeat.models.DishListItem
import kotlin.concurrent.thread import kotlin.concurrent.thread
@ -52,7 +52,7 @@ class DishesFragment : Fragment() {
} }
dialogView.findViewById<Button>(R.id.createAIBtn).setOnClickListener { dialogView.findViewById<Button>(R.id.createAIBtn).setOnClickListener {
val intent = Intent(requireContext(), CreateDishAIActivity::class.java) val intent = Intent(requireContext(), GenerateRecipeActivity::class.java)
createDishLauncher.launch(intent) createDishLauncher.launch(intent)
dialog.dismiss() dialog.dismiss()
} }
@ -68,7 +68,7 @@ class DishesFragment : Fragment() {
thread { thread {
val recipes: List<GetAllRecipesResponse> val recipes: List<GetAllRecipesResponse>
try { try {
recipes = getAllRecipies(requireContext()) recipes = getAllRecipes(requireContext())
} catch (e: ApiRequestException) { } catch (e: ApiRequestException) {
activity?.runOnUiThread { activity?.runOnUiThread {
Toast.makeText(requireContext(), e.message, Toast.LENGTH_LONG).show() Toast.makeText(requireContext(), e.message, Toast.LENGTH_LONG).show()

View File

@ -4,20 +4,19 @@ import android.app.ProgressDialog
import android.os.Bundle import android.os.Bundle
import android.widget.Button import android.widget.Button
import android.widget.EditText import android.widget.EditText
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
import tech.mercantec.easyeat.helpers.ApiRequestException import tech.mercantec.easyeat.helpers.ApiRequestException
import tech.mercantec.easyeat.helpers.GenerateRecipeResponse import tech.mercantec.easyeat.helpers.createRecipe
import tech.mercantec.easyeat.helpers.generateRecipeWithAI import tech.mercantec.easyeat.helpers.generateRecipeWithAI
import java.util.Locale import java.util.Locale
import kotlin.concurrent.thread import kotlin.concurrent.thread
class CreateDishAIActivity : AppCompatActivity() { class GenerateRecipeActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.create_dish_ai_form) setContentView(R.layout.activity_generate_recipe)
findViewById<Button>(R.id.generate).setOnClickListener { findViewById<Button>(R.id.generate).setOnClickListener {
val name = findViewById<EditText>(R.id.dish_title).text.toString() val name = findViewById<EditText>(R.id.dish_title).text.toString()
@ -27,21 +26,24 @@ class CreateDishAIActivity : AppCompatActivity() {
progressDialog.show() progressDialog.show()
thread { thread {
val response: GenerateRecipeResponse
try { try {
response = generateRecipeWithAI(this, name, Locale.getDefault().displayLanguage) val recipe = generateRecipeWithAI(this, name, Locale.getDefault().displayLanguage)
runOnUiThread {
progressDialog.setMessage("Saving...")
}
createRecipe(this, recipe)
finish()
} catch (e: ApiRequestException) { } catch (e: ApiRequestException) {
runOnUiThread { runOnUiThread {
Toast.makeText(this, e.message, Toast.LENGTH_LONG).show() Toast.makeText(this, e.message, Toast.LENGTH_LONG).show()
} }
return@thread
} finally { } finally {
progressDialog.hide() runOnUiThread {
} progressDialog.hide()
}
runOnUiThread {
Toast.makeText(this, response.toString(), Toast.LENGTH_LONG).show()
} }
} }
} }

View File

@ -7,19 +7,18 @@ import android.view.ViewGroup
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
import android.widget.TextView import android.widget.TextView
import tech.mercantec.easyeat.R import tech.mercantec.easyeat.R
import tech.mercantec.easyeat.models.Direction
class InstructionsAdapter (context: Context, instructions: List<Direction>) class InstructionsAdapter (context: Context, instructions: List<String>)
: ArrayAdapter<Direction>(context, 0, instructions) { : ArrayAdapter<String>(context, R.layout.activity_dish_details_instructions_list_item, instructions) {
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val ingredient = getItem(position) val instruction = getItem(position)
val view = convertView ?: LayoutInflater.from(context) val view = convertView ?: LayoutInflater.from(context)
.inflate(R.layout.activity_dish_details_instructions_list_item, parent, false) .inflate(R.layout.activity_dish_details_instructions_list_item, parent, false)
val nameView = view.findViewById<TextView>(R.id.instructionText) val nameView = view.findViewById<TextView>(R.id.instructionText)
nameView.text = ingredient?.instruktions ?: "" nameView.text = instruction
return view return view
} }