From 23f41706283cd12fffdc7e5ebec199146d262305 Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Fri, 27 May 2022 22:38:06 -0700 Subject: [PATCH] Avoid requesting storage permission to share eReceipt. --- .../adapters/TransfersDetailsAdapter.kt | 2 +- .../fragments/EReceiptFragment.kt | 62 +++-------- .../ui/transactions/TransactionsViewModel.kt | 101 +++++++++--------- 3 files changed, 64 insertions(+), 101 deletions(-) diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/TransfersDetailsAdapter.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/TransfersDetailsAdapter.kt index 93f26d5..f2c29b2 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/TransfersDetailsAdapter.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/TransfersDetailsAdapter.kt @@ -16,7 +16,7 @@ import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.SortedList import cy.agorise.bitsybitshareswallet.R import cy.agorise.bitsybitshareswallet.database.joins.TransferDetail -import cy.agorise.bitsybitshareswallet.fragments.TransactionsFragmentDirections +import cy.agorise.bitsybitshareswallet.ui.transactions.TransactionsFragmentDirections import java.math.RoundingMode import java.text.DecimalFormat import java.text.DecimalFormatSymbols diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/EReceiptFragment.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/EReceiptFragment.kt index eee0541..3bb9b1d 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/EReceiptFragment.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/EReceiptFragment.kt @@ -1,8 +1,6 @@ package cy.agorise.bitsybitshareswallet.fragments -import android.Manifest import android.content.Intent -import android.content.pm.PackageManager import android.graphics.drawable.Animatable import android.os.Bundle import android.text.method.LinkMovementMethod @@ -20,7 +18,6 @@ import cy.agorise.bitsybitshareswallet.database.joins.TransferDetail import cy.agorise.bitsybitshareswallet.databinding.FragmentEReceiptBinding import cy.agorise.bitsybitshareswallet.utils.Constants import cy.agorise.bitsybitshareswallet.utils.Helper -import cy.agorise.bitsybitshareswallet.utils.toast import cy.agorise.bitsybitshareswallet.viewmodels.EReceiptViewModel import java.math.RoundingMode import java.text.DecimalFormat @@ -28,15 +25,10 @@ import java.text.DecimalFormatSymbols import java.text.NumberFormat import java.text.SimpleDateFormat import java.util.* +import kotlin.math.pow class EReceiptFragment : Fragment() { - companion object { - private const val TAG = "EReceiptFragment" - - private const val REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION = 100 - } - private val args: EReceiptFragmentArgs by navArgs() private val viewModel: EReceiptViewModel by viewModels() @@ -75,9 +67,9 @@ class EReceiptFragment : Fragment() { val transferId = args.transferId - viewModel.get(userId, transferId).observe(viewLifecycleOwner, { transferDetail -> + viewModel.get(userId, transferId).observe(viewLifecycleOwner) { transferDetail -> bindTransferDetail(transferDetail) - }) + } } private fun bindTransferDetail(transferDetail: TransferDetail) { @@ -95,7 +87,7 @@ class EReceiptFragment : Fragment() { df.decimalFormatSymbols = DecimalFormatSymbols(Locale.getDefault()) val amount = transferDetail.assetAmount.toDouble() / - Math.pow(10.toDouble(), transferDetail.assetPrecision.toDouble()) + 10.toDouble().pow(transferDetail.assetPrecision.toDouble()) val assetAmount = "${df.format(amount)} ${transferDetail.getUIAssetSymbol()}" binding.tvAmount.text = assetAmount @@ -104,7 +96,7 @@ class EReceiptFragment : Fragment() { val numberFormat = NumberFormat.getNumberInstance() val currency = Currency.getInstance(transferDetail.fiatSymbol) val fiatEquivalent = transferDetail.fiatAmount.toDouble() / - Math.pow(10.0, currency.defaultFractionDigits.toDouble()) + 10.0.pow(currency.defaultFractionDigits.toDouble()) val equivalentValue = "${numberFormat.format(fiatEquivalent)} ${currency.currencyCode}" binding.tvEquivalentValue.text = equivalentValue @@ -151,47 +143,13 @@ class EReceiptFragment : Fragment() { override fun onOptionsItemSelected(item: MenuItem): Boolean { if (item.itemId == R.id.menu_share) { - verifyStoragePermission() + shareEReceiptScreenshot() return true } + return super.onOptionsItemSelected(item) } - /** Verifies if the storage permission is already granted, if that is the case then it takes the screenshot and - * shares it but if it is not then it asks the user for that permission */ - private fun verifyStoragePermission() { - if (ContextCompat - .checkSelfPermission(requireActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE) - != PackageManager.PERMISSION_GRANTED - ) { - // Permission is not already granted - requestPermissions( - arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), - REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION - ) - } else { - // Permission is already granted - shareEReceiptScreenshot() - } - } - - override fun onRequestPermissionsResult( - requestCode: Int, - permissions: Array, - grantResults: IntArray - ) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults) - - if (requestCode == REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION) { - if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) { - shareEReceiptScreenshot() - } else { - context?.toast(getString(R.string.msg__storage_permission_necessary_share)) - } - return - } - } - /** Takes a screenshot as a bitmap (hiding the tx hyperlink), saves it into a temporal cache image and then * sends an intent so the user can select the desired method to share the image. */ private fun shareEReceiptScreenshot() { @@ -214,4 +172,8 @@ class EReceiptFragment : Fragment() { shareIntent.type = "*/*" startActivity(Intent.createChooser(shareIntent, getString(R.string.text__share_with))) } -} \ No newline at end of file + + companion object { + private const val TAG = "EReceiptFragment" + } +} diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/ui/transactions/TransactionsViewModel.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/ui/transactions/TransactionsViewModel.kt index a81a96e..5fff0b2 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/ui/transactions/TransactionsViewModel.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/ui/transactions/TransactionsViewModel.kt @@ -81,8 +81,6 @@ class TransactionsViewModel(application: Application) : AndroidViewModel(applica } } - internal fun getFilteredTransactionsOnce() = filteredTransactions.value - /** * Filters the given list of [TransferDetail] given the [FilterOptions] and returns a filtered list * of [TransferDetail], doing all the work in a background thread using kotlin coroutines @@ -90,58 +88,56 @@ class TransactionsViewModel(application: Application) : AndroidViewModel(applica private suspend fun filter( transactions: List, filterOptions: FilterOptions - ): List { - return withContext(Dispatchers.Default) { + ): List = withContext(Dispatchers.Default) { - // Create a list to store the filtered transactions - val filteredTransactions = ArrayList() + // Create a list to store the filtered transactions + val filteredTransactions = ArrayList() - // Make sure the filter dates use the same format as the transactions' dates - val startDate = filterOptions.startDate / 1000 - val endDate = filterOptions.endDate / 1000 + // Make sure the filter dates use the same format as the transactions' dates + val startDate = filterOptions.startDate / 1000 + val endDate = filterOptions.endDate / 1000 - for (transaction in transactions) { - // Filter by transfer direction - if (transaction.direction) { // Transfer sent - if (filterOptions.transactionsDirection == 1) - // Looking for received transfers only - continue - } else { // Transfer received - if (filterOptions.transactionsDirection == 2) - // Looking for sent transactions only - continue - } - - // Filter by date range - if (!filterOptions.dateRangeAll && (transaction.date < startDate || - transaction.date > endDate) - ) + for (transaction in transactions) { + // Filter by transfer direction + if (transaction.direction) { // Transfer sent + if (filterOptions.transactionsDirection == 1) + // Looking for received transfers only continue - - // Filter by asset - if (!filterOptions.assetAll && transaction.assetSymbol != filterOptions.asset) + } else { // Transfer received + if (filterOptions.transactionsDirection == 2) + // Looking for sent transactions only continue - - // Filter by equivalent value - if (!filterOptions.equivalentValueAll && ((transaction.fiatAmount - ?: -1) < filterOptions.fromEquivalentValue - || (transaction.fiatAmount ?: -1) > filterOptions.toEquivalentValue) - ) - continue - - // Filter transactions sent to agorise - if (filterOptions.agoriseFees && transaction.to.equals("agorise")) - continue - - // Filter by search query - val text = "${transaction.from ?: ""} ${transaction.to ?: ""} ${transaction.memo}" - if (text.contains(filterOptions.query, ignoreCase = true)) { - filteredTransactions.add(transaction) - } } - filteredTransactions + // Filter by date range + if (!filterOptions.dateRangeAll && (transaction.date < startDate || + transaction.date > endDate) + ) + continue + + // Filter by asset + if (!filterOptions.assetAll && transaction.assetSymbol != filterOptions.asset) + continue + + // Filter by equivalent value + if (!filterOptions.equivalentValueAll && ((transaction.fiatAmount + ?: -1) < filterOptions.fromEquivalentValue + || (transaction.fiatAmount ?: -1) > filterOptions.toEquivalentValue) + ) + continue + + // Filter transactions sent to agorise + if (filterOptions.agoriseFees && transaction.to.equals("agorise")) + continue + + // Filter by search query + val text = "${transaction.from ?: ""} ${transaction.to ?: ""} ${transaction.memo}" + if (text.contains(filterOptions.query, ignoreCase = true)) { + filteredTransactions.add(transaction) + } } + + filteredTransactions } /** Creates the export procedures for PDF and CSV, depending on the user selection. */ @@ -152,13 +148,18 @@ class TransactionsViewModel(application: Application) : AndroidViewModel(applica // TODO Use injected context val folderDocumentFile = DocumentFile.fromTreeUri(getApplication(), folderUri) ?: return + val transactions = filteredTransactions.value ?: return if (exportPdf) { viewModelScope.launch { - filteredTransactions.value?.let { transactions -> - // TODO Show success/failure message - exportTransactionsToPdfUseCase(transactions, folderDocumentFile) - } + // TODO Show success/failure message + exportTransactionsToPdfUseCase(transactions, folderDocumentFile) + } + } + + if (exportCsv) { + viewModelScope.launch { + // TODO Export CSV } } }