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'
|
||||
|
||||
dependencies {
|
||||
implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.32'
|
||||
|
||||
implementation "com.facebook.shimmer:shimmer:0.5.0"
|
||||
|
||||
implementation "com.airbnb.android:lottie:6.4.0"
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
<activity
|
||||
android:name=".shop.views.AddressActivity"
|
||||
android:exported="false"
|
||||
android:screenOrientation="portrait" />
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustPan" />
|
||||
<activity
|
||||
android:name=".shop.views.PaymentActivity"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode|fontScale|fontWeightAdjustment|screenLayout"
|
||||
|
||||
@@ -76,7 +76,7 @@ object RetrofitHelper {
|
||||
}
|
||||
|
||||
// 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) {
|
||||
val body = response.body() ?: return ApiResult.Error(errorMessage = "Empty Response")
|
||||
return when (body.success) {
|
||||
|
||||
@@ -96,7 +96,7 @@ class OnboardFragment : Fragment() {
|
||||
private fun initViews() {
|
||||
binding.apply {
|
||||
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.CreateOrderResponse
|
||||
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.superlisting.SuperCategoryResponse
|
||||
import okhttp3.FormBody
|
||||
@@ -31,6 +32,9 @@ interface ShopApiService {
|
||||
@POST("sub_category_listing")
|
||||
suspend fun subcategoryListing(@Body formBody: FormBody): Response<ApiResponse<SubCategoryResponse>>
|
||||
|
||||
@POST("v2/shop_product_listing")
|
||||
suspend fun productListing(@Body formBody: FormBody): Response<ApiResponse<ProductListingResponse>>
|
||||
|
||||
// cart
|
||||
@GET("cart_listing")
|
||||
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.CreateOrderResponse
|
||||
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.superlisting.SuperCategoryResponse
|
||||
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
|
||||
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.shop.ShopRepository
|
||||
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.superlisting.SuperCategory
|
||||
import com.woka.utils.PagingData
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class ShopViewModel: ViewModel() {
|
||||
@@ -72,11 +74,12 @@ class ShopViewModel: ViewModel() {
|
||||
val subcategoryLiveData: LiveData<ApiResult<MutableList<SubCategoryData>>>
|
||||
get() = _subcategoryLiveData
|
||||
|
||||
private val subcategoryDataMap = HashMap<String, MutableList<SubCategoryData>>()
|
||||
val subcategoryDataMap = HashMap<String, MutableList<SubCategoryData>>()
|
||||
|
||||
fun loadSubCategories(categoryId: String){
|
||||
if (subcategoryDataMap.containsKey(categoryId)){
|
||||
_subcategoryLiveData.postValue(ApiResult.Success(subcategoryDataMap[categoryId]))
|
||||
fun loadSubCategories(superCategoryId: String, categoryId: String){
|
||||
val key = "${superCategoryId}_$categoryId"
|
||||
if (subcategoryDataMap.containsKey(key)){
|
||||
_subcategoryLiveData.postValue(ApiResult.Success(subcategoryDataMap[key]))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -87,7 +90,9 @@ class ShopViewModel: ViewModel() {
|
||||
is ApiResult.Loading -> {}
|
||||
is ApiResult.Success -> {
|
||||
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))
|
||||
}
|
||||
}
|
||||
@@ -98,4 +103,77 @@ class ShopViewModel: ViewModel() {
|
||||
fun clearSubCategoryLiveData(){
|
||||
_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() {
|
||||
|
||||
companion object {
|
||||
const val EXTRA_PRODUCT_IDS = "extra_product_ids"
|
||||
const val EXTRA_COUPON_CODE = "extra_coupon_code"
|
||||
}
|
||||
|
||||
private lateinit var binding: ActivityAddressBinding
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@@ -24,10 +29,32 @@ class AddressActivity : WokaBaseActivity() {
|
||||
insets
|
||||
}
|
||||
|
||||
binding.toolbar.title.text = getString(R.string.address_details)
|
||||
initViews()
|
||||
|
||||
clickEvents()
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
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.Bundle
|
||||
import android.webkit.WebSettings
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.woka.R
|
||||
import com.woka.databinding.ActivityPaymentBinding
|
||||
import com.woka.utils.WokaBaseActivity
|
||||
import com.woka.utils.lightStatusBar
|
||||
import com.woka.utils.toast
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class PaymentActivity : WokaBaseActivity() {
|
||||
|
||||
@@ -69,6 +73,22 @@ class PaymentActivity : WokaBaseActivity() {
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.Fragment
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.widget.addTextChangedListener
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.woka.R
|
||||
@@ -13,10 +13,13 @@ import com.woka.databinding.FragmentPinCodeBinding
|
||||
import com.woka.networking.ApiResult
|
||||
import com.woka.shop.viewmodels.AddressViewModel
|
||||
import com.woka.utils.ProgressView
|
||||
import com.woka.utils.toast
|
||||
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 progressView: ProgressView
|
||||
@@ -47,11 +50,15 @@ class PinCodeFragment private constructor(): Fragment() {
|
||||
binding.apply {
|
||||
btn.setOnClickListener {
|
||||
if (selectedPinCode.length == 6){
|
||||
toast(selectedPinCode)
|
||||
parentFragmentManager.beginTransaction()
|
||||
.add(R.id.fcv_address, AddAddressFragment.newInstance(selectedPinCode, productIds, couponCode))
|
||||
.addToBackStack(null)
|
||||
.commit()
|
||||
|
||||
return@setOnClickListener
|
||||
}
|
||||
|
||||
if (pincode.text.length < 6){
|
||||
if (pincode.text.length != 6){
|
||||
pincode.error = getString(R.string.enter_a_valid_pincode)
|
||||
return@setOnClickListener
|
||||
}
|
||||
@@ -73,7 +80,6 @@ class PinCodeFragment private constructor(): Fragment() {
|
||||
|
||||
selectedPinCode = pinCode
|
||||
btn.text = getString(R.string.proceed)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -94,6 +100,8 @@ class PinCodeFragment private constructor(): Fragment() {
|
||||
|
||||
companion object {
|
||||
@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.viewmodels.CartViewModel
|
||||
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.Companion.EXTRA_PAYMENT_LINK
|
||||
import com.woka.utils.ProgressView
|
||||
@@ -21,6 +23,7 @@ import com.woka.utils.hide
|
||||
import com.woka.utils.setVisibility
|
||||
import com.woka.utils.show
|
||||
import com.woka.utils.toast
|
||||
import java.util.ArrayList
|
||||
|
||||
class ParentAddressFragment : Fragment() {
|
||||
|
||||
@@ -67,17 +70,7 @@ class ParentAddressFragment : Fragment() {
|
||||
private fun clickEvents(){
|
||||
binding.apply {
|
||||
selectAddress.setOnClickListener {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
val productIds = getProductIds()
|
||||
|
||||
if (productIds.isEmpty()){
|
||||
toast(getString(R.string.no_products_added_to_cart))
|
||||
@@ -94,12 +87,33 @@ class ParentAddressFragment : Fragment() {
|
||||
|
||||
addNewAddress.setOnClickListener {
|
||||
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() {
|
||||
adapter.addressSelectListener = { addressId ->
|
||||
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 = {
|
||||
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)
|
||||
.commitAllowingStateLoss()
|
||||
}
|
||||
|
||||
@@ -6,19 +6,33 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import com.woka.R
|
||||
import com.woka.databinding.FragmentShop3Binding
|
||||
import com.woka.networking.ApiResult
|
||||
import com.woka.shop.adapters.CategoryAdapter
|
||||
import com.woka.shop.models.BaseCategory
|
||||
import com.woka.shop.adapters.ShopProductAdapter
|
||||
import com.woka.shop.viewmodels.ShopViewModel
|
||||
import com.woka.utils.hide
|
||||
import com.woka.utils.setVisibility
|
||||
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 viewModel: ShopViewModel
|
||||
private lateinit var adapter: CategoryAdapter
|
||||
private lateinit var productAdapter: ShopProductAdapter
|
||||
|
||||
private var loadMoreProducts = false
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
@@ -26,7 +40,7 @@ class ShopFragment3 private constructor(private val categoryId: String): Fragmen
|
||||
): View {
|
||||
binding = FragmentShop3Binding.inflate(inflater, container, false)
|
||||
viewModel = ViewModelProvider(requireActivity())[ShopViewModel::class.java]
|
||||
adapter = CategoryAdapter()
|
||||
productAdapter = ShopProductAdapter()
|
||||
return binding.root
|
||||
}
|
||||
|
||||
@@ -39,28 +53,53 @@ class ShopFragment3 private constructor(private val categoryId: String): Fragmen
|
||||
|
||||
setObservers()
|
||||
|
||||
viewModel.loadSubCategories(categoryId)
|
||||
viewModel.loadSubCategories(superCategoryId, categoryId)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
viewModel.clearSubCategoryLiveData()
|
||||
viewModel.clearProductListingLiveData()
|
||||
}
|
||||
|
||||
private fun initViews() {
|
||||
binding.apply {
|
||||
rvCategory.adapter = adapter
|
||||
categoryTabs.addOnTabSelectedListener(this@ShopFragment3)
|
||||
|
||||
rvProducts.adapter = productAdapter
|
||||
rvProducts.itemAnimator = null
|
||||
}
|
||||
}
|
||||
|
||||
private fun clickEvents() {
|
||||
binding.apply {
|
||||
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) {
|
||||
when (it) {
|
||||
is ApiResult.Error -> {
|
||||
rvCategory.hide()
|
||||
shimmer.hide()
|
||||
categoryTabs.hide()
|
||||
categoryShimmer.hide()
|
||||
errorView.show()
|
||||
}
|
||||
|
||||
is ApiResult.Loading -> {
|
||||
rvCategory.hide()
|
||||
shimmer.show()
|
||||
categoryTabs.hide()
|
||||
categoryShimmer.show()
|
||||
errorView.hide()
|
||||
}
|
||||
|
||||
is ApiResult.Success -> {
|
||||
it.data?.let { categoryList ->
|
||||
adapter.submitList(categoryList.map { category ->
|
||||
BaseCategory(
|
||||
category.id,
|
||||
category.sub_category_thumbnail,
|
||||
category.sub_category_name
|
||||
categoryTabs.show()
|
||||
categoryShimmer.hide()
|
||||
errorView.hide()
|
||||
for (category in categoryList) {
|
||||
binding.categoryTabs.addTab(
|
||||
binding.categoryTabs.newTab()
|
||||
.setText("${category.sub_category_name}")
|
||||
.setTag(category.id)
|
||||
)
|
||||
}
|
||||
) {
|
||||
rvCategory.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shimmer.hide()
|
||||
errorView.hide()
|
||||
viewModel.productListingLiveData.observe(viewLifecycleOwner){
|
||||
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 {
|
||||
@JvmStatic
|
||||
fun newInstance(categoryId: String) = ShopFragment3(categoryId)
|
||||
override fun onTabSelected(p0: TabLayout.Tab?) {
|
||||
loadProducts()
|
||||
}
|
||||
|
||||
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.net.ConnectivityManager
|
||||
import android.net.NetworkCapabilities
|
||||
import android.text.InputFilter
|
||||
import android.text.Spanned
|
||||
import android.view.View
|
||||
import android.view.View.GONE
|
||||
import android.view.View.VISIBLE
|
||||
import android.view.Window
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.EditText
|
||||
import android.widget.Toast
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.google.i18n.phonenumbers.PhoneNumberUtil
|
||||
import com.google.i18n.phonenumbers.Phonenumber
|
||||
import com.woka.WokaApp.Companion.userPrefs
|
||||
import java.util.Locale
|
||||
import kotlin.math.ceil
|
||||
@@ -100,4 +105,37 @@ fun Context.isNetworkConnected(): Boolean {
|
||||
val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return false
|
||||
return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) ||
|
||||
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.networking.ApiResult
|
||||
import com.woka.players.models.VideoPlayList
|
||||
import com.woka.utils.PagingData
|
||||
import com.woka.webseries.WebSeriesRepository
|
||||
import com.woka.webseries.models.ContinueEpisodeResponse
|
||||
import com.woka.webseries.models.ShowData
|
||||
@@ -20,11 +21,6 @@ class WebSeriesViewModel : ViewModel() {
|
||||
|
||||
private val repository = WebSeriesRepository
|
||||
|
||||
data class PagingData(
|
||||
var nextPageToLoad: Int = 0, var quantityPerPage: Int = 6,
|
||||
var lastPage: Boolean = false
|
||||
)
|
||||
|
||||
// categories listing
|
||||
|
||||
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">
|
||||
<item android:state_selected="true">
|
||||
<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"/>
|
||||
<solid android:color="#5e1fc4"/>
|
||||
</shape>
|
||||
</item>
|
||||
<item android:state_selected="false">
|
||||
<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"/>
|
||||
<solid android:color="@color/white"/>
|
||||
</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_height="match_parent"
|
||||
android:background="@drawable/round_25"
|
||||
android:layout_margin="15dp"
|
||||
android:layout_marginHorizontal="15dp"
|
||||
android:layout_marginBottom="15dp"
|
||||
>
|
||||
|
||||
<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"?>
|
||||
<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"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
@@ -7,85 +7,232 @@
|
||||
android:background="@color/orders_bg"
|
||||
tools:context=".shop.views.fragments.shop.ShopFragment2">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rv_category"
|
||||
android:visibility="gone"
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
tools:listitem="@layout/category_viwe_holder"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
/>
|
||||
|
||||
<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
|
||||
<com.facebook.shimmer.ShimmerFrameLayout
|
||||
android:id="@+id/category_shimmer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scrollbars="none"
|
||||
>
|
||||
android:layout_height="wrap_content"
|
||||
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
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
android:orientation="horizontal">
|
||||
|
||||
<include layout="@layout/category_viwe_holder"/>
|
||||
<include layout="@layout/category_viwe_holder"/>
|
||||
<include layout="@layout/category_viwe_holder"/>
|
||||
<include layout="@layout/category_viwe_holder"/>
|
||||
<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" />
|
||||
|
||||
<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>
|
||||
|
||||
</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
|
||||
android:id="@+id/error_view"
|
||||
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
|
||||
<LinearLayout
|
||||
android:id="@+id/error_view"
|
||||
android:visibility="gone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical">
|
||||
|
||||
android:text="@string/something_went_wrong"
|
||||
android:fontFamily="@font/exo_2_bold"
|
||||
android:textColor="@color/color_primary"
|
||||
android:textSize="@dimen/_14ssp"
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
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
|
||||
android:id="@+id/retry_button"
|
||||
android:id="@+id/prod_load_more_btn"
|
||||
android:visibility="gone"
|
||||
android:layout_width="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:textColor="@color/white"
|
||||
android:textSize="@dimen/_14ssp"
|
||||
android:textSize="@dimen/_12ssp"
|
||||
|
||||
android:background="@drawable/round_bg_25"
|
||||
android:backgroundTint="@color/game_grad_one"
|
||||
android:paddingHorizontal="25dp"
|
||||
android:layout_marginVertical="15dp"
|
||||
|
||||
android:layout_marginTop="10dp"
|
||||
android:paddingHorizontal="30dp"
|
||||
android:background="@drawable/round_25"
|
||||
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:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/color_primary"
|
||||
tools:context=".webseries.views.SeasonActivity">
|
||||
android:background="@color/color_primary">
|
||||
|
||||
<LinearLayout
|
||||
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_height="wrap_content"
|
||||
|
||||
android:textColor="@color/color_primary"
|
||||
android:textColor="@color/white"
|
||||
android:fontFamily="@font/exo_2_bold"
|
||||
android:textSize="@dimen/_12ssp"
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
android:fontFamily="@font/exo_2_bold"
|
||||
android:textColor="@color/color_primary"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/_12ssp"
|
||||
|
||||
android:layout_centerVertical="true"
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
<string name="back_btn" translatable="false">back_btn</string>
|
||||
<string name="enter_your_password">Enter your password</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_with_space" translatable="false">ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz1234567890</string>
|
||||
<string name="resend_otp">Resend OTP?</string>
|
||||
@@ -88,6 +89,7 @@
|
||||
<string name="otp_hint" translatable="false">*</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_with_space" translatable="false"><![CDATA[ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz1234567890!#$%&\'*+/-=^_`{|}~.@]]></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="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="enter_your_pincode">Enter your pincode</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="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>
|
||||
@@ -25,6 +25,6 @@ android.enableJetifier=true
|
||||
|
||||
|
||||
# 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_PASSWORD="Woka@1234"
|
||||
Reference in New Issue
Block a user