This commit is contained in:
LilleBRG 2025-05-13 10:56:42 +02:00
commit cb2df85e5b
11 changed files with 125 additions and 37 deletions

View File

@ -0,0 +1,12 @@
package tech.mercantec.easyeat.helpers
import android.content.Context
import kotlinx.serialization.Serializable
import tech.mercantec.easyeat.models.Recipe
@Serializable
data class GenerateRecipeRequest(val dish: String, val language: String, val numberOfRecipes: Int, val allergi: Array<String>)
fun generateRecipeWithAI(ctx: Context, title: String, language: String): Recipe {
return requestJson<GenerateRecipeRequest, Recipe>(ctx, "POST", "/api/Recipe/chatbot", GenerateRecipeRequest(title, language, 1, arrayOf()))
}

View File

@ -8,17 +8,10 @@ data class Recipe(
val id: Int, val id: Int,
val name: String, val name: String,
val description: String, val description: String,
val directions: List<CreateDirection>, val directions: List<String>,
val ingredients: List<CreateIngredient> val ingredients: List<Ingredient>
) )
@Serializable
data class Direction(
val id: Int,
val instruktions: String
)
@Serializable @Serializable
data class Ingredient( data class Ingredient(
val id: Int, val id: Int,

View File

@ -1,16 +1,49 @@
package tech.mercantec.easyeat.ui.dishes package tech.mercantec.easyeat.ui.dishes
import android.app.ProgressDialog
import android.os.Bundle import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.LinearLayout import android.widget.LinearLayout
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.GenerateRecipeResponse
import tech.mercantec.easyeat.helpers.generateRecipeWithAI
import java.util.Locale
import kotlin.concurrent.thread
class CreateDishAIActivity : AppCompatActivity() { class CreateDishAIActivity : 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.create_dish_ai_form)
} findViewById<Button>(R.id.generate).setOnClickListener {
val name = findViewById<EditText>(R.id.dish_title).text.toString()
val progressDialog = ProgressDialog(this)
progressDialog.setMessage("Generating...")
progressDialog.show()
thread {
val response: GenerateRecipeResponse
try {
response = generateRecipeWithAI(this, name, Locale.getDefault().displayLanguage)
} catch (e: ApiRequestException) {
runOnUiThread {
Toast.makeText(this, e.message, Toast.LENGTH_LONG).show()
}
return@thread
} finally {
progressDialog.hide()
}
runOnUiThread {
Toast.makeText(this, response.toString(), Toast.LENGTH_LONG).show()
}
}
}
}
} }

View File

@ -48,11 +48,10 @@ class CreateDishActivity : AppCompatActivity() {
saveButton.setOnClickListener { saveButton.setOnClickListener {
val ingredientList = collectIngredients() val ingredientList = collectIngredients()
val instructions = findViewById<EditText>(R.id.instructions).text.toString().trim() val instructions = findViewById<EditText>(R.id.instructions).text.toString().trim()
val directions: List<CreateDirection> = instructions val directions: List<String> = instructions
.split("\n") .split("\n")
.map { line -> line.trim() } .map { line -> line.trim() }
.filter { it.isNotEmpty() } .filter { it.isNotEmpty() }
.map { line -> CreateDirection(instructions = line) }
val recipe = CreateRecipe( val recipe = CreateRecipe(
name = findViewById<EditText>(R.id.dishName).text.toString().trim(), name = findViewById<EditText>(R.id.dishName).text.toString().trim(),
@ -61,7 +60,6 @@ class CreateDishActivity : AppCompatActivity() {
ingredients = ingredientList ingredients = ingredientList
) )
val progressDialog = ProgressDialog(this) val progressDialog = ProgressDialog(this)
progressDialog.setMessage("Loading...") progressDialog.setMessage("Loading...")
progressDialog.show() progressDialog.show()

View File

@ -39,9 +39,9 @@ class ShoppingItemAdapter(context: Context, items: ArrayList<ShoppingListItem>)
val color = TypedValue() val color = TypedValue()
context.theme.resolveAttribute(R.attr.colorDisabled, color, true) context.theme.resolveAttribute(R.attr.colorDisabled, color, true)
it.setTextColor(ContextCompat.getColor(context, color.resourceId)) it.setTextColor(ContextCompat.getColor(context, color.resourceId))
checkmarkView.visibility = View.VISIBLE
} }
checkmarkView.visibility = View.VISIBLE
} else { } else {
textViews.forEach { textViews.forEach {
it.paintFlags = it.paintFlags and Paint.STRIKE_THRU_TEXT_FLAG.inv() it.paintFlags = it.paintFlags and Paint.STRIKE_THRU_TEXT_FLAG.inv()
@ -49,9 +49,9 @@ class ShoppingItemAdapter(context: Context, items: ArrayList<ShoppingListItem>)
val color = TypedValue() val color = TypedValue()
context.theme.resolveAttribute(android.R.attr.textColorSecondary, color, true) context.theme.resolveAttribute(android.R.attr.textColorSecondary, color, true)
it.setTextColor(ContextCompat.getColor(context, color.resourceId)) it.setTextColor(ContextCompat.getColor(context, color.resourceId))
checkmarkView.visibility = View.INVISIBLE
} }
checkmarkView.visibility = View.INVISIBLE
} }
} }

