diff --git a/app/src/main/java/gq/kirmanak/mealient/ui/recipes/info/RecipeInfoFragment.kt b/app/src/main/java/gq/kirmanak/mealient/ui/recipes/info/RecipeInfoFragment.kt index 2613863..fd74d8a 100644 --- a/app/src/main/java/gq/kirmanak/mealient/ui/recipes/info/RecipeInfoFragment.kt +++ b/app/src/main/java/gq/kirmanak/mealient/ui/recipes/info/RecipeInfoFragment.kt @@ -15,19 +15,15 @@ import dagger.hilt.android.AndroidEntryPoint import gq.kirmanak.mealient.R import gq.kirmanak.mealient.databinding.FragmentRecipeInfoBinding import timber.log.Timber -import javax.inject.Inject @AndroidEntryPoint class RecipeInfoFragment : BottomSheetDialogFragment() { + private val binding by viewBinding(FragmentRecipeInfoBinding::bind) private val arguments by navArgs() private val viewModel by viewModels() - - @Inject - lateinit var ingredientsAdapter: RecipeIngredientsAdapter - - @Inject - lateinit var instructionsAdapter: RecipeInstructionsAdapter + private val ingredientsAdapter = RecipeIngredientsAdapter() + private val instructionsAdapter = RecipeInstructionsAdapter() override fun onCreateView( inflater: LayoutInflater, @@ -42,22 +38,27 @@ class RecipeInfoFragment : BottomSheetDialogFragment() { super.onViewCreated(view, savedInstanceState) Timber.v("onViewCreated() called") - binding.ingredientsList.adapter = ingredientsAdapter - binding.instructionsList.adapter = instructionsAdapter - - viewModel.loadRecipeImage(binding.image, arguments.recipeSlug) - viewModel.loadRecipeInfo(arguments.recipeId, arguments.recipeSlug) - - viewModel.recipeInfo.observe(viewLifecycleOwner) { - Timber.d("onViewCreated: full info $it") - binding.title.text = it.recipeSummaryEntity.name - binding.description.text = it.recipeSummaryEntity.description + with(binding) { + ingredientsList.adapter = ingredientsAdapter + instructionsList.adapter = instructionsAdapter } - viewModel.listsVisibility.observe(viewLifecycleOwner) { - Timber.d("onViewCreated: lists visibility $it") - binding.ingredientsHolder.isVisible = it.areIngredientsVisible - binding.instructionsGroup.isVisible = it.areInstructionsVisible + with(viewModel) { + loadRecipeImage(binding.image, arguments.recipeSlug) + loadRecipeInfo(arguments.recipeId, arguments.recipeSlug) + uiState.observe(viewLifecycleOwner, ::onUiStateChange) + } + } + + private fun onUiStateChange(uiState: RecipeInfoUiState) = with(binding) { + Timber.v("onUiStateChange() called") + ingredientsHolder.isVisible = uiState.areIngredientsVisible + instructionsGroup.isVisible = uiState.areInstructionsVisible + uiState.recipeInfo?.let { + title.text = it.recipeSummaryEntity.name + description.text = it.recipeSummaryEntity.description + ingredientsAdapter.submitList(it.recipeIngredients) + instructionsAdapter.submitList(it.recipeInstructions) } } diff --git a/app/src/main/java/gq/kirmanak/mealient/ui/recipes/info/RecipeInfoListsVisibility.kt b/app/src/main/java/gq/kirmanak/mealient/ui/recipes/info/RecipeInfoUiState.kt similarity index 51% rename from app/src/main/java/gq/kirmanak/mealient/ui/recipes/info/RecipeInfoListsVisibility.kt rename to app/src/main/java/gq/kirmanak/mealient/ui/recipes/info/RecipeInfoUiState.kt index 84bee8d..e6358df 100644 --- a/app/src/main/java/gq/kirmanak/mealient/ui/recipes/info/RecipeInfoListsVisibility.kt +++ b/app/src/main/java/gq/kirmanak/mealient/ui/recipes/info/RecipeInfoUiState.kt @@ -1,6 +1,9 @@ package gq.kirmanak.mealient.ui.recipes.info -data class RecipeInfoListsVisibility( +import gq.kirmanak.mealient.data.recipes.impl.FullRecipeInfo + +data class RecipeInfoUiState( val areIngredientsVisible: Boolean = false, val areInstructionsVisible: Boolean = false, + val recipeInfo: FullRecipeInfo? = null, ) diff --git a/app/src/main/java/gq/kirmanak/mealient/ui/recipes/info/RecipeInfoViewModel.kt b/app/src/main/java/gq/kirmanak/mealient/ui/recipes/info/RecipeInfoViewModel.kt index 77a0a83..34bf78e 100644 --- a/app/src/main/java/gq/kirmanak/mealient/ui/recipes/info/RecipeInfoViewModel.kt +++ b/app/src/main/java/gq/kirmanak/mealient/ui/recipes/info/RecipeInfoViewModel.kt @@ -8,28 +8,19 @@ import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import gq.kirmanak.mealient.data.recipes.RecipeImageLoader import gq.kirmanak.mealient.data.recipes.RecipeRepo -import gq.kirmanak.mealient.data.recipes.impl.FullRecipeInfo import gq.kirmanak.mealient.extensions.runCatchingExceptCancel import kotlinx.coroutines.launch import timber.log.Timber import javax.inject.Inject @HiltViewModel -class RecipeInfoViewModel -@Inject -constructor( +class RecipeInfoViewModel @Inject constructor( private val recipeRepo: RecipeRepo, private val recipeImageLoader: RecipeImageLoader, - private val recipeIngredientsAdapter: RecipeIngredientsAdapter, - private val recipeInstructionsAdapter: RecipeInstructionsAdapter, ) : ViewModel() { - private val _recipeInfo = MutableLiveData() - val recipeInfo: LiveData - get() = _recipeInfo - private val _listsVisibility = MutableLiveData(RecipeInfoListsVisibility()) - val listsVisibility: LiveData - get() = _listsVisibility + private val _uiState = MutableLiveData(RecipeInfoUiState()) + val uiState: LiveData get() = _uiState fun loadRecipeImage(view: ImageView, recipeSlug: String) { Timber.v("loadRecipeImage() called with: view = $view, recipeSlug = $recipeSlug") @@ -38,21 +29,16 @@ constructor( fun loadRecipeInfo(recipeId: Long, recipeSlug: String) { Timber.v("loadRecipeInfo() called with: recipeId = $recipeId, recipeSlug = $recipeSlug") - _listsVisibility.value = RecipeInfoListsVisibility() - recipeIngredientsAdapter.submitList(null) - recipeInstructionsAdapter.submitList(null) + _uiState.value = RecipeInfoUiState() viewModelScope.launch { runCatchingExceptCancel { recipeRepo.loadRecipeInfo(recipeId, recipeSlug) } .onSuccess { Timber.d("loadRecipeInfo: received recipe info = $it") - _recipeInfo.value = it - recipeIngredientsAdapter.submitList(it.recipeIngredients) - recipeInstructionsAdapter.submitList(it.recipeInstructions) - _listsVisibility.value = - RecipeInfoListsVisibility( - areIngredientsVisible = it.recipeIngredients.isNotEmpty(), - areInstructionsVisible = it.recipeInstructions.isNotEmpty() - ) + _uiState.value = RecipeInfoUiState( + areIngredientsVisible = it.recipeIngredients.isNotEmpty(), + areInstructionsVisible = it.recipeInstructions.isNotEmpty(), + recipeInfo = it, + ) } .onFailure { Timber.e(it, "loadRecipeInfo: can't load recipe info") } } 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 2ca4939..1d6215f 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 @@ -9,11 +9,8 @@ import gq.kirmanak.mealient.data.recipes.db.entity.RecipeIngredientEntity import gq.kirmanak.mealient.databinding.ViewHolderIngredientBinding import gq.kirmanak.mealient.ui.recipes.info.RecipeIngredientsAdapter.RecipeIngredientViewHolder import timber.log.Timber -import javax.inject.Inject -import javax.inject.Singleton -@Singleton -class RecipeIngredientsAdapter @Inject constructor() : +class RecipeIngredientsAdapter : ListAdapter(RecipeIngredientDiffCallback) { class RecipeIngredientViewHolder( diff --git a/app/src/main/java/gq/kirmanak/mealient/ui/recipes/info/RecipeInstructionsAdapter.kt b/app/src/main/java/gq/kirmanak/mealient/ui/recipes/info/RecipeInstructionsAdapter.kt index 6f32f87..b84cd1b 100644 --- a/app/src/main/java/gq/kirmanak/mealient/ui/recipes/info/RecipeInstructionsAdapter.kt +++ b/app/src/main/java/gq/kirmanak/mealient/ui/recipes/info/RecipeInstructionsAdapter.kt @@ -10,11 +10,8 @@ import gq.kirmanak.mealient.data.recipes.db.entity.RecipeInstructionEntity import gq.kirmanak.mealient.databinding.ViewHolderInstructionBinding import gq.kirmanak.mealient.ui.recipes.info.RecipeInstructionsAdapter.RecipeInstructionViewHolder import timber.log.Timber -import javax.inject.Inject -import javax.inject.Singleton -@Singleton -class RecipeInstructionsAdapter @Inject constructor() : +class RecipeInstructionsAdapter : ListAdapter(RecipeInstructionDiffCallback) { private object RecipeInstructionDiffCallback :