Completed address Adding Uis and api integration.
Worked on getting callbacks for url change in PaymentActivity. Integrated sub-category api and its ui with tablyout Integrated product listing api and cached data in ShopViewModel for every super-category, category and sub-category. Created ProductFragment to showcase product details: Added viewpager and its adapter to show all images of a product in a sliding manner.
This commit is contained in:
@@ -52,6 +52,8 @@ ext.jwPlayerVersion = '4.17.0'
|
|||||||
ext.exoplayerVersion = '1.3.1'
|
ext.exoplayerVersion = '1.3.1'
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.32'
|
||||||
|
|
||||||
implementation "com.facebook.shimmer:shimmer:0.5.0"
|
implementation "com.facebook.shimmer:shimmer:0.5.0"
|
||||||
|
|
||||||
implementation "com.airbnb.android:lottie:6.4.0"
|
implementation "com.airbnb.android:lottie:6.4.0"
|
||||||
|
|||||||
@@ -20,7 +20,8 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name=".shop.views.AddressActivity"
|
android:name=".shop.views.AddressActivity"
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
android:screenOrientation="portrait" />
|
android:screenOrientation="portrait"
|
||||||
|
android:windowSoftInputMode="adjustPan" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".shop.views.PaymentActivity"
|
android:name=".shop.views.PaymentActivity"
|
||||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode|fontScale|fontWeightAdjustment|screenLayout"
|
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode|fontScale|fontWeightAdjustment|screenLayout"
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ object RetrofitHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// api response handler
|
// api response handler
|
||||||
fun <T>handleApiResponse(response: Response<ApiResponse<T>>): ApiResult<T> {
|
private fun <T>handleApiResponse(response: Response<ApiResponse<T>>): ApiResult<T> {
|
||||||
if (response.isSuccessful) {
|
if (response.isSuccessful) {
|
||||||
val body = response.body() ?: return ApiResult.Error(errorMessage = "Empty Response")
|
val body = response.body() ?: return ApiResult.Error(errorMessage = "Empty Response")
|
||||||
return when (body.success) {
|
return when (body.success) {
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ class OnboardFragment : Fragment() {
|
|||||||
private fun initViews() {
|
private fun initViews() {
|
||||||
binding.apply {
|
binding.apply {
|
||||||
viewPager.adapter = OnboardingAdapter()
|
viewPager.adapter = OnboardingAdapter()
|
||||||
TabLayoutMediator(tabLayout, viewPager){tab, position -> }.attach()
|
TabLayoutMediator(tabLayout, viewPager){_, _ -> }.attach()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ 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.edd.EDDResponse
|
import com.woka.shop.models.edd.EDDResponse
|
||||||
|
import com.woka.shop.models.productlisting.ProductListingResponse
|
||||||
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
|
||||||
@@ -31,6 +32,9 @@ interface ShopApiService {
|
|||||||
@POST("sub_category_listing")
|
@POST("sub_category_listing")
|
||||||
suspend fun subcategoryListing(@Body formBody: FormBody): Response<ApiResponse<SubCategoryResponse>>
|
suspend fun subcategoryListing(@Body formBody: FormBody): Response<ApiResponse<SubCategoryResponse>>
|
||||||
|
|
||||||
|
@POST("v2/shop_product_listing")
|
||||||
|
suspend fun productListing(@Body formBody: FormBody): Response<ApiResponse<ProductListingResponse>>
|
||||||
|
|
||||||
// cart
|
// cart
|
||||||
@GET("cart_listing")
|
@GET("cart_listing")
|
||||||
suspend fun cartListing(): Response<ApiResponse<CartResponse>>
|
suspend fun cartListing(): Response<ApiResponse<CartResponse>>
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ 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.edd.EDDResponse
|
import com.woka.shop.models.edd.EDDResponse
|
||||||
|
import com.woka.shop.models.productlisting.ProductListingResponse
|
||||||
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
|
||||||
@@ -51,6 +52,25 @@ object ShopRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun productListing(categoryId: String, subcategoryId: String?, pageNo: String, count: String): ApiResult<ProductListingResponse> {
|
||||||
|
return handleApiCall {
|
||||||
|
val bodyBuilder = FormBody.Builder()
|
||||||
|
bodyBuilder.add("category_id", categoryId)
|
||||||
|
|
||||||
|
subcategoryId?.let {
|
||||||
|
bodyBuilder.add("sub_category_id", it)
|
||||||
|
}
|
||||||
|
|
||||||
|
bodyBuilder.add("api_version", "v2")
|
||||||
|
bodyBuilder.add("start", pageNo)
|
||||||
|
bodyBuilder.add("limit", count)
|
||||||
|
|
||||||
|
apiService.productListing(
|
||||||
|
bodyBuilder.build()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// cart listing with loose caching
|
// cart listing with loose caching
|
||||||
private var cartResponse: CartResponse? = null
|
private var cartResponse: CartResponse? = null
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package com.woka.shop.adapters
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
|
import com.woka.databinding.ProductImageViewHolderBinding
|
||||||
|
|
||||||
|
class ProductImagesAdapter(
|
||||||
|
private val imageList: ArrayList<String>
|
||||||
|
) : RecyclerView.Adapter<ProductImagesAdapter.ImageViewHolder>(){
|
||||||
|
|
||||||
|
inner class ImageViewHolder(val binding: ProductImageViewHolderBinding): ViewHolder(binding.root)
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ImageViewHolder {
|
||||||
|
return ImageViewHolder(
|
||||||
|
ProductImageViewHolderBinding.inflate(
|
||||||
|
LayoutInflater.from(parent.context),
|
||||||
|
parent, false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount(): Int = imageList.size
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: ImageViewHolder, position: Int) {
|
||||||
|
Glide.with(holder.binding.root.context)
|
||||||
|
.load(imageList[holder.absoluteAdapterPosition])
|
||||||
|
.into(holder.binding.root)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package com.woka.shop.adapters
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.AsyncDifferConfig
|
||||||
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
|
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
||||||
|
import com.woka.databinding.ProductViewHolderBinding
|
||||||
|
import com.woka.shop.models.productlisting.ShopProduct
|
||||||
|
import java.util.concurrent.Executors
|
||||||
|
|
||||||
|
class ShopProductAdapter: ListAdapter<ShopProduct, ShopProductAdapter.ProductViewHolder>(ASYNC_DIFF_UTIL) {
|
||||||
|
companion object{
|
||||||
|
private val DIFF_UTIL = object :DiffUtil.ItemCallback<ShopProduct>(){
|
||||||
|
override fun areItemsTheSame(oldItem: ShopProduct, newItem: ShopProduct): Boolean = oldItem.id == newItem.id
|
||||||
|
override fun areContentsTheSame(oldItem: ShopProduct, newItem: ShopProduct): Boolean = oldItem == newItem
|
||||||
|
}
|
||||||
|
|
||||||
|
private val ASYNC_DIFF_UTIL = AsyncDifferConfig.Builder(DIFF_UTIL)
|
||||||
|
.setBackgroundThreadExecutor(Executors.newSingleThreadExecutor())
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class ProductViewHolder(val binding: ProductViewHolderBinding): ViewHolder(binding.root)
|
||||||
|
|
||||||
|
var onProductClicked: ((ShopProduct) -> Unit)? = null
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProductViewHolder {
|
||||||
|
return ProductViewHolder(
|
||||||
|
ProductViewHolderBinding.inflate(
|
||||||
|
LayoutInflater.from(parent.context),
|
||||||
|
parent,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: ProductViewHolder, position: Int) {
|
||||||
|
val product = getItem(holder.absoluteAdapterPosition)
|
||||||
|
|
||||||
|
with(holder.binding){
|
||||||
|
if (product.shop_image?.isNotEmpty() == true)
|
||||||
|
image.loadImage(product.shop_image.first())
|
||||||
|
|
||||||
|
title.text = product.product_name
|
||||||
|
price.text = "${product.product_price}"
|
||||||
|
|
||||||
|
root.setOnClickListener {
|
||||||
|
onProductClicked?.invoke(product)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package com.woka.shop.models.productlisting
|
||||||
|
|
||||||
|
data class ProductListingResponse(
|
||||||
|
val result: List<ShopProduct?>?,
|
||||||
|
val total_records: Int?
|
||||||
|
)
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package com.woka.shop.models.productlisting
|
||||||
|
|
||||||
|
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?
|
||||||
|
)
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.woka.shop.models.productlisting
|
||||||
|
|
||||||
|
data class ShopProduct(
|
||||||
|
val added_to_cart: Boolean?,
|
||||||
|
val category_master_id: Int?,
|
||||||
|
val id: Int?,
|
||||||
|
val product_name: String?,
|
||||||
|
val product_price: String?,
|
||||||
|
val product_thumbnail: String?,
|
||||||
|
val remain_stock_quantity: Int?,
|
||||||
|
val shop_image: List<String?>?,
|
||||||
|
val shop_master_detail: ShopMasterDetail?,
|
||||||
|
val sku_id: String?,
|
||||||
|
val stock_status: String?,
|
||||||
|
val sub_category_master_id: Int?,
|
||||||
|
val tax_category: Any?,
|
||||||
|
val tax_value: String?
|
||||||
|
)
|
||||||
@@ -7,8 +7,10 @@ import androidx.lifecycle.viewModelScope
|
|||||||
import com.woka.networking.ApiResult
|
import com.woka.networking.ApiResult
|
||||||
import com.woka.shop.ShopRepository
|
import com.woka.shop.ShopRepository
|
||||||
import com.woka.shop.models.categorylisting.CategoryData
|
import com.woka.shop.models.categorylisting.CategoryData
|
||||||
|
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 kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class ShopViewModel: ViewModel() {
|
class ShopViewModel: ViewModel() {
|
||||||
@@ -72,11 +74,12 @@ class ShopViewModel: ViewModel() {
|
|||||||
val subcategoryLiveData: LiveData<ApiResult<MutableList<SubCategoryData>>>
|
val subcategoryLiveData: LiveData<ApiResult<MutableList<SubCategoryData>>>
|
||||||
get() = _subcategoryLiveData
|
get() = _subcategoryLiveData
|
||||||
|
|
||||||
private val subcategoryDataMap = HashMap<String, MutableList<SubCategoryData>>()
|
val subcategoryDataMap = HashMap<String, MutableList<SubCategoryData>>()
|
||||||
|
|
||||||
fun loadSubCategories(categoryId: String){
|
fun loadSubCategories(superCategoryId: String, categoryId: String){
|
||||||
if (subcategoryDataMap.containsKey(categoryId)){
|
val key = "${superCategoryId}_$categoryId"
|
||||||
_subcategoryLiveData.postValue(ApiResult.Success(subcategoryDataMap[categoryId]))
|
if (subcategoryDataMap.containsKey(key)){
|
||||||
|
_subcategoryLiveData.postValue(ApiResult.Success(subcategoryDataMap[key]))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,7 +90,9 @@ class ShopViewModel: ViewModel() {
|
|||||||
is ApiResult.Loading -> {}
|
is ApiResult.Loading -> {}
|
||||||
is ApiResult.Success -> {
|
is ApiResult.Success -> {
|
||||||
response.data?.result?.filterNotNull()?.toMutableList()?.let {
|
response.data?.result?.filterNotNull()?.toMutableList()?.let {
|
||||||
subcategoryDataMap[categoryId] = it
|
// adding a all tag at start
|
||||||
|
it.add(0, SubCategoryData(null, null, "All", null))
|
||||||
|
subcategoryDataMap[key] = it
|
||||||
_subcategoryLiveData.postValue(ApiResult.Success(it))
|
_subcategoryLiveData.postValue(ApiResult.Success(it))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -98,4 +103,77 @@ class ShopViewModel: ViewModel() {
|
|||||||
fun clearSubCategoryLiveData(){
|
fun clearSubCategoryLiveData(){
|
||||||
_subcategoryLiveData.postValue(ApiResult.Loading())
|
_subcategoryLiveData.postValue(ApiResult.Loading())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// product listing
|
||||||
|
private val _productListingLiveData = MutableLiveData<ApiResult<MutableList<ShopProduct>>>()
|
||||||
|
val productListingLiveData: LiveData<ApiResult<MutableList<ShopProduct>>>
|
||||||
|
get() = _productListingLiveData
|
||||||
|
|
||||||
|
var productPagingData = HashMap<String, PagingData>()
|
||||||
|
|
||||||
|
// product data for every super-category, category and sub-category
|
||||||
|
private var productDataMap = HashMap<String, MutableList<ShopProduct>>()
|
||||||
|
|
||||||
|
fun loadProducts(superCategoryId: String, categoryId: String, subCategoryId: String?) {
|
||||||
|
val key = "${superCategoryId}_${categoryId}_$subCategoryId"
|
||||||
|
if (productDataMap.containsKey(key) && productDataMap[key]?.isNotEmpty() == true) {
|
||||||
|
_productListingLiveData.postValue(ApiResult.Success(productDataMap[key]))
|
||||||
|
} else {
|
||||||
|
loadMoreEpisodes(superCategoryId, categoryId, subCategoryId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun loadMoreEpisodes(superCategoryId: String, categoryId: String, subCategoryId: String?) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
_productListingLiveData.postValue(ApiResult.Loading())
|
||||||
|
|
||||||
|
val key = "${superCategoryId}_${categoryId}_$subCategoryId"
|
||||||
|
|
||||||
|
val pagingData = if (productPagingData.containsKey(key)) {
|
||||||
|
productPagingData[key]!!
|
||||||
|
} else {
|
||||||
|
val pagingData = PagingData()
|
||||||
|
productPagingData[key] = pagingData
|
||||||
|
pagingData
|
||||||
|
}
|
||||||
|
|
||||||
|
when (val response = repository.productListing(
|
||||||
|
categoryId,
|
||||||
|
subCategoryId,
|
||||||
|
"${pagingData.nextPageToLoad}",
|
||||||
|
"${pagingData.quantityPerPage}"
|
||||||
|
)) {
|
||||||
|
is ApiResult.Error -> {
|
||||||
|
_productListingLiveData.postValue(
|
||||||
|
ApiResult.Error(
|
||||||
|
response.errorMessage,
|
||||||
|
response.error
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
is ApiResult.Loading -> {
|
||||||
|
_productListingLiveData.postValue(ApiResult.Loading())
|
||||||
|
}
|
||||||
|
|
||||||
|
is ApiResult.Success -> {
|
||||||
|
response.data?.let { data ->
|
||||||
|
data.result?.filterNotNull()?.let { newList ->
|
||||||
|
val currentList = productDataMap.getOrDefault(key, ArrayList())
|
||||||
|
currentList.addAll(newList)
|
||||||
|
productDataMap[key] = currentList
|
||||||
|
|
||||||
|
pagingData.lastPage = productDataMap[key]?.size == data.total_records
|
||||||
|
pagingData.nextPageToLoad++
|
||||||
|
_productListingLiveData.postValue(ApiResult.Success(productDataMap[key]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clearProductListingLiveData() {
|
||||||
|
_productListingLiveData.postValue(ApiResult.Loading())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -11,6 +11,11 @@ import com.woka.utils.WokaBaseActivity
|
|||||||
|
|
||||||
class AddressActivity : WokaBaseActivity() {
|
class AddressActivity : WokaBaseActivity() {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val EXTRA_PRODUCT_IDS = "extra_product_ids"
|
||||||
|
const val EXTRA_COUPON_CODE = "extra_coupon_code"
|
||||||
|
}
|
||||||
|
|
||||||
private lateinit var binding: ActivityAddressBinding
|
private lateinit var binding: ActivityAddressBinding
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
@@ -24,10 +29,32 @@ class AddressActivity : WokaBaseActivity() {
|
|||||||
insets
|
insets
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.toolbar.title.text = getString(R.string.address_details)
|
initViews()
|
||||||
|
|
||||||
|
clickEvents()
|
||||||
|
|
||||||
supportFragmentManager.beginTransaction()
|
supportFragmentManager.beginTransaction()
|
||||||
.add(R.id.fcv_address, PinCodeFragment.newInstance())
|
.add(
|
||||||
|
R.id.fcv_address,
|
||||||
|
PinCodeFragment.newInstance(
|
||||||
|
intent.getIntegerArrayListExtra(EXTRA_PRODUCT_IDS),
|
||||||
|
intent.getStringExtra(EXTRA_COUPON_CODE)
|
||||||
|
)
|
||||||
|
)
|
||||||
.commit()
|
.commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun initViews() {
|
||||||
|
binding.apply {
|
||||||
|
toolbar.title.text = getString(R.string.address_details)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun clickEvents() {
|
||||||
|
binding.apply {
|
||||||
|
toolbar.backBtn.setOnClickListener {
|
||||||
|
onBackPressedDispatcher.onBackPressed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -5,15 +5,19 @@ import android.graphics.Color
|
|||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.webkit.WebSettings
|
import android.webkit.WebSettings
|
||||||
|
import android.webkit.WebView
|
||||||
import android.webkit.WebViewClient
|
import android.webkit.WebViewClient
|
||||||
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.lifecycleScope
|
||||||
import com.woka.R
|
import com.woka.R
|
||||||
import com.woka.databinding.ActivityPaymentBinding
|
import com.woka.databinding.ActivityPaymentBinding
|
||||||
import com.woka.utils.WokaBaseActivity
|
import com.woka.utils.WokaBaseActivity
|
||||||
import com.woka.utils.lightStatusBar
|
import com.woka.utils.lightStatusBar
|
||||||
import com.woka.utils.toast
|
import com.woka.utils.toast
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class PaymentActivity : WokaBaseActivity() {
|
class PaymentActivity : WokaBaseActivity() {
|
||||||
|
|
||||||
@@ -69,6 +73,22 @@ class PaymentActivity : WokaBaseActivity() {
|
|||||||
|
|
||||||
binding.webView.setWebViewClient(WebViewClient())
|
binding.webView.setWebViewClient(WebViewClient())
|
||||||
|
|
||||||
|
binding.webView.webViewClient = object : WebViewClient(){
|
||||||
|
override fun onPageFinished(view: WebView?, url: String?) {
|
||||||
|
super.onPageFinished(view, url)
|
||||||
|
if (url?.startsWith("https://secure.ccavenue.com/") == true){
|
||||||
|
if (url.contains("cancelTransaction")){
|
||||||
|
lifecycleScope.launch {
|
||||||
|
delay(2000)
|
||||||
|
runOnUiThread {
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
binding.webView.loadUrl(it)
|
binding.webView.loadUrl(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,187 @@
|
|||||||
|
package com.woka.shop.views.fragments.address
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import com.woka.R
|
||||||
|
import com.woka.databinding.FragmentAddAddressBinding
|
||||||
|
import com.woka.networking.ApiResult
|
||||||
|
import com.woka.shop.models.addaddress.AddAddressRequestData
|
||||||
|
import com.woka.shop.viewmodels.AddressViewModel
|
||||||
|
import com.woka.shop.viewmodels.CartViewModel
|
||||||
|
import com.woka.shop.views.PaymentActivity
|
||||||
|
import com.woka.utils.ProgressView
|
||||||
|
import com.woka.utils.setAsPhoneInput
|
||||||
|
import com.woka.utils.toast
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
class AddAddressFragment private constructor(
|
||||||
|
private val pinCode: String,
|
||||||
|
private val productIds: ArrayList<Int>?,
|
||||||
|
private val couponCode: String?
|
||||||
|
) : Fragment() {
|
||||||
|
|
||||||
|
private lateinit var binding: FragmentAddAddressBinding
|
||||||
|
private lateinit var viewModel: AddressViewModel
|
||||||
|
private lateinit var cartViewModel: CartViewModel
|
||||||
|
private lateinit var progressView: ProgressView
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
binding = FragmentAddAddressBinding.inflate(inflater, container, false)
|
||||||
|
viewModel = ViewModelProvider(requireActivity())[AddressViewModel::class.java]
|
||||||
|
cartViewModel = ViewModelProvider(requireActivity())[CartViewModel::class.java]
|
||||||
|
progressView = ProgressView(requireContext(), getString(R.string.please_wait))
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
initViews()
|
||||||
|
|
||||||
|
clickEvents()
|
||||||
|
|
||||||
|
setObservers()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun clickEvents() {
|
||||||
|
binding.apply {
|
||||||
|
submit.setOnClickListener {
|
||||||
|
if (allOkay()){
|
||||||
|
addAddress()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addAddress(){
|
||||||
|
lifecycleScope.launch {
|
||||||
|
binding.apply {
|
||||||
|
progressView.show()
|
||||||
|
|
||||||
|
val requestData = AddAddressRequestData(
|
||||||
|
addressName.text.toString(),
|
||||||
|
"${addressLine1.text}, ${addressLine2.text}",
|
||||||
|
city.text.toString(),
|
||||||
|
state.text.toString(),
|
||||||
|
pinCode,
|
||||||
|
phone.text.toString()
|
||||||
|
)
|
||||||
|
|
||||||
|
when (val response = viewModel.addAddress(requestData)){
|
||||||
|
is ApiResult.Error -> {
|
||||||
|
progressView.hide()
|
||||||
|
toast(response.errorMessage)
|
||||||
|
}
|
||||||
|
is ApiResult.Loading -> {}
|
||||||
|
is ApiResult.Success -> {
|
||||||
|
progressView.hide()
|
||||||
|
|
||||||
|
if (productIds != null){
|
||||||
|
cartViewModel.createOrder(
|
||||||
|
productIds,
|
||||||
|
couponCode,
|
||||||
|
"${response.data?.id}"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun allOkay(): Boolean {
|
||||||
|
var allOkay = true
|
||||||
|
|
||||||
|
binding.apply {
|
||||||
|
if (addressName.text.trim().isEmpty()){
|
||||||
|
addressName.error = getString(R.string.please_enter_name)
|
||||||
|
allOkay = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addressLine1.text.trim().length < 15){
|
||||||
|
addressLine1.error = getString(R.string.at_least_15_characters)
|
||||||
|
allOkay = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addressLine2.text.length < 15){
|
||||||
|
addressLine2.error = getString(R.string.at_least_15_characters)
|
||||||
|
allOkay = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (city.text.trim().length < 2){
|
||||||
|
city.error = getString(R.string.at_least_2_characters)
|
||||||
|
allOkay = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state.text.trim().length < 2){
|
||||||
|
state.error = getString(R.string.at_least_2_characters)
|
||||||
|
allOkay = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (country.text.trim().length < 2){
|
||||||
|
country.error = getString(R.string.at_least_2_characters)
|
||||||
|
allOkay = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (phone.text.trim().length < 10){
|
||||||
|
phone.error = getString(R.string.enter_10_digit_phone)
|
||||||
|
allOkay = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return allOkay
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initViews() {
|
||||||
|
binding.apply {
|
||||||
|
phone.setAsPhoneInput()
|
||||||
|
|
||||||
|
pincode.setText(pinCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setObservers(){
|
||||||
|
cartViewModel.createOrderLiveData.observe(viewLifecycleOwner){
|
||||||
|
when(it){
|
||||||
|
is ApiResult.Error -> {
|
||||||
|
progressView.hide()
|
||||||
|
toast(it.errorMessage)
|
||||||
|
}
|
||||||
|
is ApiResult.Loading -> {
|
||||||
|
progressView.show()
|
||||||
|
}
|
||||||
|
is ApiResult.Success -> {
|
||||||
|
progressView.hide()
|
||||||
|
|
||||||
|
it.data?.url?.let {paymentUrl ->
|
||||||
|
activity?.let {activity ->
|
||||||
|
activity.startActivity(
|
||||||
|
Intent(activity, PaymentActivity::class.java).apply {
|
||||||
|
putExtra(PaymentActivity.EXTRA_PAYMENT_LINK, paymentUrl)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
null -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
fun newInstance(pinCode: String,
|
||||||
|
productIds: ArrayList<Int>?,
|
||||||
|
couponCode: String?) = AddAddressFragment(pinCode, productIds, couponCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
package com.woka.shop.views.fragments.address
|
package com.woka.shop.views.fragments.address
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
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.core.widget.addTextChangedListener
|
import androidx.core.widget.addTextChangedListener
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.woka.R
|
import com.woka.R
|
||||||
@@ -13,10 +13,13 @@ import com.woka.databinding.FragmentPinCodeBinding
|
|||||||
import com.woka.networking.ApiResult
|
import com.woka.networking.ApiResult
|
||||||
import com.woka.shop.viewmodels.AddressViewModel
|
import com.woka.shop.viewmodels.AddressViewModel
|
||||||
import com.woka.utils.ProgressView
|
import com.woka.utils.ProgressView
|
||||||
import com.woka.utils.toast
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import java.util.ArrayList
|
||||||
|
|
||||||
class PinCodeFragment private constructor(): Fragment() {
|
class PinCodeFragment private constructor(
|
||||||
|
private val productIds: ArrayList<Int>?,
|
||||||
|
private val couponCode: String?
|
||||||
|
): Fragment() {
|
||||||
|
|
||||||
private lateinit var binding: FragmentPinCodeBinding
|
private lateinit var binding: FragmentPinCodeBinding
|
||||||
private lateinit var progressView: ProgressView
|
private lateinit var progressView: ProgressView
|
||||||
@@ -47,11 +50,15 @@ class PinCodeFragment private constructor(): Fragment() {
|
|||||||
binding.apply {
|
binding.apply {
|
||||||
btn.setOnClickListener {
|
btn.setOnClickListener {
|
||||||
if (selectedPinCode.length == 6){
|
if (selectedPinCode.length == 6){
|
||||||
toast(selectedPinCode)
|
parentFragmentManager.beginTransaction()
|
||||||
|
.add(R.id.fcv_address, AddAddressFragment.newInstance(selectedPinCode, productIds, couponCode))
|
||||||
|
.addToBackStack(null)
|
||||||
|
.commit()
|
||||||
|
|
||||||
return@setOnClickListener
|
return@setOnClickListener
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pincode.text.length < 6){
|
if (pincode.text.length != 6){
|
||||||
pincode.error = getString(R.string.enter_a_valid_pincode)
|
pincode.error = getString(R.string.enter_a_valid_pincode)
|
||||||
return@setOnClickListener
|
return@setOnClickListener
|
||||||
}
|
}
|
||||||
@@ -73,7 +80,6 @@ class PinCodeFragment private constructor(): Fragment() {
|
|||||||
|
|
||||||
selectedPinCode = pinCode
|
selectedPinCode = pinCode
|
||||||
btn.text = getString(R.string.proceed)
|
btn.text = getString(R.string.proceed)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -94,6 +100,8 @@ class PinCodeFragment private constructor(): Fragment() {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun newInstance() = PinCodeFragment()
|
fun newInstance(
|
||||||
|
productIds: ArrayList<Int>?,
|
||||||
|
couponCode: String?) = PinCodeFragment(productIds, couponCode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -14,6 +14,8 @@ import com.woka.shop.adapters.ParentAddressAdapter
|
|||||||
import com.woka.shop.models.cartlisting.CartResponse
|
import com.woka.shop.models.cartlisting.CartResponse
|
||||||
import com.woka.shop.viewmodels.CartViewModel
|
import com.woka.shop.viewmodels.CartViewModel
|
||||||
import com.woka.shop.views.AddressActivity
|
import com.woka.shop.views.AddressActivity
|
||||||
|
import com.woka.shop.views.AddressActivity.Companion.EXTRA_COUPON_CODE
|
||||||
|
import com.woka.shop.views.AddressActivity.Companion.EXTRA_PRODUCT_IDS
|
||||||
import com.woka.shop.views.PaymentActivity
|
import com.woka.shop.views.PaymentActivity
|
||||||
import com.woka.shop.views.PaymentActivity.Companion.EXTRA_PAYMENT_LINK
|
import com.woka.shop.views.PaymentActivity.Companion.EXTRA_PAYMENT_LINK
|
||||||
import com.woka.utils.ProgressView
|
import com.woka.utils.ProgressView
|
||||||
@@ -21,6 +23,7 @@ import com.woka.utils.hide
|
|||||||
import com.woka.utils.setVisibility
|
import com.woka.utils.setVisibility
|
||||||
import com.woka.utils.show
|
import com.woka.utils.show
|
||||||
import com.woka.utils.toast
|
import com.woka.utils.toast
|
||||||
|
import java.util.ArrayList
|
||||||
|
|
||||||
class ParentAddressFragment : Fragment() {
|
class ParentAddressFragment : Fragment() {
|
||||||
|
|
||||||
@@ -67,17 +70,7 @@ class ParentAddressFragment : Fragment() {
|
|||||||
private fun clickEvents(){
|
private fun clickEvents(){
|
||||||
binding.apply {
|
binding.apply {
|
||||||
selectAddress.setOnClickListener {
|
selectAddress.setOnClickListener {
|
||||||
val productIds = ArrayList<Int>()
|
val productIds = getProductIds()
|
||||||
|
|
||||||
if (viewModel.cartListLiveData.value is ApiResult.Success){
|
|
||||||
(viewModel.cartListLiveData.value as ApiResult.Success<CartResponse>).data?.result?.let {
|
|
||||||
for (cartItem in it){
|
|
||||||
cartItem?.id?.let {id ->
|
|
||||||
productIds.add(id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (productIds.isEmpty()){
|
if (productIds.isEmpty()){
|
||||||
toast(getString(R.string.no_products_added_to_cart))
|
toast(getString(R.string.no_products_added_to_cart))
|
||||||
@@ -94,12 +87,33 @@ class ParentAddressFragment : Fragment() {
|
|||||||
|
|
||||||
addNewAddress.setOnClickListener {
|
addNewAddress.setOnClickListener {
|
||||||
activity?.let {
|
activity?.let {
|
||||||
it.startActivity(Intent(it, AddressActivity::class.java))
|
it.startActivity(
|
||||||
|
Intent(it, AddressActivity::class.java).apply {
|
||||||
|
putIntegerArrayListExtra(EXTRA_PRODUCT_IDS, getProductIds())
|
||||||
|
putExtra(EXTRA_COUPON_CODE, viewModel.appliedCoupon)
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getProductIds(): ArrayList<Int> {
|
||||||
|
val productIds = ArrayList<Int>()
|
||||||
|
|
||||||
|
if (viewModel.cartListLiveData.value is ApiResult.Success){
|
||||||
|
(viewModel.cartListLiveData.value as ApiResult.Success<CartResponse>).data?.result?.let {
|
||||||
|
for (cartItem in it){
|
||||||
|
cartItem?.id?.let {id ->
|
||||||
|
productIds.add(id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return productIds
|
||||||
|
}
|
||||||
|
|
||||||
private fun setObservers() {
|
private fun setObservers() {
|
||||||
adapter.addressSelectListener = { addressId ->
|
adapter.addressSelectListener = { addressId ->
|
||||||
binding.selectAddress.show()
|
binding.selectAddress.show()
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
package com.woka.shop.views.fragments.shop
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.text.Html
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import com.google.android.material.tabs.TabLayoutMediator
|
||||||
|
import com.woka.R
|
||||||
|
import com.woka.databinding.FragmentProductBinding
|
||||||
|
import com.woka.shop.adapters.ProductImagesAdapter
|
||||||
|
import com.woka.shop.models.productlisting.ShopProduct
|
||||||
|
|
||||||
|
class ProductFragment private constructor(
|
||||||
|
private val shopProduct: ShopProduct,
|
||||||
|
private val category: String
|
||||||
|
): Fragment() {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
fun newInstance(shopProduct: ShopProduct, categoryName: String) = ProductFragment(shopProduct, categoryName)
|
||||||
|
}
|
||||||
|
|
||||||
|
private lateinit var binding: FragmentProductBinding
|
||||||
|
private lateinit var imageAdapter: ProductImagesAdapter
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
binding = FragmentProductBinding.inflate(inflater, container, false)
|
||||||
|
val imageList = ArrayList<String>()
|
||||||
|
shopProduct.shop_image?.filterNotNull()?.let {
|
||||||
|
imageList.addAll(it)
|
||||||
|
}
|
||||||
|
imageAdapter = ProductImagesAdapter(imageList)
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
initViews()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initViews() {
|
||||||
|
binding.apply {
|
||||||
|
|
||||||
|
vpImages.adapter = imageAdapter
|
||||||
|
|
||||||
|
TabLayoutMediator(tabLayout, vpImages){_, _ -> }.attach()
|
||||||
|
|
||||||
|
title.text = shopProduct.product_name
|
||||||
|
categoryName.text = category
|
||||||
|
skuId.text = shopProduct.sku_id
|
||||||
|
price.text = shopProduct.product_price
|
||||||
|
|
||||||
|
description.text = Html.fromHtml(
|
||||||
|
shopProduct.shop_master_detail?.description_english,
|
||||||
|
Html.FROM_HTML_MODE_LEGACY
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -62,7 +62,7 @@ class ShopFragment2 private constructor(private val superCategoryId: String): Fr
|
|||||||
|
|
||||||
adapter.onCategoryClickListener = {
|
adapter.onCategoryClickListener = {
|
||||||
parentFragmentManager.beginTransaction()
|
parentFragmentManager.beginTransaction()
|
||||||
.replace(R.id.fcv_shop, ShopFragment3.newInstance("${it.id}"))
|
.replace(R.id.fcv_shop, ShopFragment3.newInstance(superCategoryId, "${it.id}", "${it.title}"))
|
||||||
.addToBackStack(null)
|
.addToBackStack(null)
|
||||||
.commitAllowingStateLoss()
|
.commitAllowingStateLoss()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,19 +6,33 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import com.google.android.material.tabs.TabLayout
|
||||||
|
import com.woka.R
|
||||||
import com.woka.databinding.FragmentShop3Binding
|
import com.woka.databinding.FragmentShop3Binding
|
||||||
import com.woka.networking.ApiResult
|
import com.woka.networking.ApiResult
|
||||||
import com.woka.shop.adapters.CategoryAdapter
|
import com.woka.shop.adapters.ShopProductAdapter
|
||||||
import com.woka.shop.models.BaseCategory
|
|
||||||
import com.woka.shop.viewmodels.ShopViewModel
|
import com.woka.shop.viewmodels.ShopViewModel
|
||||||
import com.woka.utils.hide
|
import com.woka.utils.hide
|
||||||
|
import com.woka.utils.setVisibility
|
||||||
import com.woka.utils.show
|
import com.woka.utils.show
|
||||||
|
|
||||||
class ShopFragment3 private constructor(private val categoryId: String): Fragment() {
|
class ShopFragment3 private constructor(
|
||||||
|
private val superCategoryId: String,
|
||||||
|
private val categoryId: String,
|
||||||
|
private val categoryName: String
|
||||||
|
) : Fragment(), TabLayout.OnTabSelectedListener {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
fun newInstance(superCategoryId: String, categoryId: String, categoryName: String) =
|
||||||
|
ShopFragment3(superCategoryId, categoryId, categoryName)
|
||||||
|
}
|
||||||
|
|
||||||
private lateinit var binding: FragmentShop3Binding
|
private lateinit var binding: FragmentShop3Binding
|
||||||
private lateinit var viewModel: ShopViewModel
|
private lateinit var viewModel: ShopViewModel
|
||||||
private lateinit var adapter: CategoryAdapter
|
private lateinit var productAdapter: ShopProductAdapter
|
||||||
|
|
||||||
|
private var loadMoreProducts = false
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
@@ -26,7 +40,7 @@ class ShopFragment3 private constructor(private val categoryId: String): Fragmen
|
|||||||
): View {
|
): View {
|
||||||
binding = FragmentShop3Binding.inflate(inflater, container, false)
|
binding = FragmentShop3Binding.inflate(inflater, container, false)
|
||||||
viewModel = ViewModelProvider(requireActivity())[ShopViewModel::class.java]
|
viewModel = ViewModelProvider(requireActivity())[ShopViewModel::class.java]
|
||||||
adapter = CategoryAdapter()
|
productAdapter = ShopProductAdapter()
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,28 +53,53 @@ class ShopFragment3 private constructor(private val categoryId: String): Fragmen
|
|||||||
|
|
||||||
setObservers()
|
setObservers()
|
||||||
|
|
||||||
viewModel.loadSubCategories(categoryId)
|
viewModel.loadSubCategories(superCategoryId, categoryId)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
viewModel.clearSubCategoryLiveData()
|
viewModel.clearSubCategoryLiveData()
|
||||||
|
viewModel.clearProductListingLiveData()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initViews() {
|
private fun initViews() {
|
||||||
binding.apply {
|
binding.apply {
|
||||||
rvCategory.adapter = adapter
|
categoryTabs.addOnTabSelectedListener(this@ShopFragment3)
|
||||||
|
|
||||||
|
rvProducts.adapter = productAdapter
|
||||||
|
rvProducts.itemAnimator = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun clickEvents() {
|
private fun clickEvents() {
|
||||||
binding.apply {
|
binding.apply {
|
||||||
retryButton.setOnClickListener {
|
retryButton.setOnClickListener {
|
||||||
viewModel.loadSubCategories(categoryId)
|
viewModel.loadSubCategories(superCategoryId, categoryId)
|
||||||
}
|
}
|
||||||
|
|
||||||
adapter.onCategoryClickListener = {
|
prodLoadMoreBtn.setOnClickListener {
|
||||||
|
loadMoreProducts = true
|
||||||
|
val subCategoryId = categoryTabs.getTabAt(categoryTabs.selectedTabPosition)?.tag?.toString()
|
||||||
|
viewModel.loadMoreEpisodes(superCategoryId, categoryId, subCategoryId)
|
||||||
|
}
|
||||||
|
|
||||||
|
productAdapter.onProductClicked = {
|
||||||
|
parentFragmentManager.beginTransaction()
|
||||||
|
.add(R.id.fcv_shop, ProductFragment.newInstance(it, categoryName))
|
||||||
|
.addToBackStack(null)
|
||||||
|
.commit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadProducts() {
|
||||||
|
val selectedTabPos = binding.categoryTabs.selectedTabPosition
|
||||||
|
if (selectedTabPos >= 0) {
|
||||||
|
viewModel.subcategoryDataMap["${superCategoryId}_$categoryId"]?.let { subCategories ->
|
||||||
|
if (selectedTabPos < subCategories.size) {
|
||||||
|
loadMoreProducts = false
|
||||||
|
viewModel.loadProducts(superCategoryId, categoryId, subCategories[selectedTabPos].id?.toString())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -70,31 +109,74 @@ class ShopFragment3 private constructor(private val categoryId: String): Fragmen
|
|||||||
viewModel.subcategoryLiveData.observe(viewLifecycleOwner) {
|
viewModel.subcategoryLiveData.observe(viewLifecycleOwner) {
|
||||||
when (it) {
|
when (it) {
|
||||||
is ApiResult.Error -> {
|
is ApiResult.Error -> {
|
||||||
rvCategory.hide()
|
categoryTabs.hide()
|
||||||
shimmer.hide()
|
categoryShimmer.hide()
|
||||||
errorView.show()
|
errorView.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
is ApiResult.Loading -> {
|
is ApiResult.Loading -> {
|
||||||
rvCategory.hide()
|
categoryTabs.hide()
|
||||||
shimmer.show()
|
categoryShimmer.show()
|
||||||
errorView.hide()
|
errorView.hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
is ApiResult.Success -> {
|
is ApiResult.Success -> {
|
||||||
it.data?.let { categoryList ->
|
it.data?.let { categoryList ->
|
||||||
adapter.submitList(categoryList.map { category ->
|
categoryTabs.show()
|
||||||
BaseCategory(
|
categoryShimmer.hide()
|
||||||
category.id,
|
errorView.hide()
|
||||||
category.sub_category_thumbnail,
|
for (category in categoryList) {
|
||||||
category.sub_category_name
|
binding.categoryTabs.addTab(
|
||||||
|
binding.categoryTabs.newTab()
|
||||||
|
.setText("${category.sub_category_name}")
|
||||||
|
.setTag(category.id)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
) {
|
}
|
||||||
rvCategory.show()
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
shimmer.hide()
|
viewModel.productListingLiveData.observe(viewLifecycleOwner){
|
||||||
errorView.hide()
|
when (it) {
|
||||||
|
is ApiResult.Error -> {
|
||||||
|
binding.productShimmer.hide()
|
||||||
|
if (loadMoreProducts) {
|
||||||
|
// load more
|
||||||
|
binding.prodLoadMoreBtn.text = getString(R.string.retry)
|
||||||
|
binding.prodLoadMoreBtn.show()
|
||||||
|
} else {
|
||||||
|
// first time load
|
||||||
|
binding.rvProducts.hide()
|
||||||
|
binding.productShimmer.hide()
|
||||||
|
binding.prodLoadMoreBtn.hide()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is ApiResult.Loading -> {
|
||||||
|
binding.productShimmer.show()
|
||||||
|
binding.prodLoadMoreBtn.hide()
|
||||||
|
binding.rvProducts.setVisibility(loadMoreProducts)
|
||||||
|
}
|
||||||
|
|
||||||
|
is ApiResult.Success -> {
|
||||||
|
it.data?.let { productList ->
|
||||||
|
binding.rvProducts.show()
|
||||||
|
binding.productShimmer.hide()
|
||||||
|
|
||||||
|
binding.prodLoadMoreBtn.text = getString(R.string.load_more)
|
||||||
|
val subCategoryId = categoryTabs.getTabAt(categoryTabs.selectedTabPosition)?.tag
|
||||||
|
binding.prodLoadMoreBtn.setVisibility(viewModel.productPagingData["${superCategoryId}_${categoryId}_$subCategoryId"]?.lastPage == false)
|
||||||
|
|
||||||
|
if (loadMoreProducts) {
|
||||||
|
// loaded more data
|
||||||
|
productAdapter.notifyItemRangeInserted(
|
||||||
|
productAdapter.currentList.size,
|
||||||
|
productList.size
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
// new category data load
|
||||||
|
productAdapter.submitList(productList)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,8 +185,11 @@ class ShopFragment3 private constructor(private val categoryId: String): Fragmen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
override fun onTabSelected(p0: TabLayout.Tab?) {
|
||||||
@JvmStatic
|
loadProducts()
|
||||||
fun newInstance(categoryId: String) = ShopFragment3(categoryId)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onTabUnselected(p0: TabLayout.Tab?) {}
|
||||||
|
override fun onTabReselected(p0: TabLayout.Tab?) {}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -7,14 +7,19 @@ import android.content.Context
|
|||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import android.net.ConnectivityManager
|
import android.net.ConnectivityManager
|
||||||
import android.net.NetworkCapabilities
|
import android.net.NetworkCapabilities
|
||||||
|
import android.text.InputFilter
|
||||||
|
import android.text.Spanned
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.View.GONE
|
import android.view.View.GONE
|
||||||
import android.view.View.VISIBLE
|
import android.view.View.VISIBLE
|
||||||
import android.view.Window
|
import android.view.Window
|
||||||
import android.view.inputmethod.InputMethodManager
|
import android.view.inputmethod.InputMethodManager
|
||||||
|
import android.widget.EditText
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.core.view.WindowCompat
|
import androidx.core.view.WindowCompat
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
|
import com.google.i18n.phonenumbers.PhoneNumberUtil
|
||||||
|
import com.google.i18n.phonenumbers.Phonenumber
|
||||||
import com.woka.WokaApp.Companion.userPrefs
|
import com.woka.WokaApp.Companion.userPrefs
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import kotlin.math.ceil
|
import kotlin.math.ceil
|
||||||
@@ -100,4 +105,37 @@ fun Context.isNetworkConnected(): Boolean {
|
|||||||
val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return false
|
val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return false
|
||||||
return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) ||
|
return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) ||
|
||||||
capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
|
capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun EditText.setAsPhoneInput(){
|
||||||
|
// phone number formatting
|
||||||
|
// to deal with input pasting in the edit text
|
||||||
|
|
||||||
|
val phoneFilter = InputFilter { charSequence: CharSequence, _: Int, _: Int, _: Spanned?, _: Int, _: Int ->
|
||||||
|
var phoneNumberStr = charSequence.toString()
|
||||||
|
try {
|
||||||
|
val phoneNumberUtil: PhoneNumberUtil = PhoneNumberUtil.getInstance()
|
||||||
|
val phoneNumber: Phonenumber.PhoneNumber = phoneNumberUtil.parse(charSequence, "US")
|
||||||
|
phoneNumberStr = java.lang.String.valueOf(phoneNumber.nationalNumber)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
// nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
if (phoneNumberStr.length > 10) {
|
||||||
|
// pasted number length is greater than 10
|
||||||
|
return@InputFilter phoneNumberStr.substring(0, 10)
|
||||||
|
}
|
||||||
|
val totalPhoneNumber: String = text.toString() + phoneNumberStr
|
||||||
|
|
||||||
|
error = null
|
||||||
|
|
||||||
|
if (totalPhoneNumber.length > 10) {
|
||||||
|
// max length should be 10
|
||||||
|
return@InputFilter ""
|
||||||
|
} else {
|
||||||
|
return@InputFilter phoneNumberStr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
filters = arrayOf(phoneFilter)
|
||||||
}
|
}
|
||||||
6
app/src/main/java/com/woka/utils/PagingData.kt
Normal file
6
app/src/main/java/com/woka/utils/PagingData.kt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
package com.woka.utils
|
||||||
|
|
||||||
|
data class PagingData(
|
||||||
|
var nextPageToLoad: Int = 0, var quantityPerPage: Int = 6,
|
||||||
|
var lastPage: Boolean = false
|
||||||
|
)
|
||||||
@@ -8,6 +8,7 @@ import com.jwplayer.pub.api.media.playlists.PlaylistItem
|
|||||||
import com.woka.modules.categorymodels.CategoriesResponse
|
import com.woka.modules.categorymodels.CategoriesResponse
|
||||||
import com.woka.networking.ApiResult
|
import com.woka.networking.ApiResult
|
||||||
import com.woka.players.models.VideoPlayList
|
import com.woka.players.models.VideoPlayList
|
||||||
|
import com.woka.utils.PagingData
|
||||||
import com.woka.webseries.WebSeriesRepository
|
import com.woka.webseries.WebSeriesRepository
|
||||||
import com.woka.webseries.models.ContinueEpisodeResponse
|
import com.woka.webseries.models.ContinueEpisodeResponse
|
||||||
import com.woka.webseries.models.ShowData
|
import com.woka.webseries.models.ShowData
|
||||||
@@ -20,11 +21,6 @@ class WebSeriesViewModel : ViewModel() {
|
|||||||
|
|
||||||
private val repository = WebSeriesRepository
|
private val repository = WebSeriesRepository
|
||||||
|
|
||||||
data class PagingData(
|
|
||||||
var nextPageToLoad: Int = 0, var quantityPerPage: Int = 6,
|
|
||||||
var lastPage: Boolean = false
|
|
||||||
)
|
|
||||||
|
|
||||||
// categories listing
|
// categories listing
|
||||||
|
|
||||||
private val _showCategoryLiveData = MutableLiveData<ApiResult<CategoriesResponse>>()
|
private val _showCategoryLiveData = MutableLiveData<ApiResult<CategoriesResponse>>()
|
||||||
|
|||||||
5
app/src/main/res/drawable/ic_cart_filled.xml
Normal file
5
app/src/main/res/drawable/ic_cart_filled.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:viewportHeight="18" android:viewportWidth="18" android:width="24dp">
|
||||||
|
|
||||||
|
<path android:fillColor="#ffffff" android:pathData="M0.5,1.25C0.5,0.836 0.836,0.5 1.25,0.5H1.808C2.759,0.5 3.328,1.139 3.653,1.733C3.87,2.129 4.027,2.588 4.15,3.004C4.183,3.001 4.217,3 4.251,3H16.748C17.578,3 18.178,3.794 17.95,4.593L16.122,11.002C15.786,12.183 14.706,12.998 13.478,12.998H7.53C6.291,12.998 5.206,12.17 4.878,10.976L4.117,8.205L2.859,3.956L2.857,3.948C2.701,3.381 2.555,2.85 2.338,2.454C2.127,2.069 1.959,2 1.808,2H1.25C0.836,2 0.5,1.664 0.5,1.25ZM7,18C8.105,18 9,17.105 9,16C9,14.895 8.105,14 7,14C5.895,14 5,14.895 5,16C5,17.105 5.895,18 7,18ZM14,18C15.105,18 16,17.105 16,16C16,14.895 15.105,14 14,14C12.895,14 12,14.895 12,16C12,17.105 12.895,18 14,18Z"/>
|
||||||
|
|
||||||
|
</vector>
|
||||||
@@ -2,14 +2,14 @@
|
|||||||
<selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:aapt="http://schemas.android.com/aapt">
|
<selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:aapt="http://schemas.android.com/aapt">
|
||||||
<item android:state_selected="true">
|
<item android:state_selected="true">
|
||||||
<shape android:shape="rectangle">
|
<shape android:shape="rectangle">
|
||||||
<stroke android:width="10dp" android:color="@color/color_primary"/>
|
<stroke android:width="10dp" android:color="@android:color/transparent"/>
|
||||||
<corners android:radius="25dp"/>
|
<corners android:radius="25dp"/>
|
||||||
<solid android:color="#5e1fc4"/>
|
<solid android:color="#5e1fc4"/>
|
||||||
</shape>
|
</shape>
|
||||||
</item>
|
</item>
|
||||||
<item android:state_selected="false">
|
<item android:state_selected="false">
|
||||||
<shape android:shape="rectangle">
|
<shape android:shape="rectangle">
|
||||||
<stroke android:width="10dp" android:color="@color/color_primary"/>
|
<stroke android:width="10dp" android:color="@android:color/transparent"/>
|
||||||
<corners android:radius="25dp"/>
|
<corners android:radius="25dp"/>
|
||||||
<solid android:color="@color/white"/>
|
<solid android:color="@color/white"/>
|
||||||
</shape>
|
</shape>
|
||||||
|
|||||||
18
app/src/main/res/drawable/sub_category_tab_bg.xml
Normal file
18
app/src/main/res/drawable/sub_category_tab_bg.xml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:aapt="http://schemas.android.com/aapt">
|
||||||
|
<item android:state_selected="true">
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<stroke android:width="10dp" android:color="@android:color/transparent"/>
|
||||||
|
<corners android:radius="25dp"/>
|
||||||
|
<solid android:color="@color/color_primary"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
<item android:state_selected="false">
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<stroke android:width="10dp" android:color="@android:color/transparent"/>
|
||||||
|
<corners android:radius="25dp"/>
|
||||||
|
<solid android:color="@color/white"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
</selector>
|
||||||
394
app/src/main/res/layout/fragment_add_address.xml
Normal file
394
app/src/main/res/layout/fragment_add_address.xml
Normal file
@@ -0,0 +1,394 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@drawable/grad_my_list"
|
||||||
|
tools:context=".shop.views.fragments.address.AddAddressFragment">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="15dp"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
|
android:text="@string/add_new_address"
|
||||||
|
android:fontFamily="@font/exo_2_bold"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="@dimen/_14ssp"
|
||||||
|
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:layout_gravity="start"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
|
android:text="@string/address_name_firstname_and_lastname"
|
||||||
|
android:fontFamily="@font/exo_2_semibold"
|
||||||
|
android:textColor="@color/color_primary"
|
||||||
|
android:textSize="@dimen/_12ssp"
|
||||||
|
android:textAlignment="center"
|
||||||
|
|
||||||
|
android:layout_marginTop="25dp"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/address_name"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:layout_marginBottom="15dp"
|
||||||
|
android:autofillHints="name"
|
||||||
|
android:background="@drawable/round_25_shadow"
|
||||||
|
|
||||||
|
android:digits="@string/alphabets_with_space"
|
||||||
|
android:elevation="5dp"
|
||||||
|
|
||||||
|
android:fontFamily="@font/exo_2"
|
||||||
|
android:hint="@string/enter_address_name"
|
||||||
|
android:inputType="textPersonName"
|
||||||
|
android:nextFocusDown="@id/address_line_1"
|
||||||
|
|
||||||
|
android:paddingHorizontal="20dp"
|
||||||
|
|
||||||
|
android:paddingVertical="12dp"
|
||||||
|
android:singleLine="true"
|
||||||
|
|
||||||
|
android:textAlignment="center"
|
||||||
|
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textColorHint="@android:color/darker_gray"
|
||||||
|
|
||||||
|
android:textSize="@dimen/_12ssp"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
|
android:text="@string/address_line_1"
|
||||||
|
android:fontFamily="@font/exo_2_semibold"
|
||||||
|
android:textColor="@color/color_primary"
|
||||||
|
android:textSize="@dimen/_12ssp"
|
||||||
|
android:textAlignment="center"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/address_line_1"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:fontFamily="@font/exo_2"
|
||||||
|
android:textSize="@dimen/_12ssp"
|
||||||
|
android:textAlignment="center"
|
||||||
|
|
||||||
|
android:hint="@string/enter_address_line_1"
|
||||||
|
android:textColorHint="@android:color/darker_gray"
|
||||||
|
|
||||||
|
android:autofillHints="postalAddress"
|
||||||
|
android:inputType="textPostalAddress"
|
||||||
|
android:digits="@string/alphanumeric_special_characters_with_space"
|
||||||
|
android:singleLine="true"
|
||||||
|
|
||||||
|
android:background="@drawable/round_25_shadow"
|
||||||
|
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:layout_marginBottom="15dp"
|
||||||
|
|
||||||
|
android:elevation="5dp"
|
||||||
|
|
||||||
|
android:paddingHorizontal="20dp"
|
||||||
|
android:paddingVertical="12dp"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
|
android:text="@string/address_line_2"
|
||||||
|
android:fontFamily="@font/exo_2_semibold"
|
||||||
|
android:textColor="@color/color_primary"
|
||||||
|
android:textSize="@dimen/_12ssp"
|
||||||
|
android:textAlignment="center"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/address_line_2"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:fontFamily="@font/exo_2"
|
||||||
|
android:textSize="@dimen/_12ssp"
|
||||||
|
android:textAlignment="center"
|
||||||
|
|
||||||
|
android:hint="@string/enter_address_line_2"
|
||||||
|
android:textColorHint="@android:color/darker_gray"
|
||||||
|
|
||||||
|
android:autofillHints="postalAddress"
|
||||||
|
android:inputType="textPostalAddress"
|
||||||
|
android:digits="@string/alphanumeric_special_characters_with_space"
|
||||||
|
android:singleLine="true"
|
||||||
|
|
||||||
|
android:background="@drawable/round_25_shadow"
|
||||||
|
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:layout_marginBottom="15dp"
|
||||||
|
|
||||||
|
android:elevation="5dp"
|
||||||
|
|
||||||
|
android:paddingHorizontal="20dp"
|
||||||
|
android:paddingVertical="12dp"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
|
android:text="@string/city"
|
||||||
|
android:fontFamily="@font/exo_2_semibold"
|
||||||
|
android:textColor="@color/color_primary"
|
||||||
|
android:textSize="@dimen/_12ssp"
|
||||||
|
android:textAlignment="center"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/city"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:fontFamily="@font/exo_2"
|
||||||
|
android:textSize="@dimen/_12ssp"
|
||||||
|
android:textAlignment="center"
|
||||||
|
|
||||||
|
android:hint="@string/enter_city"
|
||||||
|
android:textColorHint="@android:color/darker_gray"
|
||||||
|
|
||||||
|
android:autofillHints="postalAddress"
|
||||||
|
android:inputType="textPostalAddress"
|
||||||
|
android:digits="@string/alphanumeric_special_characters_with_space"
|
||||||
|
android:singleLine="true"
|
||||||
|
|
||||||
|
android:background="@drawable/round_25_shadow"
|
||||||
|
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:layout_marginBottom="15dp"
|
||||||
|
|
||||||
|
android:elevation="5dp"
|
||||||
|
|
||||||
|
android:paddingHorizontal="20dp"
|
||||||
|
android:paddingVertical="12dp"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
|
android:text="@string/state"
|
||||||
|
android:fontFamily="@font/exo_2_semibold"
|
||||||
|
android:textColor="@color/color_primary"
|
||||||
|
android:textSize="@dimen/_12ssp"
|
||||||
|
android:textAlignment="center"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/state"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:fontFamily="@font/exo_2"
|
||||||
|
android:textSize="@dimen/_12ssp"
|
||||||
|
android:textAlignment="center"
|
||||||
|
|
||||||
|
android:hint="@string/enter_state"
|
||||||
|
android:textColorHint="@android:color/darker_gray"
|
||||||
|
|
||||||
|
android:autofillHints="postalAddress"
|
||||||
|
android:inputType="textPostalAddress"
|
||||||
|
android:digits="@string/alphanumeric_special_characters_with_space"
|
||||||
|
android:singleLine="true"
|
||||||
|
|
||||||
|
android:background="@drawable/round_25_shadow"
|
||||||
|
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:layout_marginBottom="15dp"
|
||||||
|
|
||||||
|
android:elevation="5dp"
|
||||||
|
|
||||||
|
android:paddingHorizontal="20dp"
|
||||||
|
android:paddingVertical="12dp"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
|
android:text="@string/pincode"
|
||||||
|
android:fontFamily="@font/exo_2_semibold"
|
||||||
|
android:textColor="@color/color_primary"
|
||||||
|
android:textSize="@dimen/_12ssp"
|
||||||
|
android:textAlignment="center"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/pincode"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
|
android:enabled="false"
|
||||||
|
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:fontFamily="@font/exo_2"
|
||||||
|
android:textSize="@dimen/_12ssp"
|
||||||
|
android:textAlignment="center"
|
||||||
|
|
||||||
|
android:hint="@string/enter_pincode"
|
||||||
|
android:textColorHint="@android:color/darker_gray"
|
||||||
|
|
||||||
|
android:autofillHints="postalAddress"
|
||||||
|
android:inputType="number"
|
||||||
|
android:singleLine="true"
|
||||||
|
|
||||||
|
android:background="@drawable/round_25_shadow"
|
||||||
|
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:layout_marginBottom="15dp"
|
||||||
|
|
||||||
|
android:elevation="5dp"
|
||||||
|
|
||||||
|
android:paddingHorizontal="20dp"
|
||||||
|
android:paddingVertical="12dp"
|
||||||
|
|
||||||
|
android:maxLength="6"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
|
android:text="@string/country"
|
||||||
|
android:fontFamily="@font/exo_2_semibold"
|
||||||
|
android:textColor="@color/color_primary"
|
||||||
|
android:textSize="@dimen/_12ssp"
|
||||||
|
android:textAlignment="center"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/country"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:fontFamily="@font/exo_2"
|
||||||
|
android:textSize="@dimen/_12ssp"
|
||||||
|
android:textAlignment="center"
|
||||||
|
|
||||||
|
android:hint="@string/enter_coutry"
|
||||||
|
android:textColorHint="@android:color/darker_gray"
|
||||||
|
|
||||||
|
android:autofillHints="postalAddress"
|
||||||
|
android:inputType="textPostalAddress"
|
||||||
|
android:digits="@string/alphanumeric_special_characters_with_space"
|
||||||
|
android:singleLine="true"
|
||||||
|
|
||||||
|
android:background="@drawable/round_25_shadow"
|
||||||
|
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:layout_marginBottom="15dp"
|
||||||
|
|
||||||
|
android:elevation="5dp"
|
||||||
|
|
||||||
|
android:paddingHorizontal="20dp"
|
||||||
|
android:paddingVertical="12dp"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
|
android:text="@string/phone_number"
|
||||||
|
android:fontFamily="@font/exo_2_semibold"
|
||||||
|
android:textColor="@color/color_primary"
|
||||||
|
android:textSize="@dimen/_12ssp"
|
||||||
|
android:textAlignment="center"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/phone"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:fontFamily="@font/exo_2"
|
||||||
|
android:textSize="@dimen/_12ssp"
|
||||||
|
android:textAlignment="center"
|
||||||
|
|
||||||
|
android:hint="@string/enter_phone_number"
|
||||||
|
android:textColorHint="@android:color/darker_gray"
|
||||||
|
|
||||||
|
android:autofillHints="phone"
|
||||||
|
android:inputType="phone"
|
||||||
|
android:singleLine="true"
|
||||||
|
|
||||||
|
android:background="@drawable/round_25_shadow"
|
||||||
|
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:layout_marginBottom="15dp"
|
||||||
|
|
||||||
|
android:elevation="5dp"
|
||||||
|
|
||||||
|
android:paddingHorizontal="20dp"
|
||||||
|
android:paddingVertical="12dp"
|
||||||
|
|
||||||
|
android:maxLength="10"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/submit"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="45dp"
|
||||||
|
|
||||||
|
android:text="@string/submit"
|
||||||
|
android:fontFamily="@font/exo_2_bold"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="@dimen/_10ssp"
|
||||||
|
|
||||||
|
android:layout_marginBottom="15dp"
|
||||||
|
android:layout_marginTop="25dp"
|
||||||
|
|
||||||
|
android:background="@drawable/round_bg_25"
|
||||||
|
android:backgroundTint="@color/color_primary"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</ScrollView>
|
||||||
@@ -11,7 +11,8 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="@drawable/round_25"
|
android:background="@drawable/round_25"
|
||||||
android:layout_margin="15dp"
|
android:layout_marginHorizontal="15dp"
|
||||||
|
android:layout_marginBottom="15dp"
|
||||||
>
|
>
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
|||||||
208
app/src/main/res/layout/fragment_product.xml
Normal file
208
app/src/main/res/layout/fragment_product.xml
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:background="@color/orders_bg"
|
||||||
|
tools:context=".shop.views.fragments.shop.ProductFragment">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.Guideline
|
||||||
|
android:id="@+id/g1"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
app:layout_constraintGuide_percent="0.7"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:contentDescription="@string/image"
|
||||||
|
android:src="@drawable/img_my_orders_ng"
|
||||||
|
android:scaleType="fitXY"
|
||||||
|
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/g1"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<androidx.core.widget.NestedScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingHorizontal="15dp"
|
||||||
|
android:paddingVertical="10dp"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
|
tools:text="Some title of the product"
|
||||||
|
android:fontFamily="@font/exo_2_bold"
|
||||||
|
android:textColor="@color/color_primary"
|
||||||
|
android:textSize="@dimen/_14ssp"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
<androidx.viewpager2.widget.ViewPager2
|
||||||
|
android:id="@+id/vp_images"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="150dp"
|
||||||
|
android:layout_marginTop="15dp"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<com.google.android.material.tabs.TabLayout
|
||||||
|
android:id="@+id/tab_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
app:tabBackground="@drawable/onboard_indicator_selector"
|
||||||
|
app:tabGravity="center"
|
||||||
|
app:tabIndicatorHeight="0dp"
|
||||||
|
app:tabPaddingEnd="10dp"
|
||||||
|
app:tabPaddingStart="10dp"
|
||||||
|
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
|
||||||
|
android:layout_marginHorizontal="15dp"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
|
android:text="@string/category_name"
|
||||||
|
android:fontFamily="@font/exo_2_bold"
|
||||||
|
android:textColor="@color/color_primary"
|
||||||
|
android:textSize="@dimen/_12ssp"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/category_name"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
|
tools:text="This is a random text for preview"
|
||||||
|
android:fontFamily="@font/exo_2"
|
||||||
|
android:textColor="@color/color_primary"
|
||||||
|
android:textSize="@dimen/_12ssp"
|
||||||
|
|
||||||
|
android:layout_marginStart="5dp"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
|
android:text="@string/sku_id"
|
||||||
|
android:fontFamily="@font/exo_2_bold"
|
||||||
|
android:textColor="@color/color_primary"
|
||||||
|
android:textSize="@dimen/_12ssp"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/sku_id"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
|
tools:text="This is a random text for preview"
|
||||||
|
android:fontFamily="@font/exo_2"
|
||||||
|
android:textColor="@color/color_primary"
|
||||||
|
android:textSize="@dimen/_12ssp"
|
||||||
|
|
||||||
|
android:layout_marginStart="5dp"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="15dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/price"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
|
tools:text="$ 200"
|
||||||
|
android:fontFamily="@font/exo_2_bold"
|
||||||
|
android:textColor="@color/color_primary"
|
||||||
|
android:textSize="@dimen/_16ssp"
|
||||||
|
android:maxLines="1"
|
||||||
|
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/addToCart"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/addToCart"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/addToCart"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/addToCart"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
|
android:text="@string/add_to_cart"
|
||||||
|
android:fontFamily="@font/exo_2_extrabold"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="@dimen/_10ssp"
|
||||||
|
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
|
||||||
|
android:background="@drawable/round_bg_25"
|
||||||
|
android:backgroundTint="@color/color_primary"
|
||||||
|
|
||||||
|
android:drawableStart="@drawable/ic_cart_filled"
|
||||||
|
android:drawablePadding="15dp"
|
||||||
|
|
||||||
|
android:paddingEnd="20dp"
|
||||||
|
android:paddingStart="15dp"
|
||||||
|
android:paddingVertical="5dp"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/description"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
|
android:fontFamily="@font/exo_2"
|
||||||
|
android:textColor="@color/color_primary"
|
||||||
|
android:textSize="@dimen/_12ssp"
|
||||||
|
|
||||||
|
android:layout_marginTop="15dp"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
@@ -7,85 +7,232 @@
|
|||||||
android:background="@color/orders_bg"
|
android:background="@color/orders_bg"
|
||||||
tools:context=".shop.views.fragments.shop.ShopFragment2">
|
tools:context=".shop.views.fragments.shop.ShopFragment2">
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<RelativeLayout
|
||||||
android:id="@+id/rv_category"
|
|
||||||
android:visibility="gone"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
tools:listitem="@layout/category_viwe_holder"
|
<com.facebook.shimmer.ShimmerFrameLayout
|
||||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
android:id="@+id/category_shimmer"
|
||||||
/>
|
|
||||||
|
|
||||||
<com.facebook.shimmer.ShimmerFrameLayout
|
|
||||||
android:id="@+id/shimmer"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
app:shimmer_auto_start="true"
|
|
||||||
app:shimmer_duration="1500"
|
|
||||||
app:shimmer_highlight_alpha="0.5">
|
|
||||||
|
|
||||||
<ScrollView
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:scrollbars="none"
|
android:layout_marginTop="15dp"
|
||||||
>
|
android:visibility="gone"
|
||||||
|
app:shimmer_auto_start="true"
|
||||||
|
app:shimmer_base_alpha="0.6"
|
||||||
|
app:shimmer_highlight_alpha="0.5">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="horizontal">
|
||||||
>
|
|
||||||
|
|
||||||
<include layout="@layout/category_viwe_holder"/>
|
<View
|
||||||
<include layout="@layout/category_viwe_holder"/>
|
android:layout_width="100dp"
|
||||||
<include layout="@layout/category_viwe_holder"/>
|
android:layout_height="40dp"
|
||||||
<include layout="@layout/category_viwe_holder"/>
|
android:layout_marginStart="15dp"
|
||||||
|
android:background="@drawable/round_bg_25"
|
||||||
|
|
||||||
|
android:alpha="0.7"
|
||||||
|
android:backgroundTint="@android:color/darker_gray" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="100dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:layout_marginStart="15dp"
|
||||||
|
android:background="@drawable/round_bg_25"
|
||||||
|
|
||||||
|
android:alpha="0.7"
|
||||||
|
android:backgroundTint="@android:color/darker_gray" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</ScrollView>
|
</com.facebook.shimmer.ShimmerFrameLayout>
|
||||||
|
|
||||||
</com.facebook.shimmer.ShimmerFrameLayout>
|
<com.google.android.material.tabs.TabLayout
|
||||||
|
android:id="@+id/category_tabs"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="45dp"
|
||||||
|
android:layout_marginStart="5dp"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
app:tabBackground="@drawable/sub_category_tab_bg"
|
||||||
|
app:tabGravity="start"
|
||||||
|
app:tabIndicatorHeight="0dp"
|
||||||
|
app:tabMode="scrollable"
|
||||||
|
app:tabPaddingEnd="25dp"
|
||||||
|
app:tabPaddingStart="25dp"
|
||||||
|
app:tabRippleColor="@android:color/transparent"
|
||||||
|
app:tabSelectedTextColor="@color/white"
|
||||||
|
app:tabTextColor="@color/color_primary" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/error_view"
|
android:id="@+id/error_view"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_centerInParent="true"
|
|
||||||
android:gravity="center_horizontal"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
android:text="@string/something_went_wrong"
|
<TextView
|
||||||
android:fontFamily="@font/exo_2_bold"
|
android:layout_width="wrap_content"
|
||||||
android:textColor="@color/color_primary"
|
android:layout_height="wrap_content"
|
||||||
android:textSize="@dimen/_14ssp"
|
|
||||||
|
|
||||||
|
android:text="@string/something_went_wrong"
|
||||||
|
android:fontFamily="@font/exo_2_bold"
|
||||||
|
android:textColor="@color/color_primary"
|
||||||
|
android:textSize="@dimen/_12ssp"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/retry_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
|
||||||
|
android:text="@string/retry"
|
||||||
|
android:fontFamily="@font/exo_2_bold"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="@dimen/_12ssp"
|
||||||
|
|
||||||
|
android:background="@drawable/round_bg_25"
|
||||||
|
android:backgroundTint="@color/game_grad_one"
|
||||||
|
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:paddingHorizontal="30dp"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<com.facebook.shimmer.ShimmerFrameLayout
|
||||||
|
android:id="@+id/product_shimmer"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@id/rv_products"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:shimmer_auto_start="true"
|
||||||
|
app:shimmer_base_alpha="0.6"
|
||||||
|
app:shimmer_highlight_alpha="0.5">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="5dp"
|
||||||
|
android:weightSum="2">
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginHorizontal="5dp"
|
||||||
|
android:layout_marginVertical="5dp"
|
||||||
|
layout="@layout/product_view_holder"/>
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginHorizontal="5dp"
|
||||||
|
android:layout_marginVertical="5dp"
|
||||||
|
layout="@layout/product_view_holder"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="5dp"
|
||||||
|
android:weightSum="2">
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginHorizontal="5dp"
|
||||||
|
android:layout_marginVertical="5dp"
|
||||||
|
layout="@layout/product_view_holder"/>
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginHorizontal="5dp"
|
||||||
|
android:layout_marginVertical="5dp"
|
||||||
|
layout="@layout/product_view_holder"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="5dp"
|
||||||
|
android:weightSum="2">
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginHorizontal="5dp"
|
||||||
|
android:layout_marginVertical="5dp"
|
||||||
|
layout="@layout/product_view_holder"/>
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginHorizontal="5dp"
|
||||||
|
android:layout_marginVertical="5dp"
|
||||||
|
layout="@layout/product_view_holder"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</com.facebook.shimmer.ShimmerFrameLayout>
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/rv_products"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@id/category_tabs"
|
||||||
|
android:visibility="gone"
|
||||||
|
|
||||||
|
tools:listitem="@layout/product_view_holder"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
|
||||||
|
app:spanCount="2"
|
||||||
|
|
||||||
|
android:layout_marginHorizontal="5dp"
|
||||||
|
android:overScrollMode="never"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/retry_button"
|
android:id="@+id/prod_load_more_btn"
|
||||||
|
android:visibility="gone"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@id/rv_products"
|
||||||
|
|
||||||
android:text="@string/retry"
|
android:text="@string/load_more"
|
||||||
android:fontFamily="@font/exo_2_bold"
|
android:fontFamily="@font/exo_2_bold"
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
android:textSize="@dimen/_14ssp"
|
android:textSize="@dimen/_12ssp"
|
||||||
|
|
||||||
android:background="@drawable/round_bg_25"
|
android:paddingHorizontal="25dp"
|
||||||
android:backgroundTint="@color/game_grad_one"
|
android:layout_marginVertical="15dp"
|
||||||
|
|
||||||
android:layout_marginTop="10dp"
|
android:background="@drawable/round_25"
|
||||||
android:paddingHorizontal="30dp"
|
android:backgroundTint="@color/night_status"
|
||||||
|
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</LinearLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
</RelativeLayout>
|
</androidx.core.widget.NestedScrollView>
|
||||||
@@ -5,8 +5,7 @@
|
|||||||
android:id="@+id/main"
|
android:id="@+id/main"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="@color/color_primary"
|
android:background="@color/color_primary">
|
||||||
tools:context=".webseries.views.SeasonActivity">
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|||||||
6
app/src/main/res/layout/product_image_view_holder.xml
Normal file
6
app/src/main/res/layout/product_image_view_holder.xml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:contentDescription="@string/image"
|
||||||
|
/>
|
||||||
73
app/src/main/res/layout/product_view_holder.xml
Normal file
73
app/src/main/res/layout/product_view_holder.xml
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
|
||||||
|
android:layout_marginHorizontal="5dp"
|
||||||
|
android:layout_marginVertical="5dp"
|
||||||
|
|
||||||
|
app:cardBackgroundColor="@color/white"
|
||||||
|
app:cardCornerRadius="3dp"
|
||||||
|
app:cardElevation="3dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="10dp"
|
||||||
|
android:layout_marginVertical="10dp"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<com.woka.utils.AdiImageView
|
||||||
|
android:id="@+id/image"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/_60sdp"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:weightSum="10"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="6.5"
|
||||||
|
|
||||||
|
tools:text="Hello there"
|
||||||
|
android:fontFamily="@font/exo_2_semibold"
|
||||||
|
android:textColor="@color/color_primary"
|
||||||
|
android:textSize="@dimen/_9ssp"
|
||||||
|
|
||||||
|
android:maxLines="3"
|
||||||
|
android:ellipsize="end"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/price"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="3.5"
|
||||||
|
|
||||||
|
tools:text="$ 200"
|
||||||
|
android:fontFamily="@font/exo_2_semibold"
|
||||||
|
android:textColor="@color/color_primary"
|
||||||
|
android:textSize="@dimen/_9ssp"
|
||||||
|
android:textAlignment="textEnd"
|
||||||
|
|
||||||
|
android:maxLines="3"
|
||||||
|
android:ellipsize="end"
|
||||||
|
|
||||||
|
android:layout_marginStart="3dp"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
android:textColor="@color/color_primary"
|
android:textColor="@color/white"
|
||||||
android:fontFamily="@font/exo_2_bold"
|
android:fontFamily="@font/exo_2_bold"
|
||||||
android:textSize="@dimen/_12ssp"
|
android:textSize="@dimen/_12ssp"
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
android:fontFamily="@font/exo_2_bold"
|
android:fontFamily="@font/exo_2_bold"
|
||||||
android:textColor="@color/color_primary"
|
android:textColor="@color/white"
|
||||||
android:textSize="@dimen/_12ssp"
|
android:textSize="@dimen/_12ssp"
|
||||||
|
|
||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
|
|||||||
@@ -69,6 +69,7 @@
|
|||||||
<string name="back_btn" translatable="false">back_btn</string>
|
<string name="back_btn" translatable="false">back_btn</string>
|
||||||
<string name="enter_your_password">Enter your password</string>
|
<string name="enter_your_password">Enter your password</string>
|
||||||
<string name="please_wait">Please wait...</string>
|
<string name="please_wait">Please wait...</string>
|
||||||
|
<string name="alphabets_with_space" translatable="false">ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz</string>
|
||||||
<string name="alphanumeric" translatable="false">ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890</string>
|
<string name="alphanumeric" translatable="false">ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890</string>
|
||||||
<string name="alphanumeric_with_space" translatable="false">ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz1234567890</string>
|
<string name="alphanumeric_with_space" translatable="false">ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz1234567890</string>
|
||||||
<string name="resend_otp">Resend OTP?</string>
|
<string name="resend_otp">Resend OTP?</string>
|
||||||
@@ -88,6 +89,7 @@
|
|||||||
<string name="otp_hint" translatable="false">*</string>
|
<string name="otp_hint" translatable="false">*</string>
|
||||||
<string name="please_select_your_interests">Please select your interests</string>
|
<string name="please_select_your_interests">Please select your interests</string>
|
||||||
<string name="alphanumeric_special_characters_without_space" translatable="false"><![CDATA[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!#$%&\'*+/-=^_`{|}~.@]]></string>
|
<string name="alphanumeric_special_characters_without_space" translatable="false"><![CDATA[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!#$%&\'*+/-=^_`{|}~.@]]></string>
|
||||||
|
<string name="alphanumeric_special_characters_with_space" translatable="false"><![CDATA[ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz1234567890!#$%&\'*+/-=^_`{|}~.@]]></string>
|
||||||
<string name="already_logged_in">Already logged in</string>
|
<string name="already_logged_in">Already logged in</string>
|
||||||
<string name="do_you_want_to_continue_log_in">Do you want to continue log in?</string>
|
<string name="do_you_want_to_continue_log_in">Do you want to continue log in?</string>
|
||||||
<string name="yes">Yes</string>
|
<string name="yes">Yes</string>
|
||||||
@@ -253,6 +255,30 @@
|
|||||||
<string name="please_enter_your_pincode_below_to_check_service_availability_in_your_area">Please Enter Your Pincode Below to Check Service Availability in Your Area</string>
|
<string name="please_enter_your_pincode_below_to_check_service_availability_in_your_area">Please Enter Your Pincode Below to Check Service Availability in Your Area</string>
|
||||||
<string name="enter_your_pincode">Enter your pincode</string>
|
<string name="enter_your_pincode">Enter your pincode</string>
|
||||||
<string name="check_now">Check Now</string>
|
<string name="check_now">Check Now</string>
|
||||||
<string name="enter_a_valid_pincode">Enter a valid pincode</string>
|
<string name="enter_a_valid_pincode">Enter a 6 digit pincode</string>
|
||||||
<string name="proceed">Proceed</string>
|
<string name="proceed">Proceed</string>
|
||||||
|
<string name="address_name_firstname_and_lastname">Address Name (Firstname and Lastname)</string>
|
||||||
|
<string name="enter_address_name">Enter address name</string>
|
||||||
|
<string name="address_line_1">Address Line 1</string>
|
||||||
|
<string name="address_line_2">Address Line 2</string>
|
||||||
|
<string name="enter_address_line_1">Enter address line 1</string>
|
||||||
|
<string name="enter_address_line_2">Enter address line 2</string>
|
||||||
|
<string name="city">City</string>
|
||||||
|
<string name="enter_city">Enter city</string>
|
||||||
|
<string name="state">State</string>
|
||||||
|
<string name="enter_state">Enter state</string>
|
||||||
|
<string name="pincode">Pincode</string>
|
||||||
|
<string name="enter_pincode">Enter pincode</string>
|
||||||
|
<string name="country">Country</string>
|
||||||
|
<string name="enter_coutry">Enter country</string>
|
||||||
|
<string name="phone_number">Phone Number</string>
|
||||||
|
<string name="enter_phone_number">Enter phone number</string>
|
||||||
|
<string name="please_enter_name">Please enter name</string>
|
||||||
|
<string name="at_least_15_characters">Enter at least 15 characters</string>
|
||||||
|
<string name="at_least_2_characters">Enter at least 2 characters</string>
|
||||||
|
<string name="enter_10_digit_phone">Enter 10 digits phone number</string>
|
||||||
|
<string name="all">All</string>
|
||||||
|
<string name="category_name">Category Name :</string>
|
||||||
|
<string name="sku_id">SKU Id :</string>
|
||||||
|
<string name="add_to_cart">ADD TO CART</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -25,6 +25,6 @@ android.enableJetifier=true
|
|||||||
|
|
||||||
|
|
||||||
# BASE URLS
|
# BASE URLS
|
||||||
WOKA_STAGINNG_BASE_URL="https://wokaland.com/admin/api/"
|
WOKA_STAGINNG_BASE_URL="https://wokaland.com/secret-panel-10102023/hidden-admin-portal-20092023/api/"
|
||||||
WOKA_USER_NAME="admin"
|
WOKA_USER_NAME="admin"
|
||||||
WOKA_PASSWORD="Woka@1234"
|
WOKA_PASSWORD="Woka@1234"
|
||||||
Reference in New Issue
Block a user