View File

@ -1,14 +1,42 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout
xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:padding="30dp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<TextView <TextView
android:id="@+id/formforai" android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="FormForAI" android:textAlignment="center"
tools:layout_editor_absoluteX="126dp" android:textSize="24sp"
tools:layout_editor_absoluteY="287dp" /> android:text="@string/ai_generate_recipe_title"
</androidx.constraintlayout.widget.ConstraintLayout> />
<TextView
android:layout_marginTop="20dp"
android:layout_marginStart="2sp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:labelFor="@id/dish_title"
android:text="@string/dish_title_label"
/>
<EditText
android:id="@+id/dish_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:importantForAutofill="no"
android:inputType="text"
/>
<Button
android:id="@+id/generate"
android:layout_marginTop="20sp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/generate_recipe_label"
/>
</LinearLayout>

View File

@ -44,6 +44,9 @@
<string name="search_for_dishes">Search For Dishes</string> <string name="search_for_dishes">Search For Dishes</string>
<string name="manually">Manually</string> <string name="manually">Manually</string>
<string name="create_dish">Create Dish</string> <string name="create_dish">Create Dish</string>
<string name="ai_generate_recipe_title">Generate recipe with AI</string>
<string name="dish_title_label">Name of dish</string>
<string name="generate_recipe_label">Generate</string>
<string-array name="units"> <string-array name="units">
<item></item> <item></item>
<item>g</item> <item>g</item>

View File

@ -40,7 +40,19 @@ namespace API.BusinessLogic
if (recipe == null || recipe.Id == 0) { return new ConflictObjectResult(new { message = "Could not find any recipe" }); } if (recipe == null || recipe.Id == 0) { return new ConflictObjectResult(new { message = "Could not find any recipe" }); }
return new OkObjectResult(recipe); var singleRecipeDTO = new GetSingleRecipeDTO();
singleRecipeDTO.Id = recipe.Id;
singleRecipeDTO.Name = recipe.Name;
singleRecipeDTO.Description = recipe.Description;
singleRecipeDTO.Ingredients = recipe.Ingredients;
singleRecipeDTO.Directions = new List<string>();
foreach (var item in recipe.Directions)
{
string directions = item.Instruktions;
singleRecipeDTO.Directions.Add(directions);
}
return new OkObjectResult(singleRecipeDTO);
} }
/// <summary> /// <summary>
@ -78,7 +90,7 @@ namespace API.BusinessLogic
foreach (var item in recipe.Directions) foreach (var item in recipe.Directions)
{ {
Directions directions = new Directions(); Directions directions = new Directions();
directions.Instruktions = item.Instructions; directions.Instruktions = item;
dish.Directions.Add(directions); dish.Directions.Add(directions);
} }
@ -119,7 +131,7 @@ namespace API.BusinessLogic
foreach (var item in recipe.Directions) foreach (var item in recipe.Directions)
{ {
Directions directions = new Directions(); Directions directions = new Directions();
directions.Instruktions = item.Instructions; directions.Instruktions = item;
dish.Directions.Add(directions); dish.Directions.Add(directions);
} }

View File

@ -1,7 +0,0 @@
namespace API.Models.RecipeModels
{
public class DirectionsDTO
{
public string Instructions { get; set; }
}
}

View File

@ -0,0 +1,16 @@
namespace API.Models.RecipeModels
{
public class GetSingleRecipeDTO
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public List<string> Directions { get; set; }
public List<Ingredient> Ingredients { get; set; }
}
}

View File

@ -6,7 +6,7 @@
public string Description { get; set; } public string Description { get; set; }
public List<DirectionsDTO> Directions { get; set; } public List<string> Directions { get; set; }
public List<IngredientDTO> Ingredients { get; set; } public List<IngredientDTO> Ingredients { get; set; }
} }