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:
@@ -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>>
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -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?
|
|
||||||
)
|
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -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)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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()
|
||||||
|
|
||||||
|
|||||||
BIN
app/src/main/res/drawable-hdpi/img_cart.png
Normal file
BIN
app/src/main/res/drawable-hdpi/img_cart.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
BIN
app/src/main/res/drawable-ldpi/img_cart.png
Normal file
BIN
app/src/main/res/drawable-ldpi/img_cart.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.9 KiB |
BIN
app/src/main/res/drawable-mdpi/img_cart.png
Normal file
BIN
app/src/main/res/drawable-mdpi/img_cart.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
BIN
app/src/main/res/drawable-xhdpi/img_cart.png
Normal file
BIN
app/src/main/res/drawable-xhdpi/img_cart.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
BIN
app/src/main/res/drawable-xxhdpi/img_cart.png
Normal file
BIN
app/src/main/res/drawable-xxhdpi/img_cart.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 76 KiB |
BIN
app/src/main/res/drawable-xxxhdpi/img_cart.png
Normal file
BIN
app/src/main/res/drawable-xxxhdpi/img_cart.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 117 KiB |
15
app/src/main/res/drawable/default_shop_dot.xml
Normal file
15
app/src/main/res/drawable/default_shop_dot.xml
Normal 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>
|
||||||
6
app/src/main/res/drawable/product_indicator_selector.xml
Normal file
6
app/src/main/res/drawable/product_indicator_selector.xml
Normal 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>
|
||||||
15
app/src/main/res/drawable/selected_shop_dot.xml
Normal file
15
app/src/main/res/drawable/selected_shop_dot.xml
Normal 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>
|
||||||
@@ -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"
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
Reference in New Issue
Block a user