From a18984bda0a6702fe7b567e2c630bba8494184ce Mon Sep 17 00:00:00 2001 From: Kirill Kamakin Date: Sun, 4 Dec 2022 19:25:36 +0100 Subject: [PATCH 1/2] Implement displaying ingredient sections --- .../data/recipes/network/FullRecipeInfo.kt | 1 + .../mealient/extensions/ModelMappings.kt | 3 ++ .../recipes/info/RecipeIngredientsAdapter.kt | 3 ++ .../res/layout/view_holder_ingredient.xml | 31 ++++++++++++++++++- .../mealient/test/RecipeImplTestData.kt | 10 ++++++ .../7.json | 12 +++++-- .../recipe/entity/RecipeIngredientEntity.kt | 5 ++- .../v1/models/GetRecipeResponseV1.kt | 1 + 8 files changed, 61 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/gq/kirmanak/mealient/data/recipes/network/FullRecipeInfo.kt b/app/src/main/java/gq/kirmanak/mealient/data/recipes/network/FullRecipeInfo.kt index 83a8628..eb383da 100644 --- a/app/src/main/java/gq/kirmanak/mealient/data/recipes/network/FullRecipeInfo.kt +++ b/app/src/main/java/gq/kirmanak/mealient/data/recipes/network/FullRecipeInfo.kt @@ -18,6 +18,7 @@ data class RecipeIngredientInfo( val quantity: Double?, val unit: String?, val food: String?, + val title: String?, ) data class RecipeInstructionInfo( diff --git a/app/src/main/java/gq/kirmanak/mealient/extensions/ModelMappings.kt b/app/src/main/java/gq/kirmanak/mealient/extensions/ModelMappings.kt index 256b0ab..2f8263c 100644 --- a/app/src/main/java/gq/kirmanak/mealient/extensions/ModelMappings.kt +++ b/app/src/main/java/gq/kirmanak/mealient/extensions/ModelMappings.kt @@ -52,6 +52,7 @@ fun RecipeIngredientInfo.toRecipeIngredientEntity(remoteId: String) = RecipeIngr unit = unit, food = food, quantity = quantity, + title = title, ) fun RecipeInstructionInfo.toRecipeInstructionEntity(remoteId: String) = RecipeInstructionEntity( @@ -129,6 +130,7 @@ fun GetRecipeIngredientResponseV0.toRecipeIngredientInfo() = RecipeIngredientInf unit = null, food = null, quantity = 1.0, + title = null, ) fun GetRecipeInstructionResponseV0.toRecipeInstructionInfo() = RecipeInstructionInfo( @@ -153,6 +155,7 @@ fun GetRecipeIngredientResponseV1.toRecipeIngredientInfo() = RecipeIngredientInf unit = unit?.name, food = food?.name, quantity = quantity, + title = title, ) fun GetRecipeInstructionResponseV1.toRecipeInstructionInfo() = RecipeInstructionInfo( diff --git a/app/src/main/java/gq/kirmanak/mealient/ui/recipes/info/RecipeIngredientsAdapter.kt b/app/src/main/java/gq/kirmanak/mealient/ui/recipes/info/RecipeIngredientsAdapter.kt index 3b3d145..59c9cce 100644 --- a/app/src/main/java/gq/kirmanak/mealient/ui/recipes/info/RecipeIngredientsAdapter.kt +++ b/app/src/main/java/gq/kirmanak/mealient/ui/recipes/info/RecipeIngredientsAdapter.kt @@ -3,6 +3,7 @@ package gq.kirmanak.mealient.ui.recipes.info import android.view.LayoutInflater import android.view.ViewGroup import androidx.annotation.VisibleForTesting +import androidx.core.view.isGone import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView @@ -54,6 +55,8 @@ class RecipeIngredientsAdapter private constructor( fun bind(item: RecipeIngredientEntity) { logger.v { "bind() called with: item = $item" } + binding.sectionGroup.isGone = item.title.isNullOrBlank() + binding.title.text = item.title.orEmpty() binding.checkBox.text = if (disableAmounts) { item.note } else { diff --git a/app/src/main/res/layout/view_holder_ingredient.xml b/app/src/main/res/layout/view_holder_ingredient.xml index 04af9b3..56008cd 100644 --- a/app/src/main/res/layout/view_holder_ingredient.xml +++ b/app/src/main/res/layout/view_holder_ingredient.xml @@ -5,12 +5,41 @@ android:layout_width="match_parent" android:layout_height="wrap_content"> + + + + + + \ No newline at end of file diff --git a/app/src/test/java/gq/kirmanak/mealient/test/RecipeImplTestData.kt b/app/src/test/java/gq/kirmanak/mealient/test/RecipeImplTestData.kt index d7aac50..3409031 100644 --- a/app/src/test/java/gq/kirmanak/mealient/test/RecipeImplTestData.kt +++ b/app/src/test/java/gq/kirmanak/mealient/test/RecipeImplTestData.kt @@ -100,6 +100,7 @@ object RecipeImplTestData { quantity = 1.0, unit = null, food = null, + title = null, ) val BREAD_INGREDIENT = RecipeIngredientInfo( @@ -107,6 +108,7 @@ object RecipeImplTestData { quantity = 1.0, unit = null, food = null, + title = null, ) private val MILK_INGREDIENT = RecipeIngredientInfo( @@ -114,6 +116,7 @@ object RecipeImplTestData { quantity = 1.0, unit = null, food = null, + title = null, ) val MIX_INSTRUCTION = RecipeInstructionInfo( @@ -168,6 +171,7 @@ object RecipeImplTestData { quantity = 1.0, unit = null, food = null, + title = null, ) val CAKE_BREAD_RECIPE_INGREDIENT_ENTITY = RecipeIngredientEntity( @@ -176,6 +180,7 @@ object RecipeImplTestData { quantity = 1.0, unit = null, food = null, + title = null, ) val FULL_CAKE_INFO_ENTITY = FullRecipeEntity( @@ -203,6 +208,7 @@ object RecipeImplTestData { quantity = 1.0, unit = null, food = null, + title = null, ) private val PORRIDGE_SUGAR_RECIPE_INGREDIENT_ENTITY = RecipeIngredientEntity( @@ -211,6 +217,7 @@ object RecipeImplTestData { quantity = 1.0, unit = null, food = null, + title = null, ) private val PORRIDGE_MIX_RECIPE_INSTRUCTION_ENTITY = RecipeInstructionEntity( @@ -306,6 +313,7 @@ object RecipeImplTestData { quantity = 1.0, unit = null, food = null, + title = null, ) val SUGAR_RECIPE_INGREDIENT_RESPONSE_V1 = GetRecipeIngredientResponseV1( @@ -313,6 +321,7 @@ object RecipeImplTestData { quantity = 1.0, unit = null, food = null, + title = null, ) val MILK_RECIPE_INGREDIENT_INFO = RecipeIngredientInfo( @@ -320,6 +329,7 @@ object RecipeImplTestData { quantity = 1.0, unit = null, food = null, + title = null, ) val MIX_RECIPE_INSTRUCTION_RESPONSE_V0 = GetRecipeInstructionResponseV0("Mix the ingredients") diff --git a/database/schemas/gq.kirmanak.mealient.database.AppDb/7.json b/database/schemas/gq.kirmanak.mealient.database.AppDb/7.json index c51d17b..ca613b7 100644 --- a/database/schemas/gq.kirmanak.mealient.database.AppDb/7.json +++ b/database/schemas/gq.kirmanak.mealient.database.AppDb/7.json @@ -2,7 +2,7 @@ "formatVersion": 1, "database": { "version": 7, - "identityHash": "2383ca8fe2fbd04ddaec6d7680de62ad", + "identityHash": "d2679aea13d3c18e58c537164f70e249", "entities": [ { "tableName": "recipe_summaries", @@ -95,7 +95,7 @@ }, { "tableName": "recipe_ingredient", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`local_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `recipe_id` TEXT NOT NULL, `note` TEXT NOT NULL, `food` TEXT, `unit` TEXT, `quantity` REAL)", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`local_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `recipe_id` TEXT NOT NULL, `note` TEXT NOT NULL, `food` TEXT, `unit` TEXT, `quantity` REAL, `title` TEXT)", "fields": [ { "fieldPath": "localId", @@ -132,6 +132,12 @@ "columnName": "quantity", "affinity": "REAL", "notNull": false + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": false } ], "primaryKey": { @@ -179,7 +185,7 @@ "views": [], "setupQueries": [ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '2383ca8fe2fbd04ddaec6d7680de62ad')" + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'd2679aea13d3c18e58c537164f70e249')" ] } } \ No newline at end of file diff --git a/database/src/main/kotlin/gq/kirmanak/mealient/database/recipe/entity/RecipeIngredientEntity.kt b/database/src/main/kotlin/gq/kirmanak/mealient/database/recipe/entity/RecipeIngredientEntity.kt index 440f73f..0e12f1f 100644 --- a/database/src/main/kotlin/gq/kirmanak/mealient/database/recipe/entity/RecipeIngredientEntity.kt +++ b/database/src/main/kotlin/gq/kirmanak/mealient/database/recipe/entity/RecipeIngredientEntity.kt @@ -12,6 +12,7 @@ data class RecipeIngredientEntity( @ColumnInfo(name = "food") val food: String?, @ColumnInfo(name = "unit") val unit: String?, @ColumnInfo(name = "quantity") val quantity: Double?, + @ColumnInfo(name = "title") val title: String?, ) { override fun equals(other: Any?): Boolean { if (this === other) return true @@ -24,6 +25,7 @@ data class RecipeIngredientEntity( if (food != other.food) return false if (unit != other.unit) return false if (quantity != other.quantity) return false + if (title != other.title) return false return true } @@ -33,7 +35,8 @@ data class RecipeIngredientEntity( result = 31 * result + note.hashCode() result = 31 * result + (food?.hashCode() ?: 0) result = 31 * result + (unit?.hashCode() ?: 0) - result = 31 * result + quantity.hashCode() + result = 31 * result + (quantity?.hashCode() ?: 0) + result = 31 * result + (title?.hashCode() ?: 0) return result } } \ No newline at end of file diff --git a/datasource/src/main/kotlin/gq/kirmanak/mealient/datasource/v1/models/GetRecipeResponseV1.kt b/datasource/src/main/kotlin/gq/kirmanak/mealient/datasource/v1/models/GetRecipeResponseV1.kt index 9a37111..eb5e690 100644 --- a/datasource/src/main/kotlin/gq/kirmanak/mealient/datasource/v1/models/GetRecipeResponseV1.kt +++ b/datasource/src/main/kotlin/gq/kirmanak/mealient/datasource/v1/models/GetRecipeResponseV1.kt @@ -24,6 +24,7 @@ data class GetRecipeIngredientResponseV1( @SerialName("unit") val unit: GetRecipeIngredientUnitResponseV1?, @SerialName("food") val food: GetRecipeIngredientFoodResponseV1?, @SerialName("quantity") val quantity: Double?, + @SerialName("title") val title: String?, ) @Serializable From adc635152001973a92dff534fd20055cd690012c Mon Sep 17 00:00:00 2001 From: Kirill Kamakin Date: Tue, 6 Dec 2022 19:01:43 +0100 Subject: [PATCH 2/2] Show ingredients header outside of the card --- .../main/res/layout/fragment_recipe_info.xml | 81 +++++++++---------- 1 file changed, 40 insertions(+), 41 deletions(-) diff --git a/app/src/main/res/layout/fragment_recipe_info.xml b/app/src/main/res/layout/fragment_recipe_info.xml index 7f5e8b8..8228e6c 100644 --- a/app/src/main/res/layout/fragment_recipe_info.xml +++ b/app/src/main/res/layout/fragment_recipe_info.xml @@ -37,7 +37,7 @@ android:layout_height="0dp" android:contentDescription="@string/content_description_fragment_recipe_info_image" android:scaleType="centerCrop" - app:layout_constraintBottom_toTopOf="@+id/title" + app:layout_constraintBottom_toTopOf="@id/title" app:layout_constraintDimensionRatio="2:1" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" @@ -52,10 +52,10 @@ android:layout_marginHorizontal="@dimen/margin_small" android:layout_marginTop="7dp" android:textAppearance="?textAppearanceHeadline6" - app:layout_constraintBottom_toTopOf="@+id/description" - app:layout_constraintEnd_toStartOf="@+id/end_guide" - app:layout_constraintStart_toEndOf="@+id/start_guide" - app:layout_constraintTop_toBottomOf="@+id/image" + app:layout_constraintBottom_toTopOf="@id/description" + app:layout_constraintEnd_toStartOf="@id/end_guide" + app:layout_constraintStart_toEndOf="@id/start_guide" + app:layout_constraintTop_toBottomOf="@id/image" tools:text="Best-Ever Beef Stew" /> + + + app:layout_constraintBottom_toTopOf="@id/instructions_header" + app:layout_constraintEnd_toStartOf="@id/end_guide" + app:layout_constraintStart_toEndOf="@id/start_guide" + app:layout_constraintTop_toBottomOf="@id/ingredients_header"> - - - - - - + android:layout_marginHorizontal="@dimen/margin_small" + app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" + tools:itemCount="3" + tools:listitem="@layout/view_holder_ingredient" /> + app:layout_constraintBottom_toTopOf="@id/instructions_list" + app:layout_constraintEnd_toStartOf="@id/end_guide" + app:layout_constraintStart_toEndOf="@id/start_guide" + app:layout_constraintTop_toBottomOf="@id/ingredients_holder" />