Implement street mode

This commit is contained in:
pokkst 2022-11-16 13:27:14 -06:00
parent b7470567da
commit a8678114ad
No known key found for this signature in database
GPG key ID: 90C2ED85E67A50FF
10 changed files with 114 additions and 26 deletions

View file

@ -27,6 +27,8 @@ import androidx.recyclerview.widget.RecyclerView;
import net.mynero.wallet.R; import net.mynero.wallet.R;
import net.mynero.wallet.model.CoinsInfo; import net.mynero.wallet.model.CoinsInfo;
import net.mynero.wallet.model.Wallet; import net.mynero.wallet.model.Wallet;
import net.mynero.wallet.service.PrefService;
import net.mynero.wallet.util.Constants;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -102,8 +104,9 @@ public class CoinsInfoAdapter extends RecyclerView.Adapter<CoinsInfoAdapter.View
TextView amountTextView = itemView.findViewById(R.id.utxo_amount_textview); TextView amountTextView = itemView.findViewById(R.id.utxo_amount_textview);
TextView globalIdxTextView = itemView.findViewById(R.id.utxo_global_index_textview); TextView globalIdxTextView = itemView.findViewById(R.id.utxo_global_index_textview);
TextView outpointTextView = itemView.findViewById(R.id.utxo_outpoint_textview); TextView outpointTextView = itemView.findViewById(R.id.utxo_outpoint_textview);
boolean streetModeEnabled = PrefService.getInstance().getBoolean(Constants.PREF_STREET_MODE, false);
amountTextView.setText(itemView.getResources().getString(R.string.tx_amount_no_prefix, Wallet.getDisplayAmount(coinsInfo.getAmount()))); String balanceString = streetModeEnabled ? Constants.STREET_MODE_BALANCE : Wallet.getDisplayAmount(coinsInfo.getAmount());
amountTextView.setText(itemView.getResources().getString(R.string.tx_amount_no_prefix, balanceString));
pubKeyTextView.setText(coinsInfo.getPubKey()); pubKeyTextView.setText(coinsInfo.getPubKey());
globalIdxTextView.setText(itemView.getResources().getString(R.string.global_index_text, coinsInfo.getGlobalOutputIndex())); globalIdxTextView.setText(itemView.getResources().getString(R.string.global_index_text, coinsInfo.getGlobalOutputIndex()));
outpointTextView.setText(itemView.getResources().getString(R.string.outpoint_text, coinsInfo.getHash() + ":" + coinsInfo.getLocalOutputIndex())); outpointTextView.setText(itemView.getResources().getString(R.string.outpoint_text, coinsInfo.getHash() + ":" + coinsInfo.getLocalOutputIndex()));

View file

