diff --git a/app/build.gradle.kts b/app/build.gradle.kts index d33f45e..905dfd0 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -87,6 +87,7 @@ dependencies { implementation(libs.sharedpreferences) implementation(libs.lifecycle.compose) implementation(libs.runtime.livedata) + implementation(libs.swipe.refresh) // Dagger-hilt implementation("com.google.dagger:hilt-android:2.48") diff --git a/app/src/main/java/com/example/cookbook/MainActivity.kt b/app/src/main/java/com/example/cookbook/MainActivity.kt index 689b3ac..a698efe 100644 --- a/app/src/main/java/com/example/cookbook/MainActivity.kt +++ b/app/src/main/java/com/example/cookbook/MainActivity.kt @@ -4,13 +4,11 @@ import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.hilt.navigation.compose.hiltViewModel -import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.viewmodel.compose.viewModel -import androidx.navigation.NavHostController import androidx.navigation.compose.rememberNavController import com.example.cookbook.presentation.view.navigation.Navigation import com.example.cookbook.presentation.viewmodel.HomeScreenViewModel import com.example.cookbook.presentation.viewmodel.LogInScreenViewModel +import com.example.cookbook.presentation.viewmodel.RecipeDetailScreenViewModel import com.example.cookbook.presentation.viewmodel.RegisterScreenViewModel import com.example.cookbook.ui.theme.CookBookTheme import dagger.hilt.android.AndroidEntryPoint @@ -28,6 +26,7 @@ class MainActivity : ComponentActivity() { val registerScreenViewModel = hiltViewModel() val logInScreenViewModel = hiltViewModel() val homeScreenViewModel = hiltViewModel() + val recipeDetailScreenViewModel = hiltViewModel() logInScreenViewModel.setNavController(navController) @@ -35,9 +34,9 @@ class MainActivity : ComponentActivity() { navController = navController, registerScreenViewModel = registerScreenViewModel, logInScreenViewModel = logInScreenViewModel, + recipeDetailScreenViewModel, homeScreenViewModel ) - } } } diff --git a/app/src/main/java/com/example/cookbook/data/datasource/api/RetrofitApi.kt b/app/src/main/java/com/example/cookbook/data/datasource/api/RetrofitApi.kt index 2ad6b73..c2e4c0a 100644 --- a/app/src/main/java/com/example/cookbook/data/datasource/api/RetrofitApi.kt +++ b/app/src/main/java/com/example/cookbook/data/datasource/api/RetrofitApi.kt @@ -18,6 +18,9 @@ interface RetrofitApi { */ @GET("random") fun getRandomRecipe( - @Query("api_key") apiKey: String + @Query("apiKey") apiKey: String, + @Query("number") number: Int ): Call + + @GET("complexSearch") } \ No newline at end of file diff --git a/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/AnalyzedInstruction.kt b/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/AnalyzedInstruction.kt index 9a1144a..1d36ac2 100644 --- a/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/AnalyzedInstruction.kt +++ b/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/AnalyzedInstruction.kt @@ -1,6 +1,8 @@ package com.example.cookbook.data.models.randomrecipemodel +import com.google.gson.annotations.SerializedName + data class AnalyzedInstruction( - val name: String, - val steps: List + @SerializedName("name") val name : String, + @SerializedName("steps") val steps : List ) \ No newline at end of file diff --git a/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Equipment.kt b/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Equipment.kt index 83868da..10c83c1 100644 --- a/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Equipment.kt +++ b/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Equipment.kt @@ -1,9 +1,11 @@ package com.example.cookbook.data.models.randomrecipemodel +import com.google.gson.annotations.SerializedName + data class Equipment( - val id: Int, - val image: String, - val localizedName: String, - val name: String, - val temperature: Temperature + @SerializedName("id" ) val id : Int, + @SerializedName("image" ) val image : String, + @SerializedName("localizedName") val localizedName : String, + @SerializedName("name" ) val name : String, + @SerializedName("temperature" ) val temperature : Temperature ) \ No newline at end of file diff --git a/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/ExtendedIngredient.kt b/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/ExtendedIngredient.kt index b9cdac6..4040809 100644 --- a/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/ExtendedIngredient.kt +++ b/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/ExtendedIngredient.kt @@ -1,16 +1,18 @@ package com.example.cookbook.data.models.randomrecipemodel +import com.google.gson.annotations.SerializedName + data class ExtendedIngredient( - val aisle: String, - val amount: Double, - val consistency: String, - val id: Int, - val image: String, - val measures: Measures, - val meta: List, - val name: String, - val nameClean: String, - val original: String, - val originalName: String, - val unit: String + @SerializedName("aisle" ) val aisle : String, + @SerializedName("amount" ) val amount : Double, + @SerializedName("consistency" ) val consistency : String, + @SerializedName("id" ) val id : Int, + @SerializedName("image" ) val image : String, + @SerializedName("measures" ) val measures : Measures, + @SerializedName("meta" ) val meta : List, + @SerializedName("name" ) val name : String, + @SerializedName("nameClean" ) val nameClean : String, + @SerializedName("original" ) val original : String, + @SerializedName("originalName" ) val originalName : String, + @SerializedName("unit" ) val unit : String ) \ No newline at end of file diff --git a/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Ingredient.kt b/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Ingredient.kt index 19dd0ea..faea3ce 100644 --- a/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Ingredient.kt +++ b/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Ingredient.kt @@ -1,8 +1,10 @@ package com.example.cookbook.data.models.randomrecipemodel +import com.google.gson.annotations.SerializedName + data class Ingredient( - val id: Int, - val image: String, - val localizedName: String, - val name: String + @SerializedName("id" ) val id : Int, + @SerializedName("image" ) val image : String, + @SerializedName("localizedName" ) val localizedName : String, + @SerializedName("name" ) val name : String ) \ No newline at end of file diff --git a/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Length.kt b/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Length.kt index e1f30d3..97424d9 100644 --- a/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Length.kt +++ b/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Length.kt @@ -1,6 +1,8 @@ package com.example.cookbook.data.models.randomrecipemodel +import com.google.gson.annotations.SerializedName + data class Length( - val number: Int, - val unit: String + @SerializedName("number" ) val number : Int, + @SerializedName("unit" ) val unit : String ) \ No newline at end of file diff --git a/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Measures.kt b/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Measures.kt index 8fb3260..3cd8c1d 100644 --- a/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Measures.kt +++ b/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Measures.kt @@ -1,6 +1,8 @@ package com.example.cookbook.data.models.randomrecipemodel +import com.google.gson.annotations.SerializedName + data class Measures( - val metric: Metric, - val us: Us + @SerializedName("metric" ) val metric : Metric, + @SerializedName("us" ) val us : Us ) \ No newline at end of file diff --git a/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Metric.kt b/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Metric.kt index cbd9efb..998098b 100644 --- a/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Metric.kt +++ b/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Metric.kt @@ -1,7 +1,9 @@ package com.example.cookbook.data.models.randomrecipemodel +import com.google.gson.annotations.SerializedName + data class Metric( - val amount: Double, - val unitLong: String, - val unitShort: String + @SerializedName("amount" ) val amount : Double, + @SerializedName("unitLong" ) val unitLong : String, + @SerializedName("unitShort" ) val unitShort : String ) \ No newline at end of file diff --git a/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/RandomRecipeResponse.kt b/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/RandomRecipeResponse.kt index 59b6c3b..218355d 100644 --- a/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/RandomRecipeResponse.kt +++ b/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/RandomRecipeResponse.kt @@ -1,5 +1,7 @@ package com.example.cookbook.data.models.randomrecipemodel +import com.google.gson.annotations.SerializedName + data class RandomRecipeResponse( - val recipes: List + @SerializedName("recipes") val recipes : List ) \ No newline at end of file diff --git a/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Recipe.kt b/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Recipe.kt index 1e30dc5..12efcea 100644 --- a/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Recipe.kt +++ b/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Recipe.kt @@ -1,41 +1,44 @@ package com.example.cookbook.data.models.randomrecipemodel +import com.google.gson.Gson +import com.google.gson.annotations.SerializedName + data class Recipe( - val aggregateLikes: Int, - val analyzedInstructions: List, - val cheap: Boolean, - val cookingMinutes: Int, - val creditsText: String, - val cuisines: List, - val dairyFree: Boolean, - val diets: List, - val dishTypes: List, - val extendedIngredients: List, - val gaps: String, - val glutenFree: Boolean, - val healthScore: Int, - val id: Int, - val image: String, - val imageType: String, - val instructions: String, - val license: String, - val lowFodmap: Boolean, - val occasions: List, - val originalId: Any, - val preparationMinutes: Int, - val pricePerServing: Double, - val readyInMinutes: Int, - val servings: Int, - val sourceName: String, - val sourceUrl: String, - val spoonacularScore: Double, - val spoonacularSourceUrl: String, - val summary: String, - val sustainable: Boolean, - val title: String, - val vegan: Boolean, - val vegetarian: Boolean, - val veryHealthy: Boolean, - val veryPopular: Boolean, - val weightWatcherSmartPoints: Int -) \ No newline at end of file + @SerializedName("aggregateLikes" ) val aggregateLikes : Int, + @SerializedName("analyzedInstructions" ) val analyzedInstructions : List, + @SerializedName("cheap" ) val cheap : Boolean, + @SerializedName("cookingMinutes" ) val cookingMinutes : Int, + @SerializedName("creditsText" ) val creditsText : String, + @SerializedName("cuisines" ) val cuisines : List, + @SerializedName("dairyFree" ) val dairyFree : Boolean, + @SerializedName("diets" ) val diets : List, + @SerializedName("dishTypes" ) val dishTypes : List, + @SerializedName("extendedIngredients" ) val extendedIngredients : List, + @SerializedName("gaps" ) val gaps : String, + @SerializedName("glutenFree" ) val glutenFree : Boolean, + @SerializedName("healthScore" ) val healthScore : Int, + @SerializedName("id" ) val id : Int, + @SerializedName("image" ) val image : String, + @SerializedName("imageType" ) val imageType : String, + @SerializedName("instructions" ) val instructions : String, + @SerializedName("license" ) val license : String, + @SerializedName("lowFodmap" ) val lowFodmap : Boolean, + @SerializedName("occasions" ) val occasions : List, + @SerializedName("originalId" ) val originalId : Any, + @SerializedName("preparationMinutes" ) val preparationMinutes : Int, + @SerializedName("pricePerServing" ) val pricePerServing : Double, + @SerializedName("readyInMinutes" ) val readyInMinutes : Int, + @SerializedName("servings" ) val servings : Int, + @SerializedName("sourceName" ) val sourceName : String, + @SerializedName("sourceUrl" ) val sourceUrl : String, + @SerializedName("spoonacularScore" ) val spoonacularScore : Double, + @SerializedName("spoonacularSourceUrl" ) val spoonacularSourceUrl : String, + @SerializedName("summary" ) val summary : String, + @SerializedName("sustainable" ) val sustainable : Boolean, + @SerializedName("title" ) val title : String, + @SerializedName("vegan" ) val vegan : Boolean, + @SerializedName("vegetarian" ) val vegetarian : Boolean, + @SerializedName("veryHealthy" ) val veryHealthy : Boolean, + @SerializedName("veryPopular" ) val veryPopular : Boolean, + @SerializedName("weightWatcherSmartPoints" ) val weightWatcherSmartPoints : Int +) diff --git a/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Step.kt b/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Step.kt index 0c674fd..97aa080 100644 --- a/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Step.kt +++ b/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Step.kt @@ -1,9 +1,11 @@ package com.example.cookbook.data.models.randomrecipemodel +import com.google.gson.annotations.SerializedName + data class Step( - val equipment: List, - val ingredients: List, - val length: Length, - val number: Int, - val step: String + @SerializedName("equipment" ) val equipment : List, + @SerializedName("ingredients" ) val ingredients : List, + @SerializedName("length" ) val length : Length, + @SerializedName("number" ) val number : Int, + @SerializedName("step" ) val step : String ) \ No newline at end of file diff --git a/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Temperature.kt b/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Temperature.kt index e0182fe..2c329d2 100644 --- a/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Temperature.kt +++ b/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Temperature.kt @@ -1,6 +1,8 @@ package com.example.cookbook.data.models.randomrecipemodel +import com.google.gson.annotations.SerializedName + data class Temperature( - val number: Double, - val unit: String + @SerializedName("number" ) val number : Double, + @SerializedName("unit" ) val unit : String ) \ No newline at end of file diff --git a/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Us.kt b/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Us.kt index c326744..19a10cd 100644 --- a/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Us.kt +++ b/app/src/main/java/com/example/cookbook/data/models/randomrecipemodel/Us.kt @@ -1,7 +1,9 @@ package com.example.cookbook.data.models.randomrecipemodel +import com.google.gson.annotations.SerializedName + data class Us( - val amount: Double, - val unitLong: String, - val unitShort: String + @SerializedName("amount" ) val amount : Double, + @SerializedName("unitLong" ) val unitLong : String, + @SerializedName("unitShort" ) val unitShort : String ) \ No newline at end of file diff --git a/app/src/main/java/com/example/cookbook/data/reposiitory/RandomRecipeRepository.kt b/app/src/main/java/com/example/cookbook/data/reposiitory/RandomRecipeRepository.kt index 8bd1264..478bdae 100644 --- a/app/src/main/java/com/example/cookbook/data/reposiitory/RandomRecipeRepository.kt +++ b/app/src/main/java/com/example/cookbook/data/reposiitory/RandomRecipeRepository.kt @@ -3,5 +3,5 @@ package com.example.cookbook.data.reposiitory import com.example.cookbook.data.models.randomrecipemodel.RandomRecipeResponse interface RandomRecipeRepository { - suspend fun getRandomRecipe(apiKey: String) : Result + suspend fun getRandomRecipe(apiKey: String, number: Int) : Result } \ No newline at end of file diff --git a/app/src/main/java/com/example/cookbook/data/reposiitory/RandomRecipeRepositoryImpl.kt b/app/src/main/java/com/example/cookbook/data/reposiitory/RandomRecipeRepositoryImpl.kt index a5d79f9..4b74f0b 100644 --- a/app/src/main/java/com/example/cookbook/data/reposiitory/RandomRecipeRepositoryImpl.kt +++ b/app/src/main/java/com/example/cookbook/data/reposiitory/RandomRecipeRepositoryImpl.kt @@ -2,20 +2,21 @@ package com.example.cookbook.data.reposiitory import com.example.cookbook.data.datasource.api.RetrofitApi import com.example.cookbook.data.models.randomrecipemodel.RandomRecipeResponse +import retrofit2.HttpException import retrofit2.awaitResponse +import java.io.IOException class RandomRecipeRepositoryImpl( private val retrofitApi: RetrofitApi ) : RandomRecipeRepository { - /* - override suspend fun getRandomRecipe(apiKey: String): Result { + override suspend fun getRandomRecipe(apiKey: String, number: Int): + Result { return try { - val response = retrofitApi.getRandomRecipe(apiKey).awaitResponse() - Log.d("RepoImpl", "getRandomRecipe is called of retrofitApi") - Log.d("RepoImpl", "Request Parameters: apiKey - $apiKey") - Log.d("RepoImpl", "response : ${response.body()}") + val response = retrofitApi + .getRandomRecipe(apiKey, number) + .awaitResponse() + if (response.isSuccessful) { - Log.d("ResponseStatus", "response status is : ${response.message()}") val data = response.body() if (data != null) { Result.success(data) @@ -23,36 +24,18 @@ class RandomRecipeRepositoryImpl( Result.failure(Exception("Response body is null")) } } else { - Result.failure(Exception("Failed to fetch the network data with status code: ${response.code()}")) + Result.failure(Exception("Failed to fetch the network " + + "data with status code: ${response.code()}")) } } catch (e: Exception) { e.printStackTrace() - Log.e("RandomRecipeRepository", "Exception occurred: ${e.message}") Result.failure(e) } catch (ioException: IOException) { ioException.printStackTrace() - Log.e("RandomRecipeRepository", "Exception occurred: ${ioException.message}") Result.failure(ioException) } catch (httpException: HttpException) { httpException.printStackTrace() - Log.e("RandomRecipeRepository", "Exception occurred: ${httpException.message}") Result.failure(httpException) } } - - */ - override suspend fun getRandomRecipe(apiKey: String): Result { - return try { - val response = retrofitApi.getRandomRecipe(apiKey).awaitResponse() // Await the asynchronous response - if (response.isSuccessful) { - Result.success(response.body()!!) - } else { - Result.failure(Exception("Failed to fetch recipe (code: ${response.code()})")) // Include error code - } - } catch (e: Exception) { - Result.failure(e) // Handle other exceptions - } - } - - } \ No newline at end of file diff --git a/app/src/main/java/com/example/cookbook/di/MainModule.kt b/app/src/main/java/com/example/cookbook/di/MainModule.kt index 9a91fa3..0f51d14 100644 --- a/app/src/main/java/com/example/cookbook/di/MainModule.kt +++ b/app/src/main/java/com/example/cookbook/di/MainModule.kt @@ -1,6 +1,5 @@ package com.example.cookbook.di -import android.util.Log import com.example.cookbook.data.datasource.api.RetrofitApi import com.example.cookbook.data.reposiitory.RandomRecipeRepository import com.example.cookbook.data.reposiitory.RandomRecipeRepositoryImpl @@ -26,8 +25,6 @@ class MainModule { .addConverterFactory(GsonConverterFactory.create()) .build() } catch (e: IllegalArgumentException) { - // Handle IllegalArgumentException - Log.e("MainModule", "Error creating Retrofit instance: ${e.message}") throw e } } @@ -38,8 +35,6 @@ class MainModule { return try { retrofit.create(RetrofitApi::class.java) } catch (e: IllegalArgumentException) { - // Handle IllegalArgumentException - Log.e("MainModule", "Error creating RetrofitApi instance: ${e.message}") throw e } } diff --git a/app/src/main/java/com/example/cookbook/presentation/view/LogInScreen.kt b/app/src/main/java/com/example/cookbook/presentation/view/LogInScreen.kt index 0dc8e70..4b2a646 100644 --- a/app/src/main/java/com/example/cookbook/presentation/view/LogInScreen.kt +++ b/app/src/main/java/com/example/cookbook/presentation/view/LogInScreen.kt @@ -1,6 +1,6 @@ package com.example.cookbook.presentation.view -import android.util.Log +import android.widget.Toast import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* import androidx.compose.material3.Divider @@ -21,10 +21,10 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.lifecycle.Observer import androidx.navigation.NavHostController -import com.example.cookbook.presentation.utils.PreferenceManager +import com.example.cookbook.utils.LogInResult +import com.example.cookbook.utils.PreferenceManager import com.example.cookbook.presentation.view.components.CustomButton import com.example.cookbook.presentation.view.components.CustomTextField -import com.example.cookbook.presentation.viewmodel.LogInResult import com.example.cookbook.presentation.viewmodel.LogInScreenViewModel import com.example.cookbook.ui.theme.ButtonColor @@ -34,17 +34,19 @@ fun LogInScreen( navController: NavHostController ) { val context = LocalContext.current - var email by remember { mutableStateOf("") } var password by remember { mutableStateOf("") } - var passwordLengthError by remember { mutableStateOf("") } - val preferenceManager = remember { PreferenceManager(context) } var loggedIn by remember { - mutableStateOf( preferenceManager.getBoolean("loggedIn", false)) + mutableStateOf( + preferenceManager + .getBoolean( + "loggedIn", + false + ) + ) } - Log.d("LogInScreen", "loggedIn value : $loggedIn") DisposableEffect(Unit) { val observer = Observer { logInResult -> @@ -52,7 +54,7 @@ fun LogInScreen( is LogInResult.Success -> { loggedIn = true preferenceManager.saveBoolean("loggedIn", true) - navController.navigate("HomeScreen") + navController.navigate("HomeScreen/${email}") } is LogInResult.Failure -> { loggedIn = false @@ -99,7 +101,7 @@ fun LogInScreen( value = password, onValueChange = { password = it - passwordLengthError = if (password.length < 6) "Password should atleast be of 6 characters" else "" + passwordLengthError = if (password.length < 6) "Password should at least be of 6 characters" else "" }, placeHolder = "Password", keyboardType = KeyboardType.Password @@ -118,7 +120,11 @@ fun LogInScreen( CustomButton( onClick = { - logInScreenViewModel.logInUser(context, email, password) + try { + logInScreenViewModel.logInUser(context, email, password) + } catch (e : Exception) { + Toast.makeText(context, "Wrong credentials", Toast.LENGTH_LONG).show() + } }, text = "Sign In" ) @@ -141,7 +147,7 @@ fun LogInScreen( text = "Sign Up", fontWeight = FontWeight.Bold, color = ButtonColor, - modifier = Modifier.clickable { navController.navigate("RegisterScreen") } + modifier = Modifier.clickable { navController.navigate("RegisterScreen/{name}") } ) } } diff --git a/app/src/main/java/com/example/cookbook/presentation/view/RegisterScreen.kt b/app/src/main/java/com/example/cookbook/presentation/view/RegisterScreen.kt index 5ded101..6d33fd2 100644 --- a/app/src/main/java/com/example/cookbook/presentation/view/RegisterScreen.kt +++ b/app/src/main/java/com/example/cookbook/presentation/view/RegisterScreen.kt @@ -3,7 +3,6 @@ package com.example.cookbook.presentation.view import android.widget.Toast import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* -import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material3.Divider import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -21,17 +20,19 @@ import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.lifecycle.Observer +import androidx.navigation.NavBackStackEntry import androidx.navigation.NavHostController +import com.example.cookbook.utils.RegistrationResult import com.example.cookbook.presentation.view.components.CustomButton import com.example.cookbook.presentation.view.components.CustomTextField import com.example.cookbook.presentation.viewmodel.RegisterScreenViewModel -import com.example.cookbook.presentation.viewmodel.RegistrationResult import com.example.cookbook.ui.theme.ButtonColor @Composable fun RegisterScreen( registerScreenViewModel: RegisterScreenViewModel, - navController: NavHostController + navController: NavHostController, + backStackEntry: NavBackStackEntry ) { val context = LocalContext.current @@ -46,7 +47,7 @@ fun RegisterScreen( val observer = Observer { result -> when(result) { is RegistrationResult.Success -> { - navController.navigate("HomeScreen") + navController.navigate("HomeScreen/${name}") } is RegistrationResult.Failure -> { Toast.makeText(context, result.errorMessage, Toast.LENGTH_LONG).show() @@ -136,9 +137,12 @@ fun RegisterScreen( CustomButton( onClick = { - if (confirmPassword == password) { - - registerScreenViewModel.registerUser(context, name, email, password) + try { + if (confirmPassword == password) { + registerScreenViewModel.registerUser(context, name, email, password) + } + } catch (e: Exception) { + Toast.makeText(context, "Fill all the credentials", Toast.LENGTH_LONG).show() } }, text = "Sign Up" diff --git a/app/src/main/java/com/example/cookbook/presentation/view/components/Buttons.kt b/app/src/main/java/com/example/cookbook/presentation/view/components/Buttons.kt index 191ed0a..dd85e42 100644 --- a/app/src/main/java/com/example/cookbook/presentation/view/components/Buttons.kt +++ b/app/src/main/java/com/example/cookbook/presentation/view/components/Buttons.kt @@ -12,7 +12,6 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import com.example.cookbook.ui.theme.ButtonColor - @Composable fun CustomButton( onClick: () -> Unit, diff --git a/app/src/main/java/com/example/cookbook/presentation/view/components/SideNavDrawer.kt b/app/src/main/java/com/example/cookbook/presentation/view/components/SideNavDrawer.kt new file mode 100644 index 0000000..db5a7ff --- /dev/null +++ b/app/src/main/java/com/example/cookbook/presentation/view/components/SideNavDrawer.kt @@ -0,0 +1,64 @@ +package com.example.cookbook.presentation.view.components + +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Divider +import androidx.compose.material3.DrawerValue +import androidx.compose.material3.ModalDrawerSheet +import androidx.compose.material3.ModalNavigationDrawer +import androidx.compose.material3.NavigationDrawerItem +import androidx.compose.material3.Text +import androidx.compose.material3.rememberDrawerState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.unit.dp +import androidx.navigation.NavHostController +import com.example.cookbook.utils.PreferenceManager + +@Composable +fun SideNavDrawer( + isDrawerOpen: Boolean, + modifier: Modifier = Modifier, + navController: NavHostController, + onDrawerStateChange: (Boolean) -> Unit, +) { + val context = LocalContext.current + val preferenceManager = remember { PreferenceManager(context) } + + val drawerState = + rememberDrawerState( + initialValue = + if (isDrawerOpen) DrawerValue.Open + else DrawerValue.Closed) + + LaunchedEffect(isDrawerOpen) { + if (isDrawerOpen) { + drawerState.open() + } else { + drawerState.close() + } + } + + ModalNavigationDrawer( + drawerState = drawerState, + modifier = modifier, + drawerContent = { + ModalDrawerSheet { + Text("Menu", modifier = Modifier.padding(16.dp)) + Divider() + NavigationDrawerItem( + label = { Text(text = "Log Out") }, + selected = false, + onClick = { + preferenceManager.saveBoolean("loggedIn", false) + navController.navigate("logInScreen") + } + ) + } + } + ) { + onDrawerStateChange(drawerState.isOpen) + } +} diff --git a/app/src/main/java/com/example/cookbook/presentation/view/components/TextFields.kt b/app/src/main/java/com/example/cookbook/presentation/view/components/TextFields.kt index 0e7c18a..ae0bfc3 100644 --- a/app/src/main/java/com/example/cookbook/presentation/view/components/TextFields.kt +++ b/app/src/main/java/com/example/cookbook/presentation/view/components/TextFields.kt @@ -19,7 +19,6 @@ import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.unit.dp - @OptIn(ExperimentalMaterial3Api::class) @Composable fun CustomTextField( diff --git a/app/src/main/java/com/example/cookbook/presentation/view/homescreen/Categories.kt b/app/src/main/java/com/example/cookbook/presentation/view/homescreen/Categories.kt index 2a74c7f..e665a3a 100644 --- a/app/src/main/java/com/example/cookbook/presentation/view/homescreen/Categories.kt +++ b/app/src/main/java/com/example/cookbook/presentation/view/homescreen/Categories.kt @@ -5,7 +5,6 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding @@ -18,11 +17,8 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.painter.Painter -import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.example.cookbook.R @Composable fun CategoriesList( diff --git a/app/src/main/java/com/example/cookbook/presentation/view/homescreen/CustomSearchBar.kt b/app/src/main/java/com/example/cookbook/presentation/view/homescreen/CustomSearchBar.kt index f8fd34e..52c42a0 100644 --- a/app/src/main/java/com/example/cookbook/presentation/view/homescreen/CustomSearchBar.kt +++ b/app/src/main/java/com/example/cookbook/presentation/view/homescreen/CustomSearchBar.kt @@ -3,22 +3,16 @@ package com.example.cookbook.presentation.view.homescreen import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Search -import androidx.compose.material3.Card -import androidx.compose.material3.CardElevation import androidx.compose.material3.Icon import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text -import androidx.compose.material3.TextField -import androidx.compose.material3.TextFieldDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -32,8 +26,6 @@ import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.navigation.NavController import androidx.navigation.NavHostController import com.example.cookbook.R diff --git a/app/src/main/java/com/example/cookbook/presentation/view/homescreen/HeaderText.kt b/app/src/main/java/com/example/cookbook/presentation/view/homescreen/HeaderText.kt index 6b073dd..6dbe04a 100644 --- a/app/src/main/java/com/example/cookbook/presentation/view/homescreen/HeaderText.kt +++ b/app/src/main/java/com/example/cookbook/presentation/view/homescreen/HeaderText.kt @@ -1,49 +1,30 @@ package com.example.cookbook.presentation.view.homescreen import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.example.cookbook.R -import com.example.cookbook.ui.theme.ButtonColor @Composable -fun HeaderText( - name: String -) { +fun HeaderText(name: String?) { Column( modifier = Modifier .fillMaxWidth() .padding(10.dp) ) { - Row( - modifier = Modifier.fillMaxWidth() - ) { - Text( - text = stringResource(id = R.string.header_text1), - fontWeight = FontWeight.ExtraBold, - fontSize = 30.sp - ) - Spacer(modifier = Modifier.width(12.dp)) - Text( - text = name, - fontWeight = FontWeight.ExtraBold, - fontSize = 30.sp, - color = ButtonColor - ) - } + Text( + text = stringResource(id = R.string.header_text1), + fontWeight = FontWeight.ExtraBold, + fontSize = 30.sp + ) Text( text = stringResource(id = R.string.header_text2), color = Color.Gray, @@ -56,9 +37,3 @@ fun HeaderText( ) } } - -@Preview(showBackground = true) -@Composable -fun PreviewHeaderText() { - HeaderText("Rohan") -} \ No newline at end of file diff --git a/app/src/main/java/com/example/cookbook/presentation/view/homescreen/HomeScreen.kt b/app/src/main/java/com/example/cookbook/presentation/view/homescreen/HomeScreen.kt index e8428da..f210e73 100644 --- a/app/src/main/java/com/example/cookbook/presentation/view/homescreen/HomeScreen.kt +++ b/app/src/main/java/com/example/cookbook/presentation/view/homescreen/HomeScreen.kt @@ -1,70 +1,149 @@ package com.example.cookbook.presentation.view.homescreen -import android.util.Log -import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Menu import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Scaffold import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Modifier -import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.navigation.NavHostController import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment +import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource +import androidx.navigation.NavBackStackEntry import com.example.cookbook.R +import com.example.cookbook.presentation.view.components.SideNavDrawer +import com.example.cookbook.presentation.view.recipedetailsscreen.ScrollContent import com.example.cookbook.presentation.viewmodel.HomeScreenViewModel +import com.example.cookbook.presentation.viewmodel.RecipeDetailScreenViewModel +import com.example.cookbook.ui.theme.ButtonColor +import com.google.accompanist.swiperefresh.SwipeRefresh +import com.google.accompanist.swiperefresh.rememberSwipeRefreshState +import kotlinx.coroutines.launch +@OptIn(ExperimentalMaterial3Api::class) @Composable fun HomeScreen( navController: NavHostController, - homeScreenViewModel: HomeScreenViewModel + homeScreenViewModel: HomeScreenViewModel, + recipeDetailScreenViewModel: RecipeDetailScreenViewModel, + backStackEntry: NavBackStackEntry ) { + val apiKey = stringResource(id = R.string.api_key) + val isLoading by homeScreenViewModel.isLoading.collectAsState(initial = false) - Log.d("HomeScreen", "isLoading status : $isLoading") val popularItems by homeScreenViewModel.popularItems.collectAsState(emptyList()) - Log.d("HomeScreen", "list of recipes : $popularItems") + var isDrawerOpen by remember { mutableStateOf(false)} + val pullRefreshState = rememberSwipeRefreshState(isRefreshing = false) + var isInitialFetchedCompleted by rememberSaveable { mutableStateOf(false) } + val scope = rememberCoroutineScope() + val name = backStackEntry.arguments?.getString("name") - Column( - modifier = Modifier.fillMaxSize(), - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally - ) { - HeaderText(name = "Rohan") - Spacer(modifier = Modifier.height(10.dp)) - Text( - text = "Recipes", - modifier = Modifier.padding(horizontal = 30.dp), - fontWeight = FontWeight.Bold, - fontSize = 20.sp - ) + Scaffold( + topBar = { + TopAppBar( + navigationIcon = { + IconButton(onClick = { + isDrawerOpen = !isDrawerOpen + }) { + Icon( + Icons.Default.Menu, + contentDescription = null, + tint = Color.White, + modifier = Modifier.size(40.dp) + ) + } + }, + title = { Text(text = "CookBook") }, + colors = TopAppBarDefaults.topAppBarColors( + containerColor = ButtonColor, + titleContentColor = Color.White + ) + ) + }, + ) { innerPadding -> + SwipeRefresh( + state = pullRefreshState, + onRefresh = { + scope.launch { + homeScreenViewModel + .getRandomRecipe( + apiKey = apiKey, + number = 20 + ) + } + } + ) { - if (isLoading) { - CircularProgressIndicator(modifier = Modifier.padding(16.dp)) - } else { - if (popularItems.isNotEmpty()) { - PopularItems(popularItems = popularItems) - } else { - Text( - text = "No recipes found", - modifier = Modifier.padding(horizontal = 30.dp), - fontSize = 16.sp + ScrollContent(padding = innerPadding) + Box(modifier = Modifier.fillMaxSize()) { + if (isLoading) { + CircularProgressIndicator( + modifier = Modifier + .padding(16.dp) + .align(Alignment.Center) ) + } else { + Column( + modifier = Modifier + .fillMaxSize() + .padding(innerPadding), + ) { + + if (popularItems.isNotEmpty()) { + PopularItems( + popularItems = popularItems, + recipeDetailScreenViewModel, + navController, + name + ) + } else { + Text( + text = "No recipes found", + modifier = Modifier.padding(horizontal = 30.dp), + fontSize = 16.sp + ) + } + } + } + if (isDrawerOpen) { + SideNavDrawer( + isDrawerOpen = isDrawerOpen, + modifier = Modifier.padding(innerPadding), + navController + ) { drawerState -> + isDrawerOpen = drawerState + } } } + } } - val apiKey = stringResource(id = R.string.api_key) - LaunchedEffect(key1 = Unit) { - homeScreenViewModel.getRandomRecipe(apiKey = apiKey) - Log.d("HomeScreen", "Calling the viewmodel getRandomRecipe with apiKey : $apiKey") + if (!isInitialFetchedCompleted) { + LaunchedEffect(Unit) { + homeScreenViewModel.getRandomRecipe(apiKey = apiKey, number = 20) + isInitialFetchedCompleted = true + } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/example/cookbook/presentation/view/homescreen/PopularItems.kt b/app/src/main/java/com/example/cookbook/presentation/view/homescreen/PopularItems.kt index 8ec30a0..d7d1dc8 100644 --- a/app/src/main/java/com/example/cookbook/presentation/view/homescreen/PopularItems.kt +++ b/app/src/main/java/com/example/cookbook/presentation/view/homescreen/PopularItems.kt @@ -1,8 +1,8 @@ package com.example.cookbook.presentation.view.homescreen -import android.util.Log import androidx.compose.foundation.Image import androidx.compose.foundation.background +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -28,23 +28,41 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.navigation.NavHostController import coil.compose.rememberImagePainter import com.example.cookbook.data.models.randomrecipemodel.Recipe +import com.example.cookbook.presentation.viewmodel.RecipeDetailScreenViewModel @Composable fun PopularItems( - popularItems: List + popularItems: List, + recipeDetailScreenViewModel: RecipeDetailScreenViewModel, + navController: NavHostController, + name: String? ) { LazyColumn( modifier = Modifier.padding(horizontal = 16.dp) ){ + item {HeaderText(name = name)} + item { + Text( + text = "Recipes", + modifier = Modifier.padding(horizontal = 30.dp), + fontWeight = FontWeight.Bold, + fontSize = 30.sp + ) + } items(popularItems) { recipe -> - Log.d("PopularItems", "recipe : $recipe") DishCard( recipe = recipe, - onClick = {/* Handle on click here */} + onClick = { + recipeDetailScreenViewModel.setRecipe(recipe) + navController.navigate("RecipeDetailScreen") + } ) } } @@ -60,11 +78,12 @@ fun DishCard( .fillMaxWidth() .padding(horizontal = 4.dp, vertical = 8.dp) .background(Color.White, shape = RoundedCornerShape(16.dp)) + .clickable { onClick() } ) { Column( modifier = Modifier.fillMaxSize() ) { - // Background image of dish + Box( modifier = Modifier .fillMaxWidth() @@ -72,30 +91,28 @@ fun DishCard( .clip(RoundedCornerShape(16.dp)) ) { Image( - painter = rememberImagePainter(recipe.image), // Use Coil or other image loading library + painter = rememberImagePainter(recipe.image), contentDescription = null, modifier = Modifier.fillMaxSize(), contentScale = ContentScale.Crop ) } - recipe.title?.let { - Text( - text = it, - modifier = Modifier - .padding(vertical = 8.dp) - .fillMaxWidth(), - textAlign = TextAlign.Center, - style = MaterialTheme.typography.bodyMedium - ) - } + Text( + text = recipe.title, + modifier = Modifier + .padding(vertical = 8.dp) + .fillMaxWidth(), + textAlign = TextAlign.Center, + style = MaterialTheme.typography.bodyMedium + ) Row( verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp) ) { - // Display vegetarian icon if recipe is vegetarian - if (recipe.vegetarian == true) { + + if (recipe.vegetarian) { Icon( imageVector = Icons.Default.CheckCircle, contentDescription = null, @@ -113,7 +130,6 @@ fun DishCard( Spacer(modifier = Modifier.width(4.dp)) } - // Display time to make Icon( imageVector = Icons.Default.DateRange, contentDescription = null, diff --git a/app/src/main/java/com/example/cookbook/presentation/view/navigation/Navigation.kt b/app/src/main/java/com/example/cookbook/presentation/view/navigation/Navigation.kt index e521aa3..75da0a2 100644 --- a/app/src/main/java/com/example/cookbook/presentation/view/navigation/Navigation.kt +++ b/app/src/main/java/com/example/cookbook/presentation/view/navigation/Navigation.kt @@ -6,12 +6,14 @@ import androidx.compose.ui.platform.LocalContext import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable -import com.example.cookbook.presentation.utils.PreferenceManager +import com.example.cookbook.utils.PreferenceManager import com.example.cookbook.presentation.view.homescreen.HomeScreen import com.example.cookbook.presentation.view.LogInScreen import com.example.cookbook.presentation.view.RegisterScreen +import com.example.cookbook.presentation.view.recipedetailsscreen.RecipeDetailScreen import com.example.cookbook.presentation.viewmodel.HomeScreenViewModel import com.example.cookbook.presentation.viewmodel.LogInScreenViewModel +import com.example.cookbook.presentation.viewmodel.RecipeDetailScreenViewModel import com.example.cookbook.presentation.viewmodel.RegisterScreenViewModel @Composable @@ -19,6 +21,7 @@ fun Navigation( navController: NavHostController, registerScreenViewModel: RegisterScreenViewModel, logInScreenViewModel: LogInScreenViewModel, + recipeDetailScreenViewModel: RecipeDetailScreenViewModel, homeScreenViewModel: HomeScreenViewModel ) { @@ -32,16 +35,19 @@ fun Navigation( NavHost( navController = navController, - startDestination = if (loggedIn) "HomeScreen" else "logInScreen" + startDestination = if (loggedIn) "HomeScreen/{name}" else "logInScreen" ) { composable("logInScreen") { LogInScreen(logInScreenViewModel, navController) } - composable("RegisterScreen") { - RegisterScreen(registerScreenViewModel, navController) + composable("RegisterScreen/{name}") {backStackEntry -> + RegisterScreen(registerScreenViewModel, navController, backStackEntry) } - composable("HomeScreen") { - HomeScreen(navController, homeScreenViewModel) + composable("HomeScreen/{name}") {backStackEntry -> + HomeScreen(navController, homeScreenViewModel, recipeDetailScreenViewModel, backStackEntry) + } + composable("RecipeDetailScreen") {backStackEntry -> + RecipeDetailScreen(recipeDetailScreenViewModel, backStackEntry, navController) } } } \ No newline at end of file diff --git a/app/src/main/java/com/example/cookbook/presentation/view/recipedetailsscreen/Header.kt b/app/src/main/java/com/example/cookbook/presentation/view/recipedetailsscreen/Header.kt new file mode 100644 index 0000000..8a99244 --- /dev/null +++ b/app/src/main/java/com/example/cookbook/presentation/view/recipedetailsscreen/Header.kt @@ -0,0 +1,103 @@ +package com.example.cookbook.presentation.view.recipedetailsscreen + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.example.cookbook.presentation.viewmodel.RecipeDetailScreenViewModel +import com.example.cookbook.ui.theme.ButtonColor + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun Header( + recipeDetailsScreenViewModel: RecipeDetailScreenViewModel, + onBackClick: () -> Unit +) { + val selectedRecipe = + recipeDetailsScreenViewModel + .selectedRecipe + .collectAsState() + .value + + Scaffold( + topBar = { + TopAppBar( + navigationIcon = { + IconButton(onClick = { onBackClick() }) { + Icon( + Icons.Default.ArrowBack, + contentDescription = null + ) + } + }, + title = { Text(text = "Details") }, + colors = TopAppBarDefaults + .topAppBarColors( + containerColor = ButtonColor, + titleContentColor = Color.White + ) + ) + } + ) { innerPadding -> + if (selectedRecipe != null) { + Column(modifier = Modifier + .padding(innerPadding) + .fillMaxSize() + .verticalScroll( + rememberScrollState() + )) { + ScrollContent(innerPadding) + Name(recipeDetailsScreenViewModel) + ImageViewer(recipeDetailsScreenViewModel) + Informations(recipeDetailsScreenViewModel) + Ingredients(selectedRecipe = selectedRecipe) + Instructions(recipeDetailsScreenViewModel) + } + } + } +} + +@Composable +fun ScrollContent(padding: PaddingValues) {} + +@Composable +fun Name(recipeDetailsScreenViewModel: RecipeDetailScreenViewModel) { + val selectedRecipe = recipeDetailsScreenViewModel.selectedRecipe.collectAsState().value + val title = selectedRecipe?.title + + Column( + modifier = Modifier.padding(20.dp) + ) { + Text( + text = "Name", + fontSize = 30.sp, + fontWeight = FontWeight.Bold + ) + Spacer(modifier = Modifier.height(10.dp)) + Text( + text = title.toString(), + fontSize = 20.sp, + color = Color.Gray + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/cookbook/presentation/view/recipedetailsscreen/ImageViewer.kt b/app/src/main/java/com/example/cookbook/presentation/view/recipedetailsscreen/ImageViewer.kt new file mode 100644 index 0000000..8ac0b2f --- /dev/null +++ b/app/src/main/java/com/example/cookbook/presentation/view/recipedetailsscreen/ImageViewer.kt @@ -0,0 +1,40 @@ +package com.example.cookbook.presentation.view.recipedetailsscreen + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.unit.dp +import coil.compose.rememberImagePainter +import com.example.cookbook.presentation.viewmodel.RecipeDetailScreenViewModel + +@Composable +fun ImageViewer( + recipeDetailScreenViewModel: RecipeDetailScreenViewModel +) { + val selectedRecipe = recipeDetailScreenViewModel.selectedRecipe.collectAsState().value + val image = selectedRecipe?.image + + Box( + modifier = Modifier + .fillMaxWidth() + .height(300.dp) + .padding(20.dp) + .clip(RoundedCornerShape(16.dp)) + ) { + Image( + painter = rememberImagePainter(image), + contentDescription = null, + modifier = Modifier.fillMaxSize(), + contentScale = ContentScale.Crop + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/cookbook/presentation/view/recipedetailsscreen/Informations.kt b/app/src/main/java/com/example/cookbook/presentation/view/recipedetailsscreen/Informations.kt new file mode 100644 index 0000000..dab74f5 --- /dev/null +++ b/app/src/main/java/com/example/cookbook/presentation/view/recipedetailsscreen/Informations.kt @@ -0,0 +1,231 @@ +package com.example.cookbook.presentation.view.recipedetailsscreen + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.example.cookbook.presentation.viewmodel.RecipeDetailScreenViewModel +import com.example.cookbook.ui.theme.BoxColor +import com.example.cookbook.ui.theme.BoxTextColor + +@Composable +fun Informations( + recipeDetailScreenViewModel: RecipeDetailScreenViewModel +) { + val selectedRecipe = recipeDetailScreenViewModel.selectedRecipe.collectAsState().value + + Box( + modifier = Modifier.fillMaxSize() + .clip(RoundedCornerShape(16.dp)) + .background(BoxColor) + ) { + Column ( + modifier = Modifier + .fillMaxWidth() + .padding(20.dp) + ) { + Text( + text = "Information", + fontSize = 30.sp, + fontWeight = FontWeight.Bold + ) + Spacer(modifier = Modifier.height(10.dp)) + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text( + text = "Number of Servings", + color = BoxTextColor + ) + Text( + text = selectedRecipe?.servings.toString(), + color = BoxTextColor + ) + } + Spacer(modifier = Modifier.height(10.dp)) + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text( + text = "Price Per Servings", + color = BoxTextColor + ) + Text( + text = selectedRecipe?.pricePerServing.toString() + "$", + color = BoxTextColor + ) + } + Spacer(modifier = Modifier.height(10.dp)) + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text( + text = "Cooking Minutes", + color = BoxTextColor + ) + Text( + text = selectedRecipe?.cookingMinutes.toString(), + color = BoxTextColor + ) + } + Spacer(modifier = Modifier.height(10.dp)) + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text( + text = "Dairy Free ?", + color = BoxTextColor + ) + Text( + text = selectedRecipe?.dairyFree.toString(), + color = BoxTextColor + ) + } + Spacer(modifier = Modifier.height(10.dp)) + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text( + text = "Gluten Free ?", + color = BoxTextColor + ) + Text( + text = selectedRecipe?.glutenFree.toString(), + color = BoxTextColor + ) + } + Spacer(modifier = Modifier.height(10.dp)) + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text( + text = "Health Score", + color = BoxTextColor + ) + Text( + text = selectedRecipe?.healthScore.toString(), + color = BoxTextColor + ) + } + Spacer(modifier = Modifier.height(10.dp)) + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text( + text = "Preparation Minutes", + color = BoxTextColor + ) + Text( + text = selectedRecipe?.preparationMinutes.toString(), + color = BoxTextColor + ) + } + Spacer(modifier = Modifier.height(10.dp)) + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text( + text = "Ready in Minutes", + color = BoxTextColor + ) + Text( + text = selectedRecipe?.servings.toString(), + color = BoxTextColor + ) + } + Spacer(modifier = Modifier.height(10.dp)) + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text( + text = "Vegan", + color = BoxTextColor + ) + Text( + text = selectedRecipe?.vegan.toString(), + color = BoxTextColor + ) + } + Spacer(modifier = Modifier.height(10.dp)) + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text( + text = "Vegetarian", + color = BoxTextColor + ) + Text( + text = selectedRecipe?.vegetarian.toString(), + color = BoxTextColor + ) + } + Spacer(modifier = Modifier.height(10.dp)) + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text( + text = "Very Healthy ?", + color = BoxTextColor + ) + Text( + text = selectedRecipe?.veryHealthy.toString(), + color = BoxTextColor + ) + } + Spacer(modifier = Modifier.height(10.dp)) + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text( + text = "Very Popular", + color = BoxTextColor + ) + Text( + text = selectedRecipe?.veryPopular.toString(), + color = BoxTextColor + ) + } + Spacer(modifier = Modifier.height(10.dp)) + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text( + text = "Read more", + color = BoxTextColor + ) + Text( + text = selectedRecipe?.sourceUrl.toString(), + color = BoxTextColor + ) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/cookbook/presentation/view/recipedetailsscreen/Ingredients.kt b/app/src/main/java/com/example/cookbook/presentation/view/recipedetailsscreen/Ingredients.kt new file mode 100644 index 0000000..7473085 --- /dev/null +++ b/app/src/main/java/com/example/cookbook/presentation/view/recipedetailsscreen/Ingredients.kt @@ -0,0 +1,52 @@ +package com.example.cookbook.presentation.view.recipedetailsscreen + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.example.cookbook.data.models.randomrecipemodel.Recipe + +@Composable +fun Ingredients( + selectedRecipe: Recipe +) { + val ingredients = selectedRecipe.extendedIngredients + Column( + modifier = Modifier.padding(20.dp) + ) { + Text( + text = "Ingredients", + fontSize = 30.sp, + fontWeight = FontWeight.Bold + ) + Spacer(modifier = Modifier.height(20.dp)) + ingredients.forEach {ingredient -> + val quantity = if (ingredient.meta.isNotEmpty()) ingredient.meta[0] else "" + Row ( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 20.dp), + horizontalArrangement = Arrangement.SpaceBetween + ){ + Text( + text = "$quantity ${ingredient.name}", + color = Color.Gray + ) + Text( + text = "- $quantity ${ingredient.amount}", + color = Color.Gray + ) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/cookbook/presentation/view/recipedetailsscreen/Instructions.kt b/app/src/main/java/com/example/cookbook/presentation/view/recipedetailsscreen/Instructions.kt new file mode 100644 index 0000000..3e6e4a4 --- /dev/null +++ b/app/src/main/java/com/example/cookbook/presentation/view/recipedetailsscreen/Instructions.kt @@ -0,0 +1,57 @@ +package com.example.cookbook.presentation.view.recipedetailsscreen + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.example.cookbook.presentation.viewmodel.RecipeDetailScreenViewModel + +@Composable +fun Instructions( + recipeDetailScreenViewModel: RecipeDetailScreenViewModel +) { + val selectedRecipe = recipeDetailScreenViewModel + .selectedRecipe + .collectAsState() + .value + + + Column( + modifier = Modifier.padding(20.dp) + ) { + Text( + text = "Instructions", + fontSize = 30.sp, + fontWeight = FontWeight.Bold + ) + Spacer(modifier = Modifier.height(10.dp)) + Text( + text = selectedRecipe?.instructions.toString(), + color = Color.Gray + ) + Spacer(modifier = Modifier.height(20.dp)) + Text( + text = "Steps", + fontSize = 30.sp, + fontWeight = FontWeight.Bold + ) + val analyzedInstructions = selectedRecipe?.analyzedInstructions + analyzedInstructions?.forEach { analyzedInstruction -> + val steps = analyzedInstruction.steps + steps.forEach { step -> + Text( + text = step.step, + color = Color.Gray + ) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/cookbook/presentation/view/recipedetailsscreen/RecipeDetailScreen.kt b/app/src/main/java/com/example/cookbook/presentation/view/recipedetailsscreen/RecipeDetailScreen.kt new file mode 100644 index 0000000..cdb2b52 --- /dev/null +++ b/app/src/main/java/com/example/cookbook/presentation/view/recipedetailsscreen/RecipeDetailScreen.kt @@ -0,0 +1,25 @@ +package com.example.cookbook.presentation.view.recipedetailsscreen + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.navigation.NavBackStackEntry +import androidx.navigation.NavHostController +import com.example.cookbook.presentation.viewmodel.RecipeDetailScreenViewModel + +@Composable +fun RecipeDetailScreen( + recipeDetailScreenViewModel: RecipeDetailScreenViewModel, + navBackStackEntry: NavBackStackEntry, + navController: NavHostController +) { + Column( + modifier = Modifier + .fillMaxSize() + ) { + Header(recipeDetailScreenViewModel) {navController.popBackStack()} + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/cookbook/presentation/viewmodel/HomeScreenViewModel.kt b/app/src/main/java/com/example/cookbook/presentation/viewmodel/HomeScreenViewModel.kt index 2ce4d04..3c17f0d 100644 --- a/app/src/main/java/com/example/cookbook/presentation/viewmodel/HomeScreenViewModel.kt +++ b/app/src/main/java/com/example/cookbook/presentation/viewmodel/HomeScreenViewModel.kt @@ -1,6 +1,5 @@ package com.example.cookbook.presentation.viewmodel -import android.util.Log import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.example.cookbook.data.models.randomrecipemodel.Recipe @@ -25,21 +24,16 @@ class HomeScreenViewModel @Inject constructor( val popularItems: StateFlow> get() = _popularItems - fun getRandomRecipe(apiKey: String) { + + fun getRandomRecipe(apiKey: String, number: Int) { _isLoading.value = true viewModelScope.launch(Dispatchers.IO) { try { - val result = randomRecipeRepository.getRandomRecipe(apiKey) - Log.d("HomeScreenViewModel", "getRandomRecipe of repository is being called with apiKey : $apiKey") + val result = randomRecipeRepository.getRandomRecipe(apiKey, number) if (result.isSuccess) { val recipes = result.getOrNull()?.recipes ?: emptyList() _popularItems.value = recipes - Log.d("HomeScreenViewModel", "_popularItems.value : ${_popularItems.value}") - } else { - // Handle error (you can expose this via another state or event) } - } catch (e: Exception) { - // Handle network or other errors } finally { _isLoading.value = false } diff --git a/app/src/main/java/com/example/cookbook/presentation/viewmodel/LogInScreenViewModel.kt b/app/src/main/java/com/example/cookbook/presentation/viewmodel/LogInScreenViewModel.kt index 183c3ca..372aaab 100644 --- a/app/src/main/java/com/example/cookbook/presentation/viewmodel/LogInScreenViewModel.kt +++ b/app/src/main/java/com/example/cookbook/presentation/viewmodel/LogInScreenViewModel.kt @@ -1,13 +1,11 @@ package com.example.cookbook.presentation.viewmodel import android.content.Context -import android.util.Log -import android.widget.Toast import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel -import androidx.navigation.NavController import androidx.navigation.NavHostController +import com.example.cookbook.utils.LogInResult import com.google.firebase.auth.FirebaseAuth import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject @@ -17,13 +15,11 @@ class LogInScreenViewModel @Inject constructor( ) : ViewModel() { private val auth: FirebaseAuth = FirebaseAuth.getInstance() - private lateinit var navController: NavHostController private val _logInResult = MutableLiveData() val logInResult: LiveData = _logInResult - fun setNavController(navController: NavHostController) { this.navController = navController } @@ -36,15 +32,9 @@ class LogInScreenViewModel @Inject constructor( .addOnCompleteListener { task -> if (task.isSuccessful) { _logInResult.value = LogInResult.Success - Log.d("LogInScreenViewModel", "_logInResult : $_logInResult") } else { _logInResult.value = LogInResult.Failure("Sign In Failed ") } } } } - -sealed class LogInResult { - object Success: LogInResult() - data class Failure(val errorMessage: String): LogInResult() -} \ No newline at end of file diff --git a/app/src/main/java/com/example/cookbook/presentation/viewmodel/RecipeDetailScreenViewModel.kt b/app/src/main/java/com/example/cookbook/presentation/viewmodel/RecipeDetailScreenViewModel.kt new file mode 100644 index 0000000..4b9a26d --- /dev/null +++ b/app/src/main/java/com/example/cookbook/presentation/viewmodel/RecipeDetailScreenViewModel.kt @@ -0,0 +1,22 @@ +package com.example.cookbook.presentation.viewmodel + + +import androidx.lifecycle.ViewModel +import com.example.cookbook.data.models.randomrecipemodel.Recipe +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import javax.inject.Inject + +@HiltViewModel +class RecipeDetailScreenViewModel @Inject constructor( +): ViewModel() { + + private val _selectedRecipe = MutableStateFlow(null) + val selectedRecipe: StateFlow = _selectedRecipe.asStateFlow() + + fun setRecipe(recipe: Recipe) { + _selectedRecipe.value = recipe + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/cookbook/presentation/viewmodel/RegisterScreenViewModel.kt b/app/src/main/java/com/example/cookbook/presentation/viewmodel/RegisterScreenViewModel.kt index 30172a6..34e8e63 100644 --- a/app/src/main/java/com/example/cookbook/presentation/viewmodel/RegisterScreenViewModel.kt +++ b/app/src/main/java/com/example/cookbook/presentation/viewmodel/RegisterScreenViewModel.kt @@ -1,12 +1,10 @@ package com.example.cookbook.presentation.viewmodel import android.content.Context -import android.widget.Toast import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel -import androidx.navigation.NavController -import androidx.navigation.compose.rememberNavController +import com.example.cookbook.utils.RegistrationResult import com.google.firebase.auth.FirebaseAuth import com.google.firebase.auth.UserProfileChangeRequest import dagger.hilt.android.lifecycle.HiltViewModel @@ -40,17 +38,14 @@ class RegisterScreenViewModel @Inject constructor( if (displayNameUpdateTask.isSuccessful) { _registrationResult.value = RegistrationResult.Success } else { - _registrationResult.value = RegistrationResult.Failure("Failed to update display name") + _registrationResult.value = RegistrationResult + .Failure("Failed to update display name") } } } else { - _registrationResult.value = RegistrationResult.Failure("Registration Failed") + _registrationResult.value = RegistrationResult + .Failure("Registration Failed") } } } -} - -sealed class RegistrationResult { - object Success: RegistrationResult() - data class Failure(val errorMessage: String): RegistrationResult() } \ No newline at end of file diff --git a/app/src/main/java/com/example/cookbook/ui/theme/Color.kt b/app/src/main/java/com/example/cookbook/ui/theme/Color.kt index 636f0f4..cb87158 100644 --- a/app/src/main/java/com/example/cookbook/ui/theme/Color.kt +++ b/app/src/main/java/com/example/cookbook/ui/theme/Color.kt @@ -10,4 +10,6 @@ val Purple40 = Color(0xFF6650a4) val PurpleGrey40 = Color(0xFF625b71) val Pink40 = Color(0xFF7D5260) -val ButtonColor = Color(0xFFDE6D4B) \ No newline at end of file +val ButtonColor = Color(0xFFDE6D4B) +val BoxTextColor = Color(0xFF1A4752) +val BoxColor = Color(0xFFE5F8FC) \ No newline at end of file diff --git a/app/src/main/java/com/example/cookbook/utils/GetRandomRecipeResponse.kt b/app/src/main/java/com/example/cookbook/utils/GetRandomRecipeResponse.kt new file mode 100644 index 0000000..ee9f204 --- /dev/null +++ b/app/src/main/java/com/example/cookbook/utils/GetRandomRecipeResponse.kt @@ -0,0 +1,8 @@ +package com.example.cookbook.utils + +import com.example.cookbook.data.models.randomrecipemodel.RandomRecipeResponse + +sealed class GetRandomRecipeResult { + data class Success(val data: RandomRecipeResponse) : GetRandomRecipeResult() + data class Error(val throwable: Throwable) : GetRandomRecipeResult() +} diff --git a/app/src/main/java/com/example/cookbook/utils/LogInResult.kt b/app/src/main/java/com/example/cookbook/utils/LogInResult.kt new file mode 100644 index 0000000..15b8858 --- /dev/null +++ b/app/src/main/java/com/example/cookbook/utils/LogInResult.kt @@ -0,0 +1,6 @@ +package com.example.cookbook.utils + +sealed class LogInResult { + object Success: LogInResult() + data class Failure(val errorMessage: String): LogInResult() +} \ No newline at end of file diff --git a/app/src/main/java/com/example/cookbook/presentation/utils/PreferenceManager.kt b/app/src/main/java/com/example/cookbook/utils/PreferenceManager.kt similarity index 92% rename from app/src/main/java/com/example/cookbook/presentation/utils/PreferenceManager.kt rename to app/src/main/java/com/example/cookbook/utils/PreferenceManager.kt index 1a6bc65..7de020e 100644 --- a/app/src/main/java/com/example/cookbook/presentation/utils/PreferenceManager.kt +++ b/app/src/main/java/com/example/cookbook/utils/PreferenceManager.kt @@ -1,4 +1,4 @@ -package com.example.cookbook.presentation.utils +package com.example.cookbook.utils import android.content.Context import android.content.SharedPreferences diff --git a/app/src/main/java/com/example/cookbook/utils/RegistrationResult.kt b/app/src/main/java/com/example/cookbook/utils/RegistrationResult.kt new file mode 100644 index 0000000..efe6b12 --- /dev/null +++ b/app/src/main/java/com/example/cookbook/utils/RegistrationResult.kt @@ -0,0 +1,6 @@ +package com.example.cookbook.utils + +sealed class RegistrationResult { + object Success: RegistrationResult() + data class Failure(val errorMessage: String): RegistrationResult() +} \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d05afc3..0e8987b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,6 +1,6 @@ CookBook - e0157e0d0d574cefb354163aff9f9056 + 2e5c9be439954d3ab2abeab958080246 // Home screen Hello, diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e8d1393..a775cca 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -22,6 +22,7 @@ shared-preferences = "1.1.0" lifecycle-compose = "2.7.0" runtime-livedata = "1.6.1" retrofit-adapter-coroutines = "2.6.0.pom" +swiperefresh = "0.27.0" @@ -54,6 +55,7 @@ activity-ktx = { group = "androidx.activity", name = "activity-ktx", version.ref coil = { group = "io.coil-kt", name = "coil-compose", version.ref = "coil" } androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" } sharedpreferences = { group = "androidx.datastore", name = "datastore-preferences", version.ref = "shared-preferences" } +swipe-refresh = { group = "com.google.accompanist", name = "accompanist-swiperefresh", version.ref = "swiperefresh" } [plugins]