diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/FilterOptionsDialog.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/FilterOptionsDialog.kt
new file mode 100644
index 0000000..a384a25
--- /dev/null
+++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/FilterOptionsDialog.kt
@@ -0,0 +1,316 @@
+package cy.agorise.bitsybitshareswallet.fragments
+
+
+import android.app.Dialog
+import android.content.res.Resources
+import android.os.Bundle
+import android.os.Handler
+import android.os.Message
+import androidx.fragment.app.DialogFragment
+import android.widget.*
+import androidx.appcompat.app.AlertDialog
+import androidx.fragment.app.Fragment
+import cy.agorise.bitsybitshareswallet.R
+import java.text.SimpleDateFormat
+import java.util.*
+import kotlin.ClassCastException
+
+
+/**
+ * Creates a Dialog that communicates with {@link TransactionsActivity} to give it parameters about
+ * how to filter the list of Transactions
+ */
+class FilterOptionsDialog : DialogFragment() {
+
+ // Widgets TODO use android-kotlin-extensions {onViewCreated}
+ lateinit var rbTransactionAll: RadioButton
+ lateinit var rbTransactionSent: RadioButton
+ lateinit var rbTransactionReceived: RadioButton
+ lateinit var cbDateRange: CheckBox
+ lateinit var llDateRange: LinearLayout
+ lateinit var tvStartDate: TextView
+ lateinit var tvEndDate: TextView
+ lateinit var cbCryptocurrency: CheckBox
+ lateinit var sCryptocurrency: Spinner
+ lateinit var cbFiatAmount: CheckBox
+ lateinit var llFiatAmount: LinearLayout
+// lateinit var etFromFiatAmount: CurrencyEditText
+// lateinit var etToFiatAmount: CurrencyEditText
+
+ private var mCallback: OnFilterOptionsSelectedListener? = null
+
+ private var mDatePickerHandler: DatePickerHandler? = null
+
+ private var dateFormat: SimpleDateFormat = SimpleDateFormat("d/MMM/yyyy",
+ Resources.getSystem().configuration.locale)
+
+ private var startDate: Long = 0
+ private var endDate: Long = 0
+
+// /**
+// * Variable used to keep track of the current user's currency
+// */
+// private val mUserCurrency = RuntimeData.EXTERNAL_CURRENCY
+
+ companion object {
+
+ const val KEY_FILTER_TRANSACTION_DIRECTION = "key_filter_transaction_direction"
+ 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_CRYPTOCURRENCY_ALL = "key_filter_cryptocurrency_all"
+ const val KEY_FILTER_CRYPTOCURRENCY = "key_filter_cryptocurrency"
+ const val KEY_FILTER_FIAT_AMOUNT_ALL = "key_filter_fiat_amount_all"
+ const val KEY_FILTER_FROM_FIAT_AMOUNT = "filter_from_fiat_amount"
+ const val KEY_FILTER_TO_FIAT_AMOUNT = "filter_to_fiat_amount"
+
+ const val KEY_TIMESTAMP = "key_timestamp"
+
+ const val START_DATE_PICKER = 0
+ const val END_DATE_PICKER = 1
+
+ fun newInstance(filterTransactionsDirection: Int, filterDateRangeAll: Boolean,
+ filterStartDate: Long, filterEndDate: Long, filterCryptocurrencyAll: Boolean,
+ filterCryptocurrency: String, filterFiatAmountAll: Boolean,
+ filterFromFiatAmount: Long, filterToFiatAmount: Long): 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_CRYPTOCURRENCY_ALL, filterCryptocurrencyAll)
+ args.putString(KEY_FILTER_CRYPTOCURRENCY, filterCryptocurrency)
+ args.putBoolean(KEY_FILTER_FIAT_AMOUNT_ALL, filterFiatAmountAll)
+ args.putLong(KEY_FILTER_FROM_FIAT_AMOUNT, filterFromFiatAmount)
+ args.putLong(KEY_FILTER_TO_FIAT_AMOUNT, filterToFiatAmount)
+ frag.arguments = args
+ return frag
+ }
+
+ }
+
+ /**
+ * DatePicker message handler.
+ */
+ inner class DatePickerHandler : Handler() {
+
+ override fun handleMessage(msg: Message) {
+ super.handleMessage(msg)
+ val bundle = msg.data
+ val timestamp = bundle.get(KEY_TIMESTAMP) as Long
+ //Log.d(TAG, "timestamp: $timestamp")
+ when (msg.arg1) {
+ START_DATE_PICKER -> {
+ startDate = timestamp
+
+ updateDateTextViews()
+ }
+ END_DATE_PICKER -> {
+ endDate = timestamp
+
+ // Make sure there is at least one moth difference between start and end time
+ val calendar = Calendar.getInstance()
+ calendar.timeInMillis = endDate
+ calendar.add(Calendar.MONTH, -1)
+
+ val tmpTime = calendar.timeInMillis
+
+ if (tmpTime < startDate)
+ startDate = tmpTime
+
+ updateDateTextViews()
+ }
+ }
+ }
+ }
+
+ private fun updateDateTextViews() {
+ var date = Date(startDate)
+ tvStartDate.text = dateFormat.format(date)
+
+ date = Date(endDate)
+ tvEndDate.text = dateFormat.format(date)
+ }
+
+ // Container Activity must implement this interface
+ interface OnFilterOptionsSelectedListener {
+ fun onFilterOptionsSelected(filterTransactionsDirection: Int,
+ filterDateRangeAll: Boolean,
+ filterStartDate: Long,
+ filterEndDate: Long,
+ filterCryptocurrencyAll: Boolean,
+ filterCryptocurrency: String,
+ filterFiatAmountAll: Boolean,
+ filterFromFiatAmount: Long,
+ filterToFiatAmount: Long)
+ }
+
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ onAttachToParentFragment(parentFragment!!)
+
+ // Initialize handler for communication with the DatePicker
+ mDatePickerHandler = DatePickerHandler()
+
+ val builder = AlertDialog.Builder(context!!)
+ .setTitle("Filter options")
+ .setPositiveButton("Filter") { _, _ -> validateFields() }
+ .setNegativeButton("Cancel") { _, _ -> dismiss() }
+
+ // Inflate layout
+ val inflater = activity!!.layoutInflater
+ val view = inflater.inflate(R.layout.dialog_filter_options, null)
+
+ // Initialize Transactions direction
+ rbTransactionAll = view.findViewById(R.id.rbTransactionAll)
+ rbTransactionSent = view.findViewById(R.id.rbTransactionSent)
+ rbTransactionReceived = view.findViewById(R.id.rbTransactionReceived)
+ val radioButtonChecked = arguments!!.getInt(KEY_FILTER_TRANSACTION_DIRECTION, 0)
+ when (radioButtonChecked) {
+ 0 -> rbTransactionAll.isChecked = true
+ 1 -> rbTransactionSent.isChecked = true
+ 2 -> rbTransactionReceived.isChecked = true
+ }
+
+ // Initialize Date range
+ cbDateRange = view.findViewById(R.id.cbDateRange)
+// llDateRange = view.findViewById(R.id.llDateRange)
+// cbDateRange.setOnCheckedChangeListener { _, isChecked ->
+// llDateRange.visibility = if(isChecked) View.GONE else View.VISIBLE }
+ cbDateRange.isChecked = arguments!!.getBoolean(KEY_FILTER_DATE_RANGE_ALL, true)
+//
+// tvStartDate = view.findViewById(R.id.tvStartDate)
+// tvEndDate = view.findViewById(R.id.tvEndDate)
+//
+// startDate = arguments!!.getLong(KEY_FILTER_START_DATE, 0)
+// tvStartDate.setOnClickListener(mDateClickListener)
+//
+// endDate = arguments!!.getLong(KEY_FILTER_END_DATE, 0)
+// tvEndDate.setOnClickListener(mDateClickListener)
+//
+// updateDateTextViews()
+
+ // Initialize Cryptocurrency
+ cbCryptocurrency = view.findViewById(R.id.cbCryptocurrency)
+// sCryptocurrency = view.findViewById(R.id.sCryptocurrency)
+// cbCryptocurrency.setOnCheckedChangeListener { _, isChecked ->
+// sCryptocurrency.visibility = if(isChecked) View.GONE else View.VISIBLE }
+ cbCryptocurrency.isChecked = arguments!!.getBoolean(KEY_FILTER_CRYPTOCURRENCY_ALL, true)
+
+// sCryptocurrency = view.findViewById(R.id.sCryptocurrency)
+// initializeCryptocurrencySpinner()
+
+
+ // Initialize Fiat amount
+ cbFiatAmount = view.findViewById(R.id.cbFiatAmount)
+// llFiatAmount = view.findViewById(R.id.llFiatAmount)
+// cbFiatAmount.setOnCheckedChangeListener { _, isChecked ->
+// llFiatAmount.visibility = if(isChecked) View.GONE else View.VISIBLE }
+ cbFiatAmount.isChecked = arguments!!.getBoolean(KEY_FILTER_FIAT_AMOUNT_ALL, true)
+
+// val locale = Resources.getSystem().configuration.locale
+//
+// etFromFiatAmount = view.findViewById(R.id.etFromFiatAmount)
+// etFromFiatAmount.locale = locale
+// val fromFiatAmount = arguments!!.getLong(KEY_FILTER_FROM_FIAT_AMOUNT, 0)
+// etFromFiatAmount.setText("$fromFiatAmount", TextView.BufferType.EDITABLE)
+//
+// etToFiatAmount = view.findViewById(R.id.etToFiatAmount)
+// etToFiatAmount.locale = locale
+// val toFiatAmount = arguments!!.getLong(KEY_FILTER_TO_FIAT_AMOUNT, 0)
+// etToFiatAmount.setText("$toFiatAmount", TextView.BufferType.EDITABLE)
+
+ builder.setView(view)
+
+ return builder.create()
+ }
+
+ /**
+ * Attaches the current [DialogFragment] to its [Fragment] parent, to initialize the
+ * [OnFilterOptionsSelectedListener] interface
+ */
+ private fun onAttachToParentFragment(fragment: Fragment) {
+ try {
+ mCallback = fragment as OnFilterOptionsSelectedListener
+ } catch (e: ClassCastException) {
+ throw ClassCastException(fragment.toString() + " must implement OnFilterOptionsSelectedListener")
+ }
+ }
+
+// private fun initializeCryptocurrencySpinner() {
+// val cryptoCurrencyList = database!!.getSortedCryptoCurrencies(false,
+// SortType.DESCENDING, true)
+//
+// val cryptocurrencySpinnerAdapter = CryptocurrencySpinnerAdapter(context!!,
+// R.layout.item_cryptocurrency,
+// R.id.tvCryptocurrencyName,
+// cryptoCurrencyList)
+//
+// sCryptocurrency.adapter = cryptocurrencySpinnerAdapter
+//
+// val cryptocurrencySelected = arguments!!.getString(KEY_FILTER_CRYPTOCURRENCY)
+//
+// val index = Math.max(cryptocurrencySpinnerAdapter.getPosition(database!!.getCryptocurrencyBySymbol(
+// cryptocurrencySelected)), 0)
+//
+// sCryptocurrency.setSelection(index)
+// }
+
+// private val mDateClickListener = View.OnClickListener { v ->
+// val calendar = Calendar.getInstance()
+//
+// // Variable used to select that date on the calendar
+// var currentTime = calendar.timeInMillis
+// var maxTime = currentTime
+//
+// var which = -1
+// if (v.id == R.id.tvStartDate) {
+// which = START_DATE_PICKER
+// currentTime = startDate
+// calendar.timeInMillis = endDate
+// calendar.add(Calendar.MONTH, -1)
+// maxTime = calendar.timeInMillis
+// } else if (v.id == R.id.tvEndDate) {
+// which = END_DATE_PICKER
+// currentTime = endDate
+// }
+//
+// val datePickerFragment = DatePickerFragment.newInstance(which, currentTime,
+// maxTime, mDatePickerHandler)
+// datePickerFragment.show(activity!!.supportFragmentManager, "date-picker")
+// }
+
+ private fun validateFields() {
+ val filterTransactionsDirection = 0 //when {
+// rbTransactionAll.isChecked -> 0
+// rbTransactionSent.isChecked -> 1
+// rbTransactionReceived.isChecked -> 2
+// else -> { 0 }
+// }
+
+ val filterDateRangeAll = cbDateRange.isChecked
+
+ val filterCryptocurrencyAll = cbCryptocurrency.isChecked
+
+ val filterCryptocurrency = "" //(sCryptocurrency.selectedItem as CryptoCurrency).symbol
+
+ val filterFiatAmountAll = cbFiatAmount.isChecked
+
+ val filterFromFiatAmount = 0L//(etFromFiatAmount.currencyDouble *
+// Math.pow(10.0, mUserCurrency.defaultFractionDigits.toDouble())).toLong()
+
+ var filterToFiatAmount = 1L//(etToFiatAmount.currencyDouble *
+// Math.pow(10.0, mUserCurrency.defaultFractionDigits.toDouble())).toLong()
+
+ // Make sure ToFiatAmount is at least 50 units bigger than FromFiatAmount
+// if (!filterFiatAmountAll && filterToFiatAmount <= filterFromFiatAmount) {
+// filterToFiatAmount = filterFromFiatAmount + 50 *
+// Math.pow(10.0, mUserCurrency.defaultFractionDigits.toDouble()).toLong()
+// }
+
+ mCallback!!.onFilterOptionsSelected(filterTransactionsDirection, filterDateRangeAll,
+ startDate, endDate, filterCryptocurrencyAll, filterCryptocurrency, filterFiatAmountAll,
+ filterFromFiatAmount, filterToFiatAmount)
+ }
+}
\ No newline at end of file
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 f092bcd..8527710 100644
--- a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/TransactionsFragment.kt
+++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/TransactionsFragment.kt
@@ -24,7 +24,7 @@ import java.util.*
import java.util.concurrent.TimeUnit
import kotlin.collections.ArrayList
-class TransactionsFragment : Fragment() {
+class TransactionsFragment : Fragment(), FilterOptionsDialog.OnFilterOptionsSelectedListener {
private lateinit var mTransferDetailViewModel: TransferDetailViewModel
@@ -87,7 +87,7 @@ class TransactionsFragment : Fragment() {
inflater.inflate(R.menu.menu_transactions, menu)
// Adds listener for the SearchView
- val searchItem = menu.findItem(R.id.menuSearch)
+ val searchItem = menu.findItem(R.id.menu_search)
val searchView = searchItem.actionView as SearchView
mDisposables.add(
searchView.queryTextChangeEvents()
@@ -105,6 +105,25 @@ class TransactionsFragment : Fragment() {
searchView.maxWidth = getScreenWidth(activity) * 3 / 5
}
+ override fun onOptionsItemSelected(item: MenuItem?): Boolean {
+ return when (item?.itemId) {
+ R.id.menu_filter -> {
+ val filterOptionsDialog = FilterOptionsDialog.newInstance(
+ filterTransactionsDirection, filterDateRangeAll, filterStartDate * 1000,
+ filterEndDate * 1000, filterCryptocurrencyAll, filterCryptocurrency,
+ filterFiatAmountAll, filterFromFiatAmount, filterToFiatAmount
+ )
+ filterOptionsDialog.show(childFragmentManager, "filter-options-tag")
+ true
+ }
+ R.id.menu_export -> {
+ // TODO add export options
+ true
+ }
+ else -> super.onOptionsItemSelected(item)
+ }
+ }
+
/**
* Returns the screen width in pixels for the given [FragmentActivity]
*/
@@ -163,6 +182,32 @@ class TransactionsFragment : Fragment() {
rvTransactions.scrollToPosition(0)
}
+ /**
+ *
+ */
+ override fun onFilterOptionsSelected(
+ filterTransactionsDirection: Int,
+ filterDateRangeAll: Boolean,
+ filterStartDate: Long,
+ filterEndDate: Long,
+ filterCryptocurrencyAll: Boolean,
+ filterCryptocurrency: String,
+ filterFiatAmountAll: Boolean,
+ filterFromFiatAmount: Long,
+ filterToFiatAmount: Long
+ ) {
+ this.filterTransactionsDirection = filterTransactionsDirection
+ this.filterDateRangeAll = filterDateRangeAll
+ this.filterStartDate = filterStartDate / 1000
+ this.filterEndDate = filterEndDate / 1000
+ this.filterCryptocurrencyAll = filterCryptocurrencyAll
+ this.filterCryptocurrency = filterCryptocurrency
+ this.filterFiatAmountAll = filterFiatAmountAll
+ this.filterFromFiatAmount = filterFromFiatAmount
+ this.filterToFiatAmount = filterToFiatAmount
+ applyFilterOptions(true)
+ }
+
override fun onDestroy() {
super.onDestroy()
diff --git a/app/src/main/res/layout/dialog_filter_options.xml b/app/src/main/res/layout/dialog_filter_options.xml
new file mode 100644
index 0000000..15cc40a
--- /dev/null
+++ b/app/src/main/res/layout/dialog_filter_options.xml
@@ -0,0 +1,189 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/menu_transactions.xml b/app/src/main/res/menu/menu_transactions.xml
index 097141f..75b0095 100644
--- a/app/src/main/res/menu/menu_transactions.xml
+++ b/app/src/main/res/menu/menu_transactions.xml
@@ -3,21 +3,21 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
-
-
-