@ -38,8 +38,6 @@ import net.mynero.wallet.util.UriData;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SendBottomSheetDialog extends BottomSheetDialogFragment { public class SendBottomSheetDialog extends BottomSheetDialogFragment {
private final MutableLiveData<Boolean> _sendingMax = new MutableLiveData<>(false); private final MutableLiveData<Boolean> _sendingMax = new MutableLiveData<>(false);
@ -136,11 +134,10 @@ public class SendBottomSheetDialog extends BottomSheetDialogFragment {
} }
private void bindObservers() { private void bindObservers() {
BalanceService.getInstance().balanceInfo.observe(getViewLifecycleOwner(), balanceInfo -> {
BalanceService.getInstance().balance.observe(getViewLifecycleOwner(), balance -> { createButton.setEnabled(balanceInfo.getRawUnlocked() != 0);
createButton.setEnabled(balance != 0);
if(!isChurning) { if(!isChurning) {
sendMaxButton.setEnabled(balance != 0); sendMaxButton.setEnabled(balanceInfo.getRawUnlocked() != 0);
} }
}); });

View file

@ -32,6 +32,7 @@ import net.mynero.wallet.model.WalletManager;
import net.mynero.wallet.service.BalanceService; import net.mynero.wallet.service.BalanceService;
import net.mynero.wallet.service.BlockchainService; import net.mynero.wallet.service.BlockchainService;
import net.mynero.wallet.service.HistoryService; import net.mynero.wallet.service.HistoryService;
import net.mynero.wallet.util.Constants;
import java.util.Collections; import java.util.Collections;
@ -91,16 +92,16 @@ public class HomeFragment extends Fragment implements TransactionInfoAdapter.TxI
BlockchainService blockchainService = BlockchainService.getInstance(); BlockchainService blockchainService = BlockchainService.getInstance();
if (balanceService != null) { if (balanceService != null) {
balanceService.balance.observe(getViewLifecycleOwner(), balance -> { balanceService.balanceInfo.observe(getViewLifecycleOwner(), balanceInfo -> {
unlockedBalanceTextView.setText(getString(R.string.wallet_balance_text, Wallet.getDisplayAmount(balance))); if(balanceInfo != null) {
}); unlockedBalanceTextView.setText(getString(R.string.wallet_balance_text, balanceInfo.getUnlockedDisplay()));
balanceService.lockedBalance.observe(getViewLifecycleOwner(), lockedBalance -> { if (balanceInfo.getLockedDisplay().equals(Constants.STREET_MODE_BALANCE) || balanceInfo.isLockedBalanceZero()) {
if (lockedBalance == 0) { lockedBalanceTextView.setVisibility(View.INVISIBLE);
lockedBalanceTextView.setVisibility(View.INVISIBLE); } else {
} else { lockedBalanceTextView.setText(getString(R.string.wallet_locked_balance_text, balanceInfo.getLockedDisplay()));
lockedBalanceTextView.setText(getString(R.string.wallet_locked_balance_text, Wallet.getDisplayAmount(lockedBalance))); lockedBalanceTextView.setVisibility(View.VISIBLE);
lockedBalanceTextView.setVisibility(View.VISIBLE); }
} }
}); });
} }

View file

@ -33,6 +33,7 @@ import net.mynero.wallet.fragment.dialog.NodeSelectionBottomSheetDialog;
import net.mynero.wallet.fragment.dialog.PasswordBottomSheetDialog; import net.mynero.wallet.fragment.dialog.PasswordBottomSheetDialog;
import net.mynero.wallet.model.Wallet; import net.mynero.wallet.model.Wallet;
import net.mynero.wallet.model.WalletManager; import net.mynero.wallet.model.WalletManager;
import net.mynero.wallet.service.BalanceService;
import net.mynero.wallet.service.BlockchainService; import net.mynero.wallet.service.BlockchainService;
import net.mynero.wallet.service.PrefService; import net.mynero.wallet.service.PrefService;
import net.mynero.wallet.util.Constants; import net.mynero.wallet.util.Constants;
@ -97,6 +98,7 @@ public class SettingsFragment extends Fragment implements PasswordBottomSheetDia
selectNodeButton = view.findViewById(R.id.select_node_button); selectNodeButton = view.findViewById(R.id.select_node_button);
SwitchCompat nightModeSwitch = view.findViewById(R.id.day_night_switch); SwitchCompat nightModeSwitch = view.findViewById(R.id.day_night_switch);
SwitchCompat streetModeSwitch = view.findViewById(R.id.street_mode_switch);
SwitchCompat torSwitch = view.findViewById(R.id.tor_switch); SwitchCompat torSwitch = view.findViewById(R.id.tor_switch);
ConstraintLayout proxySettingsLayout = view.findViewById(R.id.wallet_proxy_settings_layout); ConstraintLayout proxySettingsLayout = view.findViewById(R.id.wallet_proxy_settings_layout);
walletProxyAddressEditText = view.findViewById(R.id.wallet_proxy_address_edittext); walletProxyAddressEditText = view.findViewById(R.id.wallet_proxy_address_edittext);
@ -111,6 +113,12 @@ public class SettingsFragment extends Fragment implements PasswordBottomSheetDia
} }
}); });
streetModeSwitch.setChecked(PrefService.getInstance().getBoolean(Constants.PREF_STREET_MODE, false));
streetModeSwitch.setOnCheckedChangeListener((compoundButton, b) -> {
PrefService.getInstance().edit().putBoolean(Constants.PREF_STREET_MODE, b).apply();
BalanceService.getInstance().refreshBalance();
});
boolean usesProxy = PrefService.getInstance().getBoolean(Constants.PREF_USES_TOR, false); boolean usesProxy = PrefService.getInstance().getBoolean(Constants.PREF_USES_TOR, false);
String proxy = PrefService.getInstance().getString(Constants.PREF_PROXY, ""); String proxy = PrefService.getInstance().getString(Constants.PREF_PROXY, "");
if (proxy.contains(":")) { if (proxy.contains(":")) {

View file

@ -18,6 +18,8 @@ import androidx.lifecycle.ViewModelProvider;
import net.mynero.wallet.R; import net.mynero.wallet.R;
import net.mynero.wallet.model.TransactionInfo; import net.mynero.wallet.model.TransactionInfo;
import net.mynero.wallet.model.Wallet;
import net.mynero.wallet.service.PrefService;
import net.mynero.wallet.util.Constants; import net.mynero.wallet.util.Constants;
import net.mynero.wallet.util.Helper; import net.mynero.wallet.util.Helper;
@ -100,12 +102,14 @@ public class TransactionFragment extends Fragment {
Context ctx = getContext(); Context ctx = getContext();
if(ctx != null) { if(ctx != null) {
boolean streetModeEnabled = PrefService.getInstance().getBoolean(Constants.PREF_STREET_MODE, false);
String balanceString = streetModeEnabled ? Constants.STREET_MODE_BALANCE : Wallet.getDisplayAmount(transactionInfo.amount);
if (transactionInfo.direction == TransactionInfo.Direction.Direction_In) { if (transactionInfo.direction == TransactionInfo.Direction.Direction_In) {
txAmountTextView.setTextColor(ContextCompat.getColor(ctx, R.color.oled_positiveColor)); txAmountTextView.setTextColor(ContextCompat.getColor(ctx, R.color.oled_positiveColor));
txAmountTextView.setText(getString(R.string.tx_list_amount_positive, Helper.getDisplayAmount(transactionInfo.amount))); txAmountTextView.setText(getString(R.string.tx_list_amount_positive, balanceString));
} else { } else {
txAmountTextView.setTextColor(ContextCompat.getColor(ctx, R.color.oled_negativeColor)); txAmountTextView.setTextColor(ContextCompat.getColor(ctx, R.color.oled_negativeColor));
txAmountTextView.setText(getString(R.string.tx_list_amount_negative, Helper.getDisplayAmount(transactionInfo.amount))); txAmountTextView.setText(getString(R.string.tx_list_amount_negative, balanceString));
} }
} }
}); });

