package com.wallet.crypto.ui; import android.arch.lifecycle.ViewModelProviders; import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.content.ContextCompat; import android.support.v7.app.AlertDialog; import android.view.Menu; import android.view.MenuItem; import android.widget.Button; import android.widget.ProgressBar; import android.widget.TextView; import com.wallet.crypto.R; import com.wallet.crypto.MercuryConstants; import com.wallet.crypto.entity.ErrorEnvelope; import com.wallet.crypto.entity.GasSettings; import com.wallet.crypto.entity.Wallet; import com.wallet.crypto.ui.dialog.InputPwdDialog; import com.wallet.crypto.ui.dialog.interfaces.IPositiveButtonDialogListener; import com.wallet.crypto.util.BalanceUtils; import com.wallet.crypto.viewmodel.ConfirmationViewModel; import com.wallet.crypto.viewmodel.ConfirmationViewModelFactory; import com.wallet.crypto.viewmodel.GasSettingsViewModel; import org.jetbrains.annotations.NotNull; import java.math.BigInteger; import javax.inject.Inject; import static com.wallet.crypto.ui.dialog.DialogManagerKt.showCusDialog; public class ConfirmationActivity extends BaseActivity implements IPositiveButtonDialogListener { AlertDialog dialog; @Inject ConfirmationViewModelFactory confirmationViewModelFactory; ConfirmationViewModel viewModel; private TextView fromAddressText; private TextView toAddressText; private TextView valueText; private TextView gasPriceText; private TextView gasLimitText; private TextView networkFeeText; private Button sendButton; private BigInteger amount; private int decimals; private String contractAddress; private boolean confirmationForTokenTransfer = false; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { // AndroidInjection.inject(this); super.onCreate(savedInstanceState); setContentView(R.layout.activity_confirm); toolbar(); fromAddressText = findViewById(R.id.text_from); toAddressText = findViewById(R.id.text_to); valueText = findViewById(R.id.text_value); gasPriceText = findViewById(R.id.text_gas_price); gasLimitText = findViewById(R.id.text_gas_limit); networkFeeText = findViewById(R.id.text_network_fee); sendButton = findViewById(R.id.send_button); sendButton.setOnClickListener(view -> onSend()); String toAddress = getIntent().getStringExtra(MercuryConstants.EXTRA_TO_ADDRESS); contractAddress = getIntent().getStringExtra(MercuryConstants.EXTRA_CONTRACT_ADDRESS); amount = new BigInteger(getIntent().getStringExtra(MercuryConstants.EXTRA_AMOUNT)); decimals = getIntent().getIntExtra(MercuryConstants.EXTRA_DECIMALS, -1); String symbol = getIntent().getStringExtra(MercuryConstants.EXTRA_SYMBOL); symbol = symbol == null ? MercuryConstants.ETH_SYMBOL : symbol; confirmationForTokenTransfer = contractAddress != null; toAddressText.setText(toAddress); String amountString = "-" + BalanceUtils.subunitToBase(amount, decimals).toPlainString() + " " + symbol; valueText.setText(amountString); valueText.setTextColor(ContextCompat.getColor(this, R.color.red)); viewModel = ViewModelProviders.of(this, confirmationViewModelFactory) .get(ConfirmationViewModel.class); viewModel.defaultWallet().observe(this, this::onDefaultWallet); viewModel.gasSettings().observe(this, this::onGasSettings); viewModel.sendTransaction().observe(this, this::onTransaction); viewModel.progress().observe(this, this::onProgress); viewModel.error().observe(this, this::onError); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.confirmation_menu, menu); return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.action_edit: { viewModel.openGasSettings(ConfirmationActivity.this); } break; } return super.onOptionsItemSelected(item); } @Override protected void onResume() { super.onResume(); viewModel.prepare(confirmationForTokenTransfer); } private void onProgress(boolean shouldShowProgress) { hideDialog(); if (shouldShowProgress) { dialog = new AlertDialog.Builder(this) .setTitle(R.string.title_dialog_sending) .setView(new ProgressBar(this)) .setCancelable(false) .create(); dialog.show(); } } private void hideDialog() { if (dialog != null && dialog.isShowing()) { dialog.dismiss(); } } private void onSend() { // 输入密码对话框 showCusDialog(this, new InputPwdDialog()); hideDialog(); } private void transfer() { GasSettings gasSettings = viewModel.gasSettings().getValue(); if (!confirmationForTokenTransfer) { viewModel.createTransaction( fromAddressText.getText().toString(), toAddressText.getText().toString(), amount, gasSettings.gasPrice, gasSettings.gasLimit); } else { viewModel.createTokenTransfer( fromAddressText.getText().toString(), toAddressText.getText().toString(), contractAddress, amount, gasSettings.gasPrice, gasSettings.gasLimit); } } private void onDefaultWallet(Wallet wallet) { fromAddressText.setText(wallet.getAddress()); } private void onTransaction(String hash) { hideDialog(); dialog = new AlertDialog.Builder(this) .setTitle(R.string.transaction_succeeded) .setMessage(hash) .setPositiveButton(R.string.button_ok, (dialog1, id) -> { finish(); }) .setNeutralButton(R.string.copy, (dialog1, id) -> { ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); ClipData clip = ClipData.newPlainText("transaction hash", hash); clipboard.setPrimaryClip(clip); finish(); }) .create(); dialog.show(); } private void onGasSettings(GasSettings gasSettings) { String gasPrice = BalanceUtils.weiToGwei(gasSettings.gasPrice) + " " + MercuryConstants.GWEI_UNIT; gasPriceText.setText(gasPrice); gasLimitText.setText(gasSettings.gasLimit.toString()); String networkFee = BalanceUtils.weiToEth(gasSettings .gasPrice.multiply(gasSettings.gasLimit)).toPlainString() + " " + MercuryConstants.ETH_SYMBOL; networkFeeText.setText(networkFee); } private void onError(ErrorEnvelope error) { hideDialog(); AlertDialog dialog = new AlertDialog.Builder(this) .setTitle(R.string.error_transaction_failed) .setMessage(error.message) .setPositiveButton(R.string.button_ok, (dialog1, id) -> { // Do nothing }) .create(); dialog.show(); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { if (requestCode == GasSettingsViewModel.SET_GAS_SETTINGS) { if (resultCode == RESULT_OK) { BigInteger gasPrice = new BigInteger(intent.getStringExtra(MercuryConstants.EXTRA_GAS_PRICE)); BigInteger gasLimit = new BigInteger(intent.getStringExtra(MercuryConstants.EXTRA_GAS_LIMIT)); GasSettings settings = new GasSettings(gasPrice, gasLimit); viewModel.gasSettings().postValue(settings); } } } @Override public void onPositiveButtonClicked(int requestCode, @NotNull Object any) { viewModel.getPassword().setValue((String) any); transfer(); } }