Skip to content

Commit

Permalink
Merge c846d1b into 5352bcd
Browse files Browse the repository at this point in the history
  • Loading branch information
muhammedesadcomert authored Sep 12, 2022
2 parents 5352bcd + c846d1b commit 2ba0254
Show file tree
Hide file tree
Showing 17 changed files with 128 additions and 43 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ android {
minSdk 24
targetSdk 32
versionCode 1
versionName "1.6.0"
versionName "1.7.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ interface ApiService {
@GET("products/advanced-filtered")
suspend fun getProducts(
@Query("categoryId") categoryId: String,
@Query("sort") sort: String
@Query("sort") sortingType: String
): Response<ProductListDto>

@GET("products/{productId}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ class ProductRepositoryImpl(

override suspend fun getProducts(
categoryId: String,
sort: String
): Resource<List<Product>, String> = apiService.getProducts(categoryId, sort)
sortingType: String
): Resource<List<Product>, String> = apiService.getProducts(categoryId, sortingType)
.safeApiCall { productListDtoMapper.toDomainList(it.products) }

override suspend fun getSingleProductDetail(productId: String): Resource<Product, String> =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import com.muhammedesadcomert.fastfood.util.Resource

interface ProductRepository {

suspend fun getProducts(categoryId: String, sort: String): Resource<List<Product>, String>
suspend fun getProducts(categoryId: String, sortingType: String): Resource<List<Product>, String>

suspend fun getSingleProductDetail(productId: String): Resource<Product, String>
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.muhammedesadcomert.fastfood.ui

import android.os.Bundle
import android.view.Menu
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
Expand Down Expand Up @@ -30,9 +29,4 @@ class MainActivity : AppCompatActivity(R.layout.activity_main) {
override fun onSupportNavigateUp(): Boolean {
return navController.navigateUp() || super.onSupportNavigateUp()
}

override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu, menu)
return super.onCreateOptionsMenu(menu)
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package com.muhammedesadcomert.fastfood.ui.home

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.*
import android.widget.Toast
import androidx.core.view.MenuHost
import androidx.core.view.MenuProvider
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
import androidx.navigation.fragment.findNavController
import com.muhammedesadcomert.fastfood.R
import com.muhammedesadcomert.fastfood.databinding.FragmentHomeBinding
import com.muhammedesadcomert.fastfood.util.Constant.CURRENT_CATEGORY
import com.muhammedesadcomert.fastfood.util.extension.startShimmerLayout
import com.muhammedesadcomert.fastfood.util.extension.stopShimmerLayout
import dagger.hilt.android.AndroidEntryPoint
Expand All @@ -35,12 +38,36 @@ class HomeFragment : Fragment() {

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initMenuProvider()
initCategoryAdapter()
handleCategories()
initProductAdapter()
handleProducts()
}

private fun initMenuProvider() {
val menuHost: MenuHost = requireActivity()

menuHost.addMenuProvider(
object : MenuProvider {
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(R.menu.menu, menu)
}

override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
when (menuItem.itemId) {
R.id.sort -> {
SortDialogFragment().show(this@HomeFragment.childFragmentManager, null)
}
}
return true
}
},
viewLifecycleOwner,
Lifecycle.State.RESUMED
)
}

private fun handleCategories() {
viewModel.categoriesUiState.observe(viewLifecycleOwner) { categoriesUiState ->
if (!categoriesUiState.errorMessage.isNullOrEmpty()) {
Expand All @@ -53,9 +80,10 @@ class HomeFragment : Fragment() {

private fun initCategoryAdapter() {
categoryAdapter = CategoryAdapter { category ->
productAdapter.submitList(null)
binding.shimmerLayoutProducts.startShimmerLayout()
viewModel.getProducts(category.id!!)
category.id?.let {
CURRENT_CATEGORY = it
}
viewModel.getProducts()
}

binding.recyclerViewCategories.apply {
Expand All @@ -72,7 +100,7 @@ class HomeFragment : Fragment() {
Toast.makeText(context, productsUiState.errorMessage, Toast.LENGTH_LONG).show()
binding.shimmerLayoutProducts.stopShimmerLayout()
} else if (productsUiState.products.isNotEmpty()) {
productAdapter.submitList(productsUiState.products)
productAdapter.differ.submitList(productsUiState.products)
binding.shimmerLayoutProducts.stopShimmerLayout()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import com.muhammedesadcomert.fastfood.domain.repository.CategoryRepository
import com.muhammedesadcomert.fastfood.domain.repository.ProductRepository
import com.muhammedesadcomert.fastfood.ui.home.model.CategoriesUiState
import com.muhammedesadcomert.fastfood.ui.home.model.ProductsUiState
import com.muhammedesadcomert.fastfood.util.Constant.DEFAULT_CATEGORY
import com.muhammedesadcomert.fastfood.util.Constant.DEFAULT_SORT
import com.muhammedesadcomert.fastfood.util.Constant.CURRENT_CATEGORY
import com.muhammedesadcomert.fastfood.util.Constant.CURRENT_SORTING_TYPE
import com.muhammedesadcomert.fastfood.util.Resource
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
Expand All @@ -19,8 +19,7 @@ import javax.inject.Inject
class HomeViewModel @Inject constructor(
private val productRepository: ProductRepository,
private val categoryRepository: CategoryRepository
) :
ViewModel() {
) : ViewModel() {

private var _categoriesUiState: MutableLiveData<CategoriesUiState> =
MutableLiveData(CategoriesUiState.initial())
Expand Down Expand Up @@ -57,10 +56,13 @@ class HomeViewModel @Inject constructor(
}
}

fun getProducts(categoryId: String = DEFAULT_CATEGORY, sort: String = DEFAULT_SORT) {
fun getProducts(
categoryId: String = CURRENT_CATEGORY,
sortingType: String = CURRENT_SORTING_TYPE
) {
viewModelScope.launch {
_productsUiState.value = _productsUiState.value?.copy(isLoading = true)
when (val resource = productRepository.getProducts(categoryId, sort)) {
when (val resource = productRepository.getProducts(categoryId, sortingType)) {
is Resource.Failure -> {
_productsUiState.value = _productsUiState.value?.copy(
errorMessage = resource.errorMessage,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.muhammedesadcomert.fastfood.ui.home
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.AsyncListDiffer
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
Expand All @@ -23,12 +24,14 @@ class ProductAdapter(private val onItemClicked: (Product) -> Unit) :
with(binding) {
textViewProductTitle.text = product.title
textViewProductPrice.text = product.price.toString().plus(PRICE_SUFFIX)

if (product.campaignPrice != null && product.campaignPrice != product.price) {
textViewProductPrice.strikeThroughOnText()
textViewProductCampaignPrice.text =
product.campaignPrice.toString().plus(PRICE_SUFFIX)
textViewProductCampaignPrice.visibility = View.VISIBLE
}

Glide.with(itemView).load(product.image)
.placeholder(R.drawable.blank_detail_image)
.into(imageViewProductImage)
Expand All @@ -43,13 +46,17 @@ class ProductAdapter(private val onItemClicked: (Product) -> Unit) :
}

override fun onBindViewHolder(holder: ProductViewHolder, position: Int) {
val product = currentList[position]
val product = differ.currentList[position]
holder.bind(product)
holder.itemView.setOnClickListener {
onItemClicked(product)
}
}

val differ = AsyncListDiffer(this, DIFF_CALLBACK)

override fun getItemCount() = differ.currentList.size

companion object {
private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Product>() {
override fun areItemsTheSame(oldItem: Product, newItem: Product): Boolean {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.muhammedesadcomert.fastfood.ui.home

import android.app.AlertDialog
import android.app.Dialog
import android.os.Bundle
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.viewModels
import com.muhammedesadcomert.fastfood.R
import com.muhammedesadcomert.fastfood.util.Constant.CURRENT_SORTING_TYPE
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class SortDialogFragment : DialogFragment() {

private val viewModel: HomeViewModel by viewModels(ownerProducer = { requireParentFragment() })

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return activity?.let {
val sortingTypes = resources.getStringArray(R.array.sorting_types)
val checkedItem = when (CURRENT_SORTING_TYPE) {
sortingTypes[0] -> 0
sortingTypes[1] -> 1
sortingTypes[2] -> 2
else -> 0
}
var selectedItem = checkedItem
val builder = AlertDialog.Builder(it)
builder.setTitle(getString(R.string.sort_dialog_title))
.setSingleChoiceItems(
R.array.sorting_types,
checkedItem
) { _, which -> selectedItem = which }
.setPositiveButton(R.string.ok) { _, _ ->
if (sortingTypes[selectedItem] != CURRENT_SORTING_TYPE) {
CURRENT_SORTING_TYPE = sortingTypes[selectedItem]
viewModel.getProducts(sortingType = sortingTypes[selectedItem])
}
}
.setNegativeButton(R.string.cancel) { _, _ -> dismiss() }
builder.create()
} ?: throw IllegalStateException(getString(R.string.sort_dialog_exception_message))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ object Constant {
const val BASE_URL = "https://api.shopiroller.com/v2.0/"
const val API_KEY = "xXspnfUxPzOGKNu90bFAjlOTnMLpN8veiixvEFXUw9I="
const val ALIAS_KEY = "AtS1aPFxlIdVLth6ee2SEETlRxk="
const val DEFAULT_CATEGORY = "61b1f109a82ec0dd1c56f5ed" // Economic Menu
const val DEFAULT_SORT = "Price"
const val PRICE_SUFFIX = ""
var CURRENT_CATEGORY = "61b1f109a82ec0dd1c56f5ed" // Economic Menu
var CURRENT_SORTING_TYPE = "Price"
}
5 changes: 0 additions & 5 deletions app/src/main/res/drawable/ic_filter.xml

This file was deleted.

5 changes: 5 additions & 0 deletions app/src/main/res/drawable/ic_sort.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<vector android:autoMirrored="true" android:height="24dp"
android:tint="#000000" android:viewportHeight="24"
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M3,18h6v-2L3,16v2zM3,6v2h18L21,6L3,6zM3,13h12v-2L3,11v2z"/>
</vector>
4 changes: 2 additions & 2 deletions app/src/main/res/layout/fragment_detail.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
android:layout_marginEnd="@dimen/space_medium"
android:textSize="18sp"
android:textStyle="bold"
tools:text="@string/price" />
tools:text="@string/selling_price" />

<TextView
android:id="@+id/textView_product_campaign_price"
Expand All @@ -81,7 +81,7 @@
android:textSize="20sp"
android:textStyle="bold"
android:visibility="gone"
tools:text="@string/price" />
tools:text="@string/selling_price" />

<TextView
android:id="@+id/textView_product_description"
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/res/layout/product_item.xml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/textView_product_title"
app:layout_constraintTop_toBottomOf="@id/textView_product_title"
tools:text="@string/price" />
tools:text="@string/selling_price" />

<TextView
android:id="@+id/textView_product_campaign_price"
Expand All @@ -61,7 +61,7 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/textView_product_title"
app:layout_constraintTop_toBottomOf="@id/textView_product_price"
tools:text="@string/price" />
tools:text="@string/selling_price" />

</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
6 changes: 3 additions & 3 deletions app/src/main/res/menu/menu.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.muhammedesadcomert.fastfood.ui.MainActivity">
<item
android:id="@+id/filter"
android:icon="@drawable/ic_filter"
android:title="@string/filter"
android:id="@+id/sort"
android:icon="@drawable/ic_sort"
android:title="@string/sort"
app:showAsAction="always" />
</menu>
5 changes: 2 additions & 3 deletions app/src/main/res/values/colors.xml
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="primary">#ffcdd2</color>
<color name="primaryVariant">#cb9ca1</color>
<color name="primary">#ff8760</color>
<color name="onPrimary">@color/black</color>
<color name="primaryContainer">#ffcdd2</color>
<color name="primaryContainer">#ff8760</color>
<color name="onPrimaryContainer">@color/black</color>
<color name="black">#000000</color>
<color name="gray">#7D7D7D</color>
Expand Down
14 changes: 13 additions & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,21 @@
<string name="economic_menu">Economic Menu</string>
<string name="product_title">Product Title</string>
<string name="product_description">Product Description</string>
<string name="price">123,40 ₺</string>
<string name="selling_price">123,40 ₺</string>
<string name="price_suffix">₺</string>
<string name="sold_out">Sold out</string>
<string name="add_to_cart">Add to Cart</string>
<string name="product_name">Product name</string>
<string name="price">Price</string>
<string name="sort">Sort</string>
<string name="ok">OK</string>
<string name="cancel">Cancel</string>
<string name="sort_dialog_title">Choose sorting type</string>
<string name="sort_dialog_exception_message">Activity cannot be null</string>

<string-array name="sorting_types">
<item>Price</item>
<item>Title</item>
<item>PublishmentDate</item>
</string-array>
</resources>

0 comments on commit 2ba0254

Please sign in to comment.