View file

@ -0,0 +1,48 @@
package net.mynero.wallet.model;
import net.mynero.wallet.service.PrefService;
import net.mynero.wallet.util.Constants;
public class BalanceInfo {
private final long rawUnlocked;
private final long rawLocked;
public BalanceInfo(long rawUnlocked, long rawLocked) {
this.rawUnlocked = rawUnlocked;
this.rawLocked = rawLocked;
}
public long getRawLocked() {
return rawLocked;
}
public long getRawUnlocked() {
return rawUnlocked;
}
public boolean isUnlockedBalanceZero() {
return rawUnlocked == 0;
}
public boolean isLockedBalanceZero() {
return rawLocked == 0;
}
public String getUnlockedDisplay() {
boolean streetModeEnabled = PrefService.getInstance().getBoolean(Constants.PREF_STREET_MODE, false);
if(streetModeEnabled) {
return Constants.STREET_MODE_BALANCE;
} else {
return Wallet.getDisplayAmount(rawUnlocked);
}
}
public String getLockedDisplay() {
boolean streetModeEnabled = PrefService.getInstance().getBoolean(Constants.PREF_STREET_MODE, false);
if(streetModeEnabled) {
return Constants.STREET_MODE_BALANCE;
} else {
return Wallet.getDisplayAmount(rawLocked);
}
}
}

View file

