From 2b5b26f2bb3666afaeb85100f06114431fa40589 Mon Sep 17 00:00:00 2001 From: Deep Date: Mon, 14 Sep 2020 12:33:54 -0400 Subject: [PATCH] Add layouts and behaviours for summary and deposit Update QR code dialog --- android/brave_java_resources.gni | 34 ++- android/brave_java_sources.gni | 10 +- ...nt.java => QRCodeShareDialogFragment.java} | 30 +-- .../browser/ntp/BraveNewTabPageLayout.java | 61 +++-- .../browser/ntp/widget/NTPWidgetAdapter.java | 9 +- .../browser/ntp/widget/NTPWidgetManager.java | 23 -- .../crypto/binance/BinanceAccountBalance.java | 13 ++ .../crypto/binance/BinanceCoinNetworks.java | 55 +++++ .../crypto/binance/BinanceDepositAdapter.java | 90 ++++++++ .../binance/BinanceDepositFragment.java | 215 ++++++++++++++++++ .../crypto/binance/BinanceNativeWorker.java | 4 +- .../crypto/binance/BinanceObserver.java | 2 +- .../binance/BinanceSummaryFragment.java | 132 +++++++++++ .../crypto/binance/BinanceWidgetManager.java | 107 +++++++++ .../widget/crypto/binance/BlankFragment.java | 31 --- .../crypto/binance/CoinNetworkModel.java | 50 ++++ ...CryptoWidgetBottomSheetDialogFragment.java | 16 +- .../binance/CryptoWidgetTabAdapter.java | 5 +- .../crypto/binance/CurrencyListAdapter.java | 79 +++++++ .../java/res/layout/binance_currency_item.xml | 53 +++++ .../java/res/layout/binance_deposit_item.xml | 26 +++ .../res/layout/binance_deposit_layout.xml | 119 ++++++++++ .../java/res/layout/crypto_widget_layout.xml | 4 +- .../res/layout/fragment_binance_deposit.xml | 15 ++ ...blank.xml => fragment_binance_summary.xml} | 45 +++- ...ment_crypto_widget_bottom_sheet_dialog.xml | 37 ++- ...l_share.xml => fragment_qr_code_share.xml} | 0 .../suggestions_site_tile_grid_modern.xml | 1 - android/java/res/layout/top_sites_layout.xml | 49 ++++ .../android/strings/android_brave_strings.grd | 6 + 30 files changed, 1195 insertions(+), 126 deletions(-) rename android/java/org/chromium/chrome/browser/{ntp_background_images/SuperReferralShareDialogFragment.java => QRCodeShareDialogFragment.java} (75%) create mode 100644 android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceCoinNetworks.java create mode 100644 android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceDepositAdapter.java create mode 100644 android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceDepositFragment.java create mode 100644 android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceSummaryFragment.java create mode 100644 android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceWidgetManager.java delete mode 100644 android/java/org/chromium/chrome/browser/widget/crypto/binance/BlankFragment.java create mode 100644 android/java/org/chromium/chrome/browser/widget/crypto/binance/CoinNetworkModel.java create mode 100644 android/java/org/chromium/chrome/browser/widget/crypto/binance/CurrencyListAdapter.java create mode 100644 android/java/res/layout/binance_currency_item.xml create mode 100644 android/java/res/layout/binance_deposit_item.xml create mode 100644 android/java/res/layout/binance_deposit_layout.xml create mode 100644 android/java/res/layout/fragment_binance_deposit.xml rename android/java/res/layout/{fragment_blank.xml => fragment_binance_summary.xml} (58%) rename android/java/res/layout/{fragment_super_referral_share.xml => fragment_qr_code_share.xml} (100%) create mode 100644 android/java/res/layout/top_sites_layout.xml diff --git a/android/brave_java_resources.gni b/android/brave_java_resources.gni index 67e0db683d7..8eb63a28610 100644 --- a/android/brave_java_resources.gni +++ b/android/brave_java_resources.gni @@ -687,7 +687,8 @@ brave_java_resources = [ "java/res/layout/brave_toolbar.xml", "java/res/layout/crypto_widget_layout.xml", "java/res/layout/ddg_offer_layout.xml", - "java/res/layout/fragment_blank.xml", + "java/res/layout/binance_currency_item.xml", + "java/res/layout/fragment_binance_summary.xml", "java/res/layout/fragment_brave_ads_onboarding.xml", "java/res/layout/fragment_brave_rewards_onboarding.xml", "java/res/layout/fragment_cross_promotional_modal_dialog.xml", @@ -696,9 +697,10 @@ brave_java_resources = [ "java/res/layout/fragment_onboarding_v2.xml", "java/res/layout/fragment_rate_dialog.xml", "java/res/layout/fragment_search_engine_onboarding.xml", - "java/res/layout/fragment_super_referral_share.xml", + "java/res/layout/fragment_qr_code_share.xml", "java/res/layout/fragment_troubleshooting_onboarding.xml", "java/res/layout/highlight_layout.xml", + "java/res/layout/fragment_binance_deposit.xml", "java/res/layout/location_status_incognito_badge.xml", "java/res/layout/menu_separator.xml", "java/res/layout/new_tab_page_incognito.xml", @@ -714,6 +716,8 @@ brave_java_resources = [ "java/res/layout/web_notification_big_brave_ads.xml", "java/res/layout/web_notification_brave_ads.xml", "java/res/layout/web_notification_icon_frame_brave.xml", + "java/res/layout/binance_deposit_item.xml", + "java/res/layout/top_sites_layout.xml", "java/res/menu/exit_settings_menu.xml", "java/res/menu/new_tab_menu.xml", "java/res/menu/ntp_widget_menu.xml", @@ -749,6 +753,32 @@ brave_java_resources = [ "java/res/xml/play_yt_video_in_browser_preferences.xml", "java/res/xml/qa_preferences.xml", "java/res/xml/use_custom_tabs_brave_preference.xml", + "java/res/drawable-nodpi/zil.png", + "java/res/drawable-nodpi/atom.png", + "java/res/drawable-nodpi/xtz.png", + "java/res/drawable-nodpi/btc.png", + "java/res/drawable-nodpi/pax.png", + "java/res/drawable-nodpi/eos.png", + "java/res/drawable-nodpi/eth.png", + "java/res/drawable-nodpi/matic.png", + "java/res/drawable-nodpi/ada.png", + "java/res/drawable-nodpi/xrp.png", + "java/res/drawable-nodpi/vet.png", + "java/res/drawable-nodpi/bnb.png", + "java/res/drawable-nodpi/usdt.png", + "java/res/drawable-nodpi/tusd.png", + "java/res/drawable-nodpi/enj.png", + "java/res/drawable-nodpi/bat.png", + "java/res/drawable-nodpi/trx.png", + "java/res/drawable-nodpi/xlm.png", + "java/res/drawable-nodpi/nano.png", + "java/res/drawable-nodpi/rvn.png", + "java/res/drawable-nodpi/link.png", + "java/res/drawable-nodpi/ont.png", + "java/res/drawable-nodpi/bch.png", + "java/res/drawable-nodpi/dash.png", + "java/res/drawable-nodpi/zrx.png", + "java/res/layout/binance_deposit_layout.xml", ] brave_components_browser_ui_site_settings_android_java_resources = [ "//brave/components/browser_ui/site_settings/android/java/res/xml/brave_site_settings_preferences.xml" ] diff --git a/android/brave_java_sources.gni b/android/brave_java_sources.gni index f70e04ab1cc..0645b199e41 100644 --- a/android/brave_java_sources.gni +++ b/android/brave_java_sources.gni @@ -74,7 +74,7 @@ brave_java_sources = [ "../../brave/android/java/org/chromium/chrome/browser/ntp/widget/SwipeAndDragHelper.java", "../../brave/android/java/org/chromium/chrome/browser/ntp_background_images/NTPBackgroundImagesBridge.java", "../../brave/android/java/org/chromium/chrome/browser/ntp_background_images/RewardsBottomSheetDialogFragment.java", - "../../brave/android/java/org/chromium/chrome/browser/ntp_background_images/SuperReferralShareDialogFragment.java", + "../../brave/android/java/org/chromium/chrome/browser/QRCodeShareDialogFragment.java", "../../brave/android/java/org/chromium/chrome/browser/ntp_background_images/model/BackgroundImage.java", "../../brave/android/java/org/chromium/chrome/browser/ntp_background_images/model/ImageCredit.java", "../../brave/android/java/org/chromium/chrome/browser/ntp_background_images/model/NTPImage.java", @@ -168,10 +168,16 @@ brave_java_sources = [ "../../brave/android/java/org/chromium/chrome/browser/util/PackageUtils.java", "../../brave/android/java/org/chromium/chrome/browser/util/TabUtils.java", "../../brave/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceNativeWorker.java", - "../../brave/android/java/org/chromium/chrome/browser/widget/crypto/binance/BlankFragment.java", + "../../brave/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceSummaryFragment.java", + "../../brave/android/java/org/chromium/chrome/browser/widget/crypto/binance/CurrencyListAdapter.java", "../../brave/android/java/org/chromium/chrome/browser/widget/crypto/binance/CryptoWidgetBottomSheetDialogFragment.java", "../../brave/android/java/org/chromium/chrome/browser/widget/crypto/binance/CryptoWidgetTabAdapter.java", "../../brave/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceAccountBalance.java", + "../../brave/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceWidgetManager.java", + "../../brave/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceCoinNetworks.java", + "../../brave/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceDepositFragment.java", + "../../brave/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceDepositAdapter.java", + "../../brave/android/java/org/chromium/chrome/browser/widget/crypto/binance/CoinNetworkModel.java", "../../brave/android/java/org/chromium/chrome/browser/widget/tile/BraveTileWithTextView.java", ] diff --git a/android/java/org/chromium/chrome/browser/ntp_background_images/SuperReferralShareDialogFragment.java b/android/java/org/chromium/chrome/browser/QRCodeShareDialogFragment.java similarity index 75% rename from android/java/org/chromium/chrome/browser/ntp_background_images/SuperReferralShareDialogFragment.java rename to android/java/org/chromium/chrome/browser/QRCodeShareDialogFragment.java index b911d6f4348..719efab1f0c 100644 --- a/android/java/org/chromium/chrome/browser/ntp_background_images/SuperReferralShareDialogFragment.java +++ b/android/java/org/chromium/chrome/browser/QRCodeShareDialogFragment.java @@ -2,7 +2,7 @@ * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.chromium.chrome.browser.ntp_background_images; +package org.chromium.chrome.browser; import android.os.Bundle; import android.content.Intent; @@ -21,15 +21,11 @@ import com.google.zxing.common.BitMatrix; import org.chromium.chrome.R; import org.chromium.base.Log; -import org.chromium.chrome.browser.profiles.Profile; -import org.chromium.chrome.browser.ntp_background_images.NTPBackgroundImagesBridge; import org.chromium.chrome.browser.night_mode.GlobalNightModeStateProviderHolder; -public class SuperReferralShareDialogFragment extends DialogFragment implements View.OnClickListener{ +public class QRCodeShareDialogFragment extends DialogFragment implements View.OnClickListener{ private static final String TAG = "SUPER-REFERRAL"; - private static final String BRAVE_REF_URL = "https://brave.com/r/"; - // For QR code generation private static final int WHITE = 0xFFFFFFFF; private static final int BLACK = 0xFF000000; @@ -38,25 +34,22 @@ public class SuperReferralShareDialogFragment extends DialogFragment implements private ImageView mQRImage; private Button mShareButton; - private NTPBackgroundImagesBridge mNTPBackgroundImagesBridge; + private String qrCodeText; - public SuperReferralShareDialogFragment() { + public QRCodeShareDialogFragment() { // Empty constructor is required for DialogFragment // Make sure not to add arguments to the constructor // Use `newInstance` instead as shown below } - - public static SuperReferralShareDialogFragment newInstance(String title) { - SuperReferralShareDialogFragment mSuperReferralShareDialogFragment = new SuperReferralShareDialogFragment(); - return mSuperReferralShareDialogFragment; - } + + public void setQRCodeText(String qrCodeText) { + this.qrCodeText = qrCodeText; + } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - Profile mProfile = Profile.getLastUsedRegularProfile(); - mNTPBackgroundImagesBridge = NTPBackgroundImagesBridge.getInstance(mProfile); - return inflater.inflate(R.layout.fragment_super_referral_share, container); + return inflater.inflate(R.layout.fragment_qr_code_share, container); } @Override @@ -80,12 +73,11 @@ public class SuperReferralShareDialogFragment extends DialogFragment implements private void openShareIntent() { Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND); sharingIntent.setType("text/plain"); - sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, BRAVE_REF_URL + mNTPBackgroundImagesBridge.getSuperReferralCode()); + sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, qrCodeText); getActivity().startActivity(Intent.createChooser(sharingIntent, getResources().getString(R.string.share_link_chooser_title))); } private void generateQRCode() { - final String qrDataFinal = BRAVE_REF_URL + mNTPBackgroundImagesBridge.getSuperReferralCode(); final int WHITE = GlobalNightModeStateProviderHolder.getInstance().isInNightMode() ? 0xFFFFFFFF : 0xFF000000; final int BLACK = GlobalNightModeStateProviderHolder.getInstance().isInNightMode() ? 0x613C4043 : 0xFFFFFFFF; new Thread(new Runnable() { @@ -94,7 +86,7 @@ public class SuperReferralShareDialogFragment extends DialogFragment implements // Generate QR code BitMatrix result; try { - result = new MultiFormatWriter().encode(qrDataFinal, BarcodeFormat.QR_CODE, WIDTH, WIDTH, null); + result = new MultiFormatWriter().encode(qrCodeText, BarcodeFormat.QR_CODE, WIDTH, WIDTH, null); } catch (WriterException e) { Log.e(TAG, "QR code unsupported format: " + e); return; diff --git a/android/java/org/chromium/chrome/browser/ntp/BraveNewTabPageLayout.java b/android/java/org/chromium/chrome/browser/ntp/BraveNewTabPageLayout.java index 9cf5ef39145..9b7b33b34f7 100644 --- a/android/java/org/chromium/chrome/browser/ntp/BraveNewTabPageLayout.java +++ b/android/java/org/chromium/chrome/browser/ntp/BraveNewTabPageLayout.java @@ -29,6 +29,7 @@ import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; +import android.widget.Button; import android.os.CountDownTimer; import androidx.annotation.Nullable; @@ -64,7 +65,7 @@ import org.chromium.chrome.browser.ntp.widget.NTPWidgetBottomSheetDialogFragment import org.chromium.chrome.browser.ntp.widget.NTPWidgetItem; import org.chromium.chrome.browser.ntp.widget.NTPWidgetManager; import org.chromium.chrome.browser.ntp_background_images.NTPBackgroundImagesBridge; -import org.chromium.chrome.browser.ntp_background_images.SuperReferralShareDialogFragment; +import org.chromium.chrome.browser.QRCodeShareDialogFragment; import org.chromium.chrome.browser.ntp_background_images.model.BackgroundImage; import org.chromium.chrome.browser.ntp_background_images.model.NTPImage; import org.chromium.chrome.browser.ntp_background_images.model.SponsoredTab; @@ -96,6 +97,7 @@ import org.chromium.components.browser_ui.widget.displaystyle.UiConfig; import org.chromium.chrome.browser.widget.crypto.binance.BinanceNativeWorker; import org.chromium.chrome.browser.widget.crypto.binance.BinanceObserver; import org.chromium.chrome.browser.widget.crypto.binance.BinanceAccountBalance; +import org.chromium.chrome.browser.widget.crypto.binance.BinanceWidgetManager; import org.chromium.chrome.browser.util.TabUtils; import java.util.ArrayList; @@ -106,6 +108,7 @@ import java.util.TreeMap; public class BraveNewTabPageLayout extends NewTabPageLayout { private static final String TAG = "BraveNewTabPageView"; private static final String BRAVE_BINANCE = "https://brave.com/binance/"; + private static final String BRAVE_REF_URL = "https://brave.com/r/"; private ImageView bgImageView; private Profile mProfile; @@ -189,11 +192,15 @@ public class BraveNewTabPageLayout extends NewTabPageLayout { ntpWidgetMap.put(ntpWidgetManager.getPrivateStatsWidget(), ntpWidgetItem); } if (ntpWidgetManager.getFavoritesWidget() != -1) { + View mTopSitesLayout = inflater.inflate(R.layout.top_sites_layout, null); + FrameLayout mTopSitesGridLayout = mTopSitesLayout.findViewById(R.id.top_sites_grid_layout); + NTPWidgetItem ntpWidgetItem = new NTPWidgetItem(NTPWidgetManager.PREF_FAVORITES, "Favorites", "Trackers & Ads Blocked, Saved Bandwidth, and Time Saved Estimates."); if (shouldShowSuperReferral() && superReferralSitesLayout != null) { - ntpWidgetItem.setWidgetView(superReferralSitesLayout); + mTopSitesGridLayout.addView(superReferralSitesLayout); + ntpWidgetItem.setWidgetView(mTopSitesLayout); ntpWidgetMap.put(ntpWidgetManager.getFavoritesWidget(), ntpWidgetItem); } else if (!mNTPBackgroundImagesBridge.isSuperReferral() || !NTPBackgroundImagesBridge.enableSponsoredImages() @@ -201,7 +208,8 @@ public class BraveNewTabPageLayout extends NewTabPageLayout { boolean showPlaceholder = getTileGroup().hasReceivedData() && getTileGroup().isEmpty(); if (mSiteSectionView != null && !showPlaceholder) { - ntpWidgetItem.setWidgetView(mSiteSectionView); + mTopSitesGridLayout.addView(mSiteSectionView); + ntpWidgetItem.setWidgetView(mTopSitesLayout); ntpWidgetMap.put(ntpWidgetManager.getFavoritesWidget(), ntpWidgetItem); } } @@ -220,11 +228,19 @@ public class BraveNewTabPageLayout extends NewTabPageLayout { binanceWidgetView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - // CryptoWidgetBottomSheetDialogFragment cryptoWidgetBottomSheetDialogFragment = - // new CryptoWidgetBottomSheetDialogFragment(); - // cryptoWidgetBottomSheetDialogFragment.show( - // ((BraveActivity) mActivity).getSupportFragmentManager(), - // "crypto_widget_bottomSheet_dialog_fragment"); + CryptoWidgetBottomSheetDialogFragment cryptoWidgetBottomSheetDialogFragment = + new CryptoWidgetBottomSheetDialogFragment(); + cryptoWidgetBottomSheetDialogFragment.show( + ((BraveActivity) mActivity).getSupportFragmentManager(), + "crypto_widget_bottomSheet_dialog_fragment"); + // Log.e("NTP", "Binance URL : " + mBinanceNativeWorker.getOAuthClientUrl()); + // TabUtils.openUrlInSameTab(mBinanceNativeWorker.getOAuthClientUrl()); + } + }); + Button connectButton = binanceWidgetView.findViewById(R.id.btn_connect); + connectButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { Log.e("NTP", "Binance URL : " + mBinanceNativeWorker.getOAuthClientUrl()); TabUtils.openUrlInSameTab(mBinanceNativeWorker.getOAuthClientUrl()); } @@ -320,7 +336,7 @@ public class BraveNewTabPageLayout extends NewTabPageLayout { mBadgeAnimationView.setVisibility(View.INVISIBLE); } showWidgets(); - if (NTPWidgetManager.getInstance().isUserAuthenticatedForBinance()) { + if (BinanceWidgetManager.getInstance().isUserAuthenticatedForBinance()) { mBinanceNativeWorker.getAccountBalances(); } mBinanceNativeWorker.AddObserver(mBinanaceObserver); @@ -404,11 +420,12 @@ public class BraveNewTabPageLayout extends NewTabPageLayout { mSuperReferralLogo.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - SuperReferralShareDialogFragment mSuperReferralShareDialogFragment = - new SuperReferralShareDialogFragment(); - mSuperReferralShareDialogFragment.show( + QRCodeShareDialogFragment mQRCodeShareDialogFragment = + new QRCodeShareDialogFragment(); + mQRCodeShareDialogFragment.setQRCodeText(BRAVE_REF_URL + mNTPBackgroundImagesBridge.getSuperReferralCode()); + mQRCodeShareDialogFragment.show( ((BraveActivity) mActivity).getSupportFragmentManager(), - "SuperReferralShareDialogFragment"); + "QRCodeShareDialogFragment"); } }); } else if (UserPrefs.get(Profile.getLastUsedRegularProfile()).getBoolean( @@ -731,7 +748,7 @@ public class BraveNewTabPageLayout extends NewTabPageLayout { @Override public void OnGetAccessToken(boolean isSuccess) { Log.e("NTP", "OnGetAccessToken : " + isSuccess); - NTPWidgetManager.getInstance().setUserAuthenticationForBinance(isSuccess); + BinanceWidgetManager.getInstance().setUserAuthenticationForBinance(isSuccess); if (isSuccess) { mBinanceNativeWorker.getAccountBalances(); } @@ -740,11 +757,11 @@ public class BraveNewTabPageLayout extends NewTabPageLayout { @Override public void OnGetAccountBalances(String jsonBalances, boolean isSuccess) { if (!isSuccess) { - NTPWidgetManager.getInstance().setUserAuthenticationForBinance(isSuccess); + BinanceWidgetManager.getInstance().setUserAuthenticationForBinance(isSuccess); } try { - NTPWidgetManager.getInstance().setBinanceAccountBalance(new BinanceAccountBalance(jsonBalances)); - Log.e("NTP", "AccountBalances : " + NTPWidgetManager.getInstance().getBinanceAccountBalance().toString()); + BinanceWidgetManager.getInstance().setBinanceAccountBalance(new BinanceAccountBalance(jsonBalances)); + // Log.e("NTP", "AccountBalances : " + BinanceWidgetManager.getInstance().getBinanceAccountBalance().toString()); } catch (JSONException e) { Log.e("NTP", e.getMessage()); } @@ -762,23 +779,23 @@ public class BraveNewTabPageLayout extends NewTabPageLayout { @Override public void OnGetCoinNetworks(String jsonNetworks) { - Log.e("NTP", "CoinNetworks : " + jsonNetworks); + // Log.e("NTP", "CoinNetworks : " + jsonNetworks); }; @Override - public void OnGetDepositInfo(String depositAddress, String depositeTag, boolean isSuccess) {}; + public void OnGetDepositInfo(String depositAddress, String depositTag, boolean isSuccess) {}; @Override public void OnConfirmConvert(boolean isSuccess, String message) {}; @Override public void OnGetConvertAssets(String jsonAssets) { - Log.e("NTP", "ConvertAssets : " + jsonAssets); + // Log.e("NTP", "ConvertAssets : " + jsonAssets); }; @Override public void OnRevokeToken(boolean isSuccess) { - NTPWidgetManager.getInstance().setUserAuthenticationForBinance(!isSuccess); + BinanceWidgetManager.getInstance().setUserAuthenticationForBinance(!isSuccess); // Reset binance widget to connect page ntpWidgetAdapter.notifyDataSetChanged(); }; @@ -790,7 +807,7 @@ public class BraveNewTabPageLayout extends NewTabPageLayout { public void onTick(long millisUntilFinished) { } public void onFinish() { - if (NTPWidgetManager.getInstance().isUserAuthenticatedForBinance()) { + if (BinanceWidgetManager.getInstance().isUserAuthenticatedForBinance()) { mBinanceNativeWorker.getAccountBalances(); } if ((BraveActivity)mActivity != null) diff --git a/android/java/org/chromium/chrome/browser/ntp/widget/NTPWidgetAdapter.java b/android/java/org/chromium/chrome/browser/ntp/widget/NTPWidgetAdapter.java index 0441027cc72..ab1094b593f 100644 --- a/android/java/org/chromium/chrome/browser/ntp/widget/NTPWidgetAdapter.java +++ b/android/java/org/chromium/chrome/browser/ntp/widget/NTPWidgetAdapter.java @@ -31,6 +31,7 @@ import org.chromium.chrome.browser.ntp_background_images.util.NTPUtil; import org.chromium.chrome.browser.preferences.BravePref; import org.chromium.chrome.browser.preferences.BravePrefServiceBridge; import org.chromium.chrome.browser.widget.crypto.binance.BinanceAccountBalance; +import org.chromium.chrome.browser.widget.crypto.binance.BinanceWidgetManager; import org.chromium.chrome.browser.profiles.Profile; import java.util.ArrayList; @@ -87,16 +88,16 @@ public class NTPWidgetAdapter extends PagerAdapter { updateBraveStats(mainView); } else if (ntpWidgetItem.getWidgetType().equals(NTPWidgetManager.PREF_BINANCE)) { Button connectButton = mainView.findViewById(R.id.btn_connect); - connectButton.setOnClickListener(null); + // connectButton.setOnClickListener(null); LinearLayout binanceWidgetLayout = mainView.findViewById(R.id.binance_widget_layout); TextView binanceBalanceText = binanceWidgetLayout.findViewById(R.id.binance_balance_text); TextView binanceUSDBalanceText = binanceWidgetLayout.findViewById(R.id.binance_usd_balance_text); - BinanceAccountBalance binanceAccountBalance = NTPWidgetManager.getInstance().getBinanceAccountBalance(); + BinanceAccountBalance binanceAccountBalance = BinanceWidgetManager.getInstance().getBinanceAccountBalance(); if (binanceAccountBalance != null) { binanceBalanceText.setText(String.format(mContext.getResources().getString(R.string.btc_balance), String.valueOf(binanceAccountBalance.getTotalBTC()))); binanceUSDBalanceText.setText(String.format(mContext.getResources().getString(R.string.usd_balance), String.valueOf(binanceAccountBalance.getTotalUSD()))); } - if (NTPWidgetManager.getInstance().isUserAuthenticatedForBinance()) { + if (BinanceWidgetManager.getInstance().isUserAuthenticatedForBinance()) { binanceWidgetLayout.setVisibility(View.VISIBLE); connectButton.setVisibility(View.GONE); } else { @@ -176,7 +177,7 @@ public class NTPWidgetAdapter extends PagerAdapter { NTPWidgetItem ntpWidgetItem = widgetList.get(position); if (ntpWidgetItem.getWidgetType().equals(NTPWidgetManager.PREF_BINANCE) - && NTPWidgetManager.getInstance().isUserAuthenticatedForBinance()) { + && BinanceWidgetManager.getInstance().isUserAuthenticatedForBinance()) { popup.getMenu().findItem(R.id.learn_more).setVisible(true); popup.getMenu().findItem(R.id.refresh_data).setVisible(true); popup.getMenu().findItem(R.id.disconnect).setVisible(true); diff --git a/android/java/org/chromium/chrome/browser/ntp/widget/NTPWidgetManager.java b/android/java/org/chromium/chrome/browser/ntp/widget/NTPWidgetManager.java index 99c944c4a79..66cbdf89268 100644 --- a/android/java/org/chromium/chrome/browser/ntp/widget/NTPWidgetManager.java +++ b/android/java/org/chromium/chrome/browser/ntp/widget/NTPWidgetManager.java @@ -16,30 +16,17 @@ import java.util.List; import java.util.Map; import java.util.TreeMap; -import org.chromium.chrome.browser.widget.crypto.binance.BinanceAccountBalance; - public class NTPWidgetManager { public static final String PREF_PRIVATE_STATS = "private_stats"; public static final String PREF_FAVORITES = "favorites"; // public static final String PREF_BRAVE_REWARDS = "brave_rewards"; public static final String PREF_BINANCE = "binance"; public static final String PREF_NTP_WIDGET_ORDER = "ntp_widget_order"; - public static final String PREF_BINANCE_USER_AUTHENTICATION = "binance_user_authentication"; private static NTPWidgetManager sInstance; private final SharedPreferences mSharedPreferences; - private static BinanceAccountBalance binanceAccountBalance; - - public BinanceAccountBalance getBinanceAccountBalance() { - return binanceAccountBalance; - } - - public void setBinanceAccountBalance(BinanceAccountBalance binanceAccountBalance) { - this.binanceAccountBalance = binanceAccountBalance; - } - private NTPWidgetManager() { mSharedPreferences = ContextUtils.getAppSharedPreferences(); } @@ -82,14 +69,4 @@ public class NTPWidgetManager { sharedPreferencesEditor.putInt(PREF_NTP_WIDGET_ORDER, position); sharedPreferencesEditor.apply(); } - - public boolean isUserAuthenticatedForBinance() { - return mSharedPreferences.getBoolean(PREF_BINANCE_USER_AUTHENTICATION, false); - } - - public void setUserAuthenticationForBinance(boolean isAuthenticated) { - SharedPreferences.Editor sharedPreferencesEditor = mSharedPreferences.edit(); - sharedPreferencesEditor.putBoolean(PREF_BINANCE_USER_AUTHENTICATION, isAuthenticated); - sharedPreferencesEditor.apply(); - } } \ No newline at end of file diff --git a/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceAccountBalance.java b/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceAccountBalance.java index 83fd24d0aa4..2df74d56c26 100644 --- a/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceAccountBalance.java +++ b/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceAccountBalance.java @@ -10,6 +10,8 @@ import java.util.Iterator; import java.util.Map; import java.util.HashMap; +import android.util.Pair; + import org.json.JSONException; import org.json.JSONObject; import org.json.JSONArray; @@ -17,6 +19,7 @@ import org.json.JSONArray; public class BinanceAccountBalance { private double mTotalUSD = 0; private double mTotalBTC = 0; + private Map > mCurrencyValues; // First : Currency value, Second : USD value public BinanceAccountBalance (String json_balance) throws JSONException { fromJson (json_balance); @@ -25,11 +28,13 @@ public class BinanceAccountBalance { private void fromJson(String json_balance) throws JSONException { JSONObject jsonroot = new JSONObject(json_balance); Iterator keys = jsonroot.keys(); + mCurrencyValues = new HashMap <>(); while(keys.hasNext()) { String key = keys.next(); JSONArray data = jsonroot.getJSONArray(key); mTotalBTC = mTotalBTC + data.getDouble(1); mTotalUSD = mTotalUSD + data.getDouble(2); + mCurrencyValues.put(key, new Pair<>(data.getDouble(0), data.getDouble(2))); } } @@ -48,4 +53,12 @@ public class BinanceAccountBalance { public double getTotalBTC() { return mTotalBTC; } + + public Pair getCurrencyValue(String currency) { + if (mCurrencyValues.containsKey(currency) + && mCurrencyValues.get(currency) != null) { + return mCurrencyValues.get(currency); + } + return null; + } } \ No newline at end of file diff --git a/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceCoinNetworks.java b/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceCoinNetworks.java new file mode 100644 index 00000000000..cd9279efb5d --- /dev/null +++ b/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceCoinNetworks.java @@ -0,0 +1,55 @@ +/** Copyright (c) 2020 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.chromium.chrome.browser.widget.crypto.binance; + +import androidx.annotation.VisibleForTesting; +import java.util.Iterator; +import java.util.Map; +import java.util.HashMap; +import java.util.List; +import java.util.ArrayList; +import android.text.TextUtils; +import android.util.Pair; + +import org.json.JSONException; +import org.json.JSONObject; +import org.json.JSONArray; + +import org.chromium.base.Log; +import org.chromium.chrome.browser.widget.crypto.binance.CoinNetworkModel; + +public class BinanceCoinNetworks { + private List mCoinNetwroksList = new ArrayList<>(); + + //|| BinanceWidgetManager.usCurrenciesMap.containsKey(key) + + public BinanceCoinNetworks (String jsonNetworks) throws JSONException { + fromJson (jsonNetworks); + } + + private void fromJson(String jsonNetworks) throws JSONException { + JSONObject jsonroot = new JSONObject(jsonNetworks); + Iterator keys = jsonroot.keys(); + while (keys.hasNext()) { + String key = keys.next(); + if (BinanceWidgetManager.comCurrenciesMap.containsKey(key)) { + CoinNetworkModel coinNetworkModel = BinanceWidgetManager.comCurrenciesMap.get(key); + Log.e("NTP", key); + coinNetworkModel.setTickerNetwork(jsonroot.getString(key)); + mCoinNetwroksList.add(coinNetworkModel); + } + } + } + + public List getCoinNetworksList() { + return mCoinNetwroksList; + } + + @Override + public String toString() { + return TextUtils.join(", ", mCoinNetwroksList); + } +} \ No newline at end of file diff --git a/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceDepositAdapter.java b/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceDepositAdapter.java new file mode 100644 index 00000000000..90c4795c9d9 --- /dev/null +++ b/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceDepositAdapter.java @@ -0,0 +1,90 @@ +/* Copyright (c) 2020 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ +package org.chromium.chrome.browser.widget.crypto.binance; + +import android.annotation.SuppressLint; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; +import android.text.TextUtils; + +import android.util.Pair; +import android.content.Context; +import org.chromium.base.ContextUtils; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.ItemTouchHelper; +import androidx.recyclerview.widget.RecyclerView; + +import org.chromium.chrome.R; +import org.chromium.chrome.browser.widget.crypto.binance.CoinNetworkModel; + +import java.util.List; + +public class BinanceDepositAdapter extends RecyclerView.Adapter { + private Context mContext = ContextUtils.getApplicationContext(); + private List currencyList; + private BinanceDepositListener binanceDepositListener; + + public interface BinanceDepositListener { + void onItemClick(CoinNetworkModel coinNetworkModel); + } + + public void setBinanceDepositListener(BinanceDepositListener binanceDepositListener) { + this.binanceDepositListener = binanceDepositListener; + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.binance_deposit_item, parent, false); + return new CurrencyViewHolder(view); + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, int position) { + CurrencyViewHolder currencyViewHolder = (CurrencyViewHolder) holder; + CoinNetworkModel coinNetworkModel = currencyList.get(position); + currencyViewHolder.currencyText.setText(coinNetworkModel.getCoin() + (TextUtils.isEmpty(coinNetworkModel.getCoinDesc()) ? "" : " (" + coinNetworkModel.getCoinDesc() + ")")); + currencyViewHolder.currencyImageView.setImageResource(coinNetworkModel.getCoinRes()); + currencyViewHolder.rootView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (binanceDepositListener != null) { + binanceDepositListener.onItemClick(coinNetworkModel); + } + } + }); + } + + @Override + public int getItemCount() { + return currencyList == null ? 0 : currencyList.size(); + } + + void setCurrencyList(List currencyList) { + this.currencyList = currencyList; + notifyDataSetChanged(); + } + + private class CurrencyViewHolder extends RecyclerView.ViewHolder { + ImageView currencyImageView; + TextView currencyText; + View rootView; + + CurrencyViewHolder(View itemView) { + super(itemView); + + rootView = itemView; + currencyImageView = itemView.findViewById(R.id.currency_image); + currencyText = itemView.findViewById(R.id.currency_text); + } + } +} \ No newline at end of file diff --git a/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceDepositFragment.java b/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceDepositFragment.java new file mode 100644 index 00000000000..1e840ea454c --- /dev/null +++ b/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceDepositFragment.java @@ -0,0 +1,215 @@ +/* Copyright (c) 2020 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.chromium.chrome.browser.widget.crypto.binance; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; +import android.widget.ImageView; +import android.widget.FrameLayout; +import android.view.MotionEvent; +import android.text.TextUtils; + +import androidx.fragment.app.Fragment; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import org.chromium.base.Log; +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; +import org.chromium.chrome.browser.widget.crypto.binance.BinanceNativeWorker; +import org.chromium.chrome.browser.widget.crypto.binance.BinanceObserver; +import org.chromium.chrome.browser.widget.crypto.binance.BinanceAccountBalance; +import org.chromium.chrome.browser.widget.crypto.binance.BinanceCoinNetworks; +import org.chromium.chrome.browser.widget.crypto.binance.BinanceWidgetManager; +import org.chromium.chrome.browser.widget.crypto.binance.CoinNetworkModel; +import org.chromium.chrome.browser.QRCodeShareDialogFragment; + +import java.util.List; +import org.json.JSONException; + +import org.chromium.chrome.R; + +/** + * A simple {@link Fragment} subclass. + */ +public class BinanceDepositFragment extends Fragment { + private BinanceNativeWorker mBinanceNativeWorker; + private BinanceDepositAdapter mBinanceDepositAdapter; + + private RecyclerView currencyRecyclerView; + + private CoinNetworkModel selectedCoinNetworkModel; + + public BinanceDepositFragment() { + // Required empty public constructor + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mBinanceNativeWorker = BinanceNativeWorker.getInstance(); + } + + @Override + public View onCreateView( + LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + // Inflate the layout for this fragment + mBinanceNativeWorker.AddObserver(mBinanaceObserver); + return inflater.inflate(R.layout.fragment_binance_deposit, container, false); + } + + @Override + public void onDestroyView() { + mBinanceNativeWorker.RemoveObserver(mBinanaceObserver); + super.onDestroyView(); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + currencyRecyclerView = view.findViewById(R.id.recyclerview_currency_list); + currencyRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); + currencyRecyclerView.setOnTouchListener(new RecyclerView.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + int action = event.getAction(); + switch (action) { + case MotionEvent.ACTION_DOWN: + // Disallow NestedScrollView to intercept touch events. + v.getParent().requestDisallowInterceptTouchEvent(true); + break; + + case MotionEvent.ACTION_UP: + // Allow NestedScrollView to intercept touch events. + v.getParent().requestDisallowInterceptTouchEvent(false); + break; + } + + // Handle RecyclerView touch events. + v.onTouchEvent(event); + return true; + } + }); + mBinanceDepositAdapter = new BinanceDepositAdapter(); + currencyRecyclerView.setAdapter(mBinanceDepositAdapter); + mBinanceDepositAdapter.setBinanceDepositListener(binanceDepositListener); + + mBinanceNativeWorker.getCoinNetworks(); + // Log.e("NTP", "Set CoinNetworks"); + } + + private BinanceDepositAdapter.BinanceDepositListener binanceDepositListener = + new BinanceDepositAdapter.BinanceDepositListener() { + @Override + public void onItemClick(CoinNetworkModel coinNetworkModel) { + selectedCoinNetworkModel = coinNetworkModel; + mBinanceNativeWorker.getDepositInfo(coinNetworkModel.getCoin(), coinNetworkModel.getTickerNetwork()); + } + }; + + private BinanceObserver mBinanaceObserver = new BinanceObserver() { + @Override + public void OnGetAccessToken(boolean isSuccess) {}; + + @Override + public void OnGetAccountBalances(String jsonBalances, boolean isSuccess) { + // Log.e("NTP", "AccountBalances : " + jsonBalances); + }; + + @Override + public void OnGetConvertQuote(String quoteId, String quotePrice, String totalFee, String totalAmount) {}; + + @Override + public void OnGetCoinNetworks(String jsonNetworks) { + // Log.e("NTP", "OnGetCoinNetworks"+jsonNetworks); + try { + BinanceCoinNetworks binanceCoinNetworks = new BinanceCoinNetworks(jsonNetworks); + mBinanceDepositAdapter.setCurrencyList(binanceCoinNetworks.getCoinNetworksList()); + // Log.e("NTP", "CoinNetworks : " + binanceCoinNetworks.toString()); + } catch (JSONException e) { + Log.e("NTP", e.getMessage()); + } + }; + + @Override + public void OnGetDepositInfo(String depositAddress, String depositTag, boolean isSuccess) { + if (isSuccess + && selectedCoinNetworkModel != null + && getView() != null) { + FrameLayout depositLayout = (FrameLayout) getView().findViewById(R.id.binance_deposit_layout); + ImageView depositBack = depositLayout.findViewById(R.id.currency_back); + TextView currencyTitleText = depositLayout.findViewById(R.id.currency_text); + ImageView deposiIcon = depositLayout.findViewById(R.id.currency_image); + ImageView deposiQrIcon = depositLayout.findViewById(R.id.currency_qr_image); + TextView currencyAddressText = depositLayout.findViewById(R.id.currency_address_text); + TextView currencyMemoText = depositLayout.findViewById(R.id.currency_memo_text); + TextView currencyAddressValueText = depositLayout.findViewById(R.id.currency_address_value_text); + TextView currencyMemoValueText = depositLayout.findViewById(R.id.currency_memo_value_text); + + deposiQrIcon.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + QRCodeShareDialogFragment mQRCodeShareDialogFragment = + new QRCodeShareDialogFragment(); + mQRCodeShareDialogFragment.setQRCodeText(depositAddress); + mQRCodeShareDialogFragment.show( + getActivity().getSupportFragmentManager(), + "QRCodeShareDialogFragment"); + } + }); + + if (selectedCoinNetworkModel != null) { + currencyTitleText.setText(selectedCoinNetworkModel.getCoin() + (TextUtils.isEmpty(selectedCoinNetworkModel.getCoinDesc()) ? "" : " (" + selectedCoinNetworkModel.getCoinDesc() + ")")); + currencyAddressText.setText(String.format(getResources().getString(R.string.currency_address_text), selectedCoinNetworkModel.getCoin())); + currencyMemoText.setText(String.format(getResources().getString(R.string.currency_memo_text), selectedCoinNetworkModel.getCoin())); + deposiIcon.setImageResource(selectedCoinNetworkModel.getCoinRes()); + } + + depositBack.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (currencyRecyclerView != null) { + currencyRecyclerView.setVisibility(View.VISIBLE); + depositLayout.setVisibility(View.GONE); + currencyMemoText.setVisibility(View.GONE); + currencyMemoValueText.setVisibility(View.GONE); + } + } + }); + depositLayout.setVisibility(View.VISIBLE); + if (currencyRecyclerView != null) { + currencyRecyclerView.setVisibility(View.GONE); + } + + currencyAddressValueText.setText(depositAddress); + if (!TextUtils.isEmpty(depositTag)) { + currencyMemoText.setVisibility(View.VISIBLE); + currencyMemoValueText.setVisibility(View.VISIBLE); + currencyMemoValueText.setText(depositTag); + } + + selectedCoinNetworkModel = null; + + Log.e("NTP", "depositAddress : " + depositAddress); + Log.e("NTP", "depositeTag : " + depositTag); + } + }; + + @Override + public void OnConfirmConvert(boolean isSuccess, String message) {}; + + @Override + public void OnGetConvertAssets(String jsonAssets) {}; + + @Override + public void OnRevokeToken(boolean isSuccess) {}; + }; +} \ No newline at end of file diff --git a/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceNativeWorker.java b/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceNativeWorker.java index e6eca296a32..b9a8f391a31 100644 --- a/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceNativeWorker.java +++ b/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceNativeWorker.java @@ -110,9 +110,9 @@ public class BinanceNativeWorker { } @CalledByNative - public void OnGetDepositInfo(String depositAddress, String depositeTag, boolean isSuccess) { + public void OnGetDepositInfo(String depositAddress, String depositTag, boolean isSuccess) { for (BinanceObserver observer : mObservers) { - observer.OnGetDepositInfo(depositAddress, depositeTag, isSuccess); + observer.OnGetDepositInfo(depositAddress, depositTag, isSuccess); } } diff --git a/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceObserver.java b/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceObserver.java index b359a6c873e..bc457c12ca2 100644 --- a/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceObserver.java +++ b/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceObserver.java @@ -9,7 +9,7 @@ public interface BinanceObserver { default public void OnGetAccountBalances(String jsonBalances, boolean isSuccess) {}; default public void OnGetConvertQuote(String quoteId, String quotePrice, String totalFee, String totalAmount) {}; default public void OnGetCoinNetworks(String jsonNetworks) {}; - default public void OnGetDepositInfo(String depositAddress, String depositeTag, boolean isSuccess) {}; + default public void OnGetDepositInfo(String depositAddress, String depositTag, boolean isSuccess) {}; default public void OnConfirmConvert(boolean isSuccess, String message) {}; default public void OnGetConvertAssets(String jsonAssets) {}; default public void OnRevokeToken(boolean isSuccess) {}; diff --git a/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceSummaryFragment.java b/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceSummaryFragment.java new file mode 100644 index 00000000000..cdd4d2d4672 --- /dev/null +++ b/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceSummaryFragment.java @@ -0,0 +1,132 @@ +/* Copyright (c) 2020 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.chromium.chrome.browser.widget.crypto.binance; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; +import android.util.Pair; + +import androidx.fragment.app.Fragment; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import org.chromium.base.Log; +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; +import org.chromium.chrome.browser.widget.crypto.binance.BinanceNativeWorker; +import org.chromium.chrome.browser.widget.crypto.binance.BinanceObserver; +import org.chromium.chrome.browser.widget.crypto.binance.BinanceAccountBalance; +import org.chromium.chrome.browser.widget.crypto.binance.BinanceCoinNetworks; +import org.chromium.chrome.browser.widget.crypto.binance.BinanceWidgetManager; + +import java.util.List; +import org.json.JSONException; + +import org.chromium.chrome.R; + +/** + * A simple {@link Fragment} subclass. + */ +public class BinanceSummaryFragment extends Fragment { + private BinanceNativeWorker mBinanceNativeWorker; + private CurrencyListAdapter mCurrencyListAdapter; + + public BinanceSummaryFragment() { + // Required empty public constructor + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mBinanceNativeWorker = BinanceNativeWorker.getInstance(); + } + + // @Override + // public void setUserVisibleHint(boolean isVisibleToUser) { + // super.setUserVisibleHint(isVisibleToUser); + // if (isVisibleToUser && isResumed()) { + // mBinanceNativeWorker.AddObserver(mBinanaceObserver); + // } else { + // mBinanceNativeWorker.RemoveObserver(mBinanaceObserver); + // } + // } + + @Override + public View onCreateView( + LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + // Inflate the layout for this fragment + mBinanceNativeWorker.AddObserver(mBinanaceObserver); + return inflater.inflate(R.layout.fragment_binance_summary, container, false); + } + + @Override + public void onDestroyView() { + mBinanceNativeWorker.RemoveObserver(mBinanaceObserver); + super.onDestroyView(); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + RecyclerView currencyRecyclerView = view.findViewById(R.id.recyclerview_currency_list); + currencyRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); + mCurrencyListAdapter = new CurrencyListAdapter(); + currencyRecyclerView.setAdapter(mCurrencyListAdapter); + + TextView binanceBalanceText = view.findViewById(R.id.binance_balance_text); + TextView binanceUSDBalanceText = view.findViewById(R.id.binance_usd_balance_text); + BinanceAccountBalance binanceAccountBalance = BinanceWidgetManager.getInstance().getBinanceAccountBalance(); + if (binanceAccountBalance != null) { + binanceBalanceText.setText(String.format(getActivity().getResources().getString(R.string.btc_balance), String.valueOf(binanceAccountBalance.getTotalBTC()))); + binanceUSDBalanceText.setText(String.format(getActivity().getResources().getString(R.string.usd_balance), String.valueOf(binanceAccountBalance.getTotalUSD()))); + } + + mBinanceNativeWorker.getCoinNetworks(); + // Log.e("NTP", "Set CoinNetworks"); + } + + private BinanceObserver mBinanaceObserver = new BinanceObserver() { + @Override + public void OnGetAccessToken(boolean isSuccess) {}; + + @Override + public void OnGetAccountBalances(String jsonBalances, boolean isSuccess) { + // Log.e("NTP", "AccountBalances : " + jsonBalances); + }; + + @Override + public void OnGetConvertQuote(String quoteId, String quotePrice, String totalFee, String totalAmount) {}; + + @Override + public void OnGetCoinNetworks(String jsonNetworks) { + // Log.e("NTP", "OnGetCoinNetworks"+jsonNetworks); + try { + BinanceCoinNetworks binanceCoinNetworks = new BinanceCoinNetworks(jsonNetworks); + mCurrencyListAdapter.setCurrencyList(binanceCoinNetworks.getCoinNetworksList()); + // Log.e("NTP", "CoinNetworks : " + binanceCoinNetworks.toString()); + } catch (JSONException e) { + Log.e("NTP", e.getMessage()); + } + }; + + @Override + public void OnGetDepositInfo(String depositAddress, String depositeTag, boolean isSuccess) {}; + + @Override + public void OnConfirmConvert(boolean isSuccess, String message) {}; + + @Override + public void OnGetConvertAssets(String jsonAssets) {}; + + @Override + public void OnRevokeToken(boolean isSuccess) {}; + }; +} \ No newline at end of file diff --git a/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceWidgetManager.java b/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceWidgetManager.java new file mode 100644 index 00000000000..aacef533d92 --- /dev/null +++ b/android/java/org/chromium/chrome/browser/widget/crypto/binance/BinanceWidgetManager.java @@ -0,0 +1,107 @@ +/** + * Copyright (c) 2020 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package org.chromium.chrome.browser.widget.crypto.binance; + +import android.content.SharedPreferences; + +import org.chromium.base.ContextUtils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import java.util.HashMap; + +import org.chromium.chrome.R; +import org.chromium.chrome.browser.widget.crypto.binance.BinanceAccountBalance; +import org.chromium.chrome.browser.widget.crypto.binance.CoinNetworkModel; + +public class BinanceWidgetManager { + public static final String PREF_BINANCE_USER_AUTHENTICATION = "binance_user_authentication"; + + private static BinanceWidgetManager sInstance; + + private final SharedPreferences mSharedPreferences; + + private static BinanceAccountBalance binanceAccountBalance; + + public static final List fiatList = Arrays.asList("USD","AUD","ARS","BGN","BRL","CAD","CHF","CNY","COP","CZK","DKK","EUR","GBP","HKD","HRK","HUF","IDR","ILS","INR","JPY","KRW","KZT","MXN","NGN","NOK","NZD","PLN","RON","RUB","SEK","THB","TRY","UAH","VND","ZAR"); + public static final Map usCurrenciesMap = new HashMap() { + { + put("BTC", new CoinNetworkModel("BTC", "Bitcoin", R.drawable.btc)); + put("ETH", new CoinNetworkModel("ETH", "Ethereum", R.drawable.eth)); + put("BNB", new CoinNetworkModel("BNB", "Binance Coin", R.drawable.bnb)); + put("BCH", new CoinNetworkModel("BCH", "Bitcoin Cash", R.drawable.bch)); + put("XRP", new CoinNetworkModel("XRP", "Ripple", R.drawable.xrp)); + put("BUSD", new CoinNetworkModel("BUSD", "US Dollar", R.drawable.eth)); + put("BAT", new CoinNetworkModel("BAT", "Basic Attention Token", R.drawable.bat)); + put("XTZ", new CoinNetworkModel("XTZ", "", R.drawable.xtz)); + put("ALGO", new CoinNetworkModel("ALGO", "", R.drawable.eth)); + put("ATOM", new CoinNetworkModel("ATOM", "", R.drawable.atom)); + put("LINK", new CoinNetworkModel("LINK", "", R.drawable.link)); + put("VET", new CoinNetworkModel("VET", "", R.drawable.vet)); + put("ZRX", new CoinNetworkModel("ZRX", "", R.drawable.zrx)); + put("ADA", new CoinNetworkModel("ADA", "", R.drawable.ada)); + put("XLM", new CoinNetworkModel("XLM", "", R.drawable.xlm)); + put("ENJ", new CoinNetworkModel("ENJ", "", R.drawable.enj)); + put("ZIL", new CoinNetworkModel("ZIL", "", R.drawable.zil)); + put("RVN", new CoinNetworkModel("RVN", "", R.drawable.rvn)); + put("ONT", new CoinNetworkModel("ONT", "", R.drawable.ont)); + put("HBAR", new CoinNetworkModel("HBAR", "", R.drawable.eth)); + put("MATIC", new CoinNetworkModel("MATIC", "", R.drawable.matic)); + } + }; + public static final Map comCurrenciesMap = new HashMap() { + { + put("BTC", new CoinNetworkModel("BTC", "Bitcoin", R.drawable.btc)); + put("ETH", new CoinNetworkModel("ETH", "Ethereum", R.drawable.eth)); + put("BAT", new CoinNetworkModel("BAT", "Basic Attention Token", R.drawable.bat)); + put("XRP", new CoinNetworkModel("XRP", "Ripple", R.drawable.xrp)); + put("BNB", new CoinNetworkModel("BNB", "Binance Coin", R.drawable.bnb)); + put("BCH", new CoinNetworkModel("BCH", "Bitcoin Cash", R.drawable.bch)); + put("DASH", new CoinNetworkModel("DASH", "", R.drawable.dash)); + put("EOS", new CoinNetworkModel("EOS", "", R.drawable.eos)); + put("NANO", new CoinNetworkModel("NANO", "", R.drawable.nano)); + put("PAX", new CoinNetworkModel("PAX", "", R.drawable.pax)); + put("TRX", new CoinNetworkModel("TRX", "", R.drawable.trx)); + put("BUSD", new CoinNetworkModel("BUSD", "US Dollar", R.drawable.eth)); + put("TUSD", new CoinNetworkModel("TUSD", "", R.drawable.tusd)); + put("USDT", new CoinNetworkModel("USDT", "", R.drawable.usdt)); + } + }; + + public BinanceAccountBalance getBinanceAccountBalance() { + return binanceAccountBalance; + } + + public void setBinanceAccountBalance(BinanceAccountBalance binanceAccountBalance) { + this.binanceAccountBalance = binanceAccountBalance; + } + + private BinanceWidgetManager() { + mSharedPreferences = ContextUtils.getAppSharedPreferences(); + } + + public static BinanceWidgetManager getInstance() { + if (sInstance == null) { + sInstance = new BinanceWidgetManager(); + } + return sInstance; + } + + public boolean isUserAuthenticatedForBinance() { + return mSharedPreferences.getBoolean(PREF_BINANCE_USER_AUTHENTICATION, false); + } + + public void setUserAuthenticationForBinance(boolean isAuthenticated) { + SharedPreferences.Editor sharedPreferencesEditor = mSharedPreferences.edit(); + sharedPreferencesEditor.putBoolean(PREF_BINANCE_USER_AUTHENTICATION, isAuthenticated); + sharedPreferencesEditor.apply(); + } +} \ No newline at end of file diff --git a/android/java/org/chromium/chrome/browser/widget/crypto/binance/BlankFragment.java b/android/java/org/chromium/chrome/browser/widget/crypto/binance/BlankFragment.java deleted file mode 100644 index a03d6ae1007..00000000000 --- a/android/java/org/chromium/chrome/browser/widget/crypto/binance/BlankFragment.java +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (c) 2020 The Brave Authors. All rights reserved. - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.chromium.chrome.browser.widget.crypto.binance; - -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import androidx.fragment.app.Fragment; - -import org.chromium.chrome.R; - -/** - * A simple {@link Fragment} subclass. - */ -public class BlankFragment extends Fragment { - public BlankFragment() { - // Required empty public constructor - } - - @Override - public View onCreateView( - LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - // Inflate the layout for this fragment - return inflater.inflate(R.layout.fragment_blank, container, false); - } -} \ No newline at end of file diff --git a/android/java/org/chromium/chrome/browser/widget/crypto/binance/CoinNetworkModel.java b/android/java/org/chromium/chrome/browser/widget/crypto/binance/CoinNetworkModel.java new file mode 100644 index 00000000000..f42a277aa17 --- /dev/null +++ b/android/java/org/chromium/chrome/browser/widget/crypto/binance/CoinNetworkModel.java @@ -0,0 +1,50 @@ +/** Copyright (c) 2020 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.chromium.chrome.browser.widget.crypto.binance; + +import androidx.annotation.VisibleForTesting; + +public class CoinNetworkModel { + + private String coin; + private String tickerNetwork; + private String coinDesc; + private int coinRes; + + public CoinNetworkModel (String coin, String coinDesc, int coinRes) { + this.coin = coin; + this.coinDesc = coinDesc; + this.coinRes = coinRes; + } + + public void setTickerNetwork(String tickerNetwork) { + this.tickerNetwork = tickerNetwork; + } + + public String getCoin() { + return coin; + } + + public String getTickerNetwork() { + return tickerNetwork; + } + + public String getCoinDesc() { + return coinDesc; + } + + public int getCoinRes() { + return coinRes; + } + + @Override + public String toString() { + StringBuilder strBuilder = new StringBuilder(coin); + strBuilder.append(tickerNetwork); + strBuilder.append(coinDesc); + return strBuilder.toString(); + } +} \ No newline at end of file diff --git a/android/java/org/chromium/chrome/browser/widget/crypto/binance/CryptoWidgetBottomSheetDialogFragment.java b/android/java/org/chromium/chrome/browser/widget/crypto/binance/CryptoWidgetBottomSheetDialogFragment.java index 2021c405c4f..2a59cc34067 100644 --- a/android/java/org/chromium/chrome/browser/widget/crypto/binance/CryptoWidgetBottomSheetDialogFragment.java +++ b/android/java/org/chromium/chrome/browser/widget/crypto/binance/CryptoWidgetBottomSheetDialogFragment.java @@ -10,6 +10,8 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import org.json.JSONException; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.FragmentPagerAdapter; @@ -19,14 +21,24 @@ import com.google.android.material.bottomsheet.BottomSheetDialogFragment; import com.google.android.material.tabs.TabLayout; import org.chromium.chrome.R; +import org.chromium.base.Log; +import org.chromium.chrome.browser.widget.crypto.binance.BinanceNativeWorker; +import org.chromium.chrome.browser.widget.crypto.binance.BinanceObserver; +import org.chromium.chrome.browser.widget.crypto.binance.BinanceAccountBalance; +import org.chromium.chrome.browser.widget.crypto.binance.BinanceCoinNetworks; +import org.chromium.chrome.browser.widget.crypto.binance.BinanceWidgetManager; + +import java.util.List; +import java.util.ArrayList; public class CryptoWidgetBottomSheetDialogFragment extends BottomSheetDialogFragment { + @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, - @Nullable Bundle savedInstanceState) { + @Nullable Bundle savedInstanceState) { View view = inflater.inflate( - R.layout.fragment_crypto_widget_bottom_sheet_dialog, container, false); + R.layout.fragment_crypto_widget_bottom_sheet_dialog, container, false); return view; } diff --git a/android/java/org/chromium/chrome/browser/widget/crypto/binance/CryptoWidgetTabAdapter.java b/android/java/org/chromium/chrome/browser/widget/crypto/binance/CryptoWidgetTabAdapter.java index 7a5c162fcc1..4ab6851ae2d 100644 --- a/android/java/org/chromium/chrome/browser/widget/crypto/binance/CryptoWidgetTabAdapter.java +++ b/android/java/org/chromium/chrome/browser/widget/crypto/binance/CryptoWidgetTabAdapter.java @@ -25,7 +25,10 @@ public class CryptoWidgetTabAdapter extends FragmentStatePagerAdapter { @NonNull @Override public Fragment getItem(int position) { - return new BlankFragment(); + if (position == 1) { + return new BinanceDepositFragment(); + } + return new BinanceSummaryFragment(); } @Override diff --git a/android/java/org/chromium/chrome/browser/widget/crypto/binance/CurrencyListAdapter.java b/android/java/org/chromium/chrome/browser/widget/crypto/binance/CurrencyListAdapter.java new file mode 100644 index 00000000000..8ee35288dd1 --- /dev/null +++ b/android/java/org/chromium/chrome/browser/widget/crypto/binance/CurrencyListAdapter.java @@ -0,0 +1,79 @@ +/* Copyright (c) 2019 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ +package org.chromium.chrome.browser.widget.crypto.binance; + +import android.annotation.SuppressLint; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import android.util.Pair; +import android.content.Context; +import org.chromium.base.ContextUtils; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.ItemTouchHelper; +import androidx.recyclerview.widget.RecyclerView; + +import org.chromium.chrome.R; + +import java.util.List; + +public class CurrencyListAdapter extends RecyclerView.Adapter { + private Context mContext = ContextUtils.getApplicationContext(); + private List currencyList; + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.binance_currency_item, parent, false); + return new CurrencyViewHolder(view); + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, int position) { + CurrencyViewHolder currencyViewHolder = (CurrencyViewHolder) holder; + CoinNetworkModel coinNetworkModel = currencyList.get(position); + currencyViewHolder.currencyText.setText(coinNetworkModel.getCoin()); + currencyViewHolder.currencyImageView.setImageResource(coinNetworkModel.getCoinRes()); + BinanceAccountBalance binanceAccountBalance = BinanceWidgetManager.getInstance().getBinanceAccountBalance(); + if (binanceAccountBalance.getCurrencyValue(coinNetworkModel.getCoin()) != null) { + Pair currencyValue = binanceAccountBalance.getCurrencyValue(coinNetworkModel.getCoin()); + currencyViewHolder.currencyValueText.setText(String.valueOf(currencyValue.first)); + currencyViewHolder.currencyUsdText.setText(String.format(mContext.getResources().getString(R.string.usd_balance), String.valueOf(currencyValue.second))); + } + } + + @Override + public int getItemCount() { + return currencyList == null ? 0 : currencyList.size(); + } + + void setCurrencyList(List currencyList) { + this.currencyList = currencyList; + notifyDataSetChanged(); + } + + private class CurrencyViewHolder extends RecyclerView.ViewHolder { + ImageView currencyImageView; + TextView currencyText; + TextView currencyValueText; + TextView currencyUsdText; + + CurrencyViewHolder(View itemView) { + super(itemView); + + currencyImageView = itemView.findViewById(R.id.currency_image); + currencyText = itemView.findViewById(R.id.currency_text); + currencyValueText = itemView.findViewById(R.id.currency_value_text); + currencyUsdText = itemView.findViewById(R.id.currency_usd_text); + } + } +} \ No newline at end of file diff --git a/android/java/res/layout/binance_currency_item.xml b/android/java/res/layout/binance_currency_item.xml new file mode 100644 index 00000000000..5e668aea664 --- /dev/null +++ b/android/java/res/layout/binance_currency_item.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/android/java/res/layout/binance_deposit_item.xml b/android/java/res/layout/binance_deposit_item.xml new file mode 100644 index 00000000000..9bda96e0f2d --- /dev/null +++ b/android/java/res/layout/binance_deposit_item.xml @@ -0,0 +1,26 @@ + + + + + + + + \ No newline at end of file diff --git a/android/java/res/layout/binance_deposit_layout.xml b/android/java/res/layout/binance_deposit_layout.xml new file mode 100644 index 00000000000..57a5277e309 --- /dev/null +++ b/android/java/res/layout/binance_deposit_layout.xml @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/android/java/res/layout/crypto_widget_layout.xml b/android/java/res/layout/crypto_widget_layout.xml index a193053b0cc..82ed9c64ffd 100644 --- a/android/java/res/layout/crypto_widget_layout.xml +++ b/android/java/res/layout/crypto_widget_layout.xml @@ -70,7 +70,7 @@ android:text="@string/btc_balance" android:textColor="#FFFFFF" android:layout_marginBottom="4dp" - android:textSize="24sp" /> + android:textSize="32sp" /> + android:textSize="16sp" /> diff --git a/android/java/res/layout/fragment_binance_deposit.xml b/android/java/res/layout/fragment_binance_deposit.xml new file mode 100644 index 00000000000..7231ec398ad --- /dev/null +++ b/android/java/res/layout/fragment_binance_deposit.xml @@ -0,0 +1,15 @@ + + + + + + + + \ No newline at end of file diff --git a/android/java/res/layout/fragment_blank.xml b/android/java/res/layout/fragment_binance_summary.xml similarity index 58% rename from android/java/res/layout/fragment_blank.xml rename to android/java/res/layout/fragment_binance_summary.xml index 60f2e11a32d..5d95e01ec92 100644 --- a/android/java/res/layout/fragment_blank.xml +++ b/android/java/res/layout/fragment_binance_summary.xml @@ -3,10 +3,47 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - android:orientation="vertical" - tools:context=".BlankFragment"> + android:orientation="vertical"> - + + + + + + + + + + + + \ No newline at end of file diff --git a/android/java/res/layout/fragment_crypto_widget_bottom_sheet_dialog.xml b/android/java/res/layout/fragment_crypto_widget_bottom_sheet_dialog.xml index 1a8941a8af5..b7713290139 100644 --- a/android/java/res/layout/fragment_crypto_widget_bottom_sheet_dialog.xml +++ b/android/java/res/layout/fragment_crypto_widget_bottom_sheet_dialog.xml @@ -7,18 +7,35 @@ android:background="#1F1F1F" android:orientation="vertical"> - + android:orientation="horizontal"> + + + + + + \ No newline at end of file diff --git a/android/java/res/layout/top_sites_layout.xml b/android/java/res/layout/top_sites_layout.xml new file mode 100644 index 00000000000..1836bea525b --- /dev/null +++ b/android/java/res/layout/top_sites_layout.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/browser/ui/android/strings/android_brave_strings.grd b/browser/ui/android/strings/android_brave_strings.grd index 0ae3f6341c9..bc43dc18d65 100644 --- a/browser/ui/android/strings/android_brave_strings.grd +++ b/browser/ui/android/strings/android_brave_strings.grd @@ -1329,6 +1329,12 @@ until they verify, or until 90 days have passed. ≈ $%1$s0.0 + + %1$s Deposit Address + + + %1$s Deposit Memo +