use of org.bitcoinj.utils.MonetaryFormat in project bitcoin-wallet by bitcoin-wallet.
the class BootstrapReceiver method maybeShowInactivityNotification.
@WorkerThread
private void maybeShowInactivityNotification(final WalletApplication application) {
final Configuration config = application.getConfiguration();
if (!config.remindBalance() || !config.hasBeenUsed() || config.getLastUsedAgo() <= Constants.LAST_USAGE_THRESHOLD_INACTIVE_MS)
return;
final Wallet wallet = application.getWallet();
final Coin estimatedBalance = wallet.getBalance(Wallet.BalanceType.ESTIMATED_SPENDABLE);
if (!estimatedBalance.isPositive())
return;
log.info("detected balance, showing inactivity notification");
final Coin availableBalance = wallet.getBalance(Wallet.BalanceType.AVAILABLE_SPENDABLE);
final boolean canDonate = Constants.DONATION_ADDRESS != null && !availableBalance.isLessThan(Constants.SOME_BALANCE_THRESHOLD);
final MonetaryFormat btcFormat = config.getFormat();
final String title = application.getString(R.string.notification_inactivity_title);
final StringBuilder text = new StringBuilder(application.getString(R.string.notification_inactivity_message, btcFormat.format(estimatedBalance)));
if (canDonate)
text.append("\n\n").append(application.getString(R.string.notification_inactivity_message_donate));
final NotificationCompat.Builder notification = new NotificationCompat.Builder(application, Constants.NOTIFICATION_CHANNEL_ID_IMPORTANT);
notification.setStyle(new NotificationCompat.BigTextStyle().bigText(text));
notification.setColor(application.getColor(R.color.fg_network_significant));
notification.setSmallIcon(R.drawable.stat_notify_received_24dp);
notification.setContentTitle(title);
notification.setContentText(text);
notification.setContentIntent(PendingIntent.getActivity(application, 0, new Intent(application, WalletActivity.class), 0));
notification.setAutoCancel(true);
if (!canDonate) {
final Intent dismissIntent = new Intent(application, BootstrapReceiver.class);
dismissIntent.setAction(ACTION_DISMISS);
notification.addAction(new NotificationCompat.Action.Builder(0, application.getString(R.string.notification_inactivity_action_dismiss), PendingIntent.getBroadcast(application, 0, dismissIntent, 0)).build());
}
final Intent dismissForeverIntent = new Intent(application, BootstrapReceiver.class);
dismissForeverIntent.setAction(ACTION_DISMISS_FOREVER);
notification.addAction(new NotificationCompat.Action.Builder(0, application.getString(R.string.notification_inactivity_action_dismiss_forever), PendingIntent.getBroadcast(application, 0, dismissForeverIntent, 0)).build());
if (canDonate) {
final Intent donateIntent = new Intent(application, BootstrapReceiver.class);
donateIntent.setAction(ACTION_DONATE);
notification.addAction(new NotificationCompat.Action.Builder(0, application.getString(R.string.wallet_options_donate), PendingIntent.getBroadcast(application, 0, donateIntent, 0)).build());
}
final NotificationManager nm = (NotificationManager) application.getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(Constants.NOTIFICATION_ID_INACTIVITY, notification.build());
}
use of org.bitcoinj.utils.MonetaryFormat in project bitcoin-wallet by bitcoin-wallet.
the class TransactionsAdapter method buildListItems.
public static List<ListItem> buildListItems(final Context context, final List<Transaction> transactions, final WarningType warning, @Nullable final Wallet wallet, @Nullable final Map<String, AddressBookEntry> addressBook, final MonetaryFormat format, final int maxConnectedPeers) {
final MonetaryFormat noCodeFormat = format.noCode();
final List<ListItem> items = new ArrayList<>(transactions.size() + 1);
if (warning != null)
items.add(new ListItem.WarningItem(warning));
for (final Transaction tx : transactions) items.add(new ListItem.TransactionItem(context, tx, wallet, addressBook, noCodeFormat, maxConnectedPeers));
return items;
}
use of org.bitcoinj.utils.MonetaryFormat in project bitcoin-wallet by bitcoin-wallet.
the class MaintenanceDialogFragment method onCreateDialog.
@Override
public Dialog onCreateDialog(final Bundle savedInstanceState) {
final View view = LayoutInflater.from(activity).inflate(R.layout.maintenance_dialog, null);
Coin value = Coin.ZERO;
Coin fee = Coin.ZERO;
for (final Transaction tx : determineMaintenanceTransactions()) {
value = value.add(tx.getValueSentFromMe(wallet));
fee = fee.add(tx.getFee());
}
final TextView messageView = view.findViewById(R.id.maintenance_dialog_message);
final MonetaryFormat format = application.getConfiguration().getFormat();
messageView.setText(getString(R.string.maintenance_dialog_message, format.format(value), format.format(fee)));
passwordGroup = view.findViewById(R.id.maintenance_dialog_password_group);
passwordView = view.findViewById(R.id.maintenance_dialog_password);
passwordView.setText(null);
badPasswordView = view.findViewById(R.id.maintenance_dialog_bad_password);
final DialogBuilder builder = DialogBuilder.custom(activity, R.string.maintenance_dialog_title, view);
// dummies, just to make buttons show
builder.setPositiveButton(R.string.maintenance_dialog_button_move, null);
builder.setNegativeButton(R.string.button_dismiss, null);
builder.setCancelable(false);
final AlertDialog dialog = builder.create();
dialog.setCanceledOnTouchOutside(false);
dialog.setOnShowListener(d -> {
positiveButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
negativeButton = dialog.getButton(DialogInterface.BUTTON_NEGATIVE);
positiveButton.setTypeface(Typeface.DEFAULT_BOLD);
positiveButton.setOnClickListener(v -> {
log.info("user decided to do maintenance");
handleGo();
});
negativeButton.setOnClickListener(v -> {
log.info("user decided to dismiss");
dismissAllowingStateLoss();
});
passwordView.addTextChangedListener(textWatcher);
MaintenanceDialogFragment.this.dialog = dialog;
updateView();
});
log.info("showing maintenance dialog");
return dialog;
}
use of org.bitcoinj.utils.MonetaryFormat in project bitcoin-wallet by bitcoin-wallet.
the class WalletTransactionsViewModel method maybePostList.
private void maybePostList() {
AsyncTask.execute(() -> {
org.bitcoinj.core.Context.propagate(Constants.CONTEXT);
final Set<Transaction> transactions = WalletTransactionsViewModel.this.transactions.getValue();
final MonetaryFormat format = configFormat.getValue();
final Map<String, AddressBookEntry> addressBook = AddressBookEntry.asMap(WalletTransactionsViewModel.this.addressBook.getValue());
if (transactions != null && format != null && addressBook != null) {
final List<Transaction> filteredTransactions = new ArrayList<>(transactions.size());
final Wallet wallet = application.getWallet();
final Direction direction = WalletTransactionsViewModel.this.direction.getValue();
for (final Transaction tx : transactions) {
final boolean sent = tx.getValue(wallet).signum() < 0;
final boolean isInternal = tx.getPurpose() == Purpose.KEY_ROTATION;
if ((direction == Direction.RECEIVED && !sent && !isInternal) || direction == null || (direction == Direction.SENT && sent && !isInternal))
filteredTransactions.add(tx);
}
Collections.sort(filteredTransactions, TRANSACTION_COMPARATOR);
list.postValue(TransactionsAdapter.buildListItems(application, filteredTransactions, warning.getValue(), wallet, addressBook, format, application.maxConnectedPeers()));
}
});
}
use of org.bitcoinj.utils.MonetaryFormat in project bitcoin-wallet by bitcoin-wallet.
the class SendCoinsFragment method sendPayment.
private void sendPayment(final SendRequest sendRequest, final Coin finalAmount) {
final Wallet wallet = walletActivityViewModel.wallet.getValue();
new SendCoinsOfflineTask(wallet, backgroundHandler) {
@Override
protected void onSuccess(final Transaction transaction) {
viewModel.sentTransaction.setValue(transaction);
setState(SendCoinsViewModel.State.SENDING);
final Address refundAddress = viewModel.paymentIntent.standard == Standard.BIP70 ? wallet.freshAddress(KeyPurpose.REFUND) : null;
final Payment payment = PaymentProtocol.createPaymentMessage(Collections.singletonList(transaction), finalAmount, refundAddress, null, viewModel.paymentIntent.payeeData);
if (directPaymentEnableView.isChecked())
directPay(payment);
final ListenableFuture<Transaction> future = walletActivityViewModel.broadcastTransaction(transaction);
future.addListener(() -> {
// Auto-close the dialog after a short delay
if (config.getSendCoinsAutoclose())
handler.postDelayed(() -> activity.finish(), Constants.AUTOCLOSE_DELAY_MS);
}, Threading.THREAD_POOL);
final ComponentName callingActivity = activity.getCallingActivity();
if (callingActivity != null) {
log.info("returning result to calling activity: {}", callingActivity.flattenToString());
final Intent result = new Intent();
BitcoinIntegration.transactionHashToResult(result, transaction.getTxId().toString());
if (viewModel.paymentIntent.standard == Standard.BIP70)
BitcoinIntegration.paymentToResult(result, payment.toByteArray());
activity.setResult(Activity.RESULT_OK, result);
}
}
private void directPay(final Payment payment) {
final DirectPaymentTask.ResultCallback callback = new DirectPaymentTask.ResultCallback() {
@Override
public void onResult(final boolean ack) {
viewModel.directPaymentAck = ack;
if (viewModel.state == SendCoinsViewModel.State.SENDING)
setState(SendCoinsViewModel.State.SENT);
updateView();
}
@Override
public void onFail(final int messageResId, final Object... messageArgs) {
final DialogBuilder dialog = DialogBuilder.warn(activity, R.string.send_coins_fragment_direct_payment_failed_title, viewModel.paymentIntent.paymentUrl + "\n" + getString(messageResId, messageArgs) + "\n\n" + getString(R.string.send_coins_fragment_direct_payment_failed_msg));
dialog.setPositiveButton(R.string.button_retry, (d, which) -> directPay(payment));
dialog.setNegativeButton(R.string.button_dismiss, null);
dialog.show();
}
};
if (viewModel.paymentIntent.isHttpPaymentUrl()) {
new DirectPaymentTask.HttpPaymentTask(backgroundHandler, callback, viewModel.paymentIntent.paymentUrl, application.httpUserAgent()).send(payment);
} else if (viewModel.paymentIntent.isBluetoothPaymentUrl() && bluetoothAdapter != null && bluetoothAdapter.isEnabled()) {
new DirectPaymentTask.BluetoothPaymentTask(backgroundHandler, callback, bluetoothAdapter, Bluetooth.getBluetoothMac(viewModel.paymentIntent.paymentUrl)).send(payment);
}
}
@Override
protected void onInsufficientMoney(final Coin missing) {
setState(SendCoinsViewModel.State.INPUT);
final Coin estimated = wallet.getBalance(BalanceType.ESTIMATED);
final Coin available = wallet.getBalance(BalanceType.AVAILABLE);
final Coin pending = estimated.subtract(available);
final MonetaryFormat btcFormat = config.getFormat();
final StringBuilder msg = new StringBuilder();
msg.append(getString(R.string.send_coins_fragment_insufficient_money_msg1, btcFormat.format(missing)));
if (pending.signum() > 0)
msg.append("\n\n").append(getString(R.string.send_coins_fragment_pending, btcFormat.format(pending)));
if (viewModel.paymentIntent.mayEditAmount())
msg.append("\n\n").append(getString(R.string.send_coins_fragment_insufficient_money_msg2));
final DialogBuilder dialog = DialogBuilder.warn(activity, R.string.send_coins_fragment_insufficient_money_title, msg);
if (viewModel.paymentIntent.mayEditAmount()) {
dialog.setPositiveButton(R.string.send_coins_options_empty, (d, which) -> handleEmpty());
dialog.setNegativeButton(R.string.button_cancel, null);
} else {
dialog.setNeutralButton(R.string.button_dismiss, null);
}
dialog.show();
}
@Override
protected void onInvalidEncryptionKey() {
setState(SendCoinsViewModel.State.INPUT);
privateKeyBadPasswordView.setVisibility(View.VISIBLE);
privateKeyPasswordView.requestFocus();
}
@Override
protected void onEmptyWalletFailed() {
setState(SendCoinsViewModel.State.INPUT);
final DialogBuilder dialog = DialogBuilder.warn(activity, R.string.send_coins_fragment_empty_wallet_failed_title, R.string.send_coins_fragment_hint_empty_wallet_failed);
dialog.setNeutralButton(R.string.button_dismiss, null);
dialog.show();
}
@Override
protected void onFailure(Exception exception) {
setState(SendCoinsViewModel.State.FAILED);
final DialogBuilder dialog = DialogBuilder.warn(activity, R.string.send_coins_error_msg, exception.toString());
dialog.setNeutralButton(R.string.button_dismiss, null);
dialog.show();
}
}.sendCoinsOffline(// send asynchronously
sendRequest);
}
Aggregations