@ -3,14 +3,15 @@ package net.mynero.wallet.service;
import androidx.lifecycle.LiveData; import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.MutableLiveData;
import net.mynero.wallet.model.BalanceInfo;
import net.mynero.wallet.model.Wallet;
import net.mynero.wallet.model.WalletManager; import net.mynero.wallet.model.WalletManager;
import net.mynero.wallet.util.Constants;
public class BalanceService extends ServiceBase { public class BalanceService extends ServiceBase {
public static BalanceService instance = null; public static BalanceService instance = null;
private final MutableLiveData<Long> _balance = new MutableLiveData<>(0L); private final MutableLiveData<BalanceInfo> _balanceInfo = new MutableLiveData<>(null);
private final MutableLiveData<Long> _lockedBalance = new MutableLiveData<>(0L); public LiveData<BalanceInfo> balanceInfo = _balanceInfo;
public LiveData<Long> balance = _balance;
public LiveData<Long> lockedBalance = _lockedBalance;
public BalanceService(MoneroHandlerThread thread) { public BalanceService(MoneroHandlerThread thread) {
super(thread); super(thread);
@ -22,8 +23,9 @@ public class BalanceService extends ServiceBase {
} }
public void refreshBalance() { public void refreshBalance() {
_balance.postValue(getUnlockedBalanceRaw()); long rawUnlocked = getUnlockedBalanceRaw();
_lockedBalance.postValue(getLockedBalanceRaw()); long rawLocked = getLockedBalanceRaw();
_balanceInfo.postValue(new BalanceInfo(rawUnlocked, rawLocked));
} }
public long getUnlockedBalanceRaw() { public long getUnlockedBalanceRaw() {

View file

@ -10,9 +10,12 @@ public class Constants {
public static final String PREF_NODE_2 = "pref_node_2"; public static final String PREF_NODE_2 = "pref_node_2";
public static final String PREF_CUSTOM_NODES = "pref_custom_nodes"; public static final String PREF_CUSTOM_NODES = "pref_custom_nodes";
public static final String PREF_USES_OFFSET = "pref_uses_offset"; public static final String PREF_USES_OFFSET = "pref_uses_offset";
public static final String PREF_STREET_MODE = "pref_street_mode";
public static final String URI_PREFIX = "monero:"; public static final String URI_PREFIX = "monero:";
public static final String URI_ARG_AMOUNT = "tx_amount"; public static final String URI_ARG_AMOUNT = "tx_amount";
public static final String URI_ARG_AMOUNT2 = "amount"; public static final String URI_ARG_AMOUNT2 = "amount";
public static final String NAV_ARG_TXINFO = "nav_arg_txinfo"; public static final String NAV_ARG_TXINFO = "nav_arg_txinfo";
public static final String STREET_MODE_BALANCE = "#.############";
} }

View file

@ -112,6 +112,27 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/appearance_settings_textview" /> app:layout_constraintTop_toBottomOf="@id/appearance_settings_textview" />
<TextView
android:id="@+id/street_mode_label_textview"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/street_mode"
android:textSize="16sp"
android:layout_marginStart="24dp"
app:layout_constraintBottom_toBottomOf="@id/street_mode_switch"
app:layout_constraintEnd_toStartOf="@id/street_mode_switch"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/street_mode_switch" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/street_mode_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="24dp"
android:minHeight="48dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/day_night_switch" />
<TextView <TextView
android:id="@+id/network_settings_textview" android:id="@+id/network_settings_textview"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -124,7 +145,7 @@
android:textStyle="bold" android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/day_night_switch" /> app:layout_constraintTop_toBottomOf="@id/street_mode_switch" />
<Button <Button
android:id="@+id/select_node_button" android:id="@+id/select_node_button"

View file

@ -39,6 +39,7 @@
<string name="invalid_mnemonic_code">Invalid mnemonic</string> <string name="invalid_mnemonic_code">Invalid mnemonic</string>
<string name="copied_to_clipboard">Copied to clipboard</string> <string name="copied_to_clipboard">Copied to clipboard</string>
<string name="night_mode">Night mode</string> <string name="night_mode">Night mode</string>
<string name="street_mode">Street mode (hide balances)</string>
<string name="display_recovery_phrase">Display wallet keys</string> <string name="display_recovery_phrase">Display wallet keys</string>
<string name="tor_switch_label">Connect to proxy</string> <string name="tor_switch_label">Connect to proxy</string>
<string name="connection_failed">Connection failed</string> <string name="connection_failed">Connection failed</string>