From 2f720bb114aea15b93039bf91edb3628c5a21f2d Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Mon, 24 Dec 2018 08:44:07 -0600 Subject: [PATCH] Add functionality to the Search funtion in the Transactions' toolbar, which fires events to filter the transactions list while the user types a search query. --- .../fragments/TransactionsFragment.kt | 123 ++++++++++++++++-- 1 file changed, 112 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/TransactionsFragment.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/TransactionsFragment.kt index 5695a79..4a898ad 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/TransactionsFragment.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/TransactionsFragment.kt @@ -1,9 +1,12 @@ package cy.agorise.bitsybitshareswallet.fragments +import android.graphics.Point import android.os.Bundle import android.preference.PreferenceManager import android.view.* +import androidx.appcompat.widget.SearchView import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentActivity import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProviders import androidx.recyclerview.widget.LinearLayoutManager @@ -14,15 +17,31 @@ import cy.agorise.bitsybitshareswallet.utils.BounceTouchListener import cy.agorise.bitsybitshareswallet.utils.Constants import cy.agorise.bitsybitshareswallet.viewmodels.TransferDetailViewModel import kotlinx.android.synthetic.main.fragment_transactions.* +import java.util.* +import kotlin.collections.ArrayList -class TransactionsFragment : Fragment() { +class TransactionsFragment : Fragment(), SearchView.OnQueryTextListener { private lateinit var mTransferDetailViewModel: TransferDetailViewModel - override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? - ): View? { + private lateinit var transfersDetailsAdapter: TransfersDetailsAdapter + + private val transfersDetails = ArrayList() + private val filteredTransfersDetails = ArrayList() + + /** Variables used to filter the transaction items */ + private var filterQuery = "" + private var filterTransactionsDirection = 0 + private var filterDateRangeAll = true + private var filterStartDate = 0L + private var filterEndDate = 0L + private var filterCryptocurrencyAll = true + private var filterCryptocurrency = "BTS" + private var filterFiatAmountAll = true + private var filterFromFiatAmount = 0L + private var filterToFiatAmount = 500L + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { setHasOptionsMenu(true) return inflater.inflate(R.layout.fragment_transactions, container, false) @@ -34,23 +53,105 @@ class TransactionsFragment : Fragment() { val userId = PreferenceManager.getDefaultSharedPreferences(context) .getString(Constants.KEY_CURRENT_ACCOUNT_ID, "") ?: "" - // Configure TransferDetailViewModel to show the transaction history - mTransferDetailViewModel = ViewModelProviders.of(this).get(TransferDetailViewModel::class.java) - - val transfersDetailsAdapter = TransfersDetailsAdapter(context!!) + transfersDetailsAdapter = TransfersDetailsAdapter(context!!) rvTransactions.adapter = transfersDetailsAdapter rvTransactions.layoutManager = LinearLayoutManager(context) + // Configure TransferDetailViewModel to fetch the transaction history + mTransferDetailViewModel = ViewModelProviders.of(this).get(TransferDetailViewModel::class.java) + mTransferDetailViewModel.getAll(userId).observe(this, Observer> { transfersDetails -> - transfersDetailsAdapter.replaceAll(transfersDetails) + this.transfersDetails.clear() + this.transfersDetails.addAll(transfersDetails) + applyFilterOptions(false) }) - // Sets custom touch listener to handle bounce/stretch effect + // Set custom touch listener to handle bounce/stretch effect val bounceTouchListener = BounceTouchListener(rvTransactions) rvTransactions.setOnTouchListener(bounceTouchListener) + + // Initialize filter options + val calendar = Calendar.getInstance() + filterEndDate = calendar.timeInMillis / 1000 + calendar.add(Calendar.MONTH, -2) + filterStartDate = calendar.timeInMillis / 1000 } override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { inflater.inflate(R.menu.menu_transactions, menu) + + // Adds listener for the SearchView + val searchItem = menu.findItem(R.id.menuSearch) + val searchView = searchItem.actionView as SearchView + searchView.setOnQueryTextListener(this) + + // Adjust SearchView width to avoid pushing other menu items out of the screen + searchView.maxWidth = getScreenWidth(activity) * 3 / 5 + } + + /** + * Returns the screen width in pixels for the given [FragmentActivity] + */ + private fun getScreenWidth(activity: FragmentActivity?): Int { + if (activity == null) + return 200 + + val size = Point() + activity.windowManager.defaultDisplay.getSize(size) + return size.x + } + + override fun onQueryTextChange(query: String): Boolean { + filterQuery = query.toLowerCase() + applyFilterOptions() + return true + } + + override fun onQueryTextSubmit(query: String?) = false // Not needed since we are filtering as the user types + + /** + * Filters the TransferDetail list given the user selected filter options. + * TODO move this to a background thread + */ + private fun applyFilterOptions(scrollToTop: Boolean = true) { + // Clean the filtered list + filteredTransfersDetails.clear() + + for (transferDetail in transfersDetails) { + // Filter by transfer direction + if (transferDetail.direction) { // Transfer sent + if (filterTransactionsDirection == 2) + // Looking for received transfers only + continue + } else { // Transfer received + if (filterTransactionsDirection == 1) + // Looking for sent transactions only + continue + } + + // Filter by date range + if (!filterDateRangeAll && (transferDetail.date < filterStartDate || transferDetail.date > filterEndDate)) + continue + + // Filter by cryptocurrency + if (!filterCryptocurrencyAll && transferDetail.cryptoSymbol != filterCryptocurrency) + continue + +// // Filter by fiat amount +// if (!filterFiatAmountAll && (transferDetail.fiatAmount < filterFromFiatAmount || transferDetail.fiatAmount > filterToFiatAmount)) +// continue + + // Filter by search query + val text = (transferDetail.from ?: "").toLowerCase() + (transferDetail.to ?: "").toLowerCase() + if (text.contains(filterQuery, ignoreCase = true)) { + filteredTransfersDetails.add(transferDetail) + } + } + + // Replaces the list of TransferDetail items with the new filtered list + transfersDetailsAdapter.replaceAll(filteredTransfersDetails) + + if (scrollToTop) + rvTransactions.scrollToPosition(0) } }