on 11/16/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
public class CertificateChainNotFound extends GeneralSecurityException {
public static final String TAG = CertificateChainNotFound.class.getName();
diff --git a/app/src/main/java/com/breadwallet/exceptions/PaymentRequestExpiredException.java b/app/src/main/java/com/breadwallet/exceptions/PaymentRequestExpiredException.java
index db879306b..4306d72d0 100644
--- a/app/src/main/java/com/breadwallet/exceptions/PaymentRequestExpiredException.java
+++ b/app/src/main/java/com/breadwallet/exceptions/PaymentRequestExpiredException.java
@@ -2,31 +2,6 @@
import java.security.GeneralSecurityException;
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 11/16/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
public class PaymentRequestExpiredException extends GeneralSecurityException {
public static final String TAG = PaymentRequestExpiredException.class.getName();
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/AnnounceUpdatesViewActivity.kt b/app/src/main/java/com/breadwallet/presenter/activities/AnnounceUpdatesViewActivity.kt
new file mode 100644
index 000000000..460582971
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/activities/AnnounceUpdatesViewActivity.kt
@@ -0,0 +1,29 @@
+package com.breadwallet.presenter.activities
+
+import android.os.Bundle
+import android.webkit.WebView
+import android.widget.Button
+import androidx.appcompat.app.AppCompatActivity
+import com.breadwallet.R
+import com.breadwallet.databinding.ActivityAnnounceUpdatesViewBinding
+
+class AnnounceUpdatesViewActivity : AppCompatActivity() {
+ private lateinit var binding: ActivityAnnounceUpdatesViewBinding
+ private var url: String = "https://litewallet.io/mobile-signup/signup.html"
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ binding = ActivityAnnounceUpdatesViewBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ val webView: WebView = findViewById(R.id.webViewEmail)
+ webView.settings.javaScriptEnabled = true
+ webView.loadUrl(url)
+
+ val buttonNoThanks: Button = findViewById(R.id.btnNoThanks)
+ buttonNoThanks.setOnClickListener {
+ finish()
+ }
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/BreadActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/BreadActivity.java
new file mode 100644
index 000000000..fafa3438b
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/activities/BreadActivity.java
@@ -0,0 +1,458 @@
+package com.breadwallet.presenter.activities;
+
+import android.animation.LayoutTransition;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.graphics.Point;
+import android.net.ConnectivityManager;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.telephony.TelephonyManager;
+import android.view.ViewTreeObserver;
+import android.view.animation.AnimationUtils;
+import android.widget.Button;
+import android.widget.ImageButton;
+import android.widget.TextView;
+import android.widget.ViewFlipper;
+
+import androidx.annotation.NonNull;
+import androidx.constraintlayout.widget.ConstraintLayout;
+import androidx.constraintlayout.widget.ConstraintSet;
+import androidx.transition.ChangeBounds;
+import androidx.transition.Fade;
+import androidx.transition.TransitionManager;
+import androidx.transition.TransitionSet;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.intro.IntroActivity;
+import com.breadwallet.presenter.activities.util.BRActivity;
+import com.breadwallet.presenter.customviews.BRNotificationBar;
+import com.breadwallet.presenter.fragments.BuyTabFragment;
+import com.breadwallet.presenter.history.HistoryFragment;
+import com.breadwallet.tools.animation.BRAnimator;
+import com.breadwallet.tools.animation.TextSizeTransition;
+import com.breadwallet.tools.manager.BRSharedPrefs;
+import com.breadwallet.tools.manager.InternetManager;
+import com.breadwallet.tools.manager.SyncManager;
+import com.breadwallet.tools.security.BitcoinUrlHandler;
+import com.breadwallet.tools.sqlite.TransactionDataSource;
+import com.breadwallet.tools.threads.BRExecutor;
+import com.breadwallet.tools.util.BRConstants;
+import com.breadwallet.tools.util.BRCurrency;
+import com.breadwallet.tools.util.BRExchange;
+import com.breadwallet.tools.util.ExtensionKt;
+import com.breadwallet.tools.util.Utils;
+import com.breadwallet.wallet.BRPeerManager;
+import com.breadwallet.wallet.BRWalletManager;
+import com.google.android.material.bottomnavigation.BottomNavigationView;
+import com.google.android.play.core.review.ReviewInfo;
+import com.google.android.play.core.review.ReviewManager;
+import com.google.android.play.core.review.ReviewManagerFactory;
+import com.google.android.play.core.tasks.Task;
+
+import java.math.BigDecimal;
+
+import timber.log.Timber;
+
+public class BreadActivity extends BRActivity implements BRWalletManager.OnBalanceChanged, BRSharedPrefs.OnIsoChangedListener,
+ TransactionDataSource.OnTxAddedListener, InternetManager.ConnectionReceiverListener {
+
+ public static final Point screenParametersPoint = new Point();
+ private static final float PRIMARY_TEXT_SIZE = 24f;
+ private static final float SECONDARY_TEXT_SIZE = 12.8f;
+ private int mSelectedBottomNavItem = -1;
+
+ private InternetManager mConnectionReceiver;
+ private Button primaryPrice;
+ private Button secondaryPrice;
+ private TextView equals;
+ private ImageButton menuBut;
+ private TextView balanceTxtV;
+
+ public static boolean appVisible = false;
+ public ViewFlipper barFlipper;
+ private ConstraintLayout toolBarConstraintLayout;
+ private boolean uiIsDone;
+
+ private static BreadActivity app;
+ private BottomNavigationView bottomNav;
+
+ private Handler mHandler = new Handler();
+
+ public static BreadActivity getApp() {
+ return app;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_bread);
+
+ app = this;
+ getWindowManager().getDefaultDisplay().getSize(screenParametersPoint);
+
+ initializeViews();
+ setPriceTags(BRSharedPrefs.getPreferredLTC(BreadActivity.this), false);
+ setListeners();
+ setUpBarFlipper();
+ checkTransactionDatabase();
+
+ primaryPrice.setTextSize(PRIMARY_TEXT_SIZE);
+ secondaryPrice.setTextSize(SECONDARY_TEXT_SIZE);
+
+ finishActivities(SetPinActivity.introSetPitActivity, IntroActivity.introActivity, ReEnterPinActivity.reEnterPinActivity);
+
+ if (!BRSharedPrefs.getGreetingsShown(BreadActivity.this)) {
+ mHandler.postDelayed(() -> {
+ BRAnimator.showGreetingsMessage(BreadActivity.this);
+ BRSharedPrefs.putGreetingsShown(BreadActivity.this, true);
+ }, 1000);
+ }
+
+ onConnectionChanged(InternetManager.getInstance().isConnected(this));
+
+ updateUI();
+ bottomNav.setSelectedItemId(R.id.nav_history);
+
+ showInAppReviewDialogIfNeeded();
+ }
+
+ private void finishActivities(BRActivity... activities) {
+ for (BRActivity activity : activities) {
+ if (activity != null) activity.finish();
+ }
+ }
+
+ private void showInAppReviewDialogIfNeeded() {
+ if (!BRSharedPrefs.isInAppReviewDone(this) && BRSharedPrefs.getSendTransactionCount(this) > 4) {
+ ReviewManager manager = ReviewManagerFactory.create(this);
+ Task request = manager.requestReviewFlow();
+ request.addOnCompleteListener(task -> {
+ if (task.isSuccessful()) {
+ ReviewInfo reviewInfo = task.getResult();
+ Task flow = manager.launchReviewFlow(BreadActivity.this, reviewInfo);
+ flow.addOnCompleteListener(task1 -> {
+ // The flow has finished. The API does not indicate whether the user
+ // reviewed or not, or even whether the review dialog was shown. Thus, no
+ // matter the result, we continue our app flow.
+ Timber.i("timber: In-app LaunchReviewFlow completed successful (%s)", task1.isSuccessful());
+ if (task1.isSuccessful()) {
+ BRSharedPrefs.inAppReviewDone(BreadActivity.this);
+ }
+ });
+ } else {
+ Timber.e(task.getException(), "In-app request review flow failed");
+ }
+ });
+ }
+ }
+
+ private void addObservers() {
+ BRWalletManager.getInstance().addBalanceChangedListener(this);
+ BRSharedPrefs.addIsoChangedListener(this);
+ }
+
+ private void removeObservers() {
+ BRWalletManager.getInstance().removeListener(this);
+ BRSharedPrefs.removeListener(this);
+ }
+
+ private void setUrlHandler(Intent intent) {
+ Uri data = intent.getData();
+ if (data == null) return;
+ String scheme = data.getScheme();
+ if (scheme != null && scheme.startsWith("litecoin")) {
+ String str = intent.getDataString();
+ BitcoinUrlHandler.processRequest(this, str);
+ }
+ }
+
+ @Override
+ protected void onNewIntent(Intent intent) {
+ super.onNewIntent(intent);
+ setUrlHandler(intent);
+ }
+
+ private void setListeners() {
+ bottomNav.setOnNavigationItemSelectedListener(item -> handleNavigationItemSelected(item.getItemId()));
+
+ primaryPrice.setOnClickListener(v -> swap());
+ secondaryPrice.setOnClickListener(v -> swap());
+ menuBut.setOnClickListener(v -> {
+ if (BRAnimator.isClickAllowed()) {
+ BRAnimator.showMenuFragment(BreadActivity.this);
+ }
+ });
+ }
+
+ public boolean handleNavigationItemSelected(int menuItemId) {
+ if (mSelectedBottomNavItem == menuItemId) return true;
+ mSelectedBottomNavItem = menuItemId;
+ if (menuItemId == R.id.nav_history) {
+ ExtensionKt.replaceFragment(BreadActivity.this, new HistoryFragment(), false, R.id.fragment_container);
+ } else if (menuItemId == R.id.nav_send) {
+ if (BRAnimator.isClickAllowed()) {
+ BRAnimator.showSendFragment(BreadActivity.this, null);
+ }
+ mSelectedBottomNavItem = 0;
+ } else if (menuItemId == R.id.nav_receive) {
+ if (BRAnimator.isClickAllowed()) {
+ BRAnimator.showReceiveFragment(BreadActivity.this, true);
+ }
+ mSelectedBottomNavItem = 0;
+ } else if (menuItemId == R.id.nav_buy) {
+ ExtensionKt.replaceFragment(BreadActivity.this, new BuyTabFragment(), false, R.id.fragment_container);
+ }
+ return true;
+ }
+
+ private void swap() {
+ if (!BRAnimator.isClickAllowed()) return;
+ boolean b = !BRSharedPrefs.getPreferredLTC(this);
+ setPriceTags(b, true);
+ BRSharedPrefs.putPreferredLTC(this, b);
+ BRSharedPrefs.notifyIsoChanged("");
+ }
+
+ private void setPriceTags(boolean ltcPreferred, boolean animate) {
+ ConstraintSet set = new ConstraintSet();
+ set.clone(toolBarConstraintLayout);
+
+ if (animate) {
+ TransitionSet textSizeTransition = new TransitionSet()
+ .setOrdering(TransitionSet.ORDERING_TOGETHER)
+ .addTransition(new TextSizeTransition())
+ .addTransition(new ChangeBounds());
+
+ TransitionSet transition = new TransitionSet()
+ .setOrdering(TransitionSet.ORDERING_SEQUENTIAL)
+ .addTransition(new Fade(Fade.OUT))
+ .addTransition(textSizeTransition)
+ .addTransition(new Fade(Fade.IN));
+ TransitionManager.beginDelayedTransition(toolBarConstraintLayout, transition);
+ }
+
+ primaryPrice.setTextSize(ltcPreferred ? PRIMARY_TEXT_SIZE : SECONDARY_TEXT_SIZE);
+ secondaryPrice.setTextSize(ltcPreferred ? SECONDARY_TEXT_SIZE : PRIMARY_TEXT_SIZE);
+
+ int[] ids = {primaryPrice.getId(), secondaryPrice.getId(), equals.getId()};
+ // Clear views constraints
+ for (int id : ids) {
+ set.clear(id);
+ set.constrainWidth(id, ConstraintSet.WRAP_CONTENT);
+ set.constrainHeight(id, ConstraintSet.WRAP_CONTENT);
+ }
+
+ int dp16 = Utils.getPixelsFromDps(this, 16);
+ int dp8 = Utils.getPixelsFromDps(this, 4);
+
+ int leftId = ltcPreferred ? primaryPrice.getId() : secondaryPrice.getId();
+ int rightId = ltcPreferred ? secondaryPrice.getId() : primaryPrice.getId();
+
+ int[] chainViews = {leftId, equals.getId(), rightId};
+
+ set.connect(leftId, ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START, dp16);
+ set.connect(leftId, ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP);
+ set.connect(leftId, ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM, dp16);
+ set.setVerticalBias(leftId, 1.0f);
+
+ set.connect(rightId, ConstraintSet.BASELINE, leftId, ConstraintSet.BASELINE);
+ set.connect(equals.getId(), ConstraintSet.BASELINE, leftId, ConstraintSet.BASELINE);
+
+ set.connect(equals.getId(), ConstraintSet.START, leftId, ConstraintSet.END, dp8);
+ set.connect(equals.getId(), ConstraintSet.END, rightId, ConstraintSet.START, dp8);
+
+ set.createHorizontalChain(leftId, ConstraintSet.LEFT, equals.getId(), ConstraintSet.RIGHT, chainViews, null, ConstraintSet.CHAIN_PACKED);
+
+ // Apply the changes
+ set.applyTo(toolBarConstraintLayout);
+
+ mHandler.postDelayed(() -> updateUI(), toolBarConstraintLayout.getLayoutTransition().getDuration(LayoutTransition.CHANGING));
+ }
+
+ private void checkTransactionDatabase() {
+
+ }
+
+ private void setUpBarFlipper() {
+ barFlipper.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.flipper_enter));
+ barFlipper.setOutAnimation(AnimationUtils.loadAnimation(this, R.anim.flipper_exit));
+ }
+
+ @Override
+ protected void onRestart() {
+ super.onRestart();
+ app = this;
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ appVisible = true;
+ app = this;
+ addObservers();
+
+ setupNetworking();
+
+ if (!BRWalletManager.getInstance().isCreated()) {
+ BRExecutor.getInstance().forBackgroundTasks().execute(() -> BRWalletManager.getInstance().initWallet(BreadActivity.this));
+ }
+ mHandler.postDelayed(() -> updateUI(), 1000);
+
+ BRWalletManager.getInstance().refreshBalance(this);
+ }
+
+ private void setupNetworking() {
+ if (mConnectionReceiver == null) mConnectionReceiver = InternetManager.getInstance();
+ IntentFilter mNetworkStateFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
+ registerReceiver(mConnectionReceiver, mNetworkStateFilter);
+ InternetManager.addConnectionListener(this);
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ appVisible = false;
+ removeObservers();
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ unregisterReceiver(mConnectionReceiver);
+ }
+
+ private void initializeViews() {
+ menuBut = findViewById(R.id.menuBut);
+ bottomNav = findViewById(R.id.bottomNav);
+ bottomNav.getMenu().clear();
+ bottomNav.inflateMenu(isInUsa() ? R.menu.bottom_nav_menu_us : R.menu.bottom_nav_menu);
+ balanceTxtV = findViewById(R.id.balanceTxtV);
+
+ primaryPrice = findViewById(R.id.primary_price);
+ secondaryPrice = findViewById(R.id.secondary_price);
+ equals = findViewById(R.id.equals);
+ toolBarConstraintLayout = findViewById(R.id.bread_toolbar);
+
+ barFlipper = findViewById(R.id.tool_bar_flipper);
+
+ final ViewTreeObserver observer = primaryPrice.getViewTreeObserver();
+ observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+ @Override
+ public void onGlobalLayout() {
+ if (observer.isAlive()) {
+ observer.removeOnGlobalLayoutListener(this);
+ }
+ if (uiIsDone) return;
+ uiIsDone = true;
+ setPriceTags(BRSharedPrefs.getPreferredLTC(BreadActivity.this), false);
+ }
+ });
+
+ balanceTxtV.append(":");
+ }
+
+ private boolean isInUsa() {
+ TelephonyManager telManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
+ return "us".equals(telManager.getSimCountryIso());
+ }
+
+ @Override
+ public void onBalanceChanged(final long balance) {
+ updateUI();
+ }
+
+ public void updateUI() {
+ BRExecutor.getInstance().forLightWeightBackgroundTasks().execute(() -> {
+ Thread.currentThread().setName(Thread.currentThread().getName() + ":updateUI");
+ //sleep a little in order to make sure all the commits are finished (like SharePreferences commits)
+ String iso = BRSharedPrefs.getIso(BreadActivity.this);
+
+ //current amount in litoshis
+ final BigDecimal amount = new BigDecimal(BRSharedPrefs.getCatchedBalance(BreadActivity.this));
+
+ //amount in LTC units
+ BigDecimal btcAmount = BRExchange.getBitcoinForSatoshis(BreadActivity.this, amount);
+ final String formattedBTCAmount = BRCurrency.getFormattedCurrencyString(BreadActivity.this, "LTC", btcAmount);
+
+ //amount in currency units
+ final BigDecimal curAmount = BRExchange.getAmountFromSatoshis(BreadActivity.this, iso, amount);
+ final String formattedCurAmount = BRCurrency.getFormattedCurrencyString(BreadActivity.this, iso, curAmount);
+ runOnUiThread(() -> {
+ primaryPrice.setText(formattedBTCAmount);
+ secondaryPrice.setText(String.format("%s", formattedCurAmount));
+ });
+ });
+ }
+
+ @Override
+ public void onIsoChanged(String iso) {
+ updateUI();
+ }
+
+ @Override
+ public void onTxAdded() {
+ BRWalletManager.getInstance().refreshBalance(BreadActivity.this);
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+
+ switch (requestCode) {
+ case BRConstants.CAMERA_REQUEST_ID: {
+ // If request is cancelled, the result arrays are empty.
+ if (grantResults.length > 0
+ && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ BRAnimator.openScanner(this, BRConstants.SCANNER_REQUEST);
+ // permission was granted, yay! Do the
+ // contacts-related task you need to do.
+ } else {
+ // permission denied, boo! Disable the
+ // functionality that depends on this permission.
+ }
+ return;
+ }
+ // other 'case' lines to check for other
+ // permissions this app might request
+ }
+ }
+
+ @Override
+ public void onConnectionChanged(boolean isConnected) {
+ if (isConnected) {
+ if (barFlipper != null) {
+ if (barFlipper.getDisplayedChild() == 1) {
+ removeNotificationBar();
+ }
+ }
+ BRExecutor.getInstance().forLightWeightBackgroundTasks().execute(() -> {
+ final double progress = BRPeerManager.syncProgress(BRSharedPrefs.getStartHeight(BreadActivity.this));
+ Timber.d("timber: Sync Progress: %s", progress);
+ if (progress < 1 && progress > 0) {
+ SyncManager.getInstance().startSyncingProgressThread();
+ }
+ });
+ } else {
+ if (barFlipper != null) {
+ addNotificationBar();
+ }
+ SyncManager.getInstance().stopSyncingProgressThread();
+ }
+ }
+
+ public void removeNotificationBar() {
+ if (barFlipper.getChildCount() == 1) return;
+ barFlipper.removeViewAt(1);
+ barFlipper.setDisplayedChild(0);
+ }
+
+ public void addNotificationBar() {
+ if (barFlipper.getChildCount() == 2) return;
+ BRNotificationBar view = new BRNotificationBar(this);
+ barFlipper.addView(view);
+ barFlipper.setDisplayedChild(1);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/DisabledActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/DisabledActivity.java
new file mode 100644
index 000000000..93cba38eb
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/activities/DisabledActivity.java
@@ -0,0 +1,135 @@
+package com.breadwallet.presenter.activities;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.CountDownTimer;
+import android.os.Handler;
+import androidx.constraintlayout.widget.ConstraintLayout;
+
+import android.view.View;
+import android.widget.Button;
+import android.widget.ImageButton;
+import android.widget.TextView;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.util.BRActivity;
+import com.breadwallet.tools.animation.BRAnimator;
+import com.breadwallet.tools.animation.SpringAnimator;
+import com.breadwallet.tools.security.AuthManager;
+import com.breadwallet.tools.util.BRConstants;
+
+import java.util.Locale;
+
+
+public class DisabledActivity extends BRActivity {
+ private static final String TAG = DisabledActivity.class.getName();
+ private TextView untilLabel;
+ private TextView disabled;
+ // private TextView attempts;
+ private ConstraintLayout layout;
+ private Button resetButton;
+ private CountDownTimer timer;
+
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_disabled);
+
+ untilLabel = (TextView) findViewById(R.id.until_label);
+ layout = (ConstraintLayout) findViewById(R.id.layout);
+ disabled = (TextView) findViewById(R.id.disabled);
+// attempts = (TextView) findViewById(R.id.attempts_label);
+ resetButton = (Button) findViewById(R.id.reset_button);
+
+ ImageButton faq = (ImageButton) findViewById(R.id.faq_button);
+ //TODO: all views are using the layout of this button. Views should be refactored without it
+ // Hiding until layouts are built.
+
+ resetButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent intent = new Intent(DisabledActivity.this, InputWordsActivity.class);
+ intent.putExtra("resetPin", true);
+ startActivity(intent);
+ overridePendingTransition(R.anim.enter_from_right, R.anim.exit_to_left);
+ }
+ });
+
+ layout.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ refresh();
+ }
+ });
+
+ untilLabel.setText("");
+
+ }
+
+ private void refresh() {
+ if (AuthManager.getInstance().isWalletDisabled(DisabledActivity.this)) {
+ SpringAnimator.failShakeAnimation(DisabledActivity.this, disabled);
+ } else {
+ BRAnimator.startBreadActivity(DisabledActivity.this, true);
+ }
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ finish();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ long disabledUntil = AuthManager.getInstance().disabledUntil(this);
+ long disabledTime = disabledUntil - System.currentTimeMillis();
+ int seconds = (int) disabledTime / 1000;
+ timer = new CountDownTimer(seconds * 1000, 1000) {
+ public void onTick(long millisUntilFinished) {
+ long durationSeconds = (millisUntilFinished / 1000);
+ untilLabel.setText(String.format(Locale.getDefault(), "%02d:%02d:%02d", durationSeconds / 3600,
+ (durationSeconds % 3600) / 60, (durationSeconds % 60)));
+ }
+
+ public void onFinish() {
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ refresh();
+ }
+ }, 2000);
+ long durationSeconds = 0;
+ untilLabel.setText(String.format(Locale.getDefault(), "%02d:%02d:%02d", durationSeconds / 3600,
+ (durationSeconds % 3600) / 60, (durationSeconds % 60)));
+ }
+ }.start();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ timer.cancel();
+
+ }
+
+ @Override
+ public void onBackPressed() {
+ if (getFragmentManager().getBackStackEntryCount() > 0) {
+ getFragmentManager().popBackStack();
+ } else if (AuthManager.getInstance().isWalletDisabled(DisabledActivity.this)) {
+ SpringAnimator.failShakeAnimation(DisabledActivity.this, disabled);
+ } else {
+ BRAnimator.startBreadActivity(DisabledActivity.this, true);
+ }
+ overridePendingTransition(R.anim.fade_up, R.anim.fade_down);
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ }
+
+ }
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/InputWordsActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/InputWordsActivity.java
new file mode 100644
index 000000000..6aecb4a19
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/activities/InputWordsActivity.java
@@ -0,0 +1,378 @@
+package com.breadwallet.presenter.activities;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ImageButton;
+import android.widget.TextView;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.intro.IntroActivity;
+import com.breadwallet.presenter.activities.util.ActivityUTILS;
+import com.breadwallet.presenter.activities.util.BRActivity;
+import com.breadwallet.presenter.customviews.BRDialogView;
+import com.breadwallet.tools.animation.BRAnimator;
+import com.breadwallet.tools.animation.BRDialog;
+import com.breadwallet.tools.animation.SpringAnimator;
+import com.breadwallet.tools.manager.BRSharedPrefs;
+import com.breadwallet.tools.security.AuthManager;
+import com.breadwallet.tools.security.PostAuth;
+import com.breadwallet.tools.security.SmartValidator;
+import com.breadwallet.tools.util.BRConstants;
+import com.breadwallet.tools.util.Utils;
+import com.breadwallet.tools.util.Bip39Reader;
+import com.breadwallet.wallet.BRWalletManager;
+
+public class InputWordsActivity extends BRActivity {
+ private static final String TAG = InputWordsActivity.class.getName();
+ private Button nextButton;
+
+ private EditText word1;
+ private EditText word2;
+ private EditText word3;
+ private EditText word4;
+ private EditText word5;
+ private EditText word6;
+ private EditText word7;
+ private EditText word8;
+ private EditText word9;
+ private EditText word10;
+ private EditText word11;
+ private EditText word12;
+ private String debugPhrase;
+
+ private TextView title;
+ private TextView description;
+ public static boolean appVisible = false;
+ private static InputWordsActivity app;
+
+ public static InputWordsActivity getApp() {
+ return app;
+ }
+
+ //will be true if this screen was called from the restore screen
+ private boolean restore = false;
+ private boolean resetPin = false;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_input_words);
+ getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
+
+ if (Utils.isEmulatorOrDebug(this)) {
+// debugPhrase = "ใใใใใใใซใฃใฆใใใใฃใใใใใคใใใใใใฉใใใตใใใใซใฃใใใใใใใใใใพใใชใพใฟใใใใณใใฏใใ";//japanese
+// debugPhrase = "video tiger report bid suspect taxi mail argue naive layer metal surface";//english
+// debugPhrases = "vocation triage capsule marchand onduler tibia illicite entier fureur minorer amateur lubie";//french
+// debugPhrase = "zorro turismo mezcla nicho morir chico blanco paฬjaro alba esencia roer repetir";//spanish
+// debugPhrase = "ๆจ ่ดช ๆ ๆ ๅน ้ณ ๅณ ๅปท ๅ ๅฉ ็ ๆ";//chinese
+// debugPhrase = "aim lawn sniff tenant coffee smoke meat hockey glow try also angle";
+
+ }
+
+ nextButton = findViewById(R.id.send_button);
+
+ if (Utils.isUsingCustomInputMethod(this)) {
+ BRDialog.showCustomDialog(this, getString(R.string.JailbreakWarnings_title), getString(R.string.Alert_customKeyboard_android),
+ getString(R.string.Button_ok), getString(R.string.JailbreakWarnings_close), new BRDialogView.BROnClickListener() {
+ @Override
+ public void onClick(BRDialogView brDialogView) {
+ InputMethodManager imeManager = (InputMethodManager) getApplicationContext().getSystemService(INPUT_METHOD_SERVICE);
+ imeManager.showInputMethodPicker();
+ brDialogView.dismissWithAnimation();
+ }
+ }, new BRDialogView.BROnClickListener() {
+ @Override
+ public void onClick(BRDialogView brDialogView) {
+ brDialogView.dismissWithAnimation();
+ }
+ }, null, 0);
+ }
+
+ ImageButton faq = (ImageButton) findViewById(R.id.faq_button);
+ //TODO: all views are using the layout of this button. Views should be refactored without it
+ // Hiding until layouts are built.
+
+ title = (TextView) findViewById(R.id.title);
+ description = (TextView) findViewById(R.id.description);
+
+ word1 = (EditText) findViewById(R.id.word1);
+ word2 = (EditText) findViewById(R.id.word2);
+ word3 = (EditText) findViewById(R.id.word3);
+ word4 = (EditText) findViewById(R.id.word4);
+ word5 = (EditText) findViewById(R.id.word5);
+ word6 = (EditText) findViewById(R.id.word6);
+ word7 = (EditText) findViewById(R.id.word7);
+ word8 = (EditText) findViewById(R.id.word8);
+ word9 = (EditText) findViewById(R.id.word9);
+ word10 = (EditText) findViewById(R.id.word10);
+ word11 = (EditText) findViewById(R.id.word11);
+ word12 = (EditText) findViewById(R.id.word12);
+
+ word1.setOnFocusChangeListener(new FocusListener());
+ word2.setOnFocusChangeListener(new FocusListener());
+ word3.setOnFocusChangeListener(new FocusListener());
+ word4.setOnFocusChangeListener(new FocusListener());
+ word5.setOnFocusChangeListener(new FocusListener());
+ word6.setOnFocusChangeListener(new FocusListener());
+ word7.setOnFocusChangeListener(new FocusListener());
+ word8.setOnFocusChangeListener(new FocusListener());
+ word9.setOnFocusChangeListener(new FocusListener());
+ word10.setOnFocusChangeListener(new FocusListener());
+ word11.setOnFocusChangeListener(new FocusListener());
+ word12.setOnFocusChangeListener(new FocusListener());
+
+ restore = getIntent().getExtras() != null && getIntent().getExtras().getBoolean("restore");
+ resetPin = getIntent().getExtras() != null && getIntent().getExtras().getBoolean("resetPin");
+
+ if (restore) {
+ //change the labels
+ title.setText(getString(R.string.MenuViewController_recoverButton));
+ description.setText(getString(R.string.WipeWallet_instruction));
+ } else if (resetPin) {
+ //change the labels
+ title.setText(getString(R.string.RecoverWallet_header_reset_pin));
+ description.setText(getString(R.string.RecoverWallet_subheader_reset_pin));
+ }
+
+ word12.setOnEditorActionListener(new TextView.OnEditorActionListener() {
+ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+ if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) || (actionId == EditorInfo.IME_ACTION_DONE)) {
+ nextButton.performClick();
+ }
+ return false;
+ }
+ });
+
+ nextButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (!BRAnimator.isClickAllowed()) return;
+ final Activity app = InputWordsActivity.this;
+ String phraseToCheck = getPhrase();
+ if (Utils.isEmulatorOrDebug(app) && !Utils.isNullOrEmpty(debugPhrase)) {
+ phraseToCheck = debugPhrase;
+ }
+ if (phraseToCheck == null) {
+ return;
+ }
+ String cleanPhrase = SmartValidator.cleanPaperKey(app, phraseToCheck);
+ if (SmartValidator.isPaperKeyValid(app, cleanPhrase)) {
+
+ if (restore || resetPin) {
+ if (SmartValidator.isPaperKeyCorrect(cleanPhrase, app)) {
+ Utils.hideKeyboard(app);
+ clearWords();
+
+ if (restore) {
+ BRDialog.showCustomDialog(InputWordsActivity.this, getString(R.string.WipeWallet_alertTitle), getString(R.string.WipeWallet_alertMessage), getString(R.string.WipeWallet_wipe), getString(R.string.Button_cancel), new BRDialogView.BROnClickListener() {
+ @Override
+ public void onClick(BRDialogView brDialogView) {
+ brDialogView.dismissWithAnimation();
+ BRWalletManager m = BRWalletManager.getInstance();
+ m.wipeWalletButKeystore(app);
+ m.wipeKeyStore(app);
+ Intent intent = new Intent(app, IntroActivity.class);
+ finalizeIntent(intent);
+ }
+ }, new BRDialogView.BROnClickListener() {
+ @Override
+ public void onClick(BRDialogView brDialogView) {
+ brDialogView.dismissWithAnimation();
+ }
+ }, null, 0);
+
+ } else {
+ AuthManager.getInstance().setPinCode("", InputWordsActivity.this);
+ Intent intent = new Intent(app, SetPinActivity.class);
+ intent.putExtra("noPin", true);
+ finalizeIntent(intent);
+ }
+
+
+ } else {
+ BRDialog.showCustomDialog(app, "", getString(R.string.RecoverWallet_invalid), getString(R.string.AccessibilityLabels_close), null, new BRDialogView.BROnClickListener() {
+ @Override
+ public void onClick(BRDialogView brDialogView) {
+ brDialogView.dismissWithAnimation();
+ }
+ }, null, null, 0);
+ }
+
+ } else {
+ Utils.hideKeyboard(app);
+ BRWalletManager m = BRWalletManager.getInstance();
+ m.wipeWalletButKeystore(app);
+ m.wipeKeyStore(app);
+ PostAuth.getInstance().setPhraseForKeyStore(cleanPhrase);
+ BRSharedPrefs.putAllowSpend(app, false);
+ //if this screen is shown then we did not upgrade to the new app, we installed it
+ BRSharedPrefs.putGreetingsShown(app, true);
+ PostAuth.getInstance().onRecoverWalletAuth(app, false);
+ }
+
+ } else {
+ BRDialog.showCustomDialog(app, "", getResources().getString(R.string.RecoverWallet_invalid), getString(R.string.AccessibilityLabels_close), null, new BRDialogView.BROnClickListener() {
+ @Override
+ public void onClick(BRDialogView brDialogView) {
+ brDialogView.dismissWithAnimation();
+ }
+ }, null, null, 0);
+
+ }
+ }
+ });
+
+ }
+
+ private void finalizeIntent(Intent intent) {
+ intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ overridePendingTransition(R.anim.enter_from_right, R.anim.exit_to_left);
+ startActivity(intent);
+ if (!InputWordsActivity.this.isDestroyed()) finish();
+ Activity app = BreadActivity.getApp();
+ if (app != null && !app.isDestroyed()) app.finish();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ appVisible = true;
+ app = this;
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ appVisible = false;
+ }
+
+ @Override
+ public void onBackPressed() {
+ super.onBackPressed();
+ overridePendingTransition(R.anim.enter_from_left, R.anim.exit_to_right);
+ }
+
+ private String getPhrase() {
+ boolean success = true;
+
+ String w1 = word1.getText().toString().toLowerCase();
+ String w2 = word2.getText().toString().toLowerCase();
+ String w3 = word3.getText().toString().toLowerCase();
+ String w4 = word4.getText().toString().toLowerCase();
+ String w5 = word5.getText().toString().toLowerCase();
+ String w6 = word6.getText().toString().toLowerCase();
+ String w7 = word7.getText().toString().toLowerCase();
+ String w8 = word8.getText().toString().toLowerCase();
+ String w9 = word9.getText().toString().toLowerCase();
+ String w10 = word10.getText().toString().toLowerCase();
+ String w11 = word11.getText().toString().toLowerCase();
+ String w12 = word12.getText().toString().toLowerCase();
+
+ if (Utils.isNullOrEmpty(w1)) {
+ SpringAnimator.failShakeAnimation(this, word1);
+ success = false;
+ }
+ if (Utils.isNullOrEmpty(w2)) {
+ SpringAnimator.failShakeAnimation(this, word2);
+ success = false;
+ }
+ if (Utils.isNullOrEmpty(w3)) {
+ SpringAnimator.failShakeAnimation(this, word3);
+ success = false;
+ }
+ if (Utils.isNullOrEmpty(w4)) {
+ SpringAnimator.failShakeAnimation(this, word4);
+ success = false;
+ }
+ if (Utils.isNullOrEmpty(w5)) {
+ SpringAnimator.failShakeAnimation(this, word5);
+ success = false;
+ }
+ if (Utils.isNullOrEmpty(w6)) {
+ SpringAnimator.failShakeAnimation(this, word6);
+ success = false;
+ }
+ if (Utils.isNullOrEmpty(w7)) {
+ SpringAnimator.failShakeAnimation(this, word7);
+ success = false;
+ }
+ if (Utils.isNullOrEmpty(w8)) {
+ SpringAnimator.failShakeAnimation(this, word8);
+ success = false;
+ }
+ if (Utils.isNullOrEmpty(w9)) {
+ SpringAnimator.failShakeAnimation(this, word9);
+ success = false;
+ }
+ if (Utils.isNullOrEmpty(w10)) {
+ SpringAnimator.failShakeAnimation(this, word10);
+ success = false;
+ }
+ if (Utils.isNullOrEmpty(w11)) {
+ SpringAnimator.failShakeAnimation(this, word11);
+ success = false;
+ }
+ if (Utils.isNullOrEmpty(w12)) {
+ SpringAnimator.failShakeAnimation(this, word12);
+ success = false;
+ }
+
+ if (!success) return null;
+
+ return w(w1) + " " + w(w2) + " " + w(w3) + " " + w(w4) + " " + w(w5) + " " + w(w6) + " " + w(w7) + " " + w(w8) + " " + w(w9) + " " + w(w10) + " " + w(w11) + " " + w(w12);
+ }
+
+ private String w(String word) {
+ return word.replaceAll(" ", "");
+ }
+
+ private void clearWords() {
+ word1.setText("");
+ word2.setText("");
+ word3.setText("");
+ word4.setText("");
+ word5.setText("");
+ word6.setText("");
+ word7.setText("");
+ word8.setText("");
+ word9.setText("");
+ word10.setText("");
+ word11.setText("");
+ word12.setText("");
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ }
+
+ private class FocusListener implements View.OnFocusChangeListener {
+
+ @Override
+ public void onFocusChange(View v, boolean hasFocus) {
+ if (!hasFocus) {
+ validateWord((EditText) v);
+ } else {
+ ((EditText) v).setTextColor(getColor(R.color.light_gray));
+ }
+ }
+ }
+
+ private void validateWord(EditText view) {
+ String word = view.getText().toString();
+ boolean valid = SmartValidator.isWordValid(this, word);
+ view.setTextColor(getColor(valid ? R.color.light_gray : R.color.red_text));
+ if (!valid)
+ SpringAnimator.failShakeAnimation(this, view);
+ }
+
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/IntroActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/IntroActivity.java
deleted file mode 100644
index 48a15c883..000000000
--- a/app/src/main/java/com/breadwallet/presenter/activities/IntroActivity.java
+++ /dev/null
@@ -1,379 +0,0 @@
-
-package com.breadwallet.presenter.activities;
-
-import android.app.Fragment;
-import android.app.FragmentManager;
-import android.app.FragmentTransaction;
-import android.content.Intent;
-import android.graphics.Point;
-import android.os.Bundle;
-import android.os.Handler;
-import android.support.v4.app.FragmentActivity;
-import android.util.Log;
-import android.view.View;
-import android.view.Window;
-import android.view.WindowManager;
-import android.view.animation.Animation;
-import android.view.animation.TranslateAnimation;
-import android.widget.Button;
-import android.widget.ImageView;
-
-import com.breadwallet.BuildConfig;
-import com.breadwallet.R;
-import com.breadwallet.BreadWalletApp;
-import com.breadwallet.presenter.fragments.IntroNewRecoverFragment;
-import com.breadwallet.presenter.fragments.IntroNewWalletFragment;
-import com.breadwallet.presenter.fragments.IntroRecoverWalletFragment;
-import com.breadwallet.presenter.fragments.IntroWarningFragment;
-import com.breadwallet.presenter.fragments.IntroWelcomeFragment;
-import com.breadwallet.tools.animation.BRAnimator;
-import com.breadwallet.tools.util.BRConstants;
-import com.breadwallet.tools.manager.SharedPreferencesManager;
-import com.breadwallet.tools.animation.BackgroundMovingAnimator;
-import com.breadwallet.tools.animation.DecelerateOvershootInterpolator;
-import com.breadwallet.tools.security.KeyStoreManager;
-import com.breadwallet.tools.security.PostAuthenticationProcessor;
-import com.breadwallet.tools.util.Utils;
-import com.breadwallet.wallet.BRWalletManager;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 8/4/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-public class IntroActivity extends FragmentActivity {
- private static final String TAG = IntroActivity.class.getName();
- public static IntroActivity app;
- private Button leftButton;
- public static final int RIGHT = 1;
- public static final int LEFT = 2;
-
- private int newRecoverNoneFlag = 0;//0 - in IntroNewRecoverFragment, 1 - in IntroNewWalletFragment, 2 - IntroRecoverWalletFragment
-
- //loading the native library
- static {
- System.loadLibrary("core");
- }
-
- private boolean backNotAllowed = false;
- private IntroWelcomeFragment introWelcomeFragment;
- private IntroNewRecoverFragment introNewRecoverFragment;
- private IntroRecoverWalletFragment introRecoverWalletFragment;
- private IntroNewWalletFragment introNewWalletFragment;
- private IntroWarningFragment introWarningFragment;
- public static final Point screenParametersPoint = new Point();
-
- @Override
- protected void onRestart() {
- super.onRestart(); // Always call the superclass method first
- app = this;
- // Activity being restarted from stopped state
- }
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_intro);
- app = this;
-
- if (!BuildConfig.DEBUG && KeyStoreManager.AUTH_DURATION_SEC != 300)
- throw new IllegalArgumentException("AUTH_DURATION_SEC should be 300");
- getWindowManager().getDefaultDisplay().getSize(screenParametersPoint);
- leftButton = (Button) findViewById(R.id.intro_left_button);
- leftButton.setVisibility(View.GONE);
- leftButton.setClickable(false);
- leftButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- onBackPressed();
- }
- });
-
- byte[] masterPubKey = KeyStoreManager.getMasterPublicKey(this);
- boolean isFirstAddressCorrect = false;
- if (masterPubKey != null && masterPubKey.length != 0) {
- isFirstAddressCorrect = checkFirstAddress(masterPubKey);
- }
- Log.e(TAG, "isFirstAddressCorrect: " + isFirstAddressCorrect);
- if (!isFirstAddressCorrect) {
- Log.e(TAG, "CLEARING THE WALLET");
- BRWalletManager.getInstance(this).wipeWalletButKeystore(this);
- }
- createFragments();
-
- setStatusBarColor(0);
-
- PostAuthenticationProcessor.getInstance().onCanaryCheck(this);
-
- }
-
- private void createFragments() {
- introWelcomeFragment = new IntroWelcomeFragment();
- introNewRecoverFragment = new IntroNewRecoverFragment();
- introNewWalletFragment = new IntroNewWalletFragment();
- introRecoverWalletFragment = new IntroRecoverWalletFragment();
- introWarningFragment = new IntroWarningFragment();
-
- FragmentManager fragmentManager = getFragmentManager();
- FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
-
- fragmentTransaction.add(R.id.intro_layout, introWelcomeFragment,
- IntroWelcomeFragment.class.getName());
- fragmentTransaction.add(R.id.intro_layout, introNewRecoverFragment,
- IntroNewRecoverFragment.class.getName());
- fragmentTransaction.add(R.id.intro_layout, introNewWalletFragment,
- IntroNewWalletFragment.class.getName());
- fragmentTransaction.add(R.id.intro_layout, introRecoverWalletFragment,
- IntroRecoverWalletFragment.class.getName());
- fragmentTransaction.add(R.id.intro_layout, introWarningFragment,
- IntroWarningFragment.class.getName());
-
- showHideFragments(introWelcomeFragment);
- newRecoverNoneFlag = 0;
- fragmentTransaction.commitAllowingStateLoss();
- }
-
- private void showHideFragments(Fragment... fragments) {
- FragmentManager fragmentManager = getFragmentManager();
- FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
- fragmentTransaction.hide(introWelcomeFragment);
- fragmentTransaction.hide(introNewRecoverFragment);
- fragmentTransaction.hide(introNewWalletFragment);
- fragmentTransaction.hide(introRecoverWalletFragment);
- fragmentTransaction.hide(introWarningFragment);
- for (Fragment f : fragments) {
- fragmentTransaction.show(f);
- }
- fragmentTransaction.commitAllowingStateLoss();
- }
-
- private void setStatusBarColor(int mode) {
- if (mode == 0) {
- Window window = getWindow();
- window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
- window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
- window.setStatusBarColor(getColor(R.color.intro_status_bar));
- } else {
- Window window = getWindow();
- window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
- window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
- window.setStatusBarColor(getColor(R.color.warning_status_bar));
- }
- }
-
-
- public boolean checkFirstAddress(byte[] mpk) {
- String addressFromPrefs = SharedPreferencesManager.getFirstAddress(this);
- String generatedAddress = BRWalletManager.getFirstAddress(mpk);
-// Log.e(TAG, "addressFromPrefs: " + addressFromPrefs);
-// Log.e(TAG, "generatedAddress: " + generatedAddress);
- return addressFromPrefs.equals(generatedAddress);
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- app = this;
- //animates the orange BW background moving.
- ImageView background = (ImageView) findViewById(R.id.intro_bread_wallet_image);
- background.setScaleType(ImageView.ScaleType.MATRIX);
- BackgroundMovingAnimator.animateBackgroundMoving(background);
-
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- BackgroundMovingAnimator.stopBackgroundMoving();
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
-
- }
-
- private void showNewRecoverWalletFragment() {
- animateSlide(introWelcomeFragment, introNewRecoverFragment, RIGHT);
-
- }
-
- public void showNewWalletFragment() {
- newRecoverNoneFlag = 1;
- leftButton.setVisibility(View.VISIBLE);
- leftButton.setClickable(true);
- animateSlide(introNewRecoverFragment, introNewWalletFragment, RIGHT);
- }
-
- public void showRecoverWalletFragment() {
- newRecoverNoneFlag = 2;
- leftButton.setVisibility(View.VISIBLE);
- leftButton.setClickable(true);
- animateSlide(introNewRecoverFragment, introRecoverWalletFragment, RIGHT);
- introRecoverWalletFragment.showKeyBoard(true);
- }
-
- public void showWarningFragment() {
- setStatusBarColor(1);
- newRecoverNoneFlag = 0;
- introNewWalletFragment.introGenerate.setClickable(false);
- leftButton.setVisibility(View.GONE);
- leftButton.setClickable(false);
- backNotAllowed = true;
- showHideFragments(introWarningFragment);
- }
-
- @Override
- protected void onStop() {
- super.onStop();
- }
-
-
- public void startMainActivity() {
- Intent intent;
- intent = new Intent(this, MainActivity.class);
- startActivity(intent);
- if (!IntroActivity.this.isDestroyed()) {
- finish();
- }
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- Log.e(TAG, "IntroActivity, onActivityResult: " + requestCode);
- switch (requestCode) {
- case BRConstants.PUT_PHRASE_NEW_WALLET_REQUEST_CODE:
- if (resultCode == RESULT_OK) {
- PostAuthenticationProcessor.getInstance().onCreateWalletAuth(this);
- } else {
- Log.e(TAG, "WARNING: resultCode != RESULT_OK");
- BRWalletManager m = BRWalletManager.getInstance(this);
-// m.wipeKeyStore(this);
- m.wipeWalletButKeystore(this);
- BRAnimator.resetFragmentAnimator();
- finish();
- }
- break;
- case BRConstants.PUT_PHRASE_RECOVERY_WALLET_REQUEST_CODE:
- if (resultCode == RESULT_OK) {
- PostAuthenticationProcessor.getInstance().onRecoverWalletAuth(this);
- } else {
- finish();
- }
- break;
- case BRConstants.CANARY_REQUEST_CODE:
- if (resultCode == RESULT_OK) {
- PostAuthenticationProcessor.getInstance().onCanaryCheck(this);
- } else {
- finish();
- }
- break;
-
- }
-
- }
-
- @Override
- public void onBackPressed() {
- if (backNotAllowed) return;
- if (newRecoverNoneFlag == 1) {
- leftButton.setVisibility(View.GONE);
- leftButton.setClickable(false);
- animateSlide(introNewWalletFragment, introNewRecoverFragment, LEFT);
- newRecoverNoneFlag = 0;
- } else if (newRecoverNoneFlag == 2) {
- showHideFragments(introRecoverWalletFragment, introNewRecoverFragment);
- leftButton.setVisibility(View.GONE);
- leftButton.setClickable(false);
- animateSlide(introRecoverWalletFragment, introNewRecoverFragment, LEFT);
- newRecoverNoneFlag = 0;
- introRecoverWalletFragment.showKeyBoard(false);
- } else {
- super.onBackPressed();
- }
-
- }
-
- public void startTheWalletIfExists() {
- final BRWalletManager m = BRWalletManager.getInstance(this);
- if (!m.isPasscodeEnabled(this)) {
- //Device passcode/password should be enabled for the app to work
- ((BreadWalletApp) getApplication()).showDeviceNotSecuredWarning(this);
- } else {
- if (m.noWallet(app)) {
- //now check if there is a wallet or should we create/restore one.
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- showNewRecoverWalletFragment();
- }
- }, 800);
- } else {
- startMainActivity();
- }
-
- }
- }
-
- // direction == 1 -> RIGHT, direction == 2 -> LEFT
- private void animateSlide(final Fragment from, final Fragment to, int direction) {
- if (to instanceof IntroRecoverWalletFragment) {
- Log.e(TAG, "animateSlide: to instanceof IntroRecoverWalletFragment");
- if (Utils.isUsingCustomInputMethod(to.getActivity()))
- ((IntroRecoverWalletFragment) to).disableEditText();
- }
- int screenWidth = screenParametersPoint.x;
- int screenHeigth = screenParametersPoint.y;
-
- showHideFragments(from, to);
- TranslateAnimation transFrom = direction == RIGHT ?
- new TranslateAnimation(0, -screenWidth, 0, 0) : new TranslateAnimation(0, screenWidth, 0, 0);
- transFrom.setDuration(BRAnimator.horizontalSlideDuration);
- transFrom.setInterpolator(new DecelerateOvershootInterpolator(1f, 0.5f));
- View fromView = from.getView();
- if (fromView != null)
- fromView.startAnimation(transFrom);
- TranslateAnimation transTo = direction == RIGHT ?
- new TranslateAnimation(screenWidth, 0, 0, 0) : new TranslateAnimation(-screenWidth, 0, 0, 0);
- transTo.setDuration(BRAnimator.horizontalSlideDuration);
- transTo.setInterpolator(new DecelerateOvershootInterpolator(1f, 0.5f));
- transTo.setAnimationListener(new Animation.AnimationListener() {
- @Override
- public void onAnimationStart(Animation animation) {
-
- }
-
- @Override
- public void onAnimationEnd(Animation animation) {
- showHideFragments(to);
- }
-
- @Override
- public void onAnimationRepeat(Animation animation) {
-
- }
- });
- View toView = to.getView();
- if (toView != null)
- toView.startAnimation(transTo);
- }
-}
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/LoginActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/LoginActivity.java
new file mode 100644
index 000000000..ca174729c
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/activities/LoginActivity.java
@@ -0,0 +1,348 @@
+package com.breadwallet.presenter.activities;
+
+import android.Manifest;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.AccelerateInterpolator;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
+
+import com.breadwallet.BuildConfig;
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.camera.ScanQRActivity;
+import com.breadwallet.presenter.activities.util.BRActivity;
+import com.breadwallet.presenter.customviews.BRKeyboard;
+import com.breadwallet.presenter.entities.CurrencyEntity;
+import com.breadwallet.presenter.interfaces.BRAuthCompletion;
+import com.breadwallet.tools.animation.BRAnimator;
+import com.breadwallet.tools.animation.BRDialog;
+import com.breadwallet.tools.animation.SpringAnimator;
+import com.breadwallet.tools.manager.AnalyticsManager;
+import com.breadwallet.tools.manager.BRSharedPrefs;
+import com.breadwallet.tools.security.AuthManager;
+import com.breadwallet.tools.security.BRKeyStore;
+import com.breadwallet.tools.sqlite.CurrencyDataSource;
+import com.breadwallet.tools.threads.BRExecutor;
+import com.breadwallet.tools.util.BRConstants;
+import com.breadwallet.tools.util.BRCurrency;
+import com.breadwallet.wallet.BRWalletManager;
+import com.google.android.material.snackbar.Snackbar;
+import com.platform.APIClient;
+
+import java.math.BigDecimal;
+import java.util.Locale;
+
+import timber.log.Timber;
+
+import static com.breadwallet.tools.util.BRConstants.PLATFORM_ON;
+import static com.breadwallet.tools.util.BRConstants.SCANNER_REQUEST;
+
+public class LoginActivity extends BRActivity {
+ private BRKeyboard keyboard;
+ private LinearLayout pinLayout;
+ private View dot1;
+ private View dot2;
+ private View dot3;
+ private View dot4;
+ private View dot5;
+ private View dot6;
+ private StringBuilder pin = new StringBuilder();
+ private int pinLimit = 6;
+ private static LoginActivity app;
+
+ private ImageView unlockedImage;
+ private TextView unlockedText;
+ private TextView enterPinLabel;
+ private TextView versionText;
+ private ViewGroup ltcPriceConstraintLayout;
+
+ private TextView ltcPriceTextView;
+ private TextView ltcPriceDescTextView;
+
+ private ImageButton fingerPrint;
+ public static boolean appVisible = false;
+ private boolean inputAllowed = true;
+
+ public static LoginActivity getApp() {
+ return app;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_pin);
+ View parentLayout = findViewById(android.R.id.content);
+ String pin = BRKeyStore.getPinCode(this);
+ if (pin.isEmpty() || (pin.length() != 6 && pin.length() != 4)) {
+ Intent intent = new Intent(this, SetPinActivity.class);
+ intent.putExtra("noPin", true);
+ startActivity(intent);
+ if (!LoginActivity.this.isDestroyed()) finish();
+ return;
+ }
+ if (BRKeyStore.getPinCode(this).length() == 4) pinLimit = 4;
+
+ keyboard = findViewById(R.id.brkeyboard);
+ pinLayout = findViewById(R.id.pinLayout);
+ fingerPrint = findViewById(R.id.fingerprint_icon);
+ versionText = findViewById(R.id.version_text);
+
+ ltcPriceTextView = findViewById(R.id.ltcPriceTextView);
+ ltcPriceDescTextView = findViewById(R.id.ltcPriceDescTextView);
+
+ unlockedImage = findViewById(R.id.unlocked_image);
+ unlockedText = findViewById(R.id.unlocked_text);
+ enterPinLabel = findViewById(R.id.enter_pin_label);
+ ltcPriceConstraintLayout = findViewById(R.id.ltcPriceConstraintLayout);
+
+ dot1 = findViewById(R.id.dot1);
+ dot2 = findViewById(R.id.dot2);
+ dot3 = findViewById(R.id.dot3);
+ dot4 = findViewById(R.id.dot4);
+ dot5 = findViewById(R.id.dot5);
+ dot6 = findViewById(R.id.dot6);
+
+ keyboard.addOnInsertListener(key -> handleClick(key));
+ keyboard.setBRButtonTextColor(R.color.white);
+ keyboard.setShowDot(false);
+
+ keyboard.setCustomButtonBackgroundColor(10, getColor(android.R.color.transparent));
+ keyboard.setDeleteImage(getDrawable(R.drawable.ic_delete_white));
+ versionText.setText(BRConstants.APP_VERSION_NAME_CODE);
+
+ findViewById(R.id.scanQRCodeImgBut).setOnClickListener(v -> {
+ if (!BRAnimator.isClickAllowed()) return;
+ try {
+ // Check if the camera permission is granted
+ if (ContextCompat.checkSelfPermission(app,
+ Manifest.permission.CAMERA)
+ != PackageManager.PERMISSION_GRANTED) {
+ if (ActivityCompat.shouldShowRequestPermissionRationale(app,
+ Manifest.permission.CAMERA)) {
+ BRDialog.showCustomDialog(app, getString(R.string.Send_cameraUnavailabeTitle_android),
+ getString(R.string.Send_cameraUnavailabeMessage_android), getString(R.string.AccessibilityLabels_close), null, brDialogView -> brDialogView.dismiss(), null, null, 0);
+ } else {
+ ActivityCompat.requestPermissions(app,
+ new String[]{Manifest.permission.CAMERA},
+ BRConstants.CAMERA_REQUEST_ID);
+ }
+ } else {
+ Intent intent = new Intent(app, ScanQRActivity.class);
+ app.startActivityForResult(intent, SCANNER_REQUEST);
+ app.overridePendingTransition(R.anim.fade_up, 0);
+ }
+ } catch (Exception e) {
+ Timber.e(e);
+ }
+ });
+
+ final boolean useFingerprint = AuthManager.isFingerPrintAvailableAndSetup(this) && BRSharedPrefs.getUseFingerprint(this);
+ fingerPrint.setVisibility(useFingerprint ? View.VISIBLE : View.GONE);
+
+ if (useFingerprint) {
+ fingerPrint.setOnClickListener(v -> AuthManager.getInstance().authPrompt(LoginActivity.this, "", "", false, true, new BRAuthCompletion() {
+ @Override
+ public void onComplete() {
+ unlockWallet();
+ AnalyticsManager.logCustomEvent(BRConstants._20200217_DUWB);
+ }
+
+ @Override
+ public void onCancel() {
+ }
+ }));
+ }
+
+ new Handler().postDelayed(() -> {
+ if (fingerPrint != null && useFingerprint)
+ fingerPrint.performClick();
+ }, 500);
+
+ setCurrentLtcPrice();
+
+ if (BuildConfig.VERSION_NAME == "v2.8.4") {
+ Snackbar.make(parentLayout,
+ R.string.release_notes,
+ Snackbar.LENGTH_INDEFINITE).setAction(R.string.Webview_dismiss, new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+
+ }
+ })
+ .setActionTextColor(getResources().getColor(android.R.color.holo_red_light ))
+ .show();
+ }
+ }
+
+ private void setCurrentLtcPrice() {
+ String iso = BRSharedPrefs.getIso(this);
+
+ String formattedCurrency = null;
+ CurrencyEntity currency = CurrencyDataSource.getInstance(this).getCurrencyByIso(iso);
+ if (currency != null) {
+ final BigDecimal roundedPriceAmount = new BigDecimal(currency.rate).multiply(new BigDecimal(100))
+ .divide(new BigDecimal(100), 2, BRConstants.ROUNDING_MODE);
+ formattedCurrency = BRCurrency.getFormattedCurrencyString(this, iso, roundedPriceAmount);
+ } else {
+ Timber.w("The currency related to %s is NULL", iso);
+ }
+
+ if (formattedCurrency != null) {
+ ltcPriceTextView.setText(getString(R.string.Login_ltcPrice, formattedCurrency));
+ ltcPriceDescTextView.setText(getString(R.string.Login_currentLtcPrice, iso));
+ }
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ updateDots();
+
+ appVisible = true;
+ app = this;
+ inputAllowed = true;
+ if (!BRWalletManager.getInstance().isCreated()) {
+ BRExecutor.getInstance().forBackgroundTasks().execute(() -> BRWalletManager.getInstance().initWallet(LoginActivity.this));
+ }
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ appVisible = false;
+ }
+
+ private void handleClick(String key) {
+ if (!inputAllowed) {
+ Timber.d("timber: handleClick: input not allowed");
+ return;
+ }
+ if (key == null) {
+ Timber.d("timber: handleClick: key is null! ");
+ return;
+ }
+
+ if (key.isEmpty()) {
+ handleDeleteClick();
+ } else if (Character.isDigit(key.charAt(0))) {
+ handleDigitClick(Integer.parseInt(key.substring(0, 1)));
+ } else {
+ Timber.d("timber: handleClick: oops: %s", key);
+ }
+ }
+
+
+ private void handleDigitClick(Integer dig) {
+ if (pin.length() < pinLimit)
+ pin.append(dig);
+ updateDots();
+ }
+
+ private void handleDeleteClick() {
+ if (pin.length() > 0)
+ pin.deleteCharAt(pin.length() - 1);
+ updateDots();
+ }
+
+ @Override
+ public void onBackPressed() {
+ if (getFragmentManager().getBackStackEntryCount() > 0) {
+ super.onBackPressed();
+ } else {
+ finishAffinity();
+ }
+ }
+
+ private void unlockWallet() {
+ pin = new StringBuilder();
+ ltcPriceConstraintLayout.animate().translationY(-600).setInterpolator(new AccelerateInterpolator());
+ pinLayout.animate().translationY(-2000).setInterpolator(new AccelerateInterpolator());
+ enterPinLabel.animate().translationY(-1800).setInterpolator(new AccelerateInterpolator());
+ keyboard.animate().translationY(2000).setInterpolator(new AccelerateInterpolator());
+ unlockedImage.animate().alpha(1f).setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ new Handler().postDelayed(() -> {
+ Intent intent = new Intent(LoginActivity.this, BreadActivity.class);
+ startActivity(intent);
+ overridePendingTransition(R.anim.fade_up, R.anim.fade_down);
+ if (!LoginActivity.this.isDestroyed()) {
+ LoginActivity.this.finish();
+
+ }
+ }, 400);
+ }
+ });
+ unlockedText.animate().alpha(1f);
+ }
+
+ private void showFailedToUnlock() {
+ SpringAnimator.failShakeAnimation(LoginActivity.this, pinLayout);
+ pin = new StringBuilder();
+ new Handler().postDelayed(() -> {
+ inputAllowed = true;
+ updateDots();
+ }, 1000);
+ }
+
+ private void updateDots() {
+ AuthManager.getInstance().updateDots(this, pinLimit, pin.toString(), dot1, dot2, dot3, dot4, dot5, dot6, R.drawable.ic_pin_dot_white,
+ () -> {
+ inputAllowed = false;
+ if (AuthManager.getInstance().checkAuth(pin.toString(), LoginActivity.this)) {
+ AuthManager.getInstance().authSuccess(LoginActivity.this);
+ unlockWallet();
+ AnalyticsManager.logCustomEvent(BRConstants._20200217_DUWB);
+ AnalyticsManager.logCustomEvent(BRConstants._20200217_DUWB);
+
+ } else {
+ AuthManager.getInstance().authFail(LoginActivity.this);
+ showFailedToUnlock();
+ }
+ });
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+
+ switch (requestCode) {
+ case BRConstants.CAMERA_REQUEST_ID: {
+ // If request is cancelled, the result arrays are empty.
+ if (grantResults.length > 0
+ && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ BRAnimator.openScanner(this, BRConstants.SCANNER_REQUEST);
+ // permission was granted, yay! Do the
+ // contacts-related task you need to do.
+ } else {
+ Timber.i("timber: onRequestPermissionsResult: permission isn't granted for: %s", requestCode);
+ // permission denied, boo! Disable the
+ // functionality that depends on this permission.
+ }
+ return;
+ }
+
+ // other 'case' lines to check for other
+ // permissions this app might request
+ }
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/MainActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/MainActivity.java
deleted file mode 100644
index 34d297dcf..000000000
--- a/app/src/main/java/com/breadwallet/presenter/activities/MainActivity.java
+++ /dev/null
@@ -1,735 +0,0 @@
-package com.breadwallet.presenter.activities;
-
-import android.annotation.TargetApi;
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.graphics.Point;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Debug;
-import android.os.Handler;
-import android.support.annotation.NonNull;
-import android.support.v4.app.FragmentActivity;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.Window;
-import android.view.WindowManager;
-import android.widget.Button;
-import android.widget.ImageView;
-import android.widget.ProgressBar;
-import android.widget.RelativeLayout;
-import android.widget.TextView;
-import android.widget.ViewFlipper;
-
-import com.breadwallet.R;
-import com.breadwallet.BreadWalletApp;
-import com.breadwallet.presenter.customviews.BubbleTextView;
-import com.breadwallet.presenter.fragments.FragmentScanResult;
-import com.breadwallet.presenter.fragments.FragmentSettings;
-import com.breadwallet.tools.animation.BRAnimator;
-import com.breadwallet.tools.util.BRConstants;
-import com.breadwallet.tools.manager.CurrencyManager;
-import com.breadwallet.tools.util.NetworkChangeReceiver;
-import com.breadwallet.tools.manager.SharedPreferencesManager;
-import com.breadwallet.tools.security.PostAuthenticationProcessor;
-import com.breadwallet.tools.security.RequestHandler;
-import com.breadwallet.tools.security.RootHelper;
-import com.breadwallet.tools.adapter.CustomPagerAdapter;
-import com.breadwallet.tools.adapter.MiddleViewAdapter;
-import com.breadwallet.tools.adapter.ParallaxViewPager;
-import com.breadwallet.tools.animation.SpringAnimator;
-import com.breadwallet.tools.security.KeyStoreManager;
-import com.breadwallet.tools.util.Utils;
-import com.breadwallet.wallet.BRPeerManager;
-import com.breadwallet.wallet.BRWalletManager;
-import com.platform.APIClient;
-
-import java.math.BigDecimal;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Observable;
-import java.util.Observer;
-import java.util.concurrent.TimeUnit;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 8/4/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-public class MainActivity extends FragmentActivity implements Observer {
- private static final String TAG = MainActivity.class.getName();
-
- public static MainActivity app;
- public RelativeLayout pageIndicator;
- private ImageView pageIndicatorLeft;
- private ImageView pageIndicatorRight;
- private Map burgerButtonMap;
- private Button burgerButton;
- public Button lockerButton;
- public TextView pay;
- private ProgressBar syncProgressBar;
- private TextView syncProgressText;
- public ParallaxViewPager parallaxViewPager;
- public ViewFlipper viewFlipper;
- public ViewFlipper lockerPayFlipper;
- private RelativeLayout networkErrorBar;
- private final NetworkChangeReceiver receiver = new NetworkChangeReceiver();
- public static final Point screenParametersPoint = new Point();
- private int middleViewState = 0;
- private BroadcastReceiver mPowerKeyReceiver = null;
- private int middleBubbleBlocksCount = 0;
- private static int MODE = BRConstants.RELEASE;
- public BubbleTextView middleBubble1;
- public BubbleTextView middleBubble2;
- public BubbleTextView middleBubbleBlocks;
- public BubbleTextView qrBubble1;
- public BubbleTextView qrBubble2;
- public BubbleTextView sendBubble1;
- public BubbleTextView sendBubble2;
- private ToastUpdater toastUpdater;
-
- public static boolean appInBackground = false;
-
- static {
- System.loadLibrary("core");
- }
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- if (savedInstanceState != null)
- savedInstanceState.clear();
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- app = this;
- initializeViews();
-
- Utils.printPhoneSpecs();
-
- Thread t = new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- BRWalletManager.getInstance(app).setUpTheWallet();
- }
- });
- t.setPriority(Thread.MIN_PRIORITY);
- t.start();
-
- registerScreenLockReceiver();
-
- getWindowManager().getDefaultDisplay().getSize(screenParametersPoint);
-
- checkDeviceRooted();
-
- if (Utils.isEmulatorOrDebug()) {
- MODE = BRConstants.DEBUG;
- Log.e(TAG, "DEBUG MODE!!!!!!");
- }
-
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- setUrlHandler();
- }
- }, 1000);
-
- setListeners();
- BRAnimator.scaleView(pageIndicatorLeft, 1f, BRConstants.PAGE_INDICATOR_SCALE_UP, 1f,
- BRConstants.PAGE_INDICATOR_SCALE_UP);
- setStatusBarColor();
-
-// updateBundle();
- }
-
- private void updateBundle() {
- new Thread(new Runnable() {
- @Override
- public void run() {
- APIClient apiClient = APIClient.getInstance(app);
- apiClient.updateBundle(); //bread-buy-staging
- }
- }).start();
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- }
-
- private void setStatusBarColor() {
- Window window = getWindow();
- window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
- window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
- window.setStatusBarColor(getColor(R.color.status_bar));
- }
-
- private void setUrlHandler() {
- Intent intent = getIntent();
- Uri data = intent.getData();
- if (data == null) return;
- String scheme = data.getScheme();
- if (scheme != null && scheme.startsWith("bitcoin")) {
- Log.e(TAG, "bitcoin url");
- String str = intent.getDataString();
- RequestHandler.processRequest(this, str);
- } else {
- Log.e(TAG, "No bitcoin url");
- }
- }
-
- private void setListeners() {
- pay.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (BRAnimator.checkTheMultipressingAvailability()) {
- hideAllBubbles();
- String amountHolder = FragmentScanResult.instance.getBitcoinValue().value;
- String addressHolder = FragmentScanResult.address;
- String multiplyBy = "100";
- int unit = SharedPreferencesManager.getCurrencyUnit(app);
- if (unit == BRConstants.CURRENT_UNIT_MBITS) multiplyBy = "100000";
- if (unit == BRConstants.CURRENT_UNIT_BITCOINS) multiplyBy = "100000000";
- BRWalletManager.getInstance(app).pay(addressHolder, new BigDecimal(amountHolder).multiply(new BigDecimal(multiplyBy)), null, false);
- }
- }
- });
- pay.setFilterTouchesWhenObscured(true);
- viewFlipper.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (BRAnimator.scanResultFragmentOn)
- return;
-
- if (MiddleViewAdapter.getSyncing() && BRAnimator.level == 0) {
- hideAllBubbles();
- if (middleBubbleBlocksCount == 0) {
- middleBubbleBlocksCount = 1;
- middleBubbleBlocks.setVisibility(View.VISIBLE);
- SpringAnimator.showBubbleAnimation(middleBubbleBlocks);
- if (toastUpdater != null) {
- toastUpdater.interrupt();
- }
- toastUpdater = null;
- toastUpdater = new ToastUpdater();
- toastUpdater.start();
- } else {
- middleBubbleBlocksCount = 0;
- middleBubbleBlocks.setVisibility(View.GONE);
- }
- return;
- }
- if (BRAnimator.level == 0 && BreadWalletApp.unlocked) {
- hideAllBubbles();
- if (middleViewState == 0) {
- middleBubble2.setVisibility(View.GONE);
- middleBubble1.setVisibility(View.VISIBLE);
- SpringAnimator.showBubbleAnimation(middleBubble1);
- middleViewState++;
- } else if (middleViewState == 1) {
- middleBubble2.setVisibility(View.VISIBLE);
- SpringAnimator.showBubbleAnimation(middleBubble2);
- middleBubble1.setVisibility(View.GONE);
- middleViewState++;
- } else {
- hideAllBubbles();
- middleViewState = 0;
- }
-
- }
- }
- });
-
- burgerButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- hideAllBubbles();
- SpringAnimator.showAnimation(burgerButton);
- if (BRAnimator.level > 1 || BRAnimator.scanResultFragmentOn || BRAnimator.decoderFragmentOn) {
- onBackPressed();
- } else {
- //check multi pressing availability here, because method onBackPressed does the checking as well.
- if (BRAnimator.checkTheMultipressingAvailability()) {
- BRAnimator.pressMenuButton(app);
- }
- }
- }
- });
- lockerButton.setOnClickListener(new View.OnClickListener() {
- @TargetApi(Build.VERSION_CODES.LOLLIPOP)
- @Override
- public void onClick(View v) {
- hideAllBubbles();
- if (BRAnimator.checkTheMultipressingAvailability()) {
- SpringAnimator.showAnimation(lockerButton);
- if (!KeyStoreManager.getPassCode(app).isEmpty())
- ((BreadWalletApp) getApplication()).promptForAuthentication(app,
- BRConstants.AUTH_FOR_GENERAL, null, null, null, null, false);
- }
-
- }
- });
- networkErrorBar.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- view.setVisibility(View.GONE);
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- BRPeerManager.getInstance(app).refreshConnection();
- }
- }, 400);
-
- }
- });
- }
-
- private void checkDeviceRooted() {
- final boolean hasBitcoin = CurrencyManager.getInstance(this).getBALANCE() > 0;
- boolean isDebuggable = 0 != (getApplicationInfo().flags &= ApplicationInfo.FLAG_DEBUGGABLE);
- if (RootHelper.isDeviceRooted() && !isDebuggable) {
-
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- if (app == null) return;
- AlertDialog.Builder builder = new AlertDialog.Builder(app);
- builder.setTitle(R.string.device_security_compromised)
- .setMessage(String.format(getString(R.string.rooted_message),
- hasBitcoin ? getString(R.string.rooted_message_holder1) : ""))
- .setCancelable(false)
- .setNegativeButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- dialog.cancel();
- }
- });
- AlertDialog alert = builder.create();
- if (app != null && !app.isDestroyed())
- alert.show();
- }
- }, 10000);
-
- }
- }
-
- @Override
- protected void onRestart() {
- super.onRestart();
- app = this;
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- Log.e(TAG, "onResume");
- appInBackground = false;
- middleViewState = 0;
- middleBubbleBlocksCount = 0;
- app = this;
- final BRWalletManager m = BRWalletManager.getInstance(this);
- CurrencyManager currencyManager = CurrencyManager.getInstance(this);
- currencyManager.startTimer();
- currencyManager.deleteObservers();
- currencyManager.addObserver(this);
- MiddleViewAdapter.resetMiddleView(this, null);
- final boolean isNetworkAvailable = ((BreadWalletApp) getApplication()).hasInternetAccess();
- networkErrorBar.setVisibility(isNetworkAvailable ? View.GONE : View.VISIBLE);
-
- lockerButton.setVisibility(BreadWalletApp.unlocked ? View.INVISIBLE : View.VISIBLE);
- startStopReceiver(true);
- BRPeerManager.getInstance(app).refreshConnection();
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- BRWalletManager.getInstance(app).askForPasscode();
- }
- }, 1000);
- if (!m.isPasscodeEnabled(this)) {
- //Device passcode/password should be enabled for the app to work
- ((BreadWalletApp) getApplication()).showDeviceNotSecuredWarning(this);
- }
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- if (SharedPreferencesManager.getPhraseWroteDown(app)) return;
- long balance = CurrencyManager.getInstance(app).getBALANCE();
- long limit = SharedPreferencesManager.getLimit(app);
- Log.e(TAG, "balance: " + balance);
- Log.e(TAG, "limit: " + limit);
- if (balance > limit)
- BRWalletManager.getInstance(app).animateSavePhraseFlow();
- }
- }, 4000);
- BRWalletManager.refreshAddress();
- checkUnlockedTooLong();
-
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- appInBackground = true;
- startStopReceiver(false);
- }
-
- @Override
- protected void onStop() {
- super.onStop();
- CurrencyManager.getInstance(this).stopTimerTask();
-
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- finish();
- BRAnimator.level = 0;
- CurrencyManager.getInstance(this).stopTimerTask();
-// Log.e(TAG, "Activity Destroyed!");
- unregisterScreenLockReceiver();
-
- }
-
- /**
- * Initializes all the views and components
- */
-
- private void initializeViews() {
- pay = (TextView) findViewById(R.id.main_button_pay);
- networkErrorBar = (RelativeLayout) findViewById(R.id.main_internet_status_bar);
- burgerButton = (Button) findViewById(R.id.main_button_burger);
- lockerPayFlipper = (ViewFlipper) findViewById(R.id.locker_pay_flipper);
- viewFlipper = (ViewFlipper) MainActivity.app.findViewById(R.id.middle_view_flipper);
- lockerButton = (Button) findViewById(R.id.main_button_locker);
- pageIndicator = (RelativeLayout) findViewById(R.id.main_pager_indicator);
- pageIndicatorLeft = (ImageView) findViewById(R.id.circle_indicator_left);
- syncProgressBar = (ProgressBar) findViewById(R.id.sync_progress_bar);
- syncProgressText = (TextView) findViewById(R.id.sync_progress_text);
- pageIndicatorRight = (ImageView) findViewById(R.id.circle_indicator_right);
- pageIndicatorLeft.setImageResource(R.drawable.circle_indicator);
- pageIndicatorRight.setImageResource(R.drawable.circle_indicator);
- CustomPagerAdapter pagerAdapter = new CustomPagerAdapter(getFragmentManager());
- burgerButtonMap = new HashMap<>();
- parallaxViewPager = ((ParallaxViewPager) findViewById(R.id.main_viewpager));
- parallaxViewPager.setOverlapPercentage(0.99f).setAdapter(pagerAdapter);
- parallaxViewPager.setBackgroundResource(R.drawable.backgroundmain);
- burgerButtonMap.put("burger", R.drawable.burger);
- burgerButtonMap.put("close", R.drawable.x);
- burgerButtonMap.put("back", R.drawable.navigationback);
- middleBubble1 = (BubbleTextView) findViewById(R.id.middle_bubble_tip1);
- middleBubble2 = (BubbleTextView) findViewById(R.id.middle_bubble_tip2);
- middleBubble2.setText(String.format(getString(R.string.middle_view_tip_second),
- BRConstants.bitcoinLowercase, BRConstants.bitcoinLowercase + "1,000,000"));
-
- middleBubbleBlocks = (BubbleTextView) findViewById(R.id.middle_bubble_blocks);
- qrBubble1 = (BubbleTextView) findViewById(R.id.qr_bubble1);
- qrBubble2 = (BubbleTextView) findViewById(R.id.qr_bubble2);
- }
-
- //check if the user hasn't used the passcode in 2 weeks or more and ask for it
- private void checkUnlockedTooLong() {
- String pass = KeyStoreManager.getPassCode(this);
- long passTime = KeyStoreManager.getLastPasscodeUsedTime(this);
- if (pass.length() == 4 && (passTime + BRConstants.PASS_CODE_TIME_LIMIT <= System.currentTimeMillis())) {
- ((BreadWalletApp) getApplication()).promptForAuthentication(this, BRConstants.AUTH_FOR_GENERAL, null, null, null, null, true);
- }
- }
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_MENU) {
- if (BRAnimator.level > 1 || BRAnimator.scanResultFragmentOn || BRAnimator.decoderFragmentOn) {
- this.onBackPressed();
- } else if (BRAnimator.checkTheMultipressingAvailability()) {
- BRAnimator.pressMenuButton(app);
- }
- }
- // let the system handle all other key events
- return super.onKeyDown(keyCode, event);
- }
-
- @Override
- public void onBackPressed() {
- if (BRAnimator.checkTheMultipressingAvailability()) {
- Log.e(TAG, "onBackPressed!");
- if (BRAnimator.wipeWalletOpen) {
- BRAnimator.pressWipeWallet(this, new FragmentSettings());
- activityButtonsEnable(true);
- return;
- }
- //switch the level of fragments creation.
- switch (BRAnimator.level) {
- case 0:
- if (BRAnimator.decoderFragmentOn) {
- BRAnimator.hideDecoderFragment();
- break;
- }
- if (BRAnimator.scanResultFragmentOn) {
- BRAnimator.hideScanResultFragment();
- break;
- }
- super.onBackPressed();
- break;
- case 1:
- BRAnimator.pressMenuButton(this);
- BRAnimator.hideDecoderFragment();
- break;
- default:
- BRAnimator.animateSlideToRight(this);
- break;
- }
- }
- }
-
- /**
- * Sets the little circle indicator to the selected page
- *
- * @patam x The page for the indicator to be shown
- */
-
- public void setPagerIndicator(int x) {
- if (x == 0) {
-// Log.d(TAG, "Left Indicator changed");
- BRAnimator.scaleView(pageIndicatorLeft, 1f, BRConstants.PAGE_INDICATOR_SCALE_UP, 1f, BRConstants.PAGE_INDICATOR_SCALE_UP);
- BRAnimator.scaleView(pageIndicatorRight, BRConstants.PAGE_INDICATOR_SCALE_UP, 1f, BRConstants.PAGE_INDICATOR_SCALE_UP, 1f);
- } else if (x == 1) {
-// Log.d(TAG, "Right Indicator changed");
- BRAnimator.scaleView(pageIndicatorRight, 1f, BRConstants.PAGE_INDICATOR_SCALE_UP, 1f, BRConstants.PAGE_INDICATOR_SCALE_UP);
- BRAnimator.scaleView(pageIndicatorLeft, BRConstants.PAGE_INDICATOR_SCALE_UP, 1f, BRConstants.PAGE_INDICATOR_SCALE_UP, 1f);
- } else {
- Log.e(TAG, "Something went wrong setting the circle pageIndicator");
- }
- }
-
- public void setBurgerButtonImage(int x) {
- String item = null;
- switch (x) {
- case 0:
- item = "burger";
- break;
- case 1:
- item = "close";
- break;
- case 2:
- item = "back";
- break;
- }
- if (item != null && item.length() > 0)
- burgerButton.setBackgroundResource(burgerButtonMap.get(item));
- }
-
- public void activityButtonsEnable(final boolean b) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- if (!BreadWalletApp.unlocked) {
- lockerButton.setVisibility(b ? View.VISIBLE : View.INVISIBLE);
- lockerButton.setClickable(b);
- } else {
- lockerButton.setVisibility(View.INVISIBLE);
- lockerButton.setClickable(false);
- }
- parallaxViewPager.setClickable(b);
- viewFlipper.setVisibility(b ? View.VISIBLE : View.INVISIBLE);
- burgerButton.setVisibility(b ? View.VISIBLE : View.INVISIBLE);
- burgerButton.setClickable(b);
- }
- });
-
- }
-
- private void startStopReceiver(boolean b) {
- if (b) {
- this.registerReceiver(receiver, new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE"));
- } else {
- this.unregisterReceiver(receiver);
- }
- }
-
- public void request(View view) {
- SpringAnimator.showAnimation(view);
- Intent intent;
- String tempAmount = FragmentScanResult.instance.getBitcoinValue().value;
- BRWalletManager m = BRWalletManager.getInstance(this);
- int unit = BRConstants.CURRENT_UNIT_BITS;
- Activity context = MainActivity.app;
- String divideBy = "100";
- if (context != null)
- unit = SharedPreferencesManager.getCurrencyUnit(context);
- if (unit == BRConstants.CURRENT_UNIT_MBITS) divideBy = "100000";
- if (unit == BRConstants.CURRENT_UNIT_BITCOINS) divideBy = "100000000";
- long minAmount = m.getMinOutputAmount();
- if (new BigDecimal(tempAmount).multiply(new BigDecimal(divideBy)).doubleValue() < minAmount) {
- String placeHolder = BRConstants.bitcoinLowercase + new BigDecimal(minAmount).divide(new BigDecimal(divideBy)).toString();
- final String bitcoinMinMessage = String.format(Locale.getDefault(), getString(R.string.bitcoin_payment_cant_be_less), placeHolder);
- ((BreadWalletApp) getApplication()).showCustomDialog(getString(R.string.amount_too_small),
- bitcoinMinMessage, getString(R.string.ok));
- return;
- }
- String divideByForIntent = "1000000";
- if (unit == BRConstants.CURRENT_UNIT_MBITS) divideByForIntent = "1000";
- if (unit == BRConstants.CURRENT_UNIT_BITCOINS) divideByForIntent = "1";
- String strAmount = String.valueOf(new BigDecimal(tempAmount).divide(new BigDecimal(divideByForIntent)).toString());
- String address = SharedPreferencesManager.getReceiveAddress(this);
- intent = new Intent(this, RequestQRActivity.class);
- intent.putExtra(BRConstants.INTENT_EXTRA_REQUEST_AMOUNT, strAmount);
- intent.putExtra(BRConstants.INTENT_EXTRA_REQUEST_ADDRESS, address);
- startActivity(intent);
- overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
- BRAnimator.hideScanResultFragment();
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- switch (requestCode) {
- case BRConstants.PAY_REQUEST_CODE:
- if (resultCode == RESULT_OK) {
- PostAuthenticationProcessor.getInstance().onPublishTxAuth(this);
- }
- break;
- case BRConstants.PAYMENT_PROTOCOL_REQUEST_CODE:
- if (resultCode == RESULT_OK) {
- PostAuthenticationProcessor.getInstance().onPaymentProtocolRequest(this);
- }
- break;
-
- }
- }
-
- @Override
- public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
- switch (requestCode) {
- case BRConstants.CAMERA_REQUEST_ID: {
- // If request is cancelled, the result arrays are empty.
- if (grantResults.length > 0
- && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
- BRAnimator.animateDecoderFragment();
-
- }
- return;
- }
- }
- super.onRequestPermissionsResult(requestCode, permissions, grantResults);
-
- }
-
- public boolean isSoftKeyboardShown() {
- int[] location = new int[2];
- viewFlipper.getLocationOnScreen(location);
- return location[1] < 0;
- }
-
-
- @Override
- public void update(Observable observable, Object data) {
- MiddleViewAdapter.resetMiddleView(this, null);
- }
-
-
- private void registerScreenLockReceiver() {
- final IntentFilter theFilter = new IntentFilter();
- /** System Defined Broadcast */
- theFilter.addAction(Intent.ACTION_SCREEN_ON);
- theFilter.addAction(Intent.ACTION_SCREEN_OFF);
-
- mPowerKeyReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String strAction = intent.getAction();
-
- if (strAction.equals(Intent.ACTION_SCREEN_OFF)) {
- ((BreadWalletApp) getApplicationContext()).setUnlocked(false);
- }
- }
- };
-
- getApplicationContext().registerReceiver(mPowerKeyReceiver, theFilter);
- }
-
- private void unregisterScreenLockReceiver() {
-
- try {
- getApplicationContext().unregisterReceiver(mPowerKeyReceiver);
- } catch (IllegalArgumentException e) {
- mPowerKeyReceiver = null;
- }
- }
-
- public void hideAllBubbles() {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- BRAnimator.fadeScaleBubble(middleBubble1, middleBubble2, middleBubbleBlocks,
- qrBubble2, qrBubble1, sendBubble1, sendBubble2);
- }
- });
- }
-
- public void showHideSyncProgressViews(boolean b) {
- if (syncProgressBar == null || syncProgressText == null) return;
- syncProgressBar.setVisibility(b ? View.VISIBLE : View.GONE);
- syncProgressText.setVisibility(b ? View.VISIBLE : View.GONE);
- }
-
- public class ToastUpdater extends Thread {
- public void run() {
- while (middleBubbleBlocks.getVisibility() == View.VISIBLE) {
- final int latestBlockKnown = BRPeerManager.getEstimatedBlockHeight();
- android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
- final int currBlock = BRPeerManager.getCurrentBlockHeight();
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- String formattedBlockInfo = String.format(getString(R.string.blocks), currBlock, latestBlockKnown);
- middleBubbleBlocks.setText(formattedBlockInfo);
- }
- });
- try {
- Thread.sleep(500);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
-
- public void setProgress(int progress, String progressText) {
- if (syncProgressBar == null || syncProgressText == null) return;
- syncProgressBar.setProgress(progress);
- syncProgressText.setText(progressText);
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/PaperKeyActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/PaperKeyActivity.java
new file mode 100644
index 000000000..87d12b0e8
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/activities/PaperKeyActivity.java
@@ -0,0 +1,217 @@
+package com.breadwallet.presenter.activities;
+
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.content.res.Resources;
+import android.os.Bundle;
+import androidx.legacy.app.FragmentPagerAdapter;
+import androidx.viewpager.widget.ViewPager;
+import android.util.SparseArray;
+import android.util.TypedValue;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.ImageButton;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.util.BRActivity;
+import com.breadwallet.presenter.customviews.BRDialogView;
+import com.breadwallet.presenter.fragments.FragmentPhraseWord;
+import com.breadwallet.tools.animation.BRAnimator;
+import com.breadwallet.tools.animation.BRDialog;
+import com.breadwallet.tools.security.PostAuth;
+import com.breadwallet.tools.util.Utils;
+
+import java.util.Locale;
+
+import timber.log.Timber;
+
+
+public class PaperKeyActivity extends BRActivity {
+ private static final String TAG = PaperKeyActivity.class.getName();
+ private ViewPager wordViewPager;
+ private Button nextButton;
+ private Button previousButton;
+ private LinearLayout buttonsLayout;
+ private TextView itemIndexText;
+ private SparseArray wordMap;
+ public static boolean appVisible = false;
+ private static PaperKeyActivity app;
+ private ImageButton close;
+
+ public static PaperKeyActivity getApp() {
+ return app;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_paper_key);
+ getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
+
+ wordViewPager = (ViewPager) findViewById(R.id.phrase_words_pager);
+ wordViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
+ public void onPageScrollStateChanged(int state) {
+
+ }
+
+ public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+
+ }
+
+ public void onPageSelected(int position) {
+ if (position == 0)
+ setButtonEnabled(false);
+ else
+ setButtonEnabled(true);
+ updateItemIndexText();
+ }
+ });
+
+ nextButton = (Button) findViewById(R.id.send_button);
+ previousButton = (Button) findViewById(R.id.button_previous);
+ close = (ImageButton) findViewById(R.id.close_button);
+ itemIndexText = (TextView) findViewById(R.id.item_index_text);
+ buttonsLayout = (LinearLayout) findViewById(R.id.buttons_layout);
+
+ nextButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ updateWordView(true);
+ }
+ });
+
+ close.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (!BRAnimator.isClickAllowed()) return;
+ BRAnimator.startBreadActivity(PaperKeyActivity.this, false);
+ if (!isDestroyed()) finish();
+ }
+ });
+ previousButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ updateWordView(false);
+
+ }
+ });
+ String cleanPhrase = getIntent().getExtras() == null ? null : getIntent().getStringExtra("phrase");
+ wordMap = new SparseArray<>();
+
+ if (Utils.isNullOrEmpty(cleanPhrase)) {
+ throw new RuntimeException(TAG + ": cleanPhrase is null");
+ }
+
+ String wordArray[] = cleanPhrase.split(" ");
+
+ if (cleanPhrase.charAt(cleanPhrase.length() - 1) == '\0') {
+ BRDialog.showCustomDialog(this, getString(R.string.JailbreakWarnings_title),
+ getString(R.string.Alert_keystore_generic_android), getString(R.string.Button_ok), null, new BRDialogView.BROnClickListener() {
+ @Override
+ public void onClick(BRDialogView brDialogView) {
+ brDialogView.dismissWithAnimation();
+ }
+ }, null, null, 0);
+ IllegalArgumentException ex = new IllegalArgumentException("Paper Key error, please contact support at contact@loafwallet.org: " + wordArray.length);
+ Timber.e(ex);
+ throw ex;
+ } else {
+ if (wordArray.length != 12) {
+ IllegalArgumentException ex = new IllegalArgumentException("Wrong number of paper keys: " + wordArray.length + ", lang: " + Locale.getDefault().getLanguage());
+ Timber.e(ex);
+ throw ex;
+ }
+ WordPagerAdapter adapter = new WordPagerAdapter(getFragmentManager());
+ adapter.setWords(wordArray);
+ wordViewPager.setAdapter(adapter);
+ for (int i = 0; i < wordArray.length; i++) {
+ wordMap.append(i, wordArray[i]);
+ }
+ updateItemIndexText();
+ }
+ }
+
+ private void updateWordView(boolean isNext) {
+ int currentIndex = wordViewPager.getCurrentItem();
+ if (isNext) {
+ setButtonEnabled(true);
+ if (currentIndex >= 11) {
+ PostAuth.getInstance().onPhraseProveAuth(this, false);
+ } else {
+ wordViewPager.setCurrentItem(currentIndex + 1);
+ }
+ } else {
+ if (currentIndex <= 1) {
+ wordViewPager.setCurrentItem(currentIndex - 1);
+ setButtonEnabled(false);
+ } else {
+ wordViewPager.setCurrentItem(currentIndex - 1);
+ }
+ }
+ }
+
+ private void setButtonEnabled(boolean b) {
+ previousButton.setTextColor(getColor(b ? R.color.light_gray : R.color.extra_light_gray));
+ Resources r = getResources();
+ float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, b ? 8 : 0, r.getDisplayMetrics());
+ previousButton.setElevation(px);
+ previousButton.setEnabled(b);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ appVisible = true;
+ app = this;
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ appVisible = false;
+ }
+
+ private void updateItemIndexText() {
+ String text = String.format(Locale.getDefault(), getString(R.string.WritePaperPhrase_step), wordViewPager.getCurrentItem() + 1, wordMap.size());
+ itemIndexText.setText(text);
+ }
+
+
+ @Override
+ public void onBackPressed() {
+ super.onBackPressed();
+ overridePendingTransition(R.anim.enter_from_right, R.anim.exit_to_left);
+ }
+
+ private class WordPagerAdapter extends FragmentPagerAdapter {
+
+ private String[] words;
+
+ public WordPagerAdapter(FragmentManager fm) {
+ super(fm);
+ }
+
+ public void setWords(String[] words) {
+ this.words = words;
+ }
+
+ @Override
+ public Fragment getItem(int pos) {
+ return FragmentPhraseWord.newInstance(words[pos]);
+ }
+
+ @Override
+ public int getCount() {
+ return words == null ? 0 : words.length;
+ }
+
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/PaperKeyProveActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/PaperKeyProveActivity.java
new file mode 100644
index 000000000..ff11d6df3
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/activities/PaperKeyProveActivity.java
@@ -0,0 +1,266 @@
+package com.breadwallet.presenter.activities;
+
+import android.os.Bundle;
+import android.os.Handler;
+import androidx.constraintlayout.widget.ConstraintLayout;
+import androidx.constraintlayout.widget.ConstraintSet;
+import androidx.transition.TransitionManager;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.util.SparseArray;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.inputmethod.EditorInfo;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.util.BRActivity;
+import com.breadwallet.presenter.customviews.BRDialogView;
+import com.breadwallet.presenter.interfaces.BROnSignalCompletion;
+import com.breadwallet.tools.animation.BRAnimator;
+import com.breadwallet.tools.animation.BRDialog;
+import com.breadwallet.tools.animation.SpringAnimator;
+import com.breadwallet.tools.manager.BRSharedPrefs;
+import com.breadwallet.tools.security.SmartValidator;
+import com.breadwallet.tools.util.Utils;
+import com.breadwallet.tools.util.Bip39Reader;
+import java.util.Locale;
+import java.util.Random;
+
+import timber.log.Timber;
+
+
+public class PaperKeyProveActivity extends BRActivity {
+ private static final String TAG = PaperKeyProveActivity.class.getName();
+ private Button submit;
+ private EditText wordEditFirst;
+ private EditText wordEditSecond;
+ private TextView wordTextFirst;
+ private TextView wordTextSecond;
+ private ImageView checkMark1;
+ private ImageView checkMark2;
+ private SparseArray sparseArrayWords = new SparseArray<>();
+ public static boolean appVisible = false;
+ private static PaperKeyProveActivity app;
+ private ConstraintLayout constraintLayout;
+ private ConstraintSet applyConstraintSet = new ConstraintSet();
+ private ConstraintSet resetConstraintSet = new ConstraintSet();
+
+ public static PaperKeyProveActivity getApp() {
+ return app;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_paper_key_prove);
+ getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
+
+ submit = (Button) findViewById(R.id.button_submit);
+ wordEditFirst = (EditText) findViewById(R.id.word_edittext_first);
+ wordEditSecond = (EditText) findViewById(R.id.word_edittext_second);
+ wordTextFirst = (TextView) findViewById(R.id.word_number_first);
+ wordTextSecond = (TextView) findViewById(R.id.word_number_second);
+
+ checkMark1 = (ImageView) findViewById(R.id.check_mark_1);
+ checkMark2 = (ImageView) findViewById(R.id.check_mark_2);
+
+// wordEditFirst.setOnFocusChangeListener(new FocusListener());
+// wordEditSecond.setOnFocusChangeListener(new FocusListener());
+
+ wordEditFirst.addTextChangedListener(new BRTextWatcher());
+ wordEditSecond.addTextChangedListener(new BRTextWatcher());
+
+ constraintLayout = (ConstraintLayout) findViewById(R.id.constraintLayout);
+ resetConstraintSet.clone(constraintLayout);
+ applyConstraintSet.clone(constraintLayout);
+
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+
+ TransitionManager.beginDelayedTransition(constraintLayout);
+ applyConstraintSet.setMargin(R.id.word_number_first, ConstraintSet.TOP, 8);
+ applyConstraintSet.setMargin(R.id.line1, ConstraintSet.TOP, 16);
+ applyConstraintSet.setMargin(R.id.line2, ConstraintSet.TOP, 16);
+ applyConstraintSet.setMargin(R.id.word_number_second, ConstraintSet.TOP, 8);
+ applyConstraintSet.applyTo(constraintLayout);
+
+
+ }
+ }, 500);
+
+ wordEditSecond.setOnEditorActionListener(new TextView.OnEditorActionListener() {
+ @Override
+ public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {
+ if (id == R.id.button_submit || id == EditorInfo.IME_NULL) {
+ submit.performClick();
+ return true;
+ }
+ return false;
+ }
+ });
+
+ submit.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (!BRAnimator.isClickAllowed()) return;
+
+ if (isWordCorrect(true) && isWordCorrect(false)) {
+ Utils.hideKeyboard(PaperKeyProveActivity.this);
+ BRSharedPrefs.putPhraseWroteDown(PaperKeyProveActivity.this, true);
+ BRAnimator.showBreadSignal(PaperKeyProveActivity.this, getString(R.string.Alerts_paperKeySet), getString(R.string.Alerts_paperKeySetSubheader), R.drawable.ic_check_mark_white, new BROnSignalCompletion() {
+ @Override
+ public void onComplete() {
+ BRAnimator.startBreadActivity(PaperKeyProveActivity.this, false);
+ overridePendingTransition(R.anim.enter_from_right, R.anim.exit_to_left);
+ finishAffinity();
+ }
+ });
+ } else {
+
+ if (!isWordCorrect(true)) {
+ wordEditFirst.setTextColor(getColor(R.color.red_text));
+ SpringAnimator.failShakeAnimation(PaperKeyProveActivity.this, wordEditFirst);
+ }
+
+ if (!isWordCorrect(false)) {
+ wordEditSecond.setTextColor(getColor(R.color.red_text));
+ SpringAnimator.failShakeAnimation(PaperKeyProveActivity.this, wordEditSecond);
+ }
+ }
+
+ }
+ });
+ String cleanPhrase = null;
+
+ cleanPhrase = getIntent().getExtras() == null ? null : getIntent().getStringExtra("phrase");
+
+ if (Utils.isNullOrEmpty(cleanPhrase)) {
+ throw new RuntimeException(TAG + ": cleanPhrase is null");
+ }
+
+ String wordArray[] = cleanPhrase.split(" ");
+
+ if (wordArray.length == 12 && cleanPhrase.charAt(cleanPhrase.length() - 1) == '\0') {
+ BRDialog.showCustomDialog(this, getString(R.string.JailbreakWarnings_title),
+ getString(R.string.Alert_keystore_generic_android), getString(R.string.Button_ok), null, new BRDialogView.BROnClickListener() {
+ @Override
+ public void onClick(BRDialogView brDialogView) {
+ brDialogView.dismissWithAnimation();
+ }
+ }, null, null, 0);
+ Timber.e(new IllegalArgumentException("Paper Key error. Problem with OS Keystore"));
+ } else {
+ randomWordsSetUp(wordArray);
+ }
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ appVisible = true;
+ app = this;
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ appVisible = false;
+ }
+
+ @Override
+ public void onBackPressed() {
+ super.onBackPressed();
+ overridePendingTransition(R.anim.enter_from_left, R.anim.exit_to_right);
+ }
+
+ private void randomWordsSetUp(String[] words) {
+ final Random random = new Random();
+ int n = random.nextInt(10) + 1;
+
+ sparseArrayWords.append(n, words[n]);
+
+ while (sparseArrayWords.get(n) != null) {
+ n = random.nextInt(10) + 1;
+ }
+
+ sparseArrayWords.append(n, words[n]);
+
+ wordTextFirst.setText(String.format(Locale.getDefault(), getString(R.string.ConfirmPaperPhrase_word), (sparseArrayWords.keyAt(0) + 1)));
+ wordTextSecond.setText(String.format(Locale.getDefault(), getString(R.string.ConfirmPaperPhrase_word), (sparseArrayWords.keyAt(1) + 1)));
+
+ }
+
+ private boolean isWordCorrect(boolean first) {
+ if (first) {
+ String edit = Bip39Reader.cleanWord(wordEditFirst.getText().toString());
+ return SmartValidator.isWordValid(PaperKeyProveActivity.this, edit) && edit.equalsIgnoreCase(sparseArrayWords.get(sparseArrayWords.keyAt(0)));
+ } else {
+ String edit = Bip39Reader.cleanWord(wordEditSecond.getText().toString());
+ return SmartValidator.isWordValid(PaperKeyProveActivity.this, edit) && edit.equalsIgnoreCase(sparseArrayWords.get(sparseArrayWords.keyAt(1)));
+ }
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ }
+
+// private class FocusListener implements View.OnFocusChangeListener {
+//
+// @Override
+// public void onFocusChange(View v, boolean hasFocus) {
+// if (!hasFocus) {
+// validateWord((EditText) v);
+// } else {
+// ((EditText) v).setTextColor(getColor(R.color.light_gray));
+// }
+// }
+// }
+
+ private void validateWord(EditText view) {
+ String word = view.getText().toString();
+ boolean valid = SmartValidator.isWordValid(this, word);
+ view.setTextColor(getColor(valid ? R.color.light_gray : R.color.red_text));
+// if (!valid)
+// SpringAnimator.failShakeAnimation(this, view);
+ if (isWordCorrect(true)) {
+ checkMark1.setVisibility(View.VISIBLE);
+ } else {
+ checkMark1.setVisibility(View.INVISIBLE);
+ }
+
+ if (isWordCorrect(false)) {
+ checkMark2.setVisibility(View.VISIBLE);
+ } else {
+ checkMark2.setVisibility(View.INVISIBLE);
+ }
+ }
+
+ private class BRTextWatcher implements TextWatcher {
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ validateWord(wordEditFirst);
+ validateWord(wordEditSecond);
+
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+
+ }
+ }
+
+
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/PhraseFlowActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/PhraseFlowActivity.java
deleted file mode 100644
index cafa3c2ac..000000000
--- a/app/src/main/java/com/breadwallet/presenter/activities/PhraseFlowActivity.java
+++ /dev/null
@@ -1,219 +0,0 @@
-package com.breadwallet.presenter.activities;
-
-import android.app.Activity;
-import android.app.Fragment;
-import android.app.FragmentManager;
-import android.app.FragmentTransaction;
-import android.content.Intent;
-import android.graphics.Point;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.View;
-import android.view.Window;
-import android.view.WindowManager;
-import android.view.animation.Animation;
-import android.view.animation.TranslateAnimation;
-import android.widget.Button;
-
-import com.breadwallet.R;
-import com.breadwallet.presenter.fragments.FragmentPhraseFlow1;
-import com.breadwallet.presenter.fragments.FragmentPhraseFlow2;
-import com.breadwallet.presenter.fragments.FragmentPhraseFlow3;
-import com.breadwallet.presenter.fragments.FragmentRecoveryPhrase;
-import com.breadwallet.presenter.fragments.IntroNewRecoverFragment;
-import com.breadwallet.presenter.fragments.IntroNewWalletFragment;
-import com.breadwallet.presenter.fragments.IntroWelcomeFragment;
-import com.breadwallet.tools.animation.BRAnimator;
-import com.breadwallet.tools.animation.DecelerateOvershootInterpolator;
-import com.breadwallet.tools.manager.CurrencyManager;
-import com.breadwallet.tools.manager.SharedPreferencesManager;
-import com.breadwallet.tools.security.PostAuthenticationProcessor;
-import com.breadwallet.tools.util.BRConstants;
-
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 8/20/16.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-
-public class PhraseFlowActivity extends Activity {
- public static final String TAG = PhraseFlowActivity.class.getName();
- public static Point screenParametersPoint = new Point();
- public FragmentPhraseFlow1 fragmentPhraseFlow1;
- public FragmentPhraseFlow2 fragmentPhraseFlow2;
- public FragmentPhraseFlow3 fragmentPhraseFlow3;
- public FragmentRecoveryPhrase fragmentRecoveryPhrase;
- public PhraseFlowActivity phraseFlowActivity;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_phrase_flow);
-
- getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,
- WindowManager.LayoutParams.FLAG_SECURE);
-
- Window window = getWindow();
- window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
- window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
- window.setStatusBarColor(getColor(R.color.status_bar));
-
- phraseFlowActivity = this;
-
- fragmentPhraseFlow1 = new FragmentPhraseFlow1();
- fragmentPhraseFlow2 = new FragmentPhraseFlow2();
- fragmentPhraseFlow3 = new FragmentPhraseFlow3();
- fragmentRecoveryPhrase = new FragmentRecoveryPhrase();
- int layoutID = R.id.main_layout;
-
- FragmentManager fragmentManager = getFragmentManager();
- FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
-
- fragmentTransaction.add(layoutID, fragmentPhraseFlow1,
- IntroWelcomeFragment.class.getName());
- fragmentTransaction.add(layoutID, fragmentPhraseFlow2,
- IntroNewRecoverFragment.class.getName());
- fragmentTransaction.add(layoutID, fragmentPhraseFlow3,
- IntroNewWalletFragment.class.getName());
- fragmentTransaction.add(layoutID, fragmentRecoveryPhrase,
- IntroNewWalletFragment.class.getName());
-
- showHideFragments();
- fragmentTransaction.commitAllowingStateLoss();
- PostAuthenticationProcessor.getInstance().onShowPhraseFlowAuth(phraseFlowActivity);
-
- }
-
- // direction == 1 -> RIGHT, direction == 2 -> LEFT
- public void animateSlide(final Fragment from, final Fragment to, int direction) {
- int screenWidth = screenParametersPoint.x;
- int screenHeigth = screenParametersPoint.y;
-
- showHideFragments(from, to);
- TranslateAnimation transFrom = direction == IntroActivity.RIGHT ?
- new TranslateAnimation(0, -screenWidth, 0, 0) : new TranslateAnimation(0, screenWidth, 0, 0);
- transFrom.setDuration(BRAnimator.horizontalSlideDuration);
- transFrom.setInterpolator(new DecelerateOvershootInterpolator(1f, 0.5f));
- View fromView = from.getView();
- if (fromView != null)
- fromView.startAnimation(transFrom);
- TranslateAnimation transTo = direction == IntroActivity.RIGHT ?
- new TranslateAnimation(screenWidth, 0, 0, 0) : new TranslateAnimation(-screenWidth, 0, 0, 0);
- transTo.setDuration(BRAnimator.horizontalSlideDuration);
- transTo.setInterpolator(new DecelerateOvershootInterpolator(1f, 0.5f));
- transTo.setAnimationListener(new Animation.AnimationListener() {
- @Override
- public void onAnimationStart(Animation animation) {
-
- }
-
- @Override
- public void onAnimationEnd(Animation animation) {
- showHideFragments(to);
- }
-
- @Override
- public void onAnimationRepeat(Animation animation) {
-
- }
- });
- View toView = to.getView();
- if (toView != null)
- toView.startAnimation(transTo);
- }
-
- public void showHideFragments(Fragment... fragments) {
- FragmentManager fragmentManager = getFragmentManager();
- FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
- fragmentTransaction.hide(fragmentPhraseFlow1);
- fragmentTransaction.hide(fragmentPhraseFlow2);
- fragmentTransaction.hide(fragmentPhraseFlow3);
- fragmentTransaction.hide(fragmentRecoveryPhrase);
- for (Fragment f : fragments) {
- fragmentTransaction.show(f);
- }
- fragmentTransaction.commitAllowingStateLoss();
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- switch (requestCode) {
- case BRConstants.SHOW_PHRASE_REQUEST_CODE:
- if (resultCode == RESULT_OK) {
- Log.e(TAG, "RESULT_OK");
- PostAuthenticationProcessor.getInstance().onShowPhraseFlowAuth(this);
- } else {
- Log.e(TAG, "NOT RESULT_OK NOT");
- onBackPressed();
- }
- break;
-
- }
- }
-
- @Override
- public void onBackPressed() {
- if (fragmentPhraseFlow3 != null && fragmentPhraseFlow3.isVisible()) {
- animateSlide(fragmentPhraseFlow3, fragmentPhraseFlow2, IntroActivity.LEFT);
- fragmentPhraseFlow2.setPhrase(fragmentPhraseFlow3.getPhrase());
- } else {
- if (CurrencyManager.getInstance(this).getBALANCE() > SharedPreferencesManager.getLimit(this)
- && !SharedPreferencesManager.getPhraseWroteDown(this)) {
- super.onBackPressed();
- } else {
- Intent intent;
- intent = new Intent(this, MainActivity.class);
- startActivity(intent);
- if (!isDestroyed()) {
- finish();
- }
- }
- }
-
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- releasePhrase();
-
- }
-
- private void releasePhrase() {
- fragmentPhraseFlow1.releasePhrase();
- fragmentPhraseFlow3.releasePhrase();
- fragmentRecoveryPhrase.releasePhrase();
- }
-
- @Override
- protected void onPause() {
- super.onPause();
-// Intent intent;
-// intent = new Intent(this, MainActivity.class);
-// startActivity(intent);
-// if (!isDestroyed()) {
-// finish();
-// }
- }
-}
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/ReEnterPinActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/ReEnterPinActivity.java
new file mode 100644
index 000000000..a3ceadf97
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/activities/ReEnterPinActivity.java
@@ -0,0 +1,184 @@
+package com.breadwallet.presenter.activities;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.util.BRActivity;
+import com.breadwallet.presenter.customviews.BRKeyboard;
+import com.breadwallet.presenter.interfaces.BROnSignalCompletion;
+import com.breadwallet.tools.animation.BRAnimator;
+import com.breadwallet.tools.animation.SpringAnimator;
+import com.breadwallet.tools.security.AuthManager;
+import com.breadwallet.tools.security.PostAuth;
+import com.breadwallet.tools.util.Utils;
+
+import timber.log.Timber;
+
+public class ReEnterPinActivity extends BRActivity {
+ private BRKeyboard keyboard;
+ public static ReEnterPinActivity reEnterPinActivity;
+ private View dot1;
+ private View dot2;
+ private View dot3;
+ private View dot4;
+ private View dot5;
+ private View dot6;
+ private StringBuilder pin = new StringBuilder();
+ private TextView title;
+ private int pinLimit = 6;
+ private String firstPIN;
+ private boolean isPressAllowed = true;
+ private LinearLayout pinLayout;
+ public static boolean appVisible = false;
+ private static ReEnterPinActivity app;
+
+ public static ReEnterPinActivity getApp() {
+ return app;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_pin_template);
+
+ keyboard = (BRKeyboard) findViewById(R.id.brkeyboard);
+ pinLayout = (LinearLayout) findViewById(R.id.pinLayout);
+
+ ImageButton faq = (ImageButton) findViewById(R.id.faq_button);
+ //TODO: all views are using the layout of this button. Views should be refactored without it
+ // Hiding until layouts are built.
+
+ title = (TextView) findViewById(R.id.title);
+ title.setText(getString(R.string.UpdatePin_createTitleConfirm));
+ firstPIN = getIntent().getExtras().getString("pin");
+ if (Utils.isNullOrEmpty(firstPIN)) {
+ throw new RuntimeException("first PIN is required");
+ }
+ reEnterPinActivity = this;
+
+ dot1 = findViewById(R.id.dot1);
+ dot2 = findViewById(R.id.dot2);
+ dot3 = findViewById(R.id.dot3);
+ dot4 = findViewById(R.id.dot4);
+ dot5 = findViewById(R.id.dot5);
+ dot6 = findViewById(R.id.dot6);
+
+ keyboard.addOnInsertListener(new BRKeyboard.OnInsertListener() {
+ @Override
+ public void onClick(String key) {
+ handleClick(key);
+ }
+ });
+ keyboard.setShowDot(false);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ updateDots();
+ appVisible = true;
+ app = this;
+ isPressAllowed = true;
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ appVisible = false;
+ }
+
+ private void handleClick(String key) {
+ if (!isPressAllowed) return;
+ if (key == null) {
+ Timber.d("timber: handleClick: key is null! ");
+ return;
+ }
+
+ if (key.isEmpty()) {
+ handleDeleteClick();
+ } else if (Character.isDigit(key.charAt(0))) {
+ handleDigitClick(Integer.parseInt(key.substring(0, 1)));
+ } else {
+ Timber.d("timber: handleClick: oops: %s", key);
+ }
+ }
+
+
+ private void handleDigitClick(Integer dig) {
+ if (pin.length() < pinLimit)
+ pin.append(dig);
+ updateDots();
+ }
+
+ private void handleDeleteClick() {
+ if (pin.length() > 0)
+ pin.deleteCharAt(pin.length() - 1);
+ updateDots();
+ }
+
+ @Override
+ public void onBackPressed() {
+ super.onBackPressed();
+ overridePendingTransition(R.anim.enter_from_left, R.anim.exit_to_right);
+ }
+
+ private void updateDots() {
+ int selectedDots = pin.length();
+
+ dot1.setBackground(getDrawable(selectedDots <= 0 ? R.drawable.ic_pin_dot_gray : R.drawable.ic_pin_dot_black));
+ selectedDots--;
+ dot2.setBackground(getDrawable(selectedDots <= 0 ? R.drawable.ic_pin_dot_gray : R.drawable.ic_pin_dot_black));
+ selectedDots--;
+ dot3.setBackground(getDrawable(selectedDots <= 0 ? R.drawable.ic_pin_dot_gray : R.drawable.ic_pin_dot_black));
+ selectedDots--;
+ dot4.setBackground(getDrawable(selectedDots <= 0 ? R.drawable.ic_pin_dot_gray : R.drawable.ic_pin_dot_black));
+ selectedDots--;
+ dot5.setBackground(getDrawable(selectedDots <= 0 ? R.drawable.ic_pin_dot_gray : R.drawable.ic_pin_dot_black));
+ selectedDots--;
+ dot6.setBackground(getDrawable(selectedDots <= 0 ? R.drawable.ic_pin_dot_gray : R.drawable.ic_pin_dot_black));
+
+ if (pin.length() == 6) {
+ verifyPin();
+ }
+ }
+
+ private void verifyPin() {
+ if (firstPIN.equalsIgnoreCase(pin.toString())) {
+ AuthManager.getInstance().authSuccess(this);
+ isPressAllowed = false;
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ pin = new StringBuilder();
+ updateDots();
+ }
+ }, 200);
+ AuthManager.getInstance().setPinCode(pin.toString(), this);
+ if (getIntent().getBooleanExtra("noPin", false)) {
+ BRAnimator.startBreadActivity(this, false);
+ } else {
+ BRAnimator.showBreadSignal(this, getString(R.string.Alerts_pinSet), getString(R.string.UpdatePin_createInstruction), R.drawable.ic_check_mark_white, new BROnSignalCompletion() {
+ @Override
+ public void onComplete() {
+ PostAuth.getInstance().onCreateWalletAuth(ReEnterPinActivity.this, false);
+ }
+ });
+ }
+ } else {
+ AuthManager.getInstance().authFail(this);
+ Timber.d("timber: verifyPin: FAIL: firs: %s, reEnter: %s ", firstPIN, pin);
+ SpringAnimator.failShakeAnimation(this, pinLayout);
+ pin = new StringBuilder();
+ }
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/RequestQRActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/RequestQRActivity.java
deleted file mode 100644
index 51618b996..000000000
--- a/app/src/main/java/com/breadwallet/presenter/activities/RequestQRActivity.java
+++ /dev/null
@@ -1,131 +0,0 @@
-package com.breadwallet.presenter.activities;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.View;
-import android.view.WindowManager;
-import android.widget.Button;
-import android.widget.ImageView;
-import android.widget.RelativeLayout;
-import android.widget.TextView;
-
-import com.breadwallet.R;
-import com.breadwallet.BreadWalletApp;
-import com.breadwallet.presenter.entities.RequestObject;
-import com.breadwallet.tools.util.BRConstants;
-import com.breadwallet.tools.util.BRStringFormatter;
-import com.breadwallet.tools.manager.SharedPreferencesManager;
-import com.breadwallet.tools.animation.SpringAnimator;
-import com.breadwallet.tools.security.RequestHandler;
-import com.breadwallet.wallet.BRWalletManager;
-
-import java.math.BigDecimal;
-import java.security.InvalidAlgorithmParameterException;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 1/15/16.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-public class RequestQRActivity extends Activity {
-
- public static final String TAG = RequestQRActivity.class.getName();
- private ImageView qrcode;
- public boolean activityIsInBackground = false;
- public static RequestQRActivity requestApp;
- public Button close;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_request_qr);
- requestApp = this;
-
- String requestAddrs = getIntent().getExtras().getString(BRConstants.INTENT_EXTRA_REQUEST_ADDRESS);
- String requestAmount = getIntent().getExtras().getString(BRConstants.INTENT_EXTRA_REQUEST_AMOUNT);
-
- String finalAddress = "bitcoin:" + requestAddrs + "?amount=" + requestAmount;
- qrcode = (ImageView) findViewById(R.id.request_image_qr_code);
- close = (Button) findViewById(R.id.request_close);
- TextView requestAmountText = (TextView) findViewById(R.id.request_amount_text);
- TextView requestAddressText = (TextView) findViewById(R.id.request_address_text);
- RelativeLayout addressLayout = (RelativeLayout) findViewById(R.id.request_address_layout);
-
- BRWalletManager.getInstance(this).generateQR(finalAddress,qrcode);
- String address = "";
- String amount = "";
- try {
- RequestObject obj = RequestHandler.getRequestFromString(finalAddress);
- address = obj.address;
- final String iso = SharedPreferencesManager.getIso(this);
- final float rate = SharedPreferencesManager.getRate(this);
- amount = BRStringFormatter.getBitsAndExchangeString(rate, iso, new BigDecimal(obj.amount), this);
- } catch (InvalidAlgorithmParameterException e) {
- e.printStackTrace();
- }
- final Intent intent = new Intent(this, MainActivity.class);
- close.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- SpringAnimator.showAnimation(v);
- onBackPressed();
- if (MainActivity.app != null) {
- onBackPressed();
- } else {
- startActivity(intent);
- }
- if (!RequestQRActivity.this.isDestroyed()) {
- finish();
- }
-
- }
- });
- requestAddressText.setText(address);
- requestAmountText.setText(amount);
- final BreadWalletApp breadWalletApp = (BreadWalletApp) getApplication();
- addressLayout.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- breadWalletApp.cancelToast();
- }
- });
-
- }
-
-
-
- @Override
- protected void onResume() {
- super.onResume();
- activityIsInBackground = false;
- requestApp = this;
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- activityIsInBackground = true;
- }
-}
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/SetPinActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/SetPinActivity.java
new file mode 100644
index 000000000..4b5299ae2
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/activities/SetPinActivity.java
@@ -0,0 +1,154 @@
+package com.breadwallet.presenter.activities;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.TextView;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.util.BRActivity;
+import com.breadwallet.presenter.customviews.BRKeyboard;
+import com.breadwallet.tools.manager.BRSharedPrefs;
+
+import timber.log.Timber;
+
+public class SetPinActivity extends BRActivity {
+ private BRKeyboard keyboard;
+ public static SetPinActivity introSetPitActivity;
+ private View dot1;
+ private View dot2;
+ private View dot3;
+ private View dot4;
+ private View dot5;
+ private View dot6;
+
+ private ImageButton faq;
+ private StringBuilder pin = new StringBuilder();
+ private int pinLimit = 6;
+ private boolean startingNextActivity;
+ private TextView title;
+ public static boolean appVisible = false;
+ private static SetPinActivity app;
+
+ public static SetPinActivity getApp() {
+ return app;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_pin_template);
+
+ keyboard = (BRKeyboard) findViewById(R.id.brkeyboard);
+ title = (TextView) findViewById(R.id.title);
+
+
+ //TODO: all views are using the layout of this button. Views should be refactored without it
+ // Hiding until layouts are built.
+ faq = (ImageButton) findViewById(R.id.faq_button);
+ dot1 = findViewById(R.id.dot1);
+ dot2 = findViewById(R.id.dot2);
+ dot3 = findViewById(R.id.dot3);
+ dot4 = findViewById(R.id.dot4);
+ dot5 = findViewById(R.id.dot5);
+ dot6 = findViewById(R.id.dot6);
+
+ keyboard.addOnInsertListener(new BRKeyboard.OnInsertListener() {
+ @Override
+ public void onClick(String key) {
+ handleClick(key);
+ }
+ });
+ keyboard.setShowDot(false);
+ BRSharedPrefs.putGreetingsShown(this, true);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ updateDots();
+ introSetPitActivity = this;
+ appVisible = true;
+ app = this;
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ appVisible = false;
+ }
+
+ private void handleClick(String key) {
+ if (key == null) {
+ Timber.d("timber: handleClick: key is null! ");
+ return;
+ }
+
+ if (key.isEmpty()) {
+ handleDeleteClick();
+ } else if (Character.isDigit(key.charAt(0))) {
+ handleDigitClick(Integer.parseInt(key.substring(0, 1)));
+ } else {
+ Timber.d("timber: handleClick: oops: %s", key);
+ }
+ }
+
+
+ private void handleDigitClick(Integer dig) {
+ if (pin.length() < pinLimit)
+ pin.append(dig);
+ updateDots();
+ }
+
+ private void handleDeleteClick() {
+ if (pin.length() > 0)
+ pin.deleteCharAt(pin.length() - 1);
+ updateDots();
+ }
+
+ @Override
+ public void onBackPressed() {
+ super.onBackPressed();
+ overridePendingTransition(R.anim.enter_from_left, R.anim.exit_to_right);
+ }
+
+ private void updateDots() {
+ int selectedDots = pin.length();
+ dot1.setBackground(getDrawable(selectedDots <= 0 ? R.drawable.ic_pin_dot_gray : R.drawable.ic_pin_dot_black));
+ selectedDots--;
+ dot2.setBackground(getDrawable(selectedDots <= 0 ? R.drawable.ic_pin_dot_gray : R.drawable.ic_pin_dot_black));
+ selectedDots--;
+ dot3.setBackground(getDrawable(selectedDots <= 0 ? R.drawable.ic_pin_dot_gray : R.drawable.ic_pin_dot_black));
+ selectedDots--;
+ dot4.setBackground(getDrawable(selectedDots <= 0 ? R.drawable.ic_pin_dot_gray : R.drawable.ic_pin_dot_black));
+ selectedDots--;
+ dot5.setBackground(getDrawable(selectedDots <= 0 ? R.drawable.ic_pin_dot_gray : R.drawable.ic_pin_dot_black));
+ selectedDots--;
+ dot6.setBackground(getDrawable(selectedDots <= 0 ? R.drawable.ic_pin_dot_gray : R.drawable.ic_pin_dot_black));
+
+ if (pin.length() == 6) {
+ if (startingNextActivity) return;
+ startingNextActivity = true;
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ Intent intent = new Intent(SetPinActivity.this, ReEnterPinActivity.class);
+ intent.putExtra("pin", pin.toString());
+ intent.putExtra("noPin", getIntent().getBooleanExtra("noPin", false));
+ startActivity(intent);
+ overridePendingTransition(R.anim.enter_from_right, R.anim.exit_to_left);
+ pin = new StringBuilder("");
+ startingNextActivity = false;
+ }
+ }, 100);
+ }
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/UpdatePinActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/UpdatePinActivity.java
new file mode 100644
index 000000000..cde1ea0cd
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/activities/UpdatePinActivity.java
@@ -0,0 +1,206 @@
+package com.breadwallet.presenter.activities;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.util.BRActivity;
+import com.breadwallet.presenter.customviews.BRKeyboard;
+import com.breadwallet.presenter.interfaces.BROnSignalCompletion;
+import com.breadwallet.tools.animation.BRAnimator;
+import com.breadwallet.tools.animation.SpringAnimator;
+import com.breadwallet.tools.security.AuthManager;
+import com.breadwallet.tools.security.BRKeyStore;
+
+import timber.log.Timber;
+
+public class UpdatePinActivity extends BRActivity {
+ private BRKeyboard keyboard;
+ private View dot1;
+ private View dot2;
+ private View dot3;
+ private View dot4;
+ private View dot5;
+ private View dot6;
+ private StringBuilder pin = new StringBuilder();
+ private int pinLimit = 6;
+ // private boolean allowInserting = true;
+ private TextView title;
+ private TextView description;
+ int mode = ENTER_PIN;
+ public static final int ENTER_PIN = 1;
+ public static final int ENTER_NEW_PIN = 2;
+ public static final int RE_ENTER_NEW_PIN = 3;
+
+ private ImageButton faq;
+ private LinearLayout pinLayout;
+ private String curNewPin = "";
+ public static boolean appVisible = false;
+ private static UpdatePinActivity app;
+
+ public static UpdatePinActivity getApp() {
+ return app;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_pin_template);
+
+ keyboard = (BRKeyboard) findViewById(R.id.brkeyboard);
+ title = (TextView) findViewById(R.id.title);
+ description = (TextView) findViewById(R.id.description);
+ pinLayout = (LinearLayout) findViewById(R.id.pinLayout);
+ if (BRKeyStore.getPinCode(this).length() == 4) pinLimit = 4;
+ setMode(ENTER_PIN);
+ title.setText(getString(R.string.UpdatePin_updateTitle));
+ dot1 = findViewById(R.id.dot1);
+ dot2 = findViewById(R.id.dot2);
+ dot3 = findViewById(R.id.dot3);
+ dot4 = findViewById(R.id.dot4);
+ dot5 = findViewById(R.id.dot5);
+ dot6 = findViewById(R.id.dot6);
+
+ //TODO: all views are using the layout of this button. Views should be refactored without it
+ // Hiding until layouts are built.
+ faq = (ImageButton) findViewById(R.id.faq_button);
+
+ keyboard.addOnInsertListener(new BRKeyboard.OnInsertListener() {
+ @Override
+ public void onClick(String key) {
+ handleClick(key);
+ }
+ });
+ keyboard.setShowDot(false);
+
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ updateDots();
+ appVisible = true;
+ app = this;
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ appVisible = false;
+ }
+
+ private void handleClick(String key) {
+ if (key == null) {
+ Timber.d("timber: handleClick: key is null! ");
+ return;
+ }
+
+ if (key.isEmpty()) {
+ handleDeleteClick();
+ } else if (Character.isDigit(key.charAt(0))) {
+ handleDigitClick(Integer.parseInt(key.substring(0, 1)));
+ } else {
+ Timber.d("timber: handleClick: oops: %s", key);
+ }
+ }
+
+
+ private void handleDigitClick(Integer dig) {
+ if (pin.length() < pinLimit)
+ pin.append(dig);
+ updateDots();
+ }
+
+ private void handleDeleteClick() {
+ if (pin.length() > 0)
+ pin.deleteCharAt(pin.length() - 1);
+ updateDots();
+ }
+
+ @Override
+ public void onBackPressed() {
+ super.onBackPressed();
+ overridePendingTransition(R.anim.enter_from_left, R.anim.exit_to_right);
+ }
+
+ private void updateDots() {
+
+ AuthManager.getInstance().updateDots(this, pinLimit, pin.toString(), dot1, dot2, dot3, dot4, dot5, dot6, R.drawable.ic_pin_dot_gray, new AuthManager.OnPinSuccess() {
+ @Override
+ public void onSuccess() {
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ goNext();
+ }
+ }, 100);
+ }
+ });
+ }
+
+ private void goNext() {
+ switch (mode) {
+ case ENTER_PIN:
+ if (AuthManager.getInstance().checkAuth(pin.toString(), this)) {
+ setMode(ENTER_NEW_PIN);
+ pinLimit = 6;
+ } else {
+ SpringAnimator.failShakeAnimation(this, pinLayout);
+ }
+ pin = new StringBuilder();
+ updateDots();
+ break;
+ case ENTER_NEW_PIN:
+ setMode(RE_ENTER_NEW_PIN);
+ curNewPin = pin.toString();
+ pin = new StringBuilder();
+ updateDots();
+ break;
+
+ case RE_ENTER_NEW_PIN:
+ if (curNewPin.equalsIgnoreCase(pin.toString())) {
+ AuthManager.getInstance().setPinCode(pin.toString(), this);
+ BRAnimator.showBreadSignal(this, getString(R.string.Alerts_pinSet), getString(R.string.UpdatePin_caption), R.drawable.ic_check_mark_white, new BROnSignalCompletion() {
+ @Override
+ public void onComplete() {
+ BRAnimator.startBreadActivity(UpdatePinActivity.this, false);
+ }
+ });
+ } else {
+ SpringAnimator.failShakeAnimation(this, pinLayout);
+ setMode(ENTER_NEW_PIN);
+ pinLimit = BRKeyStore.getPinCode(this).length();
+ }
+ pin = new StringBuilder();
+ updateDots();
+ break;
+ }
+ }
+
+ private void setMode(int mode) {
+ String text = "";
+ this.mode = mode;
+ switch (mode) {
+ case ENTER_PIN:
+ text = getString(R.string.UpdatePin_enterCurrent);
+ break;
+ case ENTER_NEW_PIN:
+ text = getString(R.string.UpdatePin_enterNew);
+ break;
+ case RE_ENTER_NEW_PIN:
+ text = getString(R.string.UpdatePin_reEnterNew);
+ break;
+ }
+ description.setText(text);
+ SpringAnimator.springView(description);
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/camera/AutoFitTextureView.java b/app/src/main/java/com/breadwallet/presenter/activities/camera/AutoFitTextureView.java
new file mode 100644
index 000000000..33ae67013
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/activities/camera/AutoFitTextureView.java
@@ -0,0 +1,110 @@
+package com.breadwallet.presenter.activities.camera;
+
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.TextureView;
+
+import android.content.Context;
+
+import com.breadwallet.R;
+
+/**
+ * A {@link TextureView} that can be adjusted to a specified aspect ratio.
+ */
+public class AutoFitTextureView extends TextureView {
+
+ private static final String TAG = AutoFitTextureView.class.getName();
+
+ private int mRatioWidth = 0;
+ private int mRatioHeight = 0;
+ private int width;
+ private int height;
+ private int guideLineWidth = 600;
+ private int guideLineHeight = 400;
+ private Paint framePaint;
+
+ public AutoFitTextureView(Context context) {
+ this(context, null);
+ init(context, null);
+ }
+
+ public AutoFitTextureView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ init(context, attrs);
+ }
+
+ public AutoFitTextureView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ init(context, attrs);
+ }
+
+ private void init(Context ctx, AttributeSet attrs) {
+ framePaint = new Paint();
+ framePaint.setAntiAlias(true);
+ framePaint.setStyle(Paint.Style.FILL);
+ framePaint.setColor(ctx.getColor(R.color.camera_guideline));
+ }
+
+ /**
+ * Sets the aspect ratio for this view. The size of the view will be measured based on the ratio
+ * calculated from the parameters. Note that the actual sizes of parameters don't matter, that
+ * is, calling setAspectRatio(2, 3) and setAspectRatio(4, 6) make the same result.
+ *
+ * @param width Relative horizontal size
+ * @param height Relative vertical size
+ */
+ public void setAspectRatio(int width, int height) {
+ if (width < 0 || height < 0) {
+ throw new IllegalArgumentException("Size cannot be negative.");
+ }
+ mRatioWidth = width;
+ mRatioHeight = height;
+ requestLayout();
+ }
+
+ @Override
+ public void onDrawForeground(Canvas canvas) {
+ int left = width / 2 - guideLineWidth / 2;
+ int top = height / 2 - guideLineHeight / 2;
+ int right = width / 2 + guideLineWidth / 2;
+ int bottom = height / 2 + guideLineWidth / 2;
+ canvas.drawRect(left, top, right, bottom, framePaint);
+ super.onDrawForeground(canvas);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ width = MeasureSpec.getSize(widthMeasureSpec);
+ height = MeasureSpec.getSize(heightMeasureSpec);
+ if (0 == mRatioWidth || 0 == mRatioHeight) {
+ setMeasuredDimension(width, height);
+ } else {
+ if (width < height * mRatioWidth / mRatioHeight) {
+ setMeasuredDimension(width, width * mRatioHeight / mRatioWidth);
+ } else {
+ setMeasuredDimension(height * mRatioWidth / mRatioHeight, height);
+ }
+ }
+ }
+
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/camera/CameraActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/camera/CameraActivity.java
new file mode 100644
index 000000000..6c4f73da0
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/activities/camera/CameraActivity.java
@@ -0,0 +1,962 @@
+package com.breadwallet.presenter.activities.camera;
+
+import android.Manifest;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.Fragment;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+import android.graphics.ImageFormat;
+import android.graphics.Matrix;
+import android.graphics.Point;
+import android.graphics.RectF;
+import android.graphics.SurfaceTexture;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CameraManager;
+import android.hardware.camera2.CameraMetadata;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.TotalCaptureResult;
+import android.hardware.camera2.params.StreamConfigurationMap;
+import android.media.Image;
+import android.media.ImageReader;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
+import androidx.annotation.NonNull;
+import androidx.legacy.app.ActivityCompat;
+import androidx.legacy.app.FragmentCompat;
+import androidx.core.content.ContextCompat;
+import android.util.Log;
+import android.util.Size;
+import android.util.SparseIntArray;
+import android.view.Surface;
+import android.view.TextureView;
+import android.view.View;
+import android.widget.Toast;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.BreadActivity;
+import com.breadwallet.presenter.activities.util.BRActivity;
+import com.breadwallet.tools.threads.BRExecutor;
+
+import java.io.File;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+import timber.log.Timber;
+
+public class CameraActivity extends BRActivity implements View.OnClickListener, ActivityCompat.OnRequestPermissionsResultCallback {
+ public static boolean appVisible = false;
+ private static CameraActivity app;
+ private boolean imageTaken;
+ /**
+ * Conversion from screen rotation to JPEG orientation.
+ */
+ private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
+ private static final int REQUEST_CAMERA_PERMISSION = 1;
+ private static final String FRAGMENT_DIALOG = "dialog";
+
+ static {
+ ORIENTATIONS.append(Surface.ROTATION_0, 90);
+ ORIENTATIONS.append(Surface.ROTATION_90, 0);
+ ORIENTATIONS.append(Surface.ROTATION_180, 270);
+ ORIENTATIONS.append(Surface.ROTATION_270, 180);
+ }
+
+ /**
+ * Camera state: Showing camera preview.
+ */
+ private static final int STATE_PREVIEW = 0;
+
+ /**
+ * Camera state: Waiting for the focus to be locked.
+ */
+ private static final int STATE_WAITING_LOCK = 1;
+
+ /**
+ * Camera state: Waiting for the exposure to be precapture state.
+ */
+ private static final int STATE_WAITING_PRECAPTURE = 2;
+
+ /**
+ * Camera state: Waiting for the exposure state to be something other than precapture.
+ */
+ private static final int STATE_WAITING_NON_PRECAPTURE = 3;
+
+ /**
+ * Camera state: Picture was taken.
+ */
+ private static final int STATE_PICTURE_TAKEN = 4;
+
+ /**
+ * Max preview width that is guaranteed by Camera2 API
+ */
+ private static final int MAX_PREVIEW_WIDTH = 1920;
+
+ /**
+ * Max preview height that is guaranteed by Camera2 API
+ */
+ private static final int MAX_PREVIEW_HEIGHT = 1080;
+
+ /**
+ * {@link TextureView.SurfaceTextureListener} handles several lifecycle events on a
+ * {@link TextureView}.
+ */
+ private final TextureView.SurfaceTextureListener mSurfaceTextureListener
+ = new TextureView.SurfaceTextureListener() {
+
+ @Override
+ public void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) {
+ openCamera(width, height);
+ }
+
+ @Override
+ public void onSurfaceTextureSizeChanged(SurfaceTexture texture, int width, int height) {
+ configureTransform(width, height);
+ }
+
+ @Override
+ public boolean onSurfaceTextureDestroyed(SurfaceTexture texture) {
+ return true;
+ }
+
+ @Override
+ public void onSurfaceTextureUpdated(SurfaceTexture texture) {
+ }
+
+ };
+
+ /**
+ * ID of the current {@link CameraDevice}.
+ */
+ private String mCameraId;
+
+ /**
+ * An {@link AutoFitTextureView} for camera preview.
+ */
+ private AutoFitTextureView mTextureView;
+
+ /**
+ * A {@link CameraCaptureSession } for camera preview.
+ */
+ private CameraCaptureSession mCaptureSession;
+
+ /**
+ * A reference to the opened {@link CameraDevice}.
+ */
+ private CameraDevice mCameraDevice;
+
+ /**
+ * The {@link android.util.Size} of camera preview.
+ */
+ private Size mPreviewSize;
+
+ /**
+ * {@link CameraDevice.StateCallback} is called when {@link CameraDevice} changes its state.
+ */
+ private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
+
+ @Override
+ public void onOpened(@NonNull CameraDevice cameraDevice) {
+ // This method is called when the camera is opened. We start camera preview here.
+ mCameraOpenCloseLock.release();
+ mCameraDevice = cameraDevice;
+ createCameraPreviewSession();
+ }
+
+ @Override
+ public void onDisconnected(@NonNull CameraDevice cameraDevice) {
+ mCameraOpenCloseLock.release();
+ cameraDevice.close();
+ mCameraDevice = null;
+ }
+
+ @Override
+ public void onError(@NonNull CameraDevice cameraDevice, int error) {
+ mCameraOpenCloseLock.release();
+ cameraDevice.close();
+ mCameraDevice = null;
+ Activity activity = CameraActivity.this;
+ if (null != activity) {
+ activity.finish();
+ }
+ }
+
+ };
+
+ /**
+ * An additional thread for running tasks that shouldn't block the UI.
+ */
+ private HandlerThread mBackgroundThread;
+
+ /**
+ * A {@link Handler} for running tasks in the background.
+ */
+ private Handler mBackgroundHandler;
+
+ /**
+ * An {@link ImageReader} that handles still image capture.
+ */
+ private ImageReader mImageReader;
+
+
+ /**
+ * This a callback object for the {@link ImageReader}. "onImageAvailable" will be called when a
+ * still image is ready to be saved.
+ */
+ private final ImageReader.OnImageAvailableListener mOnImageAvailableListener
+ = new ImageReader.OnImageAvailableListener() {
+
+ @Override
+ public void onImageAvailable(ImageReader reader) {
+ if (imageTaken) return;
+ imageTaken = true;
+ //DEV: Breaking the path to remove the ImageSaver and the CameraPlugin
+ // This was going to update an image to a BRD server
+ //TODO: Remove the ImageReader in a subsequent commit
+ //mBackgroundHandler.post(new ImageSaver(reader.acquireNextImage()));
+ }
+
+ };
+
+ /**
+ * {@link CaptureRequest.Builder} for the camera preview
+ */
+ private CaptureRequest.Builder mPreviewRequestBuilder;
+
+ /**
+ * {@link CaptureRequest} generated by {@link #mPreviewRequestBuilder}
+ */
+ private CaptureRequest mPreviewRequest;
+
+ /**
+ * The current state of camera state for taking pictures.
+ *
+ * @see #mCaptureCallback
+ */
+ private int mState = STATE_PREVIEW;
+
+ /**
+ * A {@link Semaphore} to prevent the app from exiting before closing the camera.
+ */
+ private Semaphore mCameraOpenCloseLock = new Semaphore(1);
+
+ /**
+ * Whether the current camera device supports Flash or not.
+ */
+ private boolean mFlashSupported;
+
+ /**
+ * Orientation of the camera sensor
+ */
+ private int mSensorOrientation;
+
+ /**
+ * A {@link CameraCaptureSession.CaptureCallback} that handles events related to JPEG capture.
+ */
+ private CameraCaptureSession.CaptureCallback mCaptureCallback
+ = new CameraCaptureSession.CaptureCallback() {
+
+ private void process(CaptureResult result) {
+ switch (mState) {
+ case STATE_PREVIEW: {
+ // We have nothing to do when the camera preview is working normally.
+ break;
+ }
+ case STATE_WAITING_LOCK: {
+ Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
+ if (afState == null) {
+ captureStillPicture();
+ } else if (CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED == afState ||
+ CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED == afState) {
+ // CONTROL_AE_STATE can be null on some devices
+ Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
+ if (aeState == null ||
+ aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) {
+ mState = STATE_PICTURE_TAKEN;
+ captureStillPicture();
+ } else {
+ runPrecaptureSequence();
+ }
+ }
+ break;
+ }
+ case STATE_WAITING_PRECAPTURE: {
+ // CONTROL_AE_STATE can be null on some devices
+ Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
+ if (aeState == null ||
+ aeState == CaptureResult.CONTROL_AE_STATE_PRECAPTURE ||
+ aeState == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED) {
+ mState = STATE_WAITING_NON_PRECAPTURE;
+ }
+ break;
+ }
+ case STATE_WAITING_NON_PRECAPTURE: {
+ // CONTROL_AE_STATE can be null on some devices
+ Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
+ if (aeState == null || aeState != CaptureResult.CONTROL_AE_STATE_PRECAPTURE) {
+ mState = STATE_PICTURE_TAKEN;
+ captureStillPicture();
+ }
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void onCaptureProgressed(@NonNull CameraCaptureSession session,
+ @NonNull CaptureRequest request,
+ @NonNull CaptureResult partialResult) {
+ process(partialResult);
+ }
+
+ @Override
+ public void onCaptureCompleted(@NonNull CameraCaptureSession session,
+ @NonNull CaptureRequest request,
+ @NonNull TotalCaptureResult result) {
+ process(result);
+ }
+
+ };
+
+ /**
+ * Shows a {@link Toast} on the UI thread.
+ *
+ * @param text The message to show
+ */
+ private void showToast(final String text) {
+ CameraActivity.this.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ Toast.makeText(CameraActivity.this, text, Toast.LENGTH_SHORT).show();
+ }
+ });
+ }
+
+ /**
+ * Given {@code choices} of {@code Size}s supported by a camera, choose the smallest one that
+ * is at least as large as the respective texture view size, and that is at most as large as the
+ * respective max size, and whose aspect ratio matches with the specified value. If such size
+ * doesn't exist, choose the largest one that is at most as large as the respective max size,
+ * and whose aspect ratio matches with the specified value.
+ *
+ * @param choices The list of sizes that the camera supports for the intended output
+ * class
+ * @param textureViewWidth The width of the texture view relative to sensor coordinate
+ * @param textureViewHeight The height of the texture view relative to sensor coordinate
+ * @param maxWidth The maximum width that can be chosen
+ * @param maxHeight The maximum height that can be chosen
+ * @param aspectRatio The aspect ratio
+ * @return The optimal {@code Size}, or an arbitrary one if none were big enough
+ */
+ private static Size chooseOptimalSize(Size[] choices, int textureViewWidth,
+ int textureViewHeight, int maxWidth, int maxHeight, Size aspectRatio) {
+
+ // Collect the supported resolutions that are at least as big as the preview Surface
+ List bigEnough = new ArrayList<>();
+ // Collect the supported resolutions that are smaller than the preview Surface
+ List notBigEnough = new ArrayList<>();
+ int w = aspectRatio.getWidth();
+ int h = aspectRatio.getHeight();
+ for (Size option : choices) {
+ if (option.getWidth() <= maxWidth && option.getHeight() <= maxHeight &&
+ option.getHeight() == option.getWidth() * h / w) {
+ if (option.getWidth() >= textureViewWidth &&
+ option.getHeight() >= textureViewHeight) {
+ bigEnough.add(option);
+ } else {
+ notBigEnough.add(option);
+ }
+ }
+ }
+
+ // Pick the smallest of those big enough. If there is no one big enough, pick the
+ // largest of those not big enough.
+ if (bigEnough.size() > 0) {
+ return Collections.min(bigEnough, new CompareSizesByArea());
+ } else if (notBigEnough.size() > 0) {
+ return Collections.max(notBigEnough, new CompareSizesByArea());
+ } else {
+ Timber.d("timber: Couldn't find any suitable preview size");
+ return choices[0];
+ }
+ }
+
+ private void requestCameraPermission() {
+ if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
+ new ConfirmationDialog().show(getFragmentManager(), FRAGMENT_DIALOG);
+ } else {
+ ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},
+ REQUEST_CAMERA_PERMISSION);
+ }
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
+ @NonNull int[] grantResults) {
+ if (requestCode == REQUEST_CAMERA_PERMISSION) {
+ if (grantResults.length != 1 || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
+ ErrorDialog.newInstance("This sample needs camera permission.")
+ .show(getFragmentManager(), FRAGMENT_DIALOG);
+ }
+ } else {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+ }
+ }
+
+ /**
+ * Sets up member variables related to camera.
+ *
+ * @param width The width of available size for camera preview
+ * @param height The height of available size for camera preview
+ */
+ private void setUpCameraOutputs(int width, int height) {
+ Activity activity = CameraActivity.this;
+ CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
+ try {
+ for (String cameraId : manager.getCameraIdList()) {
+ CameraCharacteristics characteristics
+ = manager.getCameraCharacteristics(cameraId);
+
+ // We don't use a front facing camera in this sample.
+ Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
+ if (facing != null && facing == CameraCharacteristics.LENS_FACING_FRONT) {
+ continue;
+ }
+
+ StreamConfigurationMap map = characteristics.get(
+ CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+ if (map == null) {
+ continue;
+ }
+
+ // For still image captures, we use the largest available size.
+ Size largest = Collections.max(
+ Arrays.asList(map.getOutputSizes(ImageFormat.JPEG)),
+ new CompareSizesByArea());
+ mImageReader = ImageReader.newInstance(largest.getWidth(), largest.getHeight(),
+ ImageFormat.JPEG, /*maxImages*/2);
+ mImageReader.setOnImageAvailableListener(
+ mOnImageAvailableListener, mBackgroundHandler);
+
+ // Find out if we need to swap dimension to get the preview size relative to sensor
+ // coordinate.
+ int displayRotation = activity.getWindowManager().getDefaultDisplay().getRotation();
+ //noinspection ConstantConditions
+ mSensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
+ boolean swappedDimensions = false;
+ switch (displayRotation) {
+ case Surface.ROTATION_0:
+ case Surface.ROTATION_180:
+ if (mSensorOrientation == 90 || mSensorOrientation == 270) {
+ swappedDimensions = true;
+ }
+ break;
+ case Surface.ROTATION_90:
+ case Surface.ROTATION_270:
+ if (mSensorOrientation == 0 || mSensorOrientation == 180) {
+ swappedDimensions = true;
+ }
+ break;
+ default:
+ Timber.d("timber: Display rotation is invalid: %s", displayRotation);
+ }
+
+ Point displaySize = new Point();
+ activity.getWindowManager().getDefaultDisplay().getSize(displaySize);
+ int rotatedPreviewWidth = width;
+ int rotatedPreviewHeight = height;
+ int maxPreviewWidth = displaySize.x;
+ int maxPreviewHeight = displaySize.y;
+
+ if (swappedDimensions) {
+ rotatedPreviewWidth = height;
+ rotatedPreviewHeight = width;
+ maxPreviewWidth = displaySize.y;
+ maxPreviewHeight = displaySize.x;
+ }
+
+ if (maxPreviewWidth > MAX_PREVIEW_WIDTH) {
+ maxPreviewWidth = MAX_PREVIEW_WIDTH;
+ }
+
+ if (maxPreviewHeight > MAX_PREVIEW_HEIGHT) {
+ maxPreviewHeight = MAX_PREVIEW_HEIGHT;
+ }
+
+ // Danger, W.R.! Attempting to use too large a preview size could exceed the camera
+ // bus' bandwidth limitation, resulting in gorgeous previews but the storage of
+ // garbage capture data.
+ mPreviewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class),
+ rotatedPreviewWidth, rotatedPreviewHeight, maxPreviewWidth,
+ maxPreviewHeight, largest);
+
+ // We fit the aspect ratio of TextureView to the size of preview we picked.
+ int orientation = getResources().getConfiguration().orientation;
+ if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
+ mTextureView.setAspectRatio(
+ mPreviewSize.getWidth(), mPreviewSize.getHeight());
+ } else {
+ mTextureView.setAspectRatio(
+ mPreviewSize.getHeight(), mPreviewSize.getWidth());
+ }
+
+ // Check if the flash is supported.
+ Boolean available = characteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE);
+ mFlashSupported = available == null ? false : available;
+
+ mCameraId = cameraId;
+ return;
+ }
+ } catch (CameraAccessException e) {
+ Timber.e(e);
+ } catch (NullPointerException e) {
+ Timber.e(e);
+ // Currently an NPE is thrown when the Camera2API is used but not supported on the
+ // device this code runs.
+ ErrorDialog.newInstance("This device doesn\'t support Camera2 API.")
+ .show(getFragmentManager(), FRAGMENT_DIALOG);
+ }
+ }
+
+ /**
+ * Opens the camera specified by {@link #mCameraId}.
+ */
+ private void openCamera(int width, int height) {
+ if (ContextCompat.checkSelfPermission(CameraActivity.this, Manifest.permission.CAMERA)
+ != PackageManager.PERMISSION_GRANTED) {
+ requestCameraPermission();
+ return;
+ }
+ setUpCameraOutputs(width, height);
+ configureTransform(width, height);
+ Activity activity = CameraActivity.this;
+ CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
+ try {
+ if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {
+ throw new RuntimeException("Time out waiting to lock camera opening.");
+ }
+ manager.openCamera(mCameraId, mStateCallback, mBackgroundHandler);
+ } catch (CameraAccessException e) {
+ Timber.e(e);
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Interrupted while trying to lock camera opening.", e);
+ }
+ }
+
+ /**
+ * Closes the current {@link CameraDevice}.
+ */
+ private void closeCamera() {
+ try {
+ mCameraOpenCloseLock.acquire();
+ if (null != mCaptureSession) {
+ mCaptureSession.close();
+ mCaptureSession = null;
+ }
+ if (null != mCameraDevice) {
+ mCameraDevice.close();
+ mCameraDevice = null;
+ }
+ if (null != mImageReader) {
+ mImageReader.close();
+ mImageReader = null;
+ }
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Interrupted while trying to lock camera closing.", e);
+ } finally {
+ mCameraOpenCloseLock.release();
+ }
+ }
+
+ /**
+ * Starts a background thread and its {@link Handler}.
+ */
+ private void startBackgroundThread() {
+ mBackgroundThread = new HandlerThread("CameraBackground");
+ mBackgroundThread.start();
+ mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
+ }
+
+ /**
+ * Stops the background thread and its {@link Handler}.
+ */
+ private void stopBackgroundThread() {
+ mBackgroundThread.quitSafely();
+ try {
+ mBackgroundThread.join();
+ mBackgroundThread = null;
+ mBackgroundHandler = null;
+ } catch (InterruptedException e) {
+ Timber.e(e);
+ }
+ }
+
+ /**
+ * Creates a new {@link CameraCaptureSession} for camera preview.
+ */
+ private void createCameraPreviewSession() {
+ try {
+ SurfaceTexture texture = mTextureView.getSurfaceTexture();
+ assert texture != null;
+
+ // We configure the size of default buffer to be the size of camera preview we want.
+ texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
+
+ // This is the output Surface we need to start preview.
+ Surface surface = new Surface(texture);
+
+ // We set up a CaptureRequest.Builder with the output Surface.
+ mPreviewRequestBuilder
+ = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+ mPreviewRequestBuilder.addTarget(surface);
+
+ // Here, we create a CameraCaptureSession for camera preview.
+ mCameraDevice.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface()),
+ new CameraCaptureSession.StateCallback() {
+
+ @Override
+ public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
+ // The camera is already closed
+ if (null == mCameraDevice) {
+ return;
+ }
+
+ // When the session is ready, we start displaying the preview.
+ mCaptureSession = cameraCaptureSession;
+ try {
+ // Auto focus should be continuous for camera preview.
+ mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
+ CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
+ // Flash is automatically enabled when necessary.
+ setAutoFlash(mPreviewRequestBuilder);
+
+ // Finally, we start displaying the camera preview.
+ mPreviewRequest = mPreviewRequestBuilder.build();
+ mCaptureSession.setRepeatingRequest(mPreviewRequest,
+ mCaptureCallback, mBackgroundHandler);
+ } catch (CameraAccessException e) {
+ Timber.e(e);
+ }
+ }
+
+ @Override
+ public void onConfigureFailed(
+ @NonNull CameraCaptureSession cameraCaptureSession) {
+ showToast("Failed");
+ }
+ }, null
+ );
+ } catch (CameraAccessException e) {
+ Timber.e(e);
+ }
+ }
+
+ /**
+ * Configures the necessary {@link android.graphics.Matrix} transformation to `mTextureView`.
+ * This method should be called after the camera preview size is determined in
+ * setUpCameraOutputs and also the size of `mTextureView` is fixed.
+ *
+ * @param viewWidth The width of `mTextureView`
+ * @param viewHeight The height of `mTextureView`
+ */
+ private void configureTransform(int viewWidth, int viewHeight) {
+ Activity activity = CameraActivity.this;
+ if (null == mTextureView || null == mPreviewSize) {
+ return;
+ }
+ int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
+ Matrix matrix = new Matrix();
+ RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);
+ RectF bufferRect = new RectF(0, 0, mPreviewSize.getHeight(), mPreviewSize.getWidth());
+ float centerX = viewRect.centerX();
+ float centerY = viewRect.centerY();
+ if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {
+ bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());
+ matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);
+ float scale = Math.max(
+ (float) viewHeight / mPreviewSize.getHeight(),
+ (float) viewWidth / mPreviewSize.getWidth());
+ matrix.postScale(scale, scale, centerX, centerY);
+ matrix.postRotate(90 * (rotation - 2), centerX, centerY);
+ } else if (Surface.ROTATION_180 == rotation) {
+ matrix.postRotate(180, centerX, centerY);
+ }
+ mTextureView.setTransform(matrix);
+ }
+
+ /**
+ * Initiate a still image capture.
+ */
+ private void takePicture() {
+ lockFocus();
+ }
+
+ /**
+ * Lock the focus as the first step for a still image capture.
+ */
+ private void lockFocus() {
+ try {
+ // This is how to tell the camera to lock focus.
+ mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
+ CameraMetadata.CONTROL_AF_TRIGGER_START);
+ // Tell #mCaptureCallback to wait for the lock.
+ mState = STATE_WAITING_LOCK;
+ mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
+ mBackgroundHandler);
+ } catch (CameraAccessException e) {
+ Timber.e(e);
+ }
+ }
+
+ /**
+ * Run the precapture sequence for capturing a still image. This method should be called when
+ * we get a response in {@link #mCaptureCallback} from {@link #lockFocus()}.
+ */
+ private void runPrecaptureSequence() {
+ try {
+ // This is how to tell the camera to trigger.
+ mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
+ CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
+ // Tell #mCaptureCallback to wait for the precapture sequence to be set.
+ mState = STATE_WAITING_PRECAPTURE;
+ mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
+ mBackgroundHandler);
+ } catch (CameraAccessException e) {
+ Timber.e(e);
+ }
+ }
+
+ /**
+ * Capture a still picture. This method should be called when we get a response in
+ * {@link #mCaptureCallback} from both {@link #lockFocus()}.
+ */
+ private void captureStillPicture() {
+ try {
+ final Activity activity = CameraActivity.this;
+ if (null == mCameraDevice) {
+ return;
+ }
+ // This is the CaptureRequest.Builder that we use to take a picture.
+ final CaptureRequest.Builder captureBuilder =
+ mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
+ captureBuilder.addTarget(mImageReader.getSurface());
+
+ // Use the same AE and AF modes as the preview.
+ captureBuilder.set(CaptureRequest.CONTROL_AF_MODE,
+ CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
+ setAutoFlash(captureBuilder);
+
+ // Orientation
+ int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
+ captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, getOrientation(rotation));
+
+ CameraCaptureSession.CaptureCallback CaptureCallback
+ = new CameraCaptureSession.CaptureCallback() {
+
+ @Override
+ public void onCaptureCompleted(@NonNull CameraCaptureSession session,
+ @NonNull CaptureRequest request,
+ @NonNull TotalCaptureResult result) {
+ unlockFocus();
+ }
+ };
+
+ mCaptureSession.stopRepeating();
+ mCaptureSession.capture(captureBuilder.build(), CaptureCallback, null);
+ } catch (CameraAccessException e) {
+ Timber.e(e);
+ }
+ }
+
+ /**
+ * Retrieves the JPEG orientation from the specified screen rotation.
+ *
+ * @param rotation The screen rotation.
+ * @return The JPEG orientation (one of 0, 90, 270, and 360)
+ */
+ private int getOrientation(int rotation) {
+ // Sensor orientation is 90 for most devices, or 270 for some devices (eg. Nexus 5X)
+ // We have to take that into account and rotate JPEG properly.
+ // For devices with orientation of 90, we simply return our mapping from ORIENTATIONS.
+ // For devices with orientation of 270, we need to rotate the JPEG 180 degrees.
+ return (ORIENTATIONS.get(rotation) + mSensorOrientation + 270) % 360;
+ }
+
+ /**
+ * Unlock the focus. This method should be called when still image capture sequence is
+ * finished.
+ */
+ private void unlockFocus() {
+ try {
+ // Reset the auto-focus trigger
+ mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
+ CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
+ setAutoFlash(mPreviewRequestBuilder);
+ mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
+ mBackgroundHandler);
+ // After this, the camera will go back to the normal state of preview.
+ mState = STATE_PREVIEW;
+ mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback,
+ mBackgroundHandler);
+ } catch (CameraAccessException e) {
+ Timber.e(e);
+ }
+ }
+
+ @Override
+ public void onClick(View view) {
+ if (view.getId() == R.id.take_picture) {
+ takePicture();
+ }
+ }
+
+ private void setAutoFlash(CaptureRequest.Builder requestBuilder) {
+ if (mFlashSupported) {
+ requestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
+ CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
+ }
+ }
+
+ /**
+ * Compares two {@code Size}s based on their areas.
+ */
+ static class CompareSizesByArea implements Comparator {
+
+ @Override
+ public int compare(Size lhs, Size rhs) {
+ // We cast here to ensure the multiplications won't overflow
+ return Long.signum((long) lhs.getWidth() * lhs.getHeight() -
+ (long) rhs.getWidth() * rhs.getHeight());
+ }
+
+ }
+
+ /**
+ * Shows an error message dialog.
+ */
+ public static class ErrorDialog extends DialogFragment {
+
+ private static final String ARG_MESSAGE = "message";
+
+ public static ErrorDialog newInstance(String message) {
+ ErrorDialog dialog = new ErrorDialog();
+ Bundle args = new Bundle();
+ args.putString(ARG_MESSAGE, message);
+ dialog.setArguments(args);
+ return dialog;
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ final Activity activity = getActivity();
+ return new AlertDialog.Builder(activity)
+ .setMessage(getArguments().getString(ARG_MESSAGE))
+ .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialogInterface, int i) {
+ activity.finish();
+ }
+ })
+ .create();
+ }
+ }
+
+ /**
+ * Shows OK/Cancel confirmation dialog about camera permission.
+ */
+ public static class ConfirmationDialog extends DialogFragment {
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ final Fragment parent = getParentFragment();
+ return new AlertDialog.Builder(getActivity())
+ .setMessage(getString(R.string.Send_cameraUnavailabeTitle_android))
+ .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ FragmentCompat.requestPermissions(parent,
+ new String[]{Manifest.permission.CAMERA},
+ REQUEST_CAMERA_PERMISSION);
+ }
+ })
+ .setNegativeButton(android.R.string.cancel,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ Activity activity = parent.getActivity();
+ if (activity != null) {
+ activity.finish();
+ }
+ }
+ })
+ .create();
+ }
+ }
+
+ public static CameraActivity getApp() {
+ return app;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_camera);
+ findViewById(R.id.take_picture).setOnClickListener(this);
+ mTextureView = (AutoFitTextureView) findViewById(R.id.texture);
+ }
+
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ appVisible = true;
+ app = this;
+ startBackgroundThread();
+ imageTaken = false;
+
+ // When the screen is turned off and turned back on, the SurfaceTexture is already
+ // available, and "onSurfaceTextureAvailable" will not be called. In that case, we can open
+ // a camera and start preview from here (otherwise, we wait until the surface is ready in
+ // the SurfaceTextureListener).
+ if (mTextureView.isAvailable()) {
+ openCamera(mTextureView.getWidth(), mTextureView.getHeight());
+ } else {
+ mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
+ }
+ }
+
+ @Override
+ protected void onPause() {
+ closeCamera();
+ stopBackgroundThread();
+ super.onPause();
+ appVisible = false;
+ }
+
+ @Override
+ public void onBackPressed() {
+ overridePendingTransition(R.anim.fade_down, 0);
+ super.onBackPressed();
+ }
+
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/camera/ScanQRActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/camera/ScanQRActivity.java
new file mode 100644
index 000000000..659537c25
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/activities/camera/ScanQRActivity.java
@@ -0,0 +1,177 @@
+package com.breadwallet.presenter.activities.camera;
+
+import android.Manifest;
+import android.app.Activity;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.graphics.PointF;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.core.app.ActivityCompat;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.util.BRActivity;
+import com.breadwallet.tools.animation.SpringAnimator;
+import com.breadwallet.tools.qrcode.QRCodeReaderView;
+import com.breadwallet.tools.security.BitcoinUrlHandler;
+
+import timber.log.Timber;
+
+public class ScanQRActivity extends BRActivity implements ActivityCompat.OnRequestPermissionsResultCallback, QRCodeReaderView.OnQRCodeReadListener {
+ private ImageView cameraGuide;
+ private TextView descriptionText;
+ private long lastUpdated;
+ private UIUpdateTask task;
+ private boolean handlingCode;
+ public static boolean appVisible = false;
+ private static final int MY_PERMISSION_REQUEST_CAMERA = 56432;
+
+ private QRCodeReaderView qrCodeReaderView;
+
+ @Override
+ protected void onCreate(final Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_qr);
+
+ cameraGuide = findViewById(R.id.scan_guide);
+ descriptionText = findViewById(R.id.description_text);
+
+ task = new UIUpdateTask();
+ task.start();
+
+ cameraGuide.setImageResource(R.drawable.cameraguide);
+ cameraGuide.setVisibility(View.GONE);
+
+ if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
+ == PackageManager.PERMISSION_GRANTED) {
+ initQRCodeReaderView();
+ } else {
+ Timber.d("timber: onCreate: Permissions needed? HUH?");
+ }
+
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ cameraGuide.setVisibility(View.VISIBLE);
+ SpringAnimator.showExpandCameraGuide(cameraGuide);
+ }
+ }, 400);
+ }
+
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ appVisible = true;
+ if (qrCodeReaderView != null) {
+ qrCodeReaderView.startCamera();
+ }
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ appVisible = false;
+ if (qrCodeReaderView != null) {
+ qrCodeReaderView.stopCamera();
+ }
+ task.stopTask();
+ }
+
+ @Override
+ public void onBackPressed() {
+ overridePendingTransition(R.anim.fade_down, 0);
+ super.onBackPressed();
+ }
+
+ private class UIUpdateTask extends Thread {
+ public boolean running = true;
+
+ @Override
+ public void run() {
+ super.run();
+ while (running) {
+ if (System.currentTimeMillis() - lastUpdated > 300) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ cameraGuide.setImageResource(R.drawable.cameraguide);
+ descriptionText.setText("");
+ }
+ });
+ }
+ try {
+ Thread.sleep(300);
+ } catch (InterruptedException e) {
+ Timber.e(e);
+ }
+ }
+ }
+
+ public void stopTask() {
+ running = false;
+ }
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
+ @NonNull int[] grantResults) {
+ if (requestCode != MY_PERMISSION_REQUEST_CAMERA) {
+ return;
+ }
+
+ if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ initQRCodeReaderView();
+ } else {
+ Timber.w("Camera permission request was denied.");
+ }
+ }
+
+ @Override
+ public void onQRCodeRead(final String text, PointF[] points) {
+ if (handlingCode) return;
+ if (BitcoinUrlHandler.isBitcoinUrl(text)) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ lastUpdated = System.currentTimeMillis();
+ cameraGuide.setImageResource(R.drawable.cameraguide);
+ descriptionText.setText("");
+ handlingCode = true;
+ Intent returnIntent = new Intent();
+ returnIntent.putExtra("result", text);
+ setResult(Activity.RESULT_OK, returnIntent);
+ finish();
+
+ }
+ });
+ } else {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ lastUpdated = System.currentTimeMillis();
+ cameraGuide.setImageResource(R.drawable.cameraguide_red);
+ descriptionText.setText(getString(R.string.Send_invalidAddressTitle));
+ }
+ });
+ }
+ }
+
+ private void initQRCodeReaderView() {
+ qrCodeReaderView = findViewById(R.id.qrdecoderview);
+ qrCodeReaderView.setAutofocusInterval(500L);
+ qrCodeReaderView.setOnQRCodeReadListener(this);
+ qrCodeReaderView.setBackCamera();
+ qrCodeReaderView.startCamera();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/intro/IntroActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/intro/IntroActivity.java
new file mode 100644
index 000000000..ace0122f1
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/activities/intro/IntroActivity.java
@@ -0,0 +1,244 @@
+
+package com.breadwallet.presenter.activities.intro;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.graphics.Point;
+import android.media.AudioAttributes;
+import android.media.MediaPlayer;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.MediaStore;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TextView;
+import android.widget.Toast;
+import com.breadwallet.presenter.activities.AnnounceUpdatesViewActivity;
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import com.breadwallet.entities.IntroLanguageResource;
+import com.breadwallet.tools.adapter.CountryLanguageAdapter;
+import com.breadwallet.tools.listeners.RecyclerItemClickListener;
+import com.google.android.material.snackbar.Snackbar;
+import com.breadwallet.BuildConfig;
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.BreadActivity;
+import com.breadwallet.presenter.activities.SetPinActivity;
+import com.breadwallet.presenter.activities.util.BRActivity;
+import com.breadwallet.tools.animation.BRAnimator;
+import com.breadwallet.tools.security.BRKeyStore;
+import com.breadwallet.tools.security.PostAuth;
+import com.breadwallet.tools.security.SmartValidator;
+import com.breadwallet.tools.threads.BRExecutor;
+import com.breadwallet.tools.util.BRConstants;
+import com.breadwallet.tools.util.Utils;
+import com.breadwallet.wallet.BRWalletManager;
+import com.platform.APIClient;
+
+import org.w3c.dom.Text;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.Objects;
+
+import timber.log.Timber;
+
+public class IntroActivity extends BRActivity implements Serializable {
+ public Button newWalletButton;
+ public Button recoverWalletButton;
+ public static IntroActivity introActivity;
+ public static boolean appVisible = false;
+ private static IntroActivity app;
+ public RecyclerView listLangRecyclerView;
+ public IntroLanguageResource introLanguageResource = new IntroLanguageResource();
+ public static IntroActivity getApp() {
+ return app;
+ }
+
+ public static final Point screenParametersPoint = new Point();
+ @Override
+ protected void onRestart() {
+ super.onRestart(); // Always call the superclass method first
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_intro);
+ Log.i("Some", getPackageName());
+ newWalletButton = (Button) findViewById(R.id.button_new_wallet);
+ recoverWalletButton = (Button) findViewById(R.id.button_recover_wallet);
+ TextView description = findViewById(R.id.textView);
+
+ TextView versionText = findViewById(R.id.version_text);
+ listLangRecyclerView = findViewById(R.id.language_list);
+ View parentLayout = findViewById(android.R.id.content);
+ LinearLayoutManager layoutManager = new LinearLayoutManager(this);
+ CountryLanguageAdapter countryLanguageAdapter = new CountryLanguageAdapter(this, introLanguageResource.loadResources());
+ listLangRecyclerView.setAdapter(countryLanguageAdapter);
+
+ listLangRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
+ @Override
+ public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
+ super.onScrollStateChanged(recyclerView, newState);
+ if (newState == RecyclerView.SCROLL_STATE_IDLE) {
+ int firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition();
+ int lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition();
+
+ int centerPosition = (lastVisibleItemPosition - firstVisibleItemPosition) / 2 + firstVisibleItemPosition;
+ if (centerPosition != RecyclerView.NO_POSITION) {
+ countryLanguageAdapter.updateCenterPosition(centerPosition);
+ description.setText(countryLanguageAdapter.selectedDesc());
+ showDialogForItem(countryLanguageAdapter.selectedMessage());
+ }
+ }
+ }
+
+ });
+
+ listLangRecyclerView.setLayoutManager(layoutManager);
+
+ setListeners();
+ updateBundles();
+ if (!BuildConfig.DEBUG && BRKeyStore.AUTH_DURATION_SEC != 300) {
+ RuntimeException ex = new RuntimeException("onCreate: AUTH_DURATION_SEC should be 300");
+ Timber.e(ex);
+ throw ex;
+ }
+ introActivity = this;
+
+ getWindowManager().getDefaultDisplay().getSize(screenParametersPoint);
+ versionText.setText(BRConstants.APP_VERSION_NAME_CODE);
+
+ if (Utils.isEmulatorOrDebug(this))
+ Utils.printPhoneSpecs();
+
+ byte[] masterPubKey = BRKeyStore.getMasterPublicKey(this);
+ boolean isFirstAddressCorrect = false;
+ if (masterPubKey != null && masterPubKey.length != 0) {
+ Timber.d("timber: masterPubkey exists");
+
+ isFirstAddressCorrect = SmartValidator.checkFirstAddress(this, masterPubKey);
+ }
+ if (!isFirstAddressCorrect) {
+ Timber.d("timber: Calling wipeWalletButKeyStore");
+ BRWalletManager.getInstance().wipeWalletButKeystore(this);
+ }
+
+ if (BuildConfig.VERSION_NAME == "v2.8.4") {
+ Snackbar.make(parentLayout,
+ R.string.release_notes,
+ Snackbar.LENGTH_INDEFINITE).setAction(R.string.Webview_dismiss, new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+
+ }
+ })
+ .setActionTextColor(getResources().getColor(android.R.color.holo_red_light ))
+ .show();
+ }
+
+ PostAuth.getInstance().onCanaryCheck(this, false);
+ }
+
+ private void showDialogForItem(String title) {
+ Dialog dialog = new Dialog(IntroActivity.this);
+ dialog.setContentView(R.layout.pop_up_language_intro);
+ Objects.requireNonNull(dialog.getWindow()).setBackgroundDrawableResource(R.drawable.rounded_pop_up_intro);
+ Button btnYes = dialog.findViewById(R.id.button_yes);
+ Button btnNo = dialog.findViewById(R.id.button_no);
+ TextView txtTitle = dialog.findViewById(R.id.dialog_message);
+ txtTitle.setText(title);
+ btnYes.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ dialog.dismiss();
+ }
+ });
+
+ btnNo.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ dialog.dismiss();
+ }
+ });
+ dialog.show();
+ }
+
+ private void updateBundles() {
+ BRExecutor.getInstance().forBackgroundTasks().execute(new Runnable() {
+ @Override
+ public void run() {
+ Thread.currentThread().setName("updateBundle");
+ final long startTime = System.currentTimeMillis();
+ APIClient apiClient = APIClient.getInstance(IntroActivity.this);
+ long endTime = System.currentTimeMillis();
+ Timber.d("timber: updateBundle DONE in %sms",endTime - startTime);
+ }
+ });
+ }
+
+ private void setListeners() {
+ newWalletButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (!BRAnimator.isClickAllowed()) return;
+ BreadActivity bApp = BreadActivity.getApp();
+ if (bApp != null) bApp.finish();
+ Intent intent = new Intent(IntroActivity.this, SetPinActivity.class);
+ startActivity(intent);
+ overridePendingTransition(R.anim.enter_from_right, R.anim.exit_to_left);
+ }
+ });
+
+ recoverWalletButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (!BRAnimator.isClickAllowed()) return;
+ BreadActivity bApp = BreadActivity.getApp();
+ if (bApp != null) bApp.finish();
+ Intent intent = new Intent(IntroActivity.this, RecoverActivity.class);
+ startActivity(intent);
+ overridePendingTransition(R.anim.enter_from_right, R.anim.exit_to_left);
+ }
+ });
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ appVisible = true;
+ app = this;
+
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ appVisible = false;
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ }
+
+
+ @Override
+ public void onBackPressed() {
+ super.onBackPressed();
+
+ }
+
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/intro/RecoverActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/intro/RecoverActivity.java
new file mode 100644
index 000000000..5dd16d4f8
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/activities/intro/RecoverActivity.java
@@ -0,0 +1,66 @@
+package com.breadwallet.presenter.activities.intro;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.InputWordsActivity;
+import com.breadwallet.presenter.activities.util.ActivityUTILS;
+import com.breadwallet.presenter.activities.util.BRActivity;
+import com.breadwallet.tools.animation.BRAnimator;
+import com.breadwallet.tools.animation.SpringAnimator;
+
+public class RecoverActivity extends BRActivity {
+ private Button nextButton;
+ public static boolean appVisible = false;
+ private static RecoverActivity app;
+
+ public static RecoverActivity getApp() {
+ return app;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_intro_recover);
+
+ nextButton = (Button) findViewById(R.id.send_button);
+
+ nextButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (!BRAnimator.isClickAllowed()) return;
+ Intent intent = new Intent(RecoverActivity.this, InputWordsActivity.class);
+ startActivity(intent);
+ overridePendingTransition(R.anim.enter_from_right, R.anim.exit_to_left);
+ }
+ });
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ appVisible = true;
+ app = this;
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ appVisible = false;
+ }
+
+
+ @Override
+ public void onBackPressed() {
+ super.onBackPressed();
+ overridePendingTransition(R.anim.enter_from_left, R.anim.exit_to_right);
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/intro/WriteDownActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/intro/WriteDownActivity.java
new file mode 100644
index 000000000..47aa19e49
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/activities/intro/WriteDownActivity.java
@@ -0,0 +1,114 @@
+package com.breadwallet.presenter.activities.intro;
+
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.ImageButton;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.util.ActivityUTILS;
+import com.breadwallet.presenter.activities.util.BRActivity;
+import com.breadwallet.presenter.interfaces.BRAuthCompletion;
+import com.breadwallet.tools.animation.BRAnimator;
+import com.breadwallet.tools.security.AuthManager;
+import com.breadwallet.tools.security.PostAuth;
+import com.breadwallet.tools.util.BRConstants;
+
+public class WriteDownActivity extends BRActivity {
+ private Button writeButton;
+ private ImageButton closeButton;
+
+ public static boolean appVisible = false;
+ private static WriteDownActivity app;
+
+ public static WriteDownActivity getApp() {
+ return app;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_write_down);
+
+ writeButton = (Button) findViewById(R.id.button_write_down);
+// close = (ImageButton) findViewById(R.id.close_button);
+// close.setOnClickListener(new View.OnClickListener() {
+// @Override
+// public void onClick(View v) {
+// close();
+// }
+// });
+
+ closeButton = (ImageButton) findViewById(R.id.close_button);
+ closeButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ onBackPressed();
+ }
+ });
+
+// public void onBackPressed() {
+// super.onBackPressed();
+// overridePendingTransition(R.anim.fade_up, R.anim.exit_to_bottom);
+// }
+
+ //TODO: all views are using the layout of this button. Views should be refactored without it
+ // Hiding until layouts are built.
+ ImageButton faq = (ImageButton) findViewById(R.id.faq_button);
+
+ writeButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (!BRAnimator.isClickAllowed()) return;
+ AuthManager.getInstance().authPrompt(WriteDownActivity.this, null, getString(R.string.VerifyPin_continueBody), true, false, new BRAuthCompletion() {
+ @Override
+ public void onComplete() {
+ PostAuth.getInstance().onPhraseCheckAuth(WriteDownActivity.this, false);
+ }
+
+ @Override
+ public void onCancel() {
+
+ }
+ });
+
+ }
+ });
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ appVisible = true;
+ app = this;
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ appVisible = false;
+ }
+
+ @Override
+ public void onBackPressed() {
+ super.onBackPressed();
+ if (getFragmentManager().getBackStackEntryCount() == 0) {
+ close();
+ } else {
+ getFragmentManager().popBackStack();
+ }
+ }
+
+ private void close() {
+ BRAnimator.startBreadActivity(this, false);
+ overridePendingTransition(R.anim.fade_up, R.anim.exit_to_bottom);
+ if (!isDestroyed()) finish();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ }
+
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/settings/AboutActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/settings/AboutActivity.java
new file mode 100644
index 000000000..39abeac5a
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/activities/settings/AboutActivity.java
@@ -0,0 +1,125 @@
+package com.breadwallet.presenter.activities.settings;
+
+import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.util.ActivityUTILS;
+import com.breadwallet.presenter.activities.util.BRActivity;
+import com.breadwallet.tools.animation.BRAnimator;
+import com.breadwallet.tools.util.BRConstants;
+
+import java.util.Locale;
+
+import timber.log.Timber;
+
+public class AboutActivity extends BRActivity {
+ private static final String TAG = AboutActivity.class.getName();
+ private TextView policyText;
+ private TextView versionText;
+
+ private ImageView instagramShare;
+ private ImageView twitterShare;
+ private ImageView blogShare;
+ private static AboutActivity app;
+
+ private ImageButton closeButton;
+
+ public static AboutActivity getApp() {
+ return app;
+ }
+
+ public static boolean appVisible = false;
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_about);
+
+ versionText = (TextView) findViewById(R.id.info_text);
+ policyText = (TextView) findViewById(R.id.policy_text);
+ instagramShare = (ImageView) findViewById(R.id.instagram_share_button);
+ twitterShare = (ImageView) findViewById(R.id.twitter_share_button);
+ blogShare = (ImageView) findViewById(R.id.blog_share_button);
+ versionText.setText(BRConstants.APP_VERSION_NAME_CODE);
+
+ instagramShare.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(BRConstants.INSTAGRAM_LINK));
+ startActivity(browserIntent);
+ app.overridePendingTransition(R.anim.enter_from_bottom, R.anim.empty_300);
+ }
+ });
+
+ twitterShare.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(BRConstants.TWITTER_LINK));
+ startActivity(browserIntent);
+ app.overridePendingTransition(R.anim.enter_from_bottom, R.anim.empty_300);
+ }
+ });
+ blogShare.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(BRConstants.WEB_LINK));
+ startActivity(browserIntent);
+ app.overridePendingTransition(R.anim.enter_from_bottom, R.anim.empty_300);
+ }
+ });
+ policyText.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(BRConstants.TOS_LINK));
+ startActivity(browserIntent);
+ app.overridePendingTransition(R.anim.enter_from_bottom, R.anim.empty_300);
+ }
+ });
+
+ closeButton = (ImageButton) findViewById(R.id.close_button);
+ closeButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ onBackPressed();
+ }
+ });
+
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ appVisible = true;
+ app = this;
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ appVisible = false;
+ }
+
+ @Override
+ public void onBackPressed() {
+ if (ActivityUTILS.isLast(this)) {
+ BRAnimator.startBreadActivity(this, false);
+ } else {
+ super.onBackPressed();
+ }
+ overridePendingTransition(R.anim.enter_from_left, R.anim.exit_to_right);
+ }
+
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/settings/AdvancedActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/settings/AdvancedActivity.java
new file mode 100644
index 000000000..8e6543baa
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/activities/settings/AdvancedActivity.java
@@ -0,0 +1,139 @@
+package com.breadwallet.presenter.activities.settings;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import androidx.annotation.LayoutRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.util.BRActivity;
+import com.breadwallet.presenter.entities.BRSettingsItem;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.breadwallet.R.layout.settings_list_item;
+import static com.breadwallet.R.layout.settings_list_section;
+
+public class AdvancedActivity extends BRActivity {
+ private static final String TAG = AdvancedActivity.class.getName();
+ private ListView listView;
+ public List items;
+ public static boolean appVisible = false;
+ private static AdvancedActivity app;
+
+ public static AdvancedActivity getApp() {
+ return app;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_advanced);
+
+ listView = (ListView) findViewById(R.id.settings_list);
+
+ }
+
+
+ public class SettingsListAdapter extends ArrayAdapter {
+
+ private List items;
+ private Context mContext;
+
+ public SettingsListAdapter(@NonNull Context context, @LayoutRes int resource, @NonNull List items) {
+ super(context, resource);
+ this.items = items;
+ this.mContext = context;
+ }
+
+ @NonNull
+ @Override
+ public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
+
+ View v;
+ BRSettingsItem item = items.get(position);
+ LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
+
+ if (item.isSection) {
+ v = inflater.inflate(settings_list_section, parent, false);
+ } else {
+ v = inflater.inflate(settings_list_item, parent, false);
+ TextView addon = (TextView) v.findViewById(R.id.item_addon);
+ addon.setText(item.addonText);
+ v.setOnClickListener(item.listener);
+ }
+
+ TextView title = (TextView) v.findViewById(R.id.item_title);
+ title.setText(item.title);
+ return v;
+
+ }
+
+ @Override
+ public int getCount() {
+ return items == null ? 0 : items.size();
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return super.getItemViewType(position);
+ }
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ appVisible = true;
+ app = this;
+ if (items == null)
+ items = new ArrayList<>();
+ items.clear();
+
+ populateItems();
+
+ listView.setAdapter(new SettingsListAdapter(this, R.layout.settings_list_item, items));
+ }
+
+
+ @Override
+ public void onBackPressed() {
+ super.onBackPressed();
+ overridePendingTransition(R.anim.enter_from_left, R.anim.exit_to_right);
+ }
+
+ private void populateItems() {
+
+ items.add(new BRSettingsItem("", "", null, true));
+
+ items.add(new BRSettingsItem(getString(R.string.NodeSelector_title), "", new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent intent = new Intent(AdvancedActivity.this, NodesActivity.class);
+ startActivity(intent);
+ overridePendingTransition(R.anim.enter_from_right, R.anim.empty_300);
+
+ }
+ }, false));
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ appVisible = false;
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/settings/DisplayCurrencyActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/settings/DisplayCurrencyActivity.java
new file mode 100644
index 000000000..3cbe551d5
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/activities/settings/DisplayCurrencyActivity.java
@@ -0,0 +1,235 @@
+package com.breadwallet.presenter.activities.settings;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Point;
+import android.os.Bundle;
+import android.util.TypedValue;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.util.BRActivity;
+import com.breadwallet.presenter.entities.CurrencyEntity;
+import com.breadwallet.tools.manager.BRSharedPrefs;
+import com.breadwallet.tools.sqlite.CurrencyDataSource;
+import com.breadwallet.tools.util.BRConstants;
+import com.breadwallet.tools.util.BRCurrency;
+
+import java.math.BigDecimal;
+import java.util.Currency;
+
+import timber.log.Timber;
+
+
+public class DisplayCurrencyActivity extends BRActivity {
+ private TextView exchangeText;
+ private ListView listView;
+ private CurrencyListAdapter adapter;
+ // private String ISO;
+// private float rate;
+ public static boolean appVisible = false;
+ private static DisplayCurrencyActivity app;
+ private Button leftButton;
+ private Button rightButton;
+
+ private ImageButton closeButton;
+
+ public static DisplayCurrencyActivity getApp() {
+ return app;
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_display_currency);
+
+ //TODO: all views are using the layout of this button. Views should be refactored without it
+ // Hiding until layouts are built.
+ ImageButton faq = findViewById(R.id.faq_button);
+
+ exchangeText = findViewById(R.id.exchange_text);
+ listView = findViewById(R.id.currency_list_view);
+ adapter = new CurrencyListAdapter(this);
+ adapter.addAll(CurrencyDataSource.getInstance(this).getAllCurrencies());
+ leftButton = findViewById(R.id.left_button);
+ rightButton = findViewById(R.id.right_button);
+ leftButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ setButton(true);
+ }
+ });
+
+ rightButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ setButton(false);
+ }
+ });
+
+ int unit = BRSharedPrefs.getCurrencyUnit(this);
+ if (unit == BRConstants.CURRENT_UNIT_LITES) {
+ setButton(true);
+ } else {
+ setButton(false);
+ }
+ updateExchangeRate();
+ listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view,
+ int position, long id) {
+ TextView currencyItemText = (TextView) view.findViewById(R.id.currency_item_text);
+ final String selectedCurrency = currencyItemText.getText().toString();
+ String iso = selectedCurrency.substring(0, 3);
+ BRSharedPrefs.putIso(DisplayCurrencyActivity.this, iso);
+ BRSharedPrefs.putCurrencyListPosition(DisplayCurrencyActivity.this, position);
+
+ updateExchangeRate();
+ }
+ });
+ listView.setAdapter(adapter);
+ adapter.notifyDataSetChanged();
+
+
+ closeButton = (ImageButton) findViewById(R.id.close_button);
+ closeButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ onBackPressed();
+ }
+ });
+ }
+
+ private void updateExchangeRate() {
+ //set the rate from the last saved
+ String iso = BRSharedPrefs.getIso(this);
+ CurrencyEntity entity = CurrencyDataSource.getInstance(this).getCurrencyByIso(iso);
+ if (entity != null) {
+ String finalExchangeRate = BRCurrency.getFormattedCurrencyString(DisplayCurrencyActivity.this, BRSharedPrefs.getIso(this), new BigDecimal(entity.rate));
+ boolean bits = BRSharedPrefs.getCurrencyUnit(this) == BRConstants.CURRENT_UNIT_LITES;
+ exchangeText.setText(BRCurrency.getFormattedCurrencyString(this, "LTC", new BigDecimal(bits ? 1000 : 1)) + " = " + finalExchangeRate);
+ }
+ adapter.notifyDataSetChanged();
+ }
+
+ private void setButton(boolean left) {
+ if (left) {
+ BRSharedPrefs.putCurrencyUnit(this, BRConstants.CURRENT_UNIT_LITES);
+ leftButton.setTextColor(getColor(R.color.white));
+ leftButton.setBackground(getDrawable(R.drawable.b_half_left_blue));
+ rightButton.setTextColor(getColor(R.color.dark_blue));
+ rightButton.setBackground(getDrawable(R.drawable.b_half_right_blue_stroke));
+ } else {
+ BRSharedPrefs.putCurrencyUnit(this, BRConstants.CURRENT_UNIT_LITECOINS);
+ leftButton.setTextColor(getColor(R.color.dark_blue));
+ leftButton.setBackground(getDrawable(R.drawable.b_half_left_blue_stroke));
+ rightButton.setTextColor(getColor(R.color.white));
+ rightButton.setBackground(getDrawable(R.drawable.b_half_right_blue));
+ }
+ updateExchangeRate();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ appVisible = true;
+ app = this;
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ appVisible = false;
+ }
+
+ @Override
+ public void onBackPressed() {
+ super.onBackPressed();
+ overridePendingTransition(R.anim.enter_from_left, R.anim.exit_to_right);
+ }
+
+ public class CurrencyListAdapter extends ArrayAdapter {
+ public final String TAG = CurrencyListAdapter.class.getName();
+
+ private final Context mContext;
+ private final int layoutResourceId;
+ private TextView textViewItem;
+ private final Point displayParameters = new Point();
+
+ public CurrencyListAdapter(Context mContext) {
+ super(mContext, R.layout.currency_list_item);
+
+ this.layoutResourceId = R.layout.currency_list_item;
+ this.mContext = mContext;
+ ((Activity) mContext).getWindowManager().getDefaultDisplay().getSize(displayParameters);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+
+ final int tmp = BRSharedPrefs.getCurrencyListPosition(mContext);
+
+ if (convertView == null) {
+ // inflate the layout
+ LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
+ convertView = inflater.inflate(layoutResourceId, parent, false);
+ }
+ // get the TextView and then set the text (item name) and tag (item ID) values
+ textViewItem = convertView.findViewById(R.id.currency_item_text);
+ String iso = getItem(position).code;
+ Currency c = null;
+ try {
+ c = Currency.getInstance(iso);
+ } catch (IllegalArgumentException ignored) {
+ }
+ textViewItem.setText(c == null ? iso : String.format("%s (%s)", iso, c.getSymbol()));
+ ImageView checkMark = convertView.findViewById(R.id.currency_checkmark);
+ Timber.d( "Value of TMP %s", tmp);
+ Timber.d( "Value of position %s", position);
+ if (position == tmp) {
+ checkMark.setVisibility(View.VISIBLE);
+ } else {
+ checkMark.setVisibility(View.GONE);
+ }
+ normalizeTextView();
+ return convertView;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return IGNORE_ITEM_VIEW_TYPE;
+ }
+
+ private boolean isTextSizeAcceptable(TextView textView) {
+ textView.measure(0, 0);
+ int textWidth = textView.getMeasuredWidth();
+ int checkMarkWidth = 76 + 20;
+ return (textWidth <= (displayParameters.x - checkMarkWidth));
+ }
+
+ private boolean normalizeTextView() {
+ int count = 0;
+ while (!isTextSizeAcceptable(textViewItem)) {
+ count++;
+ float textSize = textViewItem.getTextSize();
+ textViewItem.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize - 2);
+ this.notifyDataSetChanged();
+ }
+ return (count > 0);
+ }
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/settings/FingerprintActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/settings/FingerprintActivity.java
new file mode 100644
index 000000000..794b9c0b0
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/activities/settings/FingerprintActivity.java
@@ -0,0 +1,158 @@
+package com.breadwallet.presenter.activities.settings;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.text.SpannableString;
+import android.text.Spanned;
+import android.text.TextPaint;
+import android.text.method.LinkMovementMethod;
+import android.text.style.ClickableSpan;
+import android.view.View;
+import android.widget.CompoundButton;
+import android.widget.ImageButton;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+import android.widget.ToggleButton;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.util.BRActivity;
+import com.breadwallet.presenter.customviews.BRDialogView;
+import com.breadwallet.presenter.interfaces.BRAuthCompletion;
+import com.breadwallet.tools.animation.BRDialog;
+import com.breadwallet.tools.manager.BRSharedPrefs;
+import com.breadwallet.tools.security.AuthManager;
+import com.breadwallet.tools.security.BRKeyStore;
+import com.breadwallet.tools.util.BRCurrency;
+import com.breadwallet.tools.util.BRExchange;
+import com.breadwallet.tools.util.Utils;
+
+import java.math.BigDecimal;
+
+import timber.log.Timber;
+
+
+public class FingerprintActivity extends BRActivity {
+
+ public RelativeLayout layout;
+ public static boolean appVisible = false;
+ private static FingerprintActivity app;
+ private TextView limitExchange;
+ private TextView limitInfo;
+
+ private ToggleButton toggleButton;
+
+ public static FingerprintActivity getApp() {
+ return app;
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_fingerprint);
+ toggleButton = (ToggleButton) findViewById(R.id.toggleButton);
+ limitExchange = (TextView) findViewById(R.id.limit_exchange);
+ limitInfo = (TextView) findViewById(R.id.limit_info);
+
+ ImageButton faq = (ImageButton) findViewById(R.id.faq_button);
+ //TODO: all views are using the layout of this button. Views should be refactored without it
+ // Hiding until layouts are built.
+
+ toggleButton.setChecked(BRSharedPrefs.getUseFingerprint(this));
+
+ limitExchange.setText(getLimitText());
+
+ toggleButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ Activity app = FingerprintActivity.this;
+ if (isChecked && !Utils.isFingerprintEnrolled(app)) {
+ Timber.d("timber: onCheckedChanged: fingerprint not setup");
+ BRDialog.showCustomDialog(app, getString(R.string.TouchIdSettings_disabledWarning_title_android), getString(R.string.TouchIdSettings_disabledWarning_body_android), getString(R.string.Button_ok), null, new BRDialogView.BROnClickListener() {
+ @Override
+ public void onClick(BRDialogView brDialogView) {
+ brDialogView.dismissWithAnimation();
+ }
+ }, null, null, 0);
+ buttonView.setChecked(false);
+ } else {
+ BRSharedPrefs.putUseFingerprint(app, isChecked);
+ }
+ }
+ });
+ SpannableString ss = new SpannableString(getString(R.string.TouchIdSettings_customizeText_android));
+ ClickableSpan clickableSpan = new ClickableSpan() {
+ @Override
+ public void onClick(View textView) {
+
+ AuthManager.getInstance().authPrompt(FingerprintActivity.this, null, getString(R.string.VerifyPin_continueBody), true, false, new BRAuthCompletion() {
+ @Override
+ public void onComplete() {
+ Intent intent = new Intent(FingerprintActivity.this, SpendLimitActivity.class);
+ overridePendingTransition(R.anim.enter_from_right, R.anim.exit_to_left);
+ startActivity(intent);
+ finish();
+ }
+
+ @Override
+ public void onCancel() {
+
+ }
+ });
+ }
+
+ @Override
+ public void updateDrawState(TextPaint ds) {
+ super.updateDrawState(ds);
+ ds.setUnderlineText(false);
+ }
+ };
+ //start index of the last space (beginning of the last word)
+ int indexOfSpace = limitInfo.getText().toString().lastIndexOf(" ");
+ // make the whole text clickable if failed to select the last word
+ ss.setSpan(clickableSpan, indexOfSpace == -1 ? 0 : indexOfSpace, limitInfo.getText().length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+
+ limitInfo.setText(ss);
+ limitInfo.setMovementMethod(LinkMovementMethod.getInstance());
+ limitInfo.setHighlightColor(Color.TRANSPARENT);
+
+ }
+
+ private String getLimitText() {
+ String iso = BRSharedPrefs.getIso(this);
+ //amount in satoshis
+ BigDecimal satoshis = new BigDecimal(BRKeyStore.getSpendLimit(this));
+ //amount in BTC, mBTC or bits
+ BigDecimal amount = BRExchange.getAmountFromSatoshis(this, "LTC", satoshis);
+ //amount in user preferred ISO (e.g. USD)
+ BigDecimal curAmount = BRExchange.getAmountFromSatoshis(this, iso, satoshis);
+ //formatted string for the label
+ return String.format(getString(R.string.TouchIdSettings_spendingLimit), BRCurrency.getFormattedCurrencyString(this, "LTC", amount), BRCurrency.getFormattedCurrencyString(this, iso, curAmount));
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ appVisible = true;
+ app = this;
+ }
+
+ @Override
+ public void onBackPressed() {
+ super.onBackPressed();
+ overridePendingTransition(R.anim.enter_from_left, R.anim.exit_to_right);
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ appVisible = false;
+ }
+
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/settings/ImportActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/settings/ImportActivity.java
new file mode 100644
index 000000000..0155bbf55
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/activities/settings/ImportActivity.java
@@ -0,0 +1,106 @@
+package com.breadwallet.presenter.activities.settings;
+
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import androidx.annotation.NonNull;
+import android.view.View;
+import android.widget.Button;
+import android.widget.ImageButton;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.util.BRActivity;
+import com.breadwallet.tools.animation.BRAnimator;
+import com.breadwallet.tools.util.BRConstants;
+
+
+public class ImportActivity extends BRActivity {
+ private Button scan;
+ private static final String TAG = ImportActivity.class.getName();
+ public static boolean appVisible = false;
+ private static ImportActivity app;
+ private ImageButton closeButton;
+
+ public static ImportActivity getApp() {
+ return app;
+ }
+
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_import);
+
+ scan = (Button) findViewById(R.id.scan_button);
+ closeButton = (ImageButton) findViewById(R.id.close_button);
+ closeButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ onBackPressed();
+ }
+ });
+
+ ImageButton faq = (ImageButton) findViewById(R.id.faq_button);
+ //TODO: all views are using the layout of this button. Views should be refactored without it
+ // Hiding until layouts are built.
+
+ scan.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (!BRAnimator.isClickAllowed()) return;
+ BRAnimator.openScanner(ImportActivity.this, BRConstants.SCANNER_REQUEST);
+ }
+ });
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ appVisible = true;
+ app = this;
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ appVisible = false;
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ }
+
+ @Override
+ public void onBackPressed() {
+ super.onBackPressed();
+ overridePendingTransition(R.anim.fade_up, R.anim.exit_to_bottom);
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+
+ switch (requestCode) {
+ case BRConstants.CAMERA_REQUEST_ID: {
+ // If request is cancelled, the result arrays are empty.
+ if (grantResults.length > 0
+ && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ BRAnimator.openScanner(this,BRConstants.SCANNER_REQUEST);
+ // permission was granted, yay! Do the
+ // contacts-related task you need to do.
+
+ } else {
+
+ // permission denied, boo! Disable the
+ // functionality that depends on this permission.
+ }
+ return;
+ }
+
+ // other 'case' lines to check for other
+ // permissions this app might request
+ }
+ }
+
+
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/settings/NodesActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/settings/NodesActivity.java
new file mode 100644
index 000000000..75a256aae
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/activities/settings/NodesActivity.java
@@ -0,0 +1,247 @@
+package com.breadwallet.presenter.activities.settings;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.os.Handler;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ImageButton;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.util.ActivityUTILS;
+import com.breadwallet.presenter.activities.util.BRActivity;
+import com.breadwallet.tools.animation.BRAnimator;
+import com.breadwallet.tools.manager.BRSharedPrefs;
+import com.breadwallet.tools.threads.BRExecutor;
+import com.breadwallet.tools.util.TrustedNode;
+import com.breadwallet.tools.util.Utils;
+import com.breadwallet.wallet.BRPeerManager;
+
+
+public class NodesActivity extends BRActivity {
+ private static final String TAG = NodesActivity.class.getName();
+ private Button switchButton;
+ private TextView nodeStatus;
+ private TextView trustNode;
+ public static boolean appVisible = false;
+ AlertDialog mDialog;
+ private int mInterval = 3000;
+ private Handler mHandler;
+ private boolean updatingNode;
+// private TextView nodeLabel;
+
+ Runnable mStatusChecker = new Runnable() {
+ @Override
+ public void run() {
+ try {
+ //this function can change value of mInterval.
+ updateButtonText();
+ } finally {
+ // 100% guarantee that this always happens, even if
+ // your update method throws an exception
+ mHandler.postDelayed(mStatusChecker, mInterval);
+ }
+ }
+ };
+ private static NodesActivity app;
+
+
+ public static NodesActivity getApp() {
+ return app;
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_nodes);
+
+ //TODO: all views are using the layout of this button. Views should be refactored without it
+ // Hiding until layouts are built.
+ ImageButton faq = (ImageButton) findViewById(R.id.faq_button);
+ nodeStatus = (TextView) findViewById(R.id.node_status);
+ trustNode = (TextView) findViewById(R.id.node_text);
+
+ switchButton = (Button) findViewById(R.id.button_switch);
+ switchButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (!BRAnimator.isClickAllowed()) return;
+
+ if (BRSharedPrefs.getTrustNode(NodesActivity.this).isEmpty()) {
+ createDialog();
+ } else {
+ if (!updatingNode) {
+ updatingNode = true;
+ BRSharedPrefs.putTrustNode(NodesActivity.this, "");
+ BRExecutor.getInstance().forLightWeightBackgroundTasks().execute(new Runnable() {
+ @Override
+ public void run() {
+ BRPeerManager.getInstance().updateFixedPeer(NodesActivity.this);
+ updatingNode = false;
+ BRExecutor.getInstance().forMainThreadTasks().execute(new Runnable() {
+ @Override
+ public void run() {
+ updateButtonText();
+ }
+ });
+
+ }
+ });
+ }
+
+ }
+
+ }
+ });
+
+ updateButtonText();
+
+ }
+
+ private void updateButtonText() {
+ if (BRSharedPrefs.getTrustNode(this).isEmpty()) {
+ switchButton.setText(getString(R.string.NodeSelector_manualButton));
+ } else {
+ switchButton.setText(getString(R.string.NodeSelector_automaticButton));
+ }
+ nodeStatus.setText(BRPeerManager.getInstance().isConnected() ? getString(R.string.NodeSelector_connected) : getString(R.string.NodeSelector_notConnected));
+ if (trustNode != null)
+ trustNode.setText(BRPeerManager.getInstance().getCurrentPeerName());
+ }
+
+ private void createDialog() {
+
+ final AlertDialog.Builder alertDialog = new AlertDialog.Builder(app);
+ final TextView customTitle = new TextView(this);
+
+ customTitle.setGravity(Gravity.CENTER);
+ customTitle.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
+ int pad32 = Utils.getPixelsFromDps(app, 32);
+ int pad16 = Utils.getPixelsFromDps(app, 16);
+ customTitle.setPadding(pad16, pad16, pad16, pad16);
+ customTitle.setText(getString(R.string.NodeSelector_enterTitle));
+ customTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
+ customTitle.setTypeface(null, Typeface.BOLD);
+ alertDialog.setCustomTitle(customTitle);
+ alertDialog.setMessage(getString(R.string.NodeSelector_enterBody));
+
+ final EditText input = new EditText(app);
+ LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.MATCH_PARENT,
+ LinearLayout.LayoutParams.MATCH_PARENT);
+ int pix = Utils.getPixelsFromDps(app, 24);
+
+ input.setPadding(pix, 0, pix, pix);
+ input.setLayoutParams(lp);
+ alertDialog.setView(input);
+
+ alertDialog.setNegativeButton(getString(R.string.Button_cancel),
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.cancel();
+ }
+ });
+
+ alertDialog.setPositiveButton(getString(R.string.Button_ok),
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+
+ }
+ });
+
+ mDialog = alertDialog.show();
+
+ //Overriding the handler immediately after show is probably a better approach than OnShowListener as described below
+ mDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ String str = input.getText().toString();
+ if (TrustedNode.isValid(str)) {
+ mDialog.setMessage("");
+ BRSharedPrefs.putTrustNode(app, str);
+ if (!updatingNode) {
+ updatingNode = true;
+ customTitle.setText(getString(R.string.Webview_updating));
+ BRExecutor.getInstance().forLightWeightBackgroundTasks().execute(new Runnable() {
+ @Override
+ public void run() {
+ BRPeerManager.getInstance().updateFixedPeer(app);
+ updatingNode = false;
+ BRExecutor.getInstance().forMainThreadTasks().execute(new Runnable() {
+ @Override
+ public void run() {
+ customTitle.setText(getString(R.string.RecoverWallet_done));
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ mDialog.dismiss();
+ updateButtonText();
+ }
+ }, 500);
+
+ }
+ });
+ }
+ });
+ }
+
+ } else {
+ customTitle.setText("Invalid Node");
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ customTitle.setText(getString(R.string.NodeSelector_enterTitle));
+ }
+ }, 1000);
+ }
+ updateButtonText();
+ }
+ });
+ }
+
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ appVisible = true;
+ app = this;
+ mHandler = new Handler();
+ startRepeatingTask();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ appVisible = false;
+ stopRepeatingTask();
+ }
+
+ void startRepeatingTask() {
+ mStatusChecker.run();
+ }
+
+ void stopRepeatingTask() {
+ mHandler.removeCallbacks(mStatusChecker);
+ }
+
+ @Override
+ public void onBackPressed() {
+ super.onBackPressed();
+ overridePendingTransition(R.anim.enter_from_left, R.anim.exit_to_right);
+ }
+
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/settings/NotificationActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/settings/NotificationActivity.java
new file mode 100644
index 000000000..cffd9158c
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/activities/settings/NotificationActivity.java
@@ -0,0 +1,62 @@
+package com.breadwallet.presenter.activities.settings;
+
+import android.os.Bundle;
+import android.widget.CompoundButton;
+import android.widget.ToggleButton;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.util.ActivityUTILS;
+import com.breadwallet.presenter.activities.util.BRActivity;
+import com.breadwallet.tools.manager.BRSharedPrefs;
+
+public class NotificationActivity extends BRActivity {
+ private static final String TAG = NotificationActivity.class.getName();
+ private ToggleButton toggleButton;
+ public static boolean appVisible = false;
+ private static NotificationActivity app;
+
+ public static NotificationActivity getApp() {
+ return app;
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_notification);
+
+ toggleButton = (ToggleButton) findViewById(R.id.toggleButton);
+ toggleButton.setChecked(BRSharedPrefs.getShowNotification(this));
+ toggleButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ BRSharedPrefs.putShowNotification(NotificationActivity.this, isChecked);
+ }
+ });
+
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ appVisible = true;
+ app = this;
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ appVisible = false;
+ }
+
+ @Override
+ public void onBackPressed() {
+ super.onBackPressed();
+ overridePendingTransition(R.anim.enter_from_left, R.anim.exit_to_right);
+ }
+
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/settings/SecurityCenterActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/settings/SecurityCenterActivity.java
new file mode 100644
index 000000000..8481ddc4a
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/activities/settings/SecurityCenterActivity.java
@@ -0,0 +1,190 @@
+package com.breadwallet.presenter.activities.settings;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import androidx.annotation.LayoutRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.UpdatePinActivity;
+import com.breadwallet.presenter.activities.intro.WriteDownActivity;
+import com.breadwallet.presenter.activities.util.ActivityUTILS;
+import com.breadwallet.presenter.activities.util.BRActivity;
+import com.breadwallet.presenter.entities.BRSecurityCenterItem;
+import com.breadwallet.tools.animation.BRAnimator;
+import com.breadwallet.tools.manager.BRSharedPrefs;
+import com.breadwallet.tools.security.BRKeyStore;
+import com.breadwallet.tools.util.Utils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SecurityCenterActivity extends BRActivity {
+
+ public ListView mListView;
+ public RelativeLayout layout;
+ public List itemList;
+ public static boolean appVisible = false;
+ private static SecurityCenterActivity app;
+ private ImageButton close;
+
+ public static SecurityCenterActivity getApp() {
+ return app;
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_security_center);
+
+ itemList = new ArrayList<>();
+ mListView = (ListView) findViewById(R.id.menu_listview);
+ mListView.addFooterView(new View(this), null, true);
+ mListView.addHeaderView(new View(this), null, true);
+ mListView.setVerticalScrollBarEnabled(false);
+ mListView.setClickable(false);
+ close = (ImageButton) findViewById(R.id.close_button);
+ close.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (!BRAnimator.isClickAllowed()) return;
+ onBackPressed();
+ }
+ });
+
+ updateList();
+
+ ImageButton faq = (ImageButton) findViewById(R.id.faq_button);
+ //TODO: all views are using the layout of this button. Views should be refactored without it
+ // Hiding until layouts are built.
+
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ updateList();
+ appVisible = true;
+ app = this;
+ }
+
+ @Override
+ public void onBackPressed() {
+ super.onBackPressed();
+ if (ActivityUTILS.isLast(this)) {
+ BRAnimator.startBreadActivity(this, false);
+ } else {
+ super.onBackPressed();
+ }
+ overridePendingTransition(R.anim.fade_up, R.anim.exit_to_bottom);
+ }
+
+ public RelativeLayout getMainLayout() {
+ return layout;
+ }
+
+ public class SecurityCenterListAdapter extends ArrayAdapter {
+
+ private List items;
+ private Context mContext;
+ private int defaultLayoutResource = R.layout.security_center_list_item;
+
+ public SecurityCenterListAdapter(@NonNull Context context, @LayoutRes int resource, @NonNull List items) {
+ super(context, resource);
+ this.items = items;
+ this.mContext = context;
+ }
+
+ @NonNull
+ @Override
+ public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
+ if (convertView == null) {
+ // inflate the layout
+ LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
+ convertView = inflater.inflate(defaultLayoutResource, parent, false);
+ }
+ TextView title = (TextView) convertView.findViewById(R.id.item_title);
+ TextView text = (TextView) convertView.findViewById(R.id.item_text);
+ ImageView checkMark = (ImageView) convertView.findViewById(R.id.check_mark);
+
+ title.setText(items.get(position).title);
+ text.setText(items.get(position).text);
+ checkMark.setImageResource(items.get(position).checkMarkResId);
+ convertView.setOnClickListener(items.get(position).listener);
+ return convertView;
+ }
+
+ @Override
+ public int getCount() {
+ return items == null ? 0 : items.size();
+ }
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ appVisible = false;
+ }
+
+ private void updateList() {
+ boolean isPinSet = BRKeyStore.getPinCode(this).length() == 6;
+ itemList.clear();
+ itemList.add(new BRSecurityCenterItem(getString(R.string.SecurityCenter_pinTitle), getString(R.string.SecurityCenter_pinDescription),
+ isPinSet ? R.drawable.ic_check_mark_blue : R.drawable.ic_check_mark_grey, new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent intent = new Intent(SecurityCenterActivity.this, UpdatePinActivity.class);
+ startActivity(intent);
+ overridePendingTransition(R.anim.enter_from_right, R.anim.exit_to_left);
+ }
+ }));
+
+ int resId = Utils.isFingerprintEnrolled(SecurityCenterActivity.this)
+ && BRSharedPrefs.getUseFingerprint(SecurityCenterActivity.this)
+ ? R.drawable.ic_check_mark_blue
+ : R.drawable.ic_check_mark_grey;
+
+ if (Utils.isFingerprintAvailable(this)) {
+ itemList.add(new BRSecurityCenterItem(getString(R.string.SecurityCenter_touchIdTitle_android), getString(R.string.SecurityCenter_touchIdDescription),
+ resId, new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent intent = new Intent(SecurityCenterActivity.this, FingerprintActivity.class);
+ startActivity(intent);
+ overridePendingTransition(R.anim.enter_from_right, R.anim.exit_to_left);
+ }
+ }));
+ }
+
+ boolean isPaperKeySet = BRSharedPrefs.getPhraseWroteDown(this);
+ itemList.add(new BRSecurityCenterItem(getString(R.string.SecurityCenter_paperKeyTitle), getString(R.string.SecurityCenter_paperKeyDescription),
+ isPaperKeySet ? R.drawable.ic_check_mark_blue : R.drawable.ic_check_mark_grey, new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent intent = new Intent(SecurityCenterActivity.this, WriteDownActivity.class);
+ startActivity(intent);
+ overridePendingTransition(R.anim.enter_from_bottom, R.anim.fade_down);
+ }
+ }));
+
+ mListView.setAdapter(new SecurityCenterListAdapter(this, R.layout.menu_list_item, itemList));
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/settings/SettingsActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/settings/SettingsActivity.java
new file mode 100644
index 000000000..a5b2b0662
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/activities/settings/SettingsActivity.java
@@ -0,0 +1,232 @@
+package com.breadwallet.presenter.activities.settings;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.CompoundButton;
+import android.widget.ImageButton;
+import android.widget.ListView;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+import android.widget.ToggleButton;
+
+import androidx.annotation.LayoutRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.DisabledActivity;
+import com.breadwallet.presenter.activities.InputWordsActivity;
+import com.breadwallet.presenter.language.ChangeLanguageBottomSheet;
+import com.breadwallet.presenter.activities.util.BRActivity;
+import com.breadwallet.presenter.entities.BRSettingsItem;
+import com.breadwallet.presenter.interfaces.BRAuthCompletion;
+import com.breadwallet.tools.manager.BRSharedPrefs;
+import com.breadwallet.tools.security.AuthManager;
+import com.platform.APIClient;
+import com.breadwallet.tools.animation.BRAnimator;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.breadwallet.R.layout.settings_list_item;
+import static com.breadwallet.R.layout.settings_list_section;
+
+public class SettingsActivity extends BRActivity {
+ private ListView listView;
+ public List items;
+ public static boolean appVisible = false;
+ private ImageButton closeButton;
+ private static SettingsActivity app;
+ public static SettingsActivity getApp() {
+ return app;
+ }
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_settings);
+
+
+ listView = findViewById(R.id.settings_list);
+
+ closeButton = (ImageButton) findViewById(R.id.close_button);
+ closeButton.setOnClickListener(v -> finish());
+ }
+
+ public class SettingsListAdapter extends ArrayAdapter {
+
+ private List items;
+ private Context mContext;
+
+ public SettingsListAdapter(@NonNull Context context, @LayoutRes int resource, @NonNull List items) {
+ super(context, resource);
+ this.items = items;
+ this.mContext = context;
+ }
+
+ @NonNull
+ @Override
+ public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
+
+ View v;
+ BRSettingsItem item = items.get(position);
+ LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
+
+ if (item.isSection) {
+ v = inflater.inflate(settings_list_section, parent, false);
+ } else {
+ v = inflater.inflate(settings_list_item, parent, false);
+ TextView addon = (TextView) v.findViewById(R.id.item_addon);
+ addon.setText(item.addonText);
+ v.setOnClickListener(item.listener);
+ }
+
+ TextView title = (TextView) v.findViewById(R.id.item_title);
+ title.setText(item.title);
+ return v;
+
+ }
+
+ @Override
+ public int getCount() {
+ return items == null ? 0 : items.size();
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return super.getItemViewType(position);
+ }
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ appVisible = true;
+ app = this;
+ if (items == null)
+ items = new ArrayList<>();
+ items.clear();
+
+ populateItems();
+
+ listView.setAdapter(new SettingsListAdapter(this, R.layout.settings_list_item, items));
+ }
+
+ @Override
+ public void onBackPressed() {
+ super.onBackPressed();
+ overridePendingTransition(R.anim.fade_up, R.anim.exit_to_bottom);
+ }
+
+ private void populateItems() {
+
+ /*Wallet Title*/
+ items.add(new BRSettingsItem(getString(R.string.Settings_wallet), "", null, true));
+
+ /*Import Title*/
+ items.add(new BRSettingsItem(getString(R.string.Settings_importTitle), "", v -> {
+ Intent intent = new Intent(SettingsActivity.this, ImportActivity.class);
+ startActivity(intent);
+ overridePendingTransition(R.anim.enter_from_bottom, R.anim.empty_300);
+
+ }, false));
+
+ /*Show Seed Phrase*/
+ items.add(new BRSettingsItem(getString(R.string.settings_show_seed), "", v -> {
+ BRAnimator.showBalanceSeedFragment(this);
+ }, false));
+
+ /*Wipe Start_Recover Wallet*/
+ items.add(new BRSettingsItem(getString(R.string.Settings_wipe), "", v -> {
+ Intent intent = new Intent(SettingsActivity.this, WipeActivity.class);
+ startActivity(intent);
+ overridePendingTransition(R.anim.enter_from_bottom, R.anim.empty_300);
+ }, false));
+
+ /*Manage Title*/
+ items.add(new BRSettingsItem(getString(R.string.Settings_manage), "", null, true));
+
+ /*Fingerprint Limits*/
+ if (AuthManager.isFingerPrintAvailableAndSetup(this)) {
+ items.add(new BRSettingsItem(getString(R.string.Settings_touchIdLimit_android), "", v -> AuthManager.getInstance().authPrompt(SettingsActivity.this, null, getString(R.string.VerifyPin_continueBody), true, false, new BRAuthCompletion() {
+ @Override
+ public void onComplete() {
+ Intent intent = new Intent(SettingsActivity.this, SpendLimitActivity.class);
+ overridePendingTransition(R.anim.enter_from_right, R.anim.exit_to_left);
+ startActivity(intent);
+ }
+
+ @Override
+ public void onCancel() {
+
+ }
+ }), false));
+ }
+
+ /*Languages*/
+ items.add(new BRSettingsItem(getString(R.string.Settings_languages), null, v -> {
+ ChangeLanguageBottomSheet fragment = new ChangeLanguageBottomSheet();
+ fragment.show(getSupportFragmentManager(), fragment.getTag());
+ }, false));
+
+ /*Display Currency*/
+ items.add(new BRSettingsItem(getString(R.string.Settings_currency), BRSharedPrefs.getIso(this), v -> {
+ Intent intent = new Intent(SettingsActivity.this, DisplayCurrencyActivity.class);
+ startActivity(intent);
+ overridePendingTransition(R.anim.enter_from_right, R.anim.exit_to_left);
+ }, false));
+
+ /*Sync Blockchain*/
+ items.add(new BRSettingsItem(getString(R.string.Settings_sync), "", v -> {
+ Intent intent = new Intent(SettingsActivity.this, SyncBlockchainActivity.class);
+ startActivity(intent);
+ overridePendingTransition(R.anim.enter_from_right, R.anim.exit_to_left);
+ }, false));
+
+ /*SPACER*/
+ items.add(new BRSettingsItem("", "", null, true));
+
+ /*Share Anonymous Data*/
+ items.add(new BRSettingsItem(getString(R.string.Settings_shareData), "", v -> {
+ Intent intent = new Intent(SettingsActivity.this, ShareDataActivity.class);
+ startActivity(intent);
+ overridePendingTransition(R.anim.enter_from_right, R.anim.exit_to_left);
+ }, false));
+
+ /*About*/
+ items.add(new BRSettingsItem(getString(R.string.Settings_about), "", v -> {
+ Intent intent = new Intent(SettingsActivity.this, AboutActivity.class);
+ startActivity(intent);
+ overridePendingTransition(R.anim.enter_from_right, R.anim.exit_to_left);
+ }, false));
+
+ /*SPACER*/
+ items.add(new BRSettingsItem("", "", null, true));
+
+ /*Advanced Settings*/
+ items.add(new BRSettingsItem(getString(R.string.Settings_advancedTitle), "", v -> {
+ Intent intent = new Intent(SettingsActivity.this, AdvancedActivity.class);
+ startActivity(intent);
+ overridePendingTransition(R.anim.enter_from_right, R.anim.exit_to_left);
+ }, false));
+
+ /*SPACER*/
+ items.add(new BRSettingsItem("", "", null, true));
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ appVisible = false;
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/settings/ShareDataActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/settings/ShareDataActivity.java
new file mode 100644
index 000000000..74893fe6d
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/activities/settings/ShareDataActivity.java
@@ -0,0 +1,62 @@
+package com.breadwallet.presenter.activities.settings;
+
+import android.os.Bundle;
+import android.widget.CompoundButton;
+import android.widget.ToggleButton;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.util.ActivityUTILS;
+import com.breadwallet.presenter.activities.util.BRActivity;
+import com.breadwallet.tools.manager.BRSharedPrefs;
+
+public class ShareDataActivity extends BRActivity {
+ private static final String TAG = ShareDataActivity.class.getName();
+ private ToggleButton toggleButton;
+ public static boolean appVisible = false;
+ private static ShareDataActivity app;
+
+ public static ShareDataActivity getApp() {
+ return app;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_share_data);
+
+ toggleButton = (ToggleButton) findViewById(R.id.toggleButton);
+ toggleButton.setChecked(BRSharedPrefs.getShareData(this));
+ toggleButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ BRSharedPrefs.putShareData(ShareDataActivity.this, isChecked);
+ }
+ });
+
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ appVisible = true;
+ app = this;
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ appVisible = false;
+ }
+
+ @Override
+ public void onBackPressed() {
+ super.onBackPressed();
+ overridePendingTransition(R.anim.enter_from_left, R.anim.exit_to_right);
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ }
+
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/settings/SpendLimitActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/settings/SpendLimitActivity.java
new file mode 100644
index 000000000..731a22d50
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/activities/settings/SpendLimitActivity.java
@@ -0,0 +1,204 @@
+package com.breadwallet.presenter.activities.settings;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import androidx.annotation.NonNull;
+
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.util.BRActivity;
+import com.breadwallet.tools.manager.BRSharedPrefs;
+import com.breadwallet.tools.security.AuthManager;
+import com.breadwallet.tools.security.BRKeyStore;
+import com.breadwallet.tools.util.BRExchange;
+import com.breadwallet.wallet.BRWalletManager;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+
+import timber.log.Timber;
+
+import static com.breadwallet.tools.util.BRConstants.ONE_BITCOIN;
+
+
+public class SpendLimitActivity extends BRActivity {
+ public static boolean appVisible = false;
+ private static SpendLimitActivity app;
+ private ListView listView;
+ private LimitAdaptor adapter;
+
+ private ImageButton closeButton;
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ }
+
+ public static SpendLimitActivity getApp() {
+ return app;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_spend_limit);
+
+ //TODO: all views are using the layout of this button. Views should be refactored without it
+ // Hiding until layouts are built.
+ ImageButton faq = findViewById(R.id.faq_button);
+
+ closeButton = (ImageButton) findViewById(R.id.close_button);
+ listView = findViewById(R.id.limit_list);
+ listView.setFooterDividersEnabled(true);
+ adapter = new LimitAdaptor(this);
+ List items = new ArrayList<>();
+ items.add(getAmountByStep(0).intValue());
+ items.add(getAmountByStep(1).intValue());
+ items.add(getAmountByStep(2).intValue());
+ items.add(getAmountByStep(3).intValue());
+ items.add(getAmountByStep(4).intValue());
+
+ adapter.addAll(items);
+
+ listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view,
+ int position, long id) {
+ Timber.d("timber: onItemClick: %s", position);
+ int limit = adapter.getItem(position);
+ BRKeyStore.putSpendLimit(limit, app);
+
+ AuthManager.getInstance().setTotalLimit(app, BRWalletManager.getInstance().getTotalSent()
+ + BRKeyStore.getSpendLimit(app));
+ adapter.notifyDataSetChanged();
+ }
+ });
+ listView.setAdapter(adapter);
+ adapter.notifyDataSetChanged();
+
+ closeButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ onBackPressed();
+ }
+ });
+ }
+
+ //satoshis
+ private BigDecimal getAmountByStep(int step) {
+ BigDecimal result;
+ switch (step) {
+ case 0:
+ result = new BigDecimal(0);// 0 always require
+ break;
+ case 1:
+ result = new BigDecimal(ONE_BITCOIN / 100);// 0.01 BTC
+ break;
+ case 2:
+ result = new BigDecimal(ONE_BITCOIN / 10);// 0.1 BTC
+ break;
+ case 3:
+ result = new BigDecimal(ONE_BITCOIN);// 1 BTC
+ break;
+ case 4:
+ result = new BigDecimal(ONE_BITCOIN * 10);// 10 BTC
+ break;
+
+ default:
+ result = new BigDecimal(ONE_BITCOIN);// 1 BTC Default
+ break;
+ }
+ return result;
+ }
+
+ private int getStepFromLimit(long limit) {
+ switch ((int) limit) {
+
+ case 0:
+ return 0;
+ case ONE_BITCOIN / 100:
+ return 1;
+ case ONE_BITCOIN / 10:
+ return 2;
+ case ONE_BITCOIN:
+ return 3;
+ case ONE_BITCOIN * 10:
+ return 4;
+ default:
+ return 2; //1 BTC Default
+ }
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ appVisible = true;
+ app = this;
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ appVisible = false;
+ }
+
+ @Override
+ public void onBackPressed() {
+ super.onBackPressed();
+ overridePendingTransition(R.anim.enter_from_left, R.anim.exit_to_right);
+ }
+
+ public class LimitAdaptor extends ArrayAdapter {
+
+ private final Context mContext;
+ private final int layoutResourceId;
+
+ public LimitAdaptor(Context mContext) {
+ super(mContext, R.layout.currency_list_item);
+ this.layoutResourceId = R.layout.currency_list_item;
+ this.mContext = mContext;
+ }
+
+ @Override
+ public View getView(int position, View convertView, @NonNull ViewGroup parent) {
+ final long limit = BRKeyStore.getSpendLimit(app);
+ if (convertView == null) {
+ // inflate the layout
+ LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
+ convertView = inflater.inflate(layoutResourceId, parent, false);
+ }
+ // get the TextView and then set the text (item name) and tag (item ID) values
+ TextView textViewItem = convertView.findViewById(R.id.currency_item_text);
+ Integer item = getItem(position);
+ BigDecimal curAmount = BRExchange.getAmountFromSatoshis(app, BRSharedPrefs.getIso(app), new BigDecimal(item));
+ BigDecimal btcAmount = BRExchange.getBitcoinForSatoshis(app, new BigDecimal(item));
+ String text = String.format(item == 0 ? app.getString(R.string.TouchIdSpendingLimit) : "%s (%s)", curAmount, btcAmount);
+ textViewItem.setText(text);
+ ImageView checkMark = convertView.findViewById(R.id.currency_checkmark);
+
+ if (position == getStepFromLimit(limit)) {
+ checkMark.setVisibility(View.VISIBLE);
+ } else {
+ checkMark.setVisibility(View.GONE);
+ }
+ return convertView;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return IGNORE_ITEM_VIEW_TYPE;
+ }
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/settings/SyncBlockchainActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/settings/SyncBlockchainActivity.java
new file mode 100644
index 000000000..8c9fd4b96
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/activities/settings/SyncBlockchainActivity.java
@@ -0,0 +1,174 @@
+package com.breadwallet.presenter.activities.settings;
+
+import android.annotation.SuppressLint;
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.ImageButton;
+import android.widget.RadioGroup;
+import android.widget.TextView;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.util.ActivityUTILS;
+import com.breadwallet.presenter.activities.util.BRActivity;
+import com.breadwallet.presenter.customviews.BRDialogView;
+import com.breadwallet.tools.animation.BRAnimator;
+import com.breadwallet.tools.animation.BRDialog;
+import com.breadwallet.tools.manager.AnalyticsManager;
+import com.breadwallet.tools.manager.BRSharedPrefs;
+import com.breadwallet.tools.threads.BRExecutor;
+import com.breadwallet.tools.util.BRConstants;
+import com.breadwallet.wallet.BRPeerManager;
+
+
+
+
+public class SyncBlockchainActivity extends BRActivity {
+
+ private static final String TAG = SyncBlockchainActivity.class.getName();
+ private Button scanButton;
+ private Button lowPrivacyButton;
+ private Button semiPrivateButton;
+ private Button anonymousButton;
+
+ private ImageButton closeButton;
+
+ private RadioGroup syncRadioGroup;
+
+ public static boolean appVisible = false;
+ private static TextView syncPreferenceTextView;
+ private ImageButton fingerPrint;
+
+ private static SyncBlockchainActivity app;
+ public static SyncBlockchainActivity getApp() {
+ return app;
+ }
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ }
+
+ private void updateSyncPreference() {
+ float fprate = BRSharedPrefs.getFalsePositivesRate(SyncBlockchainActivity.this);
+ String rateAsString = String.format("%1.5f",fprate);
+ syncPreferenceTextView.setText(getString(R.string.sync_preferences, rateAsString));
+
+ if (fprate == BRConstants.FALSE_POS_RATE_LOW_PRIVACY) {
+ syncRadioGroup.check(R.id.radio_low_privacy);
+ }
+ else if (fprate == BRConstants.FALSE_POS_RATE_SEMI_PRIVACY) {
+ syncRadioGroup.check(R.id.radio_semi_private);
+ }else {
+ ///Assumed the Anon option is preferred
+ syncRadioGroup.check(R.id.radio_anonymous);
+ }
+ }
+ @SuppressLint("StringFormatInvalid")
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_sync_blockchain);
+
+ syncRadioGroup = (RadioGroup) findViewById(R.id.sync_radio_group);
+
+ ImageButton faq = (ImageButton) findViewById(R.id.faq_button);
+ syncPreferenceTextView = (TextView) findViewById(R.id.sync_preferences);
+ scanButton = (Button) findViewById(R.id.button_scan);
+ lowPrivacyButton = (Button) findViewById(R.id.radio_low_privacy);
+ semiPrivateButton = (Button) findViewById(R.id.radio_semi_private);
+ anonymousButton = (Button) findViewById(R.id.radio_anonymous);
+
+ lowPrivacyButton.setText(getString(R.string.radio_low_privacy));
+ semiPrivateButton.setText(getString(R.string.radio_semi_private));
+ anonymousButton.setText(getString(R.string.radio_anonymous));
+
+ updateSyncPreference();
+
+ lowPrivacyButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ BRSharedPrefs.putFalsePositivesRate(SyncBlockchainActivity.this, BRConstants.FALSE_POS_RATE_LOW_PRIVACY);
+ updateSyncPreference();
+ }
+ });
+
+ semiPrivateButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ BRSharedPrefs.putFalsePositivesRate(SyncBlockchainActivity.this, BRConstants.FALSE_POS_RATE_SEMI_PRIVACY);
+ updateSyncPreference();
+ }
+ });
+ anonymousButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ BRSharedPrefs.putFalsePositivesRate(SyncBlockchainActivity.this, BRConstants.FALSE_POS_RATE_ANONYMOUS);
+ updateSyncPreference();
+ }
+ });
+
+ scanButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (!BRAnimator.isClickAllowed()) return;
+ BRDialog.showCustomDialog(SyncBlockchainActivity.this, getString(R.string.ReScan_alertTitle),
+ getString(R.string.ReScan_footer), getString(R.string.ReScan_alertAction), getString(R.string.Button_cancel),
+ new BRDialogView.BROnClickListener() {
+ @Override
+ public void onClick(BRDialogView brDialogView) {
+ brDialogView.dismissWithAnimation();
+ BRExecutor.getInstance().forLightWeightBackgroundTasks().execute(new Runnable() {
+ @Override
+ public void run() {
+ BRSharedPrefs.putStartHeight(SyncBlockchainActivity.this, 0);
+ BRSharedPrefs.putAllowSpend(SyncBlockchainActivity.this, false);
+ BRPeerManager.getInstance().rescan();
+ BRAnimator.startBreadActivity(SyncBlockchainActivity.this, false);
+ AnalyticsManager.logCustomEvent(BRConstants._20200112_DSR);
+ }
+ });
+ }
+ }, new BRDialogView.BROnClickListener() {
+ @Override
+ public void onClick(BRDialogView brDialogView) {
+ brDialogView.dismissWithAnimation();
+ }
+ }, null, 0);
+ }
+ });
+
+ closeButton = (ImageButton) findViewById(R.id.close_button);
+ closeButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ onBackPressed();
+ }
+ });
+
+ }
+
+
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ appVisible = true;
+ app = this;
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ appVisible = false;
+ }
+
+ @Override
+ public void onBackPressed() {
+ super.onBackPressed();
+ overridePendingTransition(R.anim.enter_from_left, R.anim.exit_to_right);
+ }
+
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/settings/TestActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/settings/TestActivity.java
new file mode 100644
index 000000000..30af84aa2
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/activities/settings/TestActivity.java
@@ -0,0 +1,35 @@
+package com.breadwallet.presenter.activities.settings;
+
+import android.os.Bundle;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.util.BRActivity;
+
+public class TestActivity extends BRActivity {
+ private static final String TAG = TestActivity.class.getName();
+
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_about);
+
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ }
+
+
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/settings/WipeActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/settings/WipeActivity.java
new file mode 100644
index 000000000..bf9954a36
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/activities/settings/WipeActivity.java
@@ -0,0 +1,82 @@
+package com.breadwallet.presenter.activities.settings;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+import android.widget.ImageButton;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.InputWordsActivity;
+import com.breadwallet.presenter.activities.util.ActivityUTILS;
+import com.breadwallet.presenter.activities.util.BRActivity;
+import com.breadwallet.tools.animation.BRAnimator;
+import com.breadwallet.tools.util.BRConstants;
+
+
+public class WipeActivity extends BRActivity {
+ private Button nextButton;
+ private ImageButton close;
+ public static boolean appVisible = false;
+ private static WipeActivity app;
+
+ public static WipeActivity getApp() {
+ return app;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_restore);
+
+ nextButton = (Button) findViewById(R.id.send_button);
+ close = (ImageButton) findViewById(R.id.close_button);
+
+ ImageButton faq = (ImageButton) findViewById(R.id.faq_button);
+ //TODO: all views are using the layout of this button. Views should be refactored without it
+ // Hiding until layouts are built.
+
+ nextButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (!BRAnimator.isClickAllowed()) return;
+ Intent intent = new Intent(WipeActivity.this, InputWordsActivity.class);
+ intent.putExtra("restore", true);
+ startActivity(intent);
+ overridePendingTransition(R.anim.enter_from_right, R.anim.exit_to_left);
+ if (!WipeActivity.this.isDestroyed()) finish();
+ }
+ });
+ close.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (!BRAnimator.isClickAllowed()) return;
+ onBackPressed();
+ }
+ });
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ appVisible = true;
+ app = this;
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ appVisible = false;
+ }
+
+ @Override
+ public void onBackPressed() {
+ super.onBackPressed();
+ overridePendingTransition(R.anim.fade_up, R.anim.exit_to_bottom);
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/util/ActivityUTILS.java b/app/src/main/java/com/breadwallet/presenter/activities/util/ActivityUTILS.java
new file mode 100644
index 000000000..f9eab9b3d
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/activities/util/ActivityUTILS.java
@@ -0,0 +1,54 @@
+package com.breadwallet.presenter.activities.util;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.content.Intent;
+import android.os.Looper;
+import android.view.Window;
+import android.view.WindowManager;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.DisabledActivity;
+import com.breadwallet.presenter.activities.InputWordsActivity;
+import com.breadwallet.presenter.activities.SetPinActivity;
+
+import java.util.List;
+
+import timber.log.Timber;
+
+import static android.content.Context.ACTIVITY_SERVICE;
+
+public class ActivityUTILS {
+
+ //return true if the app does need to show the disabled wallet screen
+ public static boolean isAppSafe(Activity app) {
+ return app instanceof SetPinActivity || app instanceof InputWordsActivity;
+ }
+
+ public static void showWalletDisabled(Activity app) {
+ Intent intent = new Intent(app, DisabledActivity.class);
+ app.startActivity(intent);
+ app.overridePendingTransition(R.anim.fade_up, R.anim.fade_down);
+ Timber.d("timber: showWalletDisabled: %s", app.getClass().getName());
+ }
+
+ public static boolean isLast(Activity app) {
+ ActivityManager mngr = (ActivityManager) app.getSystemService(ACTIVITY_SERVICE);
+
+ List taskList = mngr.getRunningTasks(10);
+
+ if (taskList.get(0).numActivities == 1 &&
+ taskList.get(0).topActivity.getClassName().equals(app.getClass().getName())) {
+ return true;
+ }
+ return false;
+ }
+
+ public static boolean isMainThread() {
+ boolean isMain = Looper.myLooper() == Looper.getMainLooper();
+ if (isMain) {
+ Timber.d("timber: IS MAIN UI THREAD!");
+ }
+ return isMain;
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/activities/util/BRActivity.java b/app/src/main/java/com/breadwallet/presenter/activities/util/BRActivity.java
new file mode 100644
index 000000000..fe983077a
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/activities/util/BRActivity.java
@@ -0,0 +1,162 @@
+package com.breadwallet.presenter.activities.util;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+
+import androidx.annotation.Nullable;
+import androidx.fragment.app.FragmentActivity;
+
+import com.breadwallet.BreadApp;
+import com.breadwallet.presenter.activities.DisabledActivity;
+import com.breadwallet.presenter.activities.intro.IntroActivity;
+import com.breadwallet.presenter.activities.intro.RecoverActivity;
+import com.breadwallet.presenter.activities.intro.WriteDownActivity;
+import com.breadwallet.tools.animation.BRAnimator;
+import com.breadwallet.tools.manager.BRApiManager;
+import com.breadwallet.tools.manager.InternetManager;
+import com.breadwallet.tools.security.AuthManager;
+import com.breadwallet.tools.security.BRKeyStore;
+import com.breadwallet.tools.security.BitcoinUrlHandler;
+import com.breadwallet.tools.security.PostAuth;
+import com.breadwallet.tools.threads.BRExecutor;
+import com.breadwallet.tools.util.BRConstants;
+import com.breadwallet.tools.util.LocaleHelper;
+import com.breadwallet.wallet.BRWalletManager;
+import timber.log.Timber;
+
+public class BRActivity extends FragmentActivity {
+
+ static {
+ System.loadLibrary(BRConstants.NATIVE_LIB_NAME);
+ }
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ LocaleHelper.Companion.getInstance().setLocale(this);
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ protected void attachBaseContext(Context newBase) {
+ super.attachBaseContext(LocaleHelper.Companion.getInstance().setLocale(newBase));
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ BreadApp.activityCounter.decrementAndGet();
+ BreadApp.onStop(this);
+ BreadApp.backgroundedTime = System.currentTimeMillis();
+ }
+
+ @Override
+ protected void onResume() {
+ init(this);
+ super.onResume();
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ switch (requestCode) {
+ case BRConstants.PAY_REQUEST_CODE:
+ if (resultCode == RESULT_OK) {
+ BRExecutor.getInstance().forLightWeightBackgroundTasks().execute(new Runnable() {
+ @Override
+ public void run() {
+ PostAuth.getInstance().onPublishTxAuth(BRActivity.this, true);
+ }
+ });
+ }
+ break;
+ case BRConstants.PAYMENT_PROTOCOL_REQUEST_CODE:
+ if (resultCode == RESULT_OK) {
+ PostAuth.getInstance().onPaymentProtocolRequest(this, true);
+ }
+ break;
+
+ case BRConstants.CANARY_REQUEST_CODE:
+ if (resultCode == RESULT_OK) {
+ PostAuth.getInstance().onCanaryCheck(this, true);
+ } else {
+ finish();
+ }
+ break;
+
+ case BRConstants.SHOW_PHRASE_REQUEST_CODE:
+ if (resultCode == RESULT_OK) {
+ PostAuth.getInstance().onPhraseCheckAuth(this, true);
+ }
+ break;
+ case BRConstants.PROVE_PHRASE_REQUEST:
+ if (resultCode == RESULT_OK) {
+ PostAuth.getInstance().onPhraseProveAuth(this, true);
+ }
+ break;
+ case BRConstants.PUT_PHRASE_RECOVERY_WALLET_REQUEST_CODE:
+ if (resultCode == RESULT_OK) {
+ PostAuth.getInstance().onRecoverWalletAuth(this, true);
+ } else {
+ finish();
+ }
+ break;
+
+ case BRConstants.SCANNER_REQUEST:
+ if (resultCode == Activity.RESULT_OK) {
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ String result = data.getStringExtra("result");
+ if (BitcoinUrlHandler.isBitcoinUrl(result))
+ BitcoinUrlHandler.processRequest(BRActivity.this, result);
+ else
+ Timber.i("timber: onActivityResult: not litecoin address NOR bitID");
+ }
+ }, 500);
+
+ }
+ break;
+
+ case BRConstants.PUT_PHRASE_NEW_WALLET_REQUEST_CODE:
+ if (resultCode == RESULT_OK) {
+ PostAuth.getInstance().onCreateWalletAuth(this, true);
+ } else {
+ Timber.d("timber: WARNING: resultCode != RESULT_OK");
+ BRWalletManager m = BRWalletManager.getInstance();
+ m.wipeWalletButKeystore(this);
+ finish();
+ }
+ break;
+
+ default:
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+ }
+
+ public static void init(Activity app) {
+ InternetManager.getInstance();
+ if (!(app instanceof IntroActivity || app instanceof RecoverActivity || app instanceof WriteDownActivity))
+ BRApiManager.getInstance().startTimer(app);
+ //show wallet locked if it is
+ if (!ActivityUTILS.isAppSafe(app))
+ if (AuthManager.getInstance().isWalletDisabled(app))
+ AuthManager.getInstance().setWalletDisabled(app);
+
+ BreadApp.activityCounter.incrementAndGet();
+ BreadApp.setBreadContext(app);
+ //lock wallet if 3 minutes passed (180 * 1000)
+ if (BreadApp.backgroundedTime != 0 && hasTimeElapsedSinceInBackground(180 * 1000) && !(app instanceof DisabledActivity)) {
+ if (!BRKeyStore.getPinCode(app).isEmpty()) {
+ BRAnimator.startBreadActivity(app, true);
+ }
+ }
+ BreadApp.backgroundedTime = System.currentTimeMillis();
+ }
+
+ private static boolean hasTimeElapsedSinceInBackground(long timeInMillis) {
+ return System.currentTimeMillis() - BreadApp.backgroundedTime >= timeInMillis;
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/base/BaseActivity.kt b/app/src/main/java/com/breadwallet/presenter/base/BaseActivity.kt
new file mode 100644
index 000000000..b6d67c1d2
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/base/BaseActivity.kt
@@ -0,0 +1,10 @@
+package com.breadwallet.presenter.base
+
+import androidx.fragment.app.FragmentActivity
+
+/** Litewallet
+ * Created by Mohamed Barry on 6/1/20
+ * email: mosadialiou@gmail.com
+ * Copyright ยฉ 2020 Litecoin Foundation. All rights reserved.
+ */
+class BaseActivity : FragmentActivity()
diff --git a/app/src/main/java/com/breadwallet/presenter/base/BaseFragment.kt b/app/src/main/java/com/breadwallet/presenter/base/BaseFragment.kt
new file mode 100644
index 000000000..68d4c3508
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/base/BaseFragment.kt
@@ -0,0 +1,42 @@
+package com.breadwallet.presenter.base
+
+import android.os.Bundle
+import androidx.appcompat.app.AlertDialog
+import androidx.fragment.app.Fragment
+import timber.log.Timber
+
+/** Litewallet
+ * Created by Mohamed Barry on 6/1/20
+ * email: mosadialiou@gmail.com
+ * Copyright ยฉ 2020 Litecoin Foundation. All rights reserved.
+ */
+abstract class BaseFragment> : Fragment() {
+ lateinit var presenter: P
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ presenter = initPresenter()
+ }
+
+ override fun onDetach() {
+ super.onDetach()
+ if (this::presenter.isInitialized) {
+ presenter.detach()
+ } else {
+ Timber.w("presenter is not yet initialized")
+ }
+ }
+
+ fun showError(error: String) {
+ AlertDialog.Builder(requireContext()).setMessage(error).setPositiveButton(
+ android.R.string.ok,
+ null,
+ ).show()
+ }
+
+ fun showError(errorId: Int) {
+ showError(getString(errorId))
+ }
+
+ abstract fun initPresenter(): P
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/base/BasePresenter.kt b/app/src/main/java/com/breadwallet/presenter/base/BasePresenter.kt
new file mode 100644
index 000000000..6ebe38f16
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/base/BasePresenter.kt
@@ -0,0 +1,25 @@
+package com.breadwallet.presenter.base
+
+/** Litewallet
+ * Created by Mohamed Barry on 6/30/20
+ * email: mosadialiou@gmail.com
+ * Copyright ยฉ 2020 Litecoin Foundation. All rights reserved.
+ */
+abstract class BasePresenter(var view: BaseView?) {
+ init {
+ inject()
+ }
+
+ private fun inject() {
+ }
+
+ abstract fun subscribe()
+
+ abstract fun unsubscribe()
+
+ fun detach() {
+ view = null
+ }
+
+ fun isAttached() = view != null
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/base/BaseView.kt b/app/src/main/java/com/breadwallet/presenter/base/BaseView.kt
new file mode 100644
index 000000000..b48d65f2c
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/base/BaseView.kt
@@ -0,0 +1,18 @@
+package com.breadwallet.presenter.base
+
+/** Litewallet
+ * Created by Mohamed Barry on 6/30/20
+ * email: mosadialiou@gmail.com
+ * Copyright ยฉ 2020 Litecoin Foundation. All rights reserved.
+ */
+interface BaseView {
+ fun showProgress() {}
+
+ fun hideProgress() {}
+
+ fun onTokenExpired() {}
+
+ fun showError(error: String)
+
+ fun showError(errorId: Int)
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/customviews/AutoResizeTextView.java b/app/src/main/java/com/breadwallet/presenter/customviews/AutoResizeTextView.java
deleted file mode 100644
index 59dac44c0..000000000
--- a/app/src/main/java/com/breadwallet/presenter/customviews/AutoResizeTextView.java
+++ /dev/null
@@ -1,321 +0,0 @@
-package com.breadwallet.presenter.customviews;
-
-/**
- * DO WHAT YOU WANT TO PUBLIC LICENSE
- * Version 2, December 2004
- *
- * Copyright (C) 2004 Sam Hocevar
- *
- * Everyone is permitted to copy and distribute verbatim or modified
- * copies of this license document, and changing it is allowed as long
- * as the name is changed.
- *
- * DO WHAT YOU WANT TO PUBLIC LICENSE
- * TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
- *
- * 0. You just DO WHAT YOU WANT TO.
- */
-
-import android.content.Context;
-import android.text.Layout.Alignment;
-import android.text.StaticLayout;
-import android.text.TextPaint;
-import android.util.AttributeSet;
-import android.util.TypedValue;
-import android.widget.TextView;
-
-/**
- * Text view that auto adjusts text size to fit within the view.
- * If the text size equals the minimum text size and still does not
- * fit, append with an ellipsis.
- *
- * @author Chase Colburn
- * @since Apr 4, 2011
- */
-public class AutoResizeTextView extends TextView {
-
- // Minimum text size for this text view
- private static final float MIN_TEXT_SIZE = 20;
-
- // Interface for resize notifications
- public interface OnTextResizeListener {
- void onTextResize(TextView textView, float oldSize, float newSize);
- }
-
- // Our ellipse string
- private static final String mEllipsis = "...";
-
- // Registered resize listener
- private OnTextResizeListener mTextResizeListener;
-
- // Flag for text and/or size changes to force a resize
- private boolean mNeedsResize = false;
-
- // Text size that is set from code. This acts as a starting point for resizing
- private float mTextSize;
-
- // Temporary upper bounds on the starting text size
- private float mMaxTextSize = 0;
-
- // Lower bounds for text size
- private float mMinTextSize = MIN_TEXT_SIZE;
-
- // Text view line spacing multiplier
- private float mSpacingMult = 1.0f;
-
- // Text view additional line spacing
- private float mSpacingAdd = 0.0f;
-
- // Add ellipsis to text that overflows at the smallest text size
- private boolean mAddEllipsis = true;
-
- // Default constructor override
- public AutoResizeTextView(Context context) {
- this(context, null);
- }
-
- // Default constructor when inflating from XML file
- public AutoResizeTextView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- // Default constructor override
- public AutoResizeTextView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- mTextSize = getTextSize();
- }
-
- /**
- * When text changes, set the force resize flag to true and reset the text size.
- */
- @Override
- protected void onTextChanged(final CharSequence text, final int start, final int before, final int after) {
- mNeedsResize = true;
- // Since this view may be reused, it is good to reset the text size
- resetTextSize();
- }
-
- /**
- * If the text view size changed, set the force resize flag to true
- */
- @Override
- protected void onSizeChanged(int w, int h, int oldw, int oldh) {
- if (w != oldw || h != oldh) {
- mNeedsResize = true;
- }
- }
-
- /**
- * Register listener to receive resize notifications
- * @param listener
- */
- public void setOnResizeListener(OnTextResizeListener listener) {
- mTextResizeListener = listener;
- }
-
- /**
- * Override the set text size to update our internal reference values
- */
- @Override
- public void setTextSize(float size) {
- super.setTextSize(size);
- mTextSize = getTextSize();
- }
-
- /**
- * Override the set text size to update our internal reference values
- */
- @Override
- public void setTextSize(int unit, float size) {
- super.setTextSize(unit, size);
- mTextSize = getTextSize();
- }
-
- /**
- * Override the set line spacing to update our internal reference values
- */
- @Override
- public void setLineSpacing(float add, float mult) {
- super.setLineSpacing(add, mult);
- mSpacingMult = mult;
- mSpacingAdd = add;
- }
-
- /**
- * Set the upper text size limit and invalidate the view
- * @param maxTextSize
- */
- public void setMaxTextSize(float maxTextSize) {
- mMaxTextSize = maxTextSize;
- requestLayout();
- invalidate();
- }
-
- /**
- * Return upper text size limit
- * @return
- */
- public float getMaxTextSize() {
- return mMaxTextSize;
- }
-
- /**
- * Set the lower text size limit and invalidate the view
- * @param minTextSize
- */
- public void setMinTextSize(float minTextSize) {
- mMinTextSize = minTextSize;
- requestLayout();
- invalidate();
- }
-
- /**
- * Return lower text size limit
- * @return
- */
- public float getMinTextSize() {
- return mMinTextSize;
- }
-
- /**
- * Set flag to add ellipsis to text that overflows at the smallest text size
- * @param addEllipsis
- */
- public void setAddEllipsis(boolean addEllipsis) {
- mAddEllipsis = addEllipsis;
- }
-
- /**
- * Return flag to add ellipsis to text that overflows at the smallest text size
- * @return
- */
- public boolean getAddEllipsis() {
- return mAddEllipsis;
- }
-
- /**
- * Reset the text to the original size
- */
- private void resetTextSize() {
- if (mTextSize > 0) {
- super.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize);
- mMaxTextSize = mTextSize;
- }
- }
-
- /**
- * Resize text after measuring
- */
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- if (changed || mNeedsResize) {
- int widthLimit = (right - left) - getCompoundPaddingLeft() - getCompoundPaddingRight();
- int heightLimit = (bottom - top) - getCompoundPaddingBottom() - getCompoundPaddingTop();
- resizeText(widthLimit, heightLimit);
- }
- super.onLayout(changed, left, top, right, bottom);
- }
-
- /**
- * Resize the text size with default width and height
- */
- public void resizeText() {
-
- int heightLimit = getHeight() - getPaddingBottom() - getPaddingTop();
- int widthLimit = getWidth() - getPaddingLeft() - getPaddingRight();
- resizeText(widthLimit, heightLimit);
- }
-
- /**
- * Resize the text size with specified width and height
- * @param width
- * @param height
- */
- private void resizeText(int width, int height) {
- CharSequence text = getText();
- // Do not resize if the view does not have dimensions or there is no text
- if (text == null || text.length() == 0 || height <= 0 || width <= 0 || mTextSize == 0) {
- return;
- }
-
- if (getTransformationMethod() != null) {
- text = getTransformationMethod().getTransformation(text, this);
- }
-
- // Get the text view's paint object
- TextPaint textPaint = getPaint();
-
- // Store the current text size
- float oldTextSize = textPaint.getTextSize();
- // If there is a max text size set, use the lesser of that and the default text size
- float targetTextSize = mMaxTextSize > 0 ? Math.min(mTextSize, mMaxTextSize) : mTextSize;
-
- // Get the required text height
- int textHeight = getTextHeight(text, textPaint, width, targetTextSize);
-
- // Until we either fit within our text view or we had reached our min text size, incrementally try smaller sizes
- while (textHeight > height && targetTextSize > mMinTextSize) {
- targetTextSize = Math.max(targetTextSize - 2, mMinTextSize);
- textHeight = getTextHeight(text, textPaint, width, targetTextSize);
- }
-
- // If we had reached our minimum text size and still don't fit, append an ellipsis
- if (mAddEllipsis && targetTextSize == mMinTextSize && textHeight > height) {
- // Draw using a static layout
- // modified: use a copy of TextPaint for measuring
- TextPaint paint = new TextPaint(textPaint);
- // Draw using a static layout
- StaticLayout layout = new StaticLayout(text, paint, width, Alignment.ALIGN_NORMAL, mSpacingMult, mSpacingAdd, false);
- // Check that we have a least one line of rendered text
- if (layout.getLineCount() > 0) {
- // Since the line at the specific vertical position would be cut off,
- // we must trim up to the previous line
- int lastLine = layout.getLineForVertical(height) - 1;
- // If the text would not even fit on a single line, clear it
- if (lastLine < 0) {
- setText("");
- }
- // Otherwise, trim to the previous line and add an ellipsis
- else {
- int start = layout.getLineStart(lastLine);
- int end = layout.getLineEnd(lastLine);
- float lineWidth = layout.getLineWidth(lastLine);
- float ellipseWidth = textPaint.measureText(mEllipsis);
-
- // Trim characters off until we have enough room to draw the ellipsis
- while (width < lineWidth + ellipseWidth) {
- lineWidth = textPaint.measureText(text.subSequence(start, --end + 1).toString());
- }
- setText(String.valueOf(text.subSequence(0, end)).concat(mEllipsis));
- }
- }
- }
-
- // Some devices try to auto adjust line spacing, so force default line spacing
- // and invalidate the layout as a side effect
- setTextSize(TypedValue.COMPLEX_UNIT_PX, targetTextSize);
- setLineSpacing(mSpacingAdd, mSpacingMult);
-
- // Notify the listener if registered
- if (mTextResizeListener != null) {
- mTextResizeListener.onTextResize(this, oldTextSize, targetTextSize);
- }
-
- // Reset force resize flag
- mNeedsResize = false;
- }
-
- // Set the text size of the text paint object and use a static layout to render text off screen before measuring
- private int getTextHeight(CharSequence source, TextPaint paint, int width, float textSize) {
- // modified: make a copy of the original TextPaint object for measuring
- // (apparently the object gets modified while measuring, see also the
- // docs for TextView.getPaint() (which states to access it read-only)
- TextPaint paintCopy = new TextPaint(paint);
- // Update the text paint object
- paintCopy.setTextSize(textSize);
- // Measure using a static layout
- StaticLayout layout = new StaticLayout(source, paintCopy, width, Alignment.ALIGN_NORMAL, mSpacingMult, mSpacingAdd, true);
- return layout.getHeight();
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/breadwallet/presenter/customviews/BRButton.java b/app/src/main/java/com/breadwallet/presenter/customviews/BRButton.java
new file mode 100644
index 000000000..876521843
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/customviews/BRButton.java
@@ -0,0 +1,221 @@
+package com.breadwallet.presenter.customviews;
+
+import android.animation.ValueAnimator;
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.MotionEvent;
+import android.view.ViewTreeObserver;
+import android.view.animation.AccelerateDecelerateInterpolator;
+import android.view.animation.Animation;
+import android.view.animation.ScaleAnimation;
+import android.widget.Button;
+
+import androidx.annotation.ColorRes;
+import androidx.annotation.Nullable;
+
+import com.breadwallet.R;
+import com.breadwallet.tools.util.Utils;
+
+import timber.log.Timber;
+
+@SuppressLint("AppCompatCustomView") // we don't need to support older versions
+public class BRButton extends Button {
+ private static final int ANIMATION_DURATION = 30;
+ private Bitmap shadow;
+ private Rect shadowRect;
+ private RectF bRect;
+ private Paint bPaint;
+ private Paint bPaintStroke;
+ private int type = 2;
+ private static final float SHADOW_PRESSED = 0.88f;
+ private static final float SHADOW_UNPRESSED = 0.95f;
+ private float shadowOffSet = SHADOW_UNPRESSED;
+ private static final int ROUND_PIXELS = 16;
+ private boolean isBreadButton; //meaning is has the special animation and shadow
+
+ public BRButton(Context context) {
+ super(context);
+ init(context, null);
+ }
+
+ public BRButton(Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ init(context, attrs);
+ }
+
+ public BRButton(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init(context, attrs);
+ }
+
+ public BRButton(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ init(context, attrs);
+ }
+
+ private void init(Context ctx, AttributeSet attrs) {
+ shadow = BitmapFactory.decodeResource(getResources(), R.drawable.shadow);
+ bPaint = new Paint();
+ bPaint.setAntiAlias(true);
+ bPaintStroke = new Paint();
+ bPaintStroke.setAntiAlias(true);
+ shadowRect = new Rect(0, 0, 100, 100);
+ bRect = new RectF(0, 0, 100, 100);
+ TypedArray a = ctx.obtainStyledAttributes(attrs, R.styleable.BRButton);
+
+ int px16 = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 15, getResources().getDisplayMetrics());
+
+ isBreadButton = a.getBoolean(R.styleable.BRButton_isBreadButton, false);
+
+ int[] attributes = new int[]{android.R.attr.paddingStart, android.R.attr.paddingTop, android.R.attr.paddingEnd, android.R.attr.paddingBottom, R.attr.isBreadButton, R.attr.buttonType};
+ TypedArray arr = ctx.obtainStyledAttributes(attrs, attributes);
+
+ int paddingLeft = arr.getDimensionPixelOffset(0, px16);
+ int paddingTop = arr.getDimensionPixelOffset(1, 0);
+ int paddingRight = arr.getDimensionPixelOffset(2, px16);
+ int paddingBottom = arr.getDimensionPixelOffset(3, 0) + (isBreadButton ? px16 : 0);
+
+ int type = a.getInteger(R.styleable.BRButton_buttonType, 0);
+ setType(type);
+
+ if (isBreadButton) {
+ setBackground(getContext().getDrawable(R.drawable.shadow_trans));
+ }
+
+ setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
+ a.recycle();
+ arr.recycle();
+ final ViewTreeObserver observer = getViewTreeObserver();
+ observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+ @Override
+ public void onGlobalLayout() {
+ if (observer.isAlive()) {
+ observer.removeOnGlobalLayoutListener(this);
+ }
+ correctTextSizeIfNeeded();
+ }
+ });
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ if (isEnabled() && isBreadButton) {
+ if (event.getAction() == MotionEvent.ACTION_DOWN) {
+ if (getParent() != null) {
+ getParent().requestDisallowInterceptTouchEvent(false);
+ }
+ if (type != 3)
+ onTouch(true, ANIMATION_DURATION);
+ } else if (event.getAction() == MotionEvent.ACTION_UP) {
+ onTouch(false, ANIMATION_DURATION);
+ }
+ }
+
+ return super.onTouchEvent(event);
+ }
+
+ private void correctTextSizeIfNeeded() {
+ int limit = 100;
+ int lines = getLineCount();
+ float px = getTextSize();
+ while (lines > 1 && !getText().toString().contains("\n")) {
+ limit--;
+ px -= 1;
+ setTextSize(TypedValue.COMPLEX_UNIT_PX, px);
+ lines = getLineCount();
+ if (limit <= 0) {
+ Timber.d("timber: correctTextSizeIfNeeded: Failed to rescale, limit reached, final: %s", px);
+ break;
+ }
+ }
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ if (isBreadButton) {
+ final int width = getWidth();
+ final int height = getHeight();
+ shadowRect.set(5, height / 4, width - 5, (int) (height * shadowOffSet));
+ int modifiedWidth = width - 10;
+ int modifiedHeight = height - height / 4 - 5;
+ bRect.set(5, 5, modifiedWidth, modifiedHeight + 5);
+ canvas.drawBitmap(shadow, null, shadowRect, null);
+ canvas.drawRoundRect(bRect, ROUND_PIXELS, ROUND_PIXELS, bPaint);
+ if (type == 2 || type == 3 || type == 5) {
+ canvas.drawRoundRect(bRect, ROUND_PIXELS, ROUND_PIXELS, bPaintStroke);
+ }
+ }
+ super.onDraw(canvas);
+ }
+
+ public void setType(int type) {
+ if (type == 3) onTouch(true, 1);
+ this.type = type;
+
+ if (type == 1) { //blue
+ bPaint.setColor(getContext().getColor(R.color.litecoin_litewallet_blue));
+ setTextColor(getContext().getColor(R.color.white));
+ } else if (type == 2) { //gray stroke
+ setTextColor(getContext().getColor(R.color.light_gray));
+ setOutline(R.color.extra_light_gray, R.color.button_secondary);
+ } else if (type == 3) { //blue strokeww
+ setTextColor(getContext().getColor(R.color.litecoin_litewallet_blue));
+ setOutline(R.color.litecoin_litewallet_blue, R.color.button_secondary);
+ } else if (type == 4) { //white stroke
+ setOutline(R.color.white, R.color.button_secondary);
+ } else if (type == 5) {
+ setOutline(R.color.white, R.color.litecoin_litewallet_blue);
+ }
+ invalidate();
+ }
+
+ private void setOutline(@ColorRes int strokeColor, @ColorRes int color) {
+ bPaintStroke.setColor(getContext().getColor(strokeColor));
+ bPaintStroke.setStyle(Paint.Style.STROKE);
+ bPaintStroke.setStrokeWidth(Utils.getPixelsFromDps(getContext(), 1));
+ bPaint.setColor(getContext().getColor(color));
+ bPaint.setStyle(Paint.Style.FILL);
+ }
+
+ private void onTouch(boolean pressed, int duration) {
+ float from = pressed ? 1f : 0.96f;
+ float to = pressed ? 0.96f : 1f;
+ ScaleAnimation scaleAnim = new ScaleAnimation(
+ from, to,
+ from, to,
+ Animation.RELATIVE_TO_SELF, 0.5f,
+ Animation.RELATIVE_TO_SELF, 1f);
+ scaleAnim.setDuration(duration);
+ scaleAnim.setRepeatCount(0);
+ scaleAnim.setInterpolator(new AccelerateDecelerateInterpolator());
+ scaleAnim.setFillAfter(true);
+ scaleAnim.setFillBefore(true);
+ scaleAnim.setFillEnabled(true);
+
+ float[] values = new float[]{SHADOW_UNPRESSED, SHADOW_PRESSED};
+ if (!pressed) {
+ values = new float[]{SHADOW_PRESSED, SHADOW_UNPRESSED};
+ }
+ ValueAnimator shadowAnim = ValueAnimator.ofFloat(values);
+ shadowAnim.setDuration(duration);
+ shadowAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ shadowOffSet = (float) animation.getAnimatedValue();
+ invalidate();
+ }
+ });
+
+ startAnimation(scaleAnim);
+ shadowAnim.start();
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/customviews/BRButtonIntro.java b/app/src/main/java/com/breadwallet/presenter/customviews/BRButtonIntro.java
new file mode 100644
index 000000000..db0979a49
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/customviews/BRButtonIntro.java
@@ -0,0 +1,221 @@
+package com.breadwallet.presenter.customviews;
+
+import android.animation.ValueAnimator;
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.MotionEvent;
+import android.view.ViewTreeObserver;
+import android.view.animation.AccelerateDecelerateInterpolator;
+import android.view.animation.Animation;
+import android.view.animation.ScaleAnimation;
+import android.widget.Button;
+
+import androidx.annotation.ColorRes;
+import androidx.annotation.Nullable;
+
+import com.breadwallet.R;
+import com.breadwallet.tools.util.Utils;
+
+import timber.log.Timber;
+
+@SuppressLint("AppCompatCustomView") // we don't need to support older versions
+public class BRButtonIntro extends Button {
+ private static final int ANIMATION_DURATION = 30;
+ private Bitmap shadow;
+ private Rect shadowRect;
+ private RectF bRect;
+ private Paint bPaint;
+ private Paint bPaintStroke;
+ private int type = 2;
+ private static final float SHADOW_PRESSED = 0.88f;
+ private static final float SHADOW_UNPRESSED = 0.95f;
+ private float shadowOffSet = SHADOW_UNPRESSED;
+ private static final int ROUND_PIXELS = 70;
+ private boolean isBreadButton; //meaning is has the special animation and shadow
+
+ public BRButtonIntro(Context context) {
+ super(context);
+ init(context, null);
+ }
+
+ public BRButtonIntro(Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ init(context, attrs);
+ }
+
+ public BRButtonIntro(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init(context, attrs);
+ }
+
+ public BRButtonIntro(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ init(context, attrs);
+ }
+
+ private void init(Context ctx, AttributeSet attrs) {
+ shadow = BitmapFactory.decodeResource(getResources(), R.drawable.shadow);
+ bPaint = new Paint();
+ bPaint.setAntiAlias(true);
+ bPaintStroke = new Paint();
+ bPaintStroke.setAntiAlias(true);
+ shadowRect = new Rect(0, 0, 100, 100);
+ bRect = new RectF(0, 0, 100, 100);
+ TypedArray a = ctx.obtainStyledAttributes(attrs, R.styleable.BRButton);
+
+ int px16 = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 15, getResources().getDisplayMetrics());
+
+ isBreadButton = a.getBoolean(R.styleable.BRButton_isBreadButton, false);
+
+ int[] attributes = new int[]{android.R.attr.paddingStart, android.R.attr.paddingTop, android.R.attr.paddingEnd, android.R.attr.paddingBottom, R.attr.isBreadButton, R.attr.buttonType};
+ TypedArray arr = ctx.obtainStyledAttributes(attrs, attributes);
+
+ int paddingLeft = arr.getDimensionPixelOffset(0, px16);
+ int paddingTop = arr.getDimensionPixelOffset(1, 0);
+ int paddingRight = arr.getDimensionPixelOffset(2, px16);
+ int paddingBottom = arr.getDimensionPixelOffset(3, 0) + (isBreadButton ? px16 : 0);
+
+ int type = a.getInteger(R.styleable.BRButton_buttonType, 0);
+ setType(type);
+
+ if (isBreadButton) {
+ setBackground(getContext().getDrawable(R.drawable.shadow_trans));
+ }
+
+ setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
+ a.recycle();
+ arr.recycle();
+ final ViewTreeObserver observer = getViewTreeObserver();
+ observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+ @Override
+ public void onGlobalLayout() {
+ if (observer.isAlive()) {
+ observer.removeOnGlobalLayoutListener(this);
+ }
+ correctTextSizeIfNeeded();
+ }
+ });
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ if (isEnabled() && isBreadButton) {
+ if (event.getAction() == MotionEvent.ACTION_DOWN) {
+ if (getParent() != null) {
+ getParent().requestDisallowInterceptTouchEvent(false);
+ }
+ if (type != 3)
+ onTouch(true, ANIMATION_DURATION);
+ } else if (event.getAction() == MotionEvent.ACTION_UP) {
+ onTouch(false, ANIMATION_DURATION);
+ }
+ }
+
+ return super.onTouchEvent(event);
+ }
+
+ private void correctTextSizeIfNeeded() {
+ int limit = 100;
+ int lines = getLineCount();
+ float px = getTextSize();
+ while (lines > 1 && !getText().toString().contains("\n")) {
+ limit--;
+ px -= 1;
+ setTextSize(TypedValue.COMPLEX_UNIT_PX, px);
+ lines = getLineCount();
+ if (limit <= 0) {
+ Timber.d("timber: correctTextSizeIfNeeded: Failed to rescale, limit reached, final: %s", px);
+ break;
+ }
+ }
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ if (isBreadButton) {
+ final int width = getWidth();
+ final int height = getHeight();
+ shadowRect.set(5, height / 4, width - 5, (int) (height * shadowOffSet));
+ int modifiedWidth = width - 10;
+ int modifiedHeight = height - height / 4 - 5;
+ bRect.set(5, 5, modifiedWidth, modifiedHeight + 5);
+ canvas.drawBitmap(shadow, null, shadowRect, null);
+ canvas.drawRoundRect(bRect, ROUND_PIXELS, ROUND_PIXELS, bPaint);
+ if (type == 2 || type == 3 || type == 5) {
+ canvas.drawRoundRect(bRect, ROUND_PIXELS, ROUND_PIXELS, bPaintStroke);
+ }
+ }
+ super.onDraw(canvas);
+ }
+
+ public void setType(int type) {
+ if (type == 3) onTouch(true, 1);
+ this.type = type;
+
+ if (type == 1) { //blue
+ bPaint.setColor(getContext().getColor(R.color.litecoin_litewallet_blue));
+ setTextColor(getContext().getColor(R.color.white));
+ } else if (type == 2) { //gray stroke
+ setTextColor(getContext().getColor(R.color.light_gray));
+ setOutline(R.color.extra_light_gray, R.color.button_secondary);
+ } else if (type == 3) { //blue strokeww
+ setTextColor(getContext().getColor(R.color.litecoin_litewallet_blue));
+ setOutline(R.color.litecoin_litewallet_blue, R.color.button_secondary);
+ } else if (type == 4) { //white stroke
+ setOutline(R.color.white, R.color.button_secondary);
+ } else if (type == 5) {
+ setOutline(R.color.white, R.color.litecoin_litewallet_blue);
+ }
+ invalidate();
+ }
+
+ private void setOutline(@ColorRes int strokeColor, @ColorRes int color) {
+ bPaintStroke.setColor(getContext().getColor(strokeColor));
+ bPaintStroke.setStyle(Paint.Style.STROKE);
+ bPaintStroke.setStrokeWidth(Utils.getPixelsFromDps(getContext(), 1));
+ bPaint.setColor(getContext().getColor(color));
+ bPaint.setStyle(Paint.Style.FILL);
+ }
+
+ private void onTouch(boolean pressed, int duration) {
+ float from = pressed ? 1f : 0.96f;
+ float to = pressed ? 0.96f : 1f;
+ ScaleAnimation scaleAnim = new ScaleAnimation(
+ from, to,
+ from, to,
+ Animation.RELATIVE_TO_SELF, 0.5f,
+ Animation.RELATIVE_TO_SELF, 1f);
+ scaleAnim.setDuration(duration);
+ scaleAnim.setRepeatCount(0);
+ scaleAnim.setInterpolator(new AccelerateDecelerateInterpolator());
+ scaleAnim.setFillAfter(true);
+ scaleAnim.setFillBefore(true);
+ scaleAnim.setFillEnabled(true);
+
+ float[] values = new float[]{SHADOW_UNPRESSED, SHADOW_PRESSED};
+ if (!pressed) {
+ values = new float[]{SHADOW_PRESSED, SHADOW_UNPRESSED};
+ }
+ ValueAnimator shadowAnim = ValueAnimator.ofFloat(values);
+ shadowAnim.setDuration(duration);
+ shadowAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ shadowOffSet = (float) animation.getAnimatedValue();
+ invalidate();
+ }
+ });
+
+ startAnimation(scaleAnim);
+ shadowAnim.start();
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/customviews/BRDialogView.java b/app/src/main/java/com/breadwallet/presenter/customviews/BRDialogView.java
new file mode 100644
index 000000000..5229c3270
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/customviews/BRDialogView.java
@@ -0,0 +1,165 @@
+package com.breadwallet.presenter.customviews;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.text.SpannableString;
+import android.text.method.LinkMovementMethod;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.constraintlayout.widget.ConstraintLayout;
+
+import com.breadwallet.R;
+import com.breadwallet.tools.animation.BRAnimator;
+import com.breadwallet.tools.util.Utils;
+
+import timber.log.Timber;
+
+public class BRDialogView extends DialogFragment {
+
+ private static final String TAG = BRDialogView.class.getName();
+
+ private String title = "";
+ private String message = "";
+ private String posButton = "";
+ private String negButton = "";
+ private BRDialogView.BROnClickListener posListener;
+ private BRDialogView.BROnClickListener negListener;
+ private DialogInterface.OnDismissListener dismissListener;
+ private int iconRes = 0;
+ private Button negativeButton;
+ private LinearLayout buttonsLayout;
+
+ //provide the way to have clickable span in the message
+ private SpannableString spanMessage;
+
+ private ConstraintLayout mainLayout;
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ // Use the Builder class for convenient dialog construction
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ LayoutInflater inflater = getActivity().getLayoutInflater();
+ View view = inflater.inflate(R.layout.bread_alert_dialog, null);
+ TextView titleText = (TextView) view.findViewById(R.id.dialog_title);
+ TextView messageText = (TextView) view.findViewById(R.id.dialog_text);
+ Button positiveButton = (Button) view.findViewById(R.id.pos_button);
+ negativeButton = (Button) view.findViewById(R.id.neg_button);
+// ImageView icon = (ImageView) view.findViewById(R.id.dialog_icon);
+ mainLayout = (ConstraintLayout) view.findViewById(R.id.main_layout);
+ buttonsLayout = (LinearLayout) view.findViewById(R.id.linearLayout3);
+
+ titleText.setText(title);
+ messageText.setText(message);
+ if (spanMessage != null) {
+ messageText.setText(spanMessage);
+ messageText.setMovementMethod(LinkMovementMethod.getInstance());
+ }
+ positiveButton.setText(posButton);
+ positiveButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (!BRAnimator.isClickAllowed()) return;
+ if (posListener != null)
+ posListener.onClick(BRDialogView.this);
+ }
+ });
+ if (Utils.isNullOrEmpty(negButton)) {
+ Timber.e("timber:onCreateDialog: removing negative button");
+ buttonsLayout.removeView(negativeButton);
+ buttonsLayout.requestLayout();
+ }
+ negativeButton.setText(negButton);
+ negativeButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (!BRAnimator.isClickAllowed()) return;
+ if (negListener != null)
+ negListener.onClick(BRDialogView.this);
+ }
+ });
+// if (iconRes != 0)
+// icon.setImageResource(iconRes);
+
+ builder.setView(view);
+// builder.setOnDismissListener(dismissListener);
+ // Create the AlertDialog object and return it
+ return builder.create();
+ }
+
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ super.onDismiss(dialog);
+ if (dismissListener != null)
+ dismissListener.onDismiss(dialog);
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public void setSpan(SpannableString message) {
+ if (message == null) {
+ Timber.e(new NullPointerException("setSpan with null message"));
+ return;
+ }
+ this.spanMessage = message;
+ }
+
+ public void setPosButton(@NonNull String posButton) {
+ this.posButton = posButton;
+ }
+
+ public void setNegButton(String negButton) {
+ this.negButton = negButton;
+ }
+
+ public void setPosListener(BRDialogView.BROnClickListener posListener) {
+ this.posListener = posListener;
+ }
+
+ public void setNegListener(BRDialogView.BROnClickListener negListener) {
+ this.negListener = negListener;
+ }
+
+ public void setDismissListener(DialogInterface.OnDismissListener dismissListener) {
+ this.dismissListener = dismissListener;
+ }
+
+ public void setIconRes(int iconRes) {
+ this.iconRes = iconRes;
+ }
+
+ public static interface BROnClickListener {
+ void onClick(BRDialogView brDialogView);
+ }
+
+ public void dismissWithAnimation() {
+ BRDialogView.this.dismiss();
+
+ }
+
+// public interface SpanClickListener {
+// void onClick();
+//
+// }
+
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/customviews/BRKeyboard.java b/app/src/main/java/com/breadwallet/presenter/customviews/BRKeyboard.java
new file mode 100644
index 000000000..87b7ebcf7
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/customviews/BRKeyboard.java
@@ -0,0 +1,296 @@
+package com.breadwallet.presenter.customviews;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
+import androidx.annotation.ColorInt;
+import android.text.SpannableString;
+import android.text.TextUtils;
+import android.text.style.RelativeSizeSpan;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.Button;
+import android.widget.ImageButton;
+import android.widget.LinearLayout;
+
+import com.breadwallet.R;
+import com.breadwallet.tools.util.Utils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BRKeyboard extends LinearLayout implements View.OnClickListener {
+ public static final String TAG = BRKeyboard.class.getName();
+ List listeners = new ArrayList<>();
+ private Button num0;
+ private Button num1;
+ private Button num2;
+ private Button num3;
+ private Button num4;
+ private Button num5;
+ private Button num6;
+ private Button num7;
+ private Button num8;
+ private Button num9;
+ private Button numDot;
+ private ImageButton numDelete;
+ private boolean showAlphabet;
+
+ public BRKeyboard(Context context) {
+ super(context);
+ init(null);
+ }
+
+ public BRKeyboard(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(attrs);
+ }
+
+ public BRKeyboard(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init(attrs);
+ }
+
+ public BRKeyboard(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ init(attrs);
+ }
+
+ private void init(AttributeSet attrs) {
+ View root = inflate(getContext(), R.layout.pin_pad, this);
+
+ TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.BRKeyboard);
+ final int N = a.getIndexCount();
+ for (int i = 0; i < N; ++i) {
+ int attr = a.getIndex(i);
+ if (attr==R.styleable.BRKeyboard_showAlphabet) {
+ showAlphabet = a.getBoolean(attr, false);
+ }
+ }
+ a.recycle();
+
+ this.setWillNotDraw(false);
+ num0 = (Button) root.findViewById(R.id.num0);
+ num1 = (Button) root.findViewById(R.id.num1);
+ num2 = (Button) root.findViewById(R.id.num2);
+ num3 = (Button) root.findViewById(R.id.num3);
+ num4 = (Button) root.findViewById(R.id.num4);
+ num5 = (Button) root.findViewById(R.id.num5);
+ num6 = (Button) root.findViewById(R.id.num6);
+ num7 = (Button) root.findViewById(R.id.num7);
+ num8 = (Button) root.findViewById(R.id.num8);
+ num9 = (Button) root.findViewById(R.id.num9);
+ numDot = (Button) root.findViewById(R.id.numDot);
+ numDelete = (ImageButton) root.findViewById(R.id.numDelete);
+
+ num0.setOnClickListener(this);
+ num1.setOnClickListener(this);
+ num2.setOnClickListener(this);
+ num3.setOnClickListener(this);
+ num4.setOnClickListener(this);
+ num5.setOnClickListener(this);
+ num6.setOnClickListener(this);
+ num7.setOnClickListener(this);
+ num8.setOnClickListener(this);
+ num9.setOnClickListener(this);
+ numDot.setOnClickListener(this);
+ numDelete.setOnClickListener(this);
+
+ num0.setText(getText(0));
+ num1.setText(getText(1));
+ num2.setText(getText(2));
+ num3.setText(getText(3));
+ num4.setText(getText(4));
+ num5.setText(getText(5));
+ num6.setText(getText(6));
+ num7.setText(getText(7));
+ num8.setText(getText(8));
+ num9.setText(getText(9));
+
+ if (showAlphabet) {
+ int dp8 = Utils.getPixelsFromDps(getContext(), 8);
+ num0.setPadding(0, 0, 0, dp8);
+ num1.setPadding(0, 0, 0, dp8);
+ num2.setPadding(0, 0, 0, dp8);
+ num3.setPadding(0, 0, 0, dp8);
+ num4.setPadding(0, 0, 0, dp8);
+ num5.setPadding(0, 0, 0, dp8);
+ num6.setPadding(0, 0, 0, dp8);
+ num7.setPadding(0, 0, 0, dp8);
+ num8.setPadding(0, 0, 0, dp8);
+ num9.setPadding(0, 0, 0, dp8);
+ }
+ invalidate();
+ }
+
+ private CharSequence getText(int index) {
+ SpannableString span1 = new SpannableString(String.valueOf(index));
+ if (showAlphabet) {
+
+ SpannableString span2;
+ switch (index) {
+ case 2:
+ span2 = new SpannableString("ABC");
+ break;
+ case 3:
+ span2 = new SpannableString("DEF");
+ break;
+ case 4:
+ span2 = new SpannableString("GHI");
+ break;
+ case 5:
+ span2 = new SpannableString("JKL");
+ break;
+ case 6:
+ span2 = new SpannableString("MNO");
+ break;
+ case 7:
+ span2 = new SpannableString("PQRS");
+ break;
+ case 8:
+ span2 = new SpannableString("TUV");
+ break;
+ case 9:
+ span2 = new SpannableString("WXYZ");
+ break;
+ default:
+ span2 = new SpannableString(" ");
+ break;
+ }
+
+ span1.setSpan(new RelativeSizeSpan(1f), 0, 1, 0);
+ span2.setSpan(new RelativeSizeSpan(0.35f), 0, span2.length(), 0);
+ return TextUtils.concat(span1, "\n", span2);
+ } else {
+ return span1;
+ }
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ super.onSizeChanged(w, h, oldw, oldh);
+ invalidate();
+
+ }
+
+ @Override
+ public void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ }
+
+ public void addOnInsertListener(OnInsertListener listener) {
+ listeners.add(listener);
+ }
+
+ @Override
+ public void onClick(View v) {
+ for (OnInsertListener listener : listeners) {
+ listener.onClick(v instanceof ImageButton ? "" : ((Button) v).getText().toString());
+ }
+ }
+
+ public interface OnInsertListener {
+ void onClick(String key);
+ }
+
+ public void setBRKeyboardColor(int color) {
+ setBackgroundColor(getContext().getColor(color));
+ }
+
+ public void setBRButtonTextColor(int color) {
+ num0.setTextColor(getContext().getColor(color));
+ num1.setTextColor(getContext().getColor(color));
+ num2.setTextColor(getContext().getColor(color));
+ num3.setTextColor(getContext().getColor(color));
+ num4.setTextColor(getContext().getColor(color));
+ num5.setTextColor(getContext().getColor(color));
+ num6.setTextColor(getContext().getColor(color));
+ num7.setTextColor(getContext().getColor(color));
+ num8.setTextColor(getContext().getColor(color));
+ num9.setTextColor(getContext().getColor(color));
+ numDot.setTextColor(getContext().getColor(color));
+// numDelete.setColorFilter(getContext().getColor(color));
+ invalidate();
+ }
+
+ public void setBRButtonBackgroundResId(int resId) {
+ num0.setBackgroundResource(resId);
+ num1.setBackgroundResource(resId);
+ num2.setBackgroundResource(resId);
+ num3.setBackgroundResource(resId);
+ num4.setBackgroundResource(resId);
+ num5.setBackgroundResource(resId);
+ num6.setBackgroundResource(resId);
+ num7.setBackgroundResource(resId);
+ num8.setBackgroundResource(resId);
+ num9.setBackgroundResource(resId);
+ numDot.setBackgroundResource(resId);
+ numDelete.setBackgroundResource(resId);
+ invalidate();
+ }
+
+ public void setShowDot(boolean b) {
+ numDot.setVisibility(b ? VISIBLE : GONE);
+ invalidate();
+ }
+
+ public void setBreadground(Drawable drawable) {
+ setBackground(drawable);
+ invalidate();
+ }
+
+ /**
+ * Change the background of a specific button
+ *
+ * @param index the index of the button (10 - delete, 11 - dot)
+ * @param color the color to be used
+ */
+ public void setCustomButtonBackgroundColor(int index, int color) {
+ switch (index) {
+ case 0:
+ num0.setBackgroundColor(color);
+ break;
+ case 1:
+ num1.setBackgroundColor(color);
+ break;
+ case 2:
+ num2.setBackgroundColor(color);
+ break;
+ case 3:
+ num3.setBackgroundColor(color);
+ break;
+ case 4:
+ num4.setBackgroundColor(color);
+ break;
+ case 5:
+ num5.setBackgroundColor(color);
+ break;
+ case 6:
+ num6.setBackgroundColor(color);
+ break;
+ case 7:
+ num7.setBackgroundColor(color);
+ break;
+ case 8:
+ num8.setBackgroundColor(color);
+ break;
+ case 9:
+ num9.setBackgroundColor(color);
+ break;
+ case 10:
+ numDelete.setBackgroundColor(color);
+ break;
+ case 11:
+ numDot.setBackgroundColor(color);
+ break;
+ }
+ }
+
+ public void setDeleteImage(Drawable res) {
+ numDelete.setImageDrawable(res);
+ }
+
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/customviews/BRLinearLayoutWithCaret.java b/app/src/main/java/com/breadwallet/presenter/customviews/BRLinearLayoutWithCaret.java
new file mode 100644
index 000000000..29d64ad1e
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/customviews/BRLinearLayoutWithCaret.java
@@ -0,0 +1,164 @@
+package com.breadwallet.presenter.customviews;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Path;
+import androidx.annotation.ColorInt;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.widget.LinearLayout;
+
+import com.breadwallet.R;
+
+public class BRLinearLayoutWithCaret extends LinearLayout {
+ public static final String TAG = BRLinearLayoutWithCaret.class.getName();
+
+ private float mXfract = 0f;
+ private float mYfract = 0f;
+
+ private Paint strokePaint;
+ private Paint backgroundPaint;
+ private Path path_stroke;
+ private Path path_background;
+ private int caretHeight;
+ private boolean withStroke;
+
+ private int width;
+ private int height;
+ private boolean created;
+
+ public BRLinearLayoutWithCaret(Context context) {
+ super(context);
+ init(null);
+ }
+
+ public BRLinearLayoutWithCaret(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(attrs);
+ }
+
+ public BRLinearLayoutWithCaret(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init(attrs);
+ }
+
+ public void setYFraction(final float fraction) {
+ mYfract = fraction;
+ float translationY = getHeight() * fraction;
+ setTranslationY(translationY);
+ }
+
+ public float getYFraction() {
+ return mYfract;
+ }
+
+ public void setXFraction(final float fraction) {
+ mXfract = fraction;
+ float translationX = getWidth() * fraction;
+ setTranslationX(translationX);
+ }
+
+ public float getXFraction() {
+ return mXfract;
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ int width = MeasureSpec.getSize(widthMeasureSpec);
+ int height = MeasureSpec.getSize(heightMeasureSpec);
+ // Correct any translations set before the measure was set
+ setTranslationX(mXfract * width);
+ setTranslationY(mYfract * height);
+ }
+
+ private void init(AttributeSet attrs) {
+ strokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ strokePaint.setStyle(Paint.Style.STROKE);
+ float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics());
+ strokePaint.setStrokeWidth(px);
+ strokePaint.setColor(getContext().getColor(R.color.separator_gray));
+
+ path_stroke = new Path();
+ path_background = new Path();
+
+ backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ backgroundPaint.setStyle(Paint.Style.FILL);
+ backgroundPaint.setColor(getContext().getColor(R.color.extra_light_blue_background));
+
+ setBackgroundColor(getContext().getColor(android.R.color.transparent));
+ TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.BRLinearLayoutWithCaret);
+ final int N = a.getIndexCount();
+ for (int i = 0; i < N; ++i) {
+ int attr = a.getIndex(i);
+
+ if (attr==R.styleable.BRLinearLayoutWithCaret_strokeColor) {
+ @ColorInt int strokeColor = a.getColor(attr, 0);
+ if (strokeColor != 0) strokePaint.setColor(strokeColor);
+ } else if (attr==R.styleable.BRLinearLayoutWithCaret_backgroundColor) {
+ @ColorInt int bgColor = a.getColor(attr, 0);
+ if (bgColor != 0) backgroundPaint.setColor(bgColor);
+ }else{
+ withStroke = a.getBoolean(attr, false);
+ }
+ }
+ a.recycle();
+
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ super.onSizeChanged(w, h, oldw, oldh);
+ if (w != 0 && !created) {
+ created = true;
+ width = w;
+ height = h;
+
+ caretHeight = h / 10;
+ int caretWidth = caretHeight * 2;
+
+ path_stroke.moveTo(0, caretHeight);
+ path_stroke.lineTo(width / 2 - caretWidth / 2, caretHeight);
+ path_stroke.lineTo(width / 2, 0);
+ path_stroke.lineTo(width / 2 + caretWidth / 2, caretHeight);
+ path_stroke.lineTo(width, caretHeight);
+
+
+ path_background.moveTo(0, caretHeight);
+ path_background.lineTo(width / 2 - caretWidth / 2, caretHeight);// ____
+ path_background.lineTo(width / 2, 0);// ____/
+ path_background.lineTo(width / 2 + caretWidth / 2, caretHeight); // ____/\
+ path_background.lineTo(width, caretHeight);// ____/\____
+ path_background.lineTo(width, height);
+ path_background.lineTo(0, height);
+ path_background.lineTo(0, 0);
+
+ invalidate();
+ }
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ canvas.drawPath(path_background, backgroundPaint);
+ if (withStroke) {
+ canvas.drawPath(path_stroke, strokePaint);
+ }
+
+ }
+
+ public void setBgColor(@ColorInt int backgroundColor) {
+ backgroundPaint.setColor(backgroundColor);
+ }
+
+ public void setStrokeColor(@ColorInt int strokeColor) {
+ strokePaint.setColor(strokeColor);
+ }
+
+ public void setWithStroke(boolean withStroke) {
+ this.withStroke = withStroke;
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/customviews/BRLockScreenConstraintLayout.java b/app/src/main/java/com/breadwallet/presenter/customviews/BRLockScreenConstraintLayout.java
new file mode 100644
index 000000000..a3df2f1a3
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/customviews/BRLockScreenConstraintLayout.java
@@ -0,0 +1,51 @@
+package com.breadwallet.presenter.customviews;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.LinearGradient;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.Shader;
+import androidx.constraintlayout.widget.ConstraintLayout;
+import android.util.AttributeSet;
+
+import com.breadwallet.R;
+
+public class BRLockScreenConstraintLayout extends ConstraintLayout {
+ public static final String TAG = BRLockScreenConstraintLayout.class.getName();
+ private int width;
+ private int height;
+ private boolean created;
+
+ public BRLockScreenConstraintLayout(Context context) {
+ super(context);
+ init();
+ }
+
+ public BRLockScreenConstraintLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ public BRLockScreenConstraintLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init();
+ }
+
+ private void init() {
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ super.onSizeChanged(w, h, oldw, oldh);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ long start = System.currentTimeMillis();
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ int width = MeasureSpec.getSize(widthMeasureSpec);
+ int height = MeasureSpec.getSize(heightMeasureSpec);
+ // Correct any translations set before the measure was set
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/customviews/BRNotificationBar.java b/app/src/main/java/com/breadwallet/presenter/customviews/BRNotificationBar.java
new file mode 100644
index 000000000..9817baf3a
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/customviews/BRNotificationBar.java
@@ -0,0 +1,51 @@
+package com.breadwallet.presenter.customviews;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.annotation.Nullable;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.BreadActivity;
+import com.breadwallet.tools.util.Utils;
+
+public class BRNotificationBar extends androidx.appcompat.widget.Toolbar {
+
+ public BRNotificationBar(Context context) {
+ super(context);
+ init();
+ }
+
+ public BRNotificationBar(Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ public BRNotificationBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init();
+ }
+
+ private void init() {
+ setBackgroundResource(R.drawable.notification_gradient);
+ setElevation(Utils.getPixelsFromDps(getContext(), 8));
+ setContentInsetsRelative(0, 0);
+
+ inflate(getContext(), R.layout.notification_bar, this);
+ TextView description = findViewById(R.id.description);
+ BRButton close = findViewById(R.id.cancel_button);
+
+ description.setText("No internet connection found.\nCheck your connection and try again.");
+
+ close.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (getContext() instanceof BreadActivity) {
+ ((BreadActivity) getContext()).removeNotificationBar();
+ }
+ }
+ });
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/breadwallet/presenter/customviews/BRRelativeLayout.java b/app/src/main/java/com/breadwallet/presenter/customviews/BRRelativeLayout.java
new file mode 100644
index 000000000..1be33448d
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/customviews/BRRelativeLayout.java
@@ -0,0 +1,55 @@
+package com.breadwallet.presenter.customviews;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.RelativeLayout;
+
+public class BRRelativeLayout extends RelativeLayout {
+ public static final String TAG = BRRelativeLayout.class.getName();
+
+ private float mXfract = 0f;
+ private float mYfract = 0f;
+
+ public BRRelativeLayout(Context context) {
+ super(context);
+ }
+
+ public BRRelativeLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public BRRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ public void setYFraction(final float fraction) {
+ mYfract=fraction;
+ float translationY = getHeight() * fraction;
+ setTranslationY(translationY);
+ }
+
+ public float getYFraction() {
+ return mYfract;
+ }
+
+ public void setXFraction(final float fraction) {
+ mXfract=fraction;
+ float translationX = getWidth() * fraction;
+ setTranslationX(translationX);
+ }
+
+ public float getXFraction() {
+ return mXfract;
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ int width = MeasureSpec.getSize(widthMeasureSpec);
+ int height = MeasureSpec.getSize(heightMeasureSpec);
+ // Correct any translations set before the measure was set
+ setTranslationX(mXfract*width);
+ setTranslationY(mYfract*height);
+ }
+
+}
diff --git a/app/src/main/assets/fonts/AlexandriaFLF.ttf b/app/src/main/java/com/breadwallet/presenter/customviews/BRText.java
similarity index 100%
rename from app/src/main/assets/fonts/AlexandriaFLF.ttf
rename to app/src/main/java/com/breadwallet/presenter/customviews/BRText.java
diff --git a/app/src/main/java/com/breadwallet/presenter/customviews/BRToast.java b/app/src/main/java/com/breadwallet/presenter/customviews/BRToast.java
new file mode 100644
index 000000000..c5a3dedc1
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/customviews/BRToast.java
@@ -0,0 +1,63 @@
+package com.breadwallet.presenter.customviews;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Handler;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.breadwallet.BreadApp;
+import com.breadwallet.R;
+
+public class BRToast {
+ private static boolean customToastAvailable = true;
+ private static String oldMessage;
+ private static Toast toast;
+
+ /**
+ * Shows a custom toast using the given string as a paramater,
+ *
+ * @param message the message to be shown in the custom toast
+ */
+ public static void showCustomToast(Context app, String message, int yOffSet, int duration, int layoutDrawable) {
+ if (app == null) return;
+ if (!(app instanceof Activity)) app = BreadApp.getBreadContext();
+ if (app == null) return;
+ if (toast == null) toast = new Toast(app);
+ if (!BreadApp.isAppInBackground(app)) return;
+
+ if (customToastAvailable || !oldMessage.equals(message)) {
+ oldMessage = message;
+ customToastAvailable = false;
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ customToastAvailable = true;
+ }
+ }, 1000);
+ LayoutInflater inflater = ((Activity) app).getLayoutInflater();
+ View layout = inflater.inflate(R.layout.toast, (ViewGroup) ((Activity) app).findViewById(R.id.toast_layout_root));
+ layout.setBackgroundResource(layoutDrawable);
+ TextView text = layout.findViewById(R.id.toast_text);
+ text.setText(message);
+ toast.setGravity(Gravity.TOP, 0, yOffSet);
+ toast.setDuration(duration);
+ toast.setView(layout);
+ toast.show();
+ }
+ }
+
+ public static void cancelToast() {
+ if (toast != null) {
+ toast.cancel();
+ }
+ }
+
+ public static boolean isToastShown() {
+ return toast != null && toast.getView() != null && toast.getView().isShown();
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/customviews/BubbleTextView.java b/app/src/main/java/com/breadwallet/presenter/customviews/BubbleTextView.java
deleted file mode 100755
index 733d19676..000000000
--- a/app/src/main/java/com/breadwallet/presenter/customviews/BubbleTextView.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package com.breadwallet.presenter.customviews;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.util.AttributeSet;
-import android.widget.TextView;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 05/25/16.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-public class BubbleTextView extends TextView {
- public BubbleTextView(Context context) {
- super(context);
- initView();
- }
-
- public BubbleTextView(Context context, AttributeSet attrs) {
- super(context, attrs);
- initView();
- }
-
- public BubbleTextView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- initView();
- }
-
- private void initView() {
- setPadding(30, 50, 30, 20);
- }
-
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- }
-
- @Override
- protected void onSizeChanged(int w, int h, int oldw, int oldh) {
- super.onSizeChanged(w, h, oldw, oldh);
- }
-
- @Override
- public void layout(int l, int t, int r, int b) {
- super.layout(l, t, r, b);
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- }
-
-}
diff --git a/app/src/main/java/com/breadwallet/presenter/entities/BRMenuItem.java b/app/src/main/java/com/breadwallet/presenter/entities/BRMenuItem.java
new file mode 100644
index 000000000..e1a3f9279
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/entities/BRMenuItem.java
@@ -0,0 +1,20 @@
+package com.breadwallet.presenter.entities;
+
+import android.content.DialogInterface;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.view.View;
+
+public class BRMenuItem {
+
+ public String text;
+ public int resId;
+ public View.OnClickListener listener;
+
+ public BRMenuItem(String text, int resId, View.OnClickListener listener) {
+ this.text = text;
+ this.resId = resId;
+ this.listener = listener;
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/breadwallet/presenter/entities/BRMerkleBlockEntity.java b/app/src/main/java/com/breadwallet/presenter/entities/BRMerkleBlockEntity.java
index 3efa729d4..7f3c86095 100644
--- a/app/src/main/java/com/breadwallet/presenter/entities/BRMerkleBlockEntity.java
+++ b/app/src/main/java/com/breadwallet/presenter/entities/BRMerkleBlockEntity.java
@@ -1,30 +1,5 @@
package com.breadwallet.presenter.entities;
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 9/25/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
public class BRMerkleBlockEntity {
private long id;
diff --git a/app/src/main/java/com/breadwallet/presenter/entities/BRPeerEntity.java b/app/src/main/java/com/breadwallet/presenter/entities/BRPeerEntity.java
index c7e65f976..0b6eb2b03 100644
--- a/app/src/main/java/com/breadwallet/presenter/entities/BRPeerEntity.java
+++ b/app/src/main/java/com/breadwallet/presenter/entities/BRPeerEntity.java
@@ -1,31 +1,5 @@
package com.breadwallet.presenter.entities;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 9/29/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
public class BRPeerEntity {
private int id;
diff --git a/app/src/main/java/com/breadwallet/presenter/entities/BRSecurityCenterItem.java b/app/src/main/java/com/breadwallet/presenter/entities/BRSecurityCenterItem.java
new file mode 100644
index 000000000..082c818fb
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/entities/BRSecurityCenterItem.java
@@ -0,0 +1,22 @@
+package com.breadwallet.presenter.entities;
+
+import android.view.View;
+import android.widget.ImageView;
+
+import static android.R.attr.checkMark;
+
+public class BRSecurityCenterItem {
+
+ public String title;
+ public String text;
+ public int checkMarkResId;
+ public View.OnClickListener listener;
+
+ public BRSecurityCenterItem(String title, String text, int checkMarkResId, View.OnClickListener listener) {
+ this.title = title;
+ this.text = text;
+ this.checkMarkResId = checkMarkResId;
+ this.listener = listener;
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/breadwallet/presenter/entities/BRSettingsItem.java b/app/src/main/java/com/breadwallet/presenter/entities/BRSettingsItem.java
new file mode 100644
index 000000000..e55c1f375
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/entities/BRSettingsItem.java
@@ -0,0 +1,19 @@
+package com.breadwallet.presenter.entities;
+
+import android.view.View;
+
+public class BRSettingsItem {
+
+ public boolean isSection;
+ public String title;
+ public String addonText;
+ public View.OnClickListener listener;
+
+ public BRSettingsItem(String title, String addonText, View.OnClickListener listener, boolean isSection) {
+ this.title = title;
+ this.addonText = addonText;
+ this.listener = listener;
+ this.isSection = isSection;
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/breadwallet/presenter/entities/BRTransactionEntity.java b/app/src/main/java/com/breadwallet/presenter/entities/BRTransactionEntity.java
index 0e18398dd..17d132a42 100644
--- a/app/src/main/java/com/breadwallet/presenter/entities/BRTransactionEntity.java
+++ b/app/src/main/java/com/breadwallet/presenter/entities/BRTransactionEntity.java
@@ -1,41 +1,11 @@
package com.breadwallet.presenter.entities;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 9/23/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
public class BRTransactionEntity {
private byte[] buff;
private int blockheight;
private long timestamp;
private String txHash;
- private BRTransactionEntity(){
-
- }
-
public long getBlockheight() {
return blockheight;
}
diff --git a/app/src/main/java/com/breadwallet/presenter/entities/BlockEntity.java b/app/src/main/java/com/breadwallet/presenter/entities/BlockEntity.java
index 8fdb56b7d..552329a53 100644
--- a/app/src/main/java/com/breadwallet/presenter/entities/BlockEntity.java
+++ b/app/src/main/java/com/breadwallet/presenter/entities/BlockEntity.java
@@ -1,31 +1,5 @@
package com.breadwallet.presenter.entities;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 1/13/16.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
public class BlockEntity {
public static final String TAG = BlockEntity.class.getName();
diff --git a/app/src/main/java/com/breadwallet/presenter/entities/CurrencyEntity.java b/app/src/main/java/com/breadwallet/presenter/entities/CurrencyEntity.java
index b51d8c330..f2aec6f68 100644
--- a/app/src/main/java/com/breadwallet/presenter/entities/CurrencyEntity.java
+++ b/app/src/main/java/com/breadwallet/presenter/entities/CurrencyEntity.java
@@ -2,40 +2,22 @@
import java.io.Serializable;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 8/18/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
public class CurrencyEntity implements Serializable {
//Change this after modifying the class
private static final long serialVersionUID = 7526472295622776147L;
public static final String TAG = CurrencyEntity.class.getName();
- public String codeAndName;
- public String name;
public String code;
+ public String name;
public float rate;
+
+ public CurrencyEntity(String code, String name, float rate) {
+ this.code = code;
+ this.name = name;
+ this.rate = rate;
+ }
+
+ public CurrencyEntity() {
+ }
}
diff --git a/app/src/main/java/com/breadwallet/presenter/entities/Fee.java b/app/src/main/java/com/breadwallet/presenter/entities/Fee.java
new file mode 100644
index 000000000..ce71e81a5
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/entities/Fee.java
@@ -0,0 +1,21 @@
+package com.breadwallet.presenter.entities;
+
+/**
+ * Litewallet
+ * Created by Mohamed Barry on 3/10/20
+ * email: mosadialiou@gmail.com
+ * Copyright ยฉ 2020 Litecoin Foundation. All rights reserved.
+ */
+public class Fee {
+ public final long luxury;
+ public final long regular;
+ public final long economy;
+ public final long timestamp;
+
+ public Fee(long luxury, long regular, long economy, long timestamp) {
+ this.luxury = luxury;
+ this.regular = regular;
+ this.economy = economy;
+ this.timestamp = timestamp;
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/entities/ImportPrivKeyEntity.java b/app/src/main/java/com/breadwallet/presenter/entities/ImportPrivKeyEntity.java
index f40a3e1e8..dc71f8c03 100644
--- a/app/src/main/java/com/breadwallet/presenter/entities/ImportPrivKeyEntity.java
+++ b/app/src/main/java/com/breadwallet/presenter/entities/ImportPrivKeyEntity.java
@@ -1,31 +1,5 @@
package com.breadwallet.presenter.entities;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 6/2/16.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
public class ImportPrivKeyEntity {
public static final String TAG = ImportPrivKeyEntity.class.getName();
diff --git a/app/src/main/java/com/breadwallet/presenter/entities/Partner.java b/app/src/main/java/com/breadwallet/presenter/entities/Partner.java
new file mode 100644
index 000000000..d1254b661
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/entities/Partner.java
@@ -0,0 +1,51 @@
+package com.breadwallet.presenter.entities;
+
+import com.breadwallet.presenter.fragments.FragmentBuy;
+
+/**
+ * Movo
+ * Created by sadia on 2020-January-27
+ * email: mosadialiou@gmail.com
+ */
+
+public class Partner {
+ private int logo;
+ private int title;
+ private int details;
+ private FragmentBuy.Partner code;
+
+ public Partner(int logo, int title, int details, FragmentBuy.Partner code) {
+ this.logo = logo;
+ this.title = title;
+ this.details = details;
+ this.code = code;
+ }
+
+ public int getLogo() {
+ return logo;
+ }
+
+ public void setLogo(int logo) {
+ this.logo = logo;
+ }
+
+ public int getTitle() {
+ return title;
+ }
+
+ public void setTitle(int title) {
+ this.title = title;
+ }
+
+ public int getDetails() {
+ return details;
+ }
+
+ public void setDetails(int details) {
+ this.details = details;
+ }
+
+ public FragmentBuy.Partner getCode() {
+ return code;
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/entities/PartnerNames.kt b/app/src/main/java/com/breadwallet/presenter/entities/PartnerNames.kt
new file mode 100644
index 000000000..c4e2c9eca
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/entities/PartnerNames.kt
@@ -0,0 +1,11 @@
+package com.breadwallet.presenter.entities
+
+enum class PartnerNames(val key: String) {
+ MOONPAY("moonpay"),
+ BITREFILL("bitrefill"),
+ INFURA("infura-api"),
+ LITEWALLETOPS("litewallet-ops"),
+ LITEWALLETSTART("litewallet-start"),
+ PUSHER("pusher-instance-id"),
+ PUSHERSTAGING("pusher-staging-instance-id"),
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/entities/PaymentItem.java b/app/src/main/java/com/breadwallet/presenter/entities/PaymentItem.java
new file mode 100644
index 000000000..12e4c7e64
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/entities/PaymentItem.java
@@ -0,0 +1,30 @@
+package com.breadwallet.presenter.entities;
+
+public class PaymentItem {
+ public static final String TAG = PaymentItem.class.getName();
+
+ public byte[] serializedTx;
+ public String[] addresses;
+ public long amount;
+ public String cn;
+ public boolean isAmountRequested;
+ public String comment;
+
+ public PaymentItem(String[] addresses, byte[] tx, long theAmount, String theCn, boolean isAmountRequested) {
+ this.isAmountRequested = isAmountRequested;
+ this.serializedTx = tx;
+ this.addresses = addresses;
+ this.amount = theAmount;
+ this.cn = theCn;
+ }
+
+ public PaymentItem(String[] addresses, byte[] tx,long theAmount, String theCn, boolean isAmountRequested, String comment) {
+ this.isAmountRequested = isAmountRequested;
+ this.serializedTx = tx;
+ this.addresses = addresses;
+ this.amount = theAmount;
+ this.cn = theCn;
+ this.comment = comment;
+ }
+
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/entities/PaymentRequestEntity.java b/app/src/main/java/com/breadwallet/presenter/entities/PaymentRequestEntity.java
deleted file mode 100644
index cf5280fe3..000000000
--- a/app/src/main/java/com/breadwallet/presenter/entities/PaymentRequestEntity.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package com.breadwallet.presenter.entities;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 11/19/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-public class PaymentRequestEntity {
- public static final String TAG = PaymentRequestEntity.class.getName();
-
- public byte[] serializedTx;
-
- public String[] addresses;
- public long amount;
- public String cn;
- public boolean isAmountRequested;
-
- public PaymentRequestEntity(String theAddress[], long theAmount, String theCn, byte[] serializedTx, boolean isAmountRequested) {
- this.isAmountRequested = isAmountRequested;
- this.serializedTx = serializedTx;
- this.addresses = theAddress;
- this.amount = theAmount;
- this.cn = theCn;
- }
-
-}
diff --git a/app/src/main/java/com/breadwallet/presenter/entities/PaymentRequestWrapper.java b/app/src/main/java/com/breadwallet/presenter/entities/PaymentRequestWrapper.java
index 9b50a8bae..0a71875fa 100644
--- a/app/src/main/java/com/breadwallet/presenter/entities/PaymentRequestWrapper.java
+++ b/app/src/main/java/com/breadwallet/presenter/entities/PaymentRequestWrapper.java
@@ -1,31 +1,5 @@
package com.breadwallet.presenter.entities;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 11/12/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
public class PaymentRequestWrapper {
public final String TAG = PaymentRequestWrapper.class.getName();
diff --git a/app/src/main/java/com/breadwallet/presenter/entities/PeerEntity.java b/app/src/main/java/com/breadwallet/presenter/entities/PeerEntity.java
index 1b21fad68..934e2221f 100644
--- a/app/src/main/java/com/breadwallet/presenter/entities/PeerEntity.java
+++ b/app/src/main/java/com/breadwallet/presenter/entities/PeerEntity.java
@@ -1,31 +1,5 @@
package com.breadwallet.presenter.entities;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 1/13/16.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
public class PeerEntity {
public static final String TAG = PeerEntity.class.getName();
diff --git a/app/src/main/java/com/breadwallet/presenter/entities/RequestObject.java b/app/src/main/java/com/breadwallet/presenter/entities/RequestObject.java
index adb74658d..6b49e6e0f 100644
--- a/app/src/main/java/com/breadwallet/presenter/entities/RequestObject.java
+++ b/app/src/main/java/com/breadwallet/presenter/entities/RequestObject.java
@@ -1,31 +1,5 @@
package com.breadwallet.presenter.entities;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 11/20/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
public class RequestObject {
public static final String TAG = RequestObject.class.getName();
public String address;
diff --git a/app/src/main/java/com/breadwallet/presenter/entities/TransactionListItem.java b/app/src/main/java/com/breadwallet/presenter/entities/TransactionListItem.java
deleted file mode 100644
index 02e3921dc..000000000
--- a/app/src/main/java/com/breadwallet/presenter/entities/TransactionListItem.java
+++ /dev/null
@@ -1,104 +0,0 @@
-package com.breadwallet.presenter.entities;
-
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 1/13/16.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-public class TransactionListItem {
- public static final String TAG = TransactionListItem.class.getName();
- private long timeStamp;
- private int blockHeight;
- private String hash;
- private long sent;
- private long received;
- private long fee;
- private String to[];
- private String from[];
- private long balanceAfterTx;
- private long outAmounts[];
-
- private TransactionListItem() {
- }
-
- public TransactionListItem(long timeStamp, int blockHeight, String hash, long sent,
- long received, long fee, String to[], String from[],
- long balanceAfterTx, long[] outAmounts) {
- this.timeStamp = timeStamp;
- this.blockHeight = blockHeight;
- this.hash = hash;
- this.sent = sent;
- this.received = received;
- this.fee = fee;
- this.to = to;
- this.from = from;
- this.balanceAfterTx = balanceAfterTx;
- this.outAmounts = outAmounts;
- }
-
- public int getBlockHeight() {
- return blockHeight;
- }
-
- public long getFee() {
- return fee;
- }
-
- public String[] getFrom() {
- return from;
- }
-
- public String getHexId() {
- return hash;
- }
-
- public long getReceived() {
- return received;
- }
-
- public long getSent() {
- return sent;
- }
-
- public static String getTAG() {
- return TAG;
- }
-
- public long getTimeStamp() {
- return timeStamp;
- }
-
- public String[] getTo() {
- return to;
- }
-
- public long getBalanceAfterTx() {
- return balanceAfterTx;
- }
-
- public long[] getOutAmounts() {
- return outAmounts;
- }
-
-}
diff --git a/app/src/main/java/com/breadwallet/presenter/entities/TxItem.java b/app/src/main/java/com/breadwallet/presenter/entities/TxItem.java
new file mode 100644
index 000000000..ca84b4bfc
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/entities/TxItem.java
@@ -0,0 +1,101 @@
+package com.breadwallet.presenter.entities;
+
+
+import com.breadwallet.tools.util.Utils;
+import com.platform.entities.TxMetaData;
+
+public class TxItem {
+ public static final String TAG = TxItem.class.getName();
+ private long timeStamp;
+ private int blockHeight;
+ private byte[] txHash;
+ private long sent;
+ private long received;
+ private long fee;
+ private String to[];
+ private String from[];
+ public String txReversed;
+ private long balanceAfterTx;
+ private long outAmounts[];
+ private boolean isValid;
+ private int txSize;
+ public TxMetaData metaData;
+
+ private TxItem() {
+ }
+
+ public TxItem(long timeStamp, int blockHeight, byte[] hash, String txReversed, long sent,
+ long received, long fee, String to[], String from[],
+ long balanceAfterTx, int txSize, long[] outAmounts, boolean isValid) {
+ this.timeStamp = timeStamp;
+ this.blockHeight = blockHeight;
+ this.txReversed = txReversed;
+ this.txHash = hash;
+ this.sent = sent;
+ this.received = received;
+ this.fee = fee;
+ this.to = to;
+ this.from = from;
+ this.balanceAfterTx = balanceAfterTx;
+ this.outAmounts = outAmounts;
+ this.isValid = isValid;
+ this.txSize = txSize;
+ }
+
+ public int getBlockHeight() {
+ return blockHeight;
+ }
+
+ public long getFee() {
+ return fee;
+ }
+
+ public int getTxSize() {
+ return txSize;
+ }
+
+ public String[] getFrom() {
+ return from;
+ }
+
+ public byte[] getTxHash() {
+ return txHash;
+ }
+
+ public String getTxHashHexReversed() {
+ return txReversed;
+ }
+
+ public long getReceived() {
+ return received;
+ }
+
+ public long getSent() {
+ return sent;
+ }
+
+ public static String getTAG() {
+ return TAG;
+ }
+
+ public long getTimeStamp() {
+ return timeStamp;
+ }
+
+ public String[] getTo() {
+ return to;
+ }
+
+ public long getBalanceAfterTx() {
+ return balanceAfterTx;
+ }
+
+ public long[] getOutAmounts() {
+ return outAmounts;
+ }
+
+ public boolean isValid() {
+ return isValid;
+ }
+
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/BuyPartnersAdapter.java b/app/src/main/java/com/breadwallet/presenter/fragments/BuyPartnersAdapter.java
new file mode 100644
index 000000000..b56d6de13
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/fragments/BuyPartnersAdapter.java
@@ -0,0 +1,132 @@
+package com.breadwallet.presenter.fragments;
+
+import android.content.Context;
+import android.net.Uri;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.HorizontalScrollView;
+import android.widget.ImageView;
+import android.widget.RadioGroup;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.StringRes;
+import androidx.browser.customtabs.CustomTabColorSchemeParams;
+import androidx.browser.customtabs.CustomTabsIntent;
+import androidx.fragment.app.FragmentActivity;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.entities.Partner;
+import com.breadwallet.tools.animation.BRAnimator;
+import com.breadwallet.tools.util.BRConstants;
+
+import java.util.List;
+
+/**
+ * Litewallet
+ * Created by sadia on 2020-January-27
+ * email: mosadialiou@gmail.com
+ */
+class BuyPartnersAdapter extends RecyclerView.Adapter {
+
+ private final LayoutInflater inflater;
+ private List partners;
+
+ BuyPartnersAdapter(Context context, @NonNull List partners) {
+ inflater = LayoutInflater.from(context);
+ this.partners = partners;
+ }
+
+ @NonNull
+ @Override
+ public PartnerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ return new PartnerViewHolder(inflater.inflate(R.layout.buy_partner_item, parent, false));
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull final PartnerViewHolder holder, int position) {
+ final Partner partner = partners.get(position);
+ holder.logo.setImageResource(partner.getLogo());
+ holder.title.setText(partner.getTitle());
+ holder.detail.setText(partner.getDetails());
+ holder.fiatOptionHScrollView.post(() -> {
+ int checkId = holder.fiatOptions.getCheckedRadioButtonId();
+ View option = holder.fiatOptions.findViewById(checkId);
+ holder.fiatOptionHScrollView.scrollTo((int) option.getX(), (int) option.getY());
+ });
+
+ if (partner.getCode() == FragmentBuy.Partner.BITREFILL) {
+ holder.fiatOptionHScrollView.setVisibility(View.INVISIBLE);
+ holder.fiatOptions.setVisibility(View.INVISIBLE);
+ }
+
+ holder.buyPartnerWrapper.setOnClickListener(v -> {
+ int currencyResId = getCurrencyResId(holder.fiatOptions.getCheckedRadioButtonId());
+ final Context context = v.getContext();
+ String currency = context.getString(currencyResId);
+ if (partner.getCode() == FragmentBuy.Partner.MOONPAY) {
+ CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder()
+ .setDefaultColorSchemeParams(new CustomTabColorSchemeParams.Builder().setToolbarColor(context.getColor(R.color.litecoin_litewallet_blue)).build())
+ .setUrlBarHidingEnabled(true);
+ CustomTabsIntent customTabsIntent = builder.build();
+ String buyUrl = FragmentBuy.url(context, partner.getCode(), currency);
+ customTabsIntent.launchUrl(context, Uri.parse(buyUrl));
+ } else {
+ BRAnimator.showBuyFragment((FragmentActivity) context, currency, partner.getCode());
+ }
+ });
+ }
+
+ @StringRes
+ private int getCurrencyResId(int checkedOption) {
+ int currency;
+ if (checkedOption == R.id.cad_fiat) {
+ currency = R.string.cad_currency_code;
+ } else if (checkedOption == R.id.eur_fiat) {
+ currency = R.string.eur_currency_code;
+ } else if (checkedOption == R.id.jpy_fiat) {
+ currency = R.string.jpy_currency_code;
+ } else if (checkedOption == R.id.gbp_fiat) {
+ currency = R.string.gbp_currency_code;
+ } else if (checkedOption == R.id.hkd_fiat) {
+ currency = R.string.hkd_currency_code;
+ } else if (checkedOption == R.id.idr_fiat) {
+ currency = R.string.idr_currency_code;
+ } else if (checkedOption == R.id.rub_fiat) {
+ currency = R.string.rub_currency_code;
+ } else if (checkedOption == R.id.sgd_fiat) {
+ currency = R.string.sgd_currency_code;
+ } else {
+ currency = R.string.usd_currency_code;
+ }
+ return currency;
+ }
+
+ @Override
+ public int getItemCount() {
+ return partners.size();
+ }
+
+ static class PartnerViewHolder extends RecyclerView.ViewHolder {
+
+ final ImageView logo;
+ final TextView title;
+ final TextView detail;
+ final RadioGroup fiatOptions;
+ final View buyPartnerWrapper;
+ final HorizontalScrollView fiatOptionHScrollView;
+
+ PartnerViewHolder(@NonNull View itemView) {
+ super(itemView);
+
+ logo = itemView.findViewById(R.id.logo);
+ title = itemView.findViewById(R.id.titleLbl);
+ detail = itemView.findViewById(R.id.detailLbl);
+ fiatOptions = itemView.findViewById(R.id.fiat_option);
+ fiatOptionHScrollView = itemView.findViewById(R.id.fiat_option_h_scroll);
+ buyPartnerWrapper = itemView.findViewById(R.id.buyPartnerWrapper);
+ }
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/BuyTabFragment.java b/app/src/main/java/com/breadwallet/presenter/fragments/BuyTabFragment.java
new file mode 100644
index 000000000..01f4f4a60
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/fragments/BuyTabFragment.java
@@ -0,0 +1,61 @@
+package com.breadwallet.presenter.fragments;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.core.content.ContextCompat;
+import androidx.fragment.app.Fragment;
+import androidx.recyclerview.widget.DividerItemDecoration;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.entities.Partner;
+import com.breadwallet.tools.manager.AnalyticsManager;
+import com.breadwallet.tools.util.BRConstants;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Litewallet
+ * Created by sadia on 2020-January-27
+ * email: mosadialiou@gmail.com
+ */
+public class BuyTabFragment extends Fragment {
+
+ private RecyclerView mRecyclerView;
+
+ @Nullable
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.fragment_buy_tab, container, false);
+ }
+
+ @Override
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+
+ mRecyclerView = view.findViewById(R.id.recycler_view);
+
+ mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
+
+ DividerItemDecoration itemDecor = new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration.VERTICAL);
+ itemDecor.setDrawable(ContextCompat.getDrawable(mRecyclerView.getContext(), R.drawable.divider_white_shape));
+ mRecyclerView.addItemDecoration(itemDecor);
+
+ mRecyclerView.setAdapter(new BuyPartnersAdapter(getContext(), getPartners()));
+ AnalyticsManager.logCustomEvent(BRConstants._20191105_DTBT);
+ }
+
+ private List getPartners() {
+ List partners = new ArrayList<>();
+ partners.add(new Partner(R.drawable.bitrefill_logo, R.string.BuyCenter_bitrefill_Title, R.string.BuyCenter_bitrefill_FinancialDetails, FragmentBuy.Partner.BITREFILL));
+ partners.add(new Partner(R.drawable.ic_moonpay_logo, R.string.BuyCenter_moonpay_Title, R.string.BuyCenter_moonpay_FinancialDetails, FragmentBuy.Partner.MOONPAY));
+ return partners;
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/DynamicDonationFragment.java b/app/src/main/java/com/breadwallet/presenter/fragments/DynamicDonationFragment.java
new file mode 100644
index 000000000..0d5476400
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/fragments/DynamicDonationFragment.java
@@ -0,0 +1,221 @@
+package com.breadwallet.presenter.fragments;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Pair;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.ImageButton;
+import android.widget.SeekBar;
+import android.widget.Spinner;
+import android.widget.TextView;
+
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.customviews.BRDialogView;
+import com.breadwallet.presenter.entities.PaymentItem;
+import com.breadwallet.tools.manager.AnalyticsManager;
+import com.breadwallet.tools.manager.BRSharedPrefs;
+import com.breadwallet.tools.manager.FeeManager;
+import com.breadwallet.tools.security.BRSender;
+import com.breadwallet.tools.util.BRConstants;
+import com.breadwallet.tools.util.BRCurrency;
+import com.breadwallet.tools.util.BRExchange;
+import com.breadwallet.wallet.BRWalletManager;
+
+import java.math.BigDecimal;
+
+/**
+ * Litewallet
+ * Created by Mohamed Barry on 3/2/20
+ * email: mosadialiou@gmail.com
+ * Copyright ยฉ 2020 Litecoin Foundation. All rights reserved.
+ */
+public class DynamicDonationFragment extends Fragment {
+
+ static final long BALANCE_STEP = 1_000_000;
+
+ private long currentBalance;
+
+ private TextView addressVal;
+ private TextView amountVal;
+ private TextView feeVal;
+ private TextView totalVal;
+
+ private TextView donationToTheLitewalletTeam;
+
+ private TextView amountSliderVal;
+
+ private SeekBar seekBar;
+ private String selectedIso;
+ private boolean isLTCSwap = true;
+ private String chosenAddress = BRConstants.DONATION_ADDRESS;
+ private long mDonationAmount;
+
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.fragment_dynamic_donation, container, false);
+ }
+
+ @Override
+ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+ selectedIso = BRSharedPrefs.getIso(getContext());
+ isLTCSwap = BRSharedPrefs.getPreferredLTC(getContext());
+
+ addressVal = view.findViewById(R.id.addressVal);
+ addressVal.setText(chosenAddress);
+
+ donationToTheLitewalletTeam = view.findViewById(R.id.donationAddressesPhrase);
+ donationToTheLitewalletTeam.setText(getString(R.string.Donate_toThe_LWTeam));
+
+ TextView processingTimeLbl = view.findViewById(R.id.processingTimeLbl);
+ processingTimeLbl.setText(getString(R.string.Confirmation_processingAndDonationTime, "2.5-5"));
+
+ amountVal = view.findViewById(R.id.amountVal);
+ feeVal = view.findViewById(R.id.feeVal);
+ totalVal = view.findViewById(R.id.totalVal);
+
+ Button cancelBut = view.findViewById(R.id.cancelBut);
+ cancelBut.setOnClickListener(v -> {
+ AnalyticsManager.logCustomEvent(BRConstants._20200225_DCD);
+ getActivity().onBackPressed();
+ });
+
+ Button donateBut = view.findViewById(R.id.donateBut);
+ donateBut.setOnClickListener(v -> {
+ BRDialogView dialog = new BRDialogView();
+ dialog.setTitle(getString(R.string.Donate_Dialog_title));
+
+ dialog.setMessage(getString(R.string.Donate_Dialog_message));
+ dialog.setNegButton(getString(R.string.Donate_Dialog_Negative_text));
+ dialog.setPosButton(getString(R.string.Donate_Dialog_Positive_text));
+ dialog.setPosListener(brDialogView -> {
+ dialog.dismiss();
+ sendDonation();
+ });
+ dialog.setNegListener(brDialogView -> dialog.dismiss());
+ dialog.show(((Activity) getActivity()).getFragmentManager(), dialog.getClass().getName());
+
+ });
+
+ amountSliderVal = view.findViewById(R.id.amountSliderVal);
+
+ seekBar = view.findViewById(R.id.seekBar);
+
+ ImageButton upAmountBut = view.findViewById(R.id.upAmountBut);
+ ImageButton downAmountBut = view.findViewById(R.id.downAmountBut);
+
+ upAmountBut.setOnClickListener(v -> {
+ seekBar.incrementProgressBy(diff());
+
+ long newAmount = newAmount(seekBar.getProgress());
+ updateDonationValues(newAmount);
+ });
+
+ downAmountBut.setOnClickListener(v -> {
+ seekBar.incrementProgressBy(-diff());
+
+ long newAmount = newAmount(seekBar.getProgress());
+ updateDonationValues(newAmount);
+ });
+
+ seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ updateDonationValues(newAmount(progress));
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ //NO-OP
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ //NO-OP
+ }
+ });
+
+ setFeeToRegular();
+
+ currentBalance = BRSharedPrefs.getCatchedBalance(getContext());
+
+ updateDonationValues(BRConstants.DONATION_AMOUNT);
+ }
+
+ private void sendDonation() {
+ String memo = getString(R.string.Donate_toThe_LWTeam) + chosenAddress;
+ PaymentItem request = new PaymentItem(new String[]{chosenAddress}, null, mDonationAmount, null, false, memo);
+ Bundle params = new Bundle();
+ params.putString("DONATION_ACCOUNT", chosenAddress);
+ params.putLong("DONATION_AMOUNT", mDonationAmount);
+ params.putString("ADDRESS_SCHEME", "v2");
+ AnalyticsManager.logCustomEventWithParams(BRConstants._20200223_DD, params);
+ BRSender.getInstance().sendTransaction(getContext(), request);
+ }
+
+ private void setFeeToRegular() {
+ FeeManager feeManager = FeeManager.getInstance();
+
+ //TODO: This should be inserted into the FeeManager after v0.4.0
+ AnalyticsManager.logCustomEvent(BRConstants._20200301_DUDFPK);
+
+ feeManager.resetFeeType();
+ BRWalletManager.getInstance().setFeePerKb(feeManager.getFees().regular);
+ }
+
+ private int diff() {
+ float step = (currentBalance - BRConstants.DONATION_AMOUNT) * 1f / BALANCE_STEP;
+ int diff = (int) (seekBar.getMax() * 1f / step);
+ return Math.max(diff, 1);
+ }
+
+ private long newAmount(int progress) {
+ long maxFee = BRWalletManager.getInstance().feeForTransactionAmount(currentBalance);
+ long adjustedAmount = (long) ((progress * 1f / seekBar.getMax()) * (currentBalance - BRConstants.DONATION_AMOUNT - maxFee));
+ return adjustedAmount + BRConstants.DONATION_AMOUNT;
+ }
+
+ private void updateDonationValues(long donationAmount) {
+ mDonationAmount = donationAmount;
+ final BigDecimal donation = new BigDecimal(donationAmount);
+
+ long feeAmount = BRWalletManager.getInstance().feeForTransactionAmount(donationAmount);
+ final BigDecimal fee = new BigDecimal(feeAmount);
+
+ final BigDecimal total = new BigDecimal(donationAmount + feeAmount);
+
+ amountVal.setText(formatResultAmount(formatLtcAmount(donation), formatIsoAmount(donation)));
+ feeVal.setText(formatResultAmount(formatLtcAmount(fee), formatIsoAmount(fee)));
+ totalVal.setText(formatResultAmount(formatLtcAmount(total), formatIsoAmount(total)));
+
+ amountSliderVal.setText(totalVal.getText());
+ }
+
+ private String formatLtcAmount(BigDecimal amount) {
+ BigDecimal ltcAmount = BRExchange.getBitcoinForSatoshis(getContext(), amount);
+ return BRCurrency.getFormattedCurrencyString(getContext(), "LTC", ltcAmount);
+ }
+
+ private String formatIsoAmount(BigDecimal amount) {
+ BigDecimal fiatAmount = BRExchange.getAmountFromSatoshis(getContext(), selectedIso, amount);
+ return BRCurrency.getFormattedCurrencyString(getContext(), selectedIso, fiatAmount);
+ }
+
+ private String formatResultAmount(String ltcAmount, String isoAmount) {
+ String format = "%s (%s)";
+ if (isLTCSwap) {
+ return String.format(format, ltcAmount, isoAmount);
+ } else {
+ return String.format(format, isoAmount, ltcAmount);
+ }
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/FingerprintDialogFragment.java b/app/src/main/java/com/breadwallet/presenter/fragments/FingerprintDialogFragment.java
deleted file mode 100644
index e6c721cd3..000000000
--- a/app/src/main/java/com/breadwallet/presenter/fragments/FingerprintDialogFragment.java
+++ /dev/null
@@ -1,208 +0,0 @@
-package com.breadwallet.presenter.fragments;/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.app.FragmentManager;
-import android.content.DialogInterface;
-import android.hardware.fingerprint.FingerprintManager;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-import android.widget.ImageView;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.breadwallet.R;
-import com.breadwallet.BreadWalletApp;
-import com.breadwallet.presenter.activities.IntroActivity;
-import com.breadwallet.presenter.activities.MainActivity;
-import com.breadwallet.presenter.activities.PhraseFlowActivity;
-import com.breadwallet.presenter.entities.PaymentRequestEntity;
-import com.breadwallet.presenter.entities.PaymentRequestWrapper;
-import com.breadwallet.tools.animation.BRAnimator;
-import com.breadwallet.tools.manager.SharedPreferencesManager;
-import com.breadwallet.tools.security.PostAuthenticationProcessor;
-import com.breadwallet.tools.util.BRConstants;
-import com.breadwallet.tools.adapter.MiddleViewAdapter;
-import com.breadwallet.tools.security.FingerprintUiHelper;
-import com.breadwallet.tools.security.KeyStoreManager;
-import com.breadwallet.tools.threads.PaymentProtocolPostPaymentTask;
-import com.breadwallet.wallet.BRWalletManager;
-
-/**
- * A dialog which uses fingerprint APIs to authenticate the user, and falls back to password
- * authentication if fingerprint is not available.
- */
-public class FingerprintDialogFragment extends DialogFragment
- implements FingerprintUiHelper.Callback {
- public static final String TAG = FingerprintDialogFragment.class.getName();
-
- private FingerprintManager.CryptoObject mCryptoObject;
- private FingerprintUiHelper mFingerprintUiHelper;
- private String message;
- private String title;
-
- private PaymentRequestEntity request;
- private PaymentRequestWrapper paymentRequest;
-
- private int mode = -1;
-
- FingerprintUiHelper.FingerprintUiHelperBuilder mFingerprintUiHelperBuilder;
-
- public FingerprintDialogFragment() {
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- // Do not create a new Fragment when the Activity is re-created such as orientation changes.
- setRetainInstance(true);
- setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Material_Light_Dialog);
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
-
- View v = inflater.inflate(R.layout.fingerprint_dialog_container, container, false);
- getDialog().setTitle(R.string.fingerprint_auth);
- if (title != null) getDialog().setTitle(title);
- FingerprintManager mFingerprintManager = (FingerprintManager) getActivity().getSystemService(Activity.FINGERPRINT_SERVICE);
- mFingerprintUiHelperBuilder = new FingerprintUiHelper.FingerprintUiHelperBuilder(mFingerprintManager);
- mFingerprintUiHelper = mFingerprintUiHelperBuilder.build(
- (ImageView) v.findViewById(R.id.fingerprint_icon),
- (TextView) v.findViewById(R.id.fingerprint_status), this);
- View mFingerprintContent = v.findViewById(R.id.fingerprint_container);
- TextView description = (TextView) v.findViewById(R.id.fingerprint_description);
- if (message != null) {
- description.setText(message);
- }
-
- Button mCancelButton = (Button) v.findViewById(R.id.cancel_button);
- Button mSecondDialogButton = (Button) v.findViewById(R.id.second_dialog_button);
- mCancelButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- if (!BRAnimator.scanResultFragmentOn && mode == BRConstants.AUTH_FOR_PAY && request.isAmountRequested) {
- FragmentScanResult.address = request.addresses[0];
- BRWalletManager.getInstance(getActivity()).offerToChangeTheAmount(getActivity(), "");
- }
- dismiss();
- }
- });
- mCancelButton.setText(R.string.cancel);
- mSecondDialogButton.setText(R.string.use_passcode);
- mFingerprintContent.setVisibility(View.VISIBLE);
- mSecondDialogButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- goToBackup();
- }
- });
-
- return v;
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mFingerprintUiHelper.startListening(mCryptoObject);
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mFingerprintUiHelper.stopListening();
- }
-
- /**
- * Switches to backup (password) screen. This either can happen when fingerprint is not
- * available or the user chooses to use the password authentication method by pressing the
- * button. This can also happen when the user had too many fingerprint attempts.
- */
- private void goToBackup() {
-
- // Fingerprint is not used anymore. Stop listening for it.
- getDialog().cancel();
- PasswordDialogFragment passwordDialogFragment = new PasswordDialogFragment();
- passwordDialogFragment.setMode(mode);
- passwordDialogFragment.setPaymentRequestEntity(request, paymentRequest);
- passwordDialogFragment.setVerifyOnlyTrue();
- passwordDialogFragment.setMessage(message);
- FragmentManager fm = getActivity().getFragmentManager();
- passwordDialogFragment.show(fm, PasswordDialogFragment.class.getName());
- if (mFingerprintUiHelper != null)
- mFingerprintUiHelper.stopListening();
- }
-
- @Override
- public void onAuthenticated() {
- Dialog d = getDialog();
- if (d == null) return;
- d.cancel();
-
- ((BreadWalletApp) getActivity().getApplicationContext()).setUnlocked(true);
- FragmentSettingsAll.refreshUI();
- MiddleViewAdapter.resetMiddleView(getActivity(), null);
- ((BreadWalletApp) getActivity().getApplicationContext()).allowKeyStoreAccessForSeconds();
- getDialog().dismiss();
- if (mode == BRConstants.AUTH_FOR_PHRASE) {
- PhraseFlowActivity app = ((PhraseFlowActivity) getActivity());
- if (SharedPreferencesManager.getPhraseWroteDown(app)) {
- app.animateSlide(app.fragmentPhraseFlow1, app.fragmentRecoveryPhrase, IntroActivity.RIGHT);
- app.fragmentRecoveryPhrase.setPhrase(FragmentPhraseFlow1.phrase);
- } else {
- app.animateSlide(app.fragmentPhraseFlow1, app.fragmentPhraseFlow2, IntroActivity.RIGHT);
- app.fragmentPhraseFlow2.setPhrase(FragmentPhraseFlow1.phrase);
- }
- } else if (mode == BRConstants.AUTH_FOR_PAY && request != null) {
- PostAuthenticationProcessor.getInstance().onPublishTxAuth((MainActivity) getActivity());
- } else if (mode == BRConstants.AUTH_FOR_PAYMENT_PROTOCOL && paymentRequest != null) {
- if (paymentRequest.paymentURL == null || paymentRequest.paymentURL.isEmpty()) return;
- new PaymentProtocolPostPaymentTask(paymentRequest).execute();
- }
- dismiss();
- }
-
- @Override
- public void onError() {
- goToBackup();
- }
-
- public void setPaymentRequestEntity(PaymentRequestEntity requestEntity, PaymentRequestWrapper paymentRequest) {
- this.paymentRequest = paymentRequest;
- request = requestEntity;
- }
-
- public void setMode(int mode) {
- this.mode = mode;
- }
-
- public void setMessage(String message) {
- this.message = message;
- }
-
- public void setTitle(String title) {
- this.title = title;
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentAbout.java b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentAbout.java
deleted file mode 100644
index 336aee32e..000000000
--- a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentAbout.java
+++ /dev/null
@@ -1,104 +0,0 @@
-package com.breadwallet.presenter.fragments;
-
-import android.content.Intent;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.os.Build;
-import android.os.Bundle;
-import android.app.Fragment;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import com.breadwallet.R;
-import com.breadwallet.tools.animation.BRAnimator;
-import com.breadwallet.tools.util.BRConstants;
-import com.breadwallet.tools.adapter.MiddleViewAdapter;
-import java.util.Locale;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 7/14/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-public class FragmentAbout extends Fragment {
- private static final String TAG = FragmentAbout.class.getName();
-
- @Override
- public View onCreateView(LayoutInflater inflater,
- ViewGroup container, Bundle savedInstanceState) {
-
-
- View rootView = inflater.inflate(
- R.layout.fragment_about, container, false);
- PackageInfo pInfo = null;
- int versionCode = 0;
- try {
- pInfo = getActivity().getPackageManager().getPackageInfo(getActivity().getPackageName(), 0);
- versionCode = pInfo.versionCode;
- } catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
- }
- TextView versionText = (TextView) rootView.findViewById(R.id.about1);
- if (versionText != null)
- versionText.setText(String.format(getString(R.string.breadwallet_v), versionCode));
- TextView support = (TextView) rootView.findViewById(R.id.about4);
- if (support != null)
- support.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (BRAnimator.checkTheMultipressingAvailability()) {
- String to = BRConstants.SUPPORT_EMAIL;
- PackageInfo pInfo = null;
- String versionName = "";
- try {
- pInfo = getActivity().getPackageManager().getPackageInfo(getActivity().getPackageName(), 0);
- versionName = pInfo.versionName;
- } catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
- }
- String message = String.format(Locale.getDefault(), "%s / Android %s / breadwallet %s\n\n",
- Build.MODEL, Build.VERSION.RELEASE, versionName);
- Intent email = new Intent(Intent.ACTION_SEND);
- email.putExtra(Intent.EXTRA_EMAIL, new String[]{to});
- email.putExtra(Intent.EXTRA_TEXT, message);
- email.putExtra(Intent.EXTRA_SUBJECT, "support request");
-
- // need this to prompts email client only
- email.setType("message/rfc822");
- startActivity(Intent.createChooser(email, getActivity().getString(R.string.choose_an_email_client)));
- }
- }
- });
-
- return rootView;
- }
-
- @Override
- public void onResume() {
- super.onResume();
- MiddleViewAdapter.resetMiddleView(getActivity(), null);
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentBalanceSeedReminder.kt b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentBalanceSeedReminder.kt
new file mode 100644
index 000000000..fc523031e
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentBalanceSeedReminder.kt
@@ -0,0 +1,87 @@
+package com.breadwallet.presenter.fragments
+
+import android.os.Bundle
+import android.security.keystore.UserNotAuthenticatedException
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.view.ViewTreeObserver.OnGlobalLayoutListener
+import android.widget.*
+import androidx.fragment.app.Fragment
+import com.breadwallet.R
+import com.breadwallet.tools.animation.BRAnimator
+import com.breadwallet.tools.security.BRKeyStore
+import java.util.*
+
+class FragmentBalanceSeedReminder : Fragment() {
+ private lateinit var backgroundLayout: ScrollView
+ private lateinit var signalLayout: LinearLayout
+ private lateinit var showSeedButton: Button
+ private lateinit var seedPhraseTextView: TextView
+ private lateinit var closeButton: View
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?,
+ ): View? {
+ val rootView = inflater.inflate(R.layout.fragment_balance_seed_reminder, container, false)
+ backgroundLayout = rootView.findViewById(R.id.background_layout)
+ signalLayout = rootView.findViewById(R.id.signal_layout)
+ signalLayout = rootView.findViewById(R.id.signal_layout) as LinearLayout
+ seedPhraseTextView = rootView.findViewById(R.id.seed_phrase)
+ closeButton = rootView.findViewById(R.id.close_button)
+ showSeedButton = rootView.findViewById(R.id.show_seed_button)
+ return rootView
+ }
+
+ private fun setListeners() {
+ showSeedButton.setOnClickListener {
+ seedPhraseTextView.visibility = View.VISIBLE
+ }
+
+ closeButton.setOnClickListener {
+ animateClose()
+ }
+ }
+
+ override fun onViewCreated(
+ view: View,
+ savedInstanceState: Bundle?,
+ ) {
+ super.onViewCreated(view, savedInstanceState)
+ val observer = signalLayout.viewTreeObserver
+ observer.addOnGlobalLayoutListener(
+ object : OnGlobalLayoutListener {
+ override fun onGlobalLayout() {
+ if (observer.isAlive) {
+ observer.removeOnGlobalLayoutListener(this)
+ }
+ BRAnimator.animateBackgroundDim(backgroundLayout, false)
+ BRAnimator.animateSignalSlide(signalLayout, false) {
+ }
+ }
+ },
+ )
+ setListeners()
+ fetchSeedPhrase()
+ }
+
+ fun fetchSeedPhrase() {
+ try {
+ seedPhraseTextView.text = String(BRKeyStore.getPhrase(context, 0))
+ } catch (_: UserNotAuthenticatedException) {
+ }
+ }
+
+ private fun animateClose() {
+ BRAnimator.animateBackgroundDim(backgroundLayout, true)
+ BRAnimator.animateSignalSlide(signalLayout, true) { close() }
+ }
+
+ private fun close() {
+ if (activity != null && activity?.isFinishing != true) {
+ activity?.onBackPressedDispatcher?.onBackPressed()
+ }
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentBuy.java b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentBuy.java
new file mode 100644
index 000000000..cd0fe8b44
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentBuy.java
@@ -0,0 +1,269 @@
+package com.breadwallet.presenter.fragments;
+
+import static com.breadwallet.tools.util.BRConstants.LW_API_HOST;
+
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.content.ClipData;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.webkit.ValueCallback;
+import android.webkit.WebChromeClient;
+import android.webkit.WebResourceRequest;
+import android.webkit.WebSettings;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+
+import android.widget.LinearLayout;
+import android.widget.ProgressBar;
+
+import androidx.activity.OnBackPressedCallback;
+import androidx.annotation.Nullable;
+import androidx.appcompat.widget.Toolbar;
+import androidx.fragment.app.Fragment;
+
+import com.breadwallet.BuildConfig;
+import com.breadwallet.R;
+import com.breadwallet.tools.animation.BRAnimator;
+import com.breadwallet.tools.manager.BRSharedPrefs;
+import com.breadwallet.tools.util.BRConstants;
+import com.breadwallet.tools.util.Utils;
+
+import java.util.Date;
+
+import timber.log.Timber;
+
+public class FragmentBuy extends Fragment {
+ private static final int FILE_CHOOSER_REQUEST_CODE = 15423;
+ public LinearLayout backgroundLayout;
+ private ProgressBar progress;
+ private WebView webView;
+ private String onCloseUrl;
+ private static final String CURRENCY_KEY = "currency_code_key";
+ private static final String PARTNER_KEY = "partner_key";
+ private ValueCallback uploadMessage;
+ private ValueCallback uploadMessageAboveL;
+
+ public static Fragment newInstance(String currency, Partner partner) {
+ Bundle bundle = new Bundle();
+ bundle.putString(CURRENCY_KEY, currency);
+ bundle.putSerializable(PARTNER_KEY, partner);
+ Fragment fragment = new FragmentBuy();
+ fragment.setArguments(bundle);
+ return fragment;
+ }
+
+ @Override
+ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), new OnBackPressedCallback(true) {
+ @Override
+ public void handleOnBackPressed() {
+ if (webView.canGoBack()) {
+ webView.goBack();
+ } else {
+ closePayment();
+ }
+ }
+ });
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View rootView = inflater.inflate(R.layout.fragment_buy, container, false);
+ Toolbar toolbar = rootView.findViewById(R.id.toolbar);
+ toolbar.setNavigationOnClickListener(v -> closePayment());
+ backgroundLayout = rootView.findViewById(R.id.background_layout);
+ progress = rootView.findViewById(R.id.progress);
+ webView = rootView.findViewById(R.id.web_view);
+ webView.setWebChromeClient(mWebChromeClient);
+ webView.setWebViewClient(mWebViewClient);
+
+ WebSettings webSettings = webView.getSettings();
+ if (BuildConfig.DEBUG) {
+ WebView.setWebContentsDebuggingEnabled(true);
+ }
+ webSettings.setDomStorageEnabled(true);
+ webSettings.setJavaScriptEnabled(true);
+//
+// // App (in Java)
+// WebMessageListener bitrefillListener = new WebMessageListener() {
+// @Override
+// public void onPostMessage(WebView view, WebMessageCompat message, Uri sourceOrigin,
+// boolean isMainFrame, JavaScriptReplyProxy replyProxy) {
+// // do something about view, message, sourceOrigin and isMainFrame.
+// replyProxy.postMessage("Got it!");
+// }
+// };
+// if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_MESSAGE_LISTENER)) {
+// WebViewCompat.addWebMessageListener(webView, "bitrefillPostObj", rules, bitrefillListener);
+// }
+
+// // App (in Java)
+// WebMessageListener bitrefillListener = new WebMessageListener() {
+// @Override
+// public void onPostMessage(WebView view, WebMessageCompat message, Uri sourceOrigin,
+// boolean isMainFrame, JavaScriptReplyProxy replyProxy) {
+// // do something about view, message, sourceOrigin and isMainFrame.
+// replyProxy.postMessage("Got it!");
+// }
+// };
+//
+// if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_MESSAGE_LISTENER)) {
+// WebViewCompat.addWebMessageListener(webView, "bitrefillPostObj", rules, bitrefillListener);
+// }
+
+ String currency = getArguments().getString(CURRENCY_KEY);
+ Partner partner = (Partner) getArguments().getSerializable(PARTNER_KEY);
+
+ String bitrefillRef = "bAshL935";
+ String utmSource = "LitewalletAndroid";
+ String bitrefillUrl = String.format( BRConstants.BITREFILL_AFFILIATE_LINK + "/embed/?paymentMethod=litecoin&ref=%s&utm_source=%s", bitrefillRef,utmSource);
+
+ String buyUrl = partner == Partner.BITREFILL ? bitrefillUrl : url(getContext(), partner, currency);
+ Timber.d("timber: URL %s", buyUrl);
+ webView.loadUrl(buyUrl);
+
+ return rootView;
+ }
+
+ public static String url(Context context, Partner partner, String currency) {
+ String walletAddress = BRSharedPrefs.getReceiveAddress(context);
+ Long timestamp = new Date().getTime();
+ String uuid = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
+ String prefix = partner == Partner.MOONPAY ? "/moonpay/buy" : "";
+ return String.format(LW_API_HOST + prefix + "?address=%s&code=%s&idate=%s&uid=%s", walletAddress, currency, timestamp, uuid);
+ }
+
+ private void closePayment() {
+ requireActivity().getSupportFragmentManager().popBackStack();
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ BRAnimator.animateBackgroundDim(backgroundLayout, true);
+ }
+
+ private WebChromeClient mWebChromeClient = new WebChromeClient() {
+ // For Android API < 11 (3.0 OS)
+ public void openFileChooser(ValueCallback valueCallback) {
+ uploadMessage = valueCallback;
+ openImageChooserActivity();
+ }
+
+ // For Android API >= 11 (3.0 OS)
+ public void openFileChooser(ValueCallback valueCallback, String acceptType, String capture) {
+ uploadMessage = valueCallback;
+ openImageChooserActivity();
+ }
+
+ // For Android API >= 21 (5.0 OS)
+ @Override
+ public boolean onShowFileChooser(WebView webView, ValueCallback filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) {
+ uploadMessageAboveL = filePathCallback;
+ openImageChooserActivity();
+ return true;
+ }
+
+ @Override
+ public void onProgressChanged(WebView view, int newProgress) {
+ super.onProgressChanged(view, newProgress);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ progress.setProgress(newProgress, true);
+ } else progress.setProgress(newProgress);
+ }
+ };
+
+ private WebViewClient mWebViewClient = new WebViewClient() {
+ @Override
+ public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
+ String url = request.getUrl().toString();
+ Timber.d("timber: shouldOverrideUrlLoading: URL=%s\nMethod=%s", url, request.getMethod());
+ if (url.equalsIgnoreCase(onCloseUrl)) {
+ closePayment();
+ onCloseUrl = null;
+ } else if (url.contains("close")) {
+ closePayment();
+ } else {
+ view.loadUrl(url);
+ }
+
+ return true;
+ }
+
+ @Override
+ public void onPageStarted(WebView view, String url, Bitmap favicon) {
+ Timber.d("timber: onPageStarted: %s", url);
+ super.onPageStarted(view, url, favicon);
+ progress.setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ public void onPageFinished(WebView view, String url) {
+ super.onPageFinished(view, url);
+ Timber.d("timber: onPageFinished %s", url);
+ progress.setVisibility(View.GONE);
+ }
+ };
+
+ private void openImageChooserActivity() {
+ Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
+ intent.addCategory(Intent.CATEGORY_OPENABLE);
+ intent.setType("image/*");
+ startActivityForResult(Intent.createChooser(intent, "Image Chooser"), FILE_CHOOSER_REQUEST_CODE);
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ if (requestCode == FILE_CHOOSER_REQUEST_CODE) {
+ if (uploadMessageAboveL != null) {
+ Uri[] results = getResultAboveL(resultCode, data);
+ uploadMessageAboveL.onReceiveValue(results);
+ } else if (uploadMessage != null) {
+ Uri result = data != null && resultCode == Activity.RESULT_OK ? data.getData() : null;
+ uploadMessage.onReceiveValue(result);
+ }
+ uploadMessageAboveL = null;
+ uploadMessage = null;
+ }
+ }
+
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ private Uri[] getResultAboveL(int resultCode, Intent intent) {
+ Uri[] results = null;
+ if (intent != null && resultCode == Activity.RESULT_OK) {
+ String dataString = intent.getDataString();
+ ClipData clipData = intent.getClipData();
+ if (clipData != null) {
+ results = new Uri[clipData.getItemCount()];
+ for (int i = 0; i < clipData.getItemCount(); i++) {
+ ClipData.Item item = clipData.getItemAt(i);
+ results[i] = item.getUri();
+ }
+ } else if (dataString != null) {
+ results = new Uri[]{Uri.parse(dataString)};
+ }
+ }
+ return results;
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ Utils.hideKeyboard(getActivity());
+ }
+
+ public enum Partner {
+ MOONPAY, BITREFILL
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentCurrency.java b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentCurrency.java
deleted file mode 100644
index d4758cbd3..000000000
--- a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentCurrency.java
+++ /dev/null
@@ -1,218 +0,0 @@
-
-package com.breadwallet.presenter.fragments;
-
-import android.app.Activity;
-import android.app.Fragment;
-import android.os.Bundle;
-import android.os.Handler;
-import android.util.Log;
-import android.view.GestureDetector;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.Button;
-import android.widget.ListView;
-import android.widget.ProgressBar;
-import android.widget.TextView;
-
-import com.breadwallet.BreadWalletApp;
-import com.breadwallet.R;
-import com.breadwallet.presenter.activities.MainActivity;
-import com.breadwallet.presenter.entities.CurrencyEntity;
-import com.breadwallet.tools.util.BRConstants;
-import com.breadwallet.tools.util.BRStringFormatter;
-import com.breadwallet.tools.manager.CurrencyManager;
-import com.breadwallet.tools.manager.SharedPreferencesManager;
-import com.breadwallet.tools.adapter.CurrencyListAdapter;
-import com.breadwallet.tools.adapter.MiddleViewAdapter;
-import com.breadwallet.tools.animation.SpringAnimator;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 7/14/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-public class FragmentCurrency extends Fragment {
- private static final String TAG = FragmentCurrency.class.getName();
-
- private ListView currencyList;
- private Button currencyRefresh;
- private TextView noInternetConnection;
- private CurrencyListAdapter adapter;
- private TextView currencyItemText;
- private ProgressBar currencyProgressBar;
- private String ISO;
- private float rate;
- public static int lastItemsPosition = 0;
-
- @SuppressWarnings("deprecation")
- final GestureDetector gdt = new GestureDetector(new GestureListener());
-
- @Override
- public View onCreateView(LayoutInflater inflater,
- final ViewGroup container, Bundle savedInstanceState) {
- // The last two arguments ensure LayoutParams are inflated
- // properly.
- final View rootView = inflater.inflate(
- R.layout.fragment_currency, container, false);
- currencyList = (ListView) rootView.findViewById(R.id.currency_list_view);
- currencyProgressBar = (ProgressBar) rootView.findViewById(R.id.currency_progress_barr);
- currencyRefresh = (Button) rootView.findViewById(R.id.currencyRefresh);
- noInternetConnection = (TextView) rootView.findViewById(R.id.noInternetConnectionText);
- currencyList.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
- currencyRefresh.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- tryAndSetAdapter();
- SpringAnimator.showAnimation(v);
- }
- });
- currencyList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView> parent, View view,
- int position, long id) {
- Activity app = getActivity();
- if (app == null) return;
- currencyItemText = (TextView) view.findViewById(R.id.currency_item_text);
- final String selectedCurrency = currencyItemText.getText().toString();
- ISO = selectedCurrency.substring(0, 3);
- lastItemsPosition = position;
- CurrencyEntity item = adapter.getItem(position);
- rate = item == null ? 0 : item.rate;
- SharedPreferencesManager.putIso(app, ISO);
- SharedPreferencesManager.putCurrencyListPosition(app, lastItemsPosition);
- SharedPreferencesManager.putRate(app, rate);
- String finalExchangeRate = BRStringFormatter.getMiddleTextExchangeString(rate, ISO, app);
-
- MiddleViewAdapter.resetMiddleView(app, finalExchangeRate);
- adapter.notifyDataSetChanged();
-
- }
-
- });
- return rootView;
- }
-
- @Override
- public void onResume() {
- super.onResume();
- setMiddleExchangeRate();
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- tryAndSetAdapter();
- }
- }, 500);
- Activity app = getActivity();
- if (app != null)
- allowChangeDisplayUnits((MainActivity) app, true);
- }
-
- private void setMiddleExchangeRate() {
- Activity app = getActivity();
- if (app == null) return;
- final String iso = SharedPreferencesManager.getIso(getActivity());
- float tmpRate;
- CurrencyEntity item = (adapter != null && !adapter.isEmpty()) ? adapter.getItem(SharedPreferencesManager.getCurrencyListPosition(app)) : null;
- tmpRate = item == null ? SharedPreferencesManager.getRate(app) : item.rate;
- String readyText = BRStringFormatter.getMiddleTextExchangeString(tmpRate, iso, app);
- MiddleViewAdapter.resetMiddleView(app, readyText);
- }
-
- @Override
- public void onPause() {
- super.onPause();
- Activity app = getActivity();
- if (app != null)
- allowChangeDisplayUnits((MainActivity) app, false);
- }
-
- private void allowChangeDisplayUnits(MainActivity app, boolean allow) {
- if (allow)
- app.viewFlipper.setOnTouchListener(new View.OnTouchListener() {
- @Override
- public boolean onTouch(final View view, final MotionEvent event) {
- gdt.onTouchEvent(event);
- return true;
- }
- });
- else
- app.viewFlipper.setOnTouchListener(new View.OnTouchListener() {
- @Override
- public boolean onTouch(final View view, final MotionEvent event) {
- return false;
- }
- });
- }
-
- //0 - left, 1 - right
- private void changeUnitWithDirection() {
- MainActivity app = MainActivity.app;
- if (app == null) return;
- int unit = SharedPreferencesManager.getCurrencyUnit(app);
- switch (unit) {
- case BRConstants.CURRENT_UNIT_BITS:
- SharedPreferencesManager.putCurrencyUnit(app, BRConstants.CURRENT_UNIT_MBITS);
- break;
- case BRConstants.CURRENT_UNIT_MBITS:
- SharedPreferencesManager.putCurrencyUnit(app, BRConstants.CURRENT_UNIT_BITCOINS);
- break;
- case BRConstants.CURRENT_UNIT_BITCOINS:
- SharedPreferencesManager.putCurrencyUnit(app, BRConstants.CURRENT_UNIT_BITS);
- break;
- }
-
- }
-
- private static final int SWIPE_MIN_DISTANCE = 120;
- private static final int SWIPE_THRESHOLD_VELOCITY = 200;
-
- private class GestureListener extends GestureDetector.SimpleOnGestureListener {
- @Override
- public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
- if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
- changeUnitWithDirection();
- setMiddleExchangeRate();
- return false; // Right to left
- }
- return false;
- }
- }
-
- private void tryAndSetAdapter() {
- adapter = CurrencyManager.getInstance(getActivity()).getCurrencyAdapterIfReady();
- if (adapter.getCount() > 0) {
- currencyList.setAdapter(adapter);
- currencyRefresh.clearAnimation();
- currencyRefresh.setVisibility(View.GONE);
- noInternetConnection.setVisibility(View.GONE);
- currencyProgressBar.setVisibility(View.GONE);
- } else {
- currencyRefresh.setVisibility(View.VISIBLE);
- noInternetConnection.setVisibility(View.VISIBLE);
- currencyProgressBar.setVisibility(View.GONE);
- }
- }
-}
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentDecoder.java b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentDecoder.java
deleted file mode 100644
index 333258207..000000000
--- a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentDecoder.java
+++ /dev/null
@@ -1,115 +0,0 @@
-package com.breadwallet.presenter.fragments;
-
-import android.app.Fragment;
-import android.graphics.Color;
-import android.os.Bundle;
-import android.os.Handler;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.RelativeLayout;
-
-import com.breadwallet.presenter.activities.MainActivity;
-import com.breadwallet.tools.animation.BRAnimator;
-import com.breadwallet.tools.qrcode.QRScannerView;
-import com.breadwallet.tools.security.RequestHandler;
-import com.google.zxing.Result;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 4/14/16.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-public class FragmentDecoder extends Fragment implements QRScannerView.ResultHandler {
- private QRScannerView mScannerView;
- public static final String TAG = FragmentDecoder.class.getName();
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- mScannerView = new QRScannerView(getActivity());
- final RelativeLayout blackPane = new RelativeLayout(getContext());
- blackPane.setLayoutParams(new RelativeLayout.LayoutParams(MainActivity.screenParametersPoint.x, MainActivity.screenParametersPoint.y));
- blackPane.setBackgroundColor(Color.BLACK);
-
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- mScannerView.removeView(blackPane);
- }
- }, 1000);
- mScannerView.addView(blackPane);
- return mScannerView;
- }
-
- @Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- if (mScannerView != null)
- mScannerView.initViews();
- }
- }, 1000);
-
- }
-
- @Override
- public void onResume() {
- super.onResume();
- final FragmentDecoder instance = this;
- mScannerView.setResultHandler(instance);
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- mScannerView.startCamera();
- }
- }, 400);
-
- }
-
- @Override
- public void handleResult(Result rawResult) {
- final String text = rawResult.getText();
- final MainActivity app = MainActivity.app;
- if (app == null) return;
- app.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- if (!text.isEmpty()) {
- BRAnimator.hideDecoderFragment();
- RequestHandler.processRequest(app, text);
-
- }
- }
- });
-
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mScannerView.stopCamera();
- }
-}
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentEarlyAccess.java b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentEarlyAccess.java
deleted file mode 100644
index 11058dc87..000000000
--- a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentEarlyAccess.java
+++ /dev/null
@@ -1,155 +0,0 @@
-
-package com.breadwallet.presenter.fragments;
-
-import android.annotation.SuppressLint;
-import android.app.Fragment;
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.net.http.SslError;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.webkit.ConsoleMessage;
-import android.webkit.HttpAuthHandler;
-import android.webkit.JavascriptInterface;
-import android.webkit.SslErrorHandler;
-import android.webkit.WebChromeClient;
-import android.webkit.WebResourceError;
-import android.webkit.WebResourceRequest;
-import android.webkit.WebResourceResponse;
-import android.webkit.WebSettings;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
-import android.widget.Toast;
-
-import com.breadwallet.R;
-import com.platform.HTTPServer;
-
-import static com.breadwallet.tools.threads.PaymentProtocolPostPaymentTask.message;
-
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 7/14/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-public class FragmentEarlyAccess extends Fragment {
- public static final String TAG = FragmentEarlyAccess.class.getName();
-
- HTTPServer server;
- WebView webView;
-
- @SuppressLint("SetJavaScriptEnabled")
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-
- View rootView = inflater.inflate(
- R.layout.fragment_early_access, container, false);
- webView = (WebView) rootView.findViewById(R.id.early_access_web_view);
- webView.setWebViewClient(new BRWebViewClient());
- webView.setWebChromeClient(new BRWebChromeClient());
- WebSettings webSettings = webView.getSettings();
- if (0 != (getActivity().getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE))
- WebView.setWebContentsDebuggingEnabled(true);
- webSettings.setJavaScriptEnabled(true);
- server = new HTTPServer();
-// webView.getSettings().setAllowFileAccessFromFileURLs(true);
-// webView.getSettings().setAllowUniversalAccessFromFileURLs(true);
-// // Keeping these off is less critical but still a good idea, especially
-// // if your app is not using file:// or content:// URLs.
-// webView.getSettings().setAllowFileAccess(true);
-// webView.getSettings().setAllowContentAccess(true);
-
- return rootView;
- }
-
- @Override
- public void onResume() {
- super.onResume();
- server.startServer();
- webView.loadUrl(HTTPServer.URL_EA);
- }
-
- @Override
- public void onPause() {
- super.onPause();
- server.stopServer();
- }
-
- private class BRWebChromeClient extends WebChromeClient {
- @Override
- public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
- Log.e(TAG, "onConsoleMessage: consoleMessage: " + consoleMessage.message());
- return super.onConsoleMessage(consoleMessage);
- }
- }
-
-
- private class BRWebViewClient extends WebViewClient {
-
- @Override
- public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
- return super.shouldInterceptRequest(view, request);
- }
-
- @Override
- public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
- super.onReceivedError(view, request, error);
- Log.e(TAG, "onReceivedError: error:" + error.toString());
- }
-
- @Override
- public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) {
- super.onReceivedHttpAuthRequest(view, handler, host, realm);
- Log.e(TAG, "onReceivedHttpAuthRequest: ");
- }
-
- @Override
- public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
- super.onReceivedError(view, errorCode, description, failingUrl);
- Log.e(TAG, "onReceivedError: failingUrl: " + failingUrl);
- }
-
- @Override
- public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
- super.onReceivedSslError(view, handler, error);
- Log.e(TAG, "onReceivedSslError: error: " + error);
- }
-
- @Override
- public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
- super.onReceivedHttpError(view, request, errorResponse);
- Log.e(TAG, "onReceivedHttpError: request: " + request.getUrl());
- Log.e(TAG, "onReceivedHttpError: getStatusCode: " + errorResponse.getStatusCode());
- Log.e(TAG, "onReceivedHttpError: getReasonPhrase: " + errorResponse.getReasonPhrase());
- }
-
- @Override
- public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
- return super.shouldInterceptRequest(view, url);
- }
-
- }
-}
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentFingerprint.java b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentFingerprint.java
new file mode 100644
index 000000000..d1d215707
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentFingerprint.java
@@ -0,0 +1,253 @@
+package com.breadwallet.presenter.fragments;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ArgbEvaluator;
+import android.animation.ValueAnimator;
+import android.app.Activity;
+import android.app.Fragment;
+import android.content.Context;
+import android.hardware.fingerprint.FingerprintManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.view.animation.AnticipateInterpolator;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import androidx.annotation.Nullable;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.BreadActivity;
+import com.breadwallet.presenter.interfaces.BRAuthCompletion;
+import com.breadwallet.tools.animation.BRAnimator;
+import com.breadwallet.tools.animation.DecelerateOvershootInterpolator;
+import com.breadwallet.tools.manager.AnalyticsManager;
+import com.breadwallet.tools.security.AuthManager;
+import com.breadwallet.tools.security.FingerprintUiHelper;
+import com.breadwallet.tools.util.BRConstants;
+import com.breadwallet.tools.util.Utils;
+
+import timber.log.Timber;
+
+/**
+ * A dialog which uses fingerprint APIs to authenticate the user, and falls back to password
+ * authentication if fingerprint is not available.
+ */
+public class FragmentFingerprint extends Fragment
+ implements FingerprintUiHelper.Callback {
+ public static final String TAG = FragmentFingerprint.class.getName();
+
+ private FingerprintManager.CryptoObject mCryptoObject;
+ private FingerprintUiHelper mFingerprintUiHelper;
+ private BRAuthCompletion completion;
+ private TextView title;
+ private TextView message;
+ private LinearLayout fingerPrintLayout;
+ private RelativeLayout fingerprintBackground;
+ private boolean authSucceeded;
+ public static final int ANIMATION_DURATION = 300;
+ private String customTitle;
+ private String customMessage;
+
+ FingerprintUiHelper.FingerprintUiHelperBuilder mFingerprintUiHelperBuilder;
+
+ public FragmentFingerprint() {
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setRetainInstance(true);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ View authModalView = inflater.inflate(R.layout.fingerprint_dialog_container, container, false);
+ message = (TextView) authModalView.findViewById(R.id.fingerprint_description);
+ title = (TextView) authModalView.findViewById(R.id.fingerprint_title);
+ fingerPrintLayout = (LinearLayout) authModalView.findViewById(R.id.fingerprint_layout);
+ fingerprintBackground = (RelativeLayout) authModalView.findViewById(R.id.fingerprint_background);
+ Bundle bundle = getArguments();
+ String titleString = bundle.getString("title");
+ String messageString = bundle.getString("message");
+ if (!Utils.isNullOrEmpty(titleString)) {
+ customTitle = titleString;
+ title.setText(customTitle);
+ }
+ if (!Utils.isNullOrEmpty(messageString)) {
+ customMessage = messageString;
+ message.setText(customMessage);
+ }
+ FingerprintManager mFingerprintManager = (FingerprintManager) getActivity().getSystemService(Activity.FINGERPRINT_SERVICE);
+ mFingerprintUiHelperBuilder = new FingerprintUiHelper.FingerprintUiHelperBuilder(mFingerprintManager);
+ mFingerprintUiHelper = mFingerprintUiHelperBuilder.build((ImageView) authModalView.findViewById(R.id.fingerprint_icon),
+ (TextView) authModalView.findViewById(R.id.fingerprint_status), this, getContext());
+ View mFingerprintContent = authModalView.findViewById(R.id.fingerprint_container);
+
+ Button mCancelButton = (Button) authModalView.findViewById(R.id.cancel_button);
+ Button mSecondDialogButton = (Button) authModalView.findViewById(R.id.second_dialog_button);
+ mCancelButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ if (!BRAnimator.isClickAllowed()) return;
+ closeMe();
+ }
+ });
+ mCancelButton.setText(R.string.Button_cancel);
+ mSecondDialogButton.setText(getString(R.string.Prompts_TouchId_usePin_android));
+ mFingerprintContent.setVisibility(View.VISIBLE);
+ mSecondDialogButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ if (!BRAnimator.isClickAllowed()) return;
+ closeMe();
+ goToBackup();
+ }
+ });
+
+ return authModalView;
+ }
+
+ @Override
+ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+
+ final ViewTreeObserver observer = fingerPrintLayout.getViewTreeObserver();
+ observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+ @Override
+ public void onGlobalLayout() {
+ if(observer.isAlive()) {
+ observer.removeOnGlobalLayoutListener(this);
+ }
+ animateBackgroundDim(false);
+ animateSignalSlide(false);
+ }
+ });
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+// animateBackgroundDim(true);
+// animateSignalSlide(true);
+ if (!authSucceeded)
+ completion.onCancel();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ mFingerprintUiHelper.startListening(mCryptoObject);
+ authSucceeded = false;
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ mFingerprintUiHelper.stopListening();
+ }
+
+ /**
+ * Switches to backup (password) screen. This either can happen when fingerprint is not
+ * available or the user chooses to use the password authentication method by pressing the
+ * button. This can also happen when the user had too many fingerprint attempts.
+ */
+ private void goToBackup() {
+ final Context app = getContext();
+ closeMe();
+
+ if (mFingerprintUiHelper != null)
+ mFingerprintUiHelper.stopListening();
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ AuthManager.getInstance().authPrompt(app, customTitle, customMessage, true, false, completion);
+ }
+ }, ANIMATION_DURATION + 100);
+ }
+
+ @Override
+ public void onAuthenticated() {
+ final Activity app = getActivity();
+ authSucceeded = true;
+
+ if (completion != null) completion.onComplete();
+ BRAnimator.killAllFragments(app);
+ BRAnimator.startBreadIfNotStarted(app);
+
+ closeMe();
+
+ }
+
+ public void setCompletion(BRAuthCompletion completion) {
+ this.completion = completion;
+ }
+
+ @Override
+ public void onError() {
+ goToBackup();
+ }
+
+ private void animateBackgroundDim(boolean reverse) {
+ int transColor = reverse ? R.color.black_trans : android.R.color.transparent;
+ int blackTransColor = reverse ? android.R.color.transparent : R.color.black_trans;
+
+ ValueAnimator anim = new ValueAnimator();
+ anim.setIntValues(transColor, blackTransColor);
+ anim.setEvaluator(new ArgbEvaluator());
+ anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator valueAnimator) {
+ fingerprintBackground.setBackgroundColor((Integer) valueAnimator.getAnimatedValue());
+ }
+ });
+
+ anim.setDuration(ANIMATION_DURATION);
+ anim.start();
+ }
+
+ private void animateSignalSlide(final boolean reverse) {
+ float layoutTY = fingerPrintLayout.getTranslationY();
+ if (!reverse) {
+ fingerPrintLayout.setTranslationY(layoutTY + BreadActivity.screenParametersPoint.y);
+ fingerPrintLayout.animate()
+ .translationY(layoutTY)
+ .setDuration(ANIMATION_DURATION + 200)
+ .setInterpolator(new DecelerateOvershootInterpolator(2.0f, 1f))
+ .withLayer();
+ } else {
+ fingerPrintLayout.animate()
+ .translationY(1500)
+ .setDuration(ANIMATION_DURATION)
+ .withLayer()
+ .setInterpolator(new AnticipateInterpolator(2.0f))
+ .setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ if (getActivity() != null) {
+ fingerPrintLayout.clearAnimation();
+ AnalyticsManager.logCustomEvent(BRConstants._20230131_NENR);
+ }
+ }
+ });
+
+ }
+
+ }
+
+ private void closeMe() {
+ animateBackgroundDim(true);
+ animateSignalSlide(true);
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentGreetings.java b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentGreetings.java
new file mode 100644
index 000000000..7a5985dc9
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentGreetings.java
@@ -0,0 +1,88 @@
+package com.breadwallet.presenter.fragments;
+
+import android.app.Fragment;
+import android.os.Bundle;
+import androidx.annotation.LayoutRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.constraintlayout.widget.ConstraintLayout;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.widget.RelativeLayout;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.customviews.BRButton;
+import com.breadwallet.tools.animation.BRAnimator;
+
+public class FragmentGreetings extends Fragment {
+ private static final String TAG = FragmentGreetings.class.getName();
+
+ private BRButton ok;
+ private ConstraintLayout mainLayout;
+ private RelativeLayout background;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater,
+ ViewGroup container, Bundle savedInstanceState) {
+ // The last two arguments ensure LayoutParams are inflated
+ // properly.
+
+ View rootView = inflater.inflate(R.layout.fragment_greetings, container, false);
+ ok = (BRButton) rootView.findViewById(R.id.ok);
+ mainLayout = (ConstraintLayout) rootView.findViewById(R.id.signal_layout);
+ background = (RelativeLayout) rootView.findViewById(R.id.layout);
+
+ ok.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ getActivity().onBackPressed();
+ }
+ });
+ return rootView;
+ }
+
+ @Override
+ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+
+ final ViewTreeObserver observer = mainLayout.getViewTreeObserver();
+ observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+ @Override
+ public void onGlobalLayout() {
+ if(observer.isAlive()) {
+ observer.removeOnGlobalLayoutListener(this);
+ }
+ BRAnimator.animateBackgroundDim(background, false);
+ BRAnimator.animateSignalSlide(mainLayout, false, null);
+ }
+ });
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ BRAnimator.animateBackgroundDim(background, true);
+ BRAnimator.animateSignalSlide(mainLayout, true, new BRAnimator.OnSlideAnimationEnd() {
+ @Override
+ public void onAnimationEnd() {
+ if (getActivity() != null)
+ getActivity().getFragmentManager().popBackStack();
+ }
+ });
+
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentMenu.java b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentMenu.java
new file mode 100644
index 000000000..64b5bd588
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentMenu.java
@@ -0,0 +1,157 @@
+package com.breadwallet.presenter.fragments;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import androidx.annotation.LayoutRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.browser.customtabs.CustomTabsIntent;
+import androidx.constraintlayout.widget.ConstraintLayout;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.settings.SecurityCenterActivity;
+import com.breadwallet.presenter.activities.settings.SettingsActivity;
+import com.breadwallet.presenter.entities.BRMenuItem;
+import com.breadwallet.tools.animation.BRAnimator;
+import com.breadwallet.tools.animation.SlideDetector;
+import com.breadwallet.tools.manager.AnalyticsManager;
+import com.breadwallet.tools.util.BRConstants;
+import com.platform.APIClient;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class FragmentMenu extends Fragment {
+
+ public TextView mTitle;
+ public ListView mListView;
+ public RelativeLayout background;
+ public List itemList;
+ public ConstraintLayout signalLayout;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater,
+ ViewGroup container, Bundle savedInstanceState) {
+
+ View rootView = inflater.inflate(R.layout.fragment_menu, container, false);
+ background = rootView.findViewById(R.id.layout);
+ signalLayout = rootView.findViewById(R.id.signal_layout);
+ background.setOnClickListener(v -> {
+ if (!BRAnimator.isClickAllowed()) return;
+ closeMenu();
+ });
+
+ itemList = new ArrayList<>();
+
+ /* Security Center */
+ itemList.add(new BRMenuItem(getString(R.string.MenuButton_security), R.drawable.ic_shield, v -> {
+ Intent intent = new Intent(getActivity(), SecurityCenterActivity.class);
+ launchActivity(intent);
+ }));
+
+ /* Customer Support */
+ itemList.add(new BRMenuItem(getString(R.string.MenuButton_support), R.drawable.faq_question_black, v -> {
+ CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
+ CustomTabsIntent customTabsIntent = builder.build();
+ customTabsIntent.launchUrl(getContext(), Uri.parse(BRConstants.CUSTOMER_SUPPORT_LINK));
+ AnalyticsManager.logCustomEvent(BRConstants._20201118_DTGS);
+ }));
+
+ /* Settings */
+ itemList.add(new BRMenuItem(getString(R.string.MenuButton_settings), R.drawable.ic_settings, v -> {
+ Intent intent = new Intent(getActivity(), SettingsActivity.class);
+ launchActivity(intent);
+ }));
+
+ /* Lock Wallet */
+ itemList.add(new BRMenuItem(getString(R.string.MenuButton_lock), R.drawable.ic_lock, v -> {
+ closeMenu();
+ final Activity from = getActivity();
+ BRAnimator.startBreadActivity(from, true);
+ }));
+
+ /* Close button*/
+ rootView.findViewById(R.id.close_button).setOnClickListener(v -> {
+ closeMenu();
+ });
+
+ mTitle = rootView.findViewById(R.id.title);
+ mListView = rootView.findViewById(R.id.menu_listview);
+ mListView.setAdapter(new MenuListAdapter(getContext(), R.layout.menu_list_item, itemList));
+ signalLayout.setOnTouchListener(new SlideDetector(signalLayout, this::closeMenu));
+
+ return rootView;
+ }
+
+ private void launchActivity(Intent intent) {
+ closeMenu();
+ Activity app = getActivity();
+ app.startActivity(intent);
+ app.overridePendingTransition(R.anim.enter_from_bottom, R.anim.fade_down);
+ }
+
+ @Override
+ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+
+ final ViewTreeObserver observer = mListView.getViewTreeObserver();
+ observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+ @Override
+ public void onGlobalLayout() {
+ if (observer.isAlive()) {
+ observer.removeOnGlobalLayoutListener(this);
+ }
+ BRAnimator.animateBackgroundDim(background, false);
+ BRAnimator.animateSignalSlide(signalLayout, false, null);
+ }
+ });
+ }
+
+ public static class MenuListAdapter extends ArrayAdapter {
+
+ private final LayoutInflater mInflater;
+
+ public MenuListAdapter(@NonNull Context context, @LayoutRes int resource, @NonNull List items) {
+ super(context, resource, items);
+ mInflater = ((Activity) context).getLayoutInflater();
+ }
+
+ @NonNull
+ @Override
+ public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
+ if (convertView == null) {
+ convertView = mInflater.inflate(R.layout.menu_list_item, parent, false);
+ }
+ TextView text = convertView.findViewById(R.id.item_text);
+ ImageView icon = convertView.findViewById(R.id.item_icon);
+
+ final BRMenuItem item = getItem(position);
+ text.setText(item.text);
+ icon.setImageResource(item.resId);
+ convertView.setOnClickListener(item.listener);
+ return convertView;
+ }
+ }
+
+ private void closeMenu() {
+ BRAnimator.animateBackgroundDim(background, true);
+ BRAnimator.animateSignalSlide(signalLayout, true, () -> {});
+ if (getActivity() != null && !getActivity().isDestroyed() && !getActivity().isFinishing()) {
+ getActivity().getFragmentManager().popBackStack();
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentPhraseFlow1.java b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentPhraseFlow1.java
deleted file mode 100644
index 5773ecb07..000000000
--- a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentPhraseFlow1.java
+++ /dev/null
@@ -1,137 +0,0 @@
-
-package com.breadwallet.presenter.fragments;
-
-import android.app.Fragment;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.graphics.Typeface;
-import android.os.Build;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.Button;
-import android.widget.TextView;
-
-import com.breadwallet.BreadWalletApp;
-import com.breadwallet.R;
-import com.breadwallet.presenter.activities.IntroActivity;
-import com.breadwallet.presenter.activities.MainActivity;
-import com.breadwallet.presenter.activities.PhraseFlowActivity;
-import com.breadwallet.tools.adapter.MiddleViewAdapter;
-import com.breadwallet.tools.animation.BRAnimator;
-import com.breadwallet.tools.manager.CurrencyManager;
-import com.breadwallet.tools.manager.SharedPreferencesManager;
-import com.breadwallet.tools.security.KeyStoreManager;
-import com.breadwallet.tools.security.PostAuthenticationProcessor;
-import com.breadwallet.tools.util.BRConstants;
-import com.breadwallet.tools.util.BRStringFormatter;
-
-import java.math.BigDecimal;
-import java.util.Arrays;
-import java.util.Locale;
-
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 7/14/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-public class FragmentPhraseFlow1 extends Fragment {
- FragmentPhraseFlow1 fragmentPhraseFlow1;
- public static byte[] phrase;
-
- @Override
- public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
-
- View rootView = inflater.inflate(R.layout.fragment_phrase_flow1, container, false);
- Button nextButton = (Button) rootView.findViewById(R.id.next_button);
- fragmentPhraseFlow1 = this;
- if (KeyStoreManager.getPassCode(getActivity()).isEmpty()) {
- PhraseFlowActivity app = ((PhraseFlowActivity) getActivity());
- app.showHideFragments(app.fragmentPhraseFlow2);
- app.fragmentPhraseFlow2.setPhrase(phrase);
- }
-
- long limit = SharedPreferencesManager.getLimit(getActivity());
-
- nextButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- PhraseFlowActivity app = ((PhraseFlowActivity) getActivity());
- if (app == null) return;
-
- if (BRAnimator.checkTheMultipressingAvailability()) {
- ((BreadWalletApp) app.getApplicationContext()).promptForAuthentication(app, BRConstants.AUTH_FOR_PHRASE, null, null, null, null,false);
- }
- }
- });
-
- rootView.setOnTouchListener(new View.OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- return true;
- }
- });
- if (CurrencyManager.getInstance(getActivity()).getBALANCE() > limit
- && !SharedPreferencesManager.getPhraseWroteDown(getActivity())) {
- TextView title = (TextView) rootView.findViewById(R.id.warning_flow);
- TextView textFlow1 = (TextView) rootView.findViewById(R.id.textFlow1);
- TextView textFlow2 = (TextView) rootView.findViewById(R.id.textFlow2);
- if (title == null || textFlow1 == null || textFlow2 == null) return rootView;
- title.setText(R.string.write_down_your_recovery_phrase);
- String iso = SharedPreferencesManager.getIso(getActivity());
- double rate = SharedPreferencesManager.getRate(getActivity());
- String limitText = String.format("%s(%s)", BRStringFormatter.getFormattedCurrencyString("BTC", limit),
- BRStringFormatter.getExchangeForAmount(rate, iso, new BigDecimal(limit), getActivity()));
- textFlow1.setText(String.format(Locale.getDefault(), "your account balance is above %s\n\n", limitText));
- textFlow1.setTypeface(null, Typeface.BOLD);
- textFlow2.setText(R.string.protect_your_wallet);
- }
- return rootView;
- }
-
- @Override
- public void onResume() {
- super.onResume();
- }
-
- @Override
- public void onPause() {
- super.onPause();
- }
-
- public void setPhrase(final byte[] thePhrase) {
- phrase = thePhrase;
-
- }
-
- public void releasePhrase() {
- if (phrase != null)
- Arrays.fill(phrase, (byte) 0);
- }
-}
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentPhraseFlow2.java b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentPhraseFlow2.java
deleted file mode 100644
index db8ee8df6..000000000
--- a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentPhraseFlow2.java
+++ /dev/null
@@ -1,113 +0,0 @@
-
-package com.breadwallet.presenter.fragments;
-
-import android.app.Fragment;
-import android.os.Bundle;
-import android.os.Handler;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.widget.Button;
-import android.widget.ImageView;
-import android.widget.RelativeLayout;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.breadwallet.BreadWalletApp;
-import com.breadwallet.BuildConfig;
-import com.breadwallet.R;
-import com.breadwallet.presenter.activities.IntroActivity;
-import com.breadwallet.presenter.activities.MainActivity;
-import com.breadwallet.presenter.activities.PhraseFlowActivity;
-import com.breadwallet.tools.manager.BRClipboardManager;
-import com.breadwallet.tools.manager.SharedPreferencesManager;
-
-import java.util.Arrays;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 7/14/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-public class FragmentPhraseFlow2 extends Fragment {
- private TextView thePhrase;
- private Button continueButton;
- private Button backButton;
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-
- View rootView = inflater.inflate(R.layout.fragment_phrase_flow2, container, false);
- rootView.setOnTouchListener(new View.OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- return true;
- }
- });
- thePhrase = (TextView) rootView.findViewById(R.id.the_phrase);
- continueButton = (Button) rootView.findViewById(R.id.continue_button);
- TextView step1 = (TextView) rootView.findViewById(R.id.step1);
- step1.setText(String.format(getString(R.string.step_holder), 1, 3));
- backButton = (Button) rootView.findViewById(R.id.back_button);
- backButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- getActivity().onBackPressed();
- }
- });
-
- return rootView;
- }
-
- public void setPhrase(final byte[] phrase) {
- if(phrase.length == 0) throw new RuntimeException("phrase is empty what??");
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- String cleanPhrase = new String(phrase);
- if (cleanPhrase.split(" ").length == 12 && cleanPhrase.charAt(cleanPhrase.length() - 1) == '\0') {
- ((BreadWalletApp) getActivity().getApplication()).showCustomDialog(getString(R.string.warning),
- getActivity().getString(R.string.phrase_error), getString(R.string.ok));
- }
- thePhrase.setText(cleanPhrase);
- if (cleanPhrase.charAt(0) > 0x3000)
- thePhrase.setText(cleanPhrase.replace(" ", "\u3000"));
-
- continueButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- PhraseFlowActivity app = ((PhraseFlowActivity) getActivity());
- if(app == null) return;
- app.animateSlide(app.fragmentPhraseFlow2, app.fragmentPhraseFlow3, IntroActivity.RIGHT);
- app.fragmentPhraseFlow3.setPhrase(phrase);
- }
- });
- }
- }, 50);
-
- }
-
-
-}
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentPhraseFlow3.java b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentPhraseFlow3.java
deleted file mode 100644
index 9fc68a426..000000000
--- a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentPhraseFlow3.java
+++ /dev/null
@@ -1,365 +0,0 @@
-
-package com.breadwallet.presenter.fragments;
-
-import android.app.Activity;
-import android.app.Fragment;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Handler;
-import android.text.Spannable;
-import android.text.SpannableStringBuilder;
-import android.util.TypedValue;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-import android.widget.TableLayout;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.breadwallet.BreadWalletApp;
-import com.breadwallet.R;
-import com.breadwallet.presenter.activities.IntroActivity;
-import com.breadwallet.presenter.activities.MainActivity;
-import com.breadwallet.presenter.activities.PhraseFlowActivity;
-import com.breadwallet.tools.animation.SpringAnimator;
-import com.breadwallet.tools.manager.CurrencyManager;
-import com.breadwallet.tools.manager.SharedPreferencesManager;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Random;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 7/14/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-
-public class FragmentPhraseFlow3 extends Fragment {
-
- public static final String TAG = FragmentPhraseFlow3.class.getName();
-
- private byte[] phrase;
- private String[] phraseWords;
- private TextView textFlow;
- private String wordToCheck = "";
- private Button word1;
- private Button word2;
- private Button word3;
- private Button word4;
- private Button word5;
- private Button word6;
- private Button sixButtons[];
- private List sixWords;
- private View.OnClickListener listener;
- private TextView stepsTextView;
- private TableLayout tableLayout;
- private int step = 1;
- private boolean pressAvailable;
- private static final int STEPS_LIMIT = 3;
- private Button backButton;
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-
- View rootView = inflater.inflate(R.layout.fragment_phrase_flow3, container, false);
- Button skipButton = (Button) rootView.findViewById(R.id.skip_button);
- textFlow = (TextView) rootView.findViewById(R.id.textFlow3);
- stepsTextView = (TextView) rootView.findViewById(R.id.step);
- word1 = (Button) rootView.findViewById(R.id.word1);
- word2 = (Button) rootView.findViewById(R.id.word2);
- word3 = (Button) rootView.findViewById(R.id.word3);
- word4 = (Button) rootView.findViewById(R.id.word4);
- word5 = (Button) rootView.findViewById(R.id.word5);
- word6 = (Button) rootView.findViewById(R.id.word6);
- tableLayout = (TableLayout) rootView.findViewById(R.id.words_layout);
- backButton = (Button) rootView.findViewById(R.id.back_button);
- backButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- getActivity().onBackPressed();
- }
- });
- rootView.setOnTouchListener(new View.OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- return true;
- }
- });
- if (CurrencyManager.getInstance(getActivity()).getBALANCE() > SharedPreferencesManager.getLimit(getActivity())) {
- skipButton.setVisibility(View.GONE);
- }
- skipButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- Intent intent;
- Activity app = getActivity();
- intent = new Intent(app, MainActivity.class);
- startActivity(intent);
- if (!app.isDestroyed()) {
- app.finish();
- }
- }
- });
-
- return rootView;
- }
-
- public void setPhrase(byte[] phrase) {
- this.phrase = phrase;
- pressAvailable = true;
- step = 2;
- updateStepsText(step);
- sixWords = new ArrayList<>();
- sixButtons = new Button[6];
- listener = new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- if (!pressAvailable) return;
- pressAvailable = false;
- final Button b = ((Button) view);
- if (b.getText().toString().equalsIgnoreCase(wordToCheck)) {
- b.setTextColor(getActivity().getColor(R.color.green_text));
- SpringAnimator.showAnimation(b);
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- nextTry();
- }
- }, 800);
- } else {
- b.setTextColor(getActivity().getColor(R.color.red_text));
- SpringAnimator.failShakeAnimation(getActivity(), b);
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- goBack();
- }
- }, 800);
- }
-
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- b.setTextColor(getActivity().getColor(R.color.dark_blue));
- }
- }, 500);
-
- }
- };
-
- sixButtons[0] = word1;
- sixButtons[1] = word2;
- sixButtons[2] = word3;
- sixButtons[3] = word4;
- sixButtons[4] = word5;
- sixButtons[5] = word6;
- String cleanPhrase = phrase == null? "" : new String(phrase);
- if (cleanPhrase.split(" ").length == 12 && cleanPhrase.charAt(cleanPhrase.length() - 1) == '\0') {
- ((BreadWalletApp) getActivity().getApplication()).showCustomDialog(getString(R.string.warning),
- getActivity().getString(R.string.phrase_error), getString(R.string.ok));
- }
- phraseWords = cleanPhrase.split(" ");
- startOver();
- }
-
- private void startOver() {
- sixWords.clear();
- setTextWithRandomNr();
- fillWordsArray();
- setButtons();
- }
-
- @Override
- public void onResume() {
- super.onResume();
- ((BreadWalletApp) getActivity().getApplication()).hideKeyboard(getActivity());
- }
-
-
- private void setTextWithRandomNr() {
- if (textFlow == null) return;
- final Random random = new Random();
- int n = random.nextInt(10) + 1;
- String oldWord = wordToCheck;
- wordToCheck = phraseWords[n];
- while (oldWord.equalsIgnoreCase(wordToCheck)) {
- n = random.nextInt(10) + 1;
- wordToCheck = phraseWords[n];
- }
- String placeHolder;
- switch (n) {
- case 0:
- throw new IllegalArgumentException("Cannot be 0");
- case 11:
- throw new IllegalArgumentException("Cannot be 11");
- case 1:
- textFlow.setText(getText(R.string.word_nr2));
- break;
- case 2:
- textFlow.setText(getText(R.string.word_nr3));
- break;
- case 3:
- textFlow.setText(getText(R.string.word_nr4));
- break;
- case 4:
- textFlow.setText(getText(R.string.word_nr5));
- break;
- case 5:
- textFlow.setText(getText(R.string.word_nr6));
- break;
- case 6:
- textFlow.setText(getText(R.string.word_nr7));
- break;
- case 7:
- textFlow.setText(getText(R.string.word_nr8));
- break;
- case 8:
- textFlow.setText(getText(R.string.word_nr9));
- break;
- case 9:
- textFlow.setText(getText(R.string.word_nr10));
- break;
- case 10:
- textFlow.setText(getText(R.string.word_nr11));
- break;
- default:
- throw new IllegalArgumentException("cannot be other");
-
- }
-
- }
-
- private void fillWordsArray() {
- final Random random = new Random();
- sixWords.add(wordToCheck);
- for (int i = 1; i < 6; i++) {
- int n = random.nextInt(12);
- String randWord = phraseWords[n];
- while (sixWords.contains(randWord)) {
- int w = random.nextInt(12);
- randWord = phraseWords[w];
- }
- sixWords.add(randWord);
- }
- Collections.shuffle(sixWords);
-
- }
-
- private void setButtons() {
- for (int i = 0; i < 6; i++) {
- String word = sixWords.get(i);
- sixButtons[i].setText(word);
- sixButtons[i].setOnClickListener(listener);
- }
- }
-
- private void nextTry() {
- if (step == STEPS_LIMIT) {
- SharedPreferencesManager.putPhraseWroteDown(getActivity(), true);
- finishFlow();
- return;
- }
- stepsTextView.setVisibility(View.GONE);
- updateStepsText(++step);
- for (int i = 0; i < 6; i++) {
- sixButtons[i].setVisibility(View.GONE);
- }
-
- new Handler().post(new Runnable() {
- @Override
- public void run() {
- startOver();
- for (int i = 0; i < 6; i++) {
- sixButtons[i].setVisibility(View.VISIBLE);
- }
- for (int i = 0; i < 6; i++) {
- SpringAnimator.showAnimation(sixButtons[i]);
- }
- stepsTextView.setVisibility(View.VISIBLE);
- SpringAnimator.showAnimation(stepsTextView);
- SpringAnimator.showAnimation(textFlow);
- pressAvailable = true;
- }
- });
-
- }
-
- private void goBack() {
- if (this.isVisible()) {
- PhraseFlowActivity app = (PhraseFlowActivity) getActivity();
- app.animateSlide(app.fragmentPhraseFlow3, app.fragmentPhraseFlow2, IntroActivity.LEFT);
- app.fragmentPhraseFlow2.setPhrase(phrase);
- }
- }
-
- private void updateStepsText(int steps) {
- stepsTextView.setText(String.format(getString(R.string.step_holder), steps, STEPS_LIMIT));
- }
-
- private void finishFlow() {
- Toast toast = new Toast(getActivity());
-
- LayoutInflater inflater = getActivity().getLayoutInflater();
- View layout = inflater.inflate(R.layout.toast,
- (ViewGroup) getActivity().findViewById(R.id.toast_layout_root));
- layout.setBackgroundResource(R.drawable.toast_layout_black);
- TextView text = (TextView) layout.findViewById(R.id.toast_text);
- text.setText(R.string.recovery_phrase_set);
- text.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
- text.setPadding(20, 40, 20, 40);
- toast.setGravity(Gravity.BOTTOM, 0, PhraseFlowActivity.screenParametersPoint.y / 2);
- toast.setDuration(Toast.LENGTH_SHORT);
- toast.setView(layout);
- toast.show();
-
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- PhraseFlowActivity app = (PhraseFlowActivity) getActivity();
- Intent intent;
- intent = new Intent(app, MainActivity.class);
- startActivity(intent);
- if (!app.isDestroyed()) {
- app.finish();
- }
- }
- }, 1000);
-
- }
-
- public void releasePhrase() {
- if (phrase != null)
- Arrays.fill(phrase, (byte) 0);
- }
-
- public byte[] getPhrase() {
- return phrase;
- }
-
-}
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentPhraseWord.java b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentPhraseWord.java
new file mode 100644
index 000000000..4a12d45b2
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentPhraseWord.java
@@ -0,0 +1,42 @@
+package com.breadwallet.presenter.fragments;
+
+import android.app.Fragment;
+import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import com.breadwallet.R;
+
+public class FragmentPhraseWord extends Fragment {
+ private static final String TAG = FragmentPhraseWord.class.getName();
+
+ @Override
+ public View onCreateView(LayoutInflater inflater,
+ ViewGroup container, Bundle savedInstanceState) {
+
+
+ View rootView = inflater.inflate(R.layout.fragment_word_item, container, false);
+ TextView b = (TextView) rootView.findViewById(R.id.word_button);
+ b.setText(getArguments().getString("text"));
+
+ return rootView;
+ }
+
+ public static FragmentPhraseWord newInstance(String text) {
+
+ FragmentPhraseWord f = new FragmentPhraseWord();
+ Bundle b = new Bundle();
+ b.putString("text", text);
+
+ f.setArguments(b);
+
+ return f;
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentPin.java b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentPin.java
new file mode 100644
index 000000000..e091ec74f
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentPin.java
@@ -0,0 +1,228 @@
+package com.breadwallet.presenter.fragments;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.OvershootInterpolator;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import androidx.annotation.Nullable;
+import androidx.constraintlayout.widget.ConstraintLayout;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.activities.BreadActivity;
+import com.breadwallet.presenter.customviews.BRKeyboard;
+import com.breadwallet.presenter.interfaces.BRAuthCompletion;
+import com.breadwallet.tools.animation.DecelerateOvershootInterpolator;
+import com.breadwallet.tools.animation.SpringAnimator;
+import com.breadwallet.tools.security.AuthManager;
+import com.breadwallet.tools.security.BRKeyStore;
+import com.breadwallet.tools.threads.BRExecutor;
+import com.breadwallet.tools.util.Utils;
+
+import timber.log.Timber;
+
+public class FragmentPin extends Fragment {
+ private BRAuthCompletion completion;
+
+ private BRKeyboard keyboard;
+ private LinearLayout pinLayout;
+ private View dot1;
+ private View dot2;
+ private View dot3;
+ private View dot4;
+ private View dot5;
+ private View dot6;
+ private StringBuilder pin = new StringBuilder();
+ private int pinLimit = 6;
+// private boolean pinInsertAllowed;
+
+ private TextView title;
+ private TextView message;
+ private RelativeLayout dialogLayout;
+ ConstraintLayout mainLayout;
+ private boolean authSucceeded;
+ private String customTitle;
+ private String customMessage;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View rootView = inflater.inflate(R.layout.fragment_bread_pin, container, false);
+ keyboard = (BRKeyboard) rootView.findViewById(R.id.brkeyboard);
+ pinLayout = (LinearLayout) rootView.findViewById(R.id.pinLayout);
+
+ if (BRKeyStore.getPinCode(getContext()).length() == 4) pinLimit = 4;
+
+ title = (TextView) rootView.findViewById(R.id.title);
+ message = (TextView) rootView.findViewById(R.id.message);
+ dialogLayout = (RelativeLayout) rootView.findViewById(R.id.pin_dialog);
+ mainLayout = (ConstraintLayout) rootView.findViewById(R.id.activity_pin);
+
+ mainLayout.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ getActivity().getFragmentManager().beginTransaction().remove(FragmentPin.this).commit();
+ }
+ });
+
+ dot1 = rootView.findViewById(R.id.dot1);
+ dot2 = rootView.findViewById(R.id.dot2);
+ dot3 = rootView.findViewById(R.id.dot3);
+ dot4 = rootView.findViewById(R.id.dot4);
+ dot5 = rootView.findViewById(R.id.dot5);
+ dot6 = rootView.findViewById(R.id.dot6);
+
+ keyboard.addOnInsertListener(new BRKeyboard.OnInsertListener() {
+ @Override
+ public void onClick(String key) {
+ handleClick(key);
+ }
+ });
+ keyboard.setShowDot(false);
+
+ return rootView;
+ }
+
+ @Override
+ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ float keyboardTrY = keyboard.getTranslationY();
+ Bundle bundle = getArguments();
+ String titleString = bundle.getString("title");
+ String messageString = bundle.getString("message");
+ if (!Utils.isNullOrEmpty(titleString)) {
+ customTitle = titleString;
+ title.setText(customTitle);
+ }
+ if (!Utils.isNullOrEmpty(messageString)) {
+ customMessage = messageString;
+ message.setText(customMessage);
+ }
+ keyboard.setTranslationY(keyboardTrY + BreadActivity.screenParametersPoint.y / 3);
+ keyboard.animate()
+ .translationY(keyboardTrY)
+ .setDuration(400)
+ .setInterpolator(new DecelerateOvershootInterpolator(2.0f, 1f))
+ .withLayer();
+ float dialogScaleX = dialogLayout.getScaleX();
+ float dialogScaleY = dialogLayout.getScaleY();
+ dialogLayout.setScaleX(dialogScaleX / 2);
+ dialogLayout.setScaleY(dialogScaleY / 2);
+ dialogLayout.animate()
+ .scaleY(dialogScaleY)
+ .scaleX(dialogScaleX)
+ .setInterpolator(new OvershootInterpolator(2f));
+
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ updateDots();
+ authSucceeded = false;
+ }
+
+
+ private void handleClick(String key) {
+ if (key == null) {
+ Timber.d("timber: handleClick: key is null! ");
+ return;
+ }
+
+ if (key.isEmpty()) {
+ handleDeleteClick();
+ } else if (Character.isDigit(key.charAt(0))) {
+ handleDigitClick(Integer.parseInt(key.substring(0, 1)));
+ } else {
+ Timber.d("timber: handleClick: oops: %s", key);
+ }
+ }
+
+ private void handleDigitClick(Integer dig) {
+ if (pin.length() < pinLimit)
+ pin.append(dig);
+ updateDots();
+ }
+
+ private void handleDeleteClick() {
+ if (pin.length() > 0)
+ pin.deleteCharAt(pin.length() - 1);
+ updateDots();
+ }
+
+ private void updateDots() {
+ if (dot1 == null) return;
+ AuthManager.getInstance().updateDots(getActivity(), pinLimit, pin.toString(), dot1, dot2, dot3, dot4, dot5, dot6, R.drawable.ic_pin_dot_gray, new AuthManager.OnPinSuccess() {
+ @Override
+ public void onSuccess() {
+ if (AuthManager.getInstance().checkAuth(pin.toString(), getContext())) {
+ handleSuccess();
+ } else {
+ handleFail();
+ }
+ pin = new StringBuilder();
+ }
+ });
+ }
+
+ private void handleSuccess() {
+ BRExecutor.getInstance().forLightWeightBackgroundTasks().execute(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ Timber.e(e);
+ }
+ authSucceeded = true;
+ completion.onComplete();
+ Activity app = getActivity();
+ AuthManager.getInstance().authSuccess(app);
+ if (app != null)
+ app.getFragmentManager().popBackStack();
+ }
+ });
+ }
+
+ private void handleFail() {
+ SpringAnimator.failShakeAnimation(getActivity(), pinLayout);
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ updateDots();
+ }
+ }, 500);
+ AuthManager.getInstance().authFail(getActivity());
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+// keyboard.animate()
+// .translationY(1000)
+// .withLayer();
+// dialogLayout.animate()
+// .scaleY(0)
+// .scaleX(0).alpha(0);
+// mainLayout.animate().alpha(0);
+// if (!authSucceeded)
+// completion.onCancel();
+// new Handler().postDelayed(new Runnable() {
+// @Override
+// public void run() {
+// if (getActivity() != null)
+// getActivity().getFragmentManager().beginTransaction().remove(FragmentPin.this).commit();
+// }
+// }, 1000);
+ }
+
+ public void setCompletion(BRAuthCompletion completion) {
+ this.completion = completion;
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentReceive.java b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentReceive.java
new file mode 100644
index 000000000..2e4c31db3
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentReceive.java
@@ -0,0 +1,261 @@
+package com.breadwallet.presenter.fragments;
+
+import static com.breadwallet.tools.animation.BRAnimator.animateBackgroundDim;
+import static com.breadwallet.tools.animation.BRAnimator.animateSignalSlide;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.widget.Button;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.annotation.Nullable;
+
+import com.breadwallet.BreadApp;
+import com.breadwallet.R;
+import com.breadwallet.presenter.customviews.BRButton;
+import com.breadwallet.presenter.customviews.BRKeyboard;
+import com.breadwallet.presenter.customviews.BRLinearLayoutWithCaret;
+import com.breadwallet.tools.animation.BRAnimator;
+import com.breadwallet.tools.animation.SlideDetector;
+import com.breadwallet.tools.manager.AnalyticsManager;
+import com.breadwallet.tools.manager.BRClipboardManager;
+import com.breadwallet.tools.manager.BRSharedPrefs;
+import com.breadwallet.tools.qrcode.QRUtils;
+import com.breadwallet.tools.threads.BRExecutor;
+import com.breadwallet.tools.util.BRConstants;
+import com.breadwallet.tools.util.Utils;
+import com.breadwallet.wallet.BRWalletManager;
+
+public class FragmentReceive extends Fragment {
+ private static final String TAG = FragmentReceive.class.getName();
+
+ public TextView mTitle;
+ public TextView mAddress;
+ public ImageView mQrImage;
+ public LinearLayout backgroundLayout;
+ public LinearLayout signalLayout;
+ private String receiveAddress;
+ private View separator;
+ private BRButton shareButton;
+ private Button shareEmail;
+ // private Button shareTextMessage;
+ private Button requestButton;
+ private BRLinearLayoutWithCaret shareButtonsLayout;
+ private BRLinearLayoutWithCaret copiedLayout;
+ private boolean shareButtonsShown = false;
+ private boolean isReceive;
+ private ImageButton close;
+ private Handler copyCloseHandler = new Handler();
+ private BRKeyboard keyboard;
+ private View separator2;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ // The last two arguments ensure LayoutParams are inflated
+ // properly.
+
+ View rootView = inflater.inflate(R.layout.fragment_receive, container, false);
+ mTitle = (TextView) rootView.findViewById(R.id.title);
+ mAddress = (TextView) rootView.findViewById(R.id.address_text);
+ mQrImage = (ImageView) rootView.findViewById(R.id.qr_image);
+ backgroundLayout = (LinearLayout) rootView.findViewById(R.id.background_layout);
+ signalLayout = (LinearLayout) rootView.findViewById(R.id.signal_layout);
+ shareButton = (BRButton) rootView.findViewById(R.id.share_button);
+ shareEmail = (Button) rootView.findViewById(R.id.share_email);
+// shareTextMessage = (Button) rootView.findViewById(R.id.share_text);
+ shareButtonsLayout = (BRLinearLayoutWithCaret) rootView.findViewById(R.id.share_buttons_layout);
+ copiedLayout = (BRLinearLayoutWithCaret) rootView.findViewById(R.id.copied_layout);
+ requestButton = (Button) rootView.findViewById(R.id.request_button);
+ keyboard = (BRKeyboard) rootView.findViewById(R.id.keyboard);
+ keyboard.setBRButtonBackgroundResId(R.drawable.keyboard_white_button);
+ keyboard.setBRKeyboardColor(R.color.white);
+ separator = rootView.findViewById(R.id.separator);
+ close = (ImageButton) rootView.findViewById(R.id.close_button);
+ separator2 = rootView.findViewById(R.id.separator2);
+ separator2.setVisibility(View.GONE);
+
+ setListeners();
+ BRWalletManager.getInstance().addBalanceChangedListener(balance -> updateQr());
+
+ ImageButton faq = (ImageButton) rootView.findViewById(R.id.faq_button);
+ //TODO: all views are using the layout of this button. Views should be refactored without it
+ // Hiding until layouts are built.
+
+ signalLayout.removeView(shareButtonsLayout);
+ signalLayout.removeView(copiedLayout);
+ signalLayout.setLayoutTransition(BRAnimator.getDefaultTransition());
+ signalLayout.setOnTouchListener(new SlideDetector(signalLayout, this::animateClose));
+ AnalyticsManager.logCustomEvent(BRConstants._20202116_VRC);
+ return rootView;
+ }
+
+ private void setListeners() {
+ shareEmail.setOnClickListener(v -> {
+ if (!BRAnimator.isClickAllowed()) return;
+ String bitcoinUri = Utils.createBitcoinUrl(receiveAddress, 0, null, null, null);
+ QRUtils.share("mailto:", getActivity(), bitcoinUri);
+ });
+// shareTextMessage.setOnClickListener(new View.OnClickListener() {
+// @Override
+// public void onClick(View v) {
+// if (!BRAnimator.isClickAllowed()) return;
+// String bitcoinUri = Utils.createBitcoinUrl(receiveAddress, 0, null, null, null);
+// QRUtils.share("sms:", getActivity(), bitcoinUri);
+// }
+// });
+ shareButton.setOnClickListener(v -> {
+ if (!BRAnimator.isClickAllowed()) return;
+ shareButtonsShown = !shareButtonsShown;
+ showShareButtons(shareButtonsShown);
+ });
+ mAddress.setOnClickListener(v -> {
+ if (!BRAnimator.isClickAllowed()) return;
+ copyText();
+ });
+ requestButton.setOnClickListener(v -> {
+ if (!BRAnimator.isClickAllowed()) return;
+ closeAndOpenShowRequest();
+ });
+ backgroundLayout.setOnClickListener(v -> {
+ if (!BRAnimator.isClickAllowed()) return;
+ animateClose();
+ });
+ mQrImage.setOnClickListener(v -> {
+ if (!BRAnimator.isClickAllowed()) return;
+ copyText();
+ });
+ close.setOnClickListener(v -> animateClose());
+ }
+
+ private void showShareButtons(boolean b) {
+ if (!b) {
+ signalLayout.removeView(shareButtonsLayout);
+ shareButton.setType(2);
+ } else {
+ signalLayout.addView(shareButtonsLayout, isReceive ? signalLayout.getChildCount() - 2 : signalLayout.getChildCount());
+ shareButton.setType(3);
+ showCopiedLayout(false);
+ }
+ }
+
+ private void showCopiedLayout(boolean b) {
+ if (!b) {
+ signalLayout.removeView(copiedLayout);
+ copyCloseHandler.removeCallbacksAndMessages(null);
+ } else {
+ if (signalLayout.indexOfChild(copiedLayout) == -1) {
+ signalLayout.addView(copiedLayout, signalLayout.indexOfChild(shareButton));
+ showShareButtons(false);
+ shareButtonsShown = false;
+ copyCloseHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ signalLayout.removeView(copiedLayout);
+ }
+ }, 2000);
+ } else {
+ copyCloseHandler.removeCallbacksAndMessages(null);
+ signalLayout.removeView(copiedLayout);
+ }
+ }
+ }
+
+ @Override
+ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+
+ final ViewTreeObserver observer = signalLayout.getViewTreeObserver();
+ observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+ @Override
+ public void onGlobalLayout() {
+ if (observer.isAlive()) {
+ observer.removeOnGlobalLayoutListener(this);
+ }
+ animateBackgroundDim(backgroundLayout, false);
+ animateSignalSlide(signalLayout, false, null);
+ }
+ });
+
+ Bundle extras = getArguments();
+ isReceive = extras.getBoolean("receive");
+ if (!isReceive) {
+ signalLayout.removeView(separator);
+ signalLayout.removeView(requestButton);
+ mTitle.setText(getString(R.string.UnlockScreen_myAddress));
+ }
+
+ BRExecutor.getInstance().forLightWeightBackgroundTasks().execute(new Runnable() {
+ @Override
+ public void run() {
+ updateQr();
+ }
+ });
+ }
+
+ private void updateQr() {
+ final Context ctx = getContext() == null ? BreadApp.getBreadContext() : (Activity) getContext();
+ BRExecutor.getInstance().forLightWeightBackgroundTasks().execute(new Runnable() {
+ @Override
+ public void run() {
+ boolean success = BRWalletManager.refreshAddress(ctx);
+ if (!success) {
+ if (ctx instanceof Activity) {
+ BRExecutor.getInstance().forMainThreadTasks().execute(new Runnable() {
+ @Override
+ public void run() {
+ close();
+ }
+ });
+
+ }
+ return;
+ }
+ BRExecutor.getInstance().forMainThreadTasks().execute(new Runnable() {
+ @Override
+ public void run() {
+ receiveAddress = BRSharedPrefs.getReceiveAddress(ctx);
+ mAddress.setText(receiveAddress);
+ boolean generated = QRUtils.generateQR(ctx, "litecoin:" + receiveAddress, mQrImage);
+ if (!generated)
+ throw new RuntimeException("failed to generate qr image for address");
+ }
+ });
+ }
+ });
+ }
+
+ private void copyText() {
+ BRClipboardManager.putClipboard(getContext(), mAddress.getText().toString());
+ showCopiedLayout(true);
+ }
+
+ private void animateClose() {
+ animateBackgroundDim(backgroundLayout, true);
+ animateSignalSlide(signalLayout, true, this::close);
+ }
+
+ private void close() {
+ if (getActivity() != null && !getActivity().isFinishing()) {
+ getActivity().onBackPressed();
+ }
+ }
+
+ private void closeAndOpenShowRequest() {
+ animateBackgroundDim(backgroundLayout, true);
+ animateSignalSlide(signalLayout, true, () -> {
+ close();
+ BRAnimator.showRequestFragment(getActivity(), receiveAddress);
+ });
+
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentRecoveryPhrase.java b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentRecoveryPhrase.java
deleted file mode 100644
index 323cba676..000000000
--- a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentRecoveryPhrase.java
+++ /dev/null
@@ -1,138 +0,0 @@
-
-package com.breadwallet.presenter.fragments;
-
-import android.app.Activity;
-import android.app.Fragment;
-import android.content.ClipboardManager;
-import android.content.pm.ApplicationInfo;
-import android.os.Bundle;
-import android.os.Handler;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.widget.Button;
-import android.widget.ImageView;
-import android.widget.RelativeLayout;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.breadwallet.BuildConfig;
-import com.breadwallet.R;
-import com.breadwallet.BreadWalletApp;
-import com.breadwallet.presenter.activities.MainActivity;
-import com.breadwallet.tools.manager.BRClipboardManager;
-import com.breadwallet.tools.manager.SharedPreferencesManager;
-import com.breadwallet.tools.adapter.MiddleViewAdapter;
-import com.breadwallet.wallet.BRWalletManager;
-
-import java.util.Arrays;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 7/22/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-public class FragmentRecoveryPhrase extends Fragment {
- public static final String TAG = FragmentRecoveryPhrase.class.getName();
- private TextView thePhrase;
- private byte[] phrase;
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View rootView = inflater.inflate(
- R.layout.fragment_recovery_phrase, container, false);
- thePhrase = (TextView) rootView.findViewById(R.id.the_phrase);
- Button backButton = (Button) rootView.findViewById(R.id.back_button);
- backButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- getActivity().onBackPressed();
- }
- });
-
- return rootView;
- }
-
- @Override
- public void onResume() {
- super.onResume();
- getActivity().getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,
- WindowManager.LayoutParams.FLAG_SECURE);
- Activity app = getActivity();
- if (app == null) app = MainActivity.app;
- if (app != null)
- ((BreadWalletApp) app.getApplication()).hideKeyboard(app);
- MiddleViewAdapter.resetMiddleView(getActivity(), null);
- }
-
- @Override
- public void onPause() {
- super.onPause();
- getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
- }
-
- public void setPhrase(byte[] phrase) {
- if (phrase == null) return;
- this.phrase = phrase;
-
- if (0 != (getActivity().getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE)) {
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- if (getActivity() != null) {
- BRClipboardManager.copyToClipboard(getActivity(), thePhrase.getText().toString());
- ((BreadWalletApp) getActivity().getApplication()).showCustomToast(getActivity(),
- getActivity().getString(R.string.copied), 300, Toast.LENGTH_SHORT, 0);
- }
- }
- }, 2000);
- }
-
- if (phrase.length == 0) {
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- getActivity().onBackPressed();
- }
- }, 10);
- return;
- }
- String cleanPhrase = new String(phrase);
- Arrays.fill(phrase, (byte) 0);
- if (cleanPhrase.split(" ").length == 12 && cleanPhrase.charAt(cleanPhrase.length() - 1) == '\0') {
- ((BreadWalletApp) getActivity().getApplication()).showCustomDialog(getString(R.string.warning),
- getActivity().getString(R.string.phrase_error), getString(R.string.ok));
- }
-
- thePhrase.setText(cleanPhrase);
- if (cleanPhrase.charAt(0) > 0x3000)
- thePhrase.setText(cleanPhrase.replace(" ", "\u3000"));
- }
-
- public void releasePhrase() {
- if (phrase != null)
- Arrays.fill(phrase, (byte) 0);
- }
-}
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentRequestAmount.java b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentRequestAmount.java
new file mode 100644
index 000000000..3a09a41b8
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentRequestAmount.java
@@ -0,0 +1,402 @@
+package com.breadwallet.presenter.fragments;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import androidx.annotation.Nullable;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.customviews.BRButton;
+import com.breadwallet.presenter.customviews.BRKeyboard;
+import com.breadwallet.presenter.customviews.BRLinearLayoutWithCaret;
+import com.breadwallet.tools.animation.BRAnimator;
+import com.breadwallet.tools.animation.SlideDetector;
+import com.breadwallet.tools.manager.BRClipboardManager;
+import com.breadwallet.tools.manager.BRSharedPrefs;
+import com.breadwallet.tools.qrcode.QRUtils;
+import com.breadwallet.tools.threads.BRExecutor;
+import com.breadwallet.tools.util.BRConstants;
+import com.breadwallet.tools.util.BRCurrency;
+import com.breadwallet.tools.util.BRExchange;
+import com.breadwallet.tools.util.Utils;
+import com.breadwallet.wallet.BRWalletManager;
+
+import java.math.BigDecimal;
+
+import timber.log.Timber;
+
+public class FragmentRequestAmount extends Fragment {
+ private BRKeyboard keyboard;
+ private StringBuilder amountBuilder;
+ private TextView isoText;
+ private EditText amountEdit;
+ public TextView mTitle;
+ public TextView mAddress;
+ public ImageView mQrImage;
+ public LinearLayout backgroundLayout;
+ public LinearLayout signalLayout;
+ private String receiveAddress;
+ private BRButton shareButton;
+ private Button shareEmail;
+ // private Button shareTextMessage;
+ private boolean shareButtonsShown = true;
+ private String selectedIso;
+ private Button isoButton;
+ private Handler copyCloseHandler = new Handler();
+ private LinearLayout keyboardLayout;
+ private RelativeLayout amountLayout;
+ private Button request;
+ private BRLinearLayoutWithCaret shareButtonsLayout;
+ private BRLinearLayoutWithCaret copiedLayout;
+ private int keyboardIndex;
+ // private int currListIndex;
+ private ImageButton close;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+
+ View rootView = inflater.inflate(R.layout.fragment_receive, container, false);
+ backgroundLayout = (LinearLayout) rootView.findViewById(R.id.background_layout);
+ signalLayout = (LinearLayout) rootView.findViewById(R.id.signal_layout);
+ shareButtonsLayout = (BRLinearLayoutWithCaret) rootView.findViewById(R.id.share_buttons_layout);
+ copiedLayout = (BRLinearLayoutWithCaret) rootView.findViewById(R.id.copied_layout);
+// currencyListLayout = (LinearLayout) rootView.findViewById(R.id.cur_spinner_layout);
+// currencyListLayout.setVisibility(View.VISIBLE);
+ request = (Button) rootView.findViewById(R.id.request_button);
+ keyboardLayout = (LinearLayout) rootView.findViewById(R.id.keyboard_layout);
+ keyboardLayout.setVisibility(View.VISIBLE);
+ amountLayout = (RelativeLayout) rootView.findViewById(R.id.amount_layout);
+ amountLayout.setVisibility(View.VISIBLE);
+ keyboard = (BRKeyboard) rootView.findViewById(R.id.keyboard);
+ keyboard.setBRButtonBackgroundResId(R.drawable.keyboard_white_button);
+ keyboard.setBRKeyboardColor(R.color.white);
+ isoText = (TextView) rootView.findViewById(R.id.iso_text);
+ amountEdit = (EditText) rootView.findViewById(R.id.amount_edit);
+ amountBuilder = new StringBuilder(0);
+ isoButton = (Button) rootView.findViewById(R.id.iso_button);
+ mTitle = (TextView) rootView.findViewById(R.id.title);
+ mAddress = (TextView) rootView.findViewById(R.id.address_text);
+ mQrImage = (ImageView) rootView.findViewById(R.id.qr_image);
+ shareButton = (BRButton) rootView.findViewById(R.id.share_button);
+ shareEmail = (Button) rootView.findViewById(R.id.share_email);
+// shareTextMessage = (Button) rootView.findViewById(R.id.share_text);
+ shareButtonsLayout = (BRLinearLayoutWithCaret) rootView.findViewById(R.id.share_buttons_layout);
+ close = (ImageButton) rootView.findViewById(R.id.close_button);
+ keyboardIndex = signalLayout.indexOfChild(keyboardLayout);
+
+ //TODO: all views are using the layout of this button. Views should be refactored without it
+ // Hiding until layouts are built.
+ ImageButton faq = (ImageButton) rootView.findViewById(R.id.faq_button);
+
+ mTitle.setText(getString(R.string.Receive_request));
+ setListeners();
+
+ signalLayout.removeView(shareButtonsLayout);
+ signalLayout.removeView(copiedLayout);
+ signalLayout.removeView(request);
+
+ showCurrencyList(false);
+ selectedIso = BRSharedPrefs.getPreferredLTC(getContext()) ? "LTC" : BRSharedPrefs.getIso(getContext());
+
+ signalLayout.setOnClickListener(v -> {
+// removeCurrencySelector();
+ });
+ updateText();
+
+ signalLayout.setLayoutTransition(BRAnimator.getDefaultTransition());
+
+ signalLayout.setOnTouchListener(new SlideDetector(signalLayout, this::animateClose));
+
+ return rootView;
+ }
+
+ private void setListeners() {
+ amountEdit.setOnClickListener(v -> {
+ removeCurrencySelector();
+ showKeyboard(true);
+ showShareButtons(false);
+ });
+
+ close.setOnClickListener(v -> animateClose());
+
+ mQrImage.setOnClickListener(v -> {
+ removeCurrencySelector();
+ showKeyboard(false);
+ });
+
+ keyboard.addOnInsertListener(key -> {
+ removeCurrencySelector();
+ handleClick(key);
+ });
+
+
+ shareEmail.setOnClickListener(v -> {
+ removeCurrencySelector();
+ if (!BRAnimator.isClickAllowed()) return;
+ showKeyboard(false);
+ String iso = selectedIso;
+ String strAmount = amountEdit.getText().toString();
+ BigDecimal bigAmount = new BigDecimal((Utils.isNullOrEmpty(strAmount) || strAmount.equalsIgnoreCase(".")) ? "0" : strAmount);
+ long amount = BRExchange.getSatoshisFromAmount(getActivity(), iso, bigAmount).longValue();
+ String bitcoinUri = Utils.createBitcoinUrl(receiveAddress, amount, null, null, null);
+ QRUtils.share("mailto:", getActivity(), bitcoinUri);
+
+ });
+// shareTextMessage.setOnClickListener(new View.OnClickListener() {
+// @Override
+// public void onClick(View v) {
+// removeCurrencySelector();
+// if (!BRAnimator.isClickAllowed()) return;
+// showKeyboard(false);
+// String iso = selectedIso;
+// String strAmount = amountEdit.getText().toString();
+// BigDecimal bigAmount = new BigDecimal((Utils.isNullOrEmpty(strAmount) || strAmount.equalsIgnoreCase(".")) ? "0" : strAmount);
+// long amount = BRExchange.getSatoshisFromAmount(getActivity(), iso, bigAmount).longValue();
+// String bitcoinUri = Utils.createBitcoinUrl(receiveAddress, amount, null, null, null);
+// QRUtils.share("sms:", getActivity(), bitcoinUri);
+// }
+// });
+ shareButton.setOnClickListener(v -> {
+ if (!BRAnimator.isClickAllowed()) return;
+ shareButtonsShown = !shareButtonsShown;
+ showShareButtons(shareButtonsShown);
+ showKeyboard(false);
+ });
+ mAddress.setOnClickListener(v -> {
+ removeCurrencySelector();
+ copyText();
+ showKeyboard(false);
+ });
+
+ backgroundLayout.setOnClickListener(v -> {
+ removeCurrencySelector();
+ if (!BRAnimator.isClickAllowed()) return;
+ animateClose();
+ });
+
+ isoButton.setOnClickListener(v -> {
+ if (selectedIso.equalsIgnoreCase(BRSharedPrefs.getIso(getContext()))) {
+ selectedIso = "LTC";
+ } else {
+ selectedIso = BRSharedPrefs.getIso(getContext());
+ }
+ boolean generated = generateQrImage(receiveAddress, amountEdit.getText().toString(), selectedIso);
+ if (!generated)
+ throw new RuntimeException("failed to generate qr image for address");
+ updateText();
+ });
+ }
+
+ private void copyText() {
+ BRClipboardManager.putClipboard(getContext(), mAddress.getText().toString());
+ showCopiedLayout(true);
+ }
+
+ private void toggleShareButtonsVisibility() {
+ if (shareButtonsShown) {
+ signalLayout.removeView(shareButtonsLayout);
+ shareButtonsShown = false;
+ } else {
+ signalLayout.addView(shareButtonsLayout, signalLayout.getChildCount());
+ shareButtonsShown = true;
+ }
+ }
+
+ @Override
+ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+
+ final ViewTreeObserver observer = signalLayout.getViewTreeObserver();
+ observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+ @Override
+ public void onGlobalLayout() {
+ if (observer.isAlive()) {
+ observer.removeOnGlobalLayoutListener(this);
+ }
+ BRAnimator.animateBackgroundDim(backgroundLayout, false);
+ BRAnimator.animateSignalSlide(signalLayout, false, null);
+ toggleShareButtonsVisibility();
+ }
+ });
+
+ BRExecutor.getInstance().forLightWeightBackgroundTasks().execute(new Runnable() {
+ @Override
+ public void run() {
+ boolean success = BRWalletManager.refreshAddress(getActivity());
+ if (!success) throw new RuntimeException("failed to retrieve address");
+
+ receiveAddress = BRSharedPrefs.getReceiveAddress(getActivity());
+
+ BRExecutor.getInstance().forMainThreadTasks().execute(new Runnable() {
+ @Override
+ public void run() {
+ mAddress.setText(receiveAddress);
+ boolean generated = generateQrImage(receiveAddress, "0", "LTC");
+ if (!generated)
+ throw new RuntimeException("failed to generate qr image for address");
+ }
+ });
+ }
+ });
+ }
+
+ private void handleClick(String key) {
+ if (key == null) {
+ Timber.d("timber: handleClick: key is null! ");
+ return;
+ }
+
+ if (key.isEmpty()) {
+ handleDeleteClick();
+ } else if (Character.isDigit(key.charAt(0))) {
+ handleDigitClick(Integer.parseInt(key.substring(0, 1)));
+ } else if (key.charAt(0) == '.') {
+ handleSeparatorClick();
+ }
+
+ boolean generated = generateQrImage(receiveAddress, amountEdit.getText().toString(), selectedIso);
+ if (!generated) throw new RuntimeException("failed to generate qr image for address");
+ }
+
+ private void handleDigitClick(Integer dig) {
+ String currAmount = amountBuilder.toString();
+ String iso = selectedIso;
+ if (new BigDecimal(currAmount.concat(String.valueOf(dig))).doubleValue()
+ <= BRExchange.getMaxAmount(getActivity(), iso).doubleValue()) {
+ //do not insert 0 if the balance is 0 now
+ if (currAmount.equalsIgnoreCase("0")) amountBuilder = new StringBuilder("");
+ if ((currAmount.contains(".") && (currAmount.length() - currAmount.indexOf(".") > BRCurrency.getMaxDecimalPlaces(iso))))
+ return;
+ amountBuilder.append(dig);
+ updateText();
+ }
+ }
+
+ private void handleSeparatorClick() {
+ String currAmount = amountBuilder.toString();
+ if (currAmount.contains(".") || BRCurrency.getMaxDecimalPlaces(selectedIso) == 0)
+ return;
+ amountBuilder.append(".");
+ updateText();
+ }
+
+ private void handleDeleteClick() {
+ String currAmount = amountBuilder.toString();
+ if (currAmount.length() > 0) {
+ amountBuilder.deleteCharAt(currAmount.length() - 1);
+ updateText();
+ }
+ }
+
+ private void updateText() {
+ if (getActivity() == null) return;
+ String tmpAmount = amountBuilder.toString();
+ amountEdit.setText(tmpAmount);
+ isoText.setText(BRCurrency.getSymbolByIso(getActivity(), selectedIso));
+ isoButton.setText(String.format("%s(%s)", BRCurrency.getCurrencyName(getActivity(), selectedIso), BRCurrency.getSymbolByIso(getActivity(), selectedIso)));
+ }
+
+ private void showKeyboard(boolean b) {
+ int curIndex = keyboardIndex;
+
+ if (!b) {
+ signalLayout.removeView(keyboardLayout);
+ } else {
+ if (signalLayout.indexOfChild(keyboardLayout) == -1)
+ signalLayout.addView(keyboardLayout, curIndex);
+ else
+ signalLayout.removeView(keyboardLayout);
+
+ }
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ signalLayout.scrollTo(5, 10);
+ }
+ }, 2000);
+
+ }
+
+ private boolean generateQrImage(String address, String strAmount, String iso) {
+ String amountArg = "";
+ if (strAmount != null && !strAmount.isEmpty()) {
+ BigDecimal bigAmount = new BigDecimal((Utils.isNullOrEmpty(strAmount) || strAmount.equalsIgnoreCase(".")) ? "0" : strAmount);
+ long amount = BRExchange.getSatoshisFromAmount(getActivity(), iso, bigAmount).longValue();
+ String am = new BigDecimal(amount).divide(new BigDecimal(100000000), 8, BRConstants.ROUNDING_MODE).toPlainString();
+ amountArg = "?amount=" + am;
+ }
+ return QRUtils.generateQR(getActivity(), "litecoin:" + address + amountArg, mQrImage);
+ }
+
+
+ private void removeCurrencySelector() {
+// showCurrencyList(false);
+ }
+
+ private void showShareButtons(boolean b) {
+ if (!b) {
+ signalLayout.removeView(shareButtonsLayout);
+ shareButton.setType(2);
+ } else {
+ signalLayout.addView(shareButtonsLayout, signalLayout.getChildCount() - 1);
+ shareButton.setType(3);
+ showCopiedLayout(false);
+ }
+ }
+
+
+ private void showCopiedLayout(boolean b) {
+ if (!b) {
+ signalLayout.removeView(copiedLayout);
+ copyCloseHandler.removeCallbacksAndMessages(null);
+ } else {
+ if (signalLayout.indexOfChild(copiedLayout) == -1) {
+ signalLayout.addView(copiedLayout, signalLayout.indexOfChild(shareButton));
+ showShareButtons(false);
+ shareButtonsShown = false;
+ copyCloseHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ signalLayout.removeView(copiedLayout);
+ }
+ }, 2000);
+ } else {
+ copyCloseHandler.removeCallbacksAndMessages(null);
+ signalLayout.removeView(copiedLayout);
+ }
+ }
+ }
+
+ private void showCurrencyList(boolean b) {
+ }
+
+ private void animateClose() {
+ BRAnimator.animateBackgroundDim(backgroundLayout, true);
+ BRAnimator.animateSignalSlide(signalLayout, true, new BRAnimator.OnSlideAnimationEnd() {
+ @Override
+ public void onAnimationEnd() {
+ close();
+ }
+ });
+ }
+
+ private void close() {
+ Activity activity = getActivity();
+ if (activity != null && !activity.isFinishing() && !activity.isDestroyed()) {
+ activity.getFragmentManager().popBackStack();
+ }
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentScanResult.java b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentScanResult.java
deleted file mode 100644
index c65451dfd..000000000
--- a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentScanResult.java
+++ /dev/null
@@ -1,595 +0,0 @@
-package com.breadwallet.presenter.fragments;
-
-import android.app.Activity;
-import android.app.Fragment;
-import android.os.Bundle;
-import android.os.Handler;
-import android.util.Log;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
-import android.widget.Button;
-import android.widget.ImageButton;
-import android.widget.RelativeLayout;
-import android.widget.TextView;
-import android.graphics.Typeface;
-
-import com.breadwallet.R;
-import com.breadwallet.BreadWalletApp;
-import com.breadwallet.presenter.activities.MainActivity;
-import com.breadwallet.tools.animation.BRAnimator;
-import com.breadwallet.tools.util.BRConstants;
-import com.breadwallet.tools.manager.SharedPreferencesManager;
-import com.breadwallet.tools.animation.SpringAnimator;
-
-import java.math.BigDecimal;
-import java.math.RoundingMode;
-import java.text.DecimalFormat;
-import java.text.DecimalFormatSymbols;
-import java.util.Currency;
-import java.util.Locale;
-import java.util.Objects;
-
-import static com.breadwallet.tools.util.BRConstants.CURRENT_UNIT_BITS;
-import static com.breadwallet.tools.util.BRStringFormatter.getNumberOfDecimalPlaces;
-
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 7/14/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-public class FragmentScanResult extends Fragment implements View.OnClickListener {
- private static final String TAG = FragmentScanResult.class.getName();
- private TextView scanResult;
- private RelativeLayout customKeyboardLayout;
- private TextView rightTextView;
- private TextView leftTextView;
- public static String address;
- //amount stuff
- private boolean isTextColorGrey = true;
- private ValueItem rightValue;
- private ValueItem leftValue;
- private int buttonCode = BRConstants.PAY_BUTTON;
- private boolean pressAvailable = true;
- private int unit = BRConstants.CURRENT_UNIT_BITS;
-
- public static FragmentScanResult instance;
- private String ISO;
- public double rate = -1;
-
- public static boolean isARequest = false;
-
- public FragmentScanResult() {
- instance = this;
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater,
- final ViewGroup container, Bundle savedInstanceState) {
- // The last two arguments ensure LayoutParams are inflated
- // properly.
- final View rootView = inflater.inflate(R.layout.fragment_scan_result, container, false);
- scanResult = (TextView) rootView.findViewById(R.id.scan_result);
- customKeyboardLayout = (RelativeLayout) rootView.findViewById(R.id.custom_keyboard_layout);
- rightTextView = (TextView) rootView.findViewById(R.id.right_textview);
- leftTextView = (TextView) rootView.findViewById(R.id.left_textview);
- TextView doubleArrow = (TextView) rootView.findViewById(R.id.double_arrow_text);
- rightValue = new ValueItem("0", true);
- leftValue = new ValueItem("0", false);
- /**
- * This mess is for the custom keyboard to be created after the soft keyboard is hidden
- * (if it was previously shown) to prevent the wrong position of the keyboard layout placement
- */
- customKeyboardLayout.getViewTreeObserver().addOnGlobalLayoutListener(
- new ViewTreeObserver.OnGlobalLayoutListener() {
- public void onGlobalLayout() {
- MainActivity app = (MainActivity) getActivity();
- if (app != null)
- if (!app.isSoftKeyboardShown()) {
- int[] locations = new int[2];
- customKeyboardLayout.getLocationOnScreen(locations);
- customKeyboardLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
- createCustomKeyboardButtons(locations[1]);
- }
- }
- });
- View.OnClickListener listener = new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- switchCurrencies();
- SpringAnimator.showAnimation(leftTextView);
- SpringAnimator.showAnimation(rightTextView);
- }
- };
- doubleArrow.setText(BRConstants.DOUBLE_ARROW);
- doubleArrow.setOnClickListener(listener);
- leftTextView.setOnClickListener(listener);
- rightTextView.setOnClickListener(listener);
- return rootView;
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- }
-
- @Override
- public void onResume() {
- if (!isARequest && (address == null || address.length() < 20))
- throw new NullPointerException("address is corrupted");
- Activity app = getActivity();
- if (app != null)
- unit = SharedPreferencesManager.getCurrencyUnit(app);
- updateRateAndISO();
- calculateAndPassValuesToFragment("0");
- scanResult.setText(isARequest ? "" : getString(R.string.to) + address);
-
- Log.e(TAG, "onResume: unit: " + unit);
- super.onResume();
- }
-
- @Override
- public void onPause() {
- super.onPause();
- resetKeyboard();
- Activity app = getActivity();
- if (app != null)
- ((BreadWalletApp) app.getApplication()).setLockerPayButton(BRConstants.LOCKER_BUTTON);
- isARequest = false;
- BRAnimator.hideScanResultFragment();
- }
-
- @Override
- public void onDestroyView() {
- super.onDestroyView();
- }
-
- private void createCustomKeyboardButtons(int y) {
- Activity app = getActivity();
- if (app == null) return;
- int availableWidth = MainActivity.screenParametersPoint.x;
- int availableHeight = MainActivity.screenParametersPoint.y;
- int spaceNeededForRest = availableHeight / 14;
- float gapRate = 0.2f;
- float gap = (availableWidth * gapRate);
- float interButtonGap = gap / 5;
- float buttonWidth = (availableWidth - gap) / 3;
- float buttonHeight = buttonWidth;
- float spaceNeeded = buttonHeight * 4 + gap;
- int buttonTextSize = 45;
- if (spaceNeeded > (availableHeight - (spaceNeededForRest + y))) {
- buttonHeight = ((availableHeight - (spaceNeededForRest + y)) - gap) / 4;
- buttonTextSize = (int) ((buttonHeight / 7));
- }
- int minimumHeight = (int) (buttonHeight * 4 + interButtonGap * 4);
- if (customKeyboardLayout == null) {
- customKeyboardLayout = (RelativeLayout) app.findViewById(R.id.custom_keyboard_layout);
- }
- customKeyboardLayout.setMinimumHeight(minimumHeight);
- int childCount = 12;
- for (int i = 0; i < childCount; i++) {
- Button b = new Button(app);
- b.setFilterTouchesWhenObscured(true);
- b.setWidth((int) buttonWidth);
- b.setHeight((int) buttonHeight);
- b.setTextSize(buttonTextSize);
- b.setTypeface(Typeface.create("sans-serif-thin", Typeface.NORMAL));
- //noinspection deprecation
- b.setTextColor(getResources().getColor(R.color.dark_blue));
- b.setBackgroundResource(R.drawable.button_regular_blue);
- b.setOnClickListener(this);
- b.setGravity(Gravity.CENTER);
- b.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY);
- ImageButton imageB = null;
- if (i < 9)
- b.setText(String.valueOf(i + 1));
- switch (i) {
- case 0:
- b.setX(interButtonGap / 2 + interButtonGap);
- break;
- case 1:
- b.setX(interButtonGap / 2 + interButtonGap * 2 + buttonWidth);
- break;
- case 2:
- b.setX(interButtonGap / 2 + interButtonGap * 3 + buttonWidth * 2);
- break;
- case 3:
- b.setX(interButtonGap / 2 + interButtonGap);
- b.setY(buttonHeight + interButtonGap);
- break;
- case 4:
- b.setX(interButtonGap / 2 + interButtonGap * 2 + buttonWidth);
- b.setY(buttonHeight + interButtonGap);
- break;
- case 5:
- b.setY(buttonHeight + interButtonGap);
- b.setX(interButtonGap / 2 + interButtonGap * 3 + buttonWidth * 2);
- break;
- case 6:
- b.setY(buttonHeight * 2 + interButtonGap * 2);
- b.setX(interButtonGap / 2 + interButtonGap);
- break;
- case 7:
- b.setX(interButtonGap / 2 + interButtonGap * 2 + buttonWidth);
- b.setY(buttonHeight * 2 + interButtonGap * 2);
- break;
- case 8:
- b.setX(interButtonGap / 2 + interButtonGap * 3 + buttonWidth * 2);
- b.setY(buttonHeight * 2 + interButtonGap * 2);
- break;
- case 9:
- b.setText(".");
- b.setY(buttonHeight * 3 + interButtonGap * 3);
- b.setX(interButtonGap / 2 + interButtonGap);
- break;
- case 10:
- b.setX(interButtonGap / 2 + interButtonGap * 2 + buttonWidth);
- b.setText("0");
- b.setY(buttonHeight * 3 + interButtonGap * 3);
- break;
- case 11:
- imageB = new ImageButton(app);
- imageB.setBackgroundResource(R.drawable.button_regular_blue);
- imageB.setImageResource(R.drawable.deletetoleft);
- imageB.setOnClickListener(this);
- imageB.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
- imageB.setLongClickable(true);
- imageB.setOnClickListener(this);
- imageB.setId(R.id.keyboard_back_button);
- //noinspection deprecation
- imageB.setX(interButtonGap / 2 + interButtonGap * 3 + buttonWidth * 2);
- imageB.setY(buttonHeight * 3 + interButtonGap * 3);
- imageB.setMinimumWidth((int) buttonWidth);
- imageB.setMinimumHeight((int) buttonHeight);
- break;
- }
- customKeyboardLayout.addView(imageB != null ? imageB : b);
- }
- }
-
- @Override
- public void onClick(View v) {
- String tmp;
- try {
- tmp = ((Button) v).getText().toString();
- } catch (ClassCastException ex) {
- tmp = "";
- }
- preConditions(tmp);
- }
-
- public void updateBothTextValues(String left, String right) {
- Log.e(TAG, "updateBothTextValues: " + left + " : " + right);
- if (ISO == null) updateRateAndISO();
- if (ISO == null) ISO = "USD";
- leftValue.value = left;
- rightValue.value = right;
- final String btcISO = "BTC";
-
- String formattedRightVal = getFormattedCurrencyStringForKeyboard(rightValue.isBitcoin ? btcISO : ISO, rightValue.value, true);
- String formattedLeftVal = getFormattedCurrencyStringForKeyboard(leftValue.isBitcoin ? btcISO : ISO, leftValue.value, false);
- Log.e(TAG, "formatted: " + formattedLeftVal + " : " + formattedRightVal);
-
- rightTextView.setText(formattedRightVal);
- leftTextView.setText(formattedLeftVal);
- }
-
- private String getCleanValue(String value) {
- StringBuilder builder = new StringBuilder();
- for (int i = 0; i < value.length(); i++) {
- char c = value.charAt(i);
- if (c == '.' || Character.isDigit(c)) builder.append(c);
- }
- return builder.toString();
- }
-
- private void updateRateAndISO() {
- Activity app = getActivity();
- if (app == null) return;
- ISO = SharedPreferencesManager.getIso(app);
- getOtherValue().iso = ISO;
- rate = SharedPreferencesManager.getRate(app);
- }
-
- public void preConditions(String tmp) {
- Activity app = getActivity();
- if (app == null) return;
- if (FragmentScanResult.isARequest) {
- buttonCode = BRConstants.REQUEST_BUTTON;
- } else {
- buttonCode = BRConstants.PAY_BUTTON;
- }
- switch (tmp) {
- case "":
- doBackSpace();
- break;
- case ".":
- insertSeparator();
- break;
- default:
- insertDigit(tmp);
- break;
- }
- }
-
- private void doBackSpace() {
- Activity app = getActivity();
- if (app == null) return;
- String amount = rightValue.value;
- int length = amount.length();
- if (length > 1) {
- calculateAndPassValuesToFragment(rightValue.value.substring(0, length - 1));
- } else {
- ((BreadWalletApp) app.getApplication()).setLockerPayButton(BRConstants.LOCKER_BUTTON);
- changeTextColor(2);
- calculateAndPassValuesToFragment("0");
- }
- }
-
- private void insertSeparator() {
- Activity app = getActivity();
- if (app == null) return;
- if (isTextColorGrey) {
- changeTextColor(1);
- ((BreadWalletApp) app.getApplication()).setLockerPayButton(buttonCode);
- }
- String amount = rightValue.value;
- int maxDigit = getMaxFractionDigits();
-
- if (!amount.contains(".") && maxDigit != 0)
- calculateAndPassValuesToFragment(amount + ".");
- }
-
- private void insertDigit(String tmp) {
- Activity app = getActivity();
- if (app == null) return;
- String amount = rightValue.value;
-
- int length = amount.length();
- if (isTextColorGrey) {
- changeTextColor(1);
- ((BreadWalletApp) app.getApplication()).setLockerPayButton(buttonCode);
- }
- if (isDigitInsertingLegal(tmp)) {
- if (length == 1 && amount.equals("0")) {
- calculateAndPassValuesToFragment(tmp);
- } else {
- calculateAndPassValuesToFragment(rightValue.value + tmp);
- }
- }
- }
-
- private boolean isDigitInsertingLegal(String tmp) {
- int maxDig = getMaxFractionDigits();
- long limit = 21000000000000L;
- if (unit == BRConstants.CURRENT_UNIT_MBITS)
- limit = 21000000000L;
- if (unit == BRConstants.CURRENT_UNIT_BITCOINS)
- limit = 21000000L;
-
- if (rightValue.isBitcoin) {
- maxDig = BRConstants.MAX_DIGITS_AFTER_SEPARATOR_BITS;
-
- if (unit == BRConstants.CURRENT_UNIT_MBITS)
- maxDig = BRConstants.MAX_DIGITS_AFTER_SEPARATOR_MBITS;
- if (unit == BRConstants.CURRENT_UNIT_BITCOINS)
- maxDig = BRConstants.MAX_DIGITS_AFTER_SEPARATOR_BITCOINS;
-
- }
- boolean isFractionStarted = rightValue.value.contains(".");
- int nrOfDecimals = getNumberOfDecimalPlaces(rightValue.value);
- if (isFractionStarted)
- return nrOfDecimals < maxDig;
-
- long l = 0;
- try {
- l = Long.valueOf(rightValue.value + tmp);
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- return l < limit;
- }
-
- private int getMaxFractionDigits() {
- try {
- Currency currency = Currency.getInstance(rightValue.iso);
- return currency.getDefaultFractionDigits();
- } catch (Exception e) {
- e.printStackTrace();
- return 2;
- }
- }
-
- /**
- * Sets the textColor of the amount TextView to black or grey
- *
- * @param color the color of the textView: 1 Black, 2 Grey.
- */
- private void changeTextColor(int color) {
- Activity app = getActivity();
- if (app == null) return;
- isTextColorGrey = color != 1;
- rightTextView.setTextColor((color == 1) ? app.getColor(R.color.black)
- : app.getColor(android.R.color.darker_gray));
- }
-
- public void resetKeyboard() {
- isTextColorGrey = true;
- rightValue.value = "0";
- leftValue.value = "0";
- }
-
- public void calculateAndPassValuesToFragment(String valuePassed) {
- String divideBy = "1000000";
- Log.e(TAG, "calculateAndPassValuesToFragment: valuePassed: " + valuePassed);
- if (unit == BRConstants.CURRENT_UNIT_MBITS) divideBy = "1000";
- if (unit == BRConstants.CURRENT_UNIT_BITCOINS) divideBy = "1";
- rightValue.value = valuePassed;
- BigDecimal rightValueObject = new BigDecimal(valuePassed);
- BigDecimal leftValueObject;
- BigDecimal theRate = new BigDecimal(rate);
-
- //from bits to other currency using rate
- if (theRate.intValue() > 0 && rightValueObject.doubleValue() != 0) {
- if (rightValue.isBitcoin) {
- leftValueObject = theRate.multiply(rightValueObject.divide(new BigDecimal(divideBy)));
- } else {
- //from other currency to bits using rate
- leftValueObject = rightValueObject.multiply(new BigDecimal(divideBy)).
- divide(theRate, 8, RoundingMode.HALF_UP);
- }
- } else {
- leftValueObject = new BigDecimal("0");
- }
-
- updateBothTextValues(leftValueObject.toString(), valuePassed);
- }
-
- public void switchCurrencies() {
- if (checkPressingAvailability()) {
- rightValue.value = getCleanValue(rightTextView.getText().toString());
- leftValue.value = getCleanValue(leftTextView.getText().toString());
-
- ValueItem tmp = rightValue;
- rightValue = leftValue;
- leftValue = tmp;
- updateBothTextValues(leftValue.value, rightValue.value);
- }
- }
-
- public boolean checkPressingAvailability() {
- if (pressAvailable) {
- pressAvailable = false;
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- pressAvailable = true;
- }
- }, 100);
- return true;
- } else {
- return false;
- }
- }
-
- public String getFormattedCurrencyStringForKeyboard(String isoCurrencyCode, String amount, boolean rightItem) {
- Log.e(TAG, "getFormattedCurrencyStringForKeyboard: amount:" + amount);
- Activity app = getActivity();
- if (amount == null || app == null) {
- Log.e(TAG, "getFormattedCurrencyStringForKeyboard: AMOUNT == null");
- return "0";
- }
-
- String multiplyBy = "100";
-
- if (unit == BRConstants.CURRENT_UNIT_MBITS) multiplyBy = "100000";
- if (unit == BRConstants.CURRENT_UNIT_BITCOINS) multiplyBy = "100000000";
-
- BigDecimal result;
-
- if (isoCurrencyCode.equals("BTC")) {
- result = new BigDecimal(amount).multiply(new BigDecimal(multiplyBy));
- } else {
- result = new BigDecimal(amount).multiply(new BigDecimal("100"));
- }
-
- DecimalFormat currencyFormat;
- result = result.divide(new BigDecimal("100"));
- currencyFormat = (DecimalFormat) DecimalFormat.getCurrencyInstance(Locale.getDefault());
- DecimalFormatSymbols decimalFormatSymbols;
- Currency currency;
- String symbol = null;
- decimalFormatSymbols = currencyFormat.getDecimalFormatSymbols();
- int decimalPoints = 0;
- if (Objects.equals(isoCurrencyCode, "BTC")) {
- String currencySymbolString = BRConstants.bitcoinLowercase;
- currencyFormat.setMinimumFractionDigits(0);
- switch (unit) {
- case CURRENT_UNIT_BITS:
- currencySymbolString = BRConstants.bitcoinLowercase;
- decimalPoints = 2;
- if (getNumberOfDecimalPlaces(result.toPlainString()) == 1)
- currencyFormat.setMinimumFractionDigits(1);
- break;
- case BRConstants.CURRENT_UNIT_MBITS:
- currencySymbolString = "m" + BRConstants.bitcoinUppercase;
- decimalPoints = 5;
- result = new BigDecimal(String.valueOf(result.doubleValue())).divide(new BigDecimal("1000"));
- break;
- case BRConstants.CURRENT_UNIT_BITCOINS:
- currencySymbolString = BRConstants.bitcoinUppercase;
- decimalPoints = 8;
- result = new BigDecimal(String.valueOf(result.doubleValue())).divide(new BigDecimal("1000000"));
- break;
- }
- symbol = currencySymbolString;
- } else {
- try {
- currency = Currency.getInstance(isoCurrencyCode);
- } catch (IllegalArgumentException e) {
- currency = Currency.getInstance(Locale.getDefault());
- }
- symbol = currency.getSymbol();
- decimalPoints = currency.getDefaultFractionDigits();
- }
- decimalFormatSymbols.setCurrencySymbol(symbol);
- currencyFormat.setMaximumFractionDigits(decimalPoints);
- int currNrOfDecimal = getNumberOfDecimalPlaces(amount);
- currencyFormat.setGroupingUsed(true);
- if (rightItem && amount.endsWith("."))
- currencyFormat.setDecimalSeparatorAlwaysShown(true);
- currencyFormat.setDecimalFormatSymbols(decimalFormatSymbols);
- currencyFormat.setNegativePrefix(decimalFormatSymbols.getCurrencySymbol() + "-");
- currencyFormat.setNegativeSuffix("");
- Log.e(TAG, "toPattern: " + currencyFormat.toPattern());
- currencyFormat.setMinimumFractionDigits(currNrOfDecimal > decimalPoints ? decimalPoints : currNrOfDecimal);
- return currencyFormat.format(result);
- }
-
- public ValueItem getBitcoinValue() {
- if (rightValue.isBitcoin) return rightValue;
- else return leftValue;
- }
-
- public ValueItem getOtherValue() {
- if (!rightValue.isBitcoin) return rightValue;
- else return leftValue;
- }
-
- public class ValueItem {
- public String value;
- public boolean isBitcoin;
- public String iso;
-
- public ValueItem(String value, boolean isBitcoin) {
- this.value = value;
- this.isBitcoin = isBitcoin;
- }
-
- }
-
-}
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentSend.kt b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentSend.kt
new file mode 100644
index 000000000..77107f361
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentSend.kt
@@ -0,0 +1,808 @@
+package com.breadwallet.presenter.fragments
+
+import android.app.Activity
+import android.content.res.Configuration
+import android.os.Bundle
+import android.os.Handler
+import android.view.KeyEvent
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.view.ViewTreeObserver.OnGlobalLayoutListener
+import android.view.animation.OvershootInterpolator
+import android.view.inputmethod.EditorInfo
+import android.widget.*
+import androidx.annotation.ColorRes
+import androidx.annotation.StringRes
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.constraintlayout.widget.ConstraintSet
+import androidx.core.text.trimmedLength
+import androidx.fragment.app.Fragment
+import androidx.lifecycle.lifecycleScope
+import androidx.transition.AutoTransition
+import androidx.transition.Transition
+import androidx.transition.TransitionManager
+import com.breadwallet.R
+import com.breadwallet.presenter.customviews.BRKeyboard
+import com.breadwallet.presenter.customviews.BRLinearLayoutWithCaret
+import com.breadwallet.presenter.entities.PaymentItem
+import com.breadwallet.tools.animation.BRAnimator
+import com.breadwallet.tools.animation.BRDialog
+import com.breadwallet.tools.animation.SlideDetector
+import com.breadwallet.tools.animation.SpringAnimator
+import com.breadwallet.tools.manager.*
+import com.breadwallet.tools.security.BRSender
+import com.breadwallet.tools.security.BitcoinUrlHandler
+import com.breadwallet.tools.threads.BRExecutor
+import com.breadwallet.tools.util.*
+import com.breadwallet.wallet.BRWalletManager
+import com.github.razir.progressbutton.bindProgressButton
+import com.github.razir.progressbutton.hideProgress
+import com.github.razir.progressbutton.showProgress
+import timber.log.Timber
+import java.math.BigDecimal
+import java.util.regex.Pattern
+
+class FragmentSend : Fragment() {
+ private lateinit var backgroundLayout: ScrollView
+ private lateinit var signalLayout: LinearLayout
+ private lateinit var keyboard: BRKeyboard
+ private lateinit var addressEdit: EditText
+ private lateinit var scan: Button
+ private lateinit var paste: Button
+ private lateinit var send: Button
+ private lateinit var donate: Button
+ private lateinit var commentEdit: EditText
+ private lateinit var amountBuilder: StringBuilder
+ private lateinit var isoText: TextView
+ private lateinit var amountEdit: EditText
+ private lateinit var balanceText: TextView
+ private lateinit var feeText: TextView
+ private lateinit var edit: ImageView
+ private var curBalance: Long = 0
+ private var selectedIso: String? = null
+ private lateinit var isoButton: Button
+ private var keyboardIndex = 0
+ private lateinit var keyboardLayout: LinearLayout
+ private lateinit var close: ImageButton
+ private lateinit var amountLayout: ConstraintLayout
+ private lateinit var feeLayout: BRLinearLayoutWithCaret
+ private var feeButtonsShown = false
+ private lateinit var feeDescription: TextView
+ private lateinit var warningText: TextView
+ private var amountLabelOn = true
+ private var ignoreCleanup = false
+
+ private lateinit var udDomainEdit: EditText
+ private lateinit var udLookupButton: Button
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?,
+ ): View? {
+ val rootView = inflater.inflate(R.layout.fragment_send, container, false)
+ backgroundLayout = rootView.findViewById(R.id.background_layout)
+ signalLayout = rootView.findViewById(R.id.signal_layout) as LinearLayout
+ keyboard = rootView.findViewById(R.id.keyboard) as BRKeyboard
+ keyboard.setBRButtonBackgroundResId(R.drawable.keyboard_white_button)
+ keyboard.setBRKeyboardColor(R.color.white)
+ isoText = rootView.findViewById(R.id.iso_text) as TextView
+ addressEdit = rootView.findViewById(R.id.address_edit) as EditText
+ scan = rootView.findViewById(R.id.scan) as Button
+ paste = rootView.findViewById(R.id.paste_button) as Button
+
+ udDomainEdit = rootView.findViewById(R.id.ud_address_edit)
+ udLookupButton = rootView.findViewById(R.id.ud_lookup_button)
+
+ send = rootView.findViewById(R.id.send_button) as Button
+ donate = rootView.findViewById(R.id.donate_button) as Button
+ commentEdit = rootView.findViewById(R.id.comment_edit) as EditText
+ amountEdit = rootView.findViewById(R.id.amount_edit) as EditText
+ balanceText = rootView.findViewById(R.id.balance_text) as TextView
+ feeText = rootView.findViewById(R.id.fee_text) as TextView
+ edit = rootView.findViewById(R.id.edit) as ImageView
+ isoButton = rootView.findViewById(R.id.iso_button) as Button
+ keyboardLayout = rootView.findViewById(R.id.keyboard_layout) as LinearLayout
+ amountLayout = rootView.findViewById(R.id.amount_layout) as ConstraintLayout
+ feeLayout = rootView.findViewById(R.id.fee_buttons_layout) as BRLinearLayoutWithCaret
+ feeDescription = rootView.findViewById(R.id.fee_description) as TextView
+ warningText = rootView.findViewById(R.id.warning_text) as TextView
+ close = rootView.findViewById(R.id.close_button) as ImageButton
+ selectedIso =
+ if (BRSharedPrefs.getPreferredLTC(context)) "LTC" else BRSharedPrefs.getIso(context)
+ amountBuilder = StringBuilder(0)
+ setListeners()
+ isoText.text = getString(R.string.Send_amountLabel)
+ isoText.textSize = 18f
+ isoText.setTextColor(requireContext().getColor(R.color.light_gray))
+ isoText.requestLayout()
+ signalLayout.setOnTouchListener(SlideDetector(signalLayout) { animateClose() })
+ AnalyticsManager.logCustomEvent(BRConstants._20191105_VSC)
+ setupFeesSelector(rootView)
+ showFeeSelectionButtons(feeButtonsShown)
+ edit.setOnClickListener {
+ feeButtonsShown = !feeButtonsShown
+ showFeeSelectionButtons(feeButtonsShown)
+ }
+ keyboardIndex = signalLayout.indexOfChild(keyboardLayout)
+ // TODO: all views are using the layout of this button. Views should be refactored without it
+ // Hiding until layouts are built.
+ val faq = rootView.findViewById(R.id.faq_button) as ImageButton
+ showKeyboard(false)
+ signalLayout.layoutTransition = BRAnimator.getDefaultTransition()
+
+ return rootView
+ }
+
+ override fun onActivityCreated(savedInstanceState: Bundle?) {
+ super.onActivityCreated(savedInstanceState)
+ bindProgressButton(udLookupButton)
+ }
+
+ private fun setupFeesSelector(rootView: View) {
+ val feesSegment = rootView.findViewById(R.id.fees_segment)
+ feesSegment.setOnCheckedChangeListener { _, checkedId -> onFeeTypeSelected(checkedId) }
+ onFeeTypeSelected(R.id.regular_fee_but)
+ }
+
+ private fun onFeeTypeSelected(checkedId: Int) {
+ val feeManager = FeeManager.getInstance()
+ when (checkedId) {
+ R.id.regular_fee_but -> {
+ feeManager.setFeeType(FeeManager.REGULAR)
+ BRWalletManager.getInstance().setFeePerKb(feeManager.fees.regular)
+ setFeeInformation(R.string.FeeSelector_regularTime, 0, 0, View.GONE)
+ }
+ R.id.economy_fee_but -> {
+ feeManager.setFeeType(FeeManager.ECONOMY)
+ BRWalletManager.getInstance().setFeePerKb(feeManager.fees.economy)
+ setFeeInformation(
+ R.string.FeeSelector_economyTime,
+ R.string.FeeSelector_economyWarning,
+ R.color.red_text,
+ View.VISIBLE,
+ )
+ }
+ R.id.luxury_fee_but -> {
+ feeManager.setFeeType(FeeManager.LUXURY)
+ BRWalletManager.getInstance().setFeePerKb(feeManager.fees.luxury)
+ setFeeInformation(
+ R.string.FeeSelector_luxuryTime,
+ R.string.FeeSelector_luxuryMessage,
+ R.color.light_gray,
+ View.VISIBLE,
+ )
+ }
+ else -> {
+ }
+ }
+ updateText()
+ }
+
+ private fun setFeeInformation(
+ @StringRes deliveryTime: Int,
+ @StringRes warningStringId: Int,
+ @ColorRes warningColorId: Int,
+ visibility: Int,
+ ) {
+ feeDescription.text =
+ getString(R.string.FeeSelector_estimatedDeliver, getString(deliveryTime))
+ if (warningStringId != 0) {
+ warningText.setText(warningStringId)
+ }
+ if (warningColorId != 0) {
+ warningText.setTextColor(resources.getColor(warningColorId, null))
+ }
+ warningText.visibility = visibility
+ }
+
+ private fun setListeners() {
+ amountEdit.setOnClickListener {
+ showKeyboard(true)
+ if (amountLabelOn) { // only first time
+ amountLabelOn = false
+ amountEdit.hint = "0"
+ amountEdit.textSize = 24f
+ balanceText.visibility = View.VISIBLE
+ feeText.visibility = View.VISIBLE
+ edit.visibility = View.VISIBLE
+ isoText.setTextColor(requireContext().getColor(R.color.almost_black))
+ isoText.text = BRCurrency.getSymbolByIso(activity, selectedIso)
+ isoText.textSize = 28f
+ val scaleX = amountEdit.scaleX
+ amountEdit.scaleX = 0f
+ val tr = AutoTransition()
+ tr.interpolator = OvershootInterpolator()
+ tr.addListener(
+ object : Transition.TransitionListener {
+ override fun onTransitionStart(transition: Transition) {}
+
+ override fun onTransitionEnd(transition: Transition) {
+ amountEdit.requestLayout()
+ amountEdit.animate().setDuration(100).scaleX(scaleX)
+ }
+
+ override fun onTransitionCancel(transition: Transition) {}
+
+ override fun onTransitionPause(transition: Transition) {}
+
+ override fun onTransitionResume(transition: Transition) {}
+ },
+ )
+ val set = ConstraintSet()
+ set.clone(amountLayout)
+ TransitionManager.beginDelayedTransition(amountLayout, tr)
+ val px4 = Utils.getPixelsFromDps(context, 4)
+ set.connect(
+ balanceText.id,
+ ConstraintSet.TOP,
+ isoText.id,
+ ConstraintSet.BOTTOM,
+ px4,
+ )
+ set.connect(
+ feeText.id,
+ ConstraintSet.TOP,
+ balanceText.id,
+ ConstraintSet.BOTTOM,
+ px4,
+ )
+ set.connect(
+ feeText.id,
+ ConstraintSet.BOTTOM,
+ ConstraintSet.PARENT_ID,
+ ConstraintSet.BOTTOM,
+ px4,
+ )
+ set.connect(
+ isoText.id,
+ ConstraintSet.TOP,
+ ConstraintSet.PARENT_ID,
+ ConstraintSet.TOP,
+ px4,
+ )
+ set.connect(isoText.id, ConstraintSet.BOTTOM, -1, ConstraintSet.TOP, -1)
+ set.applyTo(amountLayout)
+ }
+ }
+
+ // needed to fix the overlap bug
+ commentEdit.setOnKeyListener(
+ View.OnKeyListener { v, keyCode, event ->
+ if (event.action == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_ENTER) {
+ amountLayout.requestLayout()
+ return@OnKeyListener true
+ }
+ false
+ },
+ )
+ paste.setOnClickListener(
+ View.OnClickListener {
+ if (!BRAnimator.isClickAllowed()) return@OnClickListener
+ val bitcoinUrl = BRClipboardManager.getClipboard(activity)
+ if (Utils.isNullOrEmpty(bitcoinUrl) || !isInputValid(bitcoinUrl)) {
+ showClipboardError()
+ return@OnClickListener
+ }
+ val obj = BitcoinUrlHandler.getRequestFromString(bitcoinUrl)
+ if (obj?.address == null) {
+ showClipboardError()
+ return@OnClickListener
+ }
+ val address = obj.address
+ val wm = BRWalletManager.getInstance()
+ if (BRWalletManager.validateAddress(address)) {
+ val app: Activity? = activity
+ if (app == null) {
+ Timber.e("timber:paste onClick: app is null")
+ return@OnClickListener
+ }
+ BRExecutor.getInstance().forLightWeightBackgroundTasks().execute {
+ if (wm.addressContainedInWallet(address)) {
+ app.runOnUiThread(
+ Runnable {
+ BRDialog.showCustomDialog(
+ requireActivity(),
+ "",
+ resources.getString(R.string.Send_containsAddress),
+ resources.getString(R.string.AccessibilityLabels_close),
+ null,
+ { brDialogView -> brDialogView.dismiss() },
+ null,
+ null,
+ 0,
+ )
+ BRClipboardManager.putClipboard(activity, "")
+ },
+ )
+ } else if (wm.addressIsUsed(address)) {
+ app.runOnUiThread(
+ Runnable {
+ BRDialog.showCustomDialog(
+ requireActivity(),
+ getString(R.string.Send_UsedAddress_firstLine),
+ getString(R.string.Send_UsedAddress_secondLIne),
+ "Ignore",
+ "Cancel",
+ { brDialogView ->
+ brDialogView.dismiss()
+ addressEdit.setText(address)
+ },
+ { brDialogView -> brDialogView.dismiss() },
+ null,
+ 0,
+ )
+ },
+ )
+ } else {
+ app.runOnUiThread(Runnable { addressEdit.setText(address) })
+ }
+ }
+ } else {
+ showClipboardError()
+ }
+ },
+ )
+ isoButton.setOnClickListener {
+ selectedIso =
+ if (selectedIso.equals(BRSharedPrefs.getIso(context), ignoreCase = true)) {
+ "LTC"
+ } else {
+ BRSharedPrefs.getIso(context)
+ }
+ updateText()
+ }
+ scan.setOnClickListener(
+ View.OnClickListener {
+ if (!BRAnimator.isClickAllowed()) return@OnClickListener
+ saveMetaData()
+ BRAnimator.openScanner(activity, BRConstants.SCANNER_REQUEST)
+ },
+ )
+
+ udLookupButton.setOnClickListener {
+ // Disable the button until the domain string is at least 4 chars long (e.g a.zil)
+ if (udDomainEdit.text.trimmedLength() < 4) return@setOnClickListener
+ lifecycleScope.executeAsyncTask(
+ onPreExecute = {
+ udLookupButton.showProgress {
+ buttonText = null
+ progressColorRes = R.color.litecoin_litewallet_blue
+ }
+ udLookupButton.isEnabled = false
+ addressEdit.text = null
+ AnalyticsManager.logCustomEventWithParams(
+ BRConstants._20201121_SIL,
+ Bundle().apply {
+ putLong(
+ BRConstants.START_TIME,
+ System.currentTimeMillis(),
+ )
+ },
+ )
+ },
+ doInBackground = { UDResolution().resolve(udDomainEdit.text.trim().toString()) },
+ onPostExecute = {
+ if (it.error == null) {
+ AnalyticsManager.logCustomEventWithParams(
+ BRConstants._20201121_DRIA,
+ Bundle().apply {
+ putLong(
+ BRConstants.SUCCESS_TIME,
+ System.currentTimeMillis(),
+ )
+ },
+ )
+ addressEdit.setText(it.address)
+ BRAnimator.showBreadSignal(
+ requireActivity(),
+ getString(R.string.Send_UnstoppableDomains_domainResolved),
+ null,
+ R.drawable.ic_check_mark_white,
+ null,
+ )
+ } else {
+ AnalyticsManager.logCustomEventWithParams(
+ BRConstants._20201121_FRIA,
+ Bundle().apply {
+ putLong(BRConstants.FAILURE_TIME, System.currentTimeMillis())
+ putString(BRConstants.ERROR, it.error.localizedMessage)
+ },
+ )
+ Timber.d(it.error)
+ }
+ udLookupButton.isEnabled = true
+ udLookupButton.hideProgress(R.string.Send_UnstoppableDomains_lookup)
+ },
+ )
+ }
+
+ send.setOnClickListener(
+ View.OnClickListener {
+ if (!BRAnimator.isClickAllowed()) {
+ return@OnClickListener
+ }
+ var allFilled = true
+ val address = addressEdit.text.toString()
+ val amountStr = amountBuilder.toString()
+ val iso = selectedIso
+ val comment = commentEdit.text.toString()
+
+ // get amount in satoshis from any isos
+ val bigAmount = BigDecimal(if (Utils.isNullOrEmpty(amountStr)) "0" else amountStr)
+ val satoshiAmount = BRExchange.getSatoshisFromAmount(activity, iso, bigAmount)
+ if (address.isEmpty() || !BRWalletManager.validateAddress(address)) {
+ allFilled = false
+ SpringAnimator.failShakeAnimation(activity, addressEdit)
+ }
+ if (amountStr.isEmpty()) {
+ allFilled = false
+ SpringAnimator.failShakeAnimation(activity, amountEdit)
+ }
+ if (satoshiAmount.toLong() > BRWalletManager.getInstance().getBalance(activity)) {
+ SpringAnimator.failShakeAnimation(activity, balanceText)
+ SpringAnimator.failShakeAnimation(activity, feeText)
+ }
+ if (allFilled) {
+ BRSender.getInstance().sendTransaction(
+ context,
+ PaymentItem(
+ arrayOf(address),
+ null,
+ satoshiAmount.toLong(),
+ null,
+ false,
+ comment,
+ ),
+ )
+ AnalyticsManager.logCustomEvent(BRConstants._20191105_DSL)
+ BRSharedPrefs.incrementSendTransactionCount(context)
+ }
+ },
+ )
+ donate.setOnClickListener(
+ View.OnClickListener {
+ if (!BRAnimator.isClickAllowed()) {
+ return@OnClickListener
+ }
+ BRAnimator.showDynamicDonationFragment(requireActivity())
+ },
+ )
+ backgroundLayout.setOnClickListener(
+ View.OnClickListener {
+ if (!BRAnimator.isClickAllowed()) return@OnClickListener
+ animateClose()
+ },
+ )
+ close.setOnClickListener {
+ animateClose()
+ }
+ addressEdit.setOnEditorActionListener { _, actionId, event ->
+ if (event != null && event.keyCode == KeyEvent.KEYCODE_ENTER || actionId == EditorInfo.IME_ACTION_DONE || actionId == EditorInfo.IME_ACTION_NEXT) {
+ Utils.hideKeyboard(activity)
+ Handler().postDelayed({ showKeyboard(true) }, 500)
+ }
+ false
+ }
+ keyboard.addOnInsertListener { key -> handleClick(key) }
+ }
+
+ private fun showKeyboard(b: Boolean) {
+ val curIndex = keyboardIndex
+ if (!b) {
+ signalLayout.removeView(keyboardLayout)
+ } else {
+ Utils.hideKeyboard(activity)
+ if (signalLayout.indexOfChild(keyboardLayout) == -1) {
+ signalLayout.addView(
+ keyboardLayout,
+ curIndex,
+ )
+ } else {
+ signalLayout.removeView(keyboardLayout)
+ }
+ }
+ }
+
+ private fun showClipboardError() {
+ BRDialog.showCustomDialog(
+ requireActivity(),
+ getString(R.string.Send_emptyPasteboard),
+ resources.getString(R.string.Send_invalidAddressTitle),
+ getString(R.string.AccessibilityLabels_close),
+ null,
+ { brDialogView -> brDialogView.dismiss() },
+ null,
+ null,
+ 0,
+ )
+ BRClipboardManager.putClipboard(activity, "")
+ }
+
+ override fun onViewCreated(
+ view: View,
+ savedInstanceState: Bundle?,
+ ) {
+ super.onViewCreated(view, savedInstanceState)
+ val observer = signalLayout.viewTreeObserver
+ observer.addOnGlobalLayoutListener(
+ object : OnGlobalLayoutListener {
+ override fun onGlobalLayout() {
+ if (observer.isAlive) {
+ observer.removeOnGlobalLayoutListener(this)
+ }
+ BRAnimator.animateBackgroundDim(backgroundLayout, false)
+ BRAnimator.animateSignalSlide(signalLayout, false) {
+ val bundle = arguments
+ if (bundle?.getString("url") != null) setUrl(bundle.getString("url"))
+ }
+ }
+ },
+ )
+ }
+
+ override fun onStop() {
+ super.onStop()
+ FeeManager.getInstance().resetFeeType()
+ }
+
+ override fun onResume() {
+ super.onResume()
+ loadMetaData()
+ }
+
+ override fun onPause() {
+ super.onPause()
+ Utils.hideKeyboard(activity)
+ if (!ignoreCleanup) {
+ savedIso = null
+ savedAmount = null
+ savedMemo = null
+ }
+ }
+
+ private fun handleClick(key: String?) {
+ if (key == null) {
+ Timber.d("timber: handleClick: key is null! ")
+ return
+ }
+ when {
+ key.isEmpty() -> {
+ handleDeleteClick()
+ }
+ Character.isDigit(key[0]) -> {
+ handleDigitClick(key.substring(0, 1).toInt())
+ }
+ key[0] == '.' -> {
+ handleSeparatorClick()
+ }
+ }
+ }
+
+ private fun handleDigitClick(dig: Int) {
+ val currAmount = amountBuilder.toString()
+ val iso = selectedIso
+ if (BigDecimal(currAmount + dig.toString()).toDouble()
+ <= BRExchange.getMaxAmount(activity, iso).toDouble()
+ ) {
+ // do not insert 0 if the balance is 0 now
+ if (currAmount.equals("0", ignoreCase = true)) amountBuilder = StringBuilder("")
+ if (currAmount.contains(".") && currAmount.length - currAmount.indexOf(".") >
+ BRCurrency.getMaxDecimalPlaces(
+ iso,
+ )
+ ) {
+ return
+ }
+ amountBuilder.append(dig)
+ updateText()
+ }
+ }
+
+ private fun handleSeparatorClick() {
+ val currAmount = amountBuilder.toString()
+ if (currAmount.contains(".") || BRCurrency.getMaxDecimalPlaces(selectedIso) == 0) return
+ amountBuilder.append(".")
+ updateText()
+ }
+
+ private fun handleDeleteClick() {
+ val currAmount = amountBuilder.toString()
+ if (currAmount.isNotEmpty()) {
+ amountBuilder.deleteCharAt(currAmount.length - 1)
+ updateText()
+ }
+ }
+
+ private fun updateText() {
+ if (activity == null) return
+ val tmpAmount = amountBuilder.toString()
+ setAmount()
+ val iso = selectedIso
+ val currencySymbol = BRCurrency.getSymbolByIso(activity, selectedIso)
+ curBalance = BRWalletManager.getInstance().getBalance(activity)
+ if (!amountLabelOn) isoText.text = currencySymbol
+ isoButton.text =
+ String.format(
+ "%s(%s)",
+ BRCurrency.getCurrencyName(activity, selectedIso),
+ currencySymbol,
+ )
+ // Balance depending on ISO
+ val satoshis =
+ if (Utils.isNullOrEmpty(tmpAmount) ||
+ tmpAmount.equals(
+ ".",
+ ignoreCase = true,
+ )
+ ) {
+ 0
+ } else if (selectedIso.equals("btc", ignoreCase = true)) {
+ BRExchange.getSatoshisForBitcoin(
+ activity,
+ BigDecimal(tmpAmount),
+ ).toLong()
+ } else {
+ BRExchange.getSatoshisFromAmount(
+ activity,
+ selectedIso,
+ BigDecimal(tmpAmount),
+ ).toLong()
+ }
+ val balanceForISO = BRExchange.getAmountFromSatoshis(activity, iso, BigDecimal(curBalance))
+ Timber.d("timber: updateText: balanceForISO: %s", balanceForISO)
+
+ // formattedBalance
+ val formattedBalance = BRCurrency.getFormattedCurrencyString(activity, iso, balanceForISO)
+ // Balance depending on ISO
+ var fee: Long
+ if (satoshis == 0L) {
+ fee = 0
+ } else {
+ fee = BRWalletManager.getInstance().feeForTransactionAmount(satoshis).toLong()
+ if (fee == 0L) {
+ Timber.i("timber: updateText: fee is 0, trying the estimate")
+ fee =
+ BRWalletManager.getInstance()
+ .feeForTransaction(addressEdit.text.toString(), satoshis).toLong()
+ }
+ }
+ val feeForISO =
+ BRExchange.getAmountFromSatoshis(
+ activity,
+ iso,
+ BigDecimal(if (curBalance == 0L) 0 else fee),
+ )
+ Timber.d("timber: updateText: feeForISO: %s", feeForISO)
+ // formattedBalance
+ val aproxFee = BRCurrency.getFormattedCurrencyString(activity, iso, feeForISO)
+ Timber.d("timber: updateText: aproxFee: %s", aproxFee)
+ if (BigDecimal(
+ if (tmpAmount.isEmpty() ||
+ tmpAmount.equals(
+ ".",
+ ignoreCase = true,
+ )
+ ) {
+ "0"
+ } else {
+ tmpAmount
+ },
+ ).toDouble() > balanceForISO.toDouble()
+ ) {
+ balanceText.setTextColor(requireContext().getColor(R.color.warning_color))
+ feeText.setTextColor(requireContext().getColor(R.color.warning_color))
+ amountEdit.setTextColor(requireContext().getColor(R.color.warning_color))
+ if (!amountLabelOn) isoText.setTextColor(requireContext().getColor(R.color.warning_color))
+ } else {
+ balanceText.setTextColor(requireContext().getColor(R.color.light_gray))
+ feeText.setTextColor(requireContext().getColor(R.color.light_gray))
+ amountEdit.setTextColor(requireContext().getColor(R.color.almost_black))
+ if (!amountLabelOn) isoText.setTextColor(requireContext().getColor(R.color.almost_black))
+ }
+ balanceText.text = getString(R.string.Send_balance, formattedBalance)
+ feeText.text = String.format(getString(R.string.Send_fee), aproxFee)
+ donate.text = getString(R.string.Donate_title, currencySymbol)
+ donate.isEnabled = curBalance >= BRConstants.DONATION_AMOUNT * 2
+ amountLayout.requestLayout()
+ }
+
+ fun setUrl(url: String?) {
+ val obj = BitcoinUrlHandler.getRequestFromString(url) ?: return
+ if (obj.address != null) {
+ addressEdit.setText(obj.address.trim { it <= ' ' })
+ }
+ if (obj.message != null) {
+ commentEdit.setText(obj.message)
+ }
+ if (obj.amount != null) {
+ val iso = selectedIso
+ val satoshiAmount = BigDecimal(obj.amount).multiply(BigDecimal(100000000))
+ amountBuilder =
+ StringBuilder(
+ BRExchange.getAmountFromSatoshis(activity, iso, satoshiAmount).toPlainString(),
+ )
+ updateText()
+ }
+ }
+
+ private fun showFeeSelectionButtons(b: Boolean) {
+ if (!b) {
+ signalLayout.removeView(feeLayout)
+ } else {
+ signalLayout.addView(feeLayout, signalLayout.indexOfChild(amountLayout) + 1)
+ }
+ }
+
+ private fun setAmount() {
+ val tmpAmount = amountBuilder.toString()
+ var divider = tmpAmount.length
+ if (tmpAmount.contains(".")) {
+ divider = tmpAmount.indexOf(".")
+ }
+ val newAmount = StringBuilder()
+ for (i in tmpAmount.indices) {
+ newAmount.append(tmpAmount[i])
+ if (divider > 3 && divider - 1 != i && divider > i && (divider - i - 1) % 3 == 0) {
+ newAmount.append(",")
+ }
+ }
+ amountEdit.setText(newAmount.toString())
+ }
+
+ private fun isInputValid(input: String): Boolean {
+ return Pattern.matches("[a-zA-Z0-9]*", input)
+ }
+
+ // from the link above
+ override fun onConfigurationChanged(newConfig: Configuration) {
+ super.onConfigurationChanged(newConfig)
+
+ // Checks whether a hardware keyboard is available
+ if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) {
+ Timber.d("timber: onConfigurationChanged: hidden")
+ showKeyboard(true)
+ } else if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES) {
+ Timber.d("timber: onConfigurationChanged: shown")
+ showKeyboard(false)
+ }
+ }
+
+ private fun saveMetaData() {
+ if (commentEdit.text.toString().isNotEmpty()) savedMemo = commentEdit.text.toString()
+ if (amountBuilder.toString().isNotEmpty()) savedAmount = amountBuilder.toString()
+ savedIso = selectedIso
+ ignoreCleanup = true
+ }
+
+ private fun loadMetaData() {
+ ignoreCleanup = false
+ if (!Utils.isNullOrEmpty(savedMemo)) commentEdit.setText(savedMemo)
+ if (!Utils.isNullOrEmpty(savedIso)) selectedIso = savedIso
+ if (!Utils.isNullOrEmpty(savedAmount)) {
+ amountBuilder = StringBuilder(savedAmount!!)
+ Handler().postDelayed({
+ amountEdit.performClick()
+ updateText()
+ }, 500)
+ }
+ }
+
+ private fun animateClose() {
+ BRAnimator.animateBackgroundDim(backgroundLayout, true)
+ BRAnimator.animateSignalSlide(signalLayout, true) { close() }
+ }
+
+ private fun close() {
+ if (activity != null && activity?.isFinishing != true) {
+ activity?.onBackPressed()
+ }
+ }
+
+ companion object {
+ private var savedMemo: String? = null
+ private var savedIso: String? = null
+ private var savedAmount: String? = null
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentSettings.java b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentSettings.java
deleted file mode 100644
index d5ae9fc60..000000000
--- a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentSettings.java
+++ /dev/null
@@ -1,209 +0,0 @@
-package com.breadwallet.presenter.fragments;
-
-import android.Manifest;
-import android.app.Fragment;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.pm.PackageManager;
-import android.hardware.fingerprint.FingerprintManager;
-import android.os.Bundle;
-import android.support.v4.app.ActivityCompat;
-import android.support.v7.app.AlertDialog;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.RelativeLayout;
-import android.widget.TextView;
-
-import com.breadwallet.R;
-import com.breadwallet.BreadWalletApp;
-import com.breadwallet.presenter.activities.MainActivity;
-import com.breadwallet.tools.animation.BRAnimator;
-import com.breadwallet.tools.security.KeyStoreManager;
-import com.breadwallet.tools.security.PostAuthenticationProcessor;
-import com.breadwallet.tools.util.BRConstants;
-import com.breadwallet.tools.util.BRStringFormatter;
-import com.breadwallet.tools.manager.CurrencyManager;
-import com.breadwallet.tools.manager.SharedPreferencesManager;
-import com.breadwallet.tools.adapter.CurrencyListAdapter;
-import com.breadwallet.tools.adapter.MiddleViewAdapter;
-import com.breadwallet.tools.security.PassCodeManager;
-import com.breadwallet.wallet.BRPeerManager;
-import com.breadwallet.wallet.BRWalletManager;
-import com.platform.APIClient;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 6/29/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-public class FragmentSettings extends Fragment {
- private static final String TAG = FragmentSettings.class.getName();
- private MainActivity app;
- private FragmentSettings fragmentSettings;
-
- @Override
- public View onCreateView(LayoutInflater inflater,
- ViewGroup container, Bundle savedInstanceState) {
- // The last two arguments ensure LayoutParams are inflated
- // properly.
-
- View rootView = inflater.inflate(
- R.layout.fragment_settings, container, false);
-
- app = MainActivity.app;
- fragmentSettings = this;
- initList();
- RelativeLayout about = (RelativeLayout) rootView.findViewById(R.id.about);
- TextView currencyName = (TextView) rootView.findViewById(R.id.three_letters_currency);
- RelativeLayout changePassword = (RelativeLayout) rootView.findViewById(R.id.change_password);
- final String tmp = SharedPreferencesManager.getIso(getActivity());
-// Log.e(TAG, "Tmp 3 letters: " + tmp);
- currencyName.setText(tmp);
- RelativeLayout localCurrency = (RelativeLayout) rootView.findViewById(R.id.local_currency);
- RelativeLayout recoveryPhrase = (RelativeLayout) rootView.findViewById(R.id.recovery_phrase);
- RelativeLayout startRecoveryWallet = (RelativeLayout) rootView.findViewById(R.id.start_recovery_wallet);
- RelativeLayout fingerprintLimit = (RelativeLayout) rootView.findViewById(R.id.fingerprint_limit);
- RelativeLayout earlyAccess = (RelativeLayout) rootView.findViewById(R.id.early_access);
- RelativeLayout line5 = (RelativeLayout) rootView.findViewById(R.id.settings_line_5);
- TextView theLimit = (TextView) rootView.findViewById(R.id.fingerprint_limit_text);
- RelativeLayout rescan = (RelativeLayout) rootView.findViewById(R.id.rescan_blockchain);
-
-
- theLimit.setText(BRStringFormatter.getFormattedCurrencyString("BTC", PassCodeManager.getInstance().getLimit(getActivity())));
- FingerprintManager mFingerprintManager;
- mFingerprintManager = (FingerprintManager) getActivity().getSystemService(Context.FINGERPRINT_SERVICE);
- boolean useFingerPrint;
- useFingerPrint = ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.USE_FINGERPRINT)
- == PackageManager.PERMISSION_GRANTED && mFingerprintManager.isHardwareDetected() && mFingerprintManager.hasEnrolledFingerprints();
-
- if (!useFingerPrint) {
- fingerprintLimit.setVisibility(View.GONE);
- line5.setVisibility(View.GONE);
- }
-
- fingerprintLimit.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (BRAnimator.checkTheMultipressingAvailability()) {
- ((BreadWalletApp) getActivity().getApplicationContext()).promptForAuthentication(getActivity(),
- BRConstants.AUTH_FOR_LIMIT, null, null, null, null, false);
- }
- }
- });
-
- startRecoveryWallet.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (BRAnimator.checkTheMultipressingAvailability()) {
- BRAnimator.pressWipeWallet(app, new FragmentWipeWallet());
- app.activityButtonsEnable(false);
- }
- }
- });
- recoveryPhrase.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- BRWalletManager.getInstance(getActivity()).animateSavePhraseFlow();
- }
- });
- about.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (BRAnimator.checkTheMultipressingAvailability()) {
- BRAnimator.animateSlideToLeft(app, new FragmentAbout(), fragmentSettings);
- }
- }
- });
- localCurrency.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (BRAnimator.checkTheMultipressingAvailability()) {
- BRAnimator.animateSlideToLeft(app, new FragmentCurrency(), fragmentSettings);
- }
- }
- });
- changePassword.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (BRAnimator.checkTheMultipressingAvailability()) {
- final android.app.FragmentManager fm = getActivity().getFragmentManager();
- new PasswordDialogFragment().show(fm, PasswordDialogFragment.class.getName());
- }
- }
- }
-
- );
-
- rescan.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (BRAnimator.checkTheMultipressingAvailability()) {
- new Thread(new Runnable() {
- @Override
- public void run() {
- BRAnimator.goToMainActivity(fragmentSettings);
- BRPeerManager.getInstance(getActivity()).rescan();
- SharedPreferencesManager.putStartHeight(getActivity(), BRPeerManager.getCurrentBlockHeight());
- }
- }).start();
- }
-
- }
- }
-
- );
- //keep it hidden until finished
- earlyAccess.setVisibility(View.GONE);
- rootView.findViewById(R.id.early_access_separator).setVisibility(View.GONE);
- rootView.findViewById(R.id.early_access_separator2).setVisibility(View.GONE);
-
- earlyAccess.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (BRAnimator.checkTheMultipressingAvailability()) {
- BRAnimator.animateSlideToLeft(app, new FragmentEarlyAccess(), fragmentSettings);
- }
- }
- });
-
- return rootView;
- }
-
- @Override
- public void onResume() {
- super.onResume();
- MiddleViewAdapter.resetMiddleView(getActivity(), null);
- }
-
- @Override
- public void onPause() {
- super.onPause();
- }
-
- private void initList() {
- CurrencyListAdapter.currencyListAdapter = CurrencyManager.getInstance(getActivity()).getCurrencyAdapterIfReady();
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentSettingsAll.java b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentSettingsAll.java
deleted file mode 100644
index 4008c67aa..000000000
--- a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentSettingsAll.java
+++ /dev/null
@@ -1,124 +0,0 @@
-package com.breadwallet.presenter.fragments;
-
-import android.app.Activity;
-import android.app.Fragment;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ListView;
-import android.widget.RelativeLayout;
-
-import com.breadwallet.R;
-import com.breadwallet.presenter.activities.MainActivity;
-import com.breadwallet.presenter.entities.TransactionListItem;
-import com.breadwallet.tools.adapter.TransactionListAdapter;
-import com.breadwallet.tools.animation.BRAnimator;
-import com.breadwallet.tools.adapter.MiddleViewAdapter;
-import com.breadwallet.wallet.BRWalletManager;
-
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 8/4/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-public class FragmentSettingsAll extends Fragment {
- private static final String TAG = FragmentSettingsAll.class.getName();
- public static TransactionListItem[] transactionObjects;
- public static ListView transactionList;
- public static TransactionListAdapter adapter;
- private static boolean refreshTransactionAvailable = true;
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- // The last two arguments ensure LayoutParams are inflated
- // properly.
- final View rootView = inflater.inflate(R.layout.fragment_settings_all, container, false);
-
- transactionList = (ListView) rootView.findViewById(R.id.transactions_list);
-
- adapter = new TransactionListAdapter(getActivity(), transactionObjects);
- if (transactionObjects != null) {
- if (transactionObjects.length == 0) transactionObjects = null;
- }
- if (transactionList != null)
- transactionList.setAdapter(adapter);
- refreshTransactions(getActivity());
- return rootView;
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- }
-
- @Override
- public void onResume() {
- super.onResume();
- MiddleViewAdapter.resetMiddleView(getActivity(), null);
- refreshUI();
- }
-
- public static void refreshTransactions(final Activity ctx) {
- if (refreshTransactionAvailable) {
- refreshTransactionAvailable = false;
- Log.e(TAG, "refreshTransactions");
- new Thread(new Runnable() {
- @Override
- public void run() {
- transactionObjects = BRWalletManager.getInstance(ctx).getTransactions();
- if (ctx != null && ctx instanceof MainActivity) {
- ctx.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- refreshTransactionAvailable = true;
- refreshUI();
- }
- });
- }
- }
- }).start();
- }
-
- }
-
- public static void refreshUI() {
- if (BRAnimator.level != 1) return;
- if (adapter != null) {
- adapter.updateData(transactionObjects);
- }
- }
-
- public static RelativeLayout getSeparationLine(int MODE, Activity ctx) {
- //0 - regular , 1 - with left padding
- RelativeLayout line = new RelativeLayout(ctx);
- line.setMinimumHeight(1);
- line.setBackgroundColor(ctx.getColor(R.color.gray));
- if (MODE == 1)
- line.setPadding(40, 0, 0, 0);
- return line;
- }
-
-}
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentSharing.java b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentSharing.java
deleted file mode 100644
index 643e750c5..000000000
--- a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentSharing.java
+++ /dev/null
@@ -1,145 +0,0 @@
-package com.breadwallet.presenter.fragments;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 7/24/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-import android.app.DialogFragment;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Environment;
-import android.os.Handler;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.breadwallet.R;
-import com.breadwallet.BreadWalletApp;
-import com.breadwallet.tools.animation.BRAnimator;
-import com.breadwallet.tools.manager.BRClipboardManager;
-
-import java.io.File;
-
-public class FragmentSharing extends DialogFragment {
-
- private static final String TAG = FragmentSharing.class.getName();
- private boolean customToastAvailable = true;
- private String theAddress;
-
- public FragmentSharing() {
- // Empty constructor required for DialogFragment
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.fragment_sharing_dialog, container);
- TextView copyAddress = (TextView) view.findViewById(R.id.copy_address);
- TextView sendEmail = (TextView) view.findViewById(R.id.send_email);
- TextView sendMessage = (TextView) view.findViewById(R.id.send_message);
- TextView requestAmount = (TextView) view.findViewById(R.id.request_amount);
- TextView sharingTitle = (TextView) view.findViewById(R.id.sharing_title);
- sharingTitle.setText(String.format(getString(R.string.at_this_address), "\n" + theAddress));
-
- getDialog().getWindow().setBackgroundDrawableResource(R.drawable.rounded_dialog);
-
- copyAddress.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (BRAnimator.checkTheMultipressingAvailability()) {
- BRClipboardManager.copyToClipboard(getActivity(), theAddress);
- if (customToastAvailable) {
- customToastAvailable = false;
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- customToastAvailable = true;
- }
- }, 2000);
- ((BreadWalletApp) getActivity().getApplicationContext()).
- showCustomToast(getActivity(), getResources().getString(R.string.toast_address_copied), 360, Toast.LENGTH_SHORT, 0);
- getDialog().cancel();
- }
- }
- }
-
- });
-
- sendEmail.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (BRAnimator.checkTheMultipressingAvailability()) {
- Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts(
- "mailto", "", null));
- emailIntent.putExtra(Intent.EXTRA_SUBJECT, getResources().getString(R.string.bitcoin_address));
- emailIntent.putExtra(Intent.EXTRA_TEXT, "bitcoin:" + theAddress);
- File qrFile = MainFragmentQR.getQRImage();
- Uri uri = qrFile == null ? null : Uri.fromFile(qrFile);
- if (uri != null)
- emailIntent.putExtra(Intent.EXTRA_STREAM, uri);
- startActivity(Intent.createChooser(emailIntent, getResources().getString(R.string.bitcoin_address)));
- getDialog().cancel();
- }
- }
- });
-
- sendMessage.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (BRAnimator.checkTheMultipressingAvailability()) {
- if (theAddress == null || theAddress.isEmpty()) return;
- Intent sendIntent = new Intent(Intent.ACTION_VIEW);
- sendIntent.setData(Uri.parse("sms:"));
- sendIntent.putExtra("sms_body", "bitcoin:" + theAddress);
- sendIntent.putExtra("exit_on_sent", true);
- startActivity(sendIntent);
- getDialog().cancel();
-
- }
- }
- });
-
- requestAmount.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (BRAnimator.checkTheMultipressingAvailability()) {
- getDialog().cancel();
- FragmentScanResult.isARequest = true;
- BRAnimator.animateScanResultFragment();
- }
- }
- });
-
- return view;
- }
-
- public void setTheAddress(String address) {
- theAddress = address;
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentSignal.java b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentSignal.java
new file mode 100644
index 000000000..1f15e8142
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentSignal.java
@@ -0,0 +1,92 @@
+package com.breadwallet.presenter.fragments;
+
+import android.app.Fragment;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.interfaces.BROnSignalCompletion;
+
+public class FragmentSignal extends Fragment {
+ public static final String TITLE = "title";
+ public static final String ICON_DESCRIPTION = "iconDescription";
+ public static final String RES_ID = "resId";
+ public TextView mTitle;
+ // public TextView mDescription;
+ public ImageView mIcon;
+ private BROnSignalCompletion completion;
+ private LinearLayout signalLayout;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, final Bundle savedInstanceState) {
+ // The last two arguments ensure LayoutParams are inflated
+ // properly.
+
+ View rootView = inflater.inflate(R.layout.fragment_signal, container, false);
+ mTitle = (TextView) rootView.findViewById(R.id.title);
+// mDescription = (TextView) rootView.findViewById(R.id.description);
+ mIcon = (ImageView) rootView.findViewById(R.id.qr_image);
+ signalLayout = (LinearLayout) rootView.findViewById(R.id.signal_layout);
+ signalLayout.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ //do nothing, in order to prevent click through
+ }
+ });
+
+ Bundle bundle = this.getArguments();
+
+ if (bundle != null) {
+ String title = bundle.getString(TITLE, "");
+ int resId = bundle.getInt(RES_ID, 0);
+
+ mTitle.setText(title);
+ mIcon.setImageResource(resId);
+ }
+
+ return rootView;
+ }
+
+ public void setCompletion(BROnSignalCompletion completion) {
+ this.completion = completion;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ if (getActivity() != null)
+ getActivity().getFragmentManager().popBackStack();
+ } catch (Exception ignored) {
+
+ }
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ if (completion != null) {
+ completion.onComplete();
+ completion = null;
+ }
+ }
+ }, 300);
+
+ }
+ }, 1500);
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentSpendLimit.java b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentSpendLimit.java
deleted file mode 100644
index dc75bb42f..000000000
--- a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentSpendLimit.java
+++ /dev/null
@@ -1,178 +0,0 @@
-
-package com.breadwallet.presenter.fragments;
-
-import android.app.Activity;
-import android.app.Fragment;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.RelativeLayout;
-import android.widget.TextView;
-
-import com.breadwallet.R;
-import com.breadwallet.BreadWalletApp;
-import com.breadwallet.presenter.activities.MainActivity;
-import com.breadwallet.tools.util.BRConstants;
-import com.breadwallet.tools.util.BRStringFormatter;
-import com.breadwallet.tools.manager.CurrencyManager;
-import com.breadwallet.tools.manager.SharedPreferencesManager;
-import com.breadwallet.tools.adapter.MiddleViewAdapter;
-import com.breadwallet.tools.security.PassCodeManager;
-
-import java.math.BigDecimal;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 7/22/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-public class FragmentSpendLimit extends Fragment {
- public static final String TAG = FragmentSpendLimit.class.getName();
-
- private ImageView checkMark1;
- private ImageView checkMark2;
- private ImageView checkMark3;
- private ImageView checkMark4;
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View rootView = inflater.inflate(
- R.layout.fragment_fingerprint_limit, container, false);
- RelativeLayout alwaysPasscode = (RelativeLayout) rootView.findViewById(R.id.always_passcode);
- RelativeLayout limit100k = (RelativeLayout) rootView.findViewById(R.id.limit_100k);
- RelativeLayout limit1B = (RelativeLayout) rootView.findViewById(R.id.limit_1B);
- RelativeLayout limit10B = (RelativeLayout) rootView.findViewById(R.id.limit_10B);
-
- TextView alwaysPasscodeText = (TextView) rootView.findViewById(R.id.always_passcode_text);
- TextView limit100kText = (TextView) rootView.findViewById(R.id.limit_100k_text);
- TextView limit1BText = (TextView) rootView.findViewById(R.id.limit_1B_text);
- TextView limit10BText = (TextView) rootView.findViewById(R.id.limit_10B_text);
-
- checkMark1 = (ImageView) rootView.findViewById(R.id.checkmark1);
- checkMark2 = (ImageView) rootView.findViewById(R.id.checkmark2);
- checkMark3 = (ImageView) rootView.findViewById(R.id.checkmark3);
- checkMark4 = (ImageView) rootView.findViewById(R.id.checkmark4);
-
- CurrencyManager cm = CurrencyManager.getInstance(getActivity());
- String iso = SharedPreferencesManager.getIso(getActivity());
- double rate = SharedPreferencesManager.getRate(getActivity());
-
- String alwaysPasscodeString = "always require passcode";
- String limit100kString = String.format("%s (%s)", BRStringFormatter.getFormattedCurrencyString("BTC", BRConstants.limit1),
- BRStringFormatter.getExchangeForAmount(rate, iso, new BigDecimal(String.valueOf(BRConstants.limit1)), getActivity()));
- String limit1BString = String.format("%s (%s)", BRStringFormatter.getFormattedCurrencyString("BTC", BRConstants.limit2),
- BRStringFormatter.getExchangeForAmount(rate, iso, new BigDecimal(String.valueOf(BRConstants.limit2)), getActivity()));
- String limit10BString = String.format("%s (%s)", BRStringFormatter.getFormattedCurrencyString("BTC", BRConstants.limit3),
- BRStringFormatter.getExchangeForAmount(rate, iso, new BigDecimal(String.valueOf(BRConstants.limit3)),getActivity()));
-
- alwaysPasscodeText.setText(alwaysPasscodeString);
- limit100kText.setText(limit100kString);
- limit1BText.setText(limit1BString);
- limit10BText.setText(limit10BString);
-
- setInitialCheckMark();
-
- alwaysPasscode.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- setSelected(1);
- }
- });
- limit100k.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- setSelected(2);
- }
- });
- limit1B.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- setSelected(3);
- }
- });
- limit10B.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- setSelected(4);
- }
- });
-
- return rootView;
- }
-
- private void setSelected(int mode) {
- checkMark1.setVisibility(View.GONE);
- checkMark2.setVisibility(View.GONE);
- checkMark3.setVisibility(View.GONE);
- checkMark4.setVisibility(View.GONE);
- switch (mode) {
- case 1:
- checkMark1.setVisibility(View.VISIBLE);
- PassCodeManager.getInstance().setLimit(getActivity(), 0);
- break;
- case 2:
- checkMark2.setVisibility(View.VISIBLE);
- PassCodeManager.getInstance().setLimit(getActivity(), BRConstants.limit1);
- break;
- case 3:
- checkMark3.setVisibility(View.VISIBLE);
- PassCodeManager.getInstance().setLimit(getActivity(), BRConstants.limit2);
- break;
- case 4:
- checkMark4.setVisibility(View.VISIBLE);
- PassCodeManager.getInstance().setLimit(getActivity(), BRConstants.limit3);
- break;
- }
- }
-
- private void setInitialCheckMark() {
- int limit = PassCodeManager.getInstance().getLimit(getActivity());
- switch (limit) {
- case 0:
- checkMark1.setVisibility(View.VISIBLE);
- break;
- case BRConstants.limit1:
- checkMark2.setVisibility(View.VISIBLE);
- break;
- case BRConstants.limit2:
- checkMark3.setVisibility(View.VISIBLE);
- break;
- case BRConstants.limit3:
- checkMark4.setVisibility(View.VISIBLE);
- break;
-
- }
- }
-
- @Override
- public void onResume() {
- super.onResume();
- Activity app = getActivity();
- if (app == null) app = MainActivity.app;
- if (app != null)
- ((BreadWalletApp) app.getApplication()).hideKeyboard(app);
- MiddleViewAdapter.resetMiddleView(getActivity(), null);
- }
-}
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentTransactionDetails.java b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentTransactionDetails.java
new file mode 100644
index 000000000..fd623e708
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentTransactionDetails.java
@@ -0,0 +1,95 @@
+package com.breadwallet.presenter.fragments;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.os.Bundle;
+import android.util.TypedValue;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.annotation.Nullable;
+import androidx.viewpager.widget.ViewPager;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.entities.TxItem;
+import com.breadwallet.tools.adapter.TransactionPagerAdapter;
+import com.breadwallet.tools.animation.BRAnimator;
+
+import java.util.List;
+
+import timber.log.Timber;
+
+public class FragmentTransactionDetails extends Fragment {
+
+ public TextView mTitle;
+ public LinearLayout backgroundLayout;
+ private ViewPager txViewPager;
+ private TransactionPagerAdapter txPagerAdapter;
+ private List items;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ // The last two arguments ensure LayoutParams are inflated
+ // properly.
+ View rootView = inflater.inflate(R.layout.fragment_transaction_details, container, false);
+ mTitle = (TextView) rootView.findViewById(R.id.title);
+ backgroundLayout = (LinearLayout) rootView.findViewById(R.id.background_layout);
+ txViewPager = (ViewPager) rootView.findViewById(R.id.tx_list_pager);
+ txViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
+ public void onPageScrollStateChanged(int state) {
+ }
+
+ public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+ }
+
+ public void onPageSelected(int position) {
+ // Check if this is the page you want.
+ }
+ });
+ txPagerAdapter = new TransactionPagerAdapter(getChildFragmentManager(), items);
+ txViewPager.setAdapter(txPagerAdapter);
+ txViewPager.setOffscreenPageLimit(5);
+ int margin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 16 * 2, getResources().getDisplayMetrics());
+ txViewPager.setPageMargin(-margin);
+ int pos = getArguments().getInt("pos");
+ txViewPager.setCurrentItem(pos, false);
+
+ return rootView;
+ }
+
+ @Override
+ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+
+ final ViewTreeObserver observer = txViewPager.getViewTreeObserver();
+ observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+ @Override
+ public void onGlobalLayout() {
+ if (observer.isAlive()) {
+ observer.removeOnGlobalLayoutListener(this);
+ }
+ BRAnimator.animateBackgroundDim(backgroundLayout, false);
+ BRAnimator.animateSignalSlide(txViewPager, false, null);
+ }
+ });
+ }
+
+ public void close() {
+ final Activity app = getActivity();
+ BRAnimator.animateBackgroundDim(backgroundLayout, true);
+ BRAnimator.animateSignalSlide(txViewPager, true, () -> {
+ if (app != null && !app.isFinishing())
+ app.getFragmentManager().popBackStack();
+ else
+ Timber.d("timber: onAnimationEnd: app is null");
+ });
+ }
+
+ public void setItems(List items) {
+ this.items = items;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentTransactionExpanded.java b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentTransactionExpanded.java
deleted file mode 100644
index 543811585..000000000
--- a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentTransactionExpanded.java
+++ /dev/null
@@ -1,270 +0,0 @@
-
-package com.breadwallet.presenter.fragments;
-
-import android.app.Fragment;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.LinearLayout;
-import android.widget.RelativeLayout;
-import android.widget.TextView;
-
-import com.breadwallet.R;
-import com.breadwallet.presenter.entities.TransactionListItem;
-import com.breadwallet.tools.animation.BRAnimator;
-import com.breadwallet.tools.util.BRStringFormatter;
-import com.breadwallet.tools.manager.CurrencyManager;
-import com.breadwallet.tools.manager.SharedPreferencesManager;
-import com.breadwallet.tools.adapter.MiddleViewAdapter;
-import com.breadwallet.tools.util.Utils;
-import com.breadwallet.wallet.BRWalletManager;
-
-import java.math.BigDecimal;
-import java.util.Locale;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 6/29/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-public class FragmentTransactionExpanded extends Fragment {
- private static final String TAG = FragmentTransactionExpanded.class.getName();
- private TransactionListItem item;
-
- @Override
- public View onCreateView(LayoutInflater inflater,
- ViewGroup container, Bundle savedInstanceState) {
- // The last two arguments ensure LayoutParams are inflated
- // properly.
- if (item == null) return null;
- boolean received = item.getSent() == 0;
- View rootView;
- if (received) {
- rootView = inflater.inflate(R.layout.transaction_item_expanded_received, container, false);
- } else {
- rootView = inflater.inflate(R.layout.transaction_item_expanded_sent, container, false);
- }
- final TextView hashText = (TextView) rootView.findViewById(R.id.tx_hash_text);
- TextView statusText = (TextView) rootView.findViewById(R.id.tx_status_text);
- TextView amountText = (TextView) rootView.findViewById(R.id.tx_amount_text);
- TextView exchangeText = (TextView) rootView.findViewById(R.id.tx_exchange_text);
- hashText.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- Log.e(TAG, "tx id: " + hashText.getText().toString());
- }
- });
-
-// TextView fromText = (TextView) rootView.findViewById(R.id.tx_from_text);
-// TextView fromDescription = (TextView) rootView.findViewById(R.id.tx_from_description);
-// TextView toText = (TextView) rootView.findViewById(R.id.tx_to_text);
-// TextView toDescription = (TextView) rootView.findViewById(R.id.tx_to_description);
-// TextView toAmountText = (TextView) rootView.findViewById(R.id.tx_to_amount_text);
-// TextView toExchangeText = (TextView) rootView.findViewById(R.id.tx_to_exchange_text);
-
- LinearLayout generalTxFrom = (LinearLayout) rootView.findViewById(R.id.general_tx_from_layout);
- LinearLayout generalTxTo = (LinearLayout) rootView.findViewById(R.id.general_tx_to_layout);
- CurrencyManager m = CurrencyManager.getInstance(getActivity());
- final double rate = SharedPreferencesManager.getRate(getActivity());
- final String iso = SharedPreferencesManager.getIso(getActivity());
- int blockHeight = item.getBlockHeight();
- if (!BRWalletManager.getInstance(getActivity()).transactionIsVerified(item.getHexId())) {
- statusText.setText(R.string.unverified);
- } else if (blockHeight == Integer.MAX_VALUE) {
- statusText.setText(R.string.verified_waiting);
- } else {
- String statusString = String.format(Locale.getDefault(), getActivity().getString(R.string.confirmed_in_block_nr),
- blockHeight) + "\n" + String.valueOf(item.getTimeStamp() != 0 ?
- Utils.getFormattedDateFromLong(item.getTimeStamp() * 1000) : Utils.getFormattedDateFromLong(System.currentTimeMillis()));
- statusText.setText(statusString);
- }
- String rawHash = BRWalletManager.getInstance(getActivity()).reverseTxHash(item.getHexId());
- final int mid = rawHash.length() / 2;
- String hashString = rawHash.substring(0, mid) + "\n" + rawHash.substring(mid);
-
- hashText.setText(hashString);
- BRAnimator.showCopyBubble(getActivity(), rootView.findViewById(R.id.tx_id), hashText);
-
- if (received) {
-
- long amount = item.getReceived();
-// Log.e(TAG, "Tx Detail received!!!! amount: " + amount + " item.getBlockHeight(): " + item.getBlockHeight());
-
- amountText.setText(BRStringFormatter.getFormattedCurrencyString("BTC", amount));
- exchangeText.setText(String.format("(%s)", BRStringFormatter.getExchangeForAmount(rate, iso, new BigDecimal(amount), getActivity())));
-
- String fromAddresses[] = item.getFrom();
- setReceivedFromAddresses(generalTxFrom, fromAddresses);
-
- String toAddresses[] = item.getTo();
- setReceivedToAddresses(generalTxTo, toAddresses, item.getOutAmounts());
- } else {
- TextView toFeeAmountText = (TextView) rootView.findViewById(R.id.tx_to_fee_amount_text);
- TextView toFeeExchangeText = (TextView) rootView.findViewById(R.id.tx_to_fee_exchange_text);
-
- long amount = item.getSent() - item.getReceived();
-
-// Log.e(TAG, "Tx Detail sent!!!! amount: " + amount + " tempFee: " + item.getFee() + " tempSent: "
-// + item.getSent() + " item.getBlockHeight(): " + item.getBlockHeight());
-
- amountText.setText(String.format("%s", BRStringFormatter.getFormattedCurrencyString("BTC", -amount)));
- exchangeText.setText(String.format("(%s)", BRStringFormatter.getExchangeForAmount(rate, iso, new BigDecimal(-amount), getActivity())));
- String fromAddresses[] = item.getFrom();
- long[] outAmounts = item.getOutAmounts();
- setSentFromAddresses(generalTxFrom, fromAddresses);
- String toAddresses[] = item.getTo();
- setSentToAddresses(generalTxTo, toAddresses, outAmounts);
- toFeeAmountText.setText(String.format("%s", BRStringFormatter.getFormattedCurrencyString("BTC", -item.getFee())));
- toFeeExchangeText.setText(String.format("(%s)", BRStringFormatter.getExchangeForAmount(rate, iso, new BigDecimal(-item.getFee()), getActivity())));
-
- }
- setHideCopyBubbleListeners(rootView.findViewById(R.id.tx_amount),
- rootView.findViewById(R.id.tx_fee_layout), rootView.findViewById(R.id.tx_status),
- rootView.findViewById(R.id.transactions_item));
-
-
- return rootView;
- }
-
- private void setHideCopyBubbleListeners(View... views) {
- for (View v : views) {
- if (v != null) v.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- BRAnimator.hideCopyBubble(getActivity());
- }
- });
- }
- }
-
- @Override
- public void onResume() {
- super.onResume();
- MiddleViewAdapter.resetMiddleView(getActivity(), null);
- }
-
- @Override
- public void onPause() {
- super.onPause();
- BRAnimator.hideCopyBubble(getActivity());
- }
-
-
- public void setCurrentObject(TransactionListItem item) {
- this.item = item;
- }
-
- private void setReceivedFromAddresses(LinearLayout view, String[] addresses) {
- view.addView(FragmentSettingsAll.getSeparationLine(0, getActivity()));
- LayoutInflater inflater = getActivity().getLayoutInflater();
- for (String address : addresses) {
- LinearLayout addressBlock = (LinearLayout) inflater.inflate(R.layout.
- transaction_received_from_addresses, null);
- TextView txFrom = (TextView) addressBlock.findViewById(R.id.tx_from_text);
- TextView txFromDescription = (TextView) addressBlock.findViewById(R.id.tx_from_description);
- BRAnimator.showCopyBubble(getActivity(), addressBlock, txFrom);
- if (address != null && !address.isEmpty()) {
- txFrom.setText(address);
- txFromDescription.setText(getString(R.string.spent_address));
- view.addView(addressBlock);
- view.addView(FragmentSettingsAll.getSeparationLine(0, getActivity()));
- }
- }
- }
-
- private void setSentFromAddresses(LinearLayout view, String[] addresses) {
- view.addView(FragmentSettingsAll.getSeparationLine(0, getActivity()));
- LayoutInflater inflater = getActivity().getLayoutInflater();
- for (String address : addresses) {
- RelativeLayout addressBlock = (RelativeLayout) inflater.inflate(R.layout.
- transaction_sent_from_addresses, null);
- final TextView txFrom = (TextView) addressBlock.findViewById(R.id.tx_from_text);
- TextView txFromDescription = (TextView) addressBlock.findViewById(R.id.tx_from_description);
- BRAnimator.showCopyBubble(getActivity(), addressBlock, txFrom);
- if (address != null && !address.isEmpty()) {
- txFrom.setText(address);
- txFromDescription.setText(getString(R.string.wallet_address));
- view.addView(addressBlock);
- view.addView(FragmentSettingsAll.getSeparationLine(0, getActivity()));
- }
- }
- }
-
- private void setReceivedToAddresses(LinearLayout view, String[] addresses, long[] amounts) {
- view.addView(FragmentSettingsAll.getSeparationLine(0, getActivity()));
- LayoutInflater inflater = getActivity().getLayoutInflater();
- for (int i = 0; i < addresses.length; i++) {
- RelativeLayout addressBlock = (RelativeLayout) inflater.inflate(R.layout.
- transaction_received_to_addresses, null);
- CurrencyManager m = CurrencyManager.getInstance(getActivity());
- final double rate = SharedPreferencesManager.getRate(getActivity());
- final String iso = SharedPreferencesManager.getIso(getActivity());
-
- final TextView txTo = (TextView) addressBlock.findViewById(R.id.tx_to_text);
- TextView txToDescription = (TextView) addressBlock.findViewById(R.id.tx_to_description);
- TextView txToAmount = (TextView) addressBlock.findViewById(R.id.tx_to_amount_text);
- TextView txToExchange = (TextView) addressBlock.findViewById(R.id.tx_to_exchange_text);
- BRAnimator.showCopyBubble(getActivity(), addressBlock, txTo);
-
- if (addresses[i] != null && !addresses[i].isEmpty()) {
- txTo.setText(addresses[i]);
- txToDescription.setText(getString(R.string.wallet_address));
- txToAmount.setText(BRStringFormatter.getFormattedCurrencyString("BTC", amounts[i]));
- txToExchange.setText(String.format("(%s)", BRStringFormatter.getExchangeForAmount(rate, iso, new BigDecimal(amounts[i]), getActivity())));
- view.addView(addressBlock);
-// if (i != addresses.length - 1)
- view.addView(FragmentSettingsAll.getSeparationLine(0, getActivity()));
- }
- }
- }
-
- private void setSentToAddresses(LinearLayout view, String[] addresses, long[] amounts) {
- view.addView(FragmentSettingsAll.getSeparationLine(0, getActivity()));
- LayoutInflater inflater = getActivity().getLayoutInflater();
- for (int i = 0; i < addresses.length; i++) {
- RelativeLayout addressBlock = (RelativeLayout) inflater.inflate(R.layout.
- transaction_sent_to_addresses, null);
- CurrencyManager m = CurrencyManager.getInstance(getActivity());
- final double rate = SharedPreferencesManager.getRate(getActivity());
- final String iso = SharedPreferencesManager.getIso(getActivity());
-
- TextView txTo = (TextView) addressBlock.findViewById(R.id.tx_to_text);
- TextView txToDescription = (TextView) addressBlock.findViewById(R.id.tx_to_description);
- TextView txToAmount = (TextView) addressBlock.findViewById(R.id.tx_to_amount_text);
- TextView txToExchange = (TextView) addressBlock.findViewById(R.id.tx_to_exchange_text);
- BRAnimator.showCopyBubble(getActivity(), addressBlock, txTo);
-
- if (addresses[i] != null && !addresses[i].isEmpty()) {
- txTo.setText(addresses[i]);
- txToDescription.setText(getString(R.string.payment_address));
- txToAmount.setText(String.format("%s", BRStringFormatter.getFormattedCurrencyString("BTC", -amounts[i])));
- txToExchange.setText(String.format("(%s)", BRStringFormatter.getExchangeForAmount(rate, iso, new BigDecimal(-amounts[i]), getActivity())));
- view.addView(addressBlock);
- if (i != addresses.length - 1)
- view.addView(FragmentSettingsAll.getSeparationLine(0, getActivity()));
- }
- }
- }
-}
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentTransactionItem.java b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentTransactionItem.java
new file mode 100644
index 000000000..752313b42
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentTransactionItem.java
@@ -0,0 +1,285 @@
+package com.breadwallet.presenter.fragments;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.EditText;
+import android.widget.ImageButton;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.annotation.Nullable;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.entities.TxItem;
+import com.breadwallet.tools.animation.BRAnimator;
+import com.breadwallet.tools.animation.SlideDetector;
+import com.breadwallet.tools.manager.BRSharedPrefs;
+import com.breadwallet.tools.manager.TxManager;
+import com.breadwallet.tools.threads.BRExecutor;
+import com.breadwallet.tools.util.BRConstants;
+import com.breadwallet.tools.util.BRCurrency;
+import com.breadwallet.tools.util.BRExchange;
+import com.breadwallet.tools.util.Utils;
+import com.breadwallet.wallet.BRPeerManager;
+import com.platform.entities.TxMetaData;
+import com.platform.tools.KVStoreManager;
+
+import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+import timber.log.Timber;
+
+public class FragmentTransactionItem extends Fragment {
+ public TextView mTitle;
+ private TextView mDescriptionText;
+ private TextView mSubHeader;
+ private TextView mConfirmationText;
+ private TextView mAvailableSpend;
+ private EditText mCommentText;
+ private TextView mAmountText;
+ private TextView mAddressText;
+ private TextView mDateText;
+ private TextView mToFromBottom;
+ private TextView mTxHash;
+ private TxItem item;
+ private LinearLayout signalLayout;
+ private ImageButton close;
+ private String oldComment;
+ private TextView mTxHashLink;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ final View rootView = inflater.inflate(R.layout.transaction_details_item, container, false);
+ signalLayout = (LinearLayout) rootView.findViewById(R.id.signal_layout);
+ mTitle = (TextView) rootView.findViewById(R.id.title);
+ mDescriptionText = (TextView) rootView.findViewById(R.id.description_text);
+ mSubHeader = (TextView) rootView.findViewById(R.id.sub_header);
+ mCommentText = (EditText) rootView.findViewById(R.id.comment_text);
+ mAmountText = (TextView) rootView.findViewById(R.id.amount_text);
+ mAddressText = (TextView) rootView.findViewById(R.id.address_text);
+ mDateText = (TextView) rootView.findViewById(R.id.date_text);
+ mToFromBottom = (TextView) rootView.findViewById(R.id.to_from);
+ mConfirmationText = (TextView) rootView.findViewById(R.id.confirmation_text);
+ mAvailableSpend = (TextView) rootView.findViewById(R.id.available_spend);
+ mTxHash = (TextView) rootView.findViewById(R.id.tx_hash);
+ mTxHashLink = (TextView) rootView.findViewById(R.id.tx_hash_link);
+ close = (ImageButton) rootView.findViewById(R.id.close_button);
+
+ //TODO: all views are using the layout of this button. Views should be refactored without it
+ // Hiding until layouts are built.
+ ImageButton faq = (ImageButton) rootView.findViewById(R.id.faq_button);
+
+ signalLayout.setOnTouchListener(new SlideDetector(signalLayout, this::close));
+
+ rootView.setOnClickListener(v -> {
+ if (!BRAnimator.isClickAllowed()) return;
+ close();
+ });
+ close.setOnClickListener(v -> close());
+
+ return rootView;
+ }
+
+ @Override
+ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ fillTexts();
+ }
+
+ private void fillTexts() {
+ //get the current iso
+ String iso = BRSharedPrefs.getPreferredLTC(getActivity()) ? "LTC" : BRSharedPrefs.getIso(getContext());
+
+ //get the tx amount
+ BigDecimal txAmount = new BigDecimal(item.getReceived() - item.getSent()).abs();
+ //see if it was sent
+ boolean sent = item.getReceived() - item.getSent() < 0;
+
+ //calculated and formatted amount for iso
+ String amountWithFee = BRCurrency.getFormattedCurrencyString(getActivity(), iso, BRExchange.getAmountFromSatoshis(getActivity(), iso, txAmount));
+ String amount = BRCurrency.getFormattedCurrencyString(getActivity(), iso, BRExchange.getAmountFromSatoshis(getActivity(), iso, item.getFee() == -1 ? txAmount : txAmount.subtract(new BigDecimal(item.getFee()))));
+ //calculated and formatted fee for iso
+ String fee = BRCurrency.getFormattedCurrencyString(getActivity(), iso, BRExchange.getAmountFromSatoshis(getActivity(), iso, new BigDecimal(item.getFee())));
+ //description (Sent $24.32 ....)
+ Spannable descriptionString = sent ? new SpannableString(String.format(getString(R.string.TransactionDetails_sent), amountWithFee)) : new SpannableString(String.format(getString(R.string.TransactionDetails_received), amount));
+
+ String startingBalance = BRCurrency.getFormattedCurrencyString(getActivity(), iso, BRExchange.getAmountFromSatoshis(getActivity(), iso, new BigDecimal(sent ? item.getBalanceAfterTx() + txAmount.longValue() : item.getBalanceAfterTx() - txAmount.longValue())));
+ String endingBalance = BRCurrency.getFormattedCurrencyString(getActivity(), iso, BRExchange.getAmountFromSatoshis(getActivity(), iso, new BigDecimal(item.getBalanceAfterTx())));
+ String commentString = item.metaData == null || item.metaData.comment == null ? "" : item.metaData.comment;
+ String sb = String.format(getString(R.string.Transaction_starting), startingBalance);
+ String eb = String.format(getString(R.string.Transaction_ending), endingBalance);
+ String amountString = String.format("%s %s\n\n%s\n%s", amount, item.getFee() == -1 ? "" : String.format(getString(R.string.Transaction_fee), fee), sb, eb);
+ if (sent) amountString = "-" + amountString;
+ String addr = item.getTo()[0];
+ String toFrom = sent ? String.format(getString(R.string.TransactionDetails_to), addr) : String.format(getString(R.string.TransactionDetails_from), addr);
+
+ mTxHash.setText(item.getTxHashHexReversed());
+ mTxHashLink.setOnClickListener(view -> {
+ close();
+ String txUrl = BRConstants.BLOCK_EXPLORER_BASE_URL + item.getTxHashHexReversed();
+ Timber.d("timber: txUrl = %s", txUrl);
+ Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(txUrl));
+ startActivity(browserIntent);
+ getActivity().overridePendingTransition(R.anim.enter_from_bottom, R.anim.empty_300);
+ });
+
+ int level = getLevel(item);
+
+ boolean availableForSpend = false;
+ String percentage = "";
+ switch (level) {
+ case 0:
+ percentage = "0%";
+ break;
+ case 1:
+ percentage = "20%";
+ break;
+ case 2:
+ percentage = "40%";
+ availableForSpend = true;
+ break;
+ case 3:
+ percentage = "60%";
+ availableForSpend = true;
+ break;
+ case 4:
+ percentage = "80%";
+ availableForSpend = true;
+ break;
+ case 5:
+ percentage = "100%";
+ availableForSpend = true;
+ break;
+ }
+
+ boolean removeView = sent || !availableForSpend;
+ Timber.d("timber: fillTexts: removeView : %s", removeView);
+ if (!removeView) {
+ mAvailableSpend.setText(getString(R.string.Transaction_available));
+ } else {
+ mAvailableSpend.setText("");
+ signalLayout.removeView(mAvailableSpend);
+ }
+
+ if (level == 6) {
+ mConfirmationText.setText(getString(R.string.Transaction_complete));
+ } else {
+ mConfirmationText.setText(String.format("%s", percentage));
+ }
+
+ if (!item.isValid())
+ mConfirmationText.setText(getString(R.string.Transaction_invalid));
+
+ mToFromBottom.setText(sent ? getString(R.string.TransactionDirection_to) : getString(R.string.TransactionDirection_address));
+ mDateText.setText(getFormattedDate(item.getTimeStamp()));
+ mDescriptionText.setText(TextUtils.concat(descriptionString));
+ mSubHeader.setText(toFrom);
+ mCommentText.setText(commentString);
+
+ mAmountText.setText(amountString);
+ mAddressText.setText(addr);
+ }
+
+ private int getLevel(TxItem item) {
+ int blockHeight = item.getBlockHeight();
+ int confirms = blockHeight == Integer.MAX_VALUE ? 0 : BRSharedPrefs.getLastBlockHeight(getContext()) - blockHeight + 1;
+ int level;
+ if (confirms <= 0) {
+ int relayCount = BRPeerManager.getRelayCount(item.getTxHash());
+ if (relayCount <= 0)
+ level = 0;
+ else if (relayCount == 1)
+ level = 1;
+ else
+ level = 2;
+ } else {
+ if (confirms == 1)
+ level = 3;
+ else if (confirms == 2)
+ level = 4;
+ else if (confirms == 3)
+ level = 5;
+ else
+ level = 6;
+ }
+ return level;
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ oldComment = mCommentText.getText().toString();
+ }
+
+ @Override
+ public void onPause() {
+ String comment = mCommentText.getText().toString();
+ final Activity app = getActivity();
+ if (!comment.equals(oldComment)) {
+ final TxMetaData md = new TxMetaData();
+ md.comment = comment;
+ BRExecutor.getInstance().forLightWeightBackgroundTasks().execute(new Runnable() {
+ @Override
+ public void run() {
+ KVStoreManager.getInstance().putTxMetaData(app, md, item.getTxHash());
+ TxManager.getInstance().updateTxList(app);
+ }
+ });
+ }
+ oldComment = null;
+ Utils.hideKeyboard(app);
+ super.onPause();
+ }
+
+ public static FragmentTransactionItem newInstance(TxItem item) {
+ FragmentTransactionItem f = new FragmentTransactionItem();
+ f.setItem(item);
+ return f;
+ }
+
+ public void setItem(TxItem item) {
+ this.item = item;
+ }
+
+ private String getFormattedDate(long timeStamp) {
+
+ Date currentLocalTime = new Date(timeStamp == 0 ? System.currentTimeMillis() : timeStamp * 1000);
+
+ SimpleDateFormat date1 = new SimpleDateFormat("MMMM dd, yyyy", Locale.getDefault());
+ SimpleDateFormat date2 = new SimpleDateFormat("HH:mm a", Locale.getDefault());
+
+ String str1 = date1.format(currentLocalTime);
+ String str2 = date2.format(currentLocalTime);
+
+ return str1 + " " + String.format(getString(R.string.TransactionDetails_from), str2);
+ }
+
+ private String getShortAddress(String addr) {
+ String p1 = addr.substring(0, 5);
+ String p2 = addr.substring(addr.length() - 5, addr.length());
+ return p1 + "..." + p2;
+ }
+
+ private void close() {
+ Fragment parentFragment = getParentFragment();
+ if (parentFragment instanceof FragmentTransactionDetails) {
+ ((FragmentTransactionDetails) parentFragment).close();
+ }
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentWipeWallet.java b/app/src/main/java/com/breadwallet/presenter/fragments/FragmentWipeWallet.java
deleted file mode 100644
index 07357d04f..000000000
--- a/app/src/main/java/com/breadwallet/presenter/fragments/FragmentWipeWallet.java
+++ /dev/null
@@ -1,286 +0,0 @@
-
-package com.breadwallet.presenter.fragments;
-
-import android.app.AlertDialog;
-import android.app.Fragment;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.SystemClock;
-import android.provider.Settings;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.breadwallet.R;
-import com.breadwallet.BreadWalletApp;
-import com.breadwallet.presenter.activities.IntroActivity;
-import com.breadwallet.presenter.activities.MainActivity;
-import com.breadwallet.tools.animation.BRAnimator;
-import com.breadwallet.tools.manager.SharedPreferencesManager;
-import com.breadwallet.tools.util.Utils;
-import com.breadwallet.tools.security.KeyStoreManager;
-import com.breadwallet.tools.util.WordsReader;
-import com.breadwallet.wallet.BRPeerManager;
-import com.breadwallet.wallet.BRWalletManager;
-
-import java.util.List;
-
-import static android.content.Context.INPUT_METHOD_SERVICE;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 7/14/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-public class FragmentWipeWallet extends Fragment {
- private static final String TAG = FragmentWipeWallet.class.getName();
- private EditText recoveryPhraseEditText;
- private Button continueButton;
- private Button cancelButton;
- private Button wipe;
- private BRWalletManager m;
- private boolean allowWipeButtonPress = true;
- private AlertDialog alertDialog;
- private InputMethodChangeReceiver mReceiver;
-
- @Override
- public View onCreateView(LayoutInflater inflater,
- ViewGroup container, Bundle savedInstanceState) {
- // The last two arguments ensure LayoutParams are inflated
- // properly.
- View rootView = inflater.inflate(
- R.layout.fragment_wipe_wallet, container, false);
- m = BRWalletManager.getInstance(getActivity());
- Button close = (Button) rootView.findViewById(R.id.wipe_wallet_close);
- recoveryPhraseEditText = (EditText) rootView.findViewById(R.id.editText_phrase);
- wipe = (Button) rootView.findViewById(R.id.wipe_wallet_wipe);
- continueButton = (Button) rootView.findViewById(R.id.continue_button);
- cancelButton = (Button) rootView.findViewById(R.id.cancel_button);
- recoveryPhraseEditText.setText("");
- recoveryPhraseEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
- public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
- if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) ||
- (actionId == EditorInfo.IME_ACTION_DONE)) {
- wipe.performClick();
- }
- return false;
- }
- });
- cancelButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- getActivity().onBackPressed();
- }
- });
- close.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- getActivity().onBackPressed();
- }
- });
- alertDialog = new AlertDialog.Builder(getActivity()).create();
- wipe.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (alertDialog.isShowing()) {
- alertDialog.dismiss();
- }
- if (!allowWipeButtonPress) return;
- allowWipeButtonPress = false;
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- allowWipeButtonPress = true;
- }
- }, 500);
- String cleanPhrase = WordsReader.cleanPhrase(getActivity(), recoveryPhraseEditText.getText().toString().trim().toLowerCase());
- if (KeyStoreManager.phraseIsValid(cleanPhrase, getActivity())) {
- m.wipeKeyStore(getActivity());
- m.wipeWalletButKeystore(getActivity());
- BRPeerManager.stopSyncingProgressThread();
- startIntroActivity();
- BRAnimator.resetFragmentAnimator();
- SharedPreferencesManager.putTipsShown(getActivity(), true);
- } else {
- String message = getResources().getString(R.string.bad_recovery_phrase);
- String[] words = cleanPhrase.split(" ");
- if (words.length != 12) {
- message = String.format(getActivity().getString(R.string.recovery_phrase_must_have_12_words), 12);
- } else {
- List allWords = WordsReader.getAllWordLists(getActivity());
-
- for (String word : words) {
- if (!allWords.contains(word)) {
- message = String.format(getActivity().getString(R.string.not_a_recovery_phrase_word), word);
- }
- }
- }
-
- //don't use
- alertDialog.setMessage(message);
- alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, getResources().getString(R.string.ok),
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- dialog.dismiss();
- }
- });
- alertDialog.show();
- }
- }
- });
-
- return rootView;
- }
-
-
- @Override
- public void onPause() {
- super.onPause();
- ((BreadWalletApp) getActivity().getApplication()).hideKeyboard(getActivity());
- getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
- }
-
- @Override
- public void onResume() {
- super.onResume();
- getActivity().getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,
- WindowManager.LayoutParams.FLAG_SECURE);
- allowWipeButtonPress = true;
- MainActivity app = MainActivity.app;
- if (app != null)
- app.activityButtonsEnable(false);
- if (recoveryPhraseEditText != null && !Utils.isUsingCustomInputMethod(getActivity())) {
- (new Handler()).postDelayed(new Runnable() {
-
- public void run() {
- recoveryPhraseEditText.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, 0, 0, 0));
- recoveryPhraseEditText.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, 0, 0, 0));
-
- }
- }, 100);
-
- }
-
- if (Utils.isUsingCustomInputMethod(getActivity())) {
- disableEditText();
- } else {
- enableEditText();
- }
- }
-
- public void disableEditText() {
- Log.e(TAG, "disableEditText: ");
-
- continueButton.setVisibility(View.VISIBLE);
- cancelButton.setVisibility(View.VISIBLE);
- continueButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- Log.e(TAG, "onClick: ");
- showSelectInputMethod();
- }
- });
- recoveryPhraseEditText.setEnabled(false);
- recoveryPhraseEditText.setHint(getString(R.string.insecure_keyboard_message));
- IntentFilter filter = new IntentFilter(Intent.ACTION_INPUT_METHOD_CHANGED);
- mReceiver = new InputMethodChangeReceiver();
- getActivity().registerReceiver(mReceiver, filter);
- showKeyBoard(false);
-
- }
-
- private void showSelectInputMethod() {
- InputMethodManager imeManager = (InputMethodManager) getActivity().getApplicationContext().getSystemService(INPUT_METHOD_SERVICE);
- if (imeManager != null) {
- imeManager.showInputMethodPicker();
- } else {
- Toast.makeText(getActivity(), "error showing the input method choosing dialog", Toast.LENGTH_LONG).show();
- }
- }
-
- private void enableEditText() {
- Log.e(TAG, "enableEditText: ");
- recoveryPhraseEditText.setEnabled(true);
- recoveryPhraseEditText.setHint("");
- recoveryPhraseEditText.setText("");
- continueButton.setVisibility(View.GONE);
- cancelButton.setVisibility(View.GONE);
- showKeyBoard(true);
- try {
- getActivity().unregisterReceiver(mReceiver);
- } catch (Exception ex) {
- ex.printStackTrace();
- }
- }
-
- public void showKeyBoard(boolean b) {
- if (b && !Utils.isUsingCustomInputMethod(getActivity())) {
- if (recoveryPhraseEditText != null) {
- recoveryPhraseEditText.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, 0, 0, 0));
- recoveryPhraseEditText.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, 0, 0, 0));
- }
- } else {
- ((BreadWalletApp) getActivity().getApplication()).hideKeyboard(getActivity());
- }
-
- }
-
- public class InputMethodChangeReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (action.equals(Intent.ACTION_INPUT_METHOD_CHANGED)) {
- if (Utils.isUsingCustomInputMethod(getActivity())) {
- showSelectInputMethod();
- } else {
- enableEditText();
- }
- /* You can check the package name of current IME here.*/
- }
- }
- }
-
- private void startIntroActivity() {
- Intent intent;
- intent = new Intent(getActivity(), IntroActivity.class);
- startActivity(intent);
- if (!getActivity().isDestroyed()) {
- getActivity().finish();
- }
- }
-}
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/IntroNewRecoverFragment.java b/app/src/main/java/com/breadwallet/presenter/fragments/IntroNewRecoverFragment.java
deleted file mode 100644
index 7647df3af..000000000
--- a/app/src/main/java/com/breadwallet/presenter/fragments/IntroNewRecoverFragment.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package com.breadwallet.presenter.fragments;
-
-import android.app.Fragment;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-
-import com.breadwallet.R;
-import com.breadwallet.presenter.activities.IntroActivity;
-import com.breadwallet.tools.manager.SharedPreferencesManager;
-import com.breadwallet.tools.animation.BRAnimator;
-
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 9/15/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-public class IntroNewRecoverFragment extends Fragment {
-
- @Override
- public View onCreateView(LayoutInflater inflater,
- ViewGroup container, Bundle savedInstanceState) {
- // The last two arguments ensure LayoutParams are inflated
- // properly.
- View rootView = inflater.inflate(
- R.layout.intro_fragment_new_recover, container, false);
- Button newWallet = (Button) rootView.findViewById(R.id.intro_new_wallet);
- Button recoverWallet = (Button) rootView.findViewById(R.id.intro_recover_wallet);
-
- newWallet.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (BRAnimator.checkTheMultipressingAvailability()) {
- ((IntroActivity) getActivity()).showNewWalletFragment();
- }
- }
- });
-
- recoverWallet.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (BRAnimator.checkTheMultipressingAvailability()) {
- ((IntroActivity) getActivity()).showRecoverWalletFragment();
- }
- }
- });
- SharedPreferencesManager.putReceiveAddress(getActivity(), null);
- return rootView;
- }
-}
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/IntroNewWalletFragment.java b/app/src/main/java/com/breadwallet/presenter/fragments/IntroNewWalletFragment.java
deleted file mode 100644
index dfa481f7f..000000000
--- a/app/src/main/java/com/breadwallet/presenter/fragments/IntroNewWalletFragment.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package com.breadwallet.presenter.fragments;
-
-import android.app.Fragment;
-import android.os.Bundle;
-import android.os.Handler;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-
-import com.breadwallet.R;
-import com.breadwallet.presenter.activities.IntroActivity;
-import com.breadwallet.presenter.activities.MainActivity;
-import com.breadwallet.tools.animation.BRAnimator;
-import com.breadwallet.tools.manager.SharedPreferencesManager;
-import com.breadwallet.tools.security.PostAuthenticationProcessor;
-import com.breadwallet.wallet.BRWalletManager;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 9/15/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-public class IntroNewWalletFragment extends Fragment {
- private static final String TAG = IntroNewWalletFragment.class.getName();
- public Button introGenerate;
-
- @Override
- public View onCreateView(LayoutInflater inflater,
- ViewGroup container, Bundle savedInstanceState) {
- // The last two arguments ensure LayoutParams are inflated
- // properly.
- final View rootView = inflater.inflate(R.layout.intro_fragment_new_wallet, container, false);
- introGenerate = (Button) rootView.findViewById(R.id.intro_new_wallet_generate);
- introGenerate.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (BRAnimator.checkTheMultipressingAvailability()) {
- new Handler().post(new Runnable() {
- @Override
- public void run() {
- BRWalletManager m = BRWalletManager.getInstance(getActivity());
- m.wipeWalletButKeystore(getActivity());
- m.wipeKeyStore(getActivity());
- SharedPreferencesManager.putAllowSpend(getActivity(), true);
- PostAuthenticationProcessor.getInstance().onCreateWalletAuth((IntroActivity) getActivity());
- }
- });
- }
- }
- });
- return rootView;
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/IntroRecoverWalletFragment.java b/app/src/main/java/com/breadwallet/presenter/fragments/IntroRecoverWalletFragment.java
deleted file mode 100644
index c83395af5..000000000
--- a/app/src/main/java/com/breadwallet/presenter/fragments/IntroRecoverWalletFragment.java
+++ /dev/null
@@ -1,244 +0,0 @@
-package com.breadwallet.presenter.fragments;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.Fragment;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.SystemClock;
-import android.provider.Settings;
-import android.text.InputType;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.Window;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputMethodInfo;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.breadwallet.R;
-import com.breadwallet.BreadWalletApp;
-import com.breadwallet.presenter.activities.IntroActivity;
-import com.breadwallet.tools.manager.SharedPreferencesManager;
-import com.breadwallet.tools.util.Utils;
-import com.breadwallet.tools.util.WordsReader;
-import com.breadwallet.tools.security.PostAuthenticationProcessor;
-import com.breadwallet.wallet.BRWalletManager;
-
-import java.util.List;
-
-import static android.content.Context.INPUT_METHOD_SERVICE;
-import static com.breadwallet.R.string.show;
-
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 9/15/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-public class IntroRecoverWalletFragment extends Fragment {
- public static final String TAG = IntroRecoverWalletFragment.class.getName();
- private Button recoverButton;
- private EditText editText;
- private AlertDialog alertDialog;
- private Button continueButton;
- private Button cancelButton;
- private InputMethodChangeReceiver mReceiver;
-
- @Override
- public View onCreateView(LayoutInflater inflater,
- ViewGroup container, Bundle savedInstanceState) {
- // The last two arguments ensure LayoutParams are inflated
- // properly.
- View rootView = inflater.inflate(
- R.layout.intro_fragment_recover_wallet, container, false);
-
- recoverButton = (Button) rootView.findViewById(R.id.recover_button);
- editText = (EditText) rootView.findViewById(R.id.recover_wallet_edit_text);
- continueButton = (Button) rootView.findViewById(R.id.continue_button);
- cancelButton = (Button) rootView.findViewById(R.id.cancel_button);
- editText.setText("");
- editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
- public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
- if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) ||
- (actionId == EditorInfo.IME_ACTION_DONE)) {
- recoverButton.performClick();
- }
- return false;
- }
- });
- alertDialog = new AlertDialog.Builder(getActivity()).create();
- recoverButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (alertDialog.isShowing()) {
- alertDialog.dismiss();
- }
-
- String phraseToCheck = editText.getText().toString().toLowerCase();
- String cleanPhrase = WordsReader.cleanPhrase(getActivity(), phraseToCheck);
-
- if (BRWalletManager.getInstance(getActivity()).validatePhrase(getActivity(), cleanPhrase)) {
- showKeyBoard(false);
- BRWalletManager m = BRWalletManager.getInstance(getActivity());
- m.wipeWalletButKeystore(getActivity());
- m.wipeKeyStore(getActivity());
- PostAuthenticationProcessor.getInstance().setPhraseForKeyStore(cleanPhrase);
- PostAuthenticationProcessor.getInstance().onRecoverWalletAuth((IntroActivity) getActivity());
- SharedPreferencesManager.putAllowSpend(getActivity(), false);
-
- } else {
- String message = getResources().getString(R.string.bad_recovery_phrase);
- String[] words = cleanPhrase.split(" ");
- if (words.length != 12) {
- message = String.format(getActivity().getString(R.string.recovery_phrase_must_have_12_words), 12);
- } else {
- List allWords = WordsReader.getAllWordLists(getActivity());
-
- for (String word : words) {
- if (!allWords.contains(word)) {
- message = String.format(getActivity().getString(R.string.not_a_recovery_phrase_word), word);
- }
- }
- }
-
- alertDialog.setMessage(message);
- alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, getResources().getString(R.string.ok),
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- dialog.dismiss();
- }
- });
- alertDialog.show();
- }
- }
- });
- cancelButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- getActivity().onBackPressed();
- }
- });
-
- return rootView;
- }
-
- public void disableEditText() {
- Log.e(TAG, "disableEditText: ");
- cancelButton.setVisibility(View.VISIBLE);
- continueButton.setVisibility(View.VISIBLE);
- continueButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- Log.e(TAG, "onClick: ");
- showSelectInputMethod();
- }
- });
- editText.setEnabled(false);
- editText.setHint(getString(R.string.insecure_keyboard_message));
- IntentFilter filter = new IntentFilter(Intent.ACTION_INPUT_METHOD_CHANGED);
- mReceiver = new InputMethodChangeReceiver();
- getActivity().registerReceiver(mReceiver, filter);
- showKeyBoard(false);
-
- }
-
- private void showSelectInputMethod(){
- InputMethodManager imeManager = (InputMethodManager) getActivity().getApplicationContext().getSystemService(INPUT_METHOD_SERVICE);
- if (imeManager != null) {
- imeManager.showInputMethodPicker();
- } else {
- Toast.makeText(getActivity(), "error showing the input method choosing dialog", Toast.LENGTH_LONG).show();
- }
- }
-
- private void enableEditText() {
- Log.e(TAG, "enableEditText: ");
- editText.setEnabled(true);
- editText.setHint("");
- editText.setText("");
- continueButton.setVisibility(View.GONE);
- cancelButton.setVisibility(View.GONE);
- showKeyBoard(true);
- try {
- getActivity().unregisterReceiver(mReceiver);
- } catch (Exception ex){
- ex.printStackTrace();
- }
-
- }
-
- @Override
- public void onResume() {
- Log.e(TAG, "onResume");
- if (Utils.isUsingCustomInputMethod(getActivity()) && this.isVisible()) {
- disableEditText();
- } else {
- Log.e(TAG, "onResume: !isUsingCustomInputMethod");
- enableEditText();
- }
-
- super.onResume();
- }
-
- public void showKeyBoard(boolean b) {
- if (b && !Utils.isUsingCustomInputMethod(getActivity())) {
- if (editText != null) {
- editText.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, 0, 0, 0));
- editText.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, 0, 0, 0));
- }
- } else {
- ((BreadWalletApp) getActivity().getApplication()).hideKeyboard(getActivity());
- }
-
- }
-
- public class InputMethodChangeReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (action.equals(Intent.ACTION_INPUT_METHOD_CHANGED)) {
- if(Utils.isUsingCustomInputMethod(getActivity())){
- showSelectInputMethod();
- } else {
- enableEditText();
- }
- /* You can check the package name of current IME here.*/
- }
- }
- }
-
-}
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/IntroWarningFragment.java b/app/src/main/java/com/breadwallet/presenter/fragments/IntroWarningFragment.java
deleted file mode 100644
index f2f46bcb6..000000000
--- a/app/src/main/java/com/breadwallet/presenter/fragments/IntroWarningFragment.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package com.breadwallet.presenter.fragments;
-
-import android.os.Bundle;
-import android.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.Window;
-import android.view.WindowManager;
-import android.widget.Button;
-
-import com.breadwallet.R;
-import com.breadwallet.presenter.activities.IntroActivity;
-import com.breadwallet.wallet.BRWalletManager;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 9/15/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-public class IntroWarningFragment extends Fragment {
-
- @Override
- public View onCreateView(LayoutInflater inflater,
- ViewGroup container, Bundle savedInstanceState) {
- // The last two arguments ensure LayoutParams are inflated
- // properly.
- View rootView = inflater.inflate(
- R.layout.intro_fragment_warning, container, false);
- Button show = (Button) rootView.findViewById(R.id.intro_warning_show_button);
- show.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- BRWalletManager.getInstance(getActivity()).animateSavePhraseFlow();
- getActivity().overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
- }
- });
- return rootView;
- }
-
-}
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/IntroWelcomeFragment.java b/app/src/main/java/com/breadwallet/presenter/fragments/IntroWelcomeFragment.java
deleted file mode 100644
index 1a8c82eeb..000000000
--- a/app/src/main/java/com/breadwallet/presenter/fragments/IntroWelcomeFragment.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package com.breadwallet.presenter.fragments;
-
-import android.os.Bundle;
-import android.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.breadwallet.R;
-
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 9/15/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-public class IntroWelcomeFragment extends Fragment {
-
- @Override
- public View onCreateView(LayoutInflater inflater,
- ViewGroup container, Bundle savedInstanceState) {
- // The last two arguments ensure LayoutParams are inflated
- // properly.
- return inflater.inflate(
- R.layout.intro_fragment_welcome, container, false);
- }
-}
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/MainFragment.java b/app/src/main/java/com/breadwallet/presenter/fragments/MainFragment.java
deleted file mode 100644
index d9bf8e56d..000000000
--- a/app/src/main/java/com/breadwallet/presenter/fragments/MainFragment.java
+++ /dev/null
@@ -1,303 +0,0 @@
-package com.breadwallet.presenter.fragments;
-
-import android.app.AlertDialog;
-import android.app.Fragment;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.os.Bundle;
-import android.os.Handler;
-import android.util.Log;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.LinearLayout;
-import android.widget.RelativeLayout;
-import android.widget.TextView;
-
-import com.breadwallet.R;
-import com.breadwallet.BreadWalletApp;
-import com.breadwallet.presenter.activities.MainActivity;
-import com.breadwallet.presenter.customviews.BubbleTextView;
-import com.breadwallet.tools.animation.BRAnimator;
-import com.breadwallet.tools.animation.SpringAnimator;
-import com.breadwallet.tools.manager.BRClipboardManager;
-import com.breadwallet.tools.adapter.CustomPagerAdapter;
-import com.breadwallet.tools.adapter.MiddleViewAdapter;
-import com.breadwallet.tools.manager.BRTipsManager;
-import com.breadwallet.wallet.BRWalletManager;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 7/14/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-public class MainFragment extends Fragment {
- private static final String TAG = MainFragment.class.getName();
- public EditText addressEditText;
- public RelativeLayout mainFragmentLayout;
- private int bubbleState = 0;
- private LinearLayout sendLabelLayout;
-
-// private AlertDialog alertDialog;
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-
- // Inflate the layout for this fragment
- final View rootView = inflater.inflate(R.layout.fragment_main, container, false);
-
- sendLabelLayout = (LinearLayout) rootView.findViewById(R.id.send_money_text_layout);
-
- final Button scanQRButton = (Button) rootView.findViewById(R.id.main_button_scan_qr_code);
- mainFragmentLayout = (RelativeLayout) rootView.findViewById(R.id.main_fragment);
- final Button payAddressFromClipboardButton = (Button)
- rootView.findViewById(R.id.main_button_pay_address_from_clipboard);
-
- addressEditText = (EditText) rootView.findViewById(R.id.address_edit_text);
- addressEditText.setGravity(Gravity.CENTER_HORIZONTAL);
- addressEditText.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- addressEditText.setText(BRClipboardManager.readFromClipboard(getActivity()));
- MainActivity app = MainActivity.app;
- if (app != null) {
- app.hideAllBubbles();
- }
- }
- });
-
-
- final MainActivity app = MainActivity.app;
- if (app != null) {
- app.sendBubble1 = (BubbleTextView) rootView.findViewById(R.id.send_bubble1);
- app.sendBubble2 = (BubbleTextView) rootView.findViewById(R.id.send_bubble2);
- }
- rootView.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (app != null) {
- app.hideAllBubbles();
- }
- }
- });
-
- rootView.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- ((BreadWalletApp) getActivity().getApplication()).hideKeyboard(getActivity());
- addressEditText.clearFocus();
- MainActivity app = MainActivity.app;
- if (app != null) {
- app.hideAllBubbles();
- }
- }
- });
-
- mainFragmentLayout.setPadding(0, MainActivity.screenParametersPoint.y / 5, 0, 0);
- scanQRButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- ((MainActivity) getActivity()).hideAllBubbles();
- if (BRAnimator.checkTheMultipressingAvailability()) {
- BRAnimator.animateDecoderFragment();
- }
- }
- });
-
- payAddressFromClipboardButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- AlertDialog alert = null;
- AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
- ((MainActivity) getActivity()).hideAllBubbles();
- if (BRAnimator.checkTheMultipressingAvailability()) {
- String tempAddress = BRClipboardManager.readFromClipboard(getActivity());
- if (!addressEditText.getText().toString().isEmpty()) {
- tempAddress = addressEditText.getText().toString();
- }
- final String finalAddress = tempAddress;
- BRWalletManager wm = BRWalletManager.getInstance(getActivity());
-
- if (wm.isValidBitcoinPrivateKey(finalAddress) || wm.isValidBitcoinBIP38Key(finalAddress)) {
- BRWalletManager.getInstance(getActivity()).confirmSweep(getActivity(), finalAddress);
- addressEditText.setText("");
- return;
- }
-
- if (checkIfAddressIsValid(finalAddress)) {
- if (finalAddress != null) {
- BRWalletManager m = BRWalletManager.getInstance(getActivity());
- if (m.addressContainedInWallet(finalAddress)) {
-
- //builder.setTitle(getResources().getString(R.string.alert));
- builder.setMessage(getResources().getString(R.string.address_already_in_your_wallet));
- builder.setNeutralButton(getResources().getString(R.string.ok),
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- dialog.dismiss();
- }
- });
- alert = builder.create();
- alert.show();
- BRClipboardManager.copyToClipboard(getActivity(), "");
- addressEditText.setText("");
- } else if (m.addressIsUsed(finalAddress)) {
- builder.setTitle(getResources().getString(R.string.warning));
-
- builder.setMessage(getResources().getString(R.string.address_already_used));
- builder.setPositiveButton(getResources().getString(R.string.ignore),
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- dialog.dismiss();
- FragmentScanResult.address = finalAddress;
- BRAnimator.animateScanResultFragment();
- }
- });
- builder.setNegativeButton(getResources().getString(R.string.cancel),
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- dialog.dismiss();
- }
- });
- alert = builder.create();
- alert.show();
- } else {
- FragmentScanResult.address = finalAddress;
- BRAnimator.animateScanResultFragment();
- }
- } else {
- throw new NullPointerException();
- }
- } else {
- //builder.setTitle(getResources().getString(R.string.alert));
- builder.setMessage(getResources().getString(R.string.mainfragment_clipboard_invalid_data));
- builder.setNeutralButton(getResources().getString(R.string.ok),
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- dialog.dismiss();
- }
- });
- alert = builder.create();
- alert.show();
- BRClipboardManager.copyToClipboard(getActivity(), "");
- addressEditText.setText("");
- }
- }
- }
-
- });
-
- sendLabelLayout.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- ((BreadWalletApp) getActivity().getApplication()).hideKeyboard(getActivity());
- if (BRAnimator.checkTheMultipressingAvailability()) {
- final MainActivity app = MainActivity.app;
- if (app != null) {
- app.hideAllBubbles();
- if (bubbleState == 0) {
- ((MainActivity) getActivity()).hideAllBubbles();
- app.sendBubble1.setVisibility(View.VISIBLE);
- app.sendBubble1.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- app.sendBubble1.setVisibility(View.GONE);
- app.sendBubble2.setVisibility(View.VISIBLE);
- SpringAnimator.showBubbleAnimation(app.sendBubble2);
- bubbleState++;
- }
- });
- app.sendBubble2.setVisibility(View.GONE);
- SpringAnimator.showBubbleAnimation(app.sendBubble1);
- bubbleState++;
- } else if (bubbleState == 1) {
- app.sendBubble1.setVisibility(View.GONE);
- app.sendBubble2.setVisibility(View.VISIBLE);
- app.sendBubble2.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- app.hideAllBubbles();
- bubbleState = 0;
- }
- });
- SpringAnimator.showBubbleAnimation(app.sendBubble2);
- bubbleState++;
- } else {
- app.hideAllBubbles();
- bubbleState = 0;
- }
- }
-
- }
-
- }
- });
-
- setTipsPositions(rootView);
-
- return rootView;
- }
-
- private boolean checkIfAddressIsValid(String str) {
- return BRWalletManager.validateAddress(str.trim());
- }
-
- private void setTipsPositions(final View rootView) {
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- View temp = rootView.findViewById(R.id.scan_clipboard_buttons_layout);
- View sendMoneyLabel = rootView.findViewById(R.id.send_money_text_layout);
- int tempHeight = temp == null ? 0 : temp.getHeight();
- int sendBubble1Position = tempHeight == 0 ? MainActivity.screenParametersPoint.y / 2 : tempHeight / 2 + tempHeight / 10 + sendMoneyLabel.getHeight();
- int sendBubble2Position = tempHeight == 0 ? MainActivity.screenParametersPoint.y / 2 : tempHeight + tempHeight / 3 + sendMoneyLabel.getHeight();
- BRTipsManager.setSendBubblesPosition(sendBubble1Position, sendBubble2Position);
- }
- }, 200);
- }
-
- @Override
- public void onResume() {
- super.onResume();
- MiddleViewAdapter.resetMiddleView(getActivity(), null);
- }
-
- @Override
- public void onPause() {
- super.onPause();
- InputMethodManager keyboard = (InputMethodManager) getActivity().
- getSystemService(Context.INPUT_METHOD_SERVICE);
- if (keyboard != null) {
- EditText editText = CustomPagerAdapter.adapter.
- mainFragment.addressEditText;
- if (editText != null)
- keyboard.hideSoftInputFromWindow(editText.getWindowToken(), 0);
- }
- ((MainActivity) getActivity()).hideAllBubbles();
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/MainFragmentQR.java b/app/src/main/java/com/breadwallet/presenter/fragments/MainFragmentQR.java
deleted file mode 100644
index e9cf98662..000000000
--- a/app/src/main/java/com/breadwallet/presenter/fragments/MainFragmentQR.java
+++ /dev/null
@@ -1,238 +0,0 @@
-
-package com.breadwallet.presenter.fragments;
-
-import android.app.Fragment;
-import android.app.FragmentManager;
-import android.graphics.Bitmap;
-import android.os.Bundle;
-import android.os.Environment;
-import android.os.Handler;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.RelativeLayout;
-import android.widget.TextView;
-
-import com.breadwallet.R;
-import com.breadwallet.BreadWalletApp;
-import com.breadwallet.presenter.activities.MainActivity;
-import com.breadwallet.presenter.customviews.BubbleTextView;
-import com.breadwallet.tools.manager.BRTipsManager;
-import com.breadwallet.tools.manager.SharedPreferencesManager;
-import com.breadwallet.tools.adapter.MiddleViewAdapter;
-import com.breadwallet.tools.animation.BRAnimator;
-import com.breadwallet.tools.animation.SpringAnimator;
-import com.breadwallet.wallet.BRWalletManager;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 6/23/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-public class MainFragmentQR extends Fragment {
- private static final String TAG = MainFragmentQR.class.getName();
- private ImageView qrcode;
- private TextView mainAddressText;
- private LinearLayout qrImageLayout;
- private Bitmap bitmap;
- private FragmentSharing sharingFragment;
- private FragmentManager fm;
- public static File qrCodeImageFile;
- private String receiveAddress;
- private int bubbleState = 0;
- private RelativeLayout addressLayout;
-
- @Override
- public View onCreateView(LayoutInflater inflater,
- ViewGroup container, Bundle savedInstanceState) {
- // The last two arguments ensure LayoutParams are inflated
- // properly.
- final View rootView = inflater.inflate(R.layout.fragment_qr_main, container, false);
-
- BRWalletManager.refreshAddress();
- receiveAddress = SharedPreferencesManager.getReceiveAddress(getActivity());
- qrImageLayout = (LinearLayout) rootView.findViewById(R.id.qr_image_address_layout);
- qrcode = (ImageView) rootView.findViewById(R.id.main_image_qr_code);
- sharingFragment = new FragmentSharing();
- final RelativeLayout mainFragmentQr = (RelativeLayout) rootView.findViewById(R.id.main_fragment_qr);
- mainAddressText = (TextView) rootView.findViewById(R.id.main_address_text);
- addressLayout = (RelativeLayout) rootView.findViewById(R.id.theAddressLayout);
- String bitcoinUrl = "bitcoin:" + receiveAddress;
- mainAddressText.setText(receiveAddress);
- BRWalletManager.getInstance(getActivity()).generateQR(bitcoinUrl, qrcode);
- fm = getActivity().getFragmentManager();
- mainFragmentQr.setPadding(0, MainActivity.screenParametersPoint.y / 5, 0, 0);
- final BreadWalletApp breadWalletApp = (BreadWalletApp) getActivity().getApplication();
- addressLayout.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- breadWalletApp.cancelToast();
- if (BRAnimator.checkTheMultipressingAvailability()) {
- MainActivity app = MainActivity.app;
- if (app != null) app.hideAllBubbles();
-// Log.e(TAG, "finalReceiveAddress: " + receiveAddress);
- sharingFragment.setTheAddress(receiveAddress);
- saveBitmapToFile();
- sharingFragment.show(fm, FragmentSharing.class.getName());
- }
- }
- });
- qrcode.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- showTips();
- }
- });
- qrImageLayout.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- showTips();
- }
- });
-
- final MainActivity app = MainActivity.app;
- if (app != null) {
- app.qrBubble1 = (BubbleTextView) rootView.findViewById(R.id.qr_bubble1);
- app.qrBubble2 = (BubbleTextView) rootView.findViewById(R.id.qr_bubble2);
- }
- rootView.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (app != null) {
- app.hideAllBubbles();
- }
- }
- });
-
- setTipsPositions(rootView);
-
- return rootView;
- }
-
- private void setTipsPositions(final View rootView) {
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- View temp = rootView.findViewById(R.id.qr_image_address_layout);
- int qrBubble1Position = temp == null ? MainActivity.screenParametersPoint.y / 2 : temp.getHeight() / 3 + temp.getHeight() / 10;
- int qrBubble2Position = temp == null ? MainActivity.screenParametersPoint.y / 2 : temp.getHeight() - temp.getHeight() / 7;
- BRTipsManager.setQrBubblesPosition(qrBubble1Position, qrBubble2Position);
- }
- }, 200);
- }
-
- private void showTips() {
- if (BRAnimator.checkTheMultipressingAvailability()) {
- MainActivity app = MainActivity.app;
- if (app != null) {
- app.hideAllBubbles();
- if (bubbleState == 0) {
- ((MainActivity) getActivity()).hideAllBubbles();
- app.qrBubble1.setVisibility(View.VISIBLE);
- app.qrBubble2.setVisibility(View.GONE);
- SpringAnimator.showBubbleAnimation(app.qrBubble1);
- bubbleState++;
- } else if (bubbleState == 1) {
- app.qrBubble1.setVisibility(View.GONE);
- app.qrBubble2.setVisibility(View.VISIBLE);
- SpringAnimator.showBubbleAnimation(app.qrBubble2);
- bubbleState++;
- } else {
- app.hideAllBubbles();
- bubbleState = 0;
- }
- }
-
- }
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
-
- }
-
- private void saveBitmapToFile() {
- FileOutputStream out = null;
- String path = getActivity().getFilesDir() + "/" + "qrcodes";
- Log.e(TAG, "saveBitmapToFile: path: " + path);
- File qrCodeImageFile = new File(path, "qrImage" + ".jpeg");
- Log.e(TAG, "saveBitmapToFile: qrCodeImageFile: " + qrCodeImageFile.getAbsolutePath());
- if (qrCodeImageFile.exists()) {
- Log.d(TAG, "File exists!");
- } else {
- Log.d(TAG, "File did not exist, creating a new one");
- }
- try {
- out = new FileOutputStream(qrCodeImageFile);
- bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out); // bmp is your Bitmap instance
- // PNG is a lossless format, the compression factor (100) is ignored
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (out != null) {
- out.close();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
-
- public static File getQRImage(){
- MainActivity app = MainActivity.app;
- if(app == null) return null;
- String path = app.getFilesDir() + "/" + "qrcodes";
- Log.e(TAG, "saveBitmapToFile: path: " + path);
- return new File(path, "qrImage" + ".jpeg");
- }
-
- @Override
- public void onResume() {
- super.onResume();
- MiddleViewAdapter.resetMiddleView(getActivity(), null);
- refreshAddress(null);
- }
-
- public void refreshAddress(String str) {
- if (str != null) {
- receiveAddress = str;
- } else {
- receiveAddress = SharedPreferencesManager.getReceiveAddress(getActivity());
- }
-// Log.e(TAG, "refreshAddress: receiveAddress: " + receiveAddress);
- String bitcoinUrl = "bitcoin:" + receiveAddress;
- if(mainAddressText == null) return;
- mainAddressText.setText(receiveAddress);
- BRWalletManager.getInstance(getActivity()).generateQR(bitcoinUrl, qrcode);
- }
-
-}
diff --git a/app/src/main/java/com/breadwallet/presenter/fragments/PasswordDialogFragment.java b/app/src/main/java/com/breadwallet/presenter/fragments/PasswordDialogFragment.java
deleted file mode 100644
index cb038c2ae..000000000
--- a/app/src/main/java/com/breadwallet/presenter/fragments/PasswordDialogFragment.java
+++ /dev/null
@@ -1,547 +0,0 @@
-package com.breadwallet.presenter.fragments;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 7/24/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-import android.app.Activity;
-import android.app.DialogFragment;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.SystemClock;
-import android.security.keystore.UserNotAuthenticatedException;
-import android.text.Editable;
-import android.text.TextWatcher;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.TextView;
-
-import com.breadwallet.R;
-import com.breadwallet.BreadWalletApp;
-import com.breadwallet.exceptions.BRKeystoreErrorException;
-import com.breadwallet.presenter.activities.IntroActivity;
-import com.breadwallet.presenter.activities.MainActivity;
-import com.breadwallet.presenter.activities.PhraseFlowActivity;
-import com.breadwallet.presenter.entities.PaymentRequestEntity;
-import com.breadwallet.presenter.entities.PaymentRequestWrapper;
-import com.breadwallet.tools.animation.BRAnimator;
-import com.breadwallet.tools.manager.BRTipsManager;
-import com.breadwallet.tools.security.PostAuthenticationProcessor;
-import com.breadwallet.tools.util.BRConstants;
-import com.breadwallet.tools.util.BRStringFormatter;
-import com.breadwallet.tools.manager.SharedPreferencesManager;
-import com.breadwallet.tools.adapter.MiddleViewAdapter;
-import com.breadwallet.tools.animation.SpringAnimator;
-import com.breadwallet.tools.security.KeyStoreManager;
-import com.breadwallet.tools.security.PassCodeManager;
-import com.breadwallet.tools.threads.PaymentProtocolPostPaymentTask;
-import com.breadwallet.wallet.BRWalletManager;
-
-import java.util.Locale;
-
-import static com.breadwallet.tools.security.KeyStoreManager.putLastPasscodeUsedTime;
-
-public class PasswordDialogFragment extends DialogFragment {
-
- private static final String TAG = PasswordDialogFragment.class.getName();
- private EditText passcodeEditText;
- private EditText phraseEditText;
- private Button cancel;
- private Button reset;
- private DialogFragment dialogFragment;
-
- private int currentMode = BRConstants.AUTH_MODE_CHECK_PASS;
- private String tempPassToChange;
- private boolean firstTime = false; // if false then change;
- private boolean verifyOnly = false;
- private TextView title;
- private TextView digit_1;
- private TextView digit_2;
- private TextView digit_3;
- private TextView digit_4;
- private PaymentRequestEntity request;
- private PaymentRequestWrapper paymentRequest;
- private TextView info;
- private TextWatcher textWatcher;
- private String prevPass;
- private String message;
- private TextView description;
- private boolean forceDialogStayOn;
-
- private int mode = -1;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setStyle(STYLE_NO_TITLE, 0);
-
- }
-
- @Override
- public void onDismiss(DialogInterface dialog) {
- super.onDismiss(dialog);
- Activity app = getActivity();
- if(app == null) return;
- long passTime = 0;
- passTime = KeyStoreManager.getLastPasscodeUsedTime(app);
- if (forceDialogStayOn && (passTime + BRConstants.PASS_CODE_TIME_LIMIT <= System.currentTimeMillis())) {
- ((BreadWalletApp) app.getApplication()).promptForAuthentication(app, mode, request, message, title.getText().toString(), paymentRequest, forceDialogStayOn);
- }
- }
-
- @Override
- public View onCreateView(final LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.fragment_password_dialog, container);
- String pass = KeyStoreManager.getPassCode(getActivity());
- if (pass == null || pass.length() != 4) {
- firstTime = true;
- verifyOnly = false;
- forceDialogStayOn = true;
- }
- dialogFragment = this;
- passcodeEditText = (EditText) view.findViewById(R.id.edit_passcode);
- phraseEditText = (EditText) view.findViewById(R.id.edit_phrase);
- cancel = (Button) view.findViewById(R.id.button_password_cancel);
- reset = (Button) view.findViewById(R.id.button_password_reset);
- title = (TextView) view.findViewById(R.id.passcode_dialog_title);
- info = (TextView) view.findViewById(R.id.password_info_text);
- description = (TextView) view.findViewById(R.id.passcode_dialog_description);
- if (message != null) description.setText(message);
- digit_1 = (TextView) view.findViewById(R.id.passcode_digit1);
- digit_2 = (TextView) view.findViewById(R.id.passcode_digit2);
- digit_3 = (TextView) view.findViewById(R.id.passcode_digit3);
- digit_4 = (TextView) view.findViewById(R.id.passcode_digit4);
-
- prevPass = "";
-
- clearDigits();
- final InputMethodManager keyboard = (InputMethodManager) getActivity().
- getSystemService(Context.INPUT_METHOD_SERVICE);
- cancel.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- getDialog().dismiss();
- passcodeEditText.setText("");
- keyboard.hideSoftInputFromWindow(cancel.getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY);
- if (!BRAnimator.scanResultFragmentOn && mode == BRConstants.AUTH_FOR_PAY && request.isAmountRequested) {
- FragmentScanResult.address = request.addresses[0];
- BRWalletManager.getInstance(getActivity()).offerToChangeTheAmount(getActivity(), "");
- }
- }
- });
-
- reset.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (phraseEditText == null) return;
- new Handler().postDelayed(new Runnable() {
-
- public void run() {
- phraseEditText.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, 0, 0, 0));
- phraseEditText.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, 0, 0, 0));
-
- }
- }, 100);
- if (phraseEditText.getVisibility() == View.GONE) {
- phraseEditText.setVisibility(View.VISIBLE);
- title.setText(R.string.recovery_phrase_label);
- description.setText("");
- info.setVisibility(View.GONE);
- } else {
- if (!phraseEditText.getText().toString().isEmpty() && KeyStoreManager.phraseIsValid(phraseEditText.getText().toString().toLowerCase(), getActivity())) {
- KeyStoreManager.putFailCount(0, getActivity());
- KeyStoreManager.putFailTimeStamp(0, getActivity());
- PassCodeManager.getInstance().setPassCode("", getActivity());
- BRWalletManager.getInstance(getActivity()).askForPasscode();
- getDialog().dismiss();
- } else {
- final String tmpTitle = title.getText().toString();
- title.setText(R.string.phrase_no_match);
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- title.setText(tmpTitle);
- }
- }, 3000);
- }
- }
-
- }
- });
-
- int failCount = KeyStoreManager.getFailCount(getActivity());
- long secureTime = SharedPreferencesManager.getSecureTime(getActivity());
- long failTimestamp = KeyStoreManager.getFailTimeStamp(getActivity());
- if (secureTime == 0) secureTime = System.currentTimeMillis() / 1000;
-
- updateInfoText();
-
- if (secureTime < failTimestamp + Math.pow(6, failCount - 3) * 60.0) {
- setWalletDisabled();
- return view;
- }
-
- view.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- keyboard.showSoftInput(passcodeEditText, 0);
- }
- });
-
- title.setText(getResources().getString(R.string.enter_old_passcode));
- getDialog().getWindow().setBackgroundDrawableResource(R.drawable.rounded_dialog);
-
- if (firstTime) {
- cancel.setClickable(false);
- cancel.setVisibility(View.GONE);
- title.setText(R.string.choose_new_passcode);
- currentMode = BRConstants.AUTH_MODE_NEW_PASS;
- }
- long passTime = KeyStoreManager.getLastPasscodeUsedTime(getActivity());
- if (passTime + BRConstants.PASS_CODE_TIME_LIMIT <= System.currentTimeMillis()) {
- cancel.setClickable(false);
- cancel.setVisibility(View.GONE);
- forceDialogStayOn = true;
- }
- if (verifyOnly) {
- title.setText(String.format(getResources().getString(R.string.enter_passcode), "\"" + BRConstants.bitcoinLowercase + "read\""));
- }
-
- textWatcher = new TextWatcher() {
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-
- }
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- addRemoveDigit(s.length());
- if (s.length() == 4) validatePassCode(s);
- }
-
- @Override
- public void afterTextChanged(Editable s) {
-
- }
- };
- passcodeEditText.addTextChangedListener(textWatcher);
-
- getDialog().setCanceledOnTouchOutside(false);
-
- new Handler().postDelayed(new Runnable() {
-
- public void run() {
- passcodeEditText.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, 0, 0, 0));
- passcodeEditText.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, 0, 0, 0));
-
- }
- }, 200);
- return view;
- }
-
- @Override
- public void onResume() {
- super.onResume();
- passcodeEditText.setText("");
- }
-
- @Override
- public void onPause() {
- super.onPause();
-
- View view = getActivity().getCurrentFocus();
- if (view != null) {
- InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
- imm.hideSoftInputFromWindow(passcodeEditText.getWindowToken(), 0);
- }
- }
-
-
- public void setVerifyOnlyTrue() {
- verifyOnly = true;
- firstTime = false;
- }
-
- private boolean validatePassCode(CharSequence s) {
- PassCodeManager passCodeManager = PassCodeManager.getInstance();
-
- //Set and confirm the new passcode
- if (firstTime) {
- switch (currentMode) {
- case BRConstants.AUTH_MODE_NEW_PASS:
- tempPassToChange = s.toString();
- currentMode = BRConstants.AUTH_MODE_CONFIRM_PASS;
- title.setText(getResources().getString(R.string.verify_passcode));
- passcodeEditText.setText("");
- break;
- case BRConstants.AUTH_MODE_CONFIRM_PASS:
- String passToCheck = s.toString();
- if (passToCheck.equals(tempPassToChange)) {
- passCodeManager.setPassCode(tempPassToChange, getActivity());
- tempPassToChange = "";
- try {
- getDialog().dismiss();
- } catch (Exception e) {
- e.printStackTrace();
- }
- String tmp = BRStringFormatter.getCurrentBalanceText(getActivity());
- MiddleViewAdapter.resetMiddleView(getActivity(), tmp);
- ((BreadWalletApp) getActivity().getApplicationContext()).setUnlocked(true);
- MainActivity app = MainActivity.app;
- if (app != null) {
- BRTipsManager.showTipsTutorial(app);
-
- }
- InputMethodManager keyboard = (InputMethodManager) getActivity().
- getSystemService(Context.INPUT_METHOD_SERVICE);
- keyboard.hideSoftInputFromWindow(cancel.getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY);
- currentMode = BRConstants.AUTH_MODE_CHECK_PASS;
- } else {
- SpringAnimator.failShakeAnimation(getActivity(), dialogFragment.getView());
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- passcodeEditText.setText("");
- currentMode = BRConstants.AUTH_MODE_NEW_PASS;
- title.setText(getResources().getString(R.string.choose_new_passcode));
- }
- }, 500);
-
- }
- break;
- }
- // verify the passcode
- } else if (verifyOnly) {
- //assume the passcode is wrong all the time
- if (!prevPass.equals(s.toString())) {
- KeyStoreManager.putFailCount(KeyStoreManager.getFailCount(getActivity()) + 1, getActivity());
- }
-
- prevPass = s.toString();
- if (KeyStoreManager.getFailCount(getActivity()) >= 3) setWalletDisabled();
- if (passCodeManager.checkAuth(s.toString(), getActivity())) {
- InputMethodManager inputManager =
- (InputMethodManager) getActivity().
- getSystemService(Context.INPUT_METHOD_SERVICE);
- inputManager.hideSoftInputFromWindow(
- passcodeEditText.getWindowToken(),
- InputMethodManager.HIDE_NOT_ALWAYS);
- //reset the passcode after successful attempt
- KeyStoreManager.putFailCount(0, getActivity());
- putLastPasscodeUsedTime(System.currentTimeMillis(), getActivity());
- getDialog().dismiss();
- long totalSpent = BRWalletManager.getInstance(getActivity()).getTotalSent();
- long spendLimit = totalSpent + PassCodeManager.getInstance().getLimit(getActivity()) + (request == null ? 0 : request.amount);
- KeyStoreManager.putSpendLimit(spendLimit, getActivity());
- Log.e(TAG, "Setting the new limit: " + spendLimit + ", totalSpent was: " + totalSpent);
-
- ((BreadWalletApp) getActivity().getApplicationContext()).setUnlocked(true);
- FragmentSettingsAll.refreshUI();
- MiddleViewAdapter.resetMiddleView(getActivity(), null);
- ((BreadWalletApp) getActivity().getApplicationContext()).allowKeyStoreAccessForSeconds();
- getDialog().dismiss();
- passcodeEditText.setText("");
- Log.e(TAG, "mode: " + mode + " request: " + request);
- if (mode == BRConstants.AUTH_FOR_PHRASE) {
- PhraseFlowActivity app = ((PhraseFlowActivity) getActivity());
- if (SharedPreferencesManager.getPhraseWroteDown(app)) {
- app.animateSlide(app.fragmentPhraseFlow1, app.fragmentRecoveryPhrase, IntroActivity.RIGHT);
- app.fragmentRecoveryPhrase.setPhrase(FragmentPhraseFlow1.phrase);
- } else {
- app.animateSlide(app.fragmentPhraseFlow1, app.fragmentPhraseFlow2, IntroActivity.RIGHT);
- app.fragmentPhraseFlow2.setPhrase(FragmentPhraseFlow1.phrase);
- }
- } else if (mode == BRConstants.AUTH_FOR_LIMIT) {
- BRAnimator.animateSlideToLeft((MainActivity) getActivity(), new FragmentSpendLimit(), new FragmentSettings());
- } else if (mode == BRConstants.AUTH_FOR_PAY && request != null) {
- PostAuthenticationProcessor.getInstance().onPublishTxAuth((MainActivity) getActivity());
- } else if (mode == BRConstants.AUTH_FOR_PAYMENT_PROTOCOL && paymentRequest != null) {
- if (paymentRequest.paymentURL == null || paymentRequest.paymentURL.isEmpty())
- return false;
- new PaymentProtocolPostPaymentTask(paymentRequest).execute();
- }
- } else {
- SpringAnimator.failShakeAnimation(getActivity(), dialogFragment.getView());
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- passcodeEditText.setText("");
- }
- }, 500);
- }
-
- } else {
- //Change passcode
- switch (currentMode) {
- case BRConstants.AUTH_MODE_CHECK_PASS:
- if (passCodeManager.checkAuth(s.toString(), getActivity())) {
- currentMode = BRConstants.AUTH_MODE_NEW_PASS;
- title.setText(getResources().getString(R.string.choose_new_passcode));
- passcodeEditText.setText("");
- } else {
- SpringAnimator.failShakeAnimation(getActivity(), dialogFragment.getView());
- passcodeEditText.setText("");
- if (!prevPass.equals(s.toString())) {
- KeyStoreManager.putFailCount(KeyStoreManager.getFailCount(getActivity()) + 1, getActivity());
- }
- prevPass = s.toString();
- if (KeyStoreManager.getFailCount(getActivity()) >= 3) setWalletDisabled();
- }
- break;
- case BRConstants.AUTH_MODE_NEW_PASS:
- if (s.length() > 3 && s.length() < 12) {
- tempPassToChange = s.toString();
- currentMode = BRConstants.AUTH_MODE_CONFIRM_PASS;
- title.setText(getResources().getString(R.string.verify_passcode));
- passcodeEditText.setText("");
- } else {
- SpringAnimator.showAnimation(dialogFragment.getView());
- passcodeEditText.setText("");
- }
- break;
- case BRConstants.AUTH_MODE_CONFIRM_PASS:
- String passToCheck = s.toString();
- if (passToCheck.equals(tempPassToChange)) {
- passCodeManager.setPassCode(tempPassToChange, getActivity());
- tempPassToChange = "";
- getDialog().dismiss();
- String tmp = BRStringFormatter.getCurrentBalanceText(getActivity());
- MiddleViewAdapter.resetMiddleView(getActivity(), tmp);
- ((BreadWalletApp) getActivity().getApplicationContext()).setUnlocked(true);
- InputMethodManager keyboard = (InputMethodManager) getActivity().
- getSystemService(Context.INPUT_METHOD_SERVICE);
- keyboard.hideSoftInputFromWindow(cancel.getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY);
- currentMode = BRConstants.AUTH_MODE_CHECK_PASS;
- } else {
- SpringAnimator.failShakeAnimation(getActivity(), dialogFragment.getView());
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- passcodeEditText.setText("");
- currentMode = BRConstants.AUTH_MODE_NEW_PASS;
- title.setText(getResources().getString(R.string.choose_new_passcode));
- }
- }, 500);
-
- }
- break;
- }
- }
- return false;
- }
-
- private void updateInfoText() {
- int failCount = KeyStoreManager.getFailCount(getActivity());
- int attemptsRemaining = 8 - failCount;
- if (attemptsRemaining <= 0) {
- BRWalletManager m = BRWalletManager.getInstance(getActivity());
- m.wipeKeyStore(getActivity());
- m.wipeWalletButKeystore(getActivity());
- startIntroActivity();
- BRAnimator.resetFragmentAnimator();
- }
- if (failCount >= 3) {
- info.setVisibility(View.VISIBLE);
- info.setText(attemptsRemaining == 1 ? getActivity().getString(R.string.attempt_remaining1) :
- String.format(Locale.getDefault(), getActivity().getString(R.string.attempts_remaining), attemptsRemaining));
- }
- }
-
- private void setWalletDisabled() {
- int failCount = KeyStoreManager.getFailCount(getActivity());
-
- long secureTime = SharedPreferencesManager.getSecureTime(getActivity());
- long failTimestamp = KeyStoreManager.getFailTimeStamp(getActivity());
- double waitTime = (failTimestamp + Math.pow(6, failCount - 3) * 60.0 - secureTime) / 60.0;
- title.setText(R.string.wallet_disabled);
- description.setText("");
- passcodeEditText.setVisibility(View.GONE);
- info.setVisibility(View.VISIBLE);
- // Get the Resources
- String message = String.format(getString(R.string.try_again), (int) (((int) waitTime) == 0 ? 1 : waitTime),
- (waitTime == 1 ? getString(R.string.minute) : getString(R.string.minutes)));
-
- info.setText(message);
- digit_1.setVisibility(View.GONE);
- digit_2.setVisibility(View.GONE);
- digit_3.setVisibility(View.GONE);
- digit_4.setVisibility(View.GONE);
- getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
- passcodeEditText.removeTextChangedListener(textWatcher);
- reset.setVisibility(View.VISIBLE);
-
- }
-
- public void setPaymentRequestEntity(PaymentRequestEntity requestEntity, PaymentRequestWrapper paymentRequest) {
- request = requestEntity;
- this.paymentRequest = paymentRequest;
- }
-
- public void setMode(int mode) {
- this.mode = mode;
- }
-
- private void addRemoveDigit(int digits) {
- if (digit_1 == null) return;
- digit_1.setText(digits >= 1 ? BRConstants.LITTLE_CIRCLE : "-");
- digit_2.setText(digits >= 2 ? BRConstants.LITTLE_CIRCLE : "-");
- digit_3.setText(digits >= 3 ? BRConstants.LITTLE_CIRCLE : "-");
- digit_4.setText(digits >= 4 ? BRConstants.LITTLE_CIRCLE : "-");
-
- }
-
- private void clearDigits() {
- if (digit_1 == null) return;
- digit_1.setText("-");
- digit_2.setText("-");
- digit_3.setText("-");
- digit_4.setText("-");
- }
-
- private void startIntroActivity() {
-
- Intent intent;
- intent = new Intent(getActivity(), IntroActivity.class);
- startActivity(intent);
- if (!getActivity().isDestroyed()) {
- getActivity().finish();
- }
- }
-
- public void setMessage(String message) {
- this.message = message;
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/breadwallet/presenter/history/HistoryFragment.kt b/app/src/main/java/com/breadwallet/presenter/history/HistoryFragment.kt
new file mode 100644
index 000000000..8aa05d0b5
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/history/HistoryFragment.kt
@@ -0,0 +1,99 @@
+package com.breadwallet.presenter.history
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import com.breadwallet.databinding.FragmentHistoryBinding
+import com.breadwallet.presenter.activities.BreadActivity
+import com.breadwallet.presenter.base.BaseFragment
+import com.breadwallet.tools.manager.BRSharedPrefs
+import com.breadwallet.tools.manager.BRSharedPrefs.OnIsoChangedListener
+import com.breadwallet.tools.manager.TxManager
+import com.breadwallet.tools.sqlite.TransactionDataSource.OnTxAddedListener
+import com.breadwallet.tools.threads.BRExecutor
+import com.breadwallet.wallet.BRPeerManager
+import com.breadwallet.wallet.BRPeerManager.OnTxStatusUpdate
+import com.breadwallet.wallet.BRWalletManager
+import com.breadwallet.wallet.BRWalletManager.OnBalanceChanged
+
+/** Litewallet
+ * Created by Mohamed Barry on 6/1/20
+ * email: mosadialiou@gmail.com
+ * Copyright ยฉ 2020 Litecoin Foundation. All rights reserved.
+ */
+class HistoryFragment :
+ BaseFragment(),
+ OnBalanceChanged,
+ OnTxStatusUpdate,
+ OnIsoChangedListener,
+ OnTxAddedListener,
+ HistoryView {
+ lateinit var binding: FragmentHistoryBinding
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?,
+ ): View {
+ binding = FragmentHistoryBinding.inflate(inflater, container, false)
+ return binding.root
+ }
+
+ override fun onActivityCreated(savedInstanceState: Bundle?) {
+ super.onActivityCreated(savedInstanceState)
+ TxManager.getInstance().init(requireActivity() as BreadActivity, binding.recyclerView)
+ }
+
+ private fun addObservers() {
+ BRWalletManager.getInstance().addBalanceChangedListener(this)
+ BRPeerManager.getInstance().addStatusUpdateListener(this)
+ BRSharedPrefs.addIsoChangedListener(this)
+ }
+
+ private fun removeObservers() {
+ BRWalletManager.getInstance().removeListener(this)
+ BRPeerManager.getInstance().removeListener(this)
+ BRSharedPrefs.removeListener(this)
+ }
+
+ override fun onResume() {
+ super.onResume()
+ addObservers()
+ TxManager.getInstance().onResume(requireActivity() as BreadActivity)
+ }
+
+ override fun onPause() {
+ super.onPause()
+ removeObservers()
+ }
+
+ override fun onBalanceChanged(balance: Long) {
+ updateUI()
+ }
+
+ override fun onStatusUpdate() {
+ BRExecutor.getInstance().forBackgroundTasks().execute {
+ TxManager.getInstance().updateTxList(requireActivity() as BreadActivity)
+ }
+ }
+
+ override fun onIsoChanged(iso: String) {
+ updateUI()
+ }
+
+ override fun onTxAdded() {
+ BRExecutor.getInstance().forBackgroundTasks().execute {
+ TxManager.getInstance().updateTxList(requireActivity() as BreadActivity)
+ }
+ }
+
+ private fun updateUI() {
+ BRExecutor.getInstance().forLightWeightBackgroundTasks().execute {
+ Thread.currentThread().name = Thread.currentThread().name + "HistoryFragment:updateUI"
+ TxManager.getInstance().updateTxList(requireActivity() as BreadActivity)
+ }
+ }
+
+ override fun initPresenter() = HistoryPresenter(this)
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/history/HistoryPresenter.kt b/app/src/main/java/com/breadwallet/presenter/history/HistoryPresenter.kt
new file mode 100644
index 000000000..627a78aee
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/history/HistoryPresenter.kt
@@ -0,0 +1,16 @@
+package com.breadwallet.presenter.history
+
+import com.breadwallet.presenter.base.BasePresenter
+
+/** Litewallet
+ * Created by Mohamed Barry on 6/30/20
+ * email: mosadialiou@gmail.com
+ * Copyright ยฉ 2020 Litecoin Foundation. All rights reserved.
+ */
+class HistoryPresenter(view: HistoryView) : BasePresenter(view) {
+ override fun subscribe() {
+ }
+
+ override fun unsubscribe() {
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/history/HistoryView.kt b/app/src/main/java/com/breadwallet/presenter/history/HistoryView.kt
new file mode 100644
index 000000000..faf08078c
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/history/HistoryView.kt
@@ -0,0 +1,10 @@
+package com.breadwallet.presenter.history
+
+import com.breadwallet.presenter.base.BaseView
+
+/** Litewallet
+ * Created by Mohamed Barry on 6/30/20
+ * email: mosadialiou@gmail.com
+ * Copyright ยฉ 2020 Litecoin Foundation. All rights reserved.
+ */
+interface HistoryView : BaseView
diff --git a/app/src/main/java/com/breadwallet/presenter/interfaces/BRAuthCompletion.java b/app/src/main/java/com/breadwallet/presenter/interfaces/BRAuthCompletion.java
new file mode 100644
index 000000000..387c85dc8
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/interfaces/BRAuthCompletion.java
@@ -0,0 +1,6 @@
+package com.breadwallet.presenter.interfaces;
+
+public interface BRAuthCompletion {
+ void onComplete();
+ void onCancel();
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/breadwallet/presenter/interfaces/BROnSignalCompletion.java b/app/src/main/java/com/breadwallet/presenter/interfaces/BROnSignalCompletion.java
new file mode 100644
index 000000000..43f614a48
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/interfaces/BROnSignalCompletion.java
@@ -0,0 +1,5 @@
+package com.breadwallet.presenter.interfaces;
+
+public interface BROnSignalCompletion {
+ void onComplete();
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/interfaces/BreadPayment.java b/app/src/main/java/com/breadwallet/presenter/interfaces/BreadPayment.java
new file mode 100644
index 000000000..b1d8aed42
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/interfaces/BreadPayment.java
@@ -0,0 +1,5 @@
+package com.breadwallet.presenter.interfaces;
+
+public interface BreadPayment {
+
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/language/ChangeLanguageBottomSheet.kt b/app/src/main/java/com/breadwallet/presenter/language/ChangeLanguageBottomSheet.kt
new file mode 100644
index 000000000..8092b4d48
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/language/ChangeLanguageBottomSheet.kt
@@ -0,0 +1,111 @@
+package com.breadwallet.presenter.language
+
+import android.app.Dialog
+import android.content.Intent
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.FrameLayout
+import com.breadwallet.R
+import com.breadwallet.databinding.ChangeLanguageBottomSheetBinding
+import com.breadwallet.entities.Language
+import com.breadwallet.presenter.activities.intro.IntroActivity
+import com.breadwallet.tools.util.LocaleHelper
+import com.breadwallet.tools.util.Utils
+import com.breadwallet.tools.util.getString
+import com.breadwallet.ui.RoundedBottomSheetDialogFragment
+import com.google.android.material.bottomsheet.BottomSheetBehavior
+import com.google.android.material.bottomsheet.BottomSheetDialog
+
+/** Litewallet
+ * Created by Mohamed Barry on 7/19/21
+ * email: mosadialiou@gmail.com
+ * Copyright ยฉ 2021 Litecoin Foundation. All rights reserved.
+ */
+class ChangeLanguageBottomSheet : RoundedBottomSheetDialogFragment() {
+ lateinit var binding: ChangeLanguageBottomSheetBinding
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?,
+ ): View {
+ binding = ChangeLanguageBottomSheetBinding.inflate(inflater, container, false)
+ return binding.root
+ }
+
+ override fun onViewCreated(
+ view: View,
+ savedInstanceState: Bundle?,
+ ) {
+ super.onViewCreated(view, savedInstanceState)
+
+ binding.toolbar.setNavigationOnClickListener { dismiss() }
+
+ val currentLanguage = LocaleHelper.instance.currentLocale
+ binding.toolbar.title = currentLanguage.desc
+
+ val adapter =
+ LanguageAdapter(Language.values()).apply {
+ selectedPosition = currentLanguage.ordinal
+ onLanguageChecked = {
+ binding.toolbar.title = it.desc
+ binding.okButton.text = getString(LocaleHelper.getLocale(it), R.string.Button_ok)
+ }
+ }
+ binding.recyclerView.adapter = adapter
+
+ binding.recyclerView.post {
+ binding.recyclerView.scrollToPosition(adapter.selectedPosition)
+ }
+
+ binding.okButton.setOnClickListener {
+ dismiss()
+ if (LocaleHelper.instance.setLocaleIfNeeded(adapter.selectedLanguage())) {
+ val intent = Intent(requireContext(), IntroActivity::class.java)
+ intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
+ startActivity(intent)
+ }
+ }
+ }
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ val dialog = BottomSheetDialog(requireContext(), theme)
+ dialog.setCanceledOnTouchOutside(false)
+ dialog.setCancelable(false)
+ val behavior = dialog.behavior
+ behavior.state = BottomSheetBehavior.STATE_EXPANDED
+ behavior.setPeekHeight(0, true)
+ behavior.setExpandedOffset(Utils.getPixelsFromDps(context, 16))
+ behavior.isFitToContents = false
+ behavior.isHideable = true
+
+ behavior.addBottomSheetCallback(
+ object : BottomSheetBehavior.BottomSheetCallback() {
+ override fun onSlide(
+ bottomSheet: View,
+ slideOffset: Float,
+ ) {
+ }
+
+ override fun onStateChanged(
+ bottomSheet: View,
+ newState: Int,
+ ) {
+ if (newState == BottomSheetBehavior.STATE_DRAGGING) {
+ behavior.state = BottomSheetBehavior.STATE_EXPANDED
+ }
+ }
+ },
+ )
+
+ dialog.setOnShowListener {
+ val bottomSheet: FrameLayout? = dialog.findViewById(com.google.android.material.R.id.design_bottom_sheet)
+ val lp = bottomSheet?.layoutParams
+ lp?.height = ViewGroup.LayoutParams.MATCH_PARENT
+ bottomSheet?.layoutParams = lp
+ }
+ return dialog
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/presenter/language/LanguageAdapter.kt b/app/src/main/java/com/breadwallet/presenter/language/LanguageAdapter.kt
new file mode 100644
index 000000000..94a812ca1
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/presenter/language/LanguageAdapter.kt
@@ -0,0 +1,56 @@
+package com.breadwallet.presenter.language
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.RadioButton
+import androidx.recyclerview.widget.RecyclerView
+import com.breadwallet.R
+import com.breadwallet.entities.Language
+
+/** Litewallet
+ * Created by Mohamed Barry on 7/19/21
+ * email: mosadialiou@gmail.com
+ * Copyright ยฉ 2021 Litecoin Foundation. All rights reserved.
+ */
+class LanguageAdapter(val languages: Array) : RecyclerView.Adapter() {
+ var selectedPosition = 0
+
+ var onLanguageChecked: ((Language) -> Unit)? = null
+
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int,
+ ): ViewHolder {
+ val view = LayoutInflater.from(parent.context).inflate(R.layout.change_language_item, null)
+ return ViewHolder(view)
+ }
+
+ override fun onBindViewHolder(
+ holder: ViewHolder,
+ position: Int,
+ ) {
+ val language = languages[position]
+ with(holder.lang) {
+ text = language.title
+ isChecked = selectedPosition == position
+ setOnCheckedChangeListener { radioButton, isChecked ->
+ if (isChecked) {
+ onLanguageChecked?.invoke(language)
+ radioButton.post {
+ notifyItemChanged(selectedPosition)
+ selectedPosition = position
+ }
+ }
+ }
+ }
+ }
+
+ override fun getItemCount() = languages.size
+
+ fun selectedLanguage() = languages[selectedPosition]
+
+ class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
+ val lang: RadioButton = view.findViewById(R.id.lang_radio_button)
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/tools/adapter/CountryLanguageAdapter.kt b/app/src/main/java/com/breadwallet/tools/adapter/CountryLanguageAdapter.kt
new file mode 100644
index 000000000..d1913f2ce
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/tools/adapter/CountryLanguageAdapter.kt
@@ -0,0 +1,94 @@
+package com.breadwallet.tools.adapter
+
+import android.content.Context
+import android.graphics.Typeface
+import android.media.MediaPlayer
+import android.net.Uri
+import android.util.Log
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.core.content.res.ResourcesCompat
+import androidx.recyclerview.widget.RecyclerView
+import com.breadwallet.R
+import com.breadwallet.entities.IntroLanguage
+
+class CountryLanguageAdapter(context: Context, val languages: Array) : RecyclerView.Adapter() {
+ private var mCountryLang: Array? = null
+ private var mInflater: LayoutInflater? = null
+ private var mSelectedItem = -1
+ private var barlowFont: Typeface? = null
+ private var mContext: Context? = null
+ private var mediaPlayer: MediaPlayer? = null
+
+ inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+ var txtLang: TextView
+
+ init {
+ txtLang = itemView.findViewById(R.id.text_language_intro)
+ }
+ }
+
+ init {
+ this.mCountryLang = languages
+ this.mContext = context
+ this.mInflater = LayoutInflater.from(context)
+ this.barlowFont = ResourcesCompat.getFont(context, R.font.barlowsemicondensed_light)
+ this.mediaPlayer = MediaPlayer()
+ }
+
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int,
+ ): CountryLanguageAdapter.ViewHolder {
+ val context = parent.context
+ val layoutInflater = LayoutInflater.from(context)
+ val languageView =
+ layoutInflater.inflate(R.layout.language_list, parent, false)
+ return ViewHolder(languageView)
+ }
+
+ override fun onBindViewHolder(
+ holder: ViewHolder,
+ position: Int,
+ ) {
+ val langQuestion = languages[position]
+ val textLanguage = holder.txtLang
+ textLanguage.text = langQuestion.lang
+
+ // Make text bold if it's in the center
+ if (position == mSelectedItem) {
+ if (barlowFont == null) {
+ Log.e("FONT", "FAILED TO LOAD")
+ }
+ mediaPlayer?.reset()
+ mediaPlayer?.setDataSource(mContext!!, Uri.parse("android.resource://" + mContext?.packageName + "/" + selectedAudio()))
+ mediaPlayer?.prepare()
+ mediaPlayer?.start()
+ holder.txtLang.setTypeface(barlowFont, Typeface.BOLD)
+ } else {
+ holder.txtLang.setTypeface(barlowFont, Typeface.NORMAL)
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return mCountryLang?.size ?: 0
+ }
+
+ fun updateCenterPosition(position: Int) {
+ mSelectedItem = position
+ notifyDataSetChanged() // Refresh the list to update the bold text
+ }
+
+ fun selectedMessage() = languages[mSelectedItem].message
+
+ fun selectedDesc() = languages[mSelectedItem].desc
+
+ fun selectedAudio() = languages[mSelectedItem].audio
+
+ override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
+ super.onDetachedFromRecyclerView(recyclerView)
+ mediaPlayer?.release()
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/tools/adapter/CurAdapter.java b/app/src/main/java/com/breadwallet/tools/adapter/CurAdapter.java
new file mode 100644
index 000000000..444c0b09d
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/tools/adapter/CurAdapter.java
@@ -0,0 +1,80 @@
+package com.breadwallet.tools.adapter;
+
+import android.app.Activity;
+import android.content.Context;
+import androidx.recyclerview.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.breadwallet.R;
+import com.breadwallet.presenter.customviews.BRButton;
+import com.breadwallet.tools.util.BRCurrency;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static android.widget.Adapter.IGNORE_ITEM_VIEW_TYPE;
+
+public class CurAdapter extends RecyclerView.Adapter {
+ public static final String TAG = CurAdapter.class.getName();
+
+ private final Context mContext;
+ private final int layoutResourceId;
+ private List itemFeed;
+
+ public CurAdapter(Context mContext, List items) {
+ itemFeed = items;
+ if (itemFeed == null) itemFeed = new ArrayList<>();
+ this.layoutResourceId = R.layout.spinner_item;
+ this.mContext = mContext;
+ }
+
+ public String getItemAtPos(int pos) {
+ return itemFeed.get(pos);
+ }
+
+ public List getItems() {
+ return itemFeed;
+ }
+
+ @Override
+ public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ // inflate the layout
+ LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
+ View convertView = inflater.inflate(layoutResourceId, parent, false);
+ return new CustomViewHolder(convertView);
+ }
+
+ @Override
+ public void onBindViewHolder(CustomViewHolder holder, int position) {
+ setTexts(holder, position);
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return IGNORE_ITEM_VIEW_TYPE;
+ }
+
+ @Override
+ public int getItemCount() {
+ return itemFeed.size();
+ }
+
+ private void setTexts(CustomViewHolder convertView, int position) {
+
+ String item = itemFeed.get(position);
+ convertView.button.setText(String.format("%s(%s)", item, BRCurrency.getSymbolByIso(mContext, item)));
+
+ }
+
+ class CustomViewHolder extends RecyclerView.ViewHolder {
+ public BRButton button;
+
+ public CustomViewHolder(View view) {
+ super(view);
+ button = (BRButton) view.findViewById(R.id.watch_list_layout);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/breadwallet/tools/adapter/CurrencyListAdapter.java b/app/src/main/java/com/breadwallet/tools/adapter/CurrencyListAdapter.java
deleted file mode 100644
index bbf30b9d1..000000000
--- a/app/src/main/java/com/breadwallet/tools/adapter/CurrencyListAdapter.java
+++ /dev/null
@@ -1,114 +0,0 @@
-package com.breadwallet.tools.adapter;
-
-import android.app.Activity;
-import android.content.Context;
-import android.graphics.Point;
-import android.util.TypedValue;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import com.breadwallet.R;
-import com.breadwallet.presenter.entities.CurrencyEntity;
-import com.breadwallet.tools.manager.SharedPreferencesManager;
-import com.breadwallet.tools.util.Utils;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 7/27/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-public class CurrencyListAdapter extends ArrayAdapter {
- public static final String TAG = CurrencyListAdapter.class.getName();
-
- private final Context mContext;
- private final int layoutResourceId;
- private TextView textViewItem;
- private final Point displayParameters = new Point();
- public static CurrencyListAdapter currencyListAdapter;
-
- public CurrencyListAdapter(Context mContext) {
-
- super(mContext, R.layout.currency_list_item);
-
- this.layoutResourceId = R.layout.currency_list_item;
- this.mContext = mContext;
- ((Activity) mContext).getWindowManager().getDefaultDisplay().getSize(displayParameters);
- currencyListAdapter = this;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
-
- final int tmp = SharedPreferencesManager.getCurrencyListPosition(mContext);
- if (convertView == null) {
- // inflate the layout
- LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
- convertView = inflater.inflate(layoutResourceId, parent, false);
- }
- // get the TextView and then set the text (item name) and tag (item ID) values
- textViewItem = null;
- textViewItem = (TextView) convertView.findViewById(R.id.currency_item_text);
- Utils.overrideFonts(textViewItem);
- textViewItem.setText(this.getItem(position).codeAndName);
- ImageView checkMark = (ImageView) convertView.findViewById(R.id.currency_checkmark);
-
- if (position == tmp) {
- checkMark.setVisibility(View.VISIBLE);
- } else {
- checkMark.setVisibility(View.GONE);
- }
- normalizeTextView();
- return convertView;
-
- }
-
- @Override
- public int getItemViewType(int position) {
- return IGNORE_ITEM_VIEW_TYPE;
- }
-
- private boolean isTextSizeAcceptable(TextView textView) {
- textView.measure(0, 0);
- int textWidth = textView.getMeasuredWidth();
- int checkMarkWidth = 76 + 20;
- return (textWidth <= (displayParameters.x - checkMarkWidth));
- }
-
- private boolean normalizeTextView() {
- int count = 0;
-// Log.d(TAG, "Normalizing the text view !!!!!!");
- while (!isTextSizeAcceptable(textViewItem)) {
- count++;
- float textSize = textViewItem.getTextSize();
-// Log.e(TAG, "The text size is: " + String.valueOf(textSize));
- textViewItem.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize - 2);
- this.notifyDataSetChanged();
- }
- return (count > 0);
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/breadwallet/tools/adapter/CustomPagerAdapter.java b/app/src/main/java/com/breadwallet/tools/adapter/CustomPagerAdapter.java
deleted file mode 100644
index 73984ebd8..000000000
--- a/app/src/main/java/com/breadwallet/tools/adapter/CustomPagerAdapter.java
+++ /dev/null
@@ -1,176 +0,0 @@
-package com.breadwallet.tools.adapter;
-
-import android.app.Fragment;
-import android.app.FragmentManager;
-import android.os.Handler;
-import android.support.v13.app.FragmentPagerAdapter;
-import android.view.View;
-import android.view.animation.AlphaAnimation;
-import android.view.animation.Animation;
-import android.view.animation.AnimationSet;
-import android.view.animation.TranslateAnimation;
-
-import com.breadwallet.presenter.activities.MainActivity;
-import com.breadwallet.presenter.fragments.MainFragment;
-import com.breadwallet.presenter.fragments.MainFragmentQR;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 5/23/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-public class CustomPagerAdapter extends FragmentPagerAdapter {
- private static final String TAG = CustomPagerAdapter.class.getName();
- public final MainFragment mainFragment;
- public final MainFragmentQR mainFragmentQR;
- private final List fragments;
- private final int ANIM_DURATION = 150;
- private View main;
- private View mainQR;
- public static CustomPagerAdapter adapter;
-
- public CustomPagerAdapter(FragmentManager fragmentManager) {
- super(fragmentManager);
-
- this.fragments = new ArrayList<>();
- mainFragment = new MainFragment();
- mainFragmentQR = new MainFragmentQR();
- fragments.add(mainFragment);
- fragments.add(mainFragmentQR);
- adapter = this;
-
- }
-
- @Override
- public int getCount() {
- return fragments.size();
- }
-
- @Override
- public Fragment getItem(int position) {
-
- return fragments.get(position);
- }
-
- /**
- * Show the fragments or hide, which is specified by the boolean parameter b
- *
- * @param b parameter that specifies to show or to hide the fragments
- */
- public void showFragments(boolean b, final MainActivity app) {
-// Log.w(TAG, "Warning showFragments called with variable: " + b);
- if (app == null) return;
- if (main == null) main = mainFragment.getView();
- if (mainQR == null) mainQR = mainFragmentQR.getView();
- if (b) {
- new Handler().post(new Runnable() {
-
- @Override
- public void run() {
- TranslateAnimation anim = new TranslateAnimation(0, 0, -600, 0);
- anim.setAnimationListener(new Animation.AnimationListener() {
- @Override
- public void onAnimationStart(Animation animation) {
-
- }
-
- @Override
- public void onAnimationEnd(Animation animation) {
- if (main != null) main.setVisibility(View.VISIBLE);
- if (mainQR != null) mainQR.setVisibility(View.VISIBLE);
- }
-
- @Override
- public void onAnimationRepeat(Animation animation) {
-
- }
- });
- anim.setDuration(ANIM_DURATION);
- Animation animation = new AlphaAnimation(0f, 1f);
- animation.setDuration(ANIM_DURATION);
- AnimationSet set = new AnimationSet(true);
- set.addAnimation(anim);
- set.addAnimation(animation);
- if (main != null) {
- main.startAnimation(set);
-// main.startAnimation(animation);
- }
- if (mainQR != null) {
- mainQR.startAnimation(set);
-// mainQR.startAnimation(animation);
- }
- app.pageIndicator.setVisibility(View.VISIBLE);
- if (MiddleViewAdapter.getSyncing()) {
- app.showHideSyncProgressViews(true);
- }
-
- }
- });
-
- } else {
- new Handler().post(new Runnable() {
-
- @Override
- public void run() {
- TranslateAnimation anim = new TranslateAnimation(0, 0, 0, -600);
- anim.setDuration(ANIM_DURATION);
- anim.setAnimationListener(new Animation.AnimationListener() {
- @Override
- public void onAnimationStart(Animation animation) {
-
- }
-
- @Override
- public void onAnimationEnd(Animation animation) {
- if (main != null) main.setVisibility(View.GONE);
- if (mainQR != null) mainQR.setVisibility(View.GONE);
- }
-
- @Override
- public void onAnimationRepeat(Animation animation) {
-
- }
- });
- Animation animation = new AlphaAnimation(1f, 0f);
- animation.setDuration(ANIM_DURATION);
- AnimationSet set = new AnimationSet(true);
- set.addAnimation(anim);
- set.addAnimation(animation);
- if (main != null) {
- main.startAnimation(set);
- }
- if (mainQR != null) {
- mainQR.startAnimation(set);
- }
- app.pageIndicator.setVisibility(View.GONE);
- app.showHideSyncProgressViews(false);
- }
- });
-
- }
- }
-
-}
diff --git a/app/src/main/java/com/breadwallet/tools/adapter/MiddleViewAdapter.java b/app/src/main/java/com/breadwallet/tools/adapter/MiddleViewAdapter.java
deleted file mode 100644
index 8c618f25f..000000000
--- a/app/src/main/java/com/breadwallet/tools/adapter/MiddleViewAdapter.java
+++ /dev/null
@@ -1,118 +0,0 @@
-package com.breadwallet.tools.adapter;
-
-import android.app.Activity;
-import android.util.Log;
-import android.view.WindowManager;
-
-import com.breadwallet.R;
-import com.breadwallet.BreadWalletApp;
-import com.breadwallet.presenter.activities.MainActivity;
-import com.breadwallet.presenter.fragments.FragmentSettings;
-import com.breadwallet.tools.animation.BRAnimator;
-import com.breadwallet.tools.util.BRConstants;
-import com.breadwallet.tools.util.BRStringFormatter;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 9/1/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-public class MiddleViewAdapter {
- private static final String TAG = MiddleViewAdapter.class.getName();
- private static boolean syncing = false;
-
- public static void resetMiddleView(Activity app, String text) {
-// Log.e(TAG, "in the resetMiddleView: " + text);
- if (syncing && (BRAnimator.level == 0 || BRAnimator.level == 1)) {
- try {
- ((BreadWalletApp) app.getApplication()).setTopMiddleView(BRConstants.BREAD_WALLET_TEXT, app.getString(R.string.syncing));
- } catch (NullPointerException ex) {
- ex.printStackTrace();
- }
- return;
- }
-
- if (text != null) {
- try {
- ((BreadWalletApp) app.getApplication()).setTopMiddleView(BRConstants.BREAD_WALLET_TEXT, text);
- } catch (Exception e) {
- e.printStackTrace();
- }
- return;
- }
- if (BRAnimator.level == 0 || BRAnimator.level == 1) {
- if (BreadWalletApp.unlocked) {
- try {
- String tmp = BRStringFormatter.getCurrentBalanceText(app);
- ((BreadWalletApp) app.getApplication()).setTopMiddleView(BRConstants.BREAD_WALLET_TEXT, tmp);
- } catch (Exception e) {
- e.printStackTrace();
- }
- } else {
- try {
- ((BreadWalletApp) app.getApplication()).setTopMiddleView(BRConstants.BREAD_WALLET_IMAGE, "");
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- } else if (BRAnimator.level == 2) {
- try {
- FragmentSettings myFragment = (FragmentSettings) app.getFragmentManager().findFragmentByTag(FragmentSettings.class.getName());
- if (myFragment != null && myFragment.isVisible()) {
- ((BreadWalletApp) app.getApplication()).setTopMiddleView(BRConstants.BREAD_WALLET_TEXT, app.getString(R.string.middle_view_settings));
- } else {
- ((BreadWalletApp) app.getApplication()).setTopMiddleView(BRConstants.BREAD_WALLET_TEXT, app.getString(R.string.middle_view_transaction_details));
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- } else {
- try {
- ((BreadWalletApp) app.getApplication()).setTopMiddleView(BRConstants.BREAD_WALLET_IMAGE, "");
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
-
- public static void setSyncing(Activity app, final boolean b) {
- Log.e(TAG,"setSyncing: " + b);
- if (app == null) app = MainActivity.app;
- final Activity finalApp = app;
- if (app == null) return;
- final Activity finalApp1 = app;
- app.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- syncing = b;
- if (!b) finalApp1.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
- resetMiddleView(finalApp, null);
- }
- });
-
- }
-
- public static boolean getSyncing() {
- return syncing;
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/breadwallet/tools/adapter/ParallaxViewPager.java b/app/src/main/java/com/breadwallet/tools/adapter/ParallaxViewPager.java
deleted file mode 100644
index 93b8248de..000000000
--- a/app/src/main/java/com/breadwallet/tools/adapter/ParallaxViewPager.java
+++ /dev/null
@@ -1,258 +0,0 @@
-package com.breadwallet.tools.adapter;
-
-import android.annotation.SuppressLint;
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.support.v4.view.ViewPager;
-import android.util.AttributeSet;
-import android.util.Log;
-
-import com.breadwallet.BreadWalletApp;
-import com.breadwallet.presenter.activities.MainActivity;
-import com.breadwallet.tools.animation.BRAnimator;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 6/29/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-@SuppressLint("NewApi")
-public class ParallaxViewPager extends ViewPager {
- public static final String TAG = ParallaxViewPager.class.getName();
-
- private static final int FIT_WIDTH = 0;
- private static final int FIT_HEIGHT = 1;
- public static final float OVERLAP_FULL = 1f;
- private static final float OVERLAP_HALF = 0.5f;
- public static final float OVERLAP_QUARTER = 0.25f;
- private static final float CORRECTION_PERCENTAGE = 0.01f;
- private Bitmap bitmap;
- private Rect source, destination;
- private int scaleType;
- private int chunkWidth;
- private int projectedWidth;
- private float overlap;
- private OnPageChangeListener secondOnPageChangeListener;
-
- public ParallaxViewPager(Context context) {
- super(context);
- init();
- }
-
-
- public ParallaxViewPager(Context context, AttributeSet attrs) {
- super(context, attrs);
- init();
- }
-
-
- private void init() {
- source = new Rect();
- destination = new Rect();
- scaleType = FIT_HEIGHT;
- overlap = OVERLAP_HALF;
-
-
- //noinspection deprecation
- setOnPageChangeListener(new OnPageChangeListener() {
- @Override
- public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
- if (bitmap != null) {
- source.left = (int) Math.floor((position + positionOffset - CORRECTION_PERCENTAGE) * chunkWidth);
- source.right = (int) Math.ceil((position + positionOffset + CORRECTION_PERCENTAGE) * chunkWidth + projectedWidth);
- destination.left = (int) Math.floor((position + positionOffset - CORRECTION_PERCENTAGE) * getWidth());
- destination.right = (int) Math.ceil((position + positionOffset + 1 + CORRECTION_PERCENTAGE) * getWidth());
- invalidate();
- }
-
- if (secondOnPageChangeListener != null) {
- secondOnPageChangeListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
- }
- }
-
- @Override
- public void onPageSelected(final int position) {
- if (secondOnPageChangeListener != null && BRAnimator.level == 0) {
- secondOnPageChangeListener.onPageSelected(position);
- }
- MainActivity app = MainActivity.app;
- if (app != null && BRAnimator.level == 0) {
- ((BreadWalletApp) app.getApplication()).cancelToast();
- ((BreadWalletApp) app.getApplication()).hideKeyboard(app);
- app.hideAllBubbles();
- app.setPagerIndicator(position);
- }
- }
-
- @Override
- public void onPageScrollStateChanged(int state) {
- if (secondOnPageChangeListener != null) {
- secondOnPageChangeListener.onPageScrollStateChanged(state);
- }
- }
- });
- }
-
- @Override
- protected void onSizeChanged(int w, int h, int oldw, int oldh) {
- super.onSizeChanged(w, h, oldw, oldh);
- destination.top = 0;
- destination.bottom = h;
- if (getAdapter() != null && bitmap != null)
- calculateParallaxParameters();
- }
-
- private void calculateParallaxParameters() {
- if (bitmap.getWidth() < getWidth() && bitmap.getWidth() < bitmap.getHeight() && scaleType == FIT_HEIGHT) {
- Log.w(ParallaxViewPager.class.getName(), "Invalid bitmap bounds for the current device, parallax effect will not work.");
- }
-
- final float ratio = (float) getHeight() / bitmap.getHeight();
- if (ratio != 1) {
- switch (scaleType) {
- case FIT_WIDTH:
- source.top = (int) ((bitmap.getHeight() - bitmap.getHeight() / ratio) / 2);
- source.bottom = bitmap.getHeight() - source.top;
- chunkWidth = (int) Math.ceil((float) bitmap.getWidth() / (float) getAdapter().getCount());
- projectedWidth = chunkWidth;
- break;
- case FIT_HEIGHT:
- default:
- source.top = 0;
- source.bottom = bitmap.getHeight();
- projectedWidth = (int) Math.ceil(getWidth() / ratio);
- chunkWidth = (int) Math.ceil((bitmap.getWidth() - projectedWidth) / (float) getAdapter().getCount() * overlap);
- break;
- }
- }
- }
-
-
- /**
- * Sets the background from a resource file.
- *
- * @param resid
- */
- @Override
- public void setBackgroundResource(int resid) {
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inScaled = true;
- options.inTargetDensity = 100;
- bitmap = BitmapFactory.decodeResource(getResources(), resid, options);
- }
-
-
- /**
- * Sets the background from a Drawable.
- *
- * @param background
- */
- @Override
- public void setBackground(Drawable background) {
- bitmap = ((BitmapDrawable) background).getBitmap();
- }
-
-
- /**
- * Deprecated.
- * Sets the background from a Drawable.
- *
- * @param background
- */
- @SuppressWarnings("deprecation")
- @Override
- public void setBackgroundDrawable(Drawable background) {
- bitmap = ((BitmapDrawable) background).getBitmap();
- }
-
-
- /**
- * Sets the background from a bitmap.
- *
- * @param bitmap
- * @return The ParallaxViewPager object itself.
- */
- public ParallaxViewPager setBackground(Bitmap bitmap) {
- this.bitmap = bitmap;
- return this;
- }
-
-
- /**
- * Sets how the view should scale the background. The available choices are:
- *
- * - FIT_HEIGHT - the height of the image is resized to matched the height of the View, also stretching the width to keep the aspect ratio. The non-visible part of the bitmap is divided into equal parts, each of them sliding in at the proper position.
- * - FIT_WIDTH - the width of the background image is divided into equal chunks, each taking up the whole width of the screen.
- *
- *
- * @param scaleType
- * @return
- */
- public ParallaxViewPager setScaleType(final int scaleType) {
- if (scaleType != FIT_WIDTH && scaleType != FIT_HEIGHT)
- throw new IllegalArgumentException("Illegal argument: scaleType must be FIT_WIDTH or FIT_HEIGHT");
- this.scaleType = scaleType;
- return this;
- }
-
-
- /**
- * Sets the amount of overlapping with the setOverlapPercentage(final float percentage) method. This is a number between 0 and 1, the smaller it is, the slower is the background scrolling.
- *
- * @param percentage
- * @return The ParallaxViewPager object itself.
- */
- public ParallaxViewPager setOverlapPercentage(final float percentage) {
- if (percentage <= 0 || percentage >= 1)
- throw new IllegalArgumentException("Illegal argument: percentage must be between 0 and 1");
- overlap = percentage;
- return this;
- }
-
-
- /**
- * Recalculates the parameters of the parallax effect, useful after changes in runtime.
- *
- * @return The ParallaxViewPager object itself.
- */
- public ParallaxViewPager invalidateParallaxParameters() {
- calculateParallaxParameters();
- return this;
- }
-
-
- @Override
- protected void onDraw(Canvas canvas) {
- if (bitmap != null)
- canvas.drawBitmap(bitmap, source, destination, null);
- }
-
- public void addOnPageChangeListener(OnPageChangeListener listener) {
- secondOnPageChangeListener = listener;
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/breadwallet/tools/adapter/TransactionListAdapter.java b/app/src/main/java/com/breadwallet/tools/adapter/TransactionListAdapter.java
index ad7e1af39..357b5fae7 100644
--- a/app/src/main/java/com/breadwallet/tools/adapter/TransactionListAdapter.java
+++ b/app/src/main/java/com/breadwallet/tools/adapter/TransactionListAdapter.java
@@ -1,305 +1,419 @@
package com.breadwallet.tools.adapter;
-import android.app.ActionBar;
import android.app.Activity;
import android.content.Context;
-import android.graphics.Color;
-import android.os.AsyncTask;
-import android.support.v4.content.ContextCompat;
-import android.util.Log;
+import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.BaseAdapter;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
-import com.breadwallet.BreadWalletApp;
+import androidx.constraintlayout.widget.ConstraintLayout;
+import androidx.constraintlayout.widget.ConstraintSet;
+import androidx.recyclerview.widget.RecyclerView;
+
import com.breadwallet.R;
-import com.breadwallet.presenter.activities.MainActivity;
-import com.breadwallet.presenter.entities.TransactionListItem;
-import com.breadwallet.presenter.fragments.FragmentSettings;
-import com.breadwallet.presenter.fragments.FragmentSettingsAll;
-import com.breadwallet.presenter.fragments.FragmentTransactionExpanded;
-import com.breadwallet.tools.animation.BRAnimator;
-import com.breadwallet.tools.manager.SharedPreferencesManager;
-import com.breadwallet.tools.util.BRConstants;
-import com.breadwallet.tools.util.BRStringFormatter;
+import com.breadwallet.presenter.entities.TxItem;
+import com.breadwallet.tools.manager.BRSharedPrefs;
+import com.breadwallet.tools.manager.PromptManager;
+import com.breadwallet.tools.manager.TxManager;
+import com.breadwallet.tools.threads.BRExecutor;
+import com.breadwallet.tools.util.BRCurrency;
+import com.breadwallet.tools.util.BRDateUtil;
+import com.breadwallet.tools.util.BRExchange;
import com.breadwallet.tools.util.Utils;
import com.breadwallet.wallet.BRPeerManager;
-import com.breadwallet.wallet.BRWalletManager;
-
+import com.platform.tools.KVStoreManager;
import java.math.BigDecimal;
import java.util.ArrayList;
-import java.util.Collections;
+import java.util.Date;
import java.util.List;
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 7/7/16.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-public class TransactionListAdapter extends BaseAdapter {
- public static final String TAG = TransactionListAdapter.class.getName();
-
- private Activity activity;
- private ArrayList data;
- private static LayoutInflater inflater = null;
- private static int unconfirmedColor;
- private static int sentColor;
- private static int receivedColor;
- public static boolean showAllTx = false;
-
- public TransactionListAdapter(Activity a, TransactionListItem[] d) {
- activity = a;
- data = new ArrayList<>();
- if (d != null)
- Collections.addAll(data, d);
- inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- unconfirmedColor = ContextCompat.getColor(a, R.color.white);
- sentColor = Color.parseColor("#FF5454");
- receivedColor = Color.parseColor("#00BF00");
+import timber.log.Timber;
+
+public class TransactionListAdapter extends RecyclerView.Adapter {
+ private final Context mContext;
+ private final int txResId;
+ private final int syncingResId;
+ private final int promptResId;
+ private List backUpFeed;
+ private List itemFeed;
+ // private Map mds;
+ private final int txType = 0;
+ private final int promptType = 1;
+ private final int syncingType = 2;
+ private boolean updatingReverseTxHash;
+ private boolean updatingData;
+
+ public TransactionListAdapter(Context mContext, List items) {
+ this.txResId = R.layout.tx_item;
+ this.syncingResId = R.layout.syncing_item;
+ this.promptResId = R.layout.prompt_item;
+ this.mContext = mContext;
+ items = new ArrayList<>();
+ init(items);
+ }
+
+ public void setItems(List items) {
+ init(items);
}
- public void updateData(TransactionListItem[] d) {
- if (d != null) {
- if (d.length != data.size()) {
- data.clear();
- Collections.addAll(data, d);
+ private void init(List items) {
+ if (items == null) items = new ArrayList<>();
+ if (itemFeed == null) itemFeed = new ArrayList<>();
+ if (backUpFeed == null) backUpFeed = new ArrayList<>();
+ this.itemFeed = items;
+ this.backUpFeed = items;
+ updateTxHashes();
+ }
+
+ public void updateData() {
+ if (updatingData) return;
+ BRExecutor.getInstance().forLightWeightBackgroundTasks().execute(new Runnable() {
+ @Override
+ public void run() {
+ long s = System.currentTimeMillis();
+ List newItems = new ArrayList<>(itemFeed);
+ TxItem item;
+ for (int i = 0; i < newItems.size(); i++) {
+ item = newItems.get(i);
+ item.metaData = KVStoreManager.getInstance().getTxMetaData(mContext, item.getTxHash());
+ item.txReversed = Utils.reverseHex(Utils.bytesToHex(item.getTxHash()));
+ }
+ backUpFeed = newItems;
+ Timber.d("timber: updateData: newItems: %d, took: %s", newItems.size(), System.currentTimeMillis() - s);
+ updatingData = false;
}
- }
- showAllTx = false;
- notifyDataSetChanged();
+ });
+ }
+
+ private void updateTxHashes() {
+ if (updatingReverseTxHash) return;
+ updatingReverseTxHash = true;
+
+ }
+
+ public List getItems() {
+ return itemFeed;
}
@Override
- public int getCount() {
- final int EXTRA_ITEMS = 4;
- if (!BreadWalletApp.unlocked) {
- return getUnconfirmedCount(data) == 0 ? (EXTRA_ITEMS + 1) : getUnconfirmedCount(data) == data.size()
- ? (getUnconfirmedCount(data) + EXTRA_ITEMS) : (getUnconfirmedCount(data) + EXTRA_ITEMS + 1);
- }
- if (data.size() == 0) return EXTRA_ITEMS + 1;
- return showAllTx ? (data.size() + EXTRA_ITEMS) : (data.size() > 5) ? (6 + EXTRA_ITEMS) : (data.size() + EXTRA_ITEMS);
+ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
+ if (viewType == txType)
+ return new TxHolder(inflater.inflate(txResId, parent, false));
+ else if (viewType == promptType)
+ return new PromptHolder(inflater.inflate(promptResId, parent, false));
+ else if (viewType == syncingType)
+ return new SyncingHolder(inflater.inflate(syncingResId, parent, false));
+ return null;
}
@Override
- public Object getItem(int position) {
- return data.get(position);
+ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
+ switch (holder.getItemViewType()) {
+ case txType:
+ setTexts((TxHolder) holder, position);
+ break;
+ case promptType:
+ setPrompt((PromptHolder) holder);
+ break;
+ case syncingType:
+ setSyncing((SyncingHolder) holder);
+ break;
+ }
}
@Override
- public long getItemId(int position) {
- return position;
+ public int getItemViewType(int position) {
+ if (position == 0 && TxManager.getInstance().currentPrompt == PromptManager.PromptItem.SYNCING) {
+ return syncingType;
+ } else if (position == 0 && TxManager.getInstance().currentPrompt != null) {
+ return promptType;
+ } else {
+ return txType;
+ }
}
@Override
- public View getView(int position, View convertView, ViewGroup viewGroup) {
- View tmpLayout = inflater.inflate(R.layout.transaction_list_item, null);
- if (data.size() == 0 && position == 0) {
- RelativeLayout noTransactions = (RelativeLayout) inflater.inflate(R.layout.button_no_transactions, null);
- noTransactions.setLayoutParams(new ActionBar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, Utils.getPixelsFromDps(activity, 70)));
- return noTransactions;
- } else if (position == getCount() - 4) {
- View separator = new View(activity);
- separator.setLayoutParams(new ActionBar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, Utils.getPixelsFromDps(activity, 30)));
- separator.setBackgroundResource(android.R.color.transparent);
- return separator;
- } else if (position == getCount() - 3) {
- RelativeLayout importPrivateKeys = (RelativeLayout) inflater.inflate(R.layout.button_import_privkey, null);
- importPrivateKeys.setLayoutParams(new ActionBar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, Utils.getPixelsFromDps(activity, 50)));
- importPrivateKeys.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- if (BRAnimator.checkTheMultipressingAvailability()) {
- BRAnimator.animateDecoderFragment();
- }
- }
- });
- return importPrivateKeys;
-
- } else if (position == getCount() - 2) {
- RelativeLayout settings = (RelativeLayout) inflater.inflate(R.layout.button_settings, null);
- settings.setLayoutParams(new ActionBar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, Utils.getPixelsFromDps(activity, 50)));
- settings.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (BRAnimator.checkTheMultipressingAvailability()) {
- MainActivity app = MainActivity.app;
- if (app == null) return;
- FragmentSettingsAll fragmentSettingsAll = (FragmentSettingsAll) activity.
- getFragmentManager().findFragmentByTag(FragmentSettingsAll.class.getName());
- BRAnimator.animateSlideToLeft(app, new FragmentSettings(), fragmentSettingsAll);
- }
- }
- });
- return settings;
- } else if (position == getCount() - 1) {
- View separator = new View(activity);
- separator.setLayoutParams(new ActionBar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, Utils.getPixelsFromDps(activity, 30)));
- separator.setBackgroundResource(android.R.color.transparent);
- separator.setClickable(false);
- return separator;
+ public int getItemCount() {
+ return TxManager.getInstance().currentPrompt == null ? itemFeed.size() : itemFeed.size() + 1;
+ }
+
+ private void setTexts(final TxHolder convertView, int position) {
+ TxItem item = itemFeed.get(TxManager.getInstance().currentPrompt == null ? position : position - 1);
+ item.metaData = KVStoreManager.getInstance().getTxMetaData(mContext, item.getTxHash());
+ String commentString = (item.metaData == null || item.metaData.comment == null) ? "" : item.metaData.comment;
+ convertView.comment.setText(commentString);
+ if (commentString.isEmpty()) {
+ convertView.constraintLayout.removeView(convertView.comment);
+ ConstraintSet set = new ConstraintSet();
+ set.clone(convertView.constraintLayout);
+ int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8, mContext.getResources().getDisplayMetrics());
+ set.connect(R.id.status, ConstraintSet.TOP, convertView.toFrom.getId(), ConstraintSet.BOTTOM, px);
+ // Apply the changes
+ set.applyTo(convertView.constraintLayout);
+ } else {
+ if (convertView.constraintLayout.indexOfChild(convertView.comment) == -1)
+ convertView.constraintLayout.addView(convertView.comment);
+ ConstraintSet set = new ConstraintSet();
+ set.clone(convertView.constraintLayout);
+ int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8, mContext.getResources().getDisplayMetrics());
+ set.connect(R.id.status, ConstraintSet.TOP, convertView.comment.getId(), ConstraintSet.BOTTOM, px);
+ // Apply the changes
+ set.applyTo(convertView.constraintLayout);
+ convertView.comment.requestLayout();
}
- if (!BreadWalletApp.unlocked) {
- if (getUnconfirmedCount(data) == 0 && position == 0) {
- RelativeLayout txHistory = (RelativeLayout) inflater.inflate(R.layout.button_transaction_history, null);
- txHistory.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, Utils.getPixelsFromDps(activity, 40)));
- txHistory.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (BRAnimator.checkTheMultipressingAvailability()) {
- ((BreadWalletApp) activity.getApplicationContext()).
- promptForAuthentication(activity, BRConstants.AUTH_FOR_GENERAL, null, null, null, null,false);
- }
- }
- });
- return txHistory;
- } else {
- if (position == getUnconfirmedCount(data)) {
- RelativeLayout moreAuth = (RelativeLayout) inflater.inflate(R.layout.button_more, null);
- moreAuth.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, Utils.getPixelsFromDps(activity, 40)));
- moreAuth.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (BRAnimator.checkTheMultipressingAvailability()) {
- ((BreadWalletApp) activity.getApplicationContext()).
- promptForAuthentication(activity, BRConstants.AUTH_FOR_GENERAL, null, null, null, null,false);
- }
- }
- });
- return moreAuth;
- } else {
- return getTxView(tmpLayout, position);
- }
- }
+ boolean received = item.getSent() == 0;
+ convertView.arrowIcon.setImageResource(received ? R.drawable.arrow_down_bold_circle : R.drawable.arrow_up_bold_circle);
+ convertView.mainLayout.setBackgroundResource(getResourceByPos(position));
+ convertView.sentReceived.setText(received ? mContext.getString(R.string.TransactionDetails_received, "") : mContext.getString(R.string.TransactionDetails_sent, ""));
+ convertView.toFrom.setText(received ? String.format(mContext.getString(R.string.TransactionDetails_from), "") : String.format(mContext.getString(R.string.TransactionDetails_to), ""));
+ final String addr = item.getTo()[0];
+ convertView.account.setText(addr);
+ int blockHeight = item.getBlockHeight();
+ int confirms = blockHeight == Integer.MAX_VALUE ? 0 : BRSharedPrefs.getLastBlockHeight(mContext) - blockHeight + 1;
+
+ int level = 0;
+ if (confirms <= 0) {
+ int relayCount = BRPeerManager.getRelayCount(item.getTxHash());
+ if (relayCount <= 0)
+ level = 0;
+ else if (relayCount == 1)
+ level = 1;
+ else
+ level = 2;
} else {
- if (showAllTx) return getTxView(tmpLayout, position);
- if (data.size() > 5) {
- if (position < 5) {
- return getTxView(tmpLayout, position);
- } else {
- RelativeLayout more = (RelativeLayout) inflater.inflate(R.layout.button_more, null);
- more.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, Utils.getPixelsFromDps(activity, 40)));
- more.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- showAllTx = true;
- notifyDataSetChanged();
- }
- });
- return more;
- }
- } else {
- return getTxView(tmpLayout, position);
- }
+ if (confirms == 1)
+ level = 3;
+ else if (confirms == 2)
+ level = 4;
+ else if (confirms == 3)
+ level = 5;
+ else
+ level = 6;
+ }
+ boolean availableForSpend = false;
+ String sentReceived = received ? "Receiving" : "Sending";
+ String percentage = "";
+ switch (level) {
+ case 0:
+ percentage = "0%";
+ break;
+ case 1:
+ percentage = "20%";
+ break;
+ case 2:
+ percentage = "40%";
+ availableForSpend = true;
+ break;
+ case 3:
+ percentage = "60%";
+ availableForSpend = true;
+ break;
+ case 4:
+ percentage = "80%";
+ availableForSpend = true;
+ break;
+ case 5:
+ percentage = "100%";
+ availableForSpend = true;
+ break;
+ }
+ if (availableForSpend && received) {
+ convertView.status_2.setText(mContext.getString(R.string.Transaction_available));
+ } else {
+ convertView.constraintLayout.removeView(convertView.status_2);
+ ConstraintSet set = new ConstraintSet();
+ set.clone(convertView.constraintLayout);
+ int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 16, mContext.getResources().getDisplayMetrics());
+
+ set.connect(R.id.status, ConstraintSet.BOTTOM, convertView.constraintLayout.getId(), ConstraintSet.BOTTOM, px);
+ // Apply the changes
+ set.applyTo(convertView.constraintLayout);
+ }
+ if (level == 6) {
+ convertView.status.setText(mContext.getString(R.string.Transaction_complete));
+ } else {
+ convertView.status.setText(String.format("%s - %s", sentReceived, percentage));
}
+
+ if (!item.isValid())
+ convertView.status.setText(mContext.getString(R.string.Transaction_invalid));
+
+ long satoshisAmount = received ? item.getReceived() : (item.getSent() - item.getReceived());
+
+ boolean isBTCPreferred = BRSharedPrefs.getPreferredLTC(mContext);
+ String iso = isBTCPreferred ? "LTC" : BRSharedPrefs.getIso(mContext);
+ convertView.amount.setText(BRCurrency.getFormattedCurrencyString(mContext, iso, BRExchange.getAmountFromSatoshis(mContext, iso, new BigDecimal(satoshisAmount))));
+
+ //if it's 0 we use the current time.
+ long timeStamp = item.getTimeStamp() == 0 ? System.currentTimeMillis() : item.getTimeStamp() * 1000;
+ CharSequence timeSpan = BRDateUtil.getCustomSpan(new Date(timeStamp));
+
+ convertView.timestamp.setText(timeSpan);
+
}
- public int getUnconfirmedCount(List items) {
- int count = 0;
- for (TransactionListItem t : items) {
- if (t == null) continue;
- int blockHeight = t.getBlockHeight();
- int confirms = blockHeight == Integer.MAX_VALUE ? 0 : SharedPreferencesManager.getLastBlockHeight(activity) - blockHeight + 1;
- if (blockHeight != Integer.MAX_VALUE && confirms < 6) {
- count++;
- }
+ private void setPrompt(final PromptHolder prompt) {
+ Timber.d("timber: setPrompt: %s", TxManager.getInstance().promptInfo.title);
+ if (TxManager.getInstance().promptInfo == null) {
+ throw new RuntimeException("can't happen, showing prompt with null PromptInfo");
}
- return count;
+
+ prompt.mainLayout.setOnClickListener(TxManager.getInstance().promptInfo.listener);
+ prompt.mainLayout.setBackgroundResource(R.drawable.tx_rounded);
+ prompt.title.setText(TxManager.getInstance().promptInfo.title);
+ prompt.description.setText(TxManager.getInstance().promptInfo.description);
}
- @Override
- public int getViewTypeCount() {
- return 2;
+ private void setSyncing(final SyncingHolder syncing) {
+ TxManager.getInstance().syncingHolder = syncing;
+ syncing.mainLayout.setBackgroundResource(R.drawable.tx_rounded);
}
- public View getTxView(View tmpLayout, int position) {
- TextView sentReceivedTextView = (TextView) tmpLayout.findViewById(R.id.transaction_sent_received_label);
- TextView dateTextView = (TextView) tmpLayout.findViewById(R.id.transaction_date);
- TextView bitsTextView = (TextView) tmpLayout.findViewById(R.id.transaction_amount_bits);
- TextView dollarsTextView = (TextView) tmpLayout.findViewById(R.id.transaction_amount_dollars);
- TextView bitsTotalTextView = (TextView) tmpLayout.findViewById(R.id.transaction_amount_bits_total);
- TextView dollarsTotalTextView = (TextView) tmpLayout.findViewById(R.id.transaction_amount_dollars_total);
- Utils.overrideFonts(sentReceivedTextView, dateTextView, bitsTextView, dollarsTextView, bitsTotalTextView, dollarsTotalTextView);
- tmpLayout.setBackgroundResource(R.drawable.clickable_layout);
- final TransactionListItem item = data.get(position);
-
- tmpLayout.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (BRAnimator.checkTheMultipressingAvailability()) {
- FragmentSettingsAll fragmentSettingsAll = (FragmentSettingsAll) activity.
- getFragmentManager().findFragmentByTag(FragmentSettingsAll.class.getName());
- FragmentTransactionExpanded fragmentTransactionExpanded = new FragmentTransactionExpanded();
- fragmentTransactionExpanded.setCurrentObject(item);
- BRAnimator.animateSlideToLeft((MainActivity) activity, fragmentTransactionExpanded, fragmentSettingsAll);
+ private int getResourceByPos(int pos) {
+ if (TxManager.getInstance().currentPrompt != null) pos--;
+ if (itemFeed != null && itemFeed.size() == 1) {
+ return R.drawable.tx_rounded;
+ } else if (pos == 0) {
+ return R.drawable.tx_rounded_up;
+ } else if (itemFeed != null && pos == itemFeed.size() - 1) {
+ return R.drawable.tx_rounded_down;
+ } else {
+ return R.drawable.tx_not_rounded;
+ }
+ }
+
+
+ public void filterBy(String query, boolean[] switches) {
+ filter(query, switches);
+ }
+
+ public void resetFilter() {
+ itemFeed = backUpFeed;
+ notifyDataSetChanged();
+ }
+
+ private void filter(final String query, final boolean[] switches) {
+ long start = System.currentTimeMillis();
+ String lowerQuery = query.toLowerCase().trim();
+ if (Utils.isNullOrEmpty(lowerQuery) && !switches[0] && !switches[1] && !switches[2] && !switches[3])
+ return;
+ int switchesON = 0;
+ for (boolean i : switches) if (i) switchesON++;
+
+ final List filteredList = new ArrayList<>();
+ TxItem item;
+ for (int i = 0; i < backUpFeed.size(); i++) {
+ item = backUpFeed.get(i);
+ boolean matchesHash = item.getTxHashHexReversed() != null && item.getTxHashHexReversed().contains(lowerQuery);
+ boolean matchesAddress = item.getFrom()[0].contains(lowerQuery) || item.getTo()[0].contains(lowerQuery);
+ boolean matchesMemo = item.metaData != null && item.metaData.comment != null && item.metaData.comment.toLowerCase().contains(lowerQuery);
+ if (matchesHash || matchesAddress || matchesMemo) {
+ if (switchesON == 0) {
+ filteredList.add(item);
+ } else {
+ boolean willAdd = true;
+ //filter by sent and this is received
+ if (switches[0] && (item.getSent() - item.getReceived() <= 0)) {
+ willAdd = false;
+ }
+ //filter by received and this is sent
+ if (switches[1] && (item.getSent() - item.getReceived() > 0)) {
+ willAdd = false;
+ }
+
+ int confirms = item.getBlockHeight() == Integer.MAX_VALUE ? 0 : BRSharedPrefs.getLastBlockHeight(mContext) - item.getBlockHeight() + 1;
+ //complete
+ if (switches[2] && confirms >= 6) {
+ willAdd = false;
+ }
+
+ //pending
+ if (switches[3] && confirms < 6) {
+ willAdd = false;
+ }
+
+ if (willAdd) filteredList.add(item);
}
+
}
- });
- boolean received = item.getSent() == 0;
- int blockHeight = item.getBlockHeight();
+ }
+ itemFeed = filteredList;
+ notifyDataSetChanged();
+
+ Timber.d("timber: filter: %s took: %s", query, System.currentTimeMillis() - start);
+ }
- int confirms = blockHeight == Integer.MAX_VALUE ? 0 : SharedPreferencesManager.getLastBlockHeight(activity) - blockHeight + 1;
+ private class TxHolder extends RecyclerView.ViewHolder {
+ public RelativeLayout mainLayout;
+ public ConstraintLayout constraintLayout;
+ public TextView sentReceived;
+ public TextView amount;
+ public TextView toFrom;
+ public TextView account;
+ public TextView status;
+ public TextView status_2;
+ public TextView timestamp;
+ public TextView comment;
+ public ImageView arrowIcon;
- if (item.getSent() > 0 && item.getSent() == item.getReceived()) {
- sentReceivedTextView.setBackgroundResource(R.drawable.unconfirmed_label);
- sentReceivedTextView.setText(R.string.moved);
- sentReceivedTextView.setTextColor(unconfirmedColor);
- } else if (blockHeight != Integer.MAX_VALUE && confirms >= 6) {
- sentReceivedTextView.setBackgroundResource(received ? R.drawable.received_label : R.drawable.sent_label);
- sentReceivedTextView.setText(received ? R.string.received : R.string.sent);
- sentReceivedTextView.setTextColor(received ? receivedColor : sentColor);
- } else {
- sentReceivedTextView.setBackgroundResource(R.drawable.unconfirmed_label);
- sentReceivedTextView.setTextColor(unconfirmedColor);
- if (!BRWalletManager.getInstance(activity).transactionIsVerified(item.getHexId())) {
- sentReceivedTextView.setText(R.string.unverified);
- } else {
- int confsNr = confirms >= 0 && confirms <= 5 ? confirms : 0;
- String message = confsNr == 0 ? activity.getString(R.string.nr_confirmations0) :
- (confsNr == 1 ? activity.getString(R.string.nr_confirmations1) : String.format(activity.getString(R.string.nr_confirmations), confsNr));
-
- sentReceivedTextView.setText(message);
- }
+ public TxHolder(View view) {
+ super(view);
+ mainLayout = (RelativeLayout) view.findViewById(R.id.main_layout);
+ constraintLayout = (ConstraintLayout) view.findViewById(R.id.constraintLayout);
+ sentReceived = (TextView) view.findViewById(R.id.sent_received);
+ amount = (TextView) view.findViewById(R.id.amount);
+ toFrom = (TextView) view.findViewById(R.id.to_from);
+ account = (TextView) view.findViewById(R.id.account);
+ status = (TextView) view.findViewById(R.id.status);
+ status_2 = (TextView) view.findViewById(R.id.status_2);
+ timestamp = (TextView) view.findViewById(R.id.timestamp);
+ comment = (TextView) view.findViewById(R.id.comment);
+ arrowIcon = (ImageView) view.findViewById(R.id.arrow_icon);
}
+ }
- long itemTimeStamp = item.getTimeStamp();
- dateTextView.setText(itemTimeStamp != 0 ? Utils.getFormattedDateFromLong(itemTimeStamp * 1000) : Utils.getFormattedDateFromLong(System.currentTimeMillis()));
+ public class PromptHolder extends RecyclerView.ViewHolder {
+ public RelativeLayout mainLayout;
+ public ConstraintLayout constraintLayout;
+ public TextView title;
+ public TextView description;
+ public ImageButton close;
- long satoshisAmount = received ? item.getReceived() : (item.getSent() - item.getReceived()) * -1;
+ public PromptHolder(View view) {
+ super(view);
+ mainLayout = (RelativeLayout) view.findViewById(R.id.main_layout);
+ constraintLayout = (ConstraintLayout) view.findViewById(R.id.prompt_layout);
+ title = view.findViewById(R.id.info_title);
+ description = view.findViewById(R.id.info_description);
+ close = (ImageButton) view.findViewById(R.id.info_close_button);
+ }
+ }
- bitsTextView.setText(BRStringFormatter.getFormattedCurrencyString("BTC", satoshisAmount));
- dollarsTextView.setText(String.format("(%s)", BRStringFormatter.getExchangeForAmount(SharedPreferencesManager.getRate(activity),
- SharedPreferencesManager.getIso(activity), new BigDecimal(satoshisAmount), activity)));
- long satoshisAfterTx = item.getBalanceAfterTx();
+ public class SyncingHolder extends RecyclerView.ViewHolder {
+ public RelativeLayout mainLayout;
+ public ConstraintLayout constraintLayout;
+ public TextView date;
+ public TextView label;
+ public ProgressBar progress;
- bitsTotalTextView.setText(BRStringFormatter.getFormattedCurrencyString("BTC", satoshisAfterTx));
- dollarsTotalTextView.setText(String.format("(%s)", BRStringFormatter.getExchangeForAmount(SharedPreferencesManager.getRate(activity),
- SharedPreferencesManager.getIso(activity), new BigDecimal(satoshisAfterTx), activity)));
- return tmpLayout;
+ public SyncingHolder(View view) {
+ super(view);
+ mainLayout = (RelativeLayout) view.findViewById(R.id.main_layout);
+ constraintLayout = (ConstraintLayout) view.findViewById(R.id.syncing_layout);
+ date = view.findViewById(R.id.sync_date);
+ label = view.findViewById(R.id.syncing_label);
+ progress = (ProgressBar) view.findViewById(R.id.sync_progress);
+ }
}
+
}
\ No newline at end of file
diff --git a/app/src/main/java/com/breadwallet/tools/adapter/TransactionPagerAdapter.java b/app/src/main/java/com/breadwallet/tools/adapter/TransactionPagerAdapter.java
new file mode 100644
index 000000000..e38b8087c
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/tools/adapter/TransactionPagerAdapter.java
@@ -0,0 +1,36 @@
+package com.breadwallet.tools.adapter;
+
+import android.app.Fragment;
+import android.app.FragmentManager;
+import androidx.legacy.app.FragmentPagerAdapter;
+
+import com.breadwallet.presenter.entities.TxItem;
+import com.breadwallet.presenter.fragments.FragmentTransactionItem;
+
+import java.util.List;
+
+public class TransactionPagerAdapter extends FragmentPagerAdapter {
+ private static final String TAG = TransactionPagerAdapter.class.getName();
+ private List items;
+
+ public TransactionPagerAdapter(FragmentManager fm, List items) {
+ super(fm);
+ this.items = items;
+
+ }
+
+ public TransactionPagerAdapter(FragmentManager fm){
+ super(fm);
+ }
+
+ @Override
+ public Fragment getItem(int pos) {
+ return FragmentTransactionItem.newInstance(items.get(pos));
+ }
+
+ @Override
+ public int getCount() {
+ return items == null ? 0 : items.size();
+ }
+
+}
diff --git a/app/src/main/java/com/breadwallet/tools/animation/BRAnimator.java b/app/src/main/java/com/breadwallet/tools/animation/BRAnimator.java
index a1d3eeeee..5c9a3cffe 100644
--- a/app/src/main/java/com/breadwallet/tools/animation/BRAnimator.java
+++ b/app/src/main/java/com/breadwallet/tools/animation/BRAnimator.java
@@ -1,567 +1,389 @@
package com.breadwallet.tools.animation;
import android.Manifest;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ArgbEvaluator;
+import android.animation.LayoutTransition;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.animation.ValueAnimator;
import android.app.Activity;
-import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
-import android.content.Context;
+import android.content.Intent;
import android.content.pm.PackageManager;
-import android.os.Handler;
-import android.support.v4.app.ActivityCompat;
-import android.support.v4.content.ContextCompat;
-import android.util.Log;
+import android.os.Bundle;
import android.view.View;
-import android.view.animation.AlphaAnimation;
-import android.view.animation.Animation;
-import android.view.animation.ScaleAnimation;
-import android.view.animation.TranslateAnimation;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.ImageView;
-import android.widget.RelativeLayout;
-import android.widget.TextView;
+import android.view.ViewGroup;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.OvershootInterpolator;
import android.widget.Toast;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
+import androidx.fragment.app.FragmentActivity;
+
import com.breadwallet.R;
-import com.breadwallet.BreadWalletApp;
-import com.breadwallet.presenter.activities.MainActivity;
-import com.breadwallet.presenter.fragments.FragmentDecoder;
-import com.breadwallet.presenter.fragments.FragmentScanResult;
-import com.breadwallet.presenter.fragments.FragmentSettings;
-import com.breadwallet.presenter.fragments.FragmentSettingsAll;
-import com.breadwallet.presenter.fragments.MainFragment;
-import com.breadwallet.tools.adapter.MiddleViewAdapter;
-import com.breadwallet.tools.manager.BRClipboardManager;
+import com.breadwallet.presenter.activities.BreadActivity;
+import com.breadwallet.presenter.activities.LoginActivity;
+import com.breadwallet.presenter.activities.camera.CameraActivity;
+import com.breadwallet.presenter.activities.camera.ScanQRActivity;
+import com.breadwallet.presenter.customviews.BRDialogView;
+import com.breadwallet.presenter.entities.TxItem;
+import com.breadwallet.presenter.fragments.DynamicDonationFragment;
+import com.breadwallet.presenter.fragments.FragmentBalanceSeedReminder;
+import com.breadwallet.presenter.fragments.FragmentBuy;
+import com.breadwallet.presenter.fragments.FragmentGreetings;
+import com.breadwallet.presenter.fragments.FragmentMenu;
+import com.breadwallet.presenter.fragments.FragmentReceive;
+import com.breadwallet.presenter.fragments.FragmentRequestAmount;
+import com.breadwallet.presenter.fragments.FragmentSend;
+import com.breadwallet.presenter.fragments.FragmentSignal;
+import com.breadwallet.presenter.fragments.FragmentTransactionDetails;
+import com.breadwallet.presenter.interfaces.BROnSignalCompletion;
+import com.breadwallet.tools.threads.BRExecutor;
import com.breadwallet.tools.util.BRConstants;
-import com.breadwallet.tools.adapter.CustomPagerAdapter;
-
-import java.util.Stack;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 7/13/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
+import com.breadwallet.tools.util.Utils;
+
+import java.util.List;
+
+import timber.log.Timber;
public class BRAnimator {
- private static final String TAG = BRAnimator.class.getName();
- public static boolean decoderFragmentOn;
- public static boolean scanResultFragmentOn;
- public static int level = 0;
- public static boolean wipeWalletOpen = false;
- private static Stack previous = new Stack<>();
- private static boolean multiplePressingAvailable = true;
- public static int horizontalSlideDuration = 300;
- private static boolean horizontalSlideAvailable = true;
- private static View copy;
-
- public static void animateDecoderFragment() {
+ private static FragmentSignal fragmentSignal;
+ private static boolean clickAllowed = true;
+ public static int SLIDE_ANIMATION_DURATION = 300;
+ public static boolean supportIsShowing;
+
+ public static void showBreadSignal(Activity activity, String title, String iconDescription, int drawableId, BROnSignalCompletion completion) {
+ fragmentSignal = new FragmentSignal();
+ Bundle bundle = new Bundle();
+ bundle.putString(FragmentSignal.TITLE, title);
+ bundle.putString(FragmentSignal.ICON_DESCRIPTION, iconDescription);
+ fragmentSignal.setCompletion(completion);
+ bundle.putInt(FragmentSignal.RES_ID, drawableId);
+ fragmentSignal.setArguments(bundle);
+ FragmentTransaction transaction = activity.getFragmentManager().beginTransaction();
+ transaction.setCustomAnimations(R.animator.from_bottom, R.animator.to_bottom, R.animator.from_bottom, R.animator.to_bottom);
+ transaction.add(android.R.id.content, fragmentSignal, fragmentSignal.getClass().getName());
+ transaction.addToBackStack(null);
+ if (!activity.isDestroyed())
+ transaction.commit();
+ }
+
+ public static void showBalanceSeedFragment(@NonNull FragmentActivity app) {
+ Timber.d("timber: fetched info");
+
+ androidx.fragment.app.FragmentManager fragmentManager = app.getSupportFragmentManager();
+ FragmentBalanceSeedReminder fragmentBalanceSeedReminder = (FragmentBalanceSeedReminder) fragmentManager.findFragmentByTag(FragmentBalanceSeedReminder.class.getName());
+ if (fragmentBalanceSeedReminder != null) {
+ fragmentBalanceSeedReminder.fetchSeedPhrase();
+ Timber.d("timber: fetched seed phrase");
+ return;
+ }
+
+ try {
+ fragmentBalanceSeedReminder = new FragmentBalanceSeedReminder();
+ fragmentManager.beginTransaction()
+ .setCustomAnimations(0, 0, 0, R.animator.plain_300)
+ .add(android.R.id.content, fragmentBalanceSeedReminder, FragmentBalanceSeedReminder.class.getName())
+ .addToBackStack(FragmentBalanceSeedReminder.class.getName()).commit();
+ } finally {
+ }
+ }
+ public static void showSendFragment(FragmentActivity app, final String bitcoinUrl) {
+ if (app == null) {
+ Timber.i("timber: showSendFragment: app is null");
+ return;
+ }
+ androidx.fragment.app.FragmentManager fragmentManager = app.getSupportFragmentManager();
+ FragmentSend fragmentSend = (FragmentSend) fragmentManager.findFragmentByTag(FragmentSend.class.getName());
+ if (fragmentSend != null && fragmentSend.isAdded()) {
+ fragmentSend.setUrl(bitcoinUrl);
+ return;
+ }
+ try {
+ fragmentSend = new FragmentSend();
+ if (bitcoinUrl != null && !bitcoinUrl.isEmpty()) {
+ Bundle bundle = new Bundle();
+ bundle.putString("url", bitcoinUrl);
+ fragmentSend.setArguments(bundle);
+ }
+ fragmentManager.beginTransaction()
+ .setCustomAnimations(0, 0, 0, R.animator.plain_300)
+ .add(android.R.id.content, fragmentSend, FragmentSend.class.getName())
+ .addToBackStack(FragmentSend.class.getName()).commit();
+ } finally {
+ }
+ }
+
+ public static void popBackStackTillEntry(Activity app, int entryIndex) {
+
+ if (app.getFragmentManager() == null) {
+ return;
+ }
+ if (app.getFragmentManager().getBackStackEntryCount() <= entryIndex) {
+ return;
+ }
+ FragmentManager.BackStackEntry entry = app.getFragmentManager().getBackStackEntryAt(
+ entryIndex);
+ if (entry != null) {
+ app.getFragmentManager().popBackStackImmediate(entry.getId(),
+ FragmentManager.POP_BACK_STACK_INCLUSIVE);
+ }
+ }
+
+ public static void showTransactionPager(Activity app, List items, int position) {
+ if (app == null) {
+ Timber.i("timber: showSendFragment: app is null");
+ return;
+ }
+ FragmentTransactionDetails fragmentTransactionDetails = (FragmentTransactionDetails) app.getFragmentManager().findFragmentByTag(FragmentTransactionDetails.class.getName());
+ if (fragmentTransactionDetails != null && fragmentTransactionDetails.isAdded()) {
+ fragmentTransactionDetails.setItems(items);
+ Timber.i("timber: showTransactionPager: Already showing");
+ return;
+ }
+ fragmentTransactionDetails = new FragmentTransactionDetails();
+ fragmentTransactionDetails.setItems(items);
+ Bundle bundle = new Bundle();
+ bundle.putInt("pos", position);
+ fragmentTransactionDetails.setArguments(bundle);
+
+ app.getFragmentManager().beginTransaction()
+ .setCustomAnimations(0, 0, 0, R.animator.plain_300)
+ .add(android.R.id.content, fragmentTransactionDetails, FragmentTransactionDetails.class.getName())
+ .addToBackStack(FragmentTransactionDetails.class.getName()).commit();
+
+ }
+
+ public static void openScanner(Activity app, int requestID) {
try {
- MainActivity app = MainActivity.app;
if (app == null) return;
- // Here, thisActivity is the current activity
+ // Check if the camera permission is granted
if (ContextCompat.checkSelfPermission(app,
Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(app,
Manifest.permission.CAMERA)) {
- Log.e(TAG, "YES explanation!");
- ((BreadWalletApp) app.getApplication()).showCustomToast(app,
- app.getString(R.string.allow_camera_access),
- MainActivity.screenParametersPoint.y / 2, Toast.LENGTH_LONG, 0);
+ BRDialog.showCustomDialog(app, app.getString(R.string.Send_cameraUnavailabeTitle_android), app.getString(R.string.Send_cameraUnavailabeMessage_android), app.getString(R.string.AccessibilityLabels_close), null, new BRDialogView.BROnClickListener() {
+ @Override
+ public void onClick(BRDialogView brDialogView) {
+ brDialogView.dismiss();
+ }
+ }, null, null, 0);
} else {
- Log.e(TAG, "NO explanation!");
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(app,
new String[]{Manifest.permission.CAMERA},
BRConstants.CAMERA_REQUEST_ID);
}
} else {
- if (BRAnimator.level > 0)
- BRAnimator.pressMenuButton(app);
- decoderFragmentOn = true;
- app.activityButtonsEnable(false);
- CustomPagerAdapter.adapter.showFragments(false, app);
- //Disabled inspection:
- FragmentTransaction fragmentTransaction = app.getFragmentManager().beginTransaction();
- fragmentTransaction.setCustomAnimations(R.animator.from_bottom, R.animator.to_top);
- FragmentDecoder fragmentDecoder = new FragmentDecoder();
- fragmentTransaction.replace(R.id.main_layout, fragmentDecoder, FragmentDecoder.class.getName());
- int temp = fragmentTransaction.commit();
+ // Permission is granted, open camera
+ Intent intent = new Intent(app, ScanQRActivity.class);
+ app.startActivityForResult(intent, requestID);
+ app.overridePendingTransition(R.anim.fade_up, R.anim.fade_down);
}
} catch (Exception e) {
- e.printStackTrace();
+ Timber.e(e);
}
}
- public static void animateScanResultFragment() {
- try {
- final MainActivity app = MainActivity.app;
- if (app == null || scanResultFragmentOn) return;
- CustomPagerAdapter.adapter.showFragments(false, app);
- scanResultFragmentOn = true;
- InputMethodManager keyboard = (InputMethodManager) app.
- getSystemService(Context.INPUT_METHOD_SERVICE);
-
- try {
- keyboard.hideSoftInputFromWindow(CustomPagerAdapter.adapter.
- mainFragment.addressEditText.getWindowToken(), 0);
- } catch (Exception e) {
- e.printStackTrace();
- }
- app.setBurgerButtonImage(BRConstants.BACK);
- //Disabled inspection:
- final FragmentManager fragmentManager = app.getFragmentManager();
- final FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
-
- final FragmentScanResult scanResult = new FragmentScanResult();
- fragmentTransaction.replace(R.id.main_layout, scanResult, FragmentScanResult.class.getName());
- fragmentTransaction.commit();
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- TranslateAnimation trans = new TranslateAnimation(MainActivity.screenParametersPoint.x, 0, 0, 0);
- trans.setDuration(500);
- trans.setInterpolator(new DecelerateOvershootInterpolator(3f, 0.5f));
- View view = scanResult.getView();
- if (view != null)
- view.startAnimation(trans);
- }
- }, 1);
- } catch (Exception e) {
- e.printStackTrace();
- }
+ public static LayoutTransition getDefaultTransition() {
+ LayoutTransition itemLayoutTransition = new LayoutTransition();
+ itemLayoutTransition.setStartDelay(LayoutTransition.APPEARING, 0);
+ itemLayoutTransition.setStartDelay(LayoutTransition.DISAPPEARING, 0);
+ itemLayoutTransition.setStartDelay(LayoutTransition.CHANGE_APPEARING, 0);
+ itemLayoutTransition.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, 0);
+ itemLayoutTransition.setStartDelay(LayoutTransition.CHANGING, 0);
+ itemLayoutTransition.setDuration(100);
+ itemLayoutTransition.setInterpolator(LayoutTransition.CHANGING, new OvershootInterpolator(2f));
+ Animator scaleUp = ObjectAnimator.ofPropertyValuesHolder((Object) null, PropertyValuesHolder.ofFloat(View.SCALE_X, 1, 1), PropertyValuesHolder.ofFloat(View.SCALE_Y, 0, 1));
+ scaleUp.setDuration(50);
+ scaleUp.setStartDelay(50);
+ Animator scaleDown = ObjectAnimator.ofPropertyValuesHolder((Object) null, PropertyValuesHolder.ofFloat(View.SCALE_X, 1, 1), PropertyValuesHolder.ofFloat(View.SCALE_Y, 1, 0));
+ scaleDown.setDuration(2);
+ itemLayoutTransition.setAnimator(LayoutTransition.APPEARING, scaleUp);
+ itemLayoutTransition.setAnimator(LayoutTransition.DISAPPEARING, null);
+ itemLayoutTransition.enableTransitionType(LayoutTransition.CHANGING);
+ return itemLayoutTransition;
}
- /**
- * Animate the transition on burgerButton/MenuButton pressed
- */
- public static void pressMenuButton(final MainActivity context) {
- try {
- if (context == null) return;
- ((BreadWalletApp) context.getApplication()).cancelToast();
- final FragmentManager fragmentManager = context.getFragmentManager();
- if (level == 0) {
- level++;
- CustomPagerAdapter.adapter.showFragments(false, context);
- context.setBurgerButtonImage(BRConstants.CLOSE);
- FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
- FragmentSettingsAll to = (FragmentSettingsAll) fragmentManager.
- findFragmentByTag(FragmentSettingsAll.class.getName());
- if (to == null) to = new FragmentSettingsAll();
- fragmentTransaction.add(R.id.main_layout, to, FragmentSettingsAll.class.getName());
- fragmentTransaction.commit();
- final FragmentSettingsAll finalTo = to;
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- TranslateAnimation trans = new TranslateAnimation(0, 0, 1920, 0);
- trans.setDuration(500);
- trans.setInterpolator(new DecelerateOvershootInterpolator(3f, 0.5f));
- View view = finalTo.getView();
- if (view != null)
- view.startAnimation(trans);
- }
- }, 1);
-
- InputMethodManager keyboard = (InputMethodManager) context.
- getSystemService(Context.INPUT_METHOD_SERVICE);
-
- if (keyboard != null)
- keyboard.hideSoftInputFromWindow(CustomPagerAdapter.adapter.
- mainFragment.addressEditText.getWindowToken(), 0);
- } else if (level == 1) {
- level--;
- context.setBurgerButtonImage(BRConstants.BURGER);
- FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
- fragmentTransaction.setCustomAnimations(R.animator.from_top, R.animator.to_bottom);
- FragmentSettingsAll fragmentSettingsAll = (FragmentSettingsAll) fragmentManager.
- findFragmentByTag(FragmentSettingsAll.class.getName());
- fragmentTransaction.remove(fragmentSettingsAll);
- fragmentTransaction.commit();
- CustomPagerAdapter.adapter.showFragments(true, context);
- }
- } catch (Exception e) {
- e.printStackTrace();
+ public static void showRequestFragment(Activity app, String address) {
+ if (app == null) {
+ Timber.i("timber: showRequestFragment: app is null");
+ return;
+ }
+ if (Utils.isNullOrEmpty(address)) {
+ Timber.i("timber: showRequestFragment: address is empty");
+ return;
}
- }
- /**
- * Animate the transition on wipe wallet fragment
- */
- public static void pressWipeWallet(final MainActivity context, final Fragment to) {
- try {
- if (!wipeWalletOpen) {
- wipeWalletOpen = true;
- FragmentTransaction fragmentTransaction = context.getFragmentManager().beginTransaction();
- // fragmentTransaction.setCustomAnimations(R.animator.from_bottom, R.animator.to_top);
- fragmentTransaction.replace(R.id.main_layout, to, to.getClass().getName());
- fragmentTransaction.commit();
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- TranslateAnimation trans = new TranslateAnimation(0, 0, 1920, 0);
- trans.setDuration(500);
- trans.setInterpolator(new DecelerateOvershootInterpolator(3f, 0.5f));
- View view = to.getView();
- if (view != null)
- view.startAnimation(trans);
- }
- }, 1);
+ FragmentRequestAmount fragmentRequestAmount = (FragmentRequestAmount) app.getFragmentManager().findFragmentByTag(FragmentRequestAmount.class.getName());
+ if (fragmentRequestAmount != null && fragmentRequestAmount.isAdded())
+ return;
+
+ fragmentRequestAmount = new FragmentRequestAmount();
+ Bundle bundle = new Bundle();
+ bundle.putString("address", address);
+ fragmentRequestAmount.setArguments(bundle);
+ app.getFragmentManager().beginTransaction()
+ .setCustomAnimations(0, 0, 0, R.animator.plain_300)
+ .add(android.R.id.content, fragmentRequestAmount, FragmentRequestAmount.class.getName())
+ .addToBackStack(FragmentRequestAmount.class.getName()).commit();
- } else {
- wipeWalletOpen = false;
- FragmentTransaction fragmentTransaction = context.getFragmentManager().beginTransaction();
- fragmentTransaction.setCustomAnimations(R.animator.from_top, R.animator.to_bottom);
- fragmentTransaction.replace(R.id.main_layout, new FragmentSettings(), FragmentSettings.class.getName());
- fragmentTransaction.commit();
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
}
- /**
- * Animates the fragment transition on button_regular_blue "Settings" pressed
- */
- public static void animateSlideToLeft(final MainActivity context, final Fragment to, Fragment previousFragment) {
- try {
- if (!checkTheHorizontalSlideAvailability()) return;
- level++;
- if (level > 1)
- context.setBurgerButtonImage(BRConstants.BACK);
- FragmentTransaction fragmentTransaction = context.getFragmentManager().beginTransaction();
-// fragmentTransaction.setCustomAnimations(R.animator.from_right, R.animator.to_left);
- fragmentTransaction.replace(R.id.main_layout, to, to.getClass().getName());
- if (previousFragment != null)
- previous.add(previousFragment);
- fragmentTransaction.commit();
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- TranslateAnimation trans = new TranslateAnimation(MainActivity.screenParametersPoint.x, 0, 0, 0);
- trans.setDuration(horizontalSlideDuration);
- trans.setInterpolator(new DecelerateOvershootInterpolator(1f, 0.5f));
- View view = to.getView();
- if (view != null)
- view.startAnimation(trans);
- }
- }, 1);
- } catch (Exception e) {
- e.printStackTrace();
+ //isReceive tells the Animator that the Receive fragment is requested, not My Address
+ public static void showReceiveFragment(Activity app, boolean isReceive) {
+ if (app == null) {
+ Timber.i("timber: showReceiveFragment: app is null");
+ return;
}
+ FragmentReceive fragmentReceive = (FragmentReceive) app.getFragmentManager().findFragmentByTag(FragmentReceive.class.getName());
+ if (fragmentReceive != null && fragmentReceive.isAdded())
+ return;
+ fragmentReceive = new FragmentReceive();
+ Bundle args = new Bundle();
+ args.putBoolean("receive", isReceive);
+ fragmentReceive.setArguments(args);
+
+ app.getFragmentManager().beginTransaction()
+ .setCustomAnimations(0, 0, 0, R.animator.plain_300)
+ .add(android.R.id.content, fragmentReceive, FragmentReceive.class.getName())
+ .addToBackStack(FragmentReceive.class.getName()).commit();
-// Log.e(TAG, "The level is: " + level);
}
- public static void animateSlideToRight(final MainActivity context) {
- try {
- if (!checkTheHorizontalSlideAvailability()) return;
- final Fragment tmp = previous.pop();
- level--;
- if (level < 1)
- context.setBurgerButtonImage(BRConstants.BURGER);
- if (level == 1)
- context.setBurgerButtonImage(BRConstants.CLOSE);
-// Log.e(TAG, "The actual SettingsFragment: " + tmp);
- FragmentTransaction fragmentTransaction = context.getFragmentManager().beginTransaction();
-// fragmentTransaction.setCustomAnimations(R.animator.from_left, R.animator.to_right);
- fragmentTransaction.replace(R.id.main_layout, tmp, tmp.getClass().getName());
- fragmentTransaction.commit();
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- TranslateAnimation trans = new TranslateAnimation(-MainActivity.screenParametersPoint.x, 0, 0, 0);
- trans.setDuration(horizontalSlideDuration);
- trans.setInterpolator(new DecelerateOvershootInterpolator(1f, 0.5f));
- View view = tmp.getView();
- if (view != null)
- view.startAnimation(trans);
- }
- }, 1);
- } catch (Exception e) {
- e.printStackTrace();
+ public static void showBuyFragment(FragmentActivity app, String currency, FragmentBuy.Partner partner) {
+ if (app == null) {
+ Timber.i("timber: showBuyFragment: app is null");
+ return;
}
-
+ app.getSupportFragmentManager()
+ .beginTransaction()
+ .setCustomAnimations(0, 0, 0, R.animator.plain_300)
+ .add(android.R.id.content, FragmentBuy.newInstance(currency, partner), FragmentBuy.class.getName())
+ .addToBackStack(FragmentBuy.class.getName())
+ .commit();
}
-
- /**
- * Checks if the multipressing is available and if available:
- * - make it unavailable for delay milliseconds and return true,
- * else :
- * - return false.
- */
- public static boolean checkTheMultipressingAvailability() {
- if (multiplePressingAvailable) {
- multiplePressingAvailable = false;
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- multiplePressingAvailable = true;
- Log.w(TAG, "multiplePressingAvailable is back to - true");
- }
- }, 300);
- return true;
- } else {
- return false;
- }
+ public static void showDynamicDonationFragment(@NonNull FragmentActivity app) {
+ app.getSupportFragmentManager().beginTransaction()
+ .setCustomAnimations(0, 0, 0, R.animator.plain_300)
+ .add(android.R.id.content, new DynamicDonationFragment(), DynamicDonationFragment.class.getName())
+ .addToBackStack(DynamicDonationFragment.class.getName())
+ .commit();
}
- public static boolean checkTheHorizontalSlideAvailability() {
- if (horizontalSlideAvailable) {
- horizontalSlideAvailable = false;
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- horizontalSlideAvailable = true;
- Log.w(TAG, "multiplePressingAvailable is back to - true");
- }
- }, horizontalSlideDuration);
- return true;
- } else {
- return false;
+ public static void showMenuFragment(Activity app) {
+ if (app == null) {
+ Timber.i("timber: showReceiveFragment: app is null");
+ return;
}
+ FragmentTransaction transaction = app.getFragmentManager().beginTransaction();
+ transaction.setCustomAnimations(0, 0, 0, R.animator.plain_300);
+ transaction.add(android.R.id.content, new FragmentMenu(), FragmentMenu.class.getName());
+ transaction.addToBackStack(FragmentMenu.class.getName());
+ transaction.commit();
}
- public static void hideDecoderFragment() {
- try {
- MainActivity app = MainActivity.app;
- if (app == null) return;
- decoderFragmentOn = false;
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- BRAnimator.multiplePressingAvailable = true;
- }
- }, 300);
- final FragmentManager fragmentManager = app.getFragmentManager();
- FragmentDecoder fragmentDecoder = (FragmentDecoder) fragmentManager.findFragmentByTag(FragmentDecoder.class.getName());
- if (fragmentDecoder == null) return;
- fragmentManager.beginTransaction().setCustomAnimations(R.animator.from_top, R.animator.to_bottom).
- remove(fragmentDecoder).commit();
- CustomPagerAdapter.adapter.showFragments(true, app);
- app.activityButtonsEnable(true);
- } catch (Exception e) {
- e.printStackTrace();
+ public static void showGreetingsMessage(Activity app) {
+ if (app == null) {
+ Timber.i("timber: showGreetingsMessage: app is null");
+ return;
}
+ FragmentTransaction transaction = app.getFragmentManager().beginTransaction();
+ transaction.setCustomAnimations(0, 0, 0, R.animator.plain_300);
+ transaction.add(android.R.id.content, new FragmentGreetings(), FragmentGreetings.class.getName());
+ transaction.addToBackStack(FragmentGreetings.class.getName());
+ transaction.commit();
}
- public static void hideScanResultFragment() {
- try {
- MainActivity app = MainActivity.app;
- if (app == null) return;
- CustomPagerAdapter.adapter.showFragments(true, app);
- scanResultFragmentOn = false;
- new Handler().postDelayed(new Runnable() {
+ public static boolean isClickAllowed() {
+ if (clickAllowed) {
+ clickAllowed = false;
+ BRExecutor.getInstance().forLightWeightBackgroundTasks().execute(new Runnable() {
@Override
public void run() {
- multiplePressingAvailable = true;
+ try {
+ Thread.sleep(300);
+ } catch (InterruptedException e) {
+ Timber.e(e);
+ }
+ clickAllowed = true;
}
- }, 300);
-
- FragmentManager fragmentManager = app.getFragmentManager();
- FragmentScanResult fragmentScanResult = (FragmentScanResult)
- fragmentManager.findFragmentByTag(FragmentScanResult.class.getName());
- if (fragmentScanResult == null) return;
- fragmentManager.beginTransaction().
- setCustomAnimations(R.animator.from_left, R.animator.to_right).
- remove(fragmentScanResult).commit();
- app.setBurgerButtonImage(BRConstants.BURGER);
-
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- FragmentScanResult.address = null;
- }
+ });
+ return true;
+ } else return false;
}
- public static void resetFragmentAnimator() {
- level = 0;
- wipeWalletOpen = false;
- previous.clear();
- multiplePressingAvailable = true;
+ public static void killAllFragments(Activity app) {
+ if (app != null && !app.isDestroyed())
+ app.getFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
- public static void goToMainActivity(final Fragment fragment) {
- try {
- final MainActivity app = MainActivity.app;
- if (app == null) return;
- if (fragment != null) {
- app.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- FragmentManager fragmentManager = app.getFragmentManager();
- fragmentManager.beginTransaction().setCustomAnimations(R.animator.from_top, R.animator.to_bottom).
- remove(fragment).commit();
- CustomPagerAdapter.adapter.showFragments(true, app);
- app.activityButtonsEnable(true);
- app.setBurgerButtonImage(0);
- }
- });
-
- }
- resetFragmentAnimator();
- } catch (Exception e) {
- e.printStackTrace();
- }
-
+ public static void startBreadIfNotStarted(Activity app) {
+ if (!(app instanceof BreadActivity))
+ startBreadActivity(app, false);
}
- public static void showCopyBubble(final Activity context, final View v, final View t) {
- try {
- if (context == null) return;
- if (v != null)
- v.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- if (copy == null)
- copy = context.getLayoutInflater().inflate(R.layout.copy, null);
- if (copy == null) return;
- final RelativeLayout root = (RelativeLayout) context.findViewById(R.id.main_layout);
- root.removeView(copy);
- copy.setClickable(true);
- copy.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- try {
- if (t != null) {
- BRClipboardManager.copyToClipboard(context, ((TextView) t).getText().toString());
- Log.e(TAG, "clicked copy: " + ((TextView) t).getText().toString());
- }
- hideCopyBubble(context);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- });
- root.addView(copy);
- copy.setY(getRelativeTop(v));
- copy.setX(MainActivity.screenParametersPoint.x / 2 - 40);
- }
- });
- if (t != null)
- t.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- View parent = (View) t.getParent();
- if (parent != null)
- parent.performClick();
- }
- });
- } catch (Exception e) {
- e.printStackTrace();
+ public static void startBreadActivity(Activity from, boolean auth) {
+ if (from == null) return;
+ Timber.i("timber: startBreadActivity: %s", from.getClass().getName());
+ Class toStart = auth ? LoginActivity.class : BreadActivity.class;
+ Intent intent = new Intent(from, toStart);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ from.startActivity(intent);
+ from.overridePendingTransition(R.anim.fade_up, R.anim.fade_down);
+ if (!from.isDestroyed()) {
+ from.finish();
}
-
}
- public static void hideCopyBubble(final Activity context) {
- try {
- if (context == null) return;
- if (copy == null) return;
- final RelativeLayout root = (RelativeLayout) context.findViewById(R.id.main_layout);
- if (copy.getVisibility() == View.VISIBLE) {
- Animation animation = new AlphaAnimation(1f, 0f);
- animation.setDuration(150);
- animation.setAnimationListener(new Animation.AnimationListener() {
- @Override
- public void onAnimationStart(Animation animation) {
-
- }
+ public static void animateSignalSlide(ViewGroup signalLayout, final boolean reverse, @Nullable final OnSlideAnimationEnd listener) {
+ float translationY = signalLayout.getTranslationY();
+ float signalHeight = signalLayout.getHeight();
+ signalLayout.setTranslationY(reverse ? translationY : translationY + signalHeight);
+ signalLayout.animate().translationY(reverse ? BreadActivity.screenParametersPoint.y : translationY).setDuration(SLIDE_ANIMATION_DURATION)
+ .setInterpolator(reverse ? new DecelerateInterpolator() : new OvershootInterpolator(0.7f))
+ .setListener(new AnimatorListenerAdapter() {
@Override
- public void onAnimationEnd(Animation animation) {
- root.removeView(copy);
- }
-
- @Override
- public void onAnimationRepeat(Animation animation) {
-
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ if (listener != null)
+ listener.onAnimationEnd();
}
});
- copy.startAnimation(animation);
- }
-
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- public static void fadeScaleBubble(final View... views) {
- if (views == null || views.length == 0) return;
- for (final View v : views) {
- if (v == null || v.getVisibility() != View.VISIBLE) continue;
- Animation animation = new AlphaAnimation(1f, 0f);
- animation.setDuration(150);
- animation.setAnimationListener(new Animation.AnimationListener() {
- @Override
- public void onAnimationStart(Animation animation) {
- }
-
- @Override
- public void onAnimationEnd(Animation animation) {
- v.setVisibility(View.GONE);
- }
-
- @Override
- public void onAnimationRepeat(Animation animation) {
-
- }
- });
- v.startAnimation(animation);
- }
-
- }
-
- public static void animateSavePhraseFlow() {
}
- public static void scaleView(View v, float startScaleX, float endScaleX, float startScaleY, float endScaleY) {
- Animation anim = new ScaleAnimation(
- startScaleX, endScaleX, // Start and end values for the X axis scaling
- startScaleY, endScaleY, // Start and end values for the Y axis scaling
- Animation.RELATIVE_TO_SELF, 0.5f, // Pivot point of X scaling
- Animation.RELATIVE_TO_SELF, 0.5f); // Pivot point of Y scaling
- anim.setFillAfter(true); // Needed to keep the result of the animation
- v.startAnimation(anim);
- }
+ public static void animateBackgroundDim(final ViewGroup backgroundLayout, boolean reverse) {
+ int transColor = reverse ? R.color.black_trans : android.R.color.transparent;
+ int blackTransColor = reverse ? android.R.color.transparent : R.color.black_trans;
+
+ ValueAnimator anim = new ValueAnimator();
+ anim.setIntValues(transColor, blackTransColor);
+ anim.setEvaluator(new ArgbEvaluator());
+ anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator valueAnimator) {
+ backgroundLayout.setBackgroundColor((Integer) valueAnimator.getAnimatedValue());
+ }
+ });
- private static int getRelativeLeft(View myView) {
- if (myView.getParent() == myView.getRootView())
- return myView.getLeft();
- else
- return myView.getLeft() + getRelativeLeft((View) myView.getParent());
+ anim.setDuration(SLIDE_ANIMATION_DURATION);
+ anim.start();
}
- public static int getRelativeTop(View myView) {
- if (myView == null) return 0;
- if (myView.getParent() == myView.getRootView())
- return myView.getTop();
- else
- return myView.getTop() + getRelativeTop((View) myView.getParent());
+ public interface OnSlideAnimationEnd {
+ void onAnimationEnd();
}
-
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/com/breadwallet/tools/animation/BRDialog.java b/app/src/main/java/com/breadwallet/tools/animation/BRDialog.java
new file mode 100644
index 000000000..f84035ec5
--- /dev/null
+++ b/app/src/main/java/com/breadwallet/tools/animation/BRDialog.java
@@ -0,0 +1,78 @@
+package com.breadwallet.tools.animation;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.text.SpannableString;
+
+import androidx.annotation.NonNull;
+
+import com.breadwallet.presenter.customviews.BRDialogView;
+import com.breadwallet.tools.threads.BRExecutor;
+
+import timber.log.Timber;
+
+public class BRDialog {
+ private static BRDialogView dialog;
+
+ /**
+ * Safe from any threads
+ *
+ * @param app needs to be activity
+ */
+ public static void showCustomDialog(@NonNull final Context app, @NonNull final String title, @NonNull final String message,
+ @NonNull final String posButton, final String negButton, final BRDialogView.BROnClickListener posListener,
+ final BRDialogView.BROnClickListener negListener, final DialogInterface.OnDismissListener dismissListener, final int iconRes) {
+ if (((Activity) app).isDestroyed()) {
+ Timber.d("timber: showCustomDialog: FAILED, context is destroyed");
+ return;
+ }
+
+ BRExecutor.getInstance().forMainThreadTasks().execute(new Runnable() {
+ @Override
+ public void run() {
+ dialog = new BRDialogView();
+ dialog.setTitle(title);
+ dialog.setMessage(message);
+ dialog.setPosButton(posButton);
+ dialog.setNegButton(negButton);
+ dialog.setPosListener(posListener);
+ dialog.setNegListener(negListener);
+ dialog.setDismissListener(dismissListener);
+ dialog.setIconRes(iconRes);
+ dialog.show(((Activity) app).getFragmentManager(), dialog.getClass().getName());
+ }
+ });
+
+ }
+
+ //same but with a SpannableString as message to be able to click on a portion of the text with a listener
+ public static void showCustomDialog(@NonNull final Context app, @NonNull final String title, @NonNull final SpannableString message,
+ @NonNull final String posButton, final String negButton, final BRDialogView.BROnClickListener posListener,
+ final BRDialogView.BROnClickListener negListener, final DialogInterface.OnDismissListener dismissListener, final int iconRes) {
+ if (((Activity) app).isDestroyed()) {
+ Timber.d("timber: showCustomDialog: FAILED, context is destroyed");
+ return;
+ }
+
+ BRExecutor.getInstance().forMainThreadTasks().execute(new Runnable() {
+ @Override
+ public void run() {
+ dialog = new BRDialogView();
+ dialog.setTitle(title);
+ dialog.setSpan(message);//setting Span instead of String
+ dialog.setPosButton(posButton);
+ dialog.setNegButton(negButton);
+ dialog.setPosListener(posListener);
+ dialog.setNegListener(negListener);
+ dialog.setDismissListener(dismissListener);
+ dialog.setIconRes(iconRes);
+ dialog.show(((Activity) app).getFragmentManager(), dialog.getClass().getName());
+ }
+ });
+ }
+
+ public static void hideDialog() {
+ if (dialog != null) dialog.dismiss();
+ }
+}
diff --git a/app/src/main/java/com/breadwallet/tools/animation/BackgroundMovingAnimator.java b/app/src/main/java/com/breadwallet/tools/animation/BackgroundMovingAnimator.java
deleted file mode 100644
index 001524dc3..000000000
--- a/app/src/main/java/com/breadwallet/tools/animation/BackgroundMovingAnimator.java
+++ /dev/null
@@ -1,142 +0,0 @@
-package com.breadwallet.tools.animation;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-import android.graphics.Matrix;
-import android.graphics.RectF;
-import android.util.Log;
-import android.widget.ImageView;
-
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 10/9/15.
- * Copyright (c) 2016 breadwallet LLC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-public class BackgroundMovingAnimator {
- public static final String TAG = BackgroundMovingAnimator.class.getName();
- private static final int RightToLeft = 1;
- private static final int LeftToRight = 2;
- private static int mDirection = RightToLeft;
- private static RectF mDisplayRect = new RectF();
- private static Matrix mMatrix = new Matrix();
- private static float mScaleFactor;
- private static final int DURATION = 30000;
- private static ImageView background;
- private static ValueAnimator mCurrentAnimator;
-
- private static void animate() {
- if(background == null) {
- stopBackgroundMoving();
- return;
- }
- updateDisplayRect();
- if (mDirection == RightToLeft) {
- animate(mDisplayRect.left, mDisplayRect.left -
- (mDisplayRect.right - background.getWidth()));
- } else {
- animate(mDisplayRect.left, 0.0f);
- }
- }
-
- private static void animate(float from, float to) {
- if(background == null) {
- stopBackgroundMoving();
- return;
- }
- mCurrentAnimator = ValueAnimator.ofFloat(from, to);
- mCurrentAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- if(background == null) {
- stopBackgroundMoving();
- return;
- }
- float value = (Float) animation.getAnimatedValue();
-
- mMatrix.reset();
- mMatrix.postScale(mScaleFactor, mScaleFactor);
- mMatrix.postTranslate(value, 0);
- background.setImageMatrix(mMatrix);
-
- }
- });
- mCurrentAnimator.setDuration(DURATION);
- mCurrentAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- if (mDirection == RightToLeft)
- mDirection = LeftToRight;
- else
- mDirection = RightToLeft;
- animate();
- }
- });
- mCurrentAnimator.start();
- }
-
- private static void updateDisplayRect() {
- if(background == null) {
- stopBackgroundMoving();
- return;
- }
- mDisplayRect.set(0, 0, background.getDrawable().getIntrinsicWidth(),
- background.getDrawable().getIntrinsicHeight());
- mMatrix.mapRect(mDisplayRect);
- }
-
- public static void animateBackgroundMoving(ImageView theBackground) {
-
- background = theBackground;
- background.post(new Runnable() {
- @Override
- public void run() {
- if(background == null) {
- stopBackgroundMoving();
- return;
- }
- mScaleFactor = (float) background.getHeight() /
- (float) background.getDrawable().getIntrinsicHeight();
- mMatrix.postScale(mScaleFactor, mScaleFactor);
- background.setImageMatrix(mMatrix);
- animate();
- }
- });
- }
-
- public static void stopBackgroundMoving() {
- if (background != null) {
- background.clearAnimation();
- background = null;
- }
- if (mMatrix != null)
- mMatrix.reset();
-
- if (mCurrentAnimator != null) {
- mCurrentAnimator.removeAllListeners();
- mCurrentAnimator.cancel();
- }
- mDirection = RightToLeft;
- mScaleFactor = 0;
- }
-}
diff --git a/app/src/main/java/com/breadwallet/tools/animation/DecelerateOvershootInterpolator.java b/app/src/main/java/com/breadwallet/tools/animation/DecelerateOvershootInterpolator.java
index aa6c5966f..207ed78ea 100644
--- a/app/src/main/java/com/breadwallet/tools/animation/DecelerateOvershootInterpolator.java
+++ b/app/src/main/java/com/breadwallet/tools/animation/DecelerateOvershootInterpolator.java
@@ -4,31 +4,6 @@
import android.view.animation.Interpolator;
import android.view.animation.OvershootInterpolator;
-/**
- * BreadWallet
- *
- * Created by Mihail Gutan on 6/19/16.
- * Copyright (c) 2016 breadwallet LLC
- *