diff --git a/common/src/main/java/org/dash/wallet/common/data/WalletUIConfig.kt b/common/src/main/java/org/dash/wallet/common/data/WalletUIConfig.kt
index 5c6ba0dab..66787e1fd 100644
--- a/common/src/main/java/org/dash/wallet/common/data/WalletUIConfig.kt
+++ b/common/src/main/java/org/dash/wallet/common/data/WalletUIConfig.kt
@@ -65,6 +65,7 @@ open class WalletUIConfig @Inject constructor(
val EXCHANGE_CURRENCY_DETECTED = booleanPreferencesKey("exchange_currency_detected")
val LAST_TOTAL_BALANCE = longPreferencesKey("last_total_balance")
val LAST_MIXED_BALANCE = longPreferencesKey("last_mixed_balance")
+ val CUSTOMIZED_SHORTCUTS = stringPreferencesKey("customized_shortcuts")
}
suspend fun getExchangeCurrencyCode(): String {
diff --git a/common/src/main/java/org/dash/wallet/common/services/analytics/AnalyticsConstants.kt b/common/src/main/java/org/dash/wallet/common/services/analytics/AnalyticsConstants.kt
index 167b4092c..8ce8d9466 100644
--- a/common/src/main/java/org/dash/wallet/common/services/analytics/AnalyticsConstants.kt
+++ b/common/src/main/java/org/dash/wallet/common/services/analytics/AnalyticsConstants.kt
@@ -126,6 +126,7 @@ object AnalyticsConstants {
const val SHORTCUT_SCAN_TO_PAY = "shortcut_scan_to_pay"
const val SHORTCUT_SEND_TO_ADDRESS = "shortcut_send_to_address"
const val SHORTCUT_RECEIVE = "shortcut_receive"
+ const val SHORTCUT_SEND = "shortcut_send"
const val SHORTCUT_BUY_AND_SELL = "shortcut_buy_and_sell_dash"
const val SHORTCUT_EXPLORE = "shortcut_explore"
const val HIDE_BALANCE = "home_hide_balance"
diff --git a/common/src/main/java/org/dash/wallet/common/ui/components/MyTheme.kt b/common/src/main/java/org/dash/wallet/common/ui/components/MyTheme.kt
index ffebaf4e8..526c28762 100644
--- a/common/src/main/java/org/dash/wallet/common/ui/components/MyTheme.kt
+++ b/common/src/main/java/org/dash/wallet/common/ui/components/MyTheme.kt
@@ -37,6 +37,14 @@ object MyTheme {
fontWeight = FontWeight(400)
)
+ val Overline = TextStyle(
+ fontSize = 12.sp,
+ lineHeight = 16.sp,
+ fontFamily = InterFont,
+ fontWeight = FontWeight(500),
+ textAlign = TextAlign.Center
+ )
+
val OverlineSemibold = TextStyle(
fontSize = 12.sp,
lineHeight = 16.sp,
diff --git a/common/src/main/java/org/dash/wallet/common/ui/receive/ReceiveInfoView.kt b/common/src/main/java/org/dash/wallet/common/ui/receive/ReceiveInfoView.kt
index 051b326a5..bddbc311b 100644
--- a/common/src/main/java/org/dash/wallet/common/ui/receive/ReceiveInfoView.kt
+++ b/common/src/main/java/org/dash/wallet/common/ui/receive/ReceiveInfoView.kt
@@ -80,7 +80,7 @@ class ReceiveInfoView(context: Context, attrs: AttributeSet?) : ConstraintLayout
}
binding.shareButton.setOnClickListener {
onShareClicked?.invoke()
- handleShare(paymentRequestUri)
+ address?.let { handleShare(it.toBase58()) }
}
refresh()
diff --git a/common/src/main/java/org/dash/wallet/common/util/GenericUtils.java b/common/src/main/java/org/dash/wallet/common/util/GenericUtils.java
deleted file mode 100644
index f7ea83fcb..000000000
--- a/common/src/main/java/org/dash/wallet/common/util/GenericUtils.java
+++ /dev/null
@@ -1,274 +0,0 @@
-///*
-// * Copyright 2011-2015 the original author or authors.
-// *
-// * This program is free software: you can redistribute it and/or modify
-// * it under the terms of the GNU General Public License as published by
-// * the Free Software Foundation, either version 3 of the License, or
-// * (at your option) any later version.
-// *
-// * This program is distributed in the hope that it will be useful,
-// * but WITHOUT ANY WARRANTY; without even the implied warranty of
-// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// * GNU General Public License for more details.
-// *
-// * You should have received a copy of the GNU General Public License
-// * along with this program. If not, see .
-// */
-//
-//package org.dash.wallet.common.util;
-//
-//import android.content.Context;
-//import android.graphics.drawable.Drawable;
-//import android.text.Spannable;
-//import android.text.SpannableStringBuilder;
-//import android.text.style.ImageSpan;
-//
-//import androidx.core.content.res.ResourcesCompat;
-//
-//import org.dash.wallet.common.R;
-//
-//import android.net.ConnectivityManager;
-//import android.os.Build;
-//import android.os.LocaleList;
-//import android.text.TextUtils;
-//import android.widget.Toast;
-//
-//import org.bitcoinj.utils.Fiat;
-//import org.bitcoinj.utils.MonetaryFormat;
-//import org.dash.wallet.common.Constants;
-//import org.dash.wallet.common.data.CurrencyInfo;
-//
-//import java.text.NumberFormat;
-//import java.util.Currency;
-//import java.util.Locale;
-//import java.util.Objects;
-//
-///**
-// * @author Andreas Schildbach
-// */
-//public class GenericUtils { TODO
-//
-// public static boolean startsWithIgnoreCase(final String string, final String prefix) {
-// return string.regionMatches(true, 0, prefix, 0, prefix.length());
-// }
-//
-// public static String currencySymbol(final String currencyCode) {
-// try {
-// final Currency currency = Currency.getInstance(currencyCode);
-// return currency.getSymbol();
-// } catch (final IllegalArgumentException x) {
-// return currencyCode;
-// }
-// }
-//
-// public static Spannable appendDashSymbol(Context context, CharSequence text, boolean spaceBefore, boolean spaceAfter, float scale) {
-// return insertDashSymbol(context, text, text.length(), spaceBefore, spaceAfter, scale);
-// }
-//
-// public static Spannable insertDashSymbol(Context context, CharSequence text, int position, boolean spaceBefore, boolean spaceAfter, float scale) {
-//
-// Drawable drawableDash = ResourcesCompat.getDrawable(context.getResources(), R.drawable.ic_dash_d_black, null);
-// if (drawableDash == null) {
-// return null;
-// }
-// int size = (int) (scale * 32);
-// drawableDash.setBounds(0, 0, size, size);
-// ImageSpan dashSymbol = new ImageSpan(drawableDash, ImageSpan.ALIGN_BASELINE);
-//
-// SpannableStringBuilder builder = new SpannableStringBuilder(text);
-// if (spaceBefore) {
-// builder.insert(position++, " ");
-// }
-// builder.insert(position, " ");
-// if (spaceAfter) {
-// builder.insert(position + 1, " ");
-// }
-// builder.setSpan(dashSymbol, position, position + 1, 0);
-//
-// return builder;
-// }
-//
-// public static boolean isInternetConnected(Context context) {
-// ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
-//
-// return cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnected();
-// }
-//
-// public static void showToast(Context context, String messages) {
-// Toast.makeText(context, messages, Toast.LENGTH_LONG).show();
-// }
-//
-// /**
-// * Function which returns a concatenation of the currency code or currency symbol
-// * For currencies used by multiple countries, we set a locale with any country using the currency
-// * If the currentCurrencySymbol equals the currency code, we just use the currency code, otherwise we
-// * get the symbol
-// * @param currencyCode
-// * @return
-// */
-// public static String setCurrentCurrencySymbolWithCode(String currencyCode) {
-// Locale currentLocale = new Locale("", "");
-// String currentCurrencySymbol = "";
-// switch (currencyCode.toLowerCase(Locale.ROOT)) {
-// case "eur":
-// currentLocale = Locale.FRANCE;
-// break;
-// case "xof":
-// currentLocale = new Locale("fr", "CM");
-// break;
-// case "xaf":
-// currentLocale = new Locale("fr", "SN");
-// break;
-// case "cfp":
-// currentLocale = new Locale("fr", "NC");
-// break;
-// case "hkd":
-// currentLocale = new Locale("en", "HK");
-// break;
-// case "bnd":
-// currentLocale = new Locale("ms", "BN");
-// break;
-// case "aud":
-// currentLocale = new Locale("en", "AU");
-// break;
-// case "gbp":
-// currentLocale = Locale.UK;
-// break;
-// case "inr":
-// currentLocale = new Locale("en", "IN");
-// break;
-// case "nzd":
-// currentLocale = new Locale("en", "NZ");
-// break;
-// case "ils":
-// currentLocale = new Locale("iw", "IL");
-// break;
-// case "jod":
-// currentLocale = new Locale("ar", "JO");
-// break;
-// case "rub":
-// currentLocale = new Locale("ru", "RU");
-// break;
-// case "zar":
-// currentLocale = new Locale("en", "ZA");
-// break;
-// case "chf":
-// currentLocale = new Locale("fr", "CH");
-// break;
-// case "try":
-// currentLocale = new Locale("tr", "TR");
-// break;
-// case "usd":
-// currentLocale = Locale.US;
-// break;
-// }
-// currentCurrencySymbol = TextUtils.isEmpty(currentLocale.getLanguage()) ?
-// currencySymbol(currencyCode.toLowerCase(Locale.ROOT)) : Currency.getInstance(currentLocale).getSymbol();
-//
-// return String.format(getDeviceLocale(), "%s",
-// currencyCode.equalsIgnoreCase(currentCurrencySymbol) ? currencyCode : currentCurrencySymbol);
-// }
-//
-// public static Locale getDeviceLocale() {
-// String countryCode = "";
-// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
-// countryCode = LocaleList.getDefault().get(0).getCountry();
-// } else {
-// countryCode = Locale.getDefault().getCountry();
-// }
-// String deviceLocaleLanguage = Locale.getDefault().getLanguage();
-// return new Locale(deviceLocaleLanguage, countryCode);
-// }
-//
-// public static FiatAmountFormat formatFiatFromLocale(CharSequence fiatValue) {
-// String valWithoutLetters = stripLettersFromString(fiatValue.toString());
-// String valWithoutComma = formatFiatWithoutComma(valWithoutLetters);
-// Double fiatAsDouble;
-// // we may get a NumberFormatException
-// try {
-// fiatAsDouble = valWithoutComma.length() == 0 ? 0.00 : Double.parseDouble(valWithoutComma);
-// } catch (NumberFormatException x) {
-// fiatAsDouble = 0.00;
-// }
-// NumberFormat numberFormat = NumberFormat.getCurrencyInstance(getDeviceLocale());
-// String formattedStringValue = numberFormat.format(fiatAsDouble);
-// // get currency symbol and code to remove explicitly
-// String currencyCode = numberFormat.getCurrency().getCurrencyCode();
-// String currencySymbol = numberFormat.getCurrency().getSymbol();
-// return new FiatAmountFormat(Character.isDigit(formattedStringValue.charAt(0)), stripCurrencyFromString(formattedStringValue, currencySymbol, currencyCode));
-// }
-//
-// /**
-// * Keep numericals, minus, dot, comma
-// */
-// private static String stripLettersFromString(String st) {
-// return st.replaceAll("[^\\d,.-]", "");
-// }
-//
-// /**
-// * Remove currency symbols and codes from the string
-// */
-// private static String stripCurrencyFromString(String st, String symbol, String code) {
-// return stripLettersFromString(st.replaceAll(symbol, "").replaceAll(code, ""));
-// }
-//
-// /**
-// * To perform some operations on our fiat values (ex: parse to double, convert fiat to Coin), it needs to be properly formatted
-// * In case our fiat value is in a currency that has a comma, we need to strip it away so as to have our value as a decimal
-// * @param fiatValue
-// * @return
-// */
-// public static String formatFiatWithoutComma(String fiatValue){
-// boolean fiatValueContainsCommaWithDecimal = fiatValue.contains(",") && fiatValue.contains(".");
-// return fiatValueContainsCommaWithDecimal ? fiatValue.replaceAll(",", "") : fiatValue.replaceAll(",", ".");
-// }
-//
-// public static String fiatToString(Fiat fiat) {
-// MonetaryFormat format = Constants.SEND_PAYMENT_LOCAL_FORMAT.noCode();
-// NumberFormat numberFormat = NumberFormat.getCurrencyInstance(getDeviceLocale());
-// Currency currency = Currency.getInstance(fiat.currencyCode);
-// numberFormat.setCurrency(currency);
-// String currencySymbol = currency.getSymbol(getDeviceLocale());
-// boolean isCurrencyFirst = numberFormat.format(1.0).startsWith(currencySymbol);
-//
-// if (isCurrencyFirst) {
-// return currencySymbol + " " + format.format(fiat);
-// } else {
-// return format.format(fiat) + " " + currencySymbol;
-// }
-// }
-//
-// public static boolean isCurrencyFirst(Fiat fiat) {
-// NumberFormat numberFormat = NumberFormat.getCurrencyInstance(getDeviceLocale());
-// Currency currency = Currency.getInstance(fiat.currencyCode);
-// numberFormat.setCurrency(currency);
-// String currencySymbol = currency.getSymbol(getDeviceLocale());
-// return numberFormat.format(1.0).startsWith(currencySymbol);
-// }
-//
-// public static String getLocalCurrencySymbol(String currencyCode) {
-// NumberFormat numberFormat = NumberFormat.getCurrencyInstance(getDeviceLocale());
-// Currency currency = Currency.getInstance(currencyCode);
-// numberFormat.setCurrency(currency);
-// return currency.getSymbol(getDeviceLocale());
-// }
-//
-// public static String fiatToStringWithoutCurrencyCode(Fiat fiat) {
-// MonetaryFormat format = Constants.SEND_PAYMENT_LOCAL_FORMAT.noCode();
-// return format.format(fiat).toString();
-// }
-//
-// public static String getCoinIcon(String code) {
-// return "https://raw.githubusercontent.com/jsupa/crypto-icons/main/icons/"+code.toLowerCase()+".png";
-// }
-//
-// public static String getLocaleCurrencyCode(){
-// Currency currency = Currency.getInstance(getDeviceLocale());
-// String newCurrencyCode = currency.getCurrencyCode();
-// if (CurrencyInfo.hasObsoleteCurrency(newCurrencyCode)) {
-// newCurrencyCode = CurrencyInfo.getUpdatedCurrency(newCurrencyCode);
-// }
-// newCurrencyCode = CurrencyInfo.getOtherName(newCurrencyCode);
-// return newCurrencyCode;
-// }
-//}
diff --git a/wallet/res/drawable/ic_arrow_drop_down_blue.xml b/wallet/res/drawable/ic_arrow_drop_down_blue.xml
deleted file mode 100644
index 48e5bd621..000000000
--- a/wallet/res/drawable/ic_arrow_drop_down_blue.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
diff --git a/wallet/res/drawable/ic_arrow_drop_up_blue.xml b/wallet/res/drawable/ic_arrow_drop_up_blue.xml
deleted file mode 100644
index 40906b462..000000000
--- a/wallet/res/drawable/ic_arrow_drop_up_blue.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
diff --git a/wallet/res/drawable/ic_arrow_icon.xml b/wallet/res/drawable/ic_arrow_icon.xml
deleted file mode 100644
index 9146fad55..000000000
--- a/wallet/res/drawable/ic_arrow_icon.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
diff --git a/wallet/res/drawable/ic_avatar_blue.xml b/wallet/res/drawable/ic_avatar_blue.xml
deleted file mode 100644
index a82e4d19f..000000000
--- a/wallet/res/drawable/ic_avatar_blue.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/wallet/res/drawable/ic_balance_warning.xml b/wallet/res/drawable/ic_balance_warning.xml
deleted file mode 100644
index 12817b42c..000000000
--- a/wallet/res/drawable/ic_balance_warning.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
diff --git a/wallet/res/drawable/ic_blue_clock.xml b/wallet/res/drawable/ic_blue_clock.xml
deleted file mode 100644
index e298d60b0..000000000
--- a/wallet/res/drawable/ic_blue_clock.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
diff --git a/wallet/res/drawable/ic_contact.xml b/wallet/res/drawable/ic_contact.xml
new file mode 100644
index 000000000..cde452364
--- /dev/null
+++ b/wallet/res/drawable/ic_contact.xml
@@ -0,0 +1,14 @@
+
+
+
+
diff --git a/wallet/res/drawable/ic_explore.xml b/wallet/res/drawable/ic_explore.xml
index 1d5418d19..8966f3999 100644
--- a/wallet/res/drawable/ic_explore.xml
+++ b/wallet/res/drawable/ic_explore.xml
@@ -1,45 +1,9 @@
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ android:pathData="M12,0C18.626,0 24,5.374 24,12C24,18.626 18.626,24 12,24C5.374,24 0,18.636 0,12C0,5.363 5.363,0 12,0ZM16.623,8.056C16.758,7.638 16.372,7.242 15.955,7.367L9.809,9.287C9.558,9.37 9.35,9.558 9.277,9.819L7.357,15.976C7.221,16.383 7.617,16.779 8.024,16.643L14.139,14.724C14.39,14.65 14.598,14.452 14.671,14.191L16.612,8.045L16.623,8.056Z"
+ android:fillColor="#78C4F5"/>
diff --git a/wallet/res/drawable/ic_receive_payments.xml b/wallet/res/drawable/ic_receive_payments.xml
deleted file mode 100644
index d1a14d955..000000000
--- a/wallet/res/drawable/ic_receive_payments.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/wallet/res/drawable/ic_send_to_address.xml b/wallet/res/drawable/ic_send_to_address.xml
new file mode 100644
index 000000000..28d63f021
--- /dev/null
+++ b/wallet/res/drawable/ic_send_to_address.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/wallet/res/drawable/ic_shortcut_atm.xml b/wallet/res/drawable/ic_shortcut_atm.xml
new file mode 100644
index 000000000..4e27150ab
--- /dev/null
+++ b/wallet/res/drawable/ic_shortcut_atm.xml
@@ -0,0 +1,12 @@
+
+
+
+
diff --git a/wallet/res/drawable/ic_shortcut_buy_sell_dash.xml b/wallet/res/drawable/ic_shortcut_buy_sell_dash.xml
index e24232395..c215252df 100644
--- a/wallet/res/drawable/ic_shortcut_buy_sell_dash.xml
+++ b/wallet/res/drawable/ic_shortcut_buy_sell_dash.xml
@@ -1,39 +1,12 @@
+ android:width="24dp"
+ android:height="20dp"
+ android:viewportWidth="24"
+ android:viewportHeight="20">
-
-
-
-
-
-
-
+ android:pathData="M19,0H5C2.24,0 0,2.24 0,5V6H24V5C24,2.24 21.76,0 19,0Z"
+ android:fillColor="#008DE4"/>
-
-
-
-
-
-
-
-
+ android:pathData="M0,15C0,17.76 2.24,20 5,20H19C21.76,20 24,17.76 24,15V8H0V15ZM5,14H8C8.55,14 9,14.45 9,15C9,15.55 8.55,16 8,16H5C4.45,16 4,15.55 4,15C4,14.45 4.45,14 5,14Z"
+ android:fillColor="#008DE4"/>
diff --git a/wallet/res/drawable/ic_shortcut_receive.xml b/wallet/res/drawable/ic_shortcut_receive.xml
deleted file mode 100644
index d618de294..000000000
--- a/wallet/res/drawable/ic_shortcut_receive.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/wallet/res/drawable/ic_shortcut_secure_now.xml b/wallet/res/drawable/ic_shortcut_secure_now.xml
index 1b157dc60..84c82a359 100644
--- a/wallet/res/drawable/ic_shortcut_secure_now.xml
+++ b/wallet/res/drawable/ic_shortcut_secure_now.xml
@@ -1,24 +1,9 @@
+ android:width="37dp"
+ android:height="36dp"
+ android:viewportWidth="37"
+ android:viewportHeight="36">
-
-
-
-
-
-
-
-
+ android:pathData="M18.875,0C8.935,0 0.875,8.06 0.875,18C0.875,27.94 8.935,36 18.875,36C28.815,36 36.875,27.94 36.875,18C36.875,8.06 28.815,0 18.875,0ZM20.725,27.32V28.64C20.725,29.58 19.655,30.12 18.895,29.55L15.705,27.16C14.785,26.47 14.785,25.1 15.705,24.42L18.895,22.02C19.655,21.45 20.725,21.99 20.725,22.93V24.23C23.405,23.43 25.375,20.94 25.375,18C25.375,14.42 22.455,11.5 18.875,11.5C15.295,11.5 12.375,14.42 12.375,18C12.375,18.98 12.595,19.96 13.025,20.84C13.385,21.59 13.075,22.49 12.335,22.85C11.585,23.21 10.695,22.9 10.325,22.16C9.705,20.87 9.375,19.43 9.375,18C9.375,12.76 13.635,8.5 18.875,8.5C24.115,8.5 28.375,12.76 28.375,18C28.375,22.61 25.085,26.45 20.725,27.32Z"
+ android:fillColor="#78C4F5"/>
diff --git a/wallet/res/drawable/ic_shortcut_staking.xml b/wallet/res/drawable/ic_shortcut_staking.xml
new file mode 100644
index 000000000..7d301a979
--- /dev/null
+++ b/wallet/res/drawable/ic_shortcut_staking.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
diff --git a/wallet/res/drawable/ic_where_to_spend.xml b/wallet/res/drawable/ic_where_to_spend.xml
new file mode 100644
index 000000000..8db8eb011
--- /dev/null
+++ b/wallet/res/drawable/ic_where_to_spend.xml
@@ -0,0 +1,12 @@
+
+
+
+
diff --git a/wallet/res/layout/dialog_compose_container.xml b/wallet/res/layout/dialog_compose_container.xml
index 1baa072f8..c3caf4f4a 100644
--- a/wallet/res/layout/dialog_compose_container.xml
+++ b/wallet/res/layout/dialog_compose_container.xml
@@ -14,13 +14,13 @@
android:layout_marginTop="8dp"
tools:background="@color/light_gray" />
-
-
+
+
\ No newline at end of file
diff --git a/wallet/res/layout/home_content.xml b/wallet/res/layout/home_content.xml
index 8f23c79b6..54973581c 100644
--- a/wallet/res/layout/home_content.xml
+++ b/wallet/res/layout/home_content.xml
@@ -127,10 +127,10 @@
-
+
+
+
+
+
+
+
+
+
+
+
مسح
- إرسال
+ إرسال
شراء & بيع
diff --git a/wallet/res/values-bg/strings-extra.xml b/wallet/res/values-bg/strings-extra.xml
index fc6068280..934ae3324 100644
--- a/wallet/res/values-bg/strings-extra.xml
+++ b/wallet/res/values-bg/strings-extra.xml
@@ -24,7 +24,7 @@
Сканирай
- Изпрати
+ Изпрати
Получаване
diff --git a/wallet/res/values-cs/strings-extra.xml b/wallet/res/values-cs/strings-extra.xml
index 5dfaeca41..f8dc455a0 100644
--- a/wallet/res/values-cs/strings-extra.xml
+++ b/wallet/res/values-cs/strings-extra.xml
@@ -29,7 +29,7 @@
Skenovat
- Poslat
+ Poslat
Odeslat kontaktu
diff --git a/wallet/res/values-de/strings-extra.xml b/wallet/res/values-de/strings-extra.xml
index 84278f78a..d3b89f396 100644
--- a/wallet/res/values-de/strings-extra.xml
+++ b/wallet/res/values-de/strings-extra.xml
@@ -33,7 +33,7 @@
Scannen
- Senden
+ Senden
Zu einem Kontakt senden
diff --git a/wallet/res/values-el/strings-extra.xml b/wallet/res/values-el/strings-extra.xml
index c14517c06..5895346d2 100644
--- a/wallet/res/values-el/strings-extra.xml
+++ b/wallet/res/values-el/strings-extra.xml
@@ -33,7 +33,7 @@
Σάρωση
- Αποστολή
+ Αποστολή
Στείλτε στην επαφή
diff --git a/wallet/res/values-es/strings-extra.xml b/wallet/res/values-es/strings-extra.xml
index 3367b2e92..a1e3e18da 100644
--- a/wallet/res/values-es/strings-extra.xml
+++ b/wallet/res/values-es/strings-extra.xml
@@ -33,7 +33,7 @@
Explorar
- Enviar
+ Enviar
Enviar a contacto
diff --git a/wallet/res/values-fa/strings-extra.xml b/wallet/res/values-fa/strings-extra.xml
index b03d740c5..eea286d90 100644
--- a/wallet/res/values-fa/strings-extra.xml
+++ b/wallet/res/values-fa/strings-extra.xml
@@ -33,7 +33,7 @@
اسکن
- ارسال
+ ارسال
ارسال برای مخاطب
diff --git a/wallet/res/values-fil/strings-extra.xml b/wallet/res/values-fil/strings-extra.xml
index 6a6a2b78b..85672dc77 100644
--- a/wallet/res/values-fil/strings-extra.xml
+++ b/wallet/res/values-fil/strings-extra.xml
@@ -33,7 +33,7 @@
Scan
- Ipadala
+ Ipadala
Ipadala sa Contact
diff --git a/wallet/res/values-fr/strings-extra.xml b/wallet/res/values-fr/strings-extra.xml
index c01e2dd68..fa54e5667 100644
--- a/wallet/res/values-fr/strings-extra.xml
+++ b/wallet/res/values-fr/strings-extra.xml
@@ -33,7 +33,7 @@
Scanner
- Envoyer
+ Envoyer
Envoyer au contact
diff --git a/wallet/res/values-he/strings.xml b/wallet/res/values-he/strings.xml
index c95978478..27f901d7f 100644
--- a/wallet/res/values-he/strings.xml
+++ b/wallet/res/values-he/strings.xml
@@ -24,9 +24,6 @@
נתקבל
נשלח/נתקבל
נשלח
- לא נתקבלו ביטקוינים עד כה.
- לא נשלחו ביטקוינים עד כה.
- איך להשיג ביטקוין ?\n\nהמר תמורת כסף פיאט,\nמכור סחורות או שירותים או\nהשג על ידי עבודה.
ברכותי, קיבלת את התשלום הראשון! האם כבר <u>גיבית את הארנק</u> כדי להגן מפני אבדן?
נכרו
פנימי
@@ -37,13 +34,6 @@
נהל יישומים
בדוק את הגדרות הזמנים שלך
זמן המכשיר מאחר ב %d דקות. אתה כנראה לא יכול לקבל או לשלוח ביטקוינים בגלל בעיה זהו.\n\nכדאי שתבדוק את הגדרות הזמן ואיזור הזמן שלך.
- גירסה חדשה זמינה!
- גירסה זו מתקנת באגים חשובים, לפרטים גש לדף העדכון בGoogle Play.
- אם אתה לא רואה עדכון, זה כנראה אומר שגרסאת האנדרואיד שלך אינה נתמכת יותר.
- Google Play
- הורדה
- גירסת אנדרויד לא מעודכנת
- יש סיכוי כי מהגרסאות הקרובות של ארנק ביטקוין לא נתמוך במכשירך יותר. במקרים מסוימים יהיה קשה להשתמש במטבעות על המכשיר.\n\nאלא אם אתה יודע מה אתה עושה, מומלץ שתעביר את המטבעות בקרוב.
שלח ביטקוין
אוסף חתימה מ%s…
איסוף חתימה נכשל
diff --git a/wallet/res/values-id/strings-extra.xml b/wallet/res/values-id/strings-extra.xml
index d0690d0a1..2daae3654 100644
--- a/wallet/res/values-id/strings-extra.xml
+++ b/wallet/res/values-id/strings-extra.xml
@@ -33,7 +33,7 @@
Pindai
- Kirim
+ Kirim
Kirim ke Kontak
diff --git a/wallet/res/values-it/strings-extra.xml b/wallet/res/values-it/strings-extra.xml
index ae8a30c2b..ddc9d9d39 100644
--- a/wallet/res/values-it/strings-extra.xml
+++ b/wallet/res/values-it/strings-extra.xml
@@ -33,7 +33,7 @@
Scansiona
- Invia
+ Invia
Invia al Contatto
diff --git a/wallet/res/values-iw/strings.xml b/wallet/res/values-iw/strings.xml
index d22d28cbe..f75c1b84b 100644
--- a/wallet/res/values-iw/strings.xml
+++ b/wallet/res/values-iw/strings.xml
@@ -23,9 +23,6 @@
נתקבל
נשלח/נתקבל
נשלח
- לא נתקבלו ביטקוינים עד כה.
- לא נשלחו ביטקוינים עד כה.
- איך להשיג ביטקוין ?\n\nהמר תמורת כסף פיאט,\nמכור סחורות או שירותים או\nהשג על ידי עבודה.
ברכותי, קיבלת את התשלום הראשון! האם כבר <u>גיבית את הארנק</u> כדי להגן מפני אבדן?
נכרו
פנימי
@@ -35,13 +32,6 @@
נהל יישומים
בדוק את הגדרות הזמנים שלך
זמן המכשיר מאחר ב %d דקות. אתה כנראה לא יכול לקבל או לשלוח ביטקוינים בגלל בעיה זהו.\n\nכדאי שתבדוק את הגדרות הזמן ואיזור הזמן שלך.
- גירסה חדשה זמינה!
- גירסה זו מתקנת באגים חשובים, לפרטים גש לדף העדכון בGoogle Play.
- אם אתה לא רואה עדכון, זה כנראה אומר שגרסאת האנדרואיד שלך אינה נתמכת יותר.
- Google Play
- הורדה
- גירסת אנדרויד לא מעודכנת
- יש סיכוי כי מהגרסאות הקרובות של ארנק ביטקוין לא נתמוך במכשירך יותר. במקרים מסוימים יהיה קשה להשתמש במטבעות על המכשיר.\n\nאלא אם אתה יודע מה אתה עושה, מומלץ שתעביר את המטבעות בקרוב.
שלח ביטקוין
אוסף חתימה מ%s…
איסוף חתימה נכשל
diff --git a/wallet/res/values-ja/strings-extra.xml b/wallet/res/values-ja/strings-extra.xml
index 61f3610b3..92783ba39 100644
--- a/wallet/res/values-ja/strings-extra.xml
+++ b/wallet/res/values-ja/strings-extra.xml
@@ -33,7 +33,7 @@
スキャン
- 送金する
+ 送金する
連絡先に送金する
diff --git a/wallet/res/values-ko/strings-extra.xml b/wallet/res/values-ko/strings-extra.xml
index 2b31b5385..f98c31a43 100644
--- a/wallet/res/values-ko/strings-extra.xml
+++ b/wallet/res/values-ko/strings-extra.xml
@@ -33,7 +33,7 @@
스캔
- 보내기
+ 보내기
연락처에 전송하기
diff --git a/wallet/res/values-nl/strings-extra.xml b/wallet/res/values-nl/strings-extra.xml
index f31ea04a9..7c9794f81 100644
--- a/wallet/res/values-nl/strings-extra.xml
+++ b/wallet/res/values-nl/strings-extra.xml
@@ -33,7 +33,7 @@
Zoeken
- Verzenden
+ Verzenden
Stuur naar contact
diff --git a/wallet/res/values-pl/strings-extra.xml b/wallet/res/values-pl/strings-extra.xml
index ec68c66e7..8eb486f7d 100644
--- a/wallet/res/values-pl/strings-extra.xml
+++ b/wallet/res/values-pl/strings-extra.xml
@@ -33,7 +33,7 @@
Zeskanuj
- Wyślij
+ Wyślij
Wyślij do Kontaktu
diff --git a/wallet/res/values-pt/strings-extra.xml b/wallet/res/values-pt/strings-extra.xml
index 203116411..db5ed25cb 100644
--- a/wallet/res/values-pt/strings-extra.xml
+++ b/wallet/res/values-pt/strings-extra.xml
@@ -33,7 +33,7 @@
Escanear
- Enviar
+ Enviar
Enviar para contato
diff --git a/wallet/res/values-ro/strings-extra.xml b/wallet/res/values-ro/strings-extra.xml
index 25f76c294..58611f049 100644
--- a/wallet/res/values-ro/strings-extra.xml
+++ b/wallet/res/values-ro/strings-extra.xml
@@ -8,7 +8,7 @@
Scanează
- Trimite
+ Trimite
Importă Cheia Privată
diff --git a/wallet/res/values-ru/strings-extra.xml b/wallet/res/values-ru/strings-extra.xml
index 5d8bce413..4359db69e 100644
--- a/wallet/res/values-ru/strings-extra.xml
+++ b/wallet/res/values-ru/strings-extra.xml
@@ -33,7 +33,7 @@
Скан.
- Отправить
+ Отправить
Отправить человеку в списке контактов
@@ -450,7 +450,7 @@
Ключи голосования
Ключи оператора
Ключи идентификаторов Evolution нод
- ключи
+ %d ключей
%d использовано
Ключи %d
Адрес
diff --git a/wallet/res/values-sk/strings-extra.xml b/wallet/res/values-sk/strings-extra.xml
index 29666624a..aa6c4ec14 100644
--- a/wallet/res/values-sk/strings-extra.xml
+++ b/wallet/res/values-sk/strings-extra.xml
@@ -33,7 +33,7 @@
Skenovať
- Poslať
+ Poslať
Poslať kontaktu
diff --git a/wallet/res/values-sr/strings-extra.xml b/wallet/res/values-sr/strings-extra.xml
index 13ce66442..aad7315df 100644
--- a/wallet/res/values-sr/strings-extra.xml
+++ b/wallet/res/values-sr/strings-extra.xml
@@ -8,7 +8,7 @@
Skeniraj
- Pošalji
+ Pošalji
Uvezi privatni ključ
diff --git a/wallet/res/values-sw/strings.xml b/wallet/res/values-sw/strings.xml
index b33d4b7fc..9335b76ab 100644
--- a/wallet/res/values-sw/strings.xml
+++ b/wallet/res/values-sw/strings.xml
@@ -25,9 +25,6 @@
Kupokea
Wote
Alimtuma
- Hakuna Dash kupokea hivyo mbali
- Hakuna Dash kutumwa hivyo mbali
- Jinsi ya bamba Dash? Nunua na pesa ya kawaida, na biashara, na kazi.
Pongezi budha! Wewe kupokea pesa yako ya kwanza! Lazima kubamba backup, Huna wanataka kupata kuiba.
kupatikana
ndani
@@ -40,13 +37,6 @@
Kudhibiti programu
Cheki wazingira wakati yako!
Simu yako wakati ni makosa %d minuti. Pengine hawezi kutuma Dash kwa sababu ya tatizo hili. Angalia mipangilio yako majira ya saa.
- Toleo jipya ni hapa kwa shusha!
- Hii toleo kunasa makosa makubwa. Kwa maelezo, kuona changelog juu ya Google Play.
- Kama huwezi kupata toleo jipya, Android yako ni mzee, sana!
- Google Play
- Shusha
- Android yako ni mzee, sana!
- Matoleo ya pili ya pochi hii si msaada Android yako yoyote zaidi. Katika baadhi ya matukio, matumizi ya pesa itakuwa vigumu. Kama wewe ni uhakika, tafadhali kuchukua pesa yako hivi karibuni.
Kutuma Dash
Kupata sahihi ya %s…
Kupata sahihi alishindwa.
diff --git a/wallet/res/values-th/strings-extra.xml b/wallet/res/values-th/strings-extra.xml
index 44fb4ceb9..6ea91912d 100644
--- a/wallet/res/values-th/strings-extra.xml
+++ b/wallet/res/values-th/strings-extra.xml
@@ -31,7 +31,7 @@
สแกน
- ส่ง
+ ส่ง
ส่งไปยังผู้ติดต่อ
diff --git a/wallet/res/values-tr/strings-extra.xml b/wallet/res/values-tr/strings-extra.xml
index 84fd073bc..c98a79cf7 100644
--- a/wallet/res/values-tr/strings-extra.xml
+++ b/wallet/res/values-tr/strings-extra.xml
@@ -31,7 +31,7 @@
Tara
- Gönder
+ Gönder
Kişiye Gönder
diff --git a/wallet/res/values-uk/strings-extra.xml b/wallet/res/values-uk/strings-extra.xml
index 749e6facb..c795f3736 100644
--- a/wallet/res/values-uk/strings-extra.xml
+++ b/wallet/res/values-uk/strings-extra.xml
@@ -33,7 +33,7 @@
Сканувати
- Відправити
+ Відправити
Надіслати контакту
diff --git a/wallet/res/values-vi/strings-extra.xml b/wallet/res/values-vi/strings-extra.xml
index 5cd2514bb..692f8b045 100644
--- a/wallet/res/values-vi/strings-extra.xml
+++ b/wallet/res/values-vi/strings-extra.xml
@@ -25,7 +25,7 @@
Quét
- Gửi
+ Gửi
Nhận
diff --git a/wallet/res/values-zh-rTW/strings-extra.xml b/wallet/res/values-zh-rTW/strings-extra.xml
index b38e0d324..ba2931928 100644
--- a/wallet/res/values-zh-rTW/strings-extra.xml
+++ b/wallet/res/values-zh-rTW/strings-extra.xml
@@ -33,7 +33,7 @@
掃描
- 付款
+ 付款
發送給聯繫人
diff --git a/wallet/res/values-zh/strings-extra.xml b/wallet/res/values-zh/strings-extra.xml
index ac1412e16..07acc5b70 100644
--- a/wallet/res/values-zh/strings-extra.xml
+++ b/wallet/res/values-zh/strings-extra.xml
@@ -33,7 +33,7 @@
扫描
- 发送
+ 发送
发送给联系人
diff --git a/wallet/res/values/strings-extra.xml b/wallet/res/values/strings-extra.xml
index ada20a60f..febe4bcc1 100644
--- a/wallet/res/values/strings-extra.xml
+++ b/wallet/res/values/strings-extra.xml
@@ -31,9 +31,9 @@
Backup
- Scan
+ Scan QR
- Send
+ Send
Send to Contact
@@ -42,8 +42,6 @@
Receive
Import Private Key
-
- Add Shortcut
Quick Receive
@@ -219,7 +217,7 @@
Dash Core Group does NOT store this recovery phrase
Anyone that has your recovery phrase can access your funds.
You will NOT be able to restore the wallet without a recovery phrase
- Write it in a safe place and don’t show it to anyone.
+ Write it in a safe place and don\'t show it to anyone.
Please tap on the words from your recovery phrase in the right order
Verified Successfully
Your wallet is secured now. You can use your recovery phrase anytime to recover your account on another device.
diff --git a/wallet/res/values/strings.xml b/wallet/res/values/strings.xml
index 70391ebef..f5cf6eee7 100644
--- a/wallet/res/values/strings.xml
+++ b/wallet/res/values/strings.xml
@@ -420,4 +420,7 @@
Update profile information
Select block explorer
+
+
+ Select option
diff --git a/wallet/schnapps/res/values/values.xml b/wallet/schnapps/res/values/values.xml
index d891f0709..0a4337be5 100644
--- a/wallet/schnapps/res/values/values.xml
+++ b/wallet/schnapps/res/values/values.xml
@@ -20,8 +20,10 @@
- https://insight.ouzo.networks.dash.org:3002/insight
+ - https://blockchair.com/dash/
- Insight
+ - Blockchair
\ No newline at end of file
diff --git a/wallet/src/de/schildbach/wallet/di/AppModule.kt b/wallet/src/de/schildbach/wallet/di/AppModule.kt
index fb2690f28..de695f9d6 100644
--- a/wallet/src/de/schildbach/wallet/di/AppModule.kt
+++ b/wallet/src/de/schildbach/wallet/di/AppModule.kt
@@ -95,7 +95,7 @@ abstract class AppModule {
@Provides
fun provideDeviceInfo(@ApplicationContext context: Context): DeviceInfoProvider =
- DeviceInfoProvider(context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager)
+ DeviceInfoProvider(context.resources, context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager)
@Singleton
@Provides
diff --git a/wallet/src/de/schildbach/wallet/service/DeviceInfoProvider.kt b/wallet/src/de/schildbach/wallet/service/DeviceInfoProvider.kt
index 0d30e3bb4..535fbbf0f 100644
--- a/wallet/src/de/schildbach/wallet/service/DeviceInfoProvider.kt
+++ b/wallet/src/de/schildbach/wallet/service/DeviceInfoProvider.kt
@@ -1,15 +1,21 @@
package de.schildbach.wallet.service
+import android.content.res.Resources
import android.telephony.TelephonyManager
+import android.util.DisplayMetrics
import org.slf4j.LoggerFactory
class DeviceInfoProvider(
+ private val resources: Resources,
private val telephonyManager: TelephonyManager
) {
companion object {
private val log = LoggerFactory.getLogger(DeviceInfoProvider::class.java)
}
+ val isSmallScreen: Boolean
+ get() = resources.displayMetrics.densityDpi <= DisplayMetrics.DENSITY_MEDIUM
+
/**
* Get ISO 3166-1 alpha-2 country code for this device (or null if not available)
* If available, call [.showFiatCurrencyChangeDetectedDialog]
diff --git a/wallet/src/de/schildbach/wallet/transactions/WalletBalanceObserver.kt b/wallet/src/de/schildbach/wallet/transactions/WalletBalanceObserver.kt
index 875e0c892..1e74d22c0 100644
--- a/wallet/src/de/schildbach/wallet/transactions/WalletBalanceObserver.kt
+++ b/wallet/src/de/schildbach/wallet/transactions/WalletBalanceObserver.kt
@@ -18,7 +18,6 @@
package de.schildbach.wallet.transactions
import de.schildbach.wallet.Constants
-import de.schildbach.wallet.data.CoinJoinConfig
import de.schildbach.wallet.service.CoinJoinMode
import de.schildbach.wallet.service.CoinJoinService
import de.schildbach.wallet.util.ThrottlingWalletChangeListener
@@ -41,7 +40,6 @@ import org.bitcoinj.wallet.Wallet.BalanceType
import org.dash.wallet.common.data.WalletUIConfig
import org.slf4j.LoggerFactory
-
class WalletBalanceObserver(
private val wallet: Wallet,
private val walletUIConfig: WalletUIConfig
diff --git a/wallet/src/de/schildbach/wallet/ui/compose_views/ComposeBottomSheet.kt b/wallet/src/de/schildbach/wallet/ui/compose_views/ComposeBottomSheet.kt
index 54f33a6b4..fb5b7342e 100644
--- a/wallet/src/de/schildbach/wallet/ui/compose_views/ComposeBottomSheet.kt
+++ b/wallet/src/de/schildbach/wallet/ui/compose_views/ComposeBottomSheet.kt
@@ -11,6 +11,7 @@ import org.dash.wallet.common.ui.viewBinding
class ComposeBottomSheet(
override val backgroundStyle: Int = R.style.SecondaryBackground,
+ override val forceExpand: Boolean = false,
private val content: @Composable (DialogFragment) -> Unit
) : OffsetDialogFragment(R.layout.dialog_compose_container) {
private val binding by viewBinding(DialogComposeContainerBinding::bind)
diff --git a/wallet/src/de/schildbach/wallet/ui/dashpay/FrequentContactViewHolder.kt b/wallet/src/de/schildbach/wallet/ui/dashpay/FrequentContactViewHolder.kt
index 36269a6d2..6e9e2d050 100644
--- a/wallet/src/de/schildbach/wallet/ui/dashpay/FrequentContactViewHolder.kt
+++ b/wallet/src/de/schildbach/wallet/ui/dashpay/FrequentContactViewHolder.kt
@@ -15,12 +15,9 @@
*/
package de.schildbach.wallet.ui.dashpay
-import android.view.LayoutInflater
-import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import de.schildbach.wallet.data.UsernameSearchResult
import de.schildbach.wallet.ui.dashpay.utils.display
-import de.schildbach.wallet_test.R
import de.schildbach.wallet_test.databinding.FrequentContactItemBinding
import org.dash.wallet.common.ui.avatar.ProfilePictureDisplay
diff --git a/wallet/src/de/schildbach/wallet/ui/main/MainViewModel.kt b/wallet/src/de/schildbach/wallet/ui/main/MainViewModel.kt
index 3cba30179..ee560750c 100644
--- a/wallet/src/de/schildbach/wallet/ui/main/MainViewModel.kt
+++ b/wallet/src/de/schildbach/wallet/ui/main/MainViewModel.kt
@@ -228,9 +228,6 @@ class MainViewModel @Inject constructor(
val isNetworkUnavailable: LiveData
get() = _isNetworkUnavailable
- val isPassphraseVerified: Boolean
- get() = !config.remindBackupSeed
-
val currencyChangeDetected = SingleLiveEvent>()
// CoinJoin
@@ -345,11 +342,15 @@ class MainViewModel @Inject constructor(
// we need the total wallet balance for mixing progress,
walletData.observeTotalBalance()
- .onEach(_totalBalance::postValue)
+ .onEach {
+ _totalBalance.value = it
+ }
.launchIn(viewModelScope)
walletData.observeMixedBalance()
- .onEach(_mixedBalance::postValue)
+ .onEach {
+ _mixedBalance.value = it
+ }
.launchIn(viewModelScope)
walletData.observeMostRecentTransaction()
diff --git a/wallet/src/de/schildbach/wallet/ui/main/WalletFragment.kt b/wallet/src/de/schildbach/wallet/ui/main/WalletFragment.kt
index a6f74958c..ab2ffb610 100644
--- a/wallet/src/de/schildbach/wallet/ui/main/WalletFragment.kt
+++ b/wallet/src/de/schildbach/wallet/ui/main/WalletFragment.kt
@@ -23,12 +23,15 @@ import android.content.Intent
import android.os.Bundle
import android.view.View
import androidx.activity.result.contract.ActivityResultContracts
+import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.os.bundleOf
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
+import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavOptions
+import androidx.navigation.NavOptions.*
import androidx.navigation.fragment.findNavController
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.appbar.AppBarLayout.Behavior.DragCallback
@@ -38,6 +41,7 @@ import de.schildbach.wallet.data.PaymentIntent
import de.schildbach.wallet.service.CoinJoinMode
import de.schildbach.wallet.service.MixingStatus
import de.schildbach.wallet.ui.*
+import de.schildbach.wallet.ui.compose_views.ComposeBottomSheet
import de.schildbach.wallet.ui.util.InputParser.StringInputParser
import de.schildbach.wallet.ui.dashpay.ContactsScreenMode
import de.schildbach.wallet.ui.dashpay.NotificationsFragment
@@ -46,6 +50,11 @@ import de.schildbach.wallet.ui.payments.PaymentsFragment
import de.schildbach.wallet.ui.payments.SweepWalletActivity
import de.schildbach.wallet.ui.scan.ScanActivity
import de.schildbach.wallet.ui.send.SendCoinsActivity
+import de.schildbach.wallet.ui.main.shortcuts.ShortcutOption
+import de.schildbach.wallet.ui.main.shortcuts.ShortcutsViewModel
+import de.schildbach.wallet.ui.main.shortcuts.ShortcutsList
+import de.schildbach.wallet.ui.main.shortcuts.ShortcutsPane
+import de.schildbach.wallet.ui.staking.StakingActivity
import de.schildbach.wallet.ui.transactions.TaxCategoryExplainerDialogFragment
import de.schildbach.wallet.ui.transactions.TransactionDetailsDialogFragment
import de.schildbach.wallet.ui.verify.VerifySeedActivity
@@ -64,10 +73,15 @@ import org.dash.wallet.common.services.analytics.AnalyticsConstants
import org.dash.wallet.common.ui.avatar.ProfilePictureDisplay
import org.dash.wallet.common.ui.dialogs.AdaptiveDialog
import org.dash.wallet.common.ui.viewBinding
+import org.dash.wallet.common.util.Constants
import org.dash.wallet.common.util.observe
import org.dash.wallet.common.util.safeNavigate
+import org.dash.wallet.features.exploredash.ui.explore.ExploreTopic
import org.slf4j.LoggerFactory
import javax.inject.Inject
+import androidx.core.net.toUri
+import de.schildbach.wallet.data.ServiceType
+import org.dash.wallet.common.util.openCustomTab
@AndroidEntryPoint
class WalletFragment : Fragment(R.layout.home_content) {
@@ -77,6 +91,7 @@ class WalletFragment : Fragment(R.layout.home_content) {
}
private val viewModel: MainViewModel by activityViewModels()
+ private val shortcutViewModel: ShortcutsViewModel by viewModels()
private val binding by viewBinding(HomeContentBinding::bind)
private lateinit var mixingBinding: MixingStatusPaneBinding
@Inject lateinit var configuration: Configuration
@@ -93,6 +108,14 @@ class WalletFragment : Fragment(R.layout.home_content) {
}
}
+ private val stakingLauncher = registerForActivityResult(
+ ActivityResultContracts.StartActivityForResult()
+ ) { result ->
+ if (result.resultCode == Constants.USER_BUY_SELL_DASH) {
+ safeNavigate(WalletFragmentDirections.homeToBuySell())
+ }
+ }
+
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
@@ -211,6 +234,8 @@ class WalletFragment : Fragment(R.layout.home_content) {
viewModel.totalBalance.observe(viewLifecycleOwner) {
updateMixedAndTotalBalance()
+ val balance: Coin = viewModel.totalBalance.value ?: Coin.ZERO
+ shortcutViewModel.userHasBalance = balance.isPositive
}
viewModel.mixedBalance.observe(viewLifecycleOwner) {
@@ -243,75 +268,32 @@ class WalletFragment : Fragment(R.layout.home_content) {
override fun onResume() {
super.onResume()
- showHideSecureAction()
+ shortcutViewModel.refreshIsPassphraseVerified()
}
private fun initShortcutActions() {
- binding.shortcutsPane.setOnShortcutClickListener { v ->
- when (v) {
- binding.shortcutsPane.secureNowButton -> {
- viewModel.logEvent(AnalyticsConstants.Home.SHORTCUT_SECURE_WALLET)
- handleVerifySeed()
- }
- binding.shortcutsPane.scanToPayButton -> {
- viewModel.logEvent(AnalyticsConstants.Home.SHORTCUT_SCAN_TO_PAY)
- handleScan(v)
- }
- binding.shortcutsPane.buySellButton -> {
- viewModel.logEvent(AnalyticsConstants.Home.SHORTCUT_BUY_AND_SELL)
- safeNavigate(WalletFragmentDirections.homeToBuySell())
- }
- binding.shortcutsPane.payToAddressButton -> {
- handlePayToAddress()
- }
- binding.shortcutsPane.payToContactButton -> {
- handleSelectContact()
- }
- binding.shortcutsPane.receiveButton -> {
- viewModel.logEvent(AnalyticsConstants.Home.SHORTCUT_RECEIVE)
- findNavController().navigate(
- R.id.paymentsFragment,
- bundleOf(
- PaymentsFragment.ARG_ACTIVE_TAB to PaymentsFragment.ACTIVE_TAB_RECEIVE
- )
- )
- }
- binding.shortcutsPane.importPrivateKey -> {
- SweepWalletActivity.start(requireContext(), true)
- }
- binding.shortcutsPane.explore -> {
- viewModel.logEvent(AnalyticsConstants.Home.SHORTCUT_EXPLORE)
- findNavController().navigate(
- R.id.exploreFragment,
- bundleOf(),
- NavOptions.Builder()
- .setEnterAnim(R.anim.slide_in_bottom)
- .build()
- )
+ binding.shortcutsPane.setViewCompositionStrategy(
+ ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed
+ )
+
+ binding.shortcutsPane.setContent {
+ ShortcutsPane(
+ shortcuts = shortcutViewModel.shortcuts,
+ onClick = { shortcut ->
+ onShortcutTap(shortcut)
+ },
+ onLongClick = { shortcut, index ->
+ onShortcutLongTap(shortcut, index)
}
- }
+ )
}
refreshShortcutBar()
}
private fun refreshShortcutBar() {
- showHideSecureAction()
- refreshIfUserHasBalance()
- refreshIfUserHasIdentity()
- }
-
- private fun showHideSecureAction() {
- binding.shortcutsPane.isPassphraseVerified = viewModel.isPassphraseVerified
- }
-
- private fun refreshIfUserHasBalance() {
- val balance: Coin = viewModel.totalBalance.value ?: Coin.ZERO
- binding.shortcutsPane.userHasBalance = balance.isPositive
- }
-
- private fun refreshIfUserHasIdentity() {
- binding.shortcutsPane.userHasContacts = viewModel.hasIdentity && viewModel.hasContacts.value
+ shortcutViewModel.refreshIsPassphraseVerified()
+ shortcutViewModel.userHasContacts = viewModel.hasIdentity && viewModel.hasContacts.value
}
private fun updateSyncState() {
@@ -337,15 +319,9 @@ class WalletFragment : Fragment(R.layout.home_content) {
}
}
- private fun handleScan(clickView: View?) {
- if (clickView != null) {
- val options = ScanActivity.getLaunchOptions(activity, clickView)
- val intent = ScanActivity.getTransitionIntent(activity, clickView)
- scanLauncher.launch(intent, options)
- } else {
- val intent = ScanActivity.getIntent(activity)
- scanLauncher.launch(intent)
- }
+ private fun handleScan() {
+ val intent = ScanActivity.getIntent(activity)
+ scanLauncher.launch(intent)
}
private fun startVerifySeedActivity(pin: String) {
@@ -416,4 +392,114 @@ class WalletFragment : Fragment(R.layout.home_content) {
}
)
}
+
+ private fun onShortcutTap(shortcut: ShortcutOption) {
+ when (shortcut) {
+ ShortcutOption.SECURE_NOW -> {
+ viewModel.logEvent(AnalyticsConstants.Home.SHORTCUT_SECURE_WALLET)
+ handleVerifySeed()
+ }
+ ShortcutOption.SCAN_QR -> {
+ viewModel.logEvent(AnalyticsConstants.Home.SHORTCUT_SCAN_TO_PAY)
+ handleScan()
+ }
+ ShortcutOption.BUY_SELL -> {
+ viewModel.logEvent(AnalyticsConstants.Home.SHORTCUT_BUY_AND_SELL)
+ safeNavigate(WalletFragmentDirections.homeToBuySell())
+ }
+ ShortcutOption.SEND_TO_ADDRESS -> {
+ handlePayToAddress()
+ }
+ ShortcutOption.SEND_TO_CONTACT -> {
+ handleSelectContact()
+ }
+ ShortcutOption.SEND -> {
+ viewModel.logEvent(AnalyticsConstants.Home.SHORTCUT_SEND)
+ findNavController().navigate(
+ R.id.paymentsFragment,
+ bundleOf(
+ PaymentsFragment.ARG_ACTIVE_TAB to PaymentsFragment.ACTIVE_TAB_PAY
+ )
+ )
+ }
+ ShortcutOption.RECEIVE -> {
+ viewModel.logEvent(AnalyticsConstants.Home.SHORTCUT_RECEIVE)
+ findNavController().navigate(
+ R.id.paymentsFragment,
+ bundleOf(
+ PaymentsFragment.ARG_ACTIVE_TAB to PaymentsFragment.ACTIVE_TAB_RECEIVE
+ )
+ )
+ }
+ ShortcutOption.EXPLORE -> {
+ viewModel.logEvent(AnalyticsConstants.Home.SHORTCUT_EXPLORE)
+ findNavController().navigate(
+ R.id.exploreFragment,
+ bundleOf(),
+ Builder()
+ .setEnterAnim(R.anim.slide_in_bottom)
+ .build()
+ )
+ }
+ ShortcutOption.WHERE_TO_SPEND -> {
+ safeNavigate(WalletFragmentDirections.homeToSearch(type = ExploreTopic.Merchants))
+ }
+ ShortcutOption.ATMS -> {
+ safeNavigate(WalletFragmentDirections.homeToSearch(type = ExploreTopic.ATMs))
+ }
+ ShortcutOption.STAKING -> {
+ handleStakingNavigation()
+ }
+ ShortcutOption.TOPPER -> {
+ lifecycleScope.launch {
+ val uri = shortcutViewModel.getTopperUrl(getString(R.string.dash_wallet_name))
+ requireActivity().openCustomTab(uri)
+ }
+ }
+ ShortcutOption.UPHOLD -> {
+ safeNavigate(WalletFragmentDirections.homeToUphold())
+ }
+ ShortcutOption.COINBASE -> {
+ if (shortcutViewModel.isCoinbaseAuthenticated) {
+ safeNavigate(WalletFragmentDirections.homeToCoinbase())
+ } else {
+ safeNavigate(WalletFragmentDirections.homeToBuySellOverview(ServiceType.COINBASE))
+ }
+ }
+ }
+ }
+
+ private fun onShortcutLongTap(shortcut: ShortcutOption, index: Int) {
+ if (shortcut == ShortcutOption.SECURE_NOW) {
+ return
+ }
+
+ ComposeBottomSheet(R.style.SecondaryBackground, forceExpand = true) { dialog ->
+ ShortcutsList(shortcutViewModel.getAllShortcutOptions(shortcut)) { newShortcut ->
+ shortcutViewModel.replaceShortcut(index, newShortcut)
+ dialog.dismiss()
+ }
+ }.show(requireActivity())
+ }
+
+ private fun handleStakingNavigation() {
+ lifecycleScope.launch {
+ if (viewModel.isBlockchainSynced.value == true) {
+ stakingLauncher.launch(Intent(requireContext(), StakingActivity::class.java))
+ } else {
+ val openWebsite = AdaptiveDialog.create(
+ null,
+ getString(R.string.chain_syncing),
+ getString(R.string.crowdnode_wait_for_sync),
+ getString(R.string.button_close),
+ getString(R.string.crowdnode_open_website)
+ ).showAsync(requireActivity())
+
+ if (openWebsite == true) {
+ val browserIntent = Intent(Intent.ACTION_VIEW, getString(R.string.crowdnode_website).toUri())
+ startActivity(browserIntent)
+ }
+ }
+ }
+ }
}
diff --git a/wallet/src/de/schildbach/wallet/ui/main/shortcuts/Shortcut.kt b/wallet/src/de/schildbach/wallet/ui/main/shortcuts/Shortcut.kt
new file mode 100644
index 000000000..c3ae52932
--- /dev/null
+++ b/wallet/src/de/schildbach/wallet/ui/main/shortcuts/Shortcut.kt
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2025 Dash Core Group.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package de.schildbach.wallet.ui.main.shortcuts
+
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import org.dash.wallet.common.ui.components.MyTheme
+
+@Composable
+fun Shortcut(
+ shortcutOption: ShortcutOption,
+ modifier: Modifier = Modifier
+) {
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally,
+ verticalArrangement = Arrangement.Top,
+ modifier = modifier
+ ) {
+ Image(
+ painter = painterResource(id = shortcutOption.iconResId),
+ contentDescription = stringResource(id = shortcutOption.textResId),
+ modifier = Modifier
+ .size(42.dp)
+ .padding(6.dp)
+ )
+
+ Text(
+ text = stringResource(id = shortcutOption.textResId),
+ style = MyTheme.Overline,
+ color = MyTheme.Colors.textPrimary,
+ textAlign = TextAlign.Center,
+ modifier = Modifier
+ .padding(top = 4.dp, bottom = 6.dp)
+ )
+ }
+}
+
+@Preview(showBackground = true)
+@Composable
+fun PreviewShortcutPaneItem() {
+ Shortcut(
+ shortcutOption = ShortcutOption.RECEIVE
+ )
+}
\ No newline at end of file
diff --git a/wallet/src/de/schildbach/wallet/ui/main/shortcuts/ShortcutListItem.kt b/wallet/src/de/schildbach/wallet/ui/main/shortcuts/ShortcutListItem.kt
new file mode 100644
index 000000000..7b6f44519
--- /dev/null
+++ b/wallet/src/de/schildbach/wallet/ui/main/shortcuts/ShortcutListItem.kt
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2025 Dash Core Group.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package de.schildbach.wallet.ui.main.shortcuts
+
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import org.dash.wallet.common.ui.components.MyTheme
+
+@Composable
+fun ShortcutListItem(
+ shortcutOption: ShortcutOption,
+ onClick: (ShortcutOption) -> Unit
+) {
+ Row(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(horizontal = 10.dp, vertical = 2.dp)
+ .clip(RoundedCornerShape(8.dp))
+ .background(MyTheme.Colors.backgroundSecondary)
+ .clickable { onClick(shortcutOption) }
+ .padding(horizontal = 10.dp, vertical = 12.dp),
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Box(
+ modifier = Modifier
+ .size(26.dp),
+ contentAlignment = Alignment.Center
+ ) {
+ Image(
+ painter = painterResource(id = shortcutOption.iconResId),
+ contentDescription = stringResource(id = shortcutOption.textResId),
+ modifier = Modifier.size(24.dp)
+ )
+ }
+
+ Text(
+ text = stringResource(id = shortcutOption.textResId),
+ style = MyTheme.Body2Regular,
+ color = MyTheme.Colors.textPrimary,
+ modifier = Modifier
+ .weight(1f)
+ .padding(start = 16.dp)
+ )
+ }
+}
+
+@Preview(showBackground = true)
+@Composable
+fun PreviewShortcutListItem() {
+ ShortcutListItem(
+ shortcutOption = ShortcutOption.RECEIVE,
+ onClick = {}
+ )
+}
\ No newline at end of file
diff --git a/wallet/src/de/schildbach/wallet/ui/main/shortcuts/ShortcutOption.kt b/wallet/src/de/schildbach/wallet/ui/main/shortcuts/ShortcutOption.kt
new file mode 100644
index 000000000..da422cd86
--- /dev/null
+++ b/wallet/src/de/schildbach/wallet/ui/main/shortcuts/ShortcutOption.kt
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2025 Dash Core Group.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package de.schildbach.wallet.ui.main.shortcuts
+
+import androidx.annotation.DrawableRes
+import androidx.annotation.StringRes
+import de.schildbach.wallet_test.R
+
+// Sorted by display priority. Do not change IDs if moving options around
+enum class ShortcutOption(
+ val id: Int,
+ @DrawableRes val iconResId: Int,
+ @StringRes val textResId: Int
+) {
+ SECURE_NOW(
+ 0,
+ R.drawable.ic_shortcut_secure_now,
+ R.string.shortcut_secure_now
+ ),
+ EXPLORE(
+ 1,
+ R.drawable.ic_explore,
+ R.string.menu_explore_title
+ ),
+ RECEIVE(
+ 2,
+ R.drawable.ic_transaction_received,
+ R.string.shortcut_receive
+ ),
+ SEND(
+ 3,
+ R.drawable.ic_transaction_sent,
+ R.string.shortcut_send
+ ),
+ SCAN_QR(
+ 4,
+ R.drawable.ic_qr,
+ R.string.shortcut_scan_to_pay
+ ),
+ SEND_TO_ADDRESS(
+ 5,
+ R.drawable.ic_send_to_address,
+ R.string.send_to_address
+ ),
+ SEND_TO_CONTACT(
+ 6,
+ R.drawable.ic_contact,
+ R.string.shortcut_pay_to_contact
+ ),
+ BUY_SELL(
+ 7,
+ R.drawable.ic_shortcut_buy_sell_dash,
+ R.string.shortcut_buy_sell
+ ),
+ WHERE_TO_SPEND(
+ 8,
+ R.drawable.ic_where_to_spend,
+ R.string.explore_where_to_spend
+ ),
+ ATMS(
+ 9,
+ R.drawable.ic_shortcut_atm,
+ R.string.explore_atms
+ ),
+ STAKING(
+ 10,
+ R.drawable.ic_shortcut_staking,
+ R.string.staking_title
+ ),
+ TOPPER(
+ 11,
+ R.drawable.logo_topper,
+ R.string.topper
+ ),
+ UPHOLD(
+ 12,
+ R.drawable.ic_uphold,
+ R.string.uphold_account
+ ),
+ COINBASE(
+ 13,
+ R.drawable.ic_coinbase,
+ R.string.coinbase
+ );
+
+ companion object {
+ fun fromId(id: Int): ShortcutOption {
+ return entries.first { it.id == id }
+ }
+ }
+}
\ No newline at end of file
diff --git a/wallet/src/de/schildbach/wallet/ui/main/shortcuts/ShortcutProvider.kt b/wallet/src/de/schildbach/wallet/ui/main/shortcuts/ShortcutProvider.kt
new file mode 100644
index 000000000..3dcb38112
--- /dev/null
+++ b/wallet/src/de/schildbach/wallet/ui/main/shortcuts/ShortcutProvider.kt
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2025 Dash Core Group.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package de.schildbach.wallet.ui.main.shortcuts
+
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.SupervisorJob
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.filterNotNull
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onEach
+import org.dash.wallet.common.data.WalletUIConfig
+import javax.inject.Inject
+import javax.inject.Singleton
+
+@Singleton
+class ShortcutProvider @Inject constructor(
+ private val config: WalletUIConfig
+) {
+ companion object {
+ private const val MINIMUM_SHORTCUTS = 4
+ }
+
+ private val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
+
+ private val _customShortcuts = MutableStateFlow>(emptyList())
+ val customShortcuts: StateFlow> = _customShortcuts.asStateFlow()
+
+ init {
+ config.observe(WalletUIConfig.CUSTOMIZED_SHORTCUTS)
+ .filterNotNull()
+ .distinctUntilChanged()
+ .map { shortcutSet -> parseCustomShortcuts(shortcutSet) }
+ .onEach { shortcuts ->
+ var finalShortcuts = shortcuts.toMutableList()
+
+ if (finalShortcuts.size < MINIMUM_SHORTCUTS) {
+ val allShortcuts = ShortcutOption.entries
+ allShortcuts
+ .firstOrNull { it != ShortcutOption.SECURE_NOW && it !in finalShortcuts }
+ // Most likely short 1 item due to removal from the start of the list
+ ?.let { finalShortcuts.add(0, it) }
+ setCustomShortcuts(finalShortcuts.map { it.id }.toIntArray()) // This will trigger another pass
+ } else {
+ _customShortcuts.value = finalShortcuts
+ }
+ }
+ .launchIn(scope)
+ }
+
+ // Default logic before the user customizes shortcuts
+ fun getFilteredShortcuts(
+ isPassphraseVerified: Boolean = true,
+ userHasBalance: Boolean = true,
+ userHasContacts: Boolean = false
+ ): List {
+ val shortcuts = ShortcutOption.entries.filter { shortcut ->
+ when (shortcut) {
+ ShortcutOption.SECURE_NOW -> !isPassphraseVerified
+ ShortcutOption.SCAN_QR -> userHasBalance
+ ShortcutOption.SEND -> !userHasBalance && isPassphraseVerified
+ ShortcutOption.BUY_SELL -> !userHasBalance
+ ShortcutOption.SEND_TO_ADDRESS -> userHasBalance
+ ShortcutOption.SEND_TO_CONTACT -> userHasBalance && userHasContacts
+ else -> true
+ }
+ }
+
+ return shortcuts
+ }
+
+ suspend fun setCustomShortcuts(shortcutIds: IntArray) {
+ val shortcutString = shortcutIds.joinToString(",") { it.toString() }
+ config.set(WalletUIConfig.CUSTOMIZED_SHORTCUTS, shortcutString)
+ }
+
+ private fun parseCustomShortcuts(shortcutString: String): List {
+ return shortcutString.split(",").mapNotNull { idStr ->
+ val id = idStr.toIntOrNull() ?: return@mapNotNull null
+ ShortcutOption.fromId(id)
+ }
+ }
+}
\ No newline at end of file
diff --git a/wallet/src/de/schildbach/wallet/ui/main/shortcuts/ShortcutsList.kt b/wallet/src/de/schildbach/wallet/ui/main/shortcuts/ShortcutsList.kt
new file mode 100644
index 000000000..7e3e5df6c
--- /dev/null
+++ b/wallet/src/de/schildbach/wallet/ui/main/shortcuts/ShortcutsList.kt
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2025 Dash Core Group.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package de.schildbach.wallet.ui.main.shortcuts
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.items
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import de.schildbach.wallet_test.R
+import org.dash.wallet.common.ui.components.MyTheme.Colors
+
+/**
+ * A Composable that displays a list of shortcut options.
+ *
+ * @param shortcuts The list of shortcut options to display
+ * @param onClick Callback to execute when a shortcut is clicked
+ */
+@Composable
+fun ShortcutsList(
+ shortcuts: List,
+ onClick: (ShortcutOption) -> Unit
+) {
+ Column {
+ Text(
+ text = stringResource(R.string.select_option),
+ style = MaterialTheme.typography.bodyMedium,
+ fontWeight = FontWeight.SemiBold,
+ color = Colors.textPrimary,
+ textAlign = TextAlign.Center,
+ modifier = Modifier.fillMaxWidth()
+ .padding(top = 28.dp)
+ )
+
+ LazyColumn(
+ modifier = Modifier
+ .fillMaxWidth()
+ .clip(RoundedCornerShape(12.dp))
+ .background(Colors.backgroundSecondary)
+ .padding(top = 12.dp)
+ ) {
+ item {
+ Spacer(modifier = Modifier.height(12.dp))
+ }
+
+ items(shortcuts) { shortcut ->
+ ShortcutListItem(
+ shortcutOption = shortcut,
+ onClick = onClick
+ )
+ }
+ }
+ }
+}
+
+@Preview(showBackground = true)
+@Composable
+fun PreviewShortcutsList() {
+ val shortcuts = ShortcutOption.entries
+
+ ShortcutsList(
+ shortcuts = shortcuts,
+ onClick = {}
+ )
+}
\ No newline at end of file
diff --git a/wallet/src/de/schildbach/wallet/ui/main/shortcuts/ShortcutsPane.kt b/wallet/src/de/schildbach/wallet/ui/main/shortcuts/ShortcutsPane.kt
new file mode 100644
index 000000000..27d1a5390
--- /dev/null
+++ b/wallet/src/de/schildbach/wallet/ui/main/shortcuts/ShortcutsPane.kt
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2025 Dash Core Group.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package de.schildbach.wallet.ui.main.shortcuts
+
+import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.background
+import androidx.compose.foundation.combinedClickable
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.wrapContentHeight
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.ripple.rememberRipple
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.unit.dp
+import org.dash.wallet.common.ui.components.MyTheme.Colors
+
+@OptIn(ExperimentalFoundationApi::class)
+@Composable
+fun ShortcutsPane(
+ shortcuts: List,
+ onClick: (ShortcutOption) -> Unit,
+ onLongClick: (ShortcutOption, Int) -> Unit
+) {
+ Box(
+ modifier = Modifier
+ .fillMaxWidth()
+ .wrapContentHeight(unbounded = true)
+ .clip(RoundedCornerShape(12.dp))
+ .background(Colors.backgroundSecondary)
+ .padding(horizontal = 8.dp, vertical = 4.dp)
+ ) {
+ Row(
+ horizontalArrangement = Arrangement.SpaceEvenly,
+ verticalAlignment = Alignment.Top,
+ modifier = Modifier.fillMaxWidth()
+ ) {
+ val itemWidth = 1f / shortcuts.size
+ shortcuts.forEachIndexed { index, shortcut ->
+ Shortcut(
+ shortcutOption = shortcut,
+ modifier = Modifier
+ .weight(itemWidth)
+ .padding(6.dp)
+ .combinedClickable(
+ interactionSource = remember { MutableInteractionSource() },
+ indication = rememberRipple(color = Colors.textPrimary, bounded = false, radius = 50.dp),
+ onClick = { onClick(shortcut) },
+ onLongClick = { onLongClick(shortcut, index) },
+ )
+ )
+ }
+ }
+ }
+}
diff --git a/wallet/src/de/schildbach/wallet/ui/main/shortcuts/ShortcutsViewModel.kt b/wallet/src/de/schildbach/wallet/ui/main/shortcuts/ShortcutsViewModel.kt
new file mode 100644
index 000000000..1c09c0222
--- /dev/null
+++ b/wallet/src/de/schildbach/wallet/ui/main/shortcuts/ShortcutsViewModel.kt
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2025 Dash Core Group.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package de.schildbach.wallet.ui.main.shortcuts
+
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import dagger.hilt.android.lifecycle.HiltViewModel
+import de.schildbach.wallet.service.DeviceInfoProvider
+import kotlinx.coroutines.flow.filterNot
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.launch
+import org.dash.wallet.common.Configuration
+import org.dash.wallet.common.WalletDataProvider
+import org.dash.wallet.common.data.WalletUIConfig
+import org.dash.wallet.integrations.coinbase.repository.CoinBaseRepositoryInt
+import org.dash.wallet.integrations.uphold.api.TopperClient
+import javax.inject.Inject
+
+@HiltViewModel
+class ShortcutsViewModel @Inject constructor(
+ private val walletUIConfig: WalletUIConfig,
+ private val config: Configuration,
+ private val walletData: WalletDataProvider,
+ private val shortcutProvider: ShortcutProvider,
+ private val deviceInfo: DeviceInfoProvider,
+ private val topperClient: TopperClient,
+ private val coinBaseRepository: CoinBaseRepositoryInt
+): ViewModel() {
+ private val maxShortcuts = if (deviceInfo.isSmallScreen) 3 else 4
+ private var isPassphraseVerified = true
+ private val hasCustomShortcuts: Boolean
+ get() = shortcutProvider.customShortcuts.value.isNotEmpty()
+
+ private var _userHasBalance = true
+ var userHasBalance: Boolean
+ get() = _userHasBalance
+ set(value) {
+ _userHasBalance = value
+
+ if (!hasCustomShortcuts) {
+ shortcuts = getPresetShortcuts().take(maxShortcuts)
+ }
+ }
+
+ private var _userHasContacts = true
+ var userHasContacts: Boolean
+ get() = _userHasContacts
+ set(value) {
+ _userHasContacts = value
+
+ if (!hasCustomShortcuts) {
+ shortcuts = getPresetShortcuts().take(maxShortcuts)
+ }
+ }
+
+ var shortcuts by mutableStateOf(getPresetShortcuts().take(maxShortcuts))
+
+ val isCoinbaseAuthenticated: Boolean
+ get() = coinBaseRepository.isAuthenticated
+
+ init {
+ shortcutProvider.customShortcuts
+ .filterNot { it.isEmpty() }
+ .onEach { shortcuts = it.take(maxShortcuts) }
+ .launchIn(viewModelScope)
+ }
+
+ fun getAllShortcutOptions(replacingShortcut: ShortcutOption): List {
+ return ShortcutOption.entries.filterNot { it == replacingShortcut || it == ShortcutOption.SECURE_NOW }
+ }
+
+ fun refreshIsPassphraseVerified() {
+ isPassphraseVerified = !config.remindBackupSeed
+
+ if (isPassphraseVerified && shortcuts.contains(ShortcutOption.SECURE_NOW)) {
+ if (hasCustomShortcuts) {
+ removeSecureNowShortcut()
+ } else {
+ shortcuts = getPresetShortcuts().take(maxShortcuts)
+ }
+ }
+ }
+
+ fun replaceShortcut(oldIndex: Int, new: ShortcutOption) {
+ if (oldIndex !in shortcuts.indices) {
+ return
+ }
+
+ val currentShortcuts = shortcuts.toMutableList()
+
+ if (currentShortcuts[oldIndex] == ShortcutOption.SECURE_NOW) {
+ // Don't allow replacing SECURE_NOW shortcut
+ return
+ }
+
+ currentShortcuts[oldIndex] = new
+ val shortcutIds = currentShortcuts.map { it.id }
+ .take(maxShortcuts)
+ .toIntArray()
+ viewModelScope.launch {
+ shortcutProvider.setCustomShortcuts(shortcutIds)
+ }
+ }
+
+ private fun removeSecureNowShortcut() {
+ val currentShortcuts = shortcuts.toMutableList()
+ val index = currentShortcuts.indexOf(ShortcutOption.SECURE_NOW)
+ currentShortcuts.removeAt(index)
+ val shortcutIds = currentShortcuts.map { it.id }
+ .take(maxShortcuts)
+ .toIntArray()
+ viewModelScope.launch {
+ shortcutProvider.setCustomShortcuts(shortcutIds)
+ }
+ }
+
+ private fun getPresetShortcuts(): List {
+ return shortcutProvider.getFilteredShortcuts(
+ isPassphraseVerified = isPassphraseVerified,
+ userHasBalance = userHasBalance,
+ userHasContacts = userHasContacts
+ )
+ }
+
+ suspend fun getTopperUrl(walletName: String): String {
+ return topperClient.getOnRampUrl(
+ walletUIConfig.getExchangeCurrencyCode(),
+ walletData.freshReceiveAddress(),
+ walletName
+ )
+ }
+}
\ No newline at end of file
diff --git a/wallet/src/de/schildbach/wallet/ui/widget/ShortcutButton.kt b/wallet/src/de/schildbach/wallet/ui/widget/ShortcutButton.kt
deleted file mode 100644
index 222a06007..000000000
--- a/wallet/src/de/schildbach/wallet/ui/widget/ShortcutButton.kt
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright 2020 Dash Core Group.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package de.schildbach.wallet.ui.widget
-
-import android.content.Context
-import android.content.res.Resources
-import android.util.AttributeSet
-import android.view.Gravity
-import android.view.LayoutInflater
-import android.view.View
-import android.widget.LinearLayout
-import androidx.appcompat.content.res.AppCompatResources
-import androidx.core.content.res.ResourcesCompat
-import com.tbuonomo.viewpagerdotsindicator.setPaddingVertical
-import de.schildbach.wallet_test.R
-import de.schildbach.wallet_test.databinding.ShortcutButtonBinding
-import kotlin.math.roundToInt
-
-class ShortcutButton : LinearLayout {
-
- companion object {
- val DEFAULT_MARGIN_PX = dpToPx(4)
-
- private fun dpToPx(dp: Int): Int {
- val density = Resources.getSystem().displayMetrics.density
- return (dp.toFloat() * density).roundToInt()
- }
- }
-
- private var marginsSet = false
- var shouldAppear: Boolean = true
- private val binding = ShortcutButtonBinding.inflate(LayoutInflater.from(context), this)
-
- init {
- setBackgroundResource(R.drawable.white_button_background_no_shadow)
- orientation = VERTICAL
- gravity = Gravity.CENTER
- setPaddingVertical(DEFAULT_MARGIN_PX)
- }
-
- constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
- val attrsArray = context.obtainStyledAttributes(attrs, R.styleable.ShortcutButton)
- try {
- val drawableResId = attrsArray.getResourceId(R.styleable.ShortcutButton_src, -1)
- if (drawableResId > -1) {
- val actionIconDrawable = AppCompatResources.getDrawable(context, drawableResId)
- if (actionIconDrawable != null) {
- binding.actionIcon.setImageDrawable(actionIconDrawable)
- }
- } else {
- binding.actionIcon.visibility = View.GONE
- }
- val actionText = attrsArray.getString(R.styleable.ShortcutButton_text)
- if (actionText != null) {
- binding.actionText.text = actionText
- } else {
- binding.actionText.visibility = View.GONE
- }
- val backgroundResId = attrsArray.getResourceId(
- R.styleable.ShortcutButton_background,
- R.drawable.white_button_background_no_shadow
- )
- setBackgroundResource(backgroundResId)
- val customTextColor = attrsArray.getColorStateList(R.styleable.ShortcutButton_shortcut_text_color)
- if (customTextColor != null) {
- binding.actionText.setTextColor(customTextColor)
- }
- val actionActive = attrsArray.getBoolean(R.styleable.ShortcutButton_shortcut_active, true)
- setActive(actionActive)
- } finally {
- attrsArray.recycle()
- }
- }
-
- constructor(
- context: Context,
- iconResId: Int = 0,
- textResIt: Int = 0,
- onClickListener: OnClickListener? = null,
- backgroundResId: Int = 0,
- textColorResId: Int = 0
- ) : super(context) {
- if (iconResId != 0) {
- binding.actionIcon.setImageResource(iconResId)
- } else {
- binding.actionIcon.visibility = View.GONE
- }
- if (textResIt != 0) {
- binding.actionText.setText(textResIt)
- } else {
- binding.actionText.visibility = View.GONE
- }
- setOnClickListener(onClickListener)
- if (backgroundResId != 0) {
- setBackgroundResource(backgroundResId)
- }
- if (textColorResId != 0) {
- binding.actionText.setTextColor(ResourcesCompat.getColor(resources, textColorResId, null))
- }
- }
-
- override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
- super.onMeasure(heightMeasureSpec, heightMeasureSpec)
- if (!marginsSet) {
- layoutParams = (layoutParams as MarginLayoutParams).run {
- topMargin = DEFAULT_MARGIN_PX
- bottomMargin = DEFAULT_MARGIN_PX
- this
- }
- marginsSet = true
- }
- }
-
- private fun setActive(active: Boolean) {
- if (active) {
- binding.actionIcon.colorFilter = null
- binding.actionIcon.alpha = 1.0f
- alpha = 1.0f
- } else {
- val tintColor = ResourcesCompat.getColor(resources, R.color.dash_gray, null)
- binding.actionIcon.setColorFilter(tintColor)
- binding.actionIcon.alpha = 0.7f
- alpha = 0.5f
- }
- }
-}
diff --git a/wallet/src/de/schildbach/wallet/ui/widget/ShortcutsPane.kt b/wallet/src/de/schildbach/wallet/ui/widget/ShortcutsPane.kt
deleted file mode 100644
index b32e19075..000000000
--- a/wallet/src/de/schildbach/wallet/ui/widget/ShortcutsPane.kt
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright 2020 Dash Core Group.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package de.schildbach.wallet.ui.widget
-
-import android.content.Context
-import android.util.AttributeSet
-import android.util.DisplayMetrics
-import android.view.View
-import android.view.ViewGroup
-import android.view.ViewTreeObserver
-import androidx.core.view.children
-import com.google.android.flexbox.AlignItems
-import com.google.android.flexbox.FlexDirection
-import com.google.android.flexbox.FlexboxLayout
-import com.google.android.flexbox.JustifyContent
-import de.schildbach.wallet.Constants
-import de.schildbach.wallet_test.R
-import kotlin.math.min
-
-class ShortcutsPane(context: Context, attrs: AttributeSet) : FlexboxLayout(context, attrs), View.OnClickListener {
-
- val secureNowButton: ShortcutButton by lazy {
- ShortcutButton(
- context,
- R.drawable.ic_shortcut_secure_now,
- R.string.shortcut_secure_now,
- this
- )
- }
- val receiveButton: ShortcutButton by lazy {
- ShortcutButton(
- context,
- R.drawable.ic_shortcut_receive,
- R.string.shortcut_receive,
- this
- )
- }
- val scanToPayButton: ShortcutButton by lazy {
- ShortcutButton(
- context,
- R.drawable.ic_shortcut_scan_to_pay,
- R.string.shortcut_scan_to_pay,
- this
- )
- }
- val payToAddressButton: ShortcutButton by lazy {
- ShortcutButton(
- context,
- R.drawable.ic_shortcut_pay_to_address,
- R.string.shortcut_pay_to_address,
- this
- )
- }
- val payToContactButton: ShortcutButton by lazy {
- ShortcutButton(context,
- R.drawable.ic_shortcut_pay_to_contact,
- R.string.shortcut_pay_to_contact,
- this)
- }
- val buySellButton: ShortcutButton by lazy {
- ShortcutButton(
- context,
- R.drawable.ic_shortcut_buy_sell_dash,
- R.string.shortcut_buy_sell,
- this
- )
- }
- val importPrivateKey: ShortcutButton by lazy {
- ShortcutButton(
- context,
- R.drawable.ic_shortcut_import_key,
- R.string.shortcut_import_key,
- this
- )
- }
- val explore: ShortcutButton by lazy {
- ShortcutButton(
- context,
- R.drawable.ic_shortcut_bar_explore,
- R.string.menu_explore_title,
- this
- )
- }
-
- private var isSmallScreen = resources.displayMetrics.densityDpi <= DisplayMetrics.DENSITY_MEDIUM
- private var onShortcutClickListener: OnClickListener? = null
-
- private val shortcuts = listOf(
- secureNowButton,
- explore,
- receiveButton,
- payToAddressButton,
- // TODO: for the time being, never display the "Send to Contact" button
- // payToContactButton,
- buySellButton,
- scanToPayButton
- )
-
- var isPassphraseVerified: Boolean = true
- set(value) {
- secureNowButton.shouldAppear = !value
-
- if (field != value) {
- field = value
- refresh()
- }
- }
-
- var userHasBalance: Boolean = true
- set(value) {
- scanToPayButton.shouldAppear = value
- buySellButton.shouldAppear = !value
- payToAddressButton.shouldAppear = value
- // TODO: will the send to contact button ever be displayed, if not remove
- // payToContactButton.shouldAppear = value && userHasContacts
-
- if (field != value) {
- field = value
- refresh()
- }
- }
-
- var userHasContacts: Boolean = false
- set(value) {
- // TODO: will the send to contact button ever be displayed, if not remove
- // payToContactButton.shouldAppear = value && userHasBalance
-
- if (field != value) {
- field = value
- refresh()
- }
- }
-
- init {
- setBackgroundResource(R.drawable.white_background_rounded)
- minimumHeight = 180
- flexDirection = FlexDirection.ROW
- justifyContent = JustifyContent.SPACE_EVENLY
- alignItems = AlignItems.CENTER
- if (isInEditMode) {
- refresh()
- }
- val onPreDrawListener = object : ViewTreeObserver.OnPreDrawListener {
- override fun onPreDraw(): Boolean {
- viewTreeObserver.removeOnPreDrawListener(this)
- val sizeRation = width.toFloat() / height.toFloat()
- isSmallScreen = (sizeRation < 3.3)
- refresh()
- return false
- }
- }
- viewTreeObserver.addOnPreDrawListener(onPreDrawListener)
- }
-
- private fun refresh() {
- var slotsLeft = if (isSmallScreen) 3 else 4
-
- shortcuts.forEach { btn ->
- if (btn.shouldAppear && slotsLeft > 0) {
- addShortcut(btn)
- slotsLeft--
- } else {
- removeShortcut(btn)
- }
- }
- }
-
- private fun addShortcut(shortcut: ShortcutButton) {
- if (!children.contains(shortcut)) {
- val index = min(childCount, shortcuts.indexOf(shortcut))
- val layoutParams = ViewGroup.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.MATCH_PARENT
- )
- addView(shortcut, index, layoutParams)
- }
- }
-
- private fun removeShortcut(shortcut: ShortcutButton) {
- if (children.contains(shortcut)) {
- removeView(shortcut)
- }
- }
-
- fun setOnShortcutClickListener(listener: OnClickListener) {
- onShortcutClickListener = listener
- setOnClickListener(null)
- }
-
- override fun onClick(v: View) {
- onShortcutClickListener?.onClick(v)
- }
-}
diff --git a/wallet/staging/res/values/values.xml b/wallet/staging/res/values/values.xml
index 02a2df145..dcc8c4b20 100644
--- a/wallet/staging/res/values/values.xml
+++ b/wallet/staging/res/values/values.xml
@@ -20,9 +20,11 @@
- https://insight.testnet.networks.dash.org:3002/insight/
+ - https://blockchair.com/dash/
- Insight
+ - Blockchair
\ No newline at end of file
diff --git a/wallet/testNet3/res/drawable-xhdpi/currency_symbol_mdash.png b/wallet/testNet3/res/drawable-xhdpi/currency_symbol_mdash.png
deleted file mode 100644
index 00f75445b..000000000
Binary files a/wallet/testNet3/res/drawable-xhdpi/currency_symbol_mdash.png and /dev/null differ
diff --git a/wallet/testNet3/res/drawable-xhdpi/currency_symbol_udash.png b/wallet/testNet3/res/drawable-xhdpi/currency_symbol_udash.png
deleted file mode 100644
index 1d368a72e..000000000
Binary files a/wallet/testNet3/res/drawable-xhdpi/currency_symbol_udash.png and /dev/null differ
diff --git a/wallet/testNet3/res/values/values.xml b/wallet/testNet3/res/values/values.xml
index 3f420cf63..5c6e0d5b4 100644
--- a/wallet/testNet3/res/values/values.xml
+++ b/wallet/testNet3/res/values/values.xml
@@ -21,9 +21,11 @@
- http://insight.testnet.networks.dash.org/insight/
+ - https://blockchair.com/dash/
- Insight
+ - Blockchair
\ No newline at end of file