diff --git a/app/build.gradle b/app/build.gradle index 6ad918c1..f7dbed0c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -43,6 +43,7 @@ android { buildConfigField("int", "TargetTimePerBlock", "120") buildConfigField("String", "LogDir", "\"/wallets/testnet3/dcrlibwallet.log\"") buildConfigField("String", "NetType", "\"testnet3\"") + buildConfigField("String", "PoliteiaHost", "\"https://test-proposals.decred.org\"") resValue "string", "app_name", "Decred Wallet Testnet" manifestPlaceholders = [ appIcon : "@mipmap/ic_launcher_testnet", @@ -58,6 +59,7 @@ android { buildConfigField("int", "TargetTimePerBlock", "300") buildConfigField("String", "LogDir", "\"/wallets/mainnet/dcrlibwallet.log\"") buildConfigField("String", "NetType", "\"mainnet\"") + buildConfigField("String", "PoliteiaHost", "\"https://proposals.decred.org\"") resValue "string", "app_name", "Decred Wallet" manifestPlaceholders = [ appIcon : "@mipmap/ic_launcher_mainnet", diff --git a/app/src/main/java/com/dcrandroid/HomeActivity.kt b/app/src/main/java/com/dcrandroid/HomeActivity.kt index a1835710..15498640 100644 --- a/app/src/main/java/com/dcrandroid/HomeActivity.kt +++ b/app/src/main/java/com/dcrandroid/HomeActivity.kt @@ -149,7 +149,7 @@ class HomeActivity : BaseActivity(), SyncProgressListener, TxAndBlockNotificatio } delay(6000) try { - multiWallet!!.politeia.sync() + multiWallet!!.politeia.sync(BuildConfig.PoliteiaHost) } catch (e: Exception) { e.printStackTrace() } diff --git a/app/src/main/java/com/dcrandroid/activities/ProposalDetailsActivity.kt b/app/src/main/java/com/dcrandroid/activities/ProposalDetailsActivity.kt index 47fd544c..86de47ed 100644 --- a/app/src/main/java/com/dcrandroid/activities/ProposalDetailsActivity.kt +++ b/app/src/main/java/com/dcrandroid/activities/ProposalDetailsActivity.kt @@ -6,12 +6,14 @@ import android.os.Bundle import android.view.View import androidx.appcompat.content.res.AppCompatResources import androidx.core.widget.NestedScrollView +import com.dcrandroid.BuildConfig import com.dcrandroid.R import com.dcrandroid.data.Constants import com.dcrandroid.data.Proposal import com.dcrandroid.extensions.hide import com.dcrandroid.extensions.show import com.dcrandroid.util.Utils +import dcrlibwallet.Dcrlibwallet import io.noties.markwon.Markwon import io.noties.markwon.ext.tables.TableAwareMovementMethod import io.noties.markwon.ext.tables.TablePlugin @@ -44,7 +46,7 @@ class ProposalDetailsActivity : BaseActivity() { loadProposalDetails() open_proposal.setOnClickListener { - val url = getString(R.string.politeia_server_url) + proposal.token + val url = BuildConfig.PoliteiaHost + "/record/" + proposal.token val i = Intent(Intent.ACTION_VIEW) i.data = Uri.parse(url) startActivity(i) @@ -55,7 +57,7 @@ class ProposalDetailsActivity : BaseActivity() { share.type = getString(R.string.text_pain) share.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT) share.putExtra(Intent.EXTRA_SUBJECT, proposal.name) - share.putExtra(Intent.EXTRA_TEXT, getString(R.string.politeia_server_url) + proposal.token) + share.putExtra(Intent.EXTRA_TEXT, BuildConfig.PoliteiaHost + "/record/" + proposal.token) startActivity(Intent.createChooser(share, getString(R.string.share_proposal))) } @@ -99,7 +101,7 @@ class ProposalDetailsActivity : BaseActivity() { // keep trying to load the description while displaying any errors from the screen while (true) { try { - val description = multiWallet!!.politeia.fetchProposalDescription(proposal.token) + val description = multiWallet!!.politeia.fetchProposalDescription(BuildConfig.PoliteiaHost, proposal.token) withContext(Dispatchers.Main) { description_progress?.hide() // set markdown diff --git a/app/src/main/java/com/dcrandroid/activities/privacy/AccountMixerActivity.kt b/app/src/main/java/com/dcrandroid/activities/privacy/AccountMixerActivity.kt index 30860011..d2669c32 100644 --- a/app/src/main/java/com/dcrandroid/activities/privacy/AccountMixerActivity.kt +++ b/app/src/main/java/com/dcrandroid/activities/privacy/AccountMixerActivity.kt @@ -108,17 +108,19 @@ class AccountMixerActivity : BaseActivity(), AccountMixerNotificationListener, T tv_mixer_status.setText(R.string.ready_to_mix) tv_mixer_status.setTextColor(resources.getColor(R.color.blueGraySecondTextColor)) iv_mixer_status.hide() + mixer_toggle_switch.isEnabled = true } else { tv_mixer_status.setText(R.string.no_mixable_output) tv_mixer_status.setTextColor(resources.getColor(R.color.colorError)) iv_mixer_status.hide() + mixer_toggle_switch.isEnabled = false } mixing_arrow.hide() } - unmixed_balance.text = CoinFormat.formatAlpha(wallet.getAccountBalance(unmixedAccountNumber).total) - mixed_balance.text = CoinFormat.formatAlpha(wallet.getAccountBalance(mixedAccountNumber).total) + unmixed_balance.text = CoinFormat.formatAlpha(wallet.getAccountBalance(unmixedAccountNumber).spendable) + mixed_balance.text = CoinFormat.formatAlpha(wallet.getAccountBalance(mixedAccountNumber).spendable) } private fun showWarningAndStartMixer() { diff --git a/app/src/main/java/com/dcrandroid/adapter/TransactionListAdapter.kt b/app/src/main/java/com/dcrandroid/adapter/TransactionListAdapter.kt index 18771b2c..09cedc7f 100644 --- a/app/src/main/java/com/dcrandroid/adapter/TransactionListAdapter.kt +++ b/app/src/main/java/com/dcrandroid/adapter/TransactionListAdapter.kt @@ -8,6 +8,7 @@ package com.dcrandroid.adapter import android.content.Context import android.graphics.Color +import android.text.SpannableStringBuilder import android.text.format.DateUtils import android.util.TypedValue import android.view.LayoutInflater @@ -30,7 +31,6 @@ import kotlinx.android.synthetic.main.transaction_row.view.* import java.text.SimpleDateFormat import java.util.* -// TODO: A joint class is needed for transactions and overview pages to avoid redundancy. class TransactionListAdapter(val context: Context, val transactions: ArrayList) : RecyclerView.Adapter() { private val layoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater @@ -125,9 +125,6 @@ fun populateTxRow(transaction: Transaction, layoutRow: View, layoutInflater: Lay } if (transaction.type == Dcrlibwallet.TxTypeRegular) { - if (transaction.isMixed) { - layoutRow.amount.text = context.getString(R.string.mix) - } else { val txAmount = if (transaction.direction == Dcrlibwallet.TxDirectionSent) { -transaction.amount } else { @@ -139,10 +136,27 @@ fun populateTxRow(transaction: Transaction, layoutRow: View, layoutInflater: Lay text = CoinFormat.format(strAmount + Constants.NBSP + layoutInflater.context.getString(R.string.dcr), 0.7f) setTextSize(TypedValue.COMPLEX_UNIT_PX, context.resources.getDimension(R.dimen.edit_text_size_20)) } - } layoutRow.ticket_price.hide() + } else if (transaction.type == Dcrlibwallet.TxTypeMixed) { + + var mixedAmount = CoinFormat.format(transaction.mixDenomination) + mixedAmount = CoinFormat.applyColor(mixedAmount, context.resources.getColor(R.color.darkBlueTextColor)) + + val amountBuilder = SpannableStringBuilder(mixedAmount) + if (transaction.mixCount > 1) { + amountBuilder.append("\t x${transaction.mixCount}") + } + layoutRow.ticket_price.apply { + show() + text = amountBuilder + } + + layoutRow.amount.apply { + setTextSize(TypedValue.COMPLEX_UNIT_PX, context.resources.getDimension(R.dimen.edit_text_size_18)) + setText(R.string.mixed) + } } else if (Dcrlibwallet.txMatchesFilter(transaction.type, transaction.direction, Dcrlibwallet.TxFilterStaking)) { layoutRow.amount.setTextSize(TypedValue.COMPLEX_UNIT_PX, context.resources.getDimension(R.dimen.edit_text_size_18)) diff --git a/app/src/main/java/com/dcrandroid/data/Transaction.kt b/app/src/main/java/com/dcrandroid/data/Transaction.kt index e2bf2cf2..a7cf4357 100644 --- a/app/src/main/java/com/dcrandroid/data/Transaction.kt +++ b/app/src/main/java/com/dcrandroid/data/Transaction.kt @@ -44,9 +44,6 @@ class Transaction : Serializable { @SerializedName("timestamp") var timestamp: Long = 0 - @SerializedName("is_mixed") - var isMixed: Boolean = false - @SerializedName("mix_denom") var mixDenomination: Long = 0 @@ -111,6 +108,8 @@ class Transaction : Serializable { else -> R.drawable.ic_ticket_revoked } + }else if (type == Dcrlibwallet.TxTypeMixed){ + res = R.drawable.ic_mixed } return res diff --git a/app/src/main/java/com/dcrandroid/dialog/send/SendDialog.kt b/app/src/main/java/com/dcrandroid/dialog/send/SendDialog.kt index 31572324..36168fde 100644 --- a/app/src/main/java/com/dcrandroid/dialog/send/SendDialog.kt +++ b/app/src/main/java/com/dcrandroid/dialog/send/SendDialog.kt @@ -390,7 +390,7 @@ class SendDialog(val fragmentActivity: FragmentActivity, dismissListener: Dialog val feeAndSize: TxFeeAndSize try { - txAuthor = multiWallet.newUnsignedTx(sourceAccountSpinner.wallet, selectedAccount.accountNumber) + txAuthor = multiWallet.newUnsignedTx(sourceAccountSpinner.wallet.id, selectedAccount.accountNumber) txAuthor.addSendDestination(destinationAddressCard.estimationAddress, amountAtom, sendMax) feeAndSize = txAuthor.estimateFeeAndSize() } catch (e: Exception) { diff --git a/app/src/main/java/com/dcrandroid/dialog/txdetails/TransactionDetailsDialog.kt b/app/src/main/java/com/dcrandroid/dialog/txdetails/TransactionDetailsDialog.kt index 4cf9d757..950a477e 100644 --- a/app/src/main/java/com/dcrandroid/dialog/txdetails/TransactionDetailsDialog.kt +++ b/app/src/main/java/com/dcrandroid/dialog/txdetails/TransactionDetailsDialog.kt @@ -9,6 +9,9 @@ package com.dcrandroid.dialog.txdetails import android.content.Intent import android.net.Uri import android.os.Bundle +import android.text.Spannable +import android.text.SpannableString +import android.text.SpannableStringBuilder import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -28,6 +31,7 @@ import com.dcrandroid.util.SnackBar import com.dcrandroid.util.Utils import dcrlibwallet.Dcrlibwallet import kotlinx.android.synthetic.main.transaction_details.* +import kotlinx.android.synthetic.main.transaction_row.view.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch @@ -49,8 +53,17 @@ class TransactionDetailsDialog(val transaction: Transaction) : FullScreenBottomS tx_details_icon.setImageResource(transaction.iconResource) - if (transaction.isMixed) { - tx_details_amount.text = CoinFormat.format(transaction.mixDenomination, 0.625f) + if (transaction.type == Dcrlibwallet.TxTypeMixed) { + val amountDcrFormat = CoinFormat.format(transaction.mixDenomination) + + val amountBuilder = SpannableStringBuilder(amountDcrFormat) + if (transaction.mixCount > 1) { + var mixCount = SpannableString("\t x${transaction.mixCount}") as Spannable + mixCount = CoinFormat.applyColor(mixCount, context!!.resources.getColor(R.color.lightGrayTextColor)) + amountBuilder.append(mixCount) + } + + tx_details_amount.text = amountBuilder } else { val txAmount = if (transaction.direction == Dcrlibwallet.TxDirectionSent && transaction.type == Dcrlibwallet.TxTypeRegular) { -transaction.amount @@ -94,11 +107,7 @@ class TransactionDetailsDialog(val transaction: Transaction) : FullScreenBottomS tx_details_dest.setOnClickListener(this@TransactionDetailsDialog) } - if (transaction.isMixed) { - toolbar_title.setText(R.string.mix) - } else { - toolbar_title.setText(R.string.sent) - } + toolbar_title.setText(R.string.sent) } Dcrlibwallet.TxDirectionReceived -> { tx_source_row.show() @@ -122,6 +131,7 @@ class TransactionDetailsDialog(val transaction: Transaction) : FullScreenBottomS Dcrlibwallet.TxTypeTicketPurchase -> R.string.ticket_purchase Dcrlibwallet.TxTypeVote -> R.string.vote Dcrlibwallet.TxTypeRevocation -> R.string.revoked + Dcrlibwallet.TxTypeMixed -> R.string.mixed else -> R.string.tx_sort_coinbase } diff --git a/app/src/main/java/com/dcrandroid/fragments/TransactionsFragment.kt b/app/src/main/java/com/dcrandroid/fragments/TransactionsFragment.kt index 2fc938a6..c1721a48 100644 --- a/app/src/main/java/com/dcrandroid/fragments/TransactionsFragment.kt +++ b/app/src/main/java/com/dcrandroid/fragments/TransactionsFragment.kt @@ -123,10 +123,12 @@ class TransactionsFragment : BaseFragment(), AdapterView.OnItemSelectedListener, private fun refreshAvailableTxType() = GlobalScope.launch(Dispatchers.Default) { availableTxTypes.clear() + // TODO val txCount = wallet!!.countTransactions(Dcrlibwallet.TxFilterAll) val sentTxCount = wallet!!.countTransactions(Dcrlibwallet.TxFilterSent) val receivedTxCount = wallet!!.countTransactions(Dcrlibwallet.TxFilterReceived) val transferredTxCount = wallet!!.countTransactions(Dcrlibwallet.TxFilterTransferred) + val mixedTxCount = wallet!!.countTransactions(Dcrlibwallet.TxFilterMixed) val stakingTxCount = wallet!!.countTransactions(Dcrlibwallet.TxFilterStaking) val coinbaseTxCount = wallet!!.countTransactions(Dcrlibwallet.TxFilterCoinBase) @@ -139,6 +141,7 @@ class TransactionsFragment : BaseFragment(), AdapterView.OnItemSelectedListener, availableTxTypes.add(context!!.getString(R.string.tx_sort_sent, sentTxCount)) availableTxTypes.add(context!!.getString(R.string.tx_sort_received, receivedTxCount)) availableTxTypes.add(context!!.getString(R.string.tx_sort_transferred, transferredTxCount)) + availableTxTypes.add(context!!.getString(R.string.tx_sort_mixed, mixedTxCount)) if (stakingTxCount > 0) { availableTxTypes.add(context!!.getString(R.string.tx_sort_staking, stakingTxCount)) @@ -300,6 +303,7 @@ class TransactionsFragment : BaseFragment(), AdapterView.OnItemSelectedListener, 1 -> Dcrlibwallet.TxFilterSent 2 -> Dcrlibwallet.TxFilterReceived 3 -> Dcrlibwallet.TxFilterTransferred + 4 -> Dcrlibwallet.TxFilterMixed else -> Dcrlibwallet.TxFilterStaking } diff --git a/app/src/main/java/com/dcrandroid/util/CoinFormat.kt b/app/src/main/java/com/dcrandroid/util/CoinFormat.kt index 3621e0e1..89a2964d 100644 --- a/app/src/main/java/com/dcrandroid/util/CoinFormat.kt +++ b/app/src/main/java/com/dcrandroid/util/CoinFormat.kt @@ -12,6 +12,7 @@ import android.text.SpannableString import android.text.style.CharacterStyle import android.text.style.ForegroundColorSpan import android.text.style.RelativeSizeSpan +import androidx.annotation.ColorInt import dcrlibwallet.Dcrlibwallet import java.text.DecimalFormat import java.text.NumberFormat @@ -34,6 +35,13 @@ object CoinFormat { return formatSpannable(spannable, span) } + fun applyColor(spannable: Spannable, @ColorInt color: Int): Spannable { + val span = ForegroundColorSpan(color) + + spannable.setSpan(span, 0, spannable.length, Spannable.SPAN_INCLUSIVE_EXCLUSIVE) + return spannable + } + fun formatAlpha(dcr: Long): Spannable { val str = formatDecred(Dcrlibwallet.amountCoin(dcr)) + " DCR" val spannable = SpannableString(str) @@ -76,7 +84,7 @@ object CoinFormat { return spannable } - spannable.setSpan(span, startIndex, spannable.length, Spannable.SPAN_INCLUSIVE_INCLUSIVE) + spannable.setSpan(span, startIndex, spannable.length, Spannable.SPAN_INCLUSIVE_EXCLUSIVE) return spannable } diff --git a/app/src/main/res/drawable/ic_mixed.xml b/app/src/main/res/drawable/ic_mixed.xml new file mode 100644 index 00000000..7497cae6 --- /dev/null +++ b/app/src/main/res/drawable/ic_mixed.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index 4ddab6c7..1ef3b4d3 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -644,7 +644,6 @@ 新的提案 投票已开始 投票已结束 - http://proposals.decred.org/proposals/ 分享提案链接 text/plain %d 评论 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8ad64ffc..ba30750f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -79,6 +79,11 @@ Remove watch-only wallet from device? Make sure to have the seed phrase backed up before removing the wallet. Error copied + + + %1$s DCR + %1$s DCR\t x%2$d + @@ -403,6 +408,7 @@ Sent (%1$d) Received (%1$d) Transferred (%1$d) + Mixed (%1$d) Staking (%1$d) Coinbase (%1$d) Ticket Purchase @@ -566,6 +572,7 @@ Unmixed account Mixer Mix + Mixed Mix transaction change Change from transactions will be sent to unmixed account if enabled. %1$s.]]> @@ -644,7 +651,6 @@ New Proposal Vote Started Vote Ended - http://proposals.decred.org/proposals/ Share Proposal Link text/plain %d comments