Skip to content

Commit

Permalink
Added network checks and implemented async for fetching random meals
Browse files Browse the repository at this point in the history
  • Loading branch information
GreenVenom77 committed Sep 22, 2024
1 parent 81441df commit 719355a
Show file tree
Hide file tree
Showing 13 changed files with 596 additions and 612 deletions.
2 changes: 2 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
xmlns:tools="http://schemas.android.com/tools" >

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

<application
android:allowBackup="true"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import com.example.recipeappiti.core.model.remote.Response
import com.google.android.material.dialog.MaterialAlertDialogBuilder

object CreateMaterialAlertDialogBuilder {

fun createMaterialAlertDialogBuilderOkCancel(
context: Context,
title: String,
Expand All @@ -15,7 +14,6 @@ object CreateMaterialAlertDialogBuilder {
negativeBtnMsg: String,
positiveBtnFun: () -> Unit
) {

MaterialAlertDialogBuilder(context)
.setTitle(title)
.setMessage(message)
Expand All @@ -31,7 +29,6 @@ object CreateMaterialAlertDialogBuilder {
}
.setCancelable(false)
.show()

}

fun createMaterialAlertDialogBuilderOk(
Expand All @@ -41,7 +38,6 @@ object CreateMaterialAlertDialogBuilder {
positiveBtnMsg: String,
positiveBtnFun: () -> Unit
) {

MaterialAlertDialogBuilder(context)
.setTitle(title)
.setMessage(message)
Expand All @@ -53,21 +49,19 @@ object CreateMaterialAlertDialogBuilder {
}
.setCancelable(false)
.show()

}

fun createFailureResponse(response: Response.Failure, context: Context) {
fun createFailureResponse(response: Response.Failure, context: Context, action: (() -> Unit)? = null) {
when (val failureReason = response.reason) {
is FailureReason.NoInternet -> {

createMaterialAlertDialogBuilderOkCancel(
context,
title = "No Internet Connection",
message = "Please check your internet connection and try again.",
positiveBtnMsg = "Try again",
negativeBtnMsg = "Cancel"
) {
//TODO Optionally, define any action to take after the dialog is dismissed
action?.invoke()
}
}

Expand All @@ -77,12 +71,11 @@ object CreateMaterialAlertDialogBuilder {
context,
title = "Unknown Error",
message = "An unknown error occurred: $errorMessage",
positiveBtnMsg = "OK"
positiveBtnMsg = "Try again"
) {

action?.invoke()
}
}
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.example.recipeappiti.core.util

import android.content.Context
import android.net.ConnectivityManager
import android.net.NetworkCapabilities

object SystemChecks {
fun isNetworkAvailable(context: Context): Boolean {
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val network = connectivityManager.activeNetwork ?: return false
val activeNetwork = connectivityManager.getNetworkCapabilities(network) ?: return false
return activeNetwork.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import com.example.recipeappiti.core.model.local.source.UserDatabase
import com.example.recipeappiti.core.model.remote.Meal
import com.example.recipeappiti.core.model.remote.repository.MealRepositoryImpl
import com.example.recipeappiti.core.model.remote.source.RemoteGsonDataImpl
import com.example.recipeappiti.core.util.CreateMaterialAlertDialogBuilder.createMaterialAlertDialogBuilderOk
import com.example.recipeappiti.core.util.SystemChecks
import com.example.recipeappiti.core.viewmodel.DataViewModel
import com.example.recipeappiti.core.viewmodel.DataViewModelFactory
import com.example.recipeappiti.details.view.adapters.IngredientsRecyclerViewAdapter
Expand Down Expand Up @@ -111,8 +113,7 @@ class RecipeDetailFragment : Fragment() {
super.onViewCreated(view, savedInstanceState)

initViews()
initObservers()
initListeners()
checkConnection()
}

private fun initViews() {
Expand Down Expand Up @@ -143,7 +144,6 @@ class RecipeDetailFragment : Fragment() {
instructionsText = requireView().findViewById(R.id.instructionsText)

bottomNavigationView.visibility = View.GONE

}

private fun initListeners() {
Expand All @@ -165,7 +165,6 @@ class RecipeDetailFragment : Fragment() {
}

private fun initObservers() {

dataViewModel.itemDetails.observe(viewLifecycleOwner) { id ->
recipeId = id
changeFavouriteState(recipeId, false)
Expand Down Expand Up @@ -252,6 +251,22 @@ class RecipeDetailFragment : Fragment() {
youtubePlayerView.initialize(youtubePlayerListener, iFramePlayerOptions)
}

private fun checkConnection() {
if (!SystemChecks.isNetworkAvailable(requireContext())) {
createMaterialAlertDialogBuilderOk(
requireContext(),
"No Internet Connection",
"Please check your internet connection and try again",
"Retry",
) {
checkConnection()
}
} else {
initObservers()
initListeners()
}
}

override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@ import com.example.recipeappiti.R
import com.example.recipeappiti.core.model.remote.Category

class AdapterRVCategories(
private val categories: List<Category>,
private var categories: List<Category>,
private val goToSearch: ((id: String) -> Unit)? = null
) :
RecyclerView.Adapter<AdapterRVCategories.CategoryViewHolder>() {
) : RecyclerView.Adapter<AdapterRVCategories.CategoryViewHolder>() {

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CategoryViewHolder {
val view = LayoutInflater.from(parent.context)
Expand All @@ -33,15 +32,19 @@ class AdapterRVCategories(
.into(imageView)

itemView.setOnClickListener { goToSearch?.let { it(category.strCategory) } }

}
}

override fun getItemCount(): Int = categories.size

fun submitList(newCategories: List<Category>) {
categories = newCategories
notifyDataSetChanged()
}

class CategoryViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val imageView: ImageView = itemView.findViewById(R.id.item_category_image)
val textView: TextView = itemView.findViewById(R.id.item_category_title)

}
}

Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@ import com.example.recipeappiti.R
import com.example.recipeappiti.core.model.remote.Meal

class AdapterRVItemMeal(
private val meals: List<Meal>,
private var meals: List<Meal>,
private val goToDetails: ((id: String) -> Unit)? = null
) :
RecyclerView.Adapter<AdapterRVItemMeal.MealViewHolder>() {
) : RecyclerView.Adapter<AdapterRVItemMeal.MealViewHolder>() {

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MealViewHolder {
val view = LayoutInflater.from(parent.context)
Expand All @@ -25,7 +24,6 @@ class AdapterRVItemMeal(
override fun onBindViewHolder(holder: MealViewHolder, position: Int) {
val meal = meals[position]


holder.titleView.text = formatDescription(meal.strMeal)

Glide.with(holder.itemView.context)
Expand All @@ -34,11 +32,15 @@ class AdapterRVItemMeal(
.into(holder.imageView)

holder.imageView.setOnClickListener {

goToDetails?.let { it(meal.idMeal) }

}
}

override fun getItemCount(): Int = meals.size

fun submitList(newMeals: List<Meal>) {
meals = newMeals
notifyDataSetChanged()
}

private fun formatDescription(
Expand All @@ -53,8 +55,6 @@ class AdapterRVItemMeal(
}
}

override fun getItemCount(): Int = meals.size

class MealViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val imageView: ImageView = itemView.findViewById(R.id.item_image)
val titleView: TextView = itemView.findViewById(R.id.item_title)
Expand Down
Loading

0 comments on commit 719355a

Please sign in to comment.