Untitled
unknown
kotlin
2 years ago
27 kB
8
Indexable
package `in`.swipe.app.app.ui.customers import `in`.swipe.app.R import `in`.swipe.app.app.Constants import `in`.swipe.app.app.SwipeApplication import `in`.swipe.app.app.Utils import `in`.swipe.app.app.Utils.hideKeyboard import `in`.swipe.app.app.navigateTo import `in`.swipe.app.app.ui.customers.addcustomermanually.AddCustomerManuallyActivity import `in`.swipe.app.app.ui.document.FabExtendingOnScrollListener import `in`.swipe.app.app.ui.home.SharedViewModel import `in`.swipe.app.app.ui.parties.AddPartiesListener import `in`.swipe.app.app.ui.parties.PartiesViewModel import `in`.swipe.app.app.ui.parties.SearchQueryListener import `in`.swipe.app.app.ui.parties.bottomsheet.SortPartiesBottomSheetFragment import `in`.swipe.app.app.ui.parties.bottomsheet.UserDetailsBottomSheetFragment import `in`.swipe.app.app.ui.utils.WrapContentLinearLayoutManager import `in`.swipe.app.data.model.models.CustomerData import `in`.swipe.app.data.model.models.Vendor import `in`.swipe.app.data.prefs.PreferenceHelper import `in`.swipe.app.databinding.FragmentCustomersBinding import android.app.Activity import android.content.Intent import android.os.Bundle import android.text.Editable import android.text.TextWatcher import android.view.* import android.widget.AbsListView import android.widget.LinearLayout import android.widget.Toast import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProvider import androidx.navigation.NavController import androidx.navigation.fragment.NavHostFragment import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.RecyclerView import com.mancj.materialsearchbar.MaterialSearchBar import org.koin.androidx.viewmodel.ext.android.sharedViewModel import kotlin.math.max class CustomersFragment : Fragment(), SearchQueryListener, AddPartiesListener, MenuItem.OnMenuItemClickListener, MaterialSearchBar.OnSearchActionListener, Toolbar.OnMenuItemClickListener, SortPartiesBottomSheetFragment.OnItemClickListener, CustomerAdapter.OnItemClickListener { private lateinit var binding: FragmentCustomersBinding private lateinit var parentActivity: AppCompatActivity private lateinit var navHostFragment: NavHostFragment private lateinit var navController: NavController private var isCustomerAccess = PreferenceHelper.getCustomersAccess() private var customerAdapter: CustomerAdapter? = null private lateinit var linearLayoutManager: WrapContentLinearLayoutManager private var newInvoiceLayout = false private var isSelectCustomer = false private val viewModel by sharedViewModel<CustomersViewModel>() private lateinit var sortBottomSheet: SortPartiesBottomSheetFragment private lateinit var userDetailsBottomSheet: UserDetailsBottomSheetFragment private var radioButtonValue = "Default" private var sortNetBalanceBy = "" private lateinit var resultLauncher: ActivityResultLauncher<Intent> private var selectedCustomerId = -1 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) arguments?.let { if (it.containsKey("newInvoiceLayout")) { newInvoiceLayout = it.getBoolean("newInvoiceLayout") } if (it.containsKey(Constants.BUNDLE_IS_SELECT_CUSTOMER)) { isSelectCustomer = it.getBoolean(Constants.BUNDLE_IS_SELECT_CUSTOMER) } } resultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> if (result.resultCode == Activity.RESULT_OK) { // There are no request codes val data: Intent? = result.data data?.let { if (isVisible) { selectedCustomerId = it.getIntExtra(Constants.NEW_CUSTOMER_ID, -1) } } } } setHasOptionsMenu(true) } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { binding = FragmentCustomersBinding.inflate(inflater, container, false) return binding.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { parentActivity = activity as AppCompatActivity logFragment("onViewCreated called") setupNavigationComponent() setListeners() observeData() if (isCustomerAccess == 1) { viewModel.getAllCustomers(sortNetBalanceBy) startShimmer() } if (isCustomerAccess == 1) { binding.noAccess.visibility = View.GONE binding.recyclerview.visibility = View.VISIBLE } else { binding.noAccess.visibility = View.VISIBLE customerAdapter?.resetDiffer() binding.recyclerview.visibility = View.GONE } if (isSelectCustomer) { binding.includeTool.visibility = View.VISIBLE binding.btnCreateCustomer.visibility = View.GONE binding.searchBarCustomer.visibility = View.GONE binding.sortCustomer.visibility = View.GONE searchCustomers() } else { binding.includeTool.visibility = View.GONE binding.btnCreateCustomer.visibility = View.VISIBLE binding.sortCustomer.visibility = View.VISIBLE binding.searchBarCustomer.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged( s: CharSequence?, start: Int, count: Int, after: Int ) { } override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { if (s.isNullOrEmpty().not() || s.isNullOrBlank().not()) { viewModel.searchCustomer(s.toString()) } else { if (PreferenceHelper.getCustomersAccess() == 1) { viewModel.getAllCustomers(sortNetBalanceBy) binding.recyclerview.visibility = View.VISIBLE } else { binding.noDataMessage.visibility = View.GONE binding.noAccess.visibility = View.VISIBLE customerAdapter?.resetDiffer() binding.recyclerview.visibility = View.GONE } } } override fun afterTextChanged(s: Editable?) { } }) } binding.btnCreateCustomer.setOnClickListener { logFragment("btnCreateCustomer clicked") val addCustomerManuallyIntent = Intent(parentActivity, AddCustomerManuallyActivity::class.java) resultLauncher.launch(addCustomerManuallyIntent) requireActivity().overridePendingTransition( R.anim.activity_slide_in_right_trans, R.anim.activity_slide_out_left_trans ) } binding.addCust.setOnClickListener { logFragment("addCust clicked") val addCustomerManuallyIntent = Intent(parentActivity, AddCustomerManuallyActivity::class.java) resultLauncher.launch(addCustomerManuallyIntent) requireActivity().overridePendingTransition( R.anim.activity_slide_in_right_trans, R.anim.activity_slide_out_left_trans ) } binding.btnAddCustomer.setOnClickListener { logFragment("btnCreateCustomer clicked") binding.btnCreateCustomer.visibility = View.VISIBLE binding.addCustomerLayout.visibility = View.GONE val addCustomerManuallyIntent = Intent(parentActivity, AddCustomerManuallyActivity::class.java) resultLauncher.launch(addCustomerManuallyIntent) requireActivity().overridePendingTransition( R.anim.activity_slide_in_right_trans, R.anim.activity_slide_out_left_trans ) } setupToolBar() binding.customerFragmentToolbar.setOnMenuItemClickListener(this@CustomersFragment) binding.sortCustomer.setOnClickListener { sortBottomSheet = SortPartiesBottomSheetFragment(this, radioButtonValue) val fm = childFragmentManager sortBottomSheet.show(fm, tag) } } private fun setupToolBar() { //parentActivity.setSupportActionBar(binding.customerFragmentToolbar) binding.customerFragmentToolbar.title = "Customers" binding.customerFragmentToolbar.navigationIcon = ContextCompat.getDrawable(requireActivity(), R.drawable.ic_back_black) binding.customerFragmentToolbar.setNavigationOnClickListener { activity?.onBackPressed() } } override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { menu.clear() inflater.inflate(R.menu.parties_toolbar_menu, menu) val searchItem = menu.findItem(R.id.menuItemSearch) searchItem.setOnMenuItemClickListener(this) super.onCreateOptionsMenu(menu, inflater) } private fun searchCustomers() { binding.searchBarCust.addTextChangeListener(object : TextWatcher { override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { } override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { if (s.isNullOrEmpty().not() || s.isNullOrBlank().not()) viewModel.searchCustomer(s.toString()) else viewModel.getAllCustomers(sortNetBalanceBy) } override fun afterTextChanged(s: Editable?) { } }) binding.searchBarCust.setOnSearchActionListener(this@CustomersFragment) } override fun onResume() { super.onResume() if (isAdded && isSelectCustomer) { if (isCustomerAccess == 1) { viewModel.getAllCustomers(sortNetBalanceBy) startShimmer() } } } private fun setupNavigationComponent() { logFragment("setupNavigationComponent clicked") navHostFragment = parentActivity.supportFragmentManager.findFragmentById(R.id.navHostFragmentContainer) as NavHostFragment navController = navHostFragment.navController } private fun setListeners() { val dividerItemDecoration = DividerItemDecoration(parentActivity, LinearLayout.VERTICAL) linearLayoutManager = WrapContentLinearLayoutManager(parentActivity) customerAdapter = CustomerAdapter( parentActivity, navController, newInvoiceLayout, this ) binding.recyclerview.layoutManager = linearLayoutManager binding.recyclerview.addItemDecoration(dividerItemDecoration) binding.recyclerview.setHasFixedSize(true) binding.recyclerview.adapter = customerAdapter binding.swipeRefreshLayout.setOnRefreshListener { logFragment("swipeRefreshLayout.setOnRefreshListener clicked") if(PreferenceHelper.getCustomersAccess() == 1) { if (viewModel.searchingState.value == PartiesViewModel.IDLE) { viewModel.getAllCustomers(sortNetBalanceBy) startShimmer() } else { stopShimmer() binding.swipeRefreshLayout.isRefreshing = false } binding.recyclerview.visibility = View.VISIBLE } else { binding.swipeRefreshLayout.isRefreshing = false binding.noDataMessage.visibility = View.GONE binding.noAccess.visibility = View.VISIBLE binding.recyclerview.visibility = View.GONE customerAdapter?.resetDiffer() } } binding.recyclerview.addOnScrollListener(object : RecyclerView.OnScrollListener() { override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { super.onScrollStateChanged(recyclerView, newState) if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) { viewModel.isScrolling.value = true } } override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { super.onScrolled(recyclerView, dx, dy) val currentItems = linearLayoutManager.childCount val totalItems = linearLayoutManager.itemCount val scrollOutItems = linearLayoutManager.findFirstVisibleItemPosition() if (viewModel.isScrolling.value == true && dy >= 0 && (currentItems + scrollOutItems == totalItems && viewModel.searchingState.value == PartiesViewModel.IDLE)) { if (viewModel.getCanLoadNewData().value == true) { logFragment("viewModel.getMoreData() called") viewModel.isScrolling.value = false viewModel.currentPage.value = viewModel.currentPage.value?.plus(1) viewModel.getMoreData(sortNetBalanceBy) } } } }) binding.recyclerview.addOnScrollListener(FabExtendingOnScrollListener(binding.btnCreateCustomer)) } private fun observeData() { viewModel.getDataFetched().observe(viewLifecycleOwner) { it?.let { when (it) { true -> { if (binding.recyclerview.adapter == null) { logFragment("setting up customers adapter") stopShimmer() val dividerItemDecoration = DividerItemDecoration(parentActivity, LinearLayout.VERTICAL) linearLayoutManager = WrapContentLinearLayoutManager(parentActivity) customerAdapter = CustomerAdapter( parentActivity, navController, newInvoiceLayout, this ) binding.recyclerview.layoutManager = linearLayoutManager binding.recyclerview.addItemDecoration(dividerItemDecoration) binding.recyclerview.adapter = customerAdapter } if (viewModel.searchingState.value != PartiesViewModel.IDLE) { viewModel.searchingState.value = PartiesViewModel.IDLE } binding.swipeRefreshLayout.isRefreshing = false } false -> { stopShimmer() logFragment("error fetching customers") binding.swipeRefreshLayout.isRefreshing = false Toast.makeText( parentActivity, R.string.error_fetching_customers, Toast.LENGTH_LONG ).show() } } } } viewModel.searchingState.observe(viewLifecycleOwner) { it?.let { when (it) { PartiesViewModel.IDLE -> { binding.progressBar.visibility = View.GONE } PartiesViewModel.IS_SEARCHING -> { binding.progressBar.visibility = View.VISIBLE } PartiesViewModel.SEARCHING_COMPLETED -> { customerAdapter?.updateCustomersData(viewModel.newCustomers.value!!) binding.progressBar.visibility = View.GONE } PartiesViewModel.SEARCHING_GOT_ERROR -> { Toast.makeText(activity, R.string.error_getting_search, Toast.LENGTH_LONG) .show() binding.progressBar.visibility = View.GONE } } } } viewModel.newCustomers.observe(viewLifecycleOwner) { it?.let { logFragment("newCustomers observer called", it.toString()) stopShimmer() if (selectedCustomerId != -1 && isSelectCustomer) { if (it.size > 0) { ViewModelProvider(context as AppCompatActivity)[SharedViewModel::class.java].selectedCustomer.value = Pair(it.findLast { it.customer_id == selectedCustomerId },true) selectedCustomerId = -1 requireActivity().onBackPressed() } else { Toast.makeText( requireActivity(), "Something went wrong!!", Toast.LENGTH_SHORT ).show() } } if (viewModel.searchingState.value != null && viewModel.searchingState.value != PartiesViewModel.SEARCHING_COMPLETED) { if (it.size == 0 && viewModel.currentPage.value == 0) { customerAdapter?.updateCustomersData(it) binding.noDataMessage.visibility = View.VISIBLE binding.noAccess.visibility = View.GONE if (viewModel.searchingState.value == -1) { binding.btnCreateCustomer.visibility = View.GONE binding.noDataMessage.visibility = View.GONE binding.addCustomerLayout.visibility = View.VISIBLE binding.addCustomerText.visibility = View.GONE binding.btnAddCustomer.visibility = View.VISIBLE } else { binding.btnCreateCustomer.visibility = View.VISIBLE binding.addCustomerLayout.visibility = View.GONE } if (isSelectCustomer) { binding.addCust.visibility = View.VISIBLE if (viewModel.searchingState.value != PartiesViewModel.IS_SEARCHING) { if (isVisible) { binding.searchBarCust.visibility = View.INVISIBLE activity?.currentFocus?.hideKeyboard() } } } } else { binding.noAccess.visibility = View.GONE binding.recyclerview.visibility = View.VISIBLE binding.swipeRefreshLayout.visibility = View.VISIBLE binding.customersList.visibility = View.VISIBLE if (isSelectCustomer) { binding.addCust.visibility = View.VISIBLE binding.searchBarCust.visibility = View.VISIBLE binding.searchBarCust.setHint("Search Customers") binding.searchBarCust.openSearch() if (isVisible) { Utils.showKeyboard(binding.searchBarCust.searchEditText) } } binding.addCustomerLayout.visibility = View.GONE binding.noDataMessage.visibility = View.GONE if (!isSelectCustomer) binding.btnCreateCustomer.visibility = View.VISIBLE } if (viewModel.currentPage.value == 0) { customerAdapter?.updateCustomersData(it) } else { customerAdapter?.updateData(it) } } } } viewModel.getIsLoadingNewData().observe(viewLifecycleOwner) { it?.let { logFragment("getIsLoadingNewData observer called") if (it) { } else { stopShimmer() } } } viewModel.getCanLoadNewData().observe(viewLifecycleOwner) { it?.let { logFragment("getCanLoadNewData observer called") if (!it) { Toast.makeText(parentActivity, R.string.no_more_data, Toast.LENGTH_LONG).show() customerAdapter?.lastPage = true customerAdapter?.notifyItemChanged( customerAdapter?.differ?.currentList?.lastIndex ?: 0 ) } } } viewModel.dataFetched.observe(viewLifecycleOwner) { if (!it) { binding.noAccess.visibility = View.VISIBLE customerAdapter?.resetDiffer() binding.addCustomerLayout.visibility = View.GONE binding.recyclerview.visibility = View.GONE } } } private fun startShimmer() { binding.shimmerLayout.startShimmer() binding.shimmerLayout.visibility = View.VISIBLE binding.swipeRefreshLayout.visibility = View.GONE binding.recyclerview.visibility = View.GONE } private fun stopShimmer() { binding.shimmerLayout.stopShimmer() binding.shimmerLayout.visibility = View.GONE binding.swipeRefreshLayout.visibility = View.VISIBLE binding.recyclerview.visibility = View.VISIBLE } override fun onSearchQuerySubmit(query: String) { if (isVisible) { if (query.isNullOrEmpty().not()) { viewModel.searchCustomer(query) } } } override fun onSearchBarClosed() { if (isAdded) { viewModel.getAllCustomers(sortNetBalanceBy) logFragment("onSearchBarClosed called") } } override fun onDestroy() { if (customerAdapter != null) customerAdapter!!.resetDiffer() super.onDestroy() } override fun add() { logFragment("action_navBarMenuParties_to_addNewCustFragment called") navController.currentDestination?.getAction(R.id.action_navBarMenuParties_to_addNewCustFragment) ?.let { navController.navigateTo( R.id.action_navBarMenuParties_to_addNewCustFragment ) } ?: run { navController.navigateTo(R.id.action_createInvoiceParties_to_addNewCustFragment) } } fun logFragment(methodName: String, methodParameter: String = "None") { val bundle = Bundle() bundle.putString(Constants.FRAGMENT_NAME, "customers_fragment") bundle.putString(Constants.FRAGMENT_METHOD, methodName) bundle.putString(Constants.FRAGMENT_METHOD_PARAMETER, methodParameter) if (activity != null) (activity?.applicationContext as SwipeApplication).logFragment(bundle) } override fun onMenuItemClick(item: MenuItem?): Boolean { val cx = binding.searchBarCust.measuredWidth / 2 val cy = binding.searchBarCust.measuredHeight / 2 if (isVisible){ val finalRadius = max(binding.searchBarCust.width, binding.searchBarCust.height) / 2 val anim = ViewAnimationUtils.createCircularReveal( binding.searchBarCust, cx, cy, 0F, finalRadius.toFloat() ) binding.searchBarCust.visibility = View.VISIBLE binding.searchBarCust.performClick() anim.start() } return true } override fun onSearchStateChanged(enabled: Boolean) { if (!enabled) { activity?.onBackPressed() // val cx = binding.searchBarCust.measuredWidth / 2 // val cy = binding.searchBarCust.measuredHeight / 2 // // val finalRadius = // max(binding.searchBarCust.width, binding.searchBarCust.height) / 2 // // val anim = ViewAnimationUtils.createCircularReveal( // binding.searchBarCust, cx, cy, // finalRadius.toFloat(), 0F // ) // binding.searchBarCust.visibility = View.VISIBLE // anim.addListener(object : Animator.AnimatorListener { // override fun onAnimationStart(animation: Animator?) { // } // // override fun onAnimationEnd(animation: Animator?) { // binding.searchBarCust.visibility = View.INVISIBLE // } // // override fun onAnimationCancel(animation: Animator?) { // } // // override fun onAnimationRepeat(animation: Animator?) { // } // }) // anim.start() } } fun getAllCustomers() { // if (isVisible) { // viewModel.getAllCustomers() // } } override fun onSearchConfirmed(text: CharSequence?) { } override fun onButtonClicked(buttonCode: Int) { } override fun onRadioItemSelected(selectedRadioValue: String) { radioButtonValue = selectedRadioValue sortNetBalanceBy = when (selectedRadioValue) { "Net Balance - Low to High" -> "asc" "Net Balance - High to Low" -> "desc" else -> "" } viewModel.getAllCustomers(sortNetBalanceBy) } override fun onMoreDetailsClick(customer: CustomerData) { userDetailsBottomSheet = UserDetailsBottomSheetFragment("customer",customer) val fm = childFragmentManager userDetailsBottomSheet.show(fm,tag) } }
Editor is loading...