Created FilterOptions class to serve as an easy way to communicate filter options user preferences between the TransactionsFragment and the FilterOptionsDialog, and use it to filter the transactions list.
This commit is contained in:
parent
4ed2eba66a
commit
d1bce06ec2
4 changed files with 135 additions and 137 deletions
|
@ -18,6 +18,7 @@ import com.crashlytics.android.Crashlytics
|
||||||
import cy.agorise.bitsybitshareswallet.R
|
import cy.agorise.bitsybitshareswallet.R
|
||||||
import cy.agorise.bitsybitshareswallet.adapters.BalancesDetailsAdapter
|
import cy.agorise.bitsybitshareswallet.adapters.BalancesDetailsAdapter
|
||||||
import cy.agorise.bitsybitshareswallet.database.joins.BalanceDetail
|
import cy.agorise.bitsybitshareswallet.database.joins.BalanceDetail
|
||||||
|
import cy.agorise.bitsybitshareswallet.models.FilterOptions
|
||||||
import cy.agorise.bitsybitshareswallet.utils.Constants
|
import cy.agorise.bitsybitshareswallet.utils.Constants
|
||||||
import cy.agorise.bitsybitshareswallet.viewmodels.BalanceDetailViewModel
|
import cy.agorise.bitsybitshareswallet.viewmodels.BalanceDetailViewModel
|
||||||
import cy.agorise.bitsybitshareswallet.views.DatePickerFragment
|
import cy.agorise.bitsybitshareswallet.views.DatePickerFragment
|
||||||
|
@ -36,43 +37,15 @@ class FilterOptionsDialog : DialogFragment() {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "FilterOptionsDialog"
|
private const val TAG = "FilterOptionsDialog"
|
||||||
|
|
||||||
const val KEY_FILTER_TRANSACTION_DIRECTION = "key_filter_transaction_direction"
|
const val KEY_FILTER_OPTIONS = "key_filter_options"
|
||||||
const val KEY_FILTER_DATE_RANGE_ALL = "key_filter_date_range_all"
|
|
||||||
const val KEY_FILTER_START_DATE = "key_filter_start_date"
|
|
||||||
const val KEY_FILTER_END_DATE = "key_filter_end_date"
|
|
||||||
const val KEY_FILTER_ASSET_ALL = "key_filter_asset_all"
|
|
||||||
const val KEY_FILTER_ASSET = "key_filter_asset"
|
|
||||||
const val KEY_FILTER_EQUIVALENT_VALUE_ALL = "key_filter_equivalent_value_all"
|
|
||||||
const val KEY_FILTER_FROM_EQUIVALENT_VALUE = "key_filter_from_equivalent_value"
|
|
||||||
const val KEY_FILTER_TO_EQUIVALENT_VALUE = "key_filter_to_equivalent_value"
|
|
||||||
const val KEY_FILTER_AGORISE_FEES = "key_filter_agorise_fees"
|
|
||||||
|
|
||||||
const val KEY_TIMESTAMP = "key_timestamp"
|
const val KEY_TIMESTAMP = "key_timestamp"
|
||||||
|
|
||||||
const val START_DATE_PICKER = 0
|
const val START_DATE_PICKER = 0
|
||||||
const val END_DATE_PICKER = 1
|
const val END_DATE_PICKER = 1
|
||||||
|
|
||||||
fun newInstance(filterTransactionsDirection: Int, filterDateRangeAll: Boolean,
|
|
||||||
filterStartDate: Long, filterEndDate: Long, filterAssetAll: Boolean,
|
|
||||||
filterAsset: String, filterEquivalentValueAll: Boolean, filterFromEquivalentValue: Long,
|
|
||||||
filterToEquivalentValue: Long, filterAgoriseFees: Boolean): FilterOptionsDialog {
|
|
||||||
val frag = FilterOptionsDialog()
|
|
||||||
val args = Bundle()
|
|
||||||
args.putInt(KEY_FILTER_TRANSACTION_DIRECTION, filterTransactionsDirection)
|
|
||||||
args.putBoolean(KEY_FILTER_DATE_RANGE_ALL, filterDateRangeAll)
|
|
||||||
args.putLong(KEY_FILTER_START_DATE, filterStartDate)
|
|
||||||
args.putLong(KEY_FILTER_END_DATE, filterEndDate)
|
|
||||||
args.putBoolean(KEY_FILTER_ASSET_ALL, filterAssetAll)
|
|
||||||
args.putString(KEY_FILTER_ASSET, filterAsset)
|
|
||||||
args.putBoolean(KEY_FILTER_EQUIVALENT_VALUE_ALL, filterEquivalentValueAll)
|
|
||||||
args.putLong(KEY_FILTER_FROM_EQUIVALENT_VALUE, filterFromEquivalentValue)
|
|
||||||
args.putLong(KEY_FILTER_TO_EQUIVALENT_VALUE, filterToEquivalentValue)
|
|
||||||
args.putBoolean(KEY_FILTER_AGORISE_FEES, filterAgoriseFees)
|
|
||||||
frag.arguments = args
|
|
||||||
return frag
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
private lateinit var mFilterOptions: FilterOptions
|
||||||
|
|
||||||
// Widgets TODO use android-kotlin-extensions {onViewCreated}
|
// Widgets TODO use android-kotlin-extensions {onViewCreated}
|
||||||
private lateinit var rbTransactionAll: RadioButton
|
private lateinit var rbTransactionAll: RadioButton
|
||||||
|
@ -98,9 +71,6 @@ class FilterOptionsDialog : DialogFragment() {
|
||||||
private var dateFormat: SimpleDateFormat = SimpleDateFormat("d/MMM/yyyy",
|
private var dateFormat: SimpleDateFormat = SimpleDateFormat("d/MMM/yyyy",
|
||||||
ConfigurationCompat.getLocales(Resources.getSystem().configuration)[0])
|
ConfigurationCompat.getLocales(Resources.getSystem().configuration)[0])
|
||||||
|
|
||||||
private var startDate: Long = 0
|
|
||||||
private var endDate: Long = 0
|
|
||||||
|
|
||||||
private var mBalanceDetails = ArrayList<BalanceDetail>()
|
private var mBalanceDetails = ArrayList<BalanceDetail>()
|
||||||
|
|
||||||
private lateinit var mBalanceDetailViewModel: BalanceDetailViewModel
|
private lateinit var mBalanceDetailViewModel: BalanceDetailViewModel
|
||||||
|
@ -121,22 +91,22 @@ class FilterOptionsDialog : DialogFragment() {
|
||||||
//Log.d(TAG, "timestamp: $timestamp")
|
//Log.d(TAG, "timestamp: $timestamp")
|
||||||
when (msg.arg1) {
|
when (msg.arg1) {
|
||||||
START_DATE_PICKER -> {
|
START_DATE_PICKER -> {
|
||||||
startDate = timestamp
|
mFilterOptions.startDate = timestamp
|
||||||
|
|
||||||
updateDateTextViews()
|
updateDateTextViews()
|
||||||
}
|
}
|
||||||
END_DATE_PICKER -> {
|
END_DATE_PICKER -> {
|
||||||
endDate = timestamp
|
mFilterOptions.endDate = timestamp
|
||||||
|
|
||||||
// Make sure there is at least one moth difference between start and end time
|
// Make sure there is at least one moth difference between start and end time
|
||||||
val calendar = Calendar.getInstance()
|
val calendar = Calendar.getInstance()
|
||||||
calendar.timeInMillis = endDate
|
calendar.timeInMillis = mFilterOptions.endDate
|
||||||
calendar.add(Calendar.MONTH, -1)
|
calendar.add(Calendar.MONTH, -1)
|
||||||
|
|
||||||
val tmpTime = calendar.timeInMillis
|
val tmpTime = calendar.timeInMillis
|
||||||
|
|
||||||
if (tmpTime < startDate)
|
if (tmpTime < mFilterOptions.startDate)
|
||||||
startDate = tmpTime
|
mFilterOptions.startDate = tmpTime
|
||||||
|
|
||||||
updateDateTextViews()
|
updateDateTextViews()
|
||||||
}
|
}
|
||||||
|
@ -145,25 +115,16 @@ class FilterOptionsDialog : DialogFragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateDateTextViews() {
|
private fun updateDateTextViews() {
|
||||||
var date = Date(startDate)
|
var date = Date(mFilterOptions.startDate)
|
||||||
tvStartDate.text = dateFormat.format(date)
|
tvStartDate.text = dateFormat.format(date)
|
||||||
|
|
||||||
date = Date(endDate)
|
date = Date(mFilterOptions.endDate)
|
||||||
tvEndDate.text = dateFormat.format(date)
|
tvEndDate.text = dateFormat.format(date)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Container Fragment must implement this interface
|
// Container Fragment must implement this interface
|
||||||
interface OnFilterOptionsSelectedListener {
|
interface OnFilterOptionsSelectedListener {
|
||||||
fun onFilterOptionsSelected(filterTransactionsDirection: Int,
|
fun onFilterOptionsSelected(filterOptions: FilterOptions)
|
||||||
filterDateRangeAll: Boolean,
|
|
||||||
filterStartDate: Long,
|
|
||||||
filterEndDate: Long,
|
|
||||||
filterAssetAll: Boolean,
|
|
||||||
filterAsset: String,
|
|
||||||
filterEquivalentValueAll: Boolean,
|
|
||||||
filterFromEquivalentValue: Long,
|
|
||||||
filterToEquivalentValue: Long,
|
|
||||||
filterAgoriseFees: Boolean)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -172,6 +133,8 @@ class FilterOptionsDialog : DialogFragment() {
|
||||||
|
|
||||||
Crashlytics.setString(Constants.CRASHLYTICS_KEY_LAST_SCREEN, TAG)
|
Crashlytics.setString(Constants.CRASHLYTICS_KEY_LAST_SCREEN, TAG)
|
||||||
|
|
||||||
|
mFilterOptions = arguments?.getParcelable(KEY_FILTER_OPTIONS)!!
|
||||||
|
|
||||||
// Initialize handler for communication with the DatePicker
|
// Initialize handler for communication with the DatePicker
|
||||||
mDatePickerHandler = DatePickerHandler()
|
mDatePickerHandler = DatePickerHandler()
|
||||||
|
|
||||||
|
@ -188,8 +151,7 @@ class FilterOptionsDialog : DialogFragment() {
|
||||||
rbTransactionAll = view.findViewById(R.id.rbTransactionAll)
|
rbTransactionAll = view.findViewById(R.id.rbTransactionAll)
|
||||||
rbTransactionSent = view.findViewById(R.id.rbTransactionSent)
|
rbTransactionSent = view.findViewById(R.id.rbTransactionSent)
|
||||||
rbTransactionReceived = view.findViewById(R.id.rbTransactionReceived)
|
rbTransactionReceived = view.findViewById(R.id.rbTransactionReceived)
|
||||||
val radioButtonChecked = arguments!!.getInt(KEY_FILTER_TRANSACTION_DIRECTION, 0)
|
when (mFilterOptions.transactionsDirection) {
|
||||||
when (radioButtonChecked) {
|
|
||||||
0 -> rbTransactionAll.isChecked = true
|
0 -> rbTransactionAll.isChecked = true
|
||||||
1 -> rbTransactionSent.isChecked = true
|
1 -> rbTransactionSent.isChecked = true
|
||||||
2 -> rbTransactionReceived.isChecked = true
|
2 -> rbTransactionReceived.isChecked = true
|
||||||
|
@ -200,15 +162,13 @@ class FilterOptionsDialog : DialogFragment() {
|
||||||
llDateRange = view.findViewById(R.id.llDateRange)
|
llDateRange = view.findViewById(R.id.llDateRange)
|
||||||
cbDateRange.setOnCheckedChangeListener { _, isChecked ->
|
cbDateRange.setOnCheckedChangeListener { _, isChecked ->
|
||||||
llDateRange.visibility = if(isChecked) View.GONE else View.VISIBLE }
|
llDateRange.visibility = if(isChecked) View.GONE else View.VISIBLE }
|
||||||
cbDateRange.isChecked = arguments!!.getBoolean(KEY_FILTER_DATE_RANGE_ALL, true)
|
cbDateRange.isChecked = mFilterOptions.dateRangeAll
|
||||||
|
|
||||||
tvStartDate = view.findViewById(R.id.tvStartDate)
|
tvStartDate = view.findViewById(R.id.tvStartDate)
|
||||||
tvEndDate = view.findViewById(R.id.tvEndDate)
|
tvEndDate = view.findViewById(R.id.tvEndDate)
|
||||||
|
|
||||||
startDate = arguments!!.getLong(KEY_FILTER_START_DATE, 0)
|
|
||||||
tvStartDate.setOnClickListener(mDateClickListener)
|
tvStartDate.setOnClickListener(mDateClickListener)
|
||||||
|
|
||||||
endDate = arguments!!.getLong(KEY_FILTER_END_DATE, 0)
|
|
||||||
tvEndDate.setOnClickListener(mDateClickListener)
|
tvEndDate.setOnClickListener(mDateClickListener)
|
||||||
|
|
||||||
updateDateTextViews()
|
updateDateTextViews()
|
||||||
|
@ -219,7 +179,7 @@ class FilterOptionsDialog : DialogFragment() {
|
||||||
cbAsset.setOnCheckedChangeListener { _, isChecked ->
|
cbAsset.setOnCheckedChangeListener { _, isChecked ->
|
||||||
sAsset.visibility = if(isChecked) View.GONE else View.VISIBLE
|
sAsset.visibility = if(isChecked) View.GONE else View.VISIBLE
|
||||||
}
|
}
|
||||||
cbAsset.isChecked = arguments!!.getBoolean(KEY_FILTER_ASSET_ALL, true)
|
cbAsset.isChecked = mFilterOptions.assetAll
|
||||||
|
|
||||||
// Configure BalanceDetailViewModel to obtain the user's Balances
|
// Configure BalanceDetailViewModel to obtain the user's Balances
|
||||||
mBalanceDetailViewModel = ViewModelProviders.of(this).get(BalanceDetailViewModel::class.java)
|
mBalanceDetailViewModel = ViewModelProviders.of(this).get(BalanceDetailViewModel::class.java)
|
||||||
|
@ -233,11 +193,9 @@ class FilterOptionsDialog : DialogFragment() {
|
||||||
mBalancesDetailsAdapter = BalancesDetailsAdapter(context!!, android.R.layout.simple_spinner_item, mBalanceDetails)
|
mBalancesDetailsAdapter = BalancesDetailsAdapter(context!!, android.R.layout.simple_spinner_item, mBalanceDetails)
|
||||||
sAsset.adapter = mBalancesDetailsAdapter
|
sAsset.adapter = mBalancesDetailsAdapter
|
||||||
|
|
||||||
val assetSelected = arguments!!.getString(KEY_FILTER_ASSET)
|
|
||||||
|
|
||||||
// Try to select the selectedAssetSymbol
|
// Try to select the selectedAssetSymbol
|
||||||
for (i in 0 until mBalancesDetailsAdapter!!.count) {
|
for (i in 0 until mBalancesDetailsAdapter!!.count) {
|
||||||
if (mBalancesDetailsAdapter!!.getItem(i)!!.symbol == assetSelected) {
|
if (mBalancesDetailsAdapter!!.getItem(i)!!.symbol == mFilterOptions.asset) {
|
||||||
sAsset.setSelection(i)
|
sAsset.setSelection(i)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -249,19 +207,19 @@ class FilterOptionsDialog : DialogFragment() {
|
||||||
llEquivalentValue = view.findViewById(R.id.llEquivalentValue)
|
llEquivalentValue = view.findViewById(R.id.llEquivalentValue)
|
||||||
cbEquivalentValue.setOnCheckedChangeListener { _, isChecked ->
|
cbEquivalentValue.setOnCheckedChangeListener { _, isChecked ->
|
||||||
llEquivalentValue.visibility = if(isChecked) View.GONE else View.VISIBLE }
|
llEquivalentValue.visibility = if(isChecked) View.GONE else View.VISIBLE }
|
||||||
cbEquivalentValue.isChecked = arguments!!.getBoolean(KEY_FILTER_EQUIVALENT_VALUE_ALL, true)
|
cbEquivalentValue.isChecked = mFilterOptions.equivalentValueAll
|
||||||
|
|
||||||
// TODO obtain user selected currency
|
// TODO obtain user selected currency
|
||||||
val currencySymbol = "usd"
|
val currencySymbol = "usd"
|
||||||
mCurrency = Currency.getInstance(currencySymbol)
|
mCurrency = Currency.getInstance(currencySymbol)
|
||||||
|
|
||||||
etFromEquivalentValue = view.findViewById(R.id.etFromEquivalentValue)
|
etFromEquivalentValue = view.findViewById(R.id.etFromEquivalentValue)
|
||||||
val fromEquivalentValue = arguments!!.getLong(KEY_FILTER_FROM_EQUIVALENT_VALUE, 0) /
|
val fromEquivalentValue = mFilterOptions.fromEquivalentValue /
|
||||||
Math.pow(10.0, mCurrency.defaultFractionDigits.toDouble()).toLong()
|
Math.pow(10.0, mCurrency.defaultFractionDigits.toDouble()).toLong()
|
||||||
etFromEquivalentValue.setText("$fromEquivalentValue", TextView.BufferType.EDITABLE)
|
etFromEquivalentValue.setText("$fromEquivalentValue", TextView.BufferType.EDITABLE)
|
||||||
|
|
||||||
etToEquivalentValue = view.findViewById(R.id.etToEquivalentValue)
|
etToEquivalentValue = view.findViewById(R.id.etToEquivalentValue)
|
||||||
val toEquivalentValue = arguments!!.getLong(KEY_FILTER_TO_EQUIVALENT_VALUE, 0) /
|
val toEquivalentValue = mFilterOptions.toEquivalentValue /
|
||||||
Math.pow(10.0, mCurrency.defaultFractionDigits.toDouble()).toLong()
|
Math.pow(10.0, mCurrency.defaultFractionDigits.toDouble()).toLong()
|
||||||
etToEquivalentValue.setText("$toEquivalentValue", TextView.BufferType.EDITABLE)
|
etToEquivalentValue.setText("$toEquivalentValue", TextView.BufferType.EDITABLE)
|
||||||
|
|
||||||
|
@ -270,7 +228,7 @@ class FilterOptionsDialog : DialogFragment() {
|
||||||
|
|
||||||
// Initialize transaction network fees
|
// Initialize transaction network fees
|
||||||
switchAgoriseFees = view.findViewById(R.id.switchAgoriseFees)
|
switchAgoriseFees = view.findViewById(R.id.switchAgoriseFees)
|
||||||
switchAgoriseFees.isChecked = arguments!!.getBoolean(KEY_FILTER_AGORISE_FEES, true)
|
switchAgoriseFees.isChecked = mFilterOptions.agoriseFees
|
||||||
|
|
||||||
builder.setView(view)
|
builder.setView(view)
|
||||||
|
|
||||||
|
@ -299,13 +257,13 @@ class FilterOptionsDialog : DialogFragment() {
|
||||||
var which = -1
|
var which = -1
|
||||||
if (v.id == R.id.tvStartDate) {
|
if (v.id == R.id.tvStartDate) {
|
||||||
which = START_DATE_PICKER
|
which = START_DATE_PICKER
|
||||||
currentTime = startDate
|
currentTime = mFilterOptions.startDate
|
||||||
calendar.timeInMillis = endDate
|
calendar.timeInMillis = mFilterOptions.endDate
|
||||||
calendar.add(Calendar.MONTH, -1)
|
calendar.add(Calendar.MONTH, -1)
|
||||||
maxTime = calendar.timeInMillis
|
maxTime = calendar.timeInMillis
|
||||||
} else if (v.id == R.id.tvEndDate) {
|
} else if (v.id == R.id.tvEndDate) {
|
||||||
which = END_DATE_PICKER
|
which = END_DATE_PICKER
|
||||||
currentTime = endDate
|
currentTime = mFilterOptions.endDate
|
||||||
}
|
}
|
||||||
|
|
||||||
val datePickerFragment = DatePickerFragment.newInstance(which, currentTime,
|
val datePickerFragment = DatePickerFragment.newInstance(which, currentTime,
|
||||||
|
@ -314,36 +272,33 @@ class FilterOptionsDialog : DialogFragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun validateFields() {
|
private fun validateFields() {
|
||||||
val filterTransactionsDirection = when {
|
mFilterOptions.transactionsDirection = when {
|
||||||
rbTransactionAll.isChecked -> 0
|
rbTransactionAll.isChecked -> 0
|
||||||
rbTransactionSent.isChecked -> 1
|
rbTransactionSent.isChecked -> 1
|
||||||
rbTransactionReceived.isChecked -> 2
|
rbTransactionReceived.isChecked -> 2
|
||||||
else -> { 0 }
|
else -> { 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
val filterDateRangeAll = cbDateRange.isChecked
|
mFilterOptions.dateRangeAll = cbDateRange.isChecked
|
||||||
|
|
||||||
val filterAssetAll = cbAsset.isChecked
|
mFilterOptions.assetAll = cbAsset.isChecked
|
||||||
|
|
||||||
val filterAsset = (sAsset.selectedItem as BalanceDetail).symbol
|
mFilterOptions.asset = (sAsset.selectedItem as BalanceDetail).symbol
|
||||||
|
|
||||||
val filterEquivalentValueAll = cbEquivalentValue.isChecked
|
mFilterOptions.equivalentValueAll = cbEquivalentValue.isChecked
|
||||||
|
|
||||||
val filterFromEquivalentValue = etFromEquivalentValue.text.toString().toLong() *
|
mFilterOptions.fromEquivalentValue = etFromEquivalentValue.text.toString().toLong() *
|
||||||
Math.pow(10.0, mCurrency.defaultFractionDigits.toDouble()).toLong()
|
Math.pow(10.0, mCurrency.defaultFractionDigits.toDouble()).toLong()
|
||||||
|
|
||||||
var filterToEquivalentValue = etToEquivalentValue.text.toString().toLong() *
|
mFilterOptions.toEquivalentValue = etToEquivalentValue.text.toString().toLong() *
|
||||||
Math.pow(10.0, mCurrency.defaultFractionDigits.toDouble()).toLong()
|
Math.pow(10.0, mCurrency.defaultFractionDigits.toDouble()).toLong()
|
||||||
|
|
||||||
// Make sure ToEquivalentValue is at least 50 units bigger than FromEquivalentValue
|
// Make sure ToEquivalentValue is at least 50 units bigger than FromEquivalentValue
|
||||||
if (!filterEquivalentValueAll && filterToEquivalentValue < filterFromEquivalentValue + 50) {
|
mFilterOptions.toEquivalentValue =
|
||||||
filterToEquivalentValue = filterFromEquivalentValue + 50
|
Math.max(mFilterOptions.toEquivalentValue, mFilterOptions.fromEquivalentValue + 50)
|
||||||
}
|
|
||||||
|
|
||||||
val filterAgoriseFees = switchAgoriseFees.isChecked
|
mFilterOptions.agoriseFees = switchAgoriseFees.isChecked
|
||||||
|
|
||||||
mCallback!!.onFilterOptionsSelected(filterTransactionsDirection, filterDateRangeAll,
|
mCallback!!.onFilterOptionsSelected(mFilterOptions)
|
||||||
startDate, endDate, filterAssetAll, filterAsset, filterEquivalentValueAll,
|
|
||||||
filterFromEquivalentValue, filterToEquivalentValue, filterAgoriseFees)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -21,8 +21,9 @@ import com.jakewharton.rxbinding3.appcompat.queryTextChangeEvents
|
||||||
import cy.agorise.bitsybitshareswallet.R
|
import cy.agorise.bitsybitshareswallet.R
|
||||||
import cy.agorise.bitsybitshareswallet.adapters.TransfersDetailsAdapter
|
import cy.agorise.bitsybitshareswallet.adapters.TransfersDetailsAdapter
|
||||||
import cy.agorise.bitsybitshareswallet.database.joins.TransferDetail
|
import cy.agorise.bitsybitshareswallet.database.joins.TransferDetail
|
||||||
|
import cy.agorise.bitsybitshareswallet.models.FilterOptions
|
||||||
import cy.agorise.bitsybitshareswallet.utils.*
|
import cy.agorise.bitsybitshareswallet.utils.*
|
||||||
import cy.agorise.bitsybitshareswallet.viewmodels.TransferDetailViewModel
|
import cy.agorise.bitsybitshareswallet.viewmodels.TransactionsViewModel
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.disposables.CompositeDisposable
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
import kotlinx.android.synthetic.main.fragment_transactions.*
|
import kotlinx.android.synthetic.main.fragment_transactions.*
|
||||||
|
@ -31,6 +32,10 @@ import java.util.*
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows the list of transactions as well as options to filter and export those transactions
|
||||||
|
* to PDF and CSV files
|
||||||
|
*/
|
||||||
class TransactionsFragment : Fragment(), FilterOptionsDialog.OnFilterOptionsSelectedListener {
|
class TransactionsFragment : Fragment(), FilterOptionsDialog.OnFilterOptionsSelectedListener {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -39,7 +44,7 @@ class TransactionsFragment : Fragment(), FilterOptionsDialog.OnFilterOptionsSele
|
||||||
private const val REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION = 100
|
private const val REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION = 100
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var mTransferDetailViewModel: TransferDetailViewModel
|
private lateinit var mTransactionsViewModel: TransactionsViewModel
|
||||||
|
|
||||||
private lateinit var transfersDetailsAdapter: TransfersDetailsAdapter
|
private lateinit var transfersDetailsAdapter: TransfersDetailsAdapter
|
||||||
|
|
||||||
|
@ -47,17 +52,7 @@ class TransactionsFragment : Fragment(), FilterOptionsDialog.OnFilterOptionsSele
|
||||||
private val filteredTransfersDetails = ArrayList<TransferDetail>()
|
private val filteredTransfersDetails = ArrayList<TransferDetail>()
|
||||||
|
|
||||||
/** Variables used to filter the transaction items */
|
/** Variables used to filter the transaction items */
|
||||||
private var filterQuery = ""
|
private var mFilterOptions = FilterOptions()
|
||||||
private var filterTransactionsDirection = 0
|
|
||||||
private var filterDateRangeAll = true
|
|
||||||
private var filterStartDate = 0L
|
|
||||||
private var filterEndDate = 0L
|
|
||||||
private var filterAssetAll = true
|
|
||||||
private var filterAsset = "BTS"
|
|
||||||
private var filterEquivalentValueAll = true
|
|
||||||
private var filterFromEquivalentValue = 0L
|
|
||||||
private var filterToEquivalentValue = 5000L
|
|
||||||
private var filterAgoriseFees = true
|
|
||||||
|
|
||||||
private var mDisposables = CompositeDisposable()
|
private var mDisposables = CompositeDisposable()
|
||||||
|
|
||||||
|
@ -79,10 +74,10 @@ class TransactionsFragment : Fragment(), FilterOptionsDialog.OnFilterOptionsSele
|
||||||
rvTransactions.adapter = transfersDetailsAdapter
|
rvTransactions.adapter = transfersDetailsAdapter
|
||||||
rvTransactions.layoutManager = LinearLayoutManager(context)
|
rvTransactions.layoutManager = LinearLayoutManager(context)
|
||||||
|
|
||||||
// Configure TransferDetailViewModel to fetch the transaction history
|
// Configure TransactionsViewModel to fetch the transaction history
|
||||||
mTransferDetailViewModel = ViewModelProviders.of(this).get(TransferDetailViewModel::class.java)
|
mTransactionsViewModel = ViewModelProviders.of(this).get(TransactionsViewModel::class.java)
|
||||||
|
|
||||||
mTransferDetailViewModel.getAll(userId).observe(this, Observer<List<TransferDetail>> { transfersDetails ->
|
mTransactionsViewModel.getAll(userId).observe(this, Observer<List<TransferDetail>> { transfersDetails ->
|
||||||
this.transfersDetails.clear()
|
this.transfersDetails.clear()
|
||||||
this.transfersDetails.addAll(transfersDetails)
|
this.transfersDetails.addAll(transfersDetails)
|
||||||
applyFilterOptions(false)
|
applyFilterOptions(false)
|
||||||
|
@ -102,9 +97,9 @@ class TransactionsFragment : Fragment(), FilterOptionsDialog.OnFilterOptionsSele
|
||||||
|
|
||||||
// Initialize filter options
|
// Initialize filter options
|
||||||
val calendar = Calendar.getInstance()
|
val calendar = Calendar.getInstance()
|
||||||
filterEndDate = calendar.timeInMillis / 1000
|
mFilterOptions.endDate = calendar.timeInMillis
|
||||||
calendar.add(Calendar.MONTH, -2)
|
calendar.add(Calendar.MONTH, -2)
|
||||||
filterStartDate = calendar.timeInMillis / 1000
|
mFilterOptions.startDate = calendar.timeInMillis
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||||
|
@ -120,7 +115,7 @@ class TransactionsFragment : Fragment(), FilterOptionsDialog.OnFilterOptionsSele
|
||||||
.map { it.queryText.toString().toLowerCase() }
|
.map { it.queryText.toString().toLowerCase() }
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe {
|
.subscribe {
|
||||||
filterQuery = it
|
mFilterOptions.query = it
|
||||||
applyFilterOptions()
|
applyFilterOptions()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -132,11 +127,10 @@ class TransactionsFragment : Fragment(), FilterOptionsDialog.OnFilterOptionsSele
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
return when (item.itemId) {
|
return when (item.itemId) {
|
||||||
R.id.menu_filter -> {
|
R.id.menu_filter -> {
|
||||||
val filterOptionsDialog = FilterOptionsDialog.newInstance(
|
val filterOptionsDialog = FilterOptionsDialog()
|
||||||
filterTransactionsDirection, filterDateRangeAll, filterStartDate * 1000,
|
val args = Bundle()
|
||||||
filterEndDate * 1000, filterAssetAll, filterAsset,
|
args.putParcelable(FilterOptionsDialog.KEY_FILTER_OPTIONS, mFilterOptions)
|
||||||
filterEquivalentValueAll, filterFromEquivalentValue, filterToEquivalentValue, filterAgoriseFees
|
filterOptionsDialog.arguments = args
|
||||||
)
|
|
||||||
filterOptionsDialog.show(childFragmentManager, "filter-options-tag")
|
filterOptionsDialog.show(childFragmentManager, "filter-options-tag")
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
@ -168,38 +162,43 @@ class TransactionsFragment : Fragment(), FilterOptionsDialog.OnFilterOptionsSele
|
||||||
// Clean the filtered list
|
// Clean the filtered list
|
||||||
filteredTransfersDetails.clear()
|
filteredTransfersDetails.clear()
|
||||||
|
|
||||||
|
// Make sure the filter dates use the same format as the transactions' dates
|
||||||
|
val startDate = mFilterOptions.startDate / 1000
|
||||||
|
val endDate = mFilterOptions.endDate / 1000
|
||||||
|
|
||||||
for (transferDetail in transfersDetails) {
|
for (transferDetail in transfersDetails) {
|
||||||
// Filter by transfer direction
|
// Filter by transfer direction
|
||||||
if (transferDetail.direction) { // Transfer sent
|
if (transferDetail.direction) { // Transfer sent
|
||||||
if (filterTransactionsDirection == 1)
|
if (mFilterOptions.transactionsDirection == 1)
|
||||||
// Looking for received transfers only
|
// Looking for received transfers only
|
||||||
continue
|
continue
|
||||||
} else { // Transfer received
|
} else { // Transfer received
|
||||||
if (filterTransactionsDirection == 2)
|
if (mFilterOptions.transactionsDirection == 2)
|
||||||
// Looking for sent transactions only
|
// Looking for sent transactions only
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter by date range
|
// Filter by date range
|
||||||
if (!filterDateRangeAll && (transferDetail.date < filterStartDate || transferDetail.date > filterEndDate))
|
if (!mFilterOptions.dateRangeAll && (transferDetail.date < startDate ||
|
||||||
|
transferDetail.date > endDate))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
// Filter by asset
|
// Filter by asset
|
||||||
if (!filterAssetAll && transferDetail.assetSymbol != filterAsset)
|
if (!mFilterOptions.assetAll && transferDetail.assetSymbol != mFilterOptions.asset)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
// Filter by equivalent value
|
// Filter by equivalent value
|
||||||
if (!filterEquivalentValueAll && ((transferDetail.fiatAmount ?: -1 ) < filterFromEquivalentValue
|
if (!mFilterOptions.equivalentValueAll && ((transferDetail.fiatAmount ?: -1 ) < mFilterOptions.fromEquivalentValue
|
||||||
|| (transferDetail.fiatAmount ?: -1) > filterToEquivalentValue))
|
|| (transferDetail.fiatAmount ?: -1) > mFilterOptions.toEquivalentValue))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
// Filter transactions sent to agorise
|
// Filter transactions sent to agorise
|
||||||
if (filterAgoriseFees && transferDetail.to.equals("agorise"))
|
if (mFilterOptions.agoriseFees && transferDetail.to.equals("agorise"))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
// Filter by search query
|
// Filter by search query
|
||||||
val text = (transferDetail.from ?: "").toLowerCase() + (transferDetail.to ?: "").toLowerCase()
|
val text = (transferDetail.from ?: "").toLowerCase() + (transferDetail.to ?: "").toLowerCase()
|
||||||
if (text.contains(filterQuery, ignoreCase = true)) {
|
if (text.contains(mFilterOptions.query, ignoreCase = true)) {
|
||||||
filteredTransfersDetails.add(transferDetail)
|
filteredTransfersDetails.add(transferDetail)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -214,28 +213,8 @@ class TransactionsFragment : Fragment(), FilterOptionsDialog.OnFilterOptionsSele
|
||||||
/**
|
/**
|
||||||
* Gets called when the user selects some filter options in the [FilterOptionsDialog] and wants to apply them.
|
* Gets called when the user selects some filter options in the [FilterOptionsDialog] and wants to apply them.
|
||||||
*/
|
*/
|
||||||
override fun onFilterOptionsSelected(
|
override fun onFilterOptionsSelected(filterOptions: FilterOptions) {
|
||||||
filterTransactionsDirection: Int,
|
mFilterOptions = filterOptions
|
||||||
filterDateRangeAll: Boolean,
|
|
||||||
filterStartDate: Long,
|
|
||||||
filterEndDate: Long,
|
|
||||||
filterAssetAll: Boolean,
|
|
||||||
filterAsset: String,
|
|
||||||
filterEquivalentValueAll: Boolean,
|
|
||||||
filterFromEquivalentValue: Long,
|
|
||||||
filterToEquivalentValue: Long,
|
|
||||||
filterAgoriseFees: Boolean
|
|
||||||
) {
|
|
||||||
this.filterTransactionsDirection = filterTransactionsDirection
|
|
||||||
this.filterDateRangeAll = filterDateRangeAll
|
|
||||||
this.filterStartDate = filterStartDate / 1000
|
|
||||||
this.filterEndDate = filterEndDate / 1000
|
|
||||||
this.filterAssetAll = filterAssetAll
|
|
||||||
this.filterAsset = filterAsset
|
|
||||||
this.filterEquivalentValueAll = filterEquivalentValueAll
|
|
||||||
this.filterFromEquivalentValue = filterFromEquivalentValue
|
|
||||||
this.filterToEquivalentValue = filterToEquivalentValue
|
|
||||||
this.filterAgoriseFees = filterAgoriseFees
|
|
||||||
applyFilterOptions(true)
|
applyFilterOptions(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,7 +223,7 @@ class TransactionsFragment : Fragment(), FilterOptionsDialog.OnFilterOptionsSele
|
||||||
if (ContextCompat.checkSelfPermission(activity!!, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
if (ContextCompat.checkSelfPermission(activity!!, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||||
!= PackageManager.PERMISSION_GRANTED) {
|
!= PackageManager.PERMISSION_GRANTED) {
|
||||||
// Permission is not already granted
|
// Permission is not already granted
|
||||||
requestPermissions(arrayOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE),
|
requestPermissions(arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
|
||||||
REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION)
|
REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION)
|
||||||
} else {
|
} else {
|
||||||
// Permission is already granted
|
// Permission is already granted
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
package cy.agorise.bitsybitshareswallet.models
|
||||||
|
|
||||||
|
import android.os.Parcel
|
||||||
|
import android.os.Parcelable
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model that includes all the options to filter the transactions in the [TransactionsFragment]
|
||||||
|
*/
|
||||||
|
data class FilterOptions (
|
||||||
|
var query: String = "",
|
||||||
|
var transactionsDirection: Int = 0,
|
||||||
|
var dateRangeAll: Boolean = true,
|
||||||
|
var startDate: Long = 0L,
|
||||||
|
var endDate: Long = 0L,
|
||||||
|
var assetAll: Boolean = true,
|
||||||
|
var asset: String = "BTS",
|
||||||
|
var equivalentValueAll: Boolean = true,
|
||||||
|
var fromEquivalentValue: Long = 0L,
|
||||||
|
var toEquivalentValue: Long = 5000L,
|
||||||
|
var agoriseFees: Boolean = true
|
||||||
|
) : Parcelable {
|
||||||
|
constructor(parcel: Parcel) : this(
|
||||||
|
parcel.readString(),
|
||||||
|
parcel.readInt(),
|
||||||
|
parcel.readByte() != 0.toByte(),
|
||||||
|
parcel.readLong(),
|
||||||
|
parcel.readLong(),
|
||||||
|
parcel.readByte() != 0.toByte(),
|
||||||
|
parcel.readString(),
|
||||||
|
parcel.readByte() != 0.toByte(),
|
||||||
|
parcel.readLong(),
|
||||||
|
parcel.readLong(),
|
||||||
|
parcel.readByte() != 0.toByte()
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
||||||
|
parcel.writeString(query)
|
||||||
|
parcel.writeInt(transactionsDirection)
|
||||||
|
parcel.writeByte(if (dateRangeAll) 1 else 0)
|
||||||
|
parcel.writeLong(startDate)
|
||||||
|
parcel.writeLong(endDate)
|
||||||
|
parcel.writeByte(if (assetAll) 1 else 0)
|
||||||
|
parcel.writeString(asset)
|
||||||
|
parcel.writeByte(if (equivalentValueAll) 1 else 0)
|
||||||
|
parcel.writeLong(fromEquivalentValue)
|
||||||
|
parcel.writeLong(toEquivalentValue)
|
||||||
|
parcel.writeByte(if (agoriseFees) 1 else 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun describeContents(): Int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object CREATOR : Parcelable.Creator<FilterOptions> {
|
||||||
|
override fun createFromParcel(parcel: Parcel): FilterOptions {
|
||||||
|
return FilterOptions(parcel)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun newArray(size: Int): Array<FilterOptions?> {
|
||||||
|
return arrayOfNulls(size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -6,7 +6,7 @@ import androidx.lifecycle.LiveData
|
||||||
import cy.agorise.bitsybitshareswallet.database.joins.TransferDetail
|
import cy.agorise.bitsybitshareswallet.database.joins.TransferDetail
|
||||||
import cy.agorise.bitsybitshareswallet.repositories.TransferDetailRepository
|
import cy.agorise.bitsybitshareswallet.repositories.TransferDetailRepository
|
||||||
|
|
||||||
class TransferDetailViewModel(application: Application) : AndroidViewModel(application) {
|
class TransactionsViewModel(application: Application) : AndroidViewModel(application) {
|
||||||
private var mRepository = TransferDetailRepository(application)
|
private var mRepository = TransferDetailRepository(application)
|
||||||
|
|
||||||
internal fun getAll(userId: String): LiveData<List<TransferDetail>> {
|
internal fun getAll(userId: String): LiveData<List<TransferDetail>> {
|
Loading…
Reference in a new issue