Integrated add_to_cart api and ui updates.

Cart count live data updates caching and handling cart data.

Text updates wrt to subcategory in product listing.

adding to cart data caching issue - problem solving
This commit is contained in:
2024-07-30 21:16:10 +05:30
parent 86f0aa47dc
commit 4d393b0fcf
27 changed files with 352 additions and 57 deletions

View File

@@ -42,6 +42,9 @@ interface ShopApiService {
@POST("remove_cart") @POST("remove_cart")
suspend fun removeCartItem(@Body formBody: FormBody): Response<ApiResponse<Any>> suspend fun removeCartItem(@Body formBody: FormBody): Response<ApiResponse<Any>>
@POST("add_cart")
suspend fun addToCart(@Body formBody: FormBody): Response<ApiResponse<Any>>
@GET("coupon_listing") @GET("coupon_listing")
suspend fun couponsListing(): Response<ApiResponse<CouponsResponse>> suspend fun couponsListing(): Response<ApiResponse<CouponsResponse>>

View File

@@ -1,5 +1,7 @@
package com.woka.shop package com.woka.shop
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.woka.networking.ApiResult import com.woka.networking.ApiResult
import com.woka.networking.RetrofitHelper import com.woka.networking.RetrofitHelper
import com.woka.networking.RetrofitHelper.handleApiCall import com.woka.networking.RetrofitHelper.handleApiCall
@@ -7,6 +9,7 @@ import com.woka.shop.models.addaddress.AddAddressRequestData
import com.woka.shop.models.addaddress.AddAddressResponseData import com.woka.shop.models.addaddress.AddAddressResponseData
import com.woka.shop.models.addresslisting.ParentAddressData import com.woka.shop.models.addresslisting.ParentAddressData
import com.woka.shop.models.applycoupon.ApplyCouponResponse import com.woka.shop.models.applycoupon.ApplyCouponResponse
import com.woka.shop.models.cartlisting.CartItem
import com.woka.shop.models.cartlisting.CartResponse import com.woka.shop.models.cartlisting.CartResponse
import com.woka.shop.models.categorylisting.CategoryResponse import com.woka.shop.models.categorylisting.CategoryResponse
import com.woka.shop.models.couponlisting.CouponsResponse import com.woka.shop.models.couponlisting.CouponsResponse
@@ -14,6 +17,7 @@ import com.woka.shop.models.createorder.CreateOrderRequestData
import com.woka.shop.models.createorder.CreateOrderResponse import com.woka.shop.models.createorder.CreateOrderResponse
import com.woka.shop.models.edd.EDDResponse import com.woka.shop.models.edd.EDDResponse
import com.woka.shop.models.productlisting.ProductListingResponse import com.woka.shop.models.productlisting.ProductListingResponse
import com.woka.shop.models.productlisting.ShopProduct
import com.woka.shop.models.subcategorylisting.SubCategoryResponse import com.woka.shop.models.subcategorylisting.SubCategoryResponse
import com.woka.shop.models.superlisting.SuperCategoryResponse import com.woka.shop.models.superlisting.SuperCategoryResponse
import okhttp3.FormBody import okhttp3.FormBody
@@ -74,6 +78,10 @@ object ShopRepository {
// cart listing with loose caching // cart listing with loose caching
private var cartResponse: CartResponse? = null private var cartResponse: CartResponse? = null
private val _cartCountLiveData = MutableLiveData<Int>()
val cartCountLiveData: LiveData<Int>
get() = _cartCountLiveData
suspend fun cartListing(): ApiResult<CartResponse> { suspend fun cartListing(): ApiResult<CartResponse> {
if (cartResponse != null) { if (cartResponse != null) {
return ApiResult.Success(cartResponse) return ApiResult.Success(cartResponse)
@@ -88,12 +96,50 @@ object ShopRepository {
is ApiResult.Loading -> {} is ApiResult.Loading -> {}
is ApiResult.Success -> { is ApiResult.Success -> {
cartResponse = response.data cartResponse = response.data
response.data?.result?.let {
_cartCountLiveData.postValue(it.size)
}
} }
} }
return response return response
} }
suspend fun addToCart(shopProduct: ShopProduct): ApiResult<Any>{
val response = handleApiCall {
apiService.addToCart(
FormBody.Builder()
.add("shop_master_id", "${shopProduct.id}")
.build()
)
}
when (response) {
is ApiResult.Error -> {}
is ApiResult.Loading -> {}
is ApiResult.Success -> {
if (cartResponse == null){
cartListing()
}else{
// removing from cache
cartResponse?.let { cartData ->
cartData.result?.let { cartItems ->
cartItems.add(CartItem(shopProduct))
shopProduct.product_final_price?.let {
cartData.total_amount = (cartData.total_amount?:0.0) + it
}
cartItems.let {
_cartCountLiveData.postValue(it.size)
}
}
}
}
}
}
return response
}
suspend fun removeCartItem(id: Int): ApiResult<Double> { suspend fun removeCartItem(id: Int): ApiResult<Double> {
val response = handleApiCall { val response = handleApiCall {
apiService.removeCartItem( apiService.removeCartItem(
@@ -120,6 +166,10 @@ object ShopRepository {
} }
cartItems.removeIf { it?.id == id } cartItems.removeIf { it?.id == id }
cartItems.let {
_cartCountLiveData.postValue(it.size)
}
} }
} }

View File

@@ -26,7 +26,7 @@ class CartAdapter: ListAdapter<CartItem, CartAdapter.CartViewHolder>(ASYNC_DIFF_
inner class CartViewHolder(val binding: CartItemViewHolderBinding): ViewHolder(binding.root) inner class CartViewHolder(val binding: CartItemViewHolderBinding): ViewHolder(binding.root)
var onCartItemDeleteListener: ((Int, Int) -> Unit)? = null var onCartItemDeleteListener: ((CartItem, Int) -> Unit)? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CartViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CartViewHolder {
return CartViewHolder( return CartViewHolder(
@@ -55,7 +55,7 @@ class CartAdapter: ListAdapter<CartItem, CartAdapter.CartViewHolder>(ASYNC_DIFF_
delete.show() delete.show()
delete.setOnClickListener { delete.setOnClickListener {
cartItem.id?.let { id -> onCartItemDeleteListener?.invoke(id, holder.absoluteAdapterPosition) } onCartItemDeleteListener?.invoke(cartItem, holder.absoluteAdapterPosition)
} }
} }
} }

View File

@@ -43,7 +43,12 @@ class ShopProductAdapter: ListAdapter<ShopProduct, ShopProductAdapter.ProductVie
if (product.shop_image?.isNotEmpty() == true) if (product.shop_image?.isNotEmpty() == true)
image.loadImage(product.shop_image.first()) image.loadImage(product.shop_image.first())
title.text = product.product_name title.text = if (product.sub_category_master_id == 12){
product.shop_master_detail?.product_name_english
}else{
product.shop_master_detail?.product_name_hindi
}
price.text = "${product.product_price}" price.text = "${product.product_price}"
root.setOnClickListener { root.setOnClickListener {

View File

@@ -1,5 +1,8 @@
package com.woka.shop.models.cartlisting package com.woka.shop.models.cartlisting
import com.woka.shop.models.productlisting.ShopMasterDetail
import com.woka.shop.models.productlisting.ShopProduct
data class CartItem( data class CartItem(
val category_master_id: Int?, val category_master_id: Int?,
val id: Int?, val id: Int?,
@@ -13,6 +16,21 @@ data class CartItem(
val sku_id: String?, val sku_id: String?,
val stock_status: String?, val stock_status: String?,
val sub_category_master_id: Int?, val sub_category_master_id: Int?,
val tax_category: Any?,
val tax_value: String? val tax_value: String?
) ){
constructor(shopProduct: ShopProduct): this(
shopProduct.category_master_id,
shopProduct.id,
shopProduct.product_name,
shopProduct.product_price,
shopProduct.product_final_price,
1,
shopProduct.remain_stock_quantity,
shopProduct.shop_image,
shopProduct.shop_master_detail,
shopProduct.sku_id,
shopProduct.stock_status,
shopProduct.sub_category_master_id,
shopProduct.tax_value
)
}

View File

@@ -1,10 +0,0 @@
package com.woka.shop.models.cartlisting
data class ShopMasterDetail(
val description_english: String?,
val description_hindi: String?,
val id: Int?,
val product_id: Int?,
val product_name_english: String?,
val product_name_hindi: String?
)

View File

@@ -1,5 +1,9 @@
package com.woka.shop.models.productlisting package com.woka.shop.models.productlisting
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
data class ShopMasterDetail( data class ShopMasterDetail(
val description_english: String?, val description_english: String?,
val description_hindi: String?, val description_hindi: String?,
@@ -7,4 +11,4 @@ data class ShopMasterDetail(
val product_id: Int?, val product_id: Int?,
val product_name_english: String?, val product_name_english: String?,
val product_name_hindi: String? val product_name_hindi: String?
) ): Parcelable

View File

@@ -1,11 +1,17 @@
package com.woka.shop.models.productlisting package com.woka.shop.models.productlisting
import android.os.Parcelable
import com.woka.shop.models.cartlisting.CartItem
import kotlinx.parcelize.Parcelize
@Parcelize
data class ShopProduct( data class ShopProduct(
val added_to_cart: Boolean?, var added_to_cart: Boolean?,
val category_master_id: Int?, val category_master_id: Int?,
val id: Int?, val id: Int?,
val product_name: String?, val product_name: String?,
val product_price: String?, val product_price: String?,
val product_final_price: Double?,
val product_thumbnail: String?, val product_thumbnail: String?,
val remain_stock_quantity: Int?, val remain_stock_quantity: Int?,
val shop_image: List<String?>?, val shop_image: List<String?>?,
@@ -13,6 +19,33 @@ data class ShopProduct(
val sku_id: String?, val sku_id: String?,
val stock_status: String?, val stock_status: String?,
val sub_category_master_id: Int?, val sub_category_master_id: Int?,
val tax_category: Any?,
val tax_value: String? val tax_value: String?
) ): Parcelable{
constructor(cartItem: CartItem, added_to_cart: Boolean?): this(
added_to_cart,
cartItem.category_master_id,
cartItem.id,
cartItem.product_name,
cartItem.product_price,
cartItem.product_final_price,
null,
cartItem.remain_stock_quantity,
cartItem.shop_image,
cartItem.shop_master_detail,
cartItem.sku_id,
cartItem.stock_status,
cartItem.sub_category_master_id,
cartItem.tax_value
)
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is ShopProduct) return false
return other.id == this.id
}
override fun hashCode(): Int {
return this.id?:0
}
}

View File

@@ -12,6 +12,7 @@ import com.woka.shop.models.cartlisting.CartResponse
import com.woka.shop.models.couponlisting.CouponsResponse import com.woka.shop.models.couponlisting.CouponsResponse
import com.woka.shop.models.createorder.CreateOrderRequestData import com.woka.shop.models.createorder.CreateOrderRequestData
import com.woka.shop.models.createorder.CreateOrderResponse import com.woka.shop.models.createorder.CreateOrderResponse
import com.woka.shop.models.productlisting.ShopProduct
import kotlinx.coroutines.async import kotlinx.coroutines.async
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@@ -30,6 +31,8 @@ class CartViewModel: ViewModel() {
var selectedAddressId: Int? = null var selectedAddressId: Int? = null
val eddMap = HashMap<Int, String>() val eddMap = HashMap<Int, String>()
// cart
val removedProducts = ArrayList<ShopProduct>()
// data callbacks // data callbacks
private val repository = ShopRepository private val repository = ShopRepository

View File

@@ -1,5 +1,6 @@
package com.woka.shop.viewmodels package com.woka.shop.viewmodels
import android.util.Log
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
@@ -11,7 +12,9 @@ import com.woka.shop.models.productlisting.ShopProduct
import com.woka.shop.models.subcategorylisting.SubCategoryData import com.woka.shop.models.subcategorylisting.SubCategoryData
import com.woka.shop.models.superlisting.SuperCategory import com.woka.shop.models.superlisting.SuperCategory
import com.woka.utils.PagingData import com.woka.utils.PagingData
import com.woka.utils.TAG
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlin.collections.HashSet
class ShopViewModel: ViewModel() { class ShopViewModel: ViewModel() {
@@ -105,14 +108,14 @@ class ShopViewModel: ViewModel() {
} }
// product listing // product listing
private val _productListingLiveData = MutableLiveData<ApiResult<MutableList<ShopProduct>>>() private val _productListingLiveData = MutableLiveData<ApiResult<HashSet<ShopProduct>>>()
val productListingLiveData: LiveData<ApiResult<MutableList<ShopProduct>>> val productListingLiveData: LiveData<ApiResult<HashSet<ShopProduct>>>
get() = _productListingLiveData get() = _productListingLiveData
var productPagingData = HashMap<String, PagingData>() var productPagingData = HashMap<String, PagingData>()
// product data for every super-category, category and sub-category // product data for every super-category, category and sub-category
private var productDataMap = HashMap<String, MutableList<ShopProduct>>() private var productDataMap = HashMap<String, HashSet<ShopProduct>>()
fun loadProducts(superCategoryId: String, categoryId: String, subCategoryId: String?) { fun loadProducts(superCategoryId: String, categoryId: String, subCategoryId: String?) {
val key = "${superCategoryId}_${categoryId}_$subCategoryId" val key = "${superCategoryId}_${categoryId}_$subCategoryId"
@@ -159,7 +162,7 @@ class ShopViewModel: ViewModel() {
is ApiResult.Success -> { is ApiResult.Success -> {
response.data?.let { data -> response.data?.let { data ->
data.result?.filterNotNull()?.let { newList -> data.result?.filterNotNull()?.let { newList ->
val currentList = productDataMap.getOrDefault(key, ArrayList()) val currentList = productDataMap.getOrDefault(key, HashSet())
currentList.addAll(newList) currentList.addAll(newList)
productDataMap[key] = currentList productDataMap[key] = currentList
@@ -173,7 +176,39 @@ class ShopViewModel: ViewModel() {
} }
} }
fun removeProductsFromCart(products: List<ShopProduct>){
val toBeReplaced = mutableSetOf<ShopProduct>()
for (productSet in productDataMap.values){
toBeReplaced.clear()
for (product in products){
if (productSet.contains(product)){
toBeReplaced.add(product)
}
}
productSet.removeAll(toBeReplaced)
productSet.addAll(toBeReplaced)
}
_productListingLiveData.postValue(ApiResult.Success(productDataMap[""]))
}
fun clearProductListingLiveData() { fun clearProductListingLiveData() {
_productListingLiveData.postValue(ApiResult.Loading()) _productListingLiveData.postValue(ApiResult.Loading())
} }
// cart
val cartCountLivedata: LiveData<Int>
get() {
viewModelScope.launch {
repository.cartListing()
}
return repository.cartCountLiveData
}
suspend fun addToCart(shopProduct: ShopProduct): ApiResult<Any> {
return repository.addToCart(shopProduct)
}
} }

View File

@@ -11,6 +11,10 @@ import com.woka.utils.WokaBaseActivity
class CartActivity : WokaBaseActivity() { class CartActivity : WokaBaseActivity() {
companion object{
const val EXTRA_REMOVED_CART_ITEMS = "extra_removed_cart_items"
}
private lateinit var binding: ActivityCartBinding private lateinit var binding: ActivityCartBinding
private lateinit var viewModel: CartViewModel private lateinit var viewModel: CartViewModel

View File

@@ -5,14 +5,18 @@ import android.os.Bundle
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.ViewModelProvider
import com.woka.R import com.woka.R
import com.woka.databinding.ActivityShopBinding import com.woka.databinding.ActivityShopBinding
import com.woka.shop.viewmodels.ShopViewModel
import com.woka.shop.views.fragments.shop.ShopFragment1 import com.woka.shop.views.fragments.shop.ShopFragment1
import com.woka.utils.WokaBaseActivity import com.woka.utils.WokaBaseActivity
import com.woka.utils.setVisibility
class ShopActivity : WokaBaseActivity() { class ShopActivity : WokaBaseActivity() {
private lateinit var binding: ActivityShopBinding private lateinit var binding: ActivityShopBinding
private lateinit var viewModel: ShopViewModel
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@@ -25,6 +29,8 @@ class ShopActivity : WokaBaseActivity() {
insets insets
} }
viewModel = ViewModelProvider(this)[ShopViewModel::class.java]
window.navigationBarColor = getColor(R.color.orders_bg) window.navigationBarColor = getColor(R.color.orders_bg)
supportFragmentManager.beginTransaction() supportFragmentManager.beginTransaction()
@@ -34,6 +40,8 @@ class ShopActivity : WokaBaseActivity() {
initViews() initViews()
clickEvents() clickEvents()
setObservers()
} }
private fun initViews(){ private fun initViews(){
@@ -55,4 +63,11 @@ class ShopActivity : WokaBaseActivity() {
} }
} }
} }
private fun setObservers() {
viewModel.cartCountLivedata.observe(this){
binding.cartCount.text = "$it"
binding.cartCountView.setVisibility(it > 0)
}
}
} }

View File

@@ -1,9 +1,11 @@
package com.woka.shop.views.fragments.cart package com.woka.shop.views.fragments.cart
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
@@ -12,7 +14,9 @@ import com.woka.R
import com.woka.databinding.FragmentCartBinding import com.woka.databinding.FragmentCartBinding
import com.woka.networking.ApiResult import com.woka.networking.ApiResult
import com.woka.shop.adapters.CartAdapter import com.woka.shop.adapters.CartAdapter
import com.woka.shop.models.productlisting.ShopProduct
import com.woka.shop.viewmodels.CartViewModel import com.woka.shop.viewmodels.CartViewModel
import com.woka.shop.views.CartActivity
import com.woka.utils.ProgressView import com.woka.utils.ProgressView
import com.woka.utils.hide import com.woka.utils.hide
import com.woka.utils.show import com.woka.utils.show
@@ -65,35 +69,42 @@ class CartFragment: Fragment() {
private fun clickEvents() { private fun clickEvents() {
binding.apply { binding.apply {
adapter.onCartItemDeleteListener = {id, position -> adapter.onCartItemDeleteListener = {cartItem, position ->
lifecycleScope.launch { lifecycleScope.launch {
progressDialog.show(getString(R.string.removing_item)) progressDialog.show(getString(R.string.removing_item))
when (val response = viewModel.removeItem(id)){ cartItem.id?.let {
is ApiResult.Error -> { when (val response = viewModel.removeItem(it)){
progressDialog.hide() is ApiResult.Error -> {
toast(response.errorMessage) progressDialog.hide()
} toast(response.errorMessage)
is ApiResult.Loading -> {} }
is ApiResult.Success -> { is ApiResult.Loading -> {}
progressDialog.hide() is ApiResult.Success -> {
toast(response.message) progressDialog.hide()
toast(response.message)
try { try {
adapter.notifyItemRemoved(position) adapter.notifyItemRemoved(position)
} finally { } finally {
response.data?.let {cartValue -> response.data?.let {cartValue ->
if (cartValue > 0){ if (cartValue > 0){
val finalAmount = "$cartValue" val finalAmount = "$cartValue"
totalAmount.text = finalAmount totalAmount.text = finalAmount
}else{ }else{
rvCart.hide() rvCart.hide()
progressView.hide() progressView.hide()
checkoutView.hide() checkoutView.hide()
noDataView.show() noDataView.show()
}
} }
} }
viewModel.removedProducts.add(ShopProduct(cartItem, false))
activity?.setResult(AppCompatActivity.RESULT_OK, Intent().apply {
putParcelableArrayListExtra(CartActivity.EXTRA_REMOVED_CART_ITEMS, viewModel.removedProducts)
})
} }
} }
} }

View File

@@ -1,16 +1,28 @@
package com.woka.shop.views.fragments.shop package com.woka.shop.views.fragments.shop
import android.app.Activity.RESULT_OK
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.text.Html import android.text.Html
import androidx.fragment.app.Fragment
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import com.google.android.material.tabs.TabLayoutMediator import com.google.android.material.tabs.TabLayoutMediator
import com.woka.R import com.woka.R
import com.woka.databinding.FragmentProductBinding import com.woka.databinding.FragmentProductBinding
import com.woka.networking.ApiResult
import com.woka.shop.adapters.ProductImagesAdapter import com.woka.shop.adapters.ProductImagesAdapter
import com.woka.shop.models.productlisting.ShopProduct import com.woka.shop.models.productlisting.ShopProduct
import com.woka.shop.viewmodels.ShopViewModel
import com.woka.shop.views.CartActivity
import com.woka.utils.ProgressView
import com.woka.utils.toast
import kotlinx.coroutines.launch
class ProductFragment private constructor( class ProductFragment private constructor(
private val shopProduct: ShopProduct, private val shopProduct: ShopProduct,
@@ -23,18 +35,26 @@ class ProductFragment private constructor(
} }
private lateinit var binding: FragmentProductBinding private lateinit var binding: FragmentProductBinding
private lateinit var viewModel: ShopViewModel
private lateinit var imageAdapter: ProductImagesAdapter private lateinit var imageAdapter: ProductImagesAdapter
private lateinit var progressView: ProgressView
private lateinit var cartLauncher: ActivityResultLauncher<Intent>
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View { ): View {
binding = FragmentProductBinding.inflate(inflater, container, false) binding = FragmentProductBinding.inflate(inflater, container, false)
viewModel = ViewModelProvider(requireActivity())[ShopViewModel::class.java]
progressView = ProgressView(requireContext(), getString(R.string.please_wait))
val imageList = ArrayList<String>() val imageList = ArrayList<String>()
shopProduct.shop_image?.filterNotNull()?.let { shopProduct.shop_image?.filterNotNull()?.let {
imageList.addAll(it) imageList.addAll(it)
} }
imageAdapter = ProductImagesAdapter(imageList) imageAdapter = ProductImagesAdapter(imageList)
return binding.root return binding.root
} }
@@ -43,6 +63,10 @@ class ProductFragment private constructor(
initViews() initViews()
clickEvents()
registerLaunchers()
} }
private fun initViews() { private fun initViews() {
@@ -52,15 +76,77 @@ class ProductFragment private constructor(
TabLayoutMediator(tabLayout, vpImages){_, _ -> }.attach() TabLayoutMediator(tabLayout, vpImages){_, _ -> }.attach()
title.text = shopProduct.product_name
categoryName.text = category categoryName.text = category
skuId.text = shopProduct.sku_id skuId.text = shopProduct.sku_id
price.text = shopProduct.product_price price.text = shopProduct.product_price
description.text = Html.fromHtml( addToCart.text = if (shopProduct.added_to_cart == true){
shopProduct.shop_master_detail?.description_english, getString(R.string.view_cart)
Html.FROM_HTML_MODE_LEGACY }else{
) getString(R.string.add_to_cart)
}
if (shopProduct.sub_category_master_id == 12){
title.text = shopProduct.shop_master_detail?.product_name_english
description.text = Html.fromHtml(
shopProduct.shop_master_detail?.description_english,
Html.FROM_HTML_MODE_LEGACY
)
}else{
title.text = shopProduct.shop_master_detail?.product_name_hindi
description.text = Html.fromHtml(
shopProduct.shop_master_detail?.description_hindi,
Html.FROM_HTML_MODE_LEGACY
)
}
}
}
private fun clickEvents(){
binding.apply {
addToCart.setOnClickListener {
if (shopProduct.added_to_cart == false){
lifecycleScope.launch {
progressView.show()
when (val response = viewModel.addToCart(shopProduct)){
is ApiResult.Error -> {
progressView.hide()
toast(response.errorMessage)
}
is ApiResult.Loading -> {}
is ApiResult.Success -> {
progressView.hide()
toast(response.message)
shopProduct.added_to_cart = true
addToCart.text = getString(R.string.view_cart)
}
}
}
}else{
activity?.let {
cartLauncher.launch(Intent(it, CartActivity::class.java))
}
}
}
}
}
private fun registerLaunchers(){
cartLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){ activityResult ->
if (activityResult.resultCode == RESULT_OK){
@Suppress("DEPRECATION")
activityResult.data?.getParcelableArrayListExtra<ShopProduct>(CartActivity.EXTRA_REMOVED_CART_ITEMS)?.let {
viewModel.removeProductsFromCart(it)
if (it.toSet().contains(shopProduct)){
binding.addToCart.text = if (shopProduct.added_to_cart == true){
getString(R.string.view_cart)
}else{
getString(R.string.add_to_cart)
}
}
}
}
} }
} }
} }

View File

@@ -160,7 +160,7 @@ class ShopFragment3 private constructor(
} }
is ApiResult.Success -> { is ApiResult.Success -> {
it.data?.let { productList -> it.data?.toMutableList()?.let { productList ->
binding.rvProducts.show() binding.rvProducts.show()
binding.productShimmer.hide() binding.productShimmer.hide()

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape
android:innerRadius="0dp"
android:shape="ring"
android:thickness="3dp"
android:useLevel="false">
<solid android:color="@color/white" />
<stroke
android:width="1dp"
android:color="@color/color_primary"/>
</shape>
</item>
</layer-list>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/selected_shop_dot"
android:state_selected="true"/>
<item android:drawable="@drawable/default_shop_dot"/>
</selector>

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape
android:innerRadius="0dp"
android:shape="ring"
android:thickness="3dp"
android:useLevel="false">
<solid android:color="@color/color_primary" />
<stroke
android:width="1dp"
android:color="@android:color/darker_gray"/>
</shape>
</item>
</layer-list>

View File

@@ -57,11 +57,11 @@
<com.woka.utils.PressableImageView <com.woka.utils.PressableImageView
android:id="@+id/cart" android:id="@+id/cart"
android:visibility="visible" android:visibility="visible"
android:layout_width="@dimen/_30sdp" android:layout_width="@dimen/_34sdp"
android:layout_height="@dimen/_30sdp" android:layout_height="@dimen/_34sdp"
android:contentDescription="@string/image" android:contentDescription="@string/image"
android:src="@drawable/img_notification" android:src="@drawable/img_cart"
android:scaleType="fitXY" android:scaleType="fitXY"
android:layout_centerVertical="true" android:layout_centerVertical="true"

View File

@@ -52,7 +52,7 @@
<androidx.viewpager2.widget.ViewPager2 <androidx.viewpager2.widget.ViewPager2
android:id="@+id/vp_images" android:id="@+id/vp_images"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="150dp" android:layout_height="@dimen/_120sdp"
android:layout_marginTop="15dp" android:layout_marginTop="15dp"
/> />
@@ -61,11 +61,12 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom" android:layout_gravity="bottom"
app:tabBackground="@drawable/onboard_indicator_selector" app:tabBackground="@drawable/product_indicator_selector"
app:tabGravity="center" app:tabGravity="center"
app:tabIndicatorHeight="0dp" app:tabIndicatorHeight="0dp"
app:tabPaddingEnd="10dp" app:tabPaddingEnd="10dp"
app:tabPaddingStart="10dp" app:tabPaddingStart="10dp"
app:tabRippleColor="@android:color/transparent"
android:background="@android:color/transparent" android:background="@android:color/transparent"

View File

@@ -281,4 +281,5 @@
<string name="category_name">Category Name :</string> <string name="category_name">Category Name :</string>
<string name="sku_id">SKU Id :</string> <string name="sku_id">SKU Id :</string>
<string name="add_to_cart">ADD TO CART</string> <string name="add_to_cart">ADD TO CART</string>
<string name="view_cart">view cart</string>
</resources> </resources>