mirror of
https://codeberg.org/r4v3r23/mysu.git
synced 2024-11-25 15:22:28 +00:00
Convert remaining screens to Kotlin
This commit is contained in:
parent
2f400d7e8d
commit
a1c43db4db
15 changed files with 965 additions and 988 deletions
|
@ -40,8 +40,8 @@ class MainActivity : AppCompatActivity(), MoneroHandlerThread.Listener, Password
|
||||||
val walletKeysFile = File(applicationInfo.dataDir, Constants.WALLET_NAME + ".keys")
|
val walletKeysFile = File(applicationInfo.dataDir, Constants.WALLET_NAME + ".keys")
|
||||||
if (walletKeysFile.exists()) {
|
if (walletKeysFile.exists()) {
|
||||||
val promptPassword =
|
val promptPassword =
|
||||||
PrefService.instance?.getBoolean(Constants.PREF_USES_PASSWORD, false)
|
PrefService.instance?.getBoolean(Constants.PREF_USES_PASSWORD, false) == true
|
||||||
if (promptPassword == false) {
|
if (!promptPassword) {
|
||||||
init(walletFile, "")
|
init(walletFile, "")
|
||||||
} else {
|
} else {
|
||||||
val passwordDialog = PasswordBottomSheetDialog()
|
val passwordDialog = PasswordBottomSheetDialog()
|
||||||
|
|
|
@ -96,7 +96,7 @@ class CoinsInfoAdapter(val listener: CoinsInfoAdapterListener?) :
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CoinsInfoAdapterListener {
|
interface CoinsInfoAdapterListener {
|
||||||
fun onUtxoSelected(coinsInfo: CoinsInfo?)
|
fun onUtxoSelected(coinsInfo: CoinsInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -127,9 +127,9 @@ class CoinsInfoAdapter(val listener: CoinsInfoAdapterListener?) :
|
||||||
val globalIdxTextView = itemView.findViewById<TextView>(R.id.utxo_global_index_textview)
|
val globalIdxTextView = itemView.findViewById<TextView>(R.id.utxo_global_index_textview)
|
||||||
val outpointTextView = itemView.findViewById<TextView>(R.id.utxo_outpoint_textview)
|
val outpointTextView = itemView.findViewById<TextView>(R.id.utxo_outpoint_textview)
|
||||||
val streetModeEnabled =
|
val streetModeEnabled =
|
||||||
PrefService.instance?.getBoolean(Constants.PREF_STREET_MODE, false)
|
PrefService.instance?.getBoolean(Constants.PREF_STREET_MODE, false) == true
|
||||||
val balanceString =
|
val balanceString =
|
||||||
if (streetModeEnabled == true) Constants.STREET_MODE_BALANCE else Wallet.getDisplayAmount(
|
if (streetModeEnabled) Constants.STREET_MODE_BALANCE else Wallet.getDisplayAmount(
|
||||||
coinsInfo.amount
|
coinsInfo.amount
|
||||||
)
|
)
|
||||||
amountTextView.text =
|
amountTextView.text =
|
||||||
|
@ -167,7 +167,7 @@ class CoinsInfoAdapter(val listener: CoinsInfoAdapterListener?) :
|
||||||
if (!editing) return
|
if (!editing) return
|
||||||
val unlocked = coinsInfo?.isUnlocked == true
|
val unlocked = coinsInfo?.isUnlocked == true
|
||||||
if (unlocked) {
|
if (unlocked) {
|
||||||
listener?.onUtxoSelected(coinsInfo)
|
coinsInfo?.let { listener?.onUtxoSelected(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,7 +175,7 @@ class CoinsInfoAdapter(val listener: CoinsInfoAdapterListener?) :
|
||||||
if (editing) return false
|
if (editing) return false
|
||||||
val unlocked = coinsInfo?.isUnlocked == true
|
val unlocked = coinsInfo?.isUnlocked == true
|
||||||
if (unlocked) {
|
if (unlocked) {
|
||||||
listener?.onUtxoSelected(coinsInfo)
|
coinsInfo?.let { listener?.onUtxoSelected(it) }
|
||||||
}
|
}
|
||||||
return unlocked
|
return unlocked
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,8 +91,8 @@ class SubaddressAdapter(val listener: SubaddressAdapterListener?) :
|
||||||
val amount = subaddress.amount
|
val amount = subaddress.amount
|
||||||
if (amount > 0) {
|
if (amount > 0) {
|
||||||
val streetMode =
|
val streetMode =
|
||||||
PrefService.instance?.getBoolean(Constants.PREF_STREET_MODE, false)
|
PrefService.instance?.getBoolean(Constants.PREF_STREET_MODE, false) == true
|
||||||
if (streetMode == true) {
|
if (streetMode) {
|
||||||
addressAmountTextView.text = itemView.context.getString(
|
addressAmountTextView.text = itemView.context.getString(
|
||||||
R.string.tx_list_amount_positive,
|
R.string.tx_list_amount_positive,
|
||||||
Constants.STREET_MODE_BALANCE
|
Constants.STREET_MODE_BALANCE
|
||||||
|
|
|
@ -94,9 +94,9 @@ class TransactionInfoAdapter(val listener: TxInfoAdapterListener?) :
|
||||||
|
|
||||||
fun bind(txInfo: TransactionInfo) {
|
fun bind(txInfo: TransactionInfo) {
|
||||||
val streetModeEnabled =
|
val streetModeEnabled =
|
||||||
PrefService.instance?.getBoolean(Constants.PREF_STREET_MODE, false)
|
PrefService.instance?.getBoolean(Constants.PREF_STREET_MODE, false) == true
|
||||||
val displayAmount =
|
val displayAmount =
|
||||||
if (streetModeEnabled == true) Constants.STREET_MODE_BALANCE else Helper.getDisplayAmount(
|
if (streetModeEnabled) Constants.STREET_MODE_BALANCE else Helper.getDisplayAmount(
|
||||||
txInfo.amount,
|
txInfo.amount,
|
||||||
Helper.DISPLAY_DIGITS_INFO
|
Helper.DISPLAY_DIGITS_INFO
|
||||||
)
|
)
|
||||||
|
|
|
@ -30,17 +30,17 @@ class WalletKeysBottomSheetDialog : BottomSheetDialogFragment() {
|
||||||
val informationTextView = view.findViewById<TextView>(R.id.information_textview) // seed
|
val informationTextView = view.findViewById<TextView>(R.id.information_textview) // seed
|
||||||
val viewKeyTextView = view.findViewById<TextView>(R.id.viewkey_textview)
|
val viewKeyTextView = view.findViewById<TextView>(R.id.viewkey_textview)
|
||||||
val restoreHeightTextView = view.findViewById<TextView>(R.id.restore_height_textview)
|
val restoreHeightTextView = view.findViewById<TextView>(R.id.restore_height_textview)
|
||||||
val wallet = WalletManager.instance!!.wallet
|
val wallet = WalletManager.instance?.wallet
|
||||||
var seed = wallet!!.getSeed("")
|
var seed = wallet?.getSeed("")
|
||||||
val usesOffset = PrefService.instance!!.getBoolean(Constants.PREF_USES_OFFSET, false)
|
val usesOffset = PrefService.instance?.getBoolean(Constants.PREF_USES_OFFSET, false) == true
|
||||||
if (usesOffset) {
|
if (usesOffset) {
|
||||||
seed = wallet.getSeed(password)
|
seed = wallet?.getSeed(password)
|
||||||
view.findViewById<View>(R.id.wallet_seed_offset_textview).visibility = View.VISIBLE
|
view.findViewById<View>(R.id.wallet_seed_offset_textview).visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
val privateViewKey = wallet.getSecretViewKey()
|
val privateViewKey = wallet?.getSecretViewKey()
|
||||||
informationTextView.text = seed
|
informationTextView.text = seed
|
||||||
viewKeyTextView.text = privateViewKey
|
viewKeyTextView.text = privateViewKey
|
||||||
restoreHeightTextView.text = "${wallet.getRestoreHeight()}"
|
restoreHeightTextView.text = "${wallet?.getRestoreHeight()}"
|
||||||
copyViewKeyImageButton.setOnClickListener {
|
copyViewKeyImageButton.setOnClickListener {
|
||||||
clipBoardCopy(
|
clipBoardCopy(
|
||||||
context, "private view-key", privateViewKey
|
context, "private view-key", privateViewKey
|
||||||
|
|
|
@ -165,8 +165,9 @@ class HomeFragment : Fragment(), TxInfoAdapterListener {
|
||||||
val botImageView = view.findViewById<ImageView>(R.id.monerochan_imageview)
|
val botImageView = view.findViewById<ImageView>(R.id.monerochan_imageview)
|
||||||
view.findViewById<View>(R.id.no_history_layout).visibility =
|
view.findViewById<View>(R.id.no_history_layout).visibility =
|
||||||
if (display) View.VISIBLE else View.GONE
|
if (display) View.VISIBLE else View.GONE
|
||||||
val displayMonerochan = PrefService.instance?.getBoolean(Constants.PREF_MONEROCHAN, true)
|
val displayMonerochan =
|
||||||
if (displayMonerochan == true) {
|
PrefService.instance?.getBoolean(Constants.PREF_MONEROCHAN, true) == true
|
||||||
|
if (displayMonerochan) {
|
||||||
botImageView.visibility = View.VISIBLE
|
botImageView.visibility = View.VISIBLE
|
||||||
mnrjTextView.visibility = View.VISIBLE
|
mnrjTextView.visibility = View.VISIBLE
|
||||||
textView.visibility = View.GONE
|
textView.visibility = View.GONE
|
||||||
|
|
|
@ -1,326 +1,297 @@
|
||||||
package net.mynero.wallet.fragment.onboarding;
|
package net.mynero.wallet.fragment.onboarding
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity
|
||||||
import android.os.Bundle;
|
import android.os.Bundle
|
||||||
import android.text.Editable;
|
import android.text.Editable
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher
|
||||||
import android.util.Patterns;
|
import android.util.Patterns
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater
|
||||||
import android.view.View;
|
import android.view.View
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup
|
||||||
import android.widget.Button;
|
import android.widget.Button
|
||||||
import android.widget.CheckBox;
|
import android.widget.CheckBox
|
||||||
import android.widget.EditText;
|
import android.widget.CompoundButton
|
||||||
import android.widget.ImageView;
|
import android.widget.EditText
|
||||||
import android.widget.TextView;
|
import android.widget.ImageView
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.activity.OnBackPressedCallback
|
||||||
|
import androidx.appcompat.widget.SwitchCompat
|
||||||
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import net.mynero.wallet.MoneroApplication
|
||||||
|
import net.mynero.wallet.R
|
||||||
|
import net.mynero.wallet.data.Node
|
||||||
|
import net.mynero.wallet.fragment.dialog.AddNodeBottomSheetDialog
|
||||||
|
import net.mynero.wallet.fragment.dialog.AddNodeBottomSheetDialog.AddNodeListener
|
||||||
|
import net.mynero.wallet.fragment.dialog.NodeSelectionBottomSheetDialog
|
||||||
|
import net.mynero.wallet.fragment.dialog.NodeSelectionBottomSheetDialog.NodeSelectionDialogListener
|
||||||
|
import net.mynero.wallet.fragment.onboarding.OnboardingViewModel.SeedType
|
||||||
|
import net.mynero.wallet.service.PrefService
|
||||||
|
import net.mynero.wallet.util.Constants
|
||||||
|
|
||||||
import androidx.activity.OnBackPressedCallback;
|
class OnboardingFragment : Fragment(), NodeSelectionDialogListener, AddNodeListener {
|
||||||
import androidx.annotation.NonNull;
|
private var useOffset = true
|
||||||
import androidx.annotation.Nullable;
|
private var mViewModel: OnboardingViewModel? = null
|
||||||
import androidx.appcompat.widget.SwitchCompat;
|
private var proxyAddressListener: TextWatcher = object : TextWatcher {
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
|
||||||
import androidx.fragment.app.Fragment;
|
override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
|
||||||
import androidx.fragment.app.FragmentActivity;
|
override fun afterTextChanged(editable: Editable) {
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
|
||||||
|
|
||||||
import net.mynero.wallet.MoneroApplication;
|
|
||||||
import net.mynero.wallet.R;
|
|
||||||
import net.mynero.wallet.data.Node;
|
|
||||||
import net.mynero.wallet.fragment.dialog.AddNodeBottomSheetDialog;
|
|
||||||
import net.mynero.wallet.fragment.dialog.NodeSelectionBottomSheetDialog;
|
|
||||||
import net.mynero.wallet.service.PrefService;
|
|
||||||
import net.mynero.wallet.util.Constants;
|
|
||||||
|
|
||||||
public class OnboardingFragment extends Fragment implements NodeSelectionBottomSheetDialog.NodeSelectionDialogListener, AddNodeBottomSheetDialog.AddNodeListener {
|
|
||||||
private boolean useOffset = true;
|
|
||||||
private OnboardingViewModel mViewModel;
|
|
||||||
TextWatcher proxyAddressListener = new TextWatcher() {
|
|
||||||
@Override
|
|
||||||
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterTextChanged(Editable editable) {
|
|
||||||
if (mViewModel != null) {
|
if (mViewModel != null) {
|
||||||
mViewModel.setProxyAddress(editable.toString());
|
mViewModel?.setProxyAddress(editable.toString())
|
||||||
mViewModel.updateProxy(((MoneroApplication) getActivity().getApplication()));
|
mViewModel?.updateProxy(activity?.application as MoneroApplication)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
TextWatcher proxyPortListener = new TextWatcher() {
|
private var proxyPortListener: TextWatcher = object : TextWatcher {
|
||||||
@Override
|
override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
|
||||||
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
|
||||||
}
|
override fun afterTextChanged(editable: Editable) {
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterTextChanged(Editable editable) {
|
|
||||||
if (mViewModel != null) {
|
if (mViewModel != null) {
|
||||||
mViewModel.setProxyPort(editable.toString());
|
mViewModel?.setProxyPort(editable.toString())
|
||||||
mViewModel.updateProxy(((MoneroApplication) getActivity().getApplication()));
|
mViewModel?.updateProxy(activity?.application as MoneroApplication)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
private EditText walletProxyAddressEditText;
|
private var walletProxyAddressEditText: EditText? = null
|
||||||
private EditText walletProxyPortEditText;
|
private var walletProxyPortEditText: EditText? = null
|
||||||
private EditText walletPasswordEditText;
|
private var walletPasswordEditText: EditText? = null
|
||||||
private EditText walletPasswordConfirmEditText;
|
private var walletPasswordConfirmEditText: EditText? = null
|
||||||
private EditText walletSeedEditText;
|
private var walletSeedEditText: EditText? = null
|
||||||
private EditText walletRestoreHeightEditText;
|
private var walletRestoreHeightEditText: EditText? = null
|
||||||
private Button createWalletButton;
|
private var createWalletButton: Button? = null
|
||||||
private TextView moreOptionsDropdownTextView;
|
private var moreOptionsDropdownTextView: TextView? = null
|
||||||
private SwitchCompat torSwitch;
|
private var torSwitch: SwitchCompat? = null
|
||||||
private ConstraintLayout advancedOptionsLayout;
|
private var advancedOptionsLayout: ConstraintLayout? = null
|
||||||
private ImageView moreOptionsChevronImageView;
|
private var moreOptionsChevronImageView: ImageView? = null
|
||||||
private CheckBox seedOffsetCheckbox;
|
private var seedOffsetCheckbox: CheckBox? = null
|
||||||
private Button selectNodeButton;
|
private var selectNodeButton: Button? = null
|
||||||
private SwitchCompat showXmrchanSwitch;
|
private var showXmrchanSwitch: SwitchCompat? = null
|
||||||
private ImageView xmrchanOnboardingImage;
|
private var xmrchanOnboardingImage: ImageView? = null
|
||||||
private Button seedTypeButton;
|
private var seedTypeButton: Button? = null
|
||||||
private TextView seedTypeDescTextView;
|
private var seedTypeDescTextView: TextView? = null
|
||||||
|
override fun onCreateView(
|
||||||
@Override
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
savedInstanceState: Bundle?
|
||||||
@Nullable Bundle savedInstanceState) {
|
): View? {
|
||||||
return inflater.inflate(R.layout.fragment_onboarding, container, false);
|
return inflater.inflate(R.layout.fragment_onboarding, container, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
super.onViewCreated(view, savedInstanceState)
|
||||||
super.onViewCreated(view, savedInstanceState);
|
mViewModel = ViewModelProvider(this)[OnboardingViewModel::class.java]
|
||||||
mViewModel = new ViewModelProvider(this).get(OnboardingViewModel.class);
|
selectNodeButton = view.findViewById(R.id.select_node_button)
|
||||||
selectNodeButton = view.findViewById(R.id.select_node_button);
|
walletPasswordEditText = view.findViewById(R.id.wallet_password_edittext)
|
||||||
walletPasswordEditText = view.findViewById(R.id.wallet_password_edittext);
|
walletPasswordConfirmEditText = view.findViewById(R.id.wallet_password_confirm_edittext)
|
||||||
walletPasswordConfirmEditText = view.findViewById(R.id.wallet_password_confirm_edittext);
|
walletSeedEditText = view.findViewById(R.id.wallet_seed_edittext)
|
||||||
walletSeedEditText = view.findViewById(R.id.wallet_seed_edittext);
|
walletRestoreHeightEditText = view.findViewById(R.id.wallet_restore_height_edittext)
|
||||||
walletRestoreHeightEditText = view.findViewById(R.id.wallet_restore_height_edittext);
|
createWalletButton = view.findViewById(R.id.create_wallet_button)
|
||||||
createWalletButton = view.findViewById(R.id.create_wallet_button);
|
moreOptionsDropdownTextView = view.findViewById(R.id.advanced_settings_dropdown_textview)
|
||||||
moreOptionsDropdownTextView = view.findViewById(R.id.advanced_settings_dropdown_textview);
|
moreOptionsChevronImageView = view.findViewById(R.id.advanced_settings_chevron_imageview)
|
||||||
moreOptionsChevronImageView = view.findViewById(R.id.advanced_settings_chevron_imageview);
|
torSwitch = view.findViewById(R.id.tor_onboarding_switch)
|
||||||
torSwitch = view.findViewById(R.id.tor_onboarding_switch);
|
seedOffsetCheckbox = view.findViewById(R.id.seed_offset_checkbox)
|
||||||
seedOffsetCheckbox = view.findViewById(R.id.seed_offset_checkbox);
|
walletProxyAddressEditText = view.findViewById(R.id.wallet_proxy_address_edittext)
|
||||||
walletProxyAddressEditText = view.findViewById(R.id.wallet_proxy_address_edittext);
|
walletProxyPortEditText = view.findViewById(R.id.wallet_proxy_port_edittext)
|
||||||
walletProxyPortEditText = view.findViewById(R.id.wallet_proxy_port_edittext);
|
advancedOptionsLayout = view.findViewById(R.id.more_options_layout)
|
||||||
advancedOptionsLayout = view.findViewById(R.id.more_options_layout);
|
showXmrchanSwitch = view.findViewById(R.id.show_xmrchan_switch)
|
||||||
showXmrchanSwitch = view.findViewById(R.id.show_xmrchan_switch);
|
xmrchanOnboardingImage = view.findViewById(R.id.xmrchan_onboarding_imageview)
|
||||||
xmrchanOnboardingImage = view.findViewById(R.id.xmrchan_onboarding_imageview);
|
seedTypeButton = view.findViewById(R.id.seed_type_button)
|
||||||
seedTypeButton = view.findViewById(R.id.seed_type_button);
|
seedTypeDescTextView = view.findViewById(R.id.seed_type_desc_textview)
|
||||||
seedTypeDescTextView = view.findViewById(R.id.seed_type_desc_textview);
|
bindListeners()
|
||||||
|
bindObservers()
|
||||||
bindListeners();
|
|
||||||
bindObservers();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindObservers() {
|
private fun bindObservers() {
|
||||||
mViewModel.showMoreOptions.observe(getViewLifecycleOwner(), show -> {
|
mViewModel?.showMoreOptions?.observe(viewLifecycleOwner) { show: Boolean ->
|
||||||
if (show) {
|
if (show) {
|
||||||
moreOptionsChevronImageView.setImageResource(R.drawable.ic_keyboard_arrow_up);
|
moreOptionsChevronImageView?.setImageResource(R.drawable.ic_keyboard_arrow_up)
|
||||||
advancedOptionsLayout.setVisibility(View.VISIBLE);
|
advancedOptionsLayout?.visibility = View.VISIBLE
|
||||||
} else {
|
} else {
|
||||||
moreOptionsChevronImageView.setImageResource(R.drawable.ic_keyboard_arrow_down);
|
moreOptionsChevronImageView?.setImageResource(R.drawable.ic_keyboard_arrow_down)
|
||||||
advancedOptionsLayout.setVisibility(View.GONE);
|
advancedOptionsLayout?.visibility = View.GONE
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
mViewModel?.enableCreateButton?.observe(viewLifecycleOwner) { enable: Boolean ->
|
||||||
mViewModel.enableCreateButton.observe(getViewLifecycleOwner(), enable -> {
|
createWalletButton?.isEnabled = enable
|
||||||
createWalletButton.setEnabled(enable);
|
}
|
||||||
});
|
mViewModel?.seedType?.observe(viewLifecycleOwner) { seedType: SeedType ->
|
||||||
|
seedTypeButton?.text = seedType.toString()
|
||||||
mViewModel.seedType.observe(getViewLifecycleOwner(), seedType -> {
|
seedTypeDescTextView?.text = getText(seedType.descResId)
|
||||||
seedTypeButton.setText(seedType.toString());
|
if (seedType == SeedType.LEGACY) {
|
||||||
seedTypeDescTextView.setText(getText(seedType.getDescResId()));
|
seedOffsetCheckbox?.visibility = View.VISIBLE
|
||||||
if (seedType == OnboardingViewModel.SeedType.LEGACY) {
|
walletRestoreHeightEditText?.visibility = View.VISIBLE
|
||||||
seedOffsetCheckbox.setVisibility(View.VISIBLE);
|
walletPasswordEditText?.hint = getString(R.string.password_optional)
|
||||||
walletRestoreHeightEditText.setVisibility(View.VISIBLE);
|
|
||||||
walletPasswordEditText.setHint(getString(R.string.password_optional));
|
|
||||||
} else {
|
} else {
|
||||||
seedOffsetCheckbox.setVisibility(View.GONE);
|
seedOffsetCheckbox?.visibility = View.GONE
|
||||||
walletRestoreHeightEditText.setVisibility(View.GONE);
|
walletRestoreHeightEditText?.visibility = View.GONE
|
||||||
walletPasswordEditText.setHint(getString(R.string.password_non_optional));
|
walletPasswordEditText?.hint = getString(R.string.password_non_optional)
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindListeners() {
|
private fun bindListeners() {
|
||||||
seedOffsetCheckbox.setChecked(useOffset);
|
seedOffsetCheckbox?.isChecked = useOffset
|
||||||
// Disable onBack click
|
// Disable onBack click
|
||||||
OnBackPressedCallback onBackPressedCallback = new OnBackPressedCallback(true) {
|
val onBackPressedCallback: OnBackPressedCallback = object : OnBackPressedCallback(true) {
|
||||||
@Override
|
override fun handleOnBackPressed() {}
|
||||||
public void handleOnBackPressed() {
|
}
|
||||||
}
|
val activity = activity
|
||||||
};
|
activity?.onBackPressedDispatcher?.addCallback(viewLifecycleOwner, onBackPressedCallback)
|
||||||
FragmentActivity activity = getActivity();
|
moreOptionsDropdownTextView?.setOnClickListener { mViewModel?.onMoreOptionsClicked() }
|
||||||
if (activity != null)
|
moreOptionsChevronImageView?.setOnClickListener { mViewModel?.onMoreOptionsClicked() }
|
||||||
activity.getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), onBackPressedCallback);
|
seedOffsetCheckbox?.setOnCheckedChangeListener { _: CompoundButton?, b: Boolean ->
|
||||||
|
useOffset = b
|
||||||
moreOptionsDropdownTextView.setOnClickListener(view12 -> mViewModel.onMoreOptionsClicked());
|
}
|
||||||
moreOptionsChevronImageView.setOnClickListener(view12 -> mViewModel.onMoreOptionsClicked());
|
createWalletButton?.setOnClickListener {
|
||||||
seedOffsetCheckbox.setOnCheckedChangeListener((compoundButton, b) -> useOffset = b);
|
prepareDefaultNode()
|
||||||
|
onBackPressedCallback.isEnabled = false
|
||||||
createWalletButton.setOnClickListener(view1 -> {
|
(getActivity()?.application as MoneroApplication).executor?.execute {
|
||||||
prepareDefaultNode();
|
|
||||||
onBackPressedCallback.setEnabled(false);
|
|
||||||
((MoneroApplication) getActivity().getApplication()).getExecutor().execute(() -> {
|
|
||||||
createOrImportWallet(
|
createOrImportWallet(
|
||||||
walletPasswordEditText.getText().toString(),
|
walletPasswordEditText?.text.toString(),
|
||||||
walletPasswordConfirmEditText.getText().toString(),
|
walletPasswordConfirmEditText?.text.toString(),
|
||||||
walletSeedEditText.getText().toString().trim(),
|
walletSeedEditText?.text.toString().trim { it <= ' ' },
|
||||||
walletRestoreHeightEditText.getText().toString().trim()
|
walletRestoreHeightEditText?.text.toString().trim { it <= ' ' }
|
||||||
);
|
)
|
||||||
});
|
|
||||||
});
|
|
||||||
walletPasswordEditText.addTextChangedListener(new TextWatcher() {
|
|
||||||
@Override
|
|
||||||
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@Override
|
walletPasswordEditText?.addTextChangedListener(object : TextWatcher {
|
||||||
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
|
||||||
}
|
override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
|
||||||
|
override fun afterTextChanged(editable: Editable) {
|
||||||
@Override
|
val text = editable.toString()
|
||||||
public void afterTextChanged(Editable editable) {
|
|
||||||
String text = editable.toString();
|
|
||||||
if (text.isEmpty()) {
|
if (text.isEmpty()) {
|
||||||
walletPasswordConfirmEditText.setText(null);
|
walletPasswordConfirmEditText?.text = null
|
||||||
walletPasswordConfirmEditText.setVisibility(View.GONE);
|
walletPasswordConfirmEditText?.visibility = View.GONE
|
||||||
} else {
|
} else {
|
||||||
walletPasswordConfirmEditText.setVisibility(View.VISIBLE);
|
walletPasswordConfirmEditText?.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
walletSeedEditText.addTextChangedListener(new TextWatcher() {
|
walletSeedEditText?.addTextChangedListener(object : TextWatcher {
|
||||||
@Override
|
override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
|
||||||
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
|
||||||
}
|
override fun afterTextChanged(editable: Editable) {
|
||||||
|
val text = editable.toString()
|
||||||
@Override
|
|
||||||
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterTextChanged(Editable editable) {
|
|
||||||
String text = editable.toString();
|
|
||||||
|
|
||||||
if (text.isEmpty()) {
|
if (text.isEmpty()) {
|
||||||
createWalletButton.setText(R.string.create_wallet);
|
createWalletButton?.setText(R.string.create_wallet)
|
||||||
} else {
|
} else {
|
||||||
createWalletButton.setText(R.string.menu_restore);
|
createWalletButton?.setText(R.string.menu_restore)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
seedTypeButton?.setOnClickListener { toggleSeedType() }
|
||||||
seedTypeButton.setOnClickListener(v -> toggleSeedType());
|
torSwitch?.setOnCheckedChangeListener { _: CompoundButton?, b: Boolean ->
|
||||||
|
PrefService.instance?.edit()?.putBoolean(Constants.PREF_USES_TOR, b)?.apply()
|
||||||
torSwitch.setOnCheckedChangeListener((compoundButton, b) -> {
|
removeProxyTextListeners()
|
||||||
PrefService.getInstance().edit().putBoolean(Constants.PREF_USES_TOR, b).apply();
|
|
||||||
removeProxyTextListeners();
|
|
||||||
if (b) {
|
if (b) {
|
||||||
if (PrefService.getInstance().hasProxySet()) {
|
if (PrefService.instance?.hasProxySet() == true) {
|
||||||
String proxyAddress = PrefService.getInstance().getProxyAddress();
|
val proxyAddress =
|
||||||
String proxyPort = PrefService.getInstance().getProxyPort();
|
PrefService.instance?.proxyAddress ?: return@setOnCheckedChangeListener
|
||||||
initProxyStuff(proxyAddress, proxyPort);
|
val proxyPort =
|
||||||
|
PrefService.instance?.proxyPort ?: return@setOnCheckedChangeListener
|
||||||
|
initProxyStuff(proxyAddress, proxyPort)
|
||||||
} else {
|
} else {
|
||||||
initProxyStuff("127.0.0.1", "9050");
|
initProxyStuff("127.0.0.1", "9050")
|
||||||
}
|
}
|
||||||
addProxyTextListeners();
|
addProxyTextListeners()
|
||||||
}
|
}
|
||||||
|
mViewModel?.updateProxy(getActivity()?.application as MoneroApplication)
|
||||||
mViewModel.updateProxy(((MoneroApplication) getActivity().getApplication()));
|
}
|
||||||
});
|
showXmrchanSwitch?.isChecked =
|
||||||
|
PrefService.instance?.getBoolean(Constants.PREF_MONEROCHAN, true) == true
|
||||||
showXmrchanSwitch.setChecked(PrefService.getInstance().getBoolean(Constants.PREF_MONEROCHAN, true));
|
showXmrchanSwitch?.setOnCheckedChangeListener { _: CompoundButton?, b: Boolean ->
|
||||||
showXmrchanSwitch.setOnCheckedChangeListener((compoundButton, b) -> {
|
PrefService.instance?.edit()?.putBoolean(Constants.PREF_MONEROCHAN, b)?.apply()
|
||||||
PrefService.getInstance().edit().putBoolean(Constants.PREF_MONEROCHAN, b).apply();
|
|
||||||
if (b) {
|
if (b) {
|
||||||
xmrchanOnboardingImage.setVisibility(View.VISIBLE);
|
xmrchanOnboardingImage?.visibility = View.VISIBLE
|
||||||
} else {
|
} else {
|
||||||
xmrchanOnboardingImage.setVisibility(View.GONE);
|
xmrchanOnboardingImage?.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val node = PrefService.instance?.node // should be using default here
|
||||||
|
selectNodeButton?.text = getString(R.string.node_button_text, node?.address)
|
||||||
|
selectNodeButton?.setOnClickListener {
|
||||||
|
activity?.supportFragmentManager?.let { fragmentManager ->
|
||||||
|
val dialog = NodeSelectionBottomSheetDialog()
|
||||||
|
dialog.listener = this
|
||||||
|
dialog.show(fragmentManager, "node_selection_dialog")
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
Node node = PrefService.getInstance().getNode(); // should be using default here
|
|
||||||
selectNodeButton.setText(getString(R.string.node_button_text, node.getAddress()));
|
|
||||||
selectNodeButton.setOnClickListener(view1 -> {
|
|
||||||
NodeSelectionBottomSheetDialog dialog = new NodeSelectionBottomSheetDialog();
|
|
||||||
dialog.listener = this;
|
|
||||||
dialog.show(getActivity().getSupportFragmentManager(), "node_selection_dialog");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void toggleSeedType() {
|
|
||||||
OnboardingViewModel.SeedType seedType = mViewModel.seedType.getValue();
|
|
||||||
if (seedType == null) return;
|
|
||||||
OnboardingViewModel.SeedType newSeedType = OnboardingViewModel.SeedType.UNKNOWN;
|
|
||||||
if (seedType == OnboardingViewModel.SeedType.POLYSEED) {
|
|
||||||
newSeedType = OnboardingViewModel.SeedType.LEGACY;
|
|
||||||
} else if (seedType == OnboardingViewModel.SeedType.LEGACY) {
|
|
||||||
newSeedType = OnboardingViewModel.SeedType.POLYSEED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mViewModel.setSeedType(newSeedType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prepareDefaultNode() {
|
private fun toggleSeedType() {
|
||||||
PrefService.getInstance().getNode();
|
val seedType = mViewModel?.seedType?.value ?: return
|
||||||
|
var newSeedType = SeedType.UNKNOWN
|
||||||
|
if (seedType == SeedType.POLYSEED) {
|
||||||
|
newSeedType = SeedType.LEGACY
|
||||||
|
} else if (seedType == SeedType.LEGACY) {
|
||||||
|
newSeedType = SeedType.POLYSEED
|
||||||
|
}
|
||||||
|
mViewModel?.setSeedType(newSeedType)
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createOrImportWallet(String walletPassword, String confirmedPassword, String walletSeed, String restoreHeightText) {
|
private fun prepareDefaultNode() {
|
||||||
Activity activity = getActivity();
|
PrefService.instance?.node
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createOrImportWallet(
|
||||||
|
walletPassword: String,
|
||||||
|
confirmedPassword: String,
|
||||||
|
walletSeed: String,
|
||||||
|
restoreHeightText: String
|
||||||
|
) {
|
||||||
|
val activity: Activity? = activity
|
||||||
if (activity != null) {
|
if (activity != null) {
|
||||||
mViewModel.createOrImportWallet(activity, walletPassword, confirmedPassword, walletSeed, restoreHeightText, useOffset);
|
mViewModel?.createOrImportWallet(
|
||||||
|
activity,
|
||||||
|
walletPassword,
|
||||||
|
confirmedPassword,
|
||||||
|
walletSeed,
|
||||||
|
restoreHeightText,
|
||||||
|
useOffset
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeProxyTextListeners() {
|
private fun removeProxyTextListeners() {
|
||||||
walletProxyAddressEditText.removeTextChangedListener(proxyAddressListener);
|
walletProxyAddressEditText?.removeTextChangedListener(proxyAddressListener)
|
||||||
walletProxyPortEditText.removeTextChangedListener(proxyPortListener);
|
walletProxyPortEditText?.removeTextChangedListener(proxyPortListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addProxyTextListeners() {
|
private fun addProxyTextListeners() {
|
||||||
walletProxyAddressEditText.addTextChangedListener(proxyAddressListener);
|
walletProxyAddressEditText?.addTextChangedListener(proxyAddressListener)
|
||||||
walletProxyPortEditText.addTextChangedListener(proxyPortListener);
|
walletProxyPortEditText?.addTextChangedListener(proxyPortListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initProxyStuff(String proxyAddress, String proxyPort) {
|
private fun initProxyStuff(proxyAddress: String, proxyPort: String) {
|
||||||
boolean validIpAddress = Patterns.IP_ADDRESS.matcher(proxyAddress).matches();
|
val validIpAddress = Patterns.IP_ADDRESS.matcher(proxyAddress).matches()
|
||||||
if (validIpAddress) {
|
if (validIpAddress) {
|
||||||
mViewModel.setProxyAddress(proxyAddress);
|
mViewModel?.setProxyAddress(proxyAddress)
|
||||||
mViewModel.setProxyPort(proxyPort);
|
mViewModel?.setProxyPort(proxyPort)
|
||||||
walletProxyAddressEditText.setText(proxyAddress);
|
walletProxyAddressEditText?.setText(proxyAddress)
|
||||||
walletProxyPortEditText.setText(proxyPort);
|
walletProxyPortEditText?.setText(proxyPort)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun onNodeSelected() {
|
||||||
public void onNodeSelected() {
|
val node = PrefService.instance?.node
|
||||||
Node node = PrefService.getInstance().getNode();
|
selectNodeButton?.text = getString(R.string.node_button_text, node?.address)
|
||||||
selectNodeButton.setText(getString(R.string.node_button_text, node.getAddress()));
|
mViewModel?.updateProxy(activity?.application as MoneroApplication)
|
||||||
mViewModel.updateProxy(((MoneroApplication) getActivity().getApplication()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun onClickedEditNode(node: Node?) {}
|
||||||
public void onClickedEditNode(Node node) {
|
override fun onClickedAddNode() {
|
||||||
|
activity?.supportFragmentManager?.let { fragmentManager ->
|
||||||
|
val addNodeDialog = AddNodeBottomSheetDialog()
|
||||||
|
addNodeDialog.listener = this
|
||||||
|
addNodeDialog.show(fragmentManager, "add_node_dialog")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun onNodeAdded() {
|
||||||
public void onClickedAddNode() {
|
activity?.supportFragmentManager?.let { fragmentManager ->
|
||||||
AddNodeBottomSheetDialog addNodeDialog = new AddNodeBottomSheetDialog();
|
val dialog = NodeSelectionBottomSheetDialog()
|
||||||
addNodeDialog.listener = this;
|
dialog.listener = this
|
||||||
addNodeDialog.show(getActivity().getSupportFragmentManager(), "add_node_dialog");
|
dialog.show(fragmentManager, "node_selection_dialog")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNodeAdded() {
|
|
||||||
NodeSelectionBottomSheetDialog dialog = new NodeSelectionBottomSheetDialog();
|
|
||||||
dialog.listener = this;
|
|
||||||
dialog.show(getActivity().getSupportFragmentManager(), "node_selection_dialog");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,179 +1,211 @@
|
||||||
package net.mynero.wallet.fragment.onboarding;
|
package net.mynero.wallet.fragment.onboarding
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity
|
||||||
import android.util.Patterns;
|
import android.util.Patterns
|
||||||
import android.widget.Toast;
|
import android.widget.Toast
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import net.mynero.wallet.MainActivity
|
||||||
|
import net.mynero.wallet.MoneroApplication
|
||||||
|
import net.mynero.wallet.R
|
||||||
|
import net.mynero.wallet.model.Wallet
|
||||||
|
import net.mynero.wallet.model.WalletManager
|
||||||
|
import net.mynero.wallet.service.PrefService
|
||||||
|
import net.mynero.wallet.util.Constants
|
||||||
|
import net.mynero.wallet.util.RestoreHeight
|
||||||
|
import java.io.File
|
||||||
|
import java.util.Calendar
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData;
|
class OnboardingViewModel : ViewModel() {
|
||||||
import androidx.lifecycle.MutableLiveData;
|
private val _showMoreOptions = MutableLiveData(false)
|
||||||
import androidx.lifecycle.ViewModel;
|
private val _enableCreateButton = MutableLiveData(true)
|
||||||
|
private val _seedType = MutableLiveData(SeedType.POLYSEED)
|
||||||
import net.mynero.wallet.MainActivity;
|
var showMoreOptions: LiveData<Boolean> = _showMoreOptions
|
||||||
import net.mynero.wallet.MoneroApplication;
|
var enableCreateButton: LiveData<Boolean> = _enableCreateButton
|
||||||
import net.mynero.wallet.R;
|
var seedType: LiveData<SeedType> = _seedType
|
||||||
import net.mynero.wallet.model.Wallet;
|
private var proxyAddress = ""
|
||||||
import net.mynero.wallet.model.WalletManager;
|
private var proxyPort = ""
|
||||||
import net.mynero.wallet.service.PrefService;
|
fun onMoreOptionsClicked() {
|
||||||
import net.mynero.wallet.util.Constants;
|
val currentValue = showMoreOptions.value ?: false
|
||||||
import net.mynero.wallet.util.RestoreHeight;
|
val newValue = !currentValue
|
||||||
|
_showMoreOptions.value = newValue
|
||||||
import java.io.File;
|
|
||||||
import java.util.Calendar;
|
|
||||||
|
|
||||||
public class OnboardingViewModel extends ViewModel {
|
|
||||||
private final MutableLiveData<Boolean> _showMoreOptions = new MutableLiveData<>(false);
|
|
||||||
private final MutableLiveData<Boolean> _enableCreateButton = new MutableLiveData<>(true);
|
|
||||||
private final MutableLiveData<SeedType> _seedType = new MutableLiveData<>(SeedType.POLYSEED);
|
|
||||||
public LiveData<Boolean> showMoreOptions = _showMoreOptions;
|
|
||||||
public LiveData<Boolean> enableCreateButton = _enableCreateButton;
|
|
||||||
public LiveData<SeedType> seedType = _seedType;
|
|
||||||
private String proxyAddress = "";
|
|
||||||
private String proxyPort = "";
|
|
||||||
|
|
||||||
public void onMoreOptionsClicked() {
|
|
||||||
boolean currentValue = showMoreOptions.getValue() != null ? showMoreOptions.getValue() : false;
|
|
||||||
boolean newValue = !currentValue;
|
|
||||||
_showMoreOptions.setValue(newValue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateProxy(MoneroApplication application) {
|
fun updateProxy(application: MoneroApplication) {
|
||||||
application.getExecutor().execute(() -> {
|
application.executor?.execute {
|
||||||
boolean usesProxy = PrefService.getInstance().getBoolean(Constants.PREF_USES_TOR, false);
|
val usesProxy = PrefService.instance?.getBoolean(Constants.PREF_USES_TOR, false) == true
|
||||||
|
|
||||||
if (!usesProxy) {
|
if (!usesProxy) {
|
||||||
return;
|
return@execute
|
||||||
}
|
}
|
||||||
|
if (proxyAddress.isEmpty()) proxyAddress = "127.0.0.1"
|
||||||
if (proxyAddress.isEmpty()) proxyAddress = "127.0.0.1";
|
if (proxyPort.isEmpty()) proxyPort = "9050"
|
||||||
if (proxyPort.isEmpty()) proxyPort = "9050";
|
val validIpAddress = Patterns.IP_ADDRESS.matcher(proxyAddress).matches()
|
||||||
boolean validIpAddress = Patterns.IP_ADDRESS.matcher(proxyAddress).matches();
|
|
||||||
|
|
||||||
if (validIpAddress) {
|
if (validIpAddress) {
|
||||||
String proxy = proxyAddress + ":" + proxyPort;
|
val proxy = "$proxyAddress:$proxyPort"
|
||||||
PrefService.getInstance().edit().putString(Constants.PREF_PROXY, proxy).apply();
|
PrefService.instance?.edit()?.putString(Constants.PREF_PROXY, proxy)?.apply()
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSeedType(SeedType seedType) {
|
fun setSeedType(seedType: SeedType?) {
|
||||||
this._seedType.setValue(seedType);
|
_seedType.value = seedType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setProxyAddress(address: String) {
|
||||||
public void setProxyAddress(String address) {
|
proxyAddress = address
|
||||||
this.proxyAddress = address;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setProxyPort(String port) {
|
fun setProxyPort(port: String) {
|
||||||
this.proxyPort = port;
|
proxyPort = port
|
||||||
}
|
}
|
||||||
|
|
||||||
public void createOrImportWallet(Activity mainActivity, String walletPassword, String confirmedPassword, String walletSeed, String restoreHeightText, boolean useOffset) {
|
fun createOrImportWallet(
|
||||||
MoneroApplication application = (MoneroApplication) mainActivity.getApplication();
|
mainActivity: Activity,
|
||||||
application.getExecutor().execute(() -> {
|
walletPassword: String,
|
||||||
_enableCreateButton.postValue(false);
|
confirmedPassword: String,
|
||||||
String offset = useOffset ? walletPassword : "";
|
walletSeed: String,
|
||||||
if (!walletPassword.isEmpty()) {
|
restoreHeightText: String,
|
||||||
if (!walletPassword.equals(confirmedPassword)) {
|
useOffset: Boolean
|
||||||
_enableCreateButton.postValue(true);
|
) {
|
||||||
mainActivity.runOnUiThread(() -> Toast.makeText(mainActivity, application.getString(R.string.invalid_confirmed_password), Toast.LENGTH_SHORT).show());
|
val application = mainActivity.application as MoneroApplication
|
||||||
return;
|
application.executor?.execute {
|
||||||
|
_enableCreateButton.postValue(false)
|
||||||
|
val offset = if (useOffset) walletPassword else ""
|
||||||
|
if (walletPassword.isNotEmpty()) {
|
||||||
|
if (walletPassword != confirmedPassword) {
|
||||||
|
_enableCreateButton.postValue(true)
|
||||||
|
mainActivity.runOnUiThread {
|
||||||
|
Toast.makeText(
|
||||||
|
mainActivity,
|
||||||
|
application.getString(R.string.invalid_confirmed_password),
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
return@execute
|
||||||
}
|
}
|
||||||
PrefService.getInstance().edit().putBoolean(Constants.PREF_USES_PASSWORD, true).apply();
|
PrefService.instance?.edit()?.putBoolean(Constants.PREF_USES_PASSWORD, true)
|
||||||
|
?.apply()
|
||||||
}
|
}
|
||||||
long restoreHeight = getNewRestoreHeight();
|
var restoreHeight = newRestoreHeight
|
||||||
File walletFile = new File(mainActivity.getApplicationInfo().dataDir, Constants.WALLET_NAME);
|
val walletFile = File(mainActivity.applicationInfo.dataDir, Constants.WALLET_NAME)
|
||||||
Wallet wallet = null;
|
var wallet: Wallet? = null
|
||||||
if (!offset.isEmpty()) {
|
if (offset.isNotEmpty()) {
|
||||||
PrefService.getInstance().edit().putBoolean(Constants.PREF_USES_OFFSET, true).apply();
|
PrefService.instance?.edit()?.putBoolean(Constants.PREF_USES_OFFSET, true)?.apply()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (walletSeed.isEmpty()) {
|
if (walletSeed.isEmpty()) {
|
||||||
SeedType seedTypeValue = seedType.getValue();
|
val seedTypeValue = seedType.value ?: return@execute
|
||||||
if (seedTypeValue == null) return;
|
|
||||||
|
|
||||||
if (seedTypeValue == SeedType.POLYSEED) {
|
if (seedTypeValue == SeedType.POLYSEED) {
|
||||||
if (offset.isEmpty()) {
|
wallet = if (offset.isEmpty()) {
|
||||||
mainActivity.runOnUiThread(() -> {
|
mainActivity.runOnUiThread {
|
||||||
_enableCreateButton.postValue(true);
|
_enableCreateButton.postValue(true)
|
||||||
Toast.makeText(mainActivity, application.getString(R.string.invalid_empty_passphrase), Toast.LENGTH_SHORT).show();
|
Toast.makeText(
|
||||||
});
|
mainActivity,
|
||||||
return;
|
application.getString(R.string.invalid_empty_passphrase),
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
return@execute
|
||||||
} else {
|
} else {
|
||||||
wallet = WalletManager.getInstance().createWalletPolyseed(walletFile, walletPassword, offset, Constants.MNEMONIC_LANGUAGE);
|
WalletManager.instance?.createWalletPolyseed(
|
||||||
|
walletFile,
|
||||||
|
walletPassword,
|
||||||
|
offset,
|
||||||
|
Constants.MNEMONIC_LANGUAGE
|
||||||
|
)
|
||||||
}
|
}
|
||||||
} else if (seedTypeValue == SeedType.LEGACY) {
|
} else if (seedTypeValue == SeedType.LEGACY) {
|
||||||
File tmpWalletFile = new File(mainActivity.getApplicationInfo().dataDir, Constants.WALLET_NAME + "_tmp");
|
val tmpWalletFile =
|
||||||
Wallet tmpWallet = createTempWallet(tmpWalletFile); //we do this to get seed, then recover wallet so we can use seed offset
|
File(mainActivity.applicationInfo.dataDir, Constants.WALLET_NAME + "_tmp")
|
||||||
wallet = WalletManager.getInstance().recoveryWallet(walletFile, walletPassword, tmpWallet.getSeed(""), offset, restoreHeight);
|
val tmpWallet =
|
||||||
tmpWalletFile.delete();
|
createTempWallet(tmpWalletFile) //we do this to get seed, then recover wallet so we can use seed offset
|
||||||
|
tmpWallet?.let {
|
||||||
|
wallet = WalletManager.instance?.recoveryWallet(
|
||||||
|
walletFile,
|
||||||
|
walletPassword,
|
||||||
|
tmpWallet.getSeed("") ?: return@let,
|
||||||
|
offset,
|
||||||
|
restoreHeight
|
||||||
|
)
|
||||||
|
tmpWalletFile.delete()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (getMnemonicType(walletSeed) == SeedType.UNKNOWN) {
|
if (getMnemonicType(walletSeed) == SeedType.UNKNOWN) {
|
||||||
mainActivity.runOnUiThread(() -> {
|
mainActivity.runOnUiThread {
|
||||||
_enableCreateButton.postValue(true);
|
_enableCreateButton.postValue(true)
|
||||||
Toast.makeText(mainActivity, application.getString(R.string.invalid_mnemonic_code), Toast.LENGTH_SHORT).show();
|
Toast.makeText(
|
||||||
});
|
mainActivity,
|
||||||
return;
|
application.getString(R.string.invalid_mnemonic_code),
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
return@execute
|
||||||
}
|
}
|
||||||
if (!restoreHeightText.isEmpty()) {
|
if (restoreHeightText.isNotEmpty()) {
|
||||||
restoreHeight = Long.parseLong(restoreHeightText);
|
restoreHeight = restoreHeightText.toLong()
|
||||||
}
|
}
|
||||||
wallet = WalletManager.getInstance().recoveryWallet(walletFile, walletPassword, walletSeed, offset, restoreHeight);
|
wallet = WalletManager.instance?.recoveryWallet(
|
||||||
|
walletFile,
|
||||||
|
walletPassword,
|
||||||
|
walletSeed,
|
||||||
|
offset,
|
||||||
|
restoreHeight
|
||||||
|
)
|
||||||
}
|
}
|
||||||
Wallet.Status walletStatus = wallet.getStatus();
|
val walletStatus = wallet?.status
|
||||||
wallet.close();
|
wallet?.close()
|
||||||
boolean ok = walletStatus.isOk();
|
val ok = walletStatus?.isOk
|
||||||
walletFile.delete(); // cache is broken for some reason when recovering wallets. delete the file here. this happens in monerujo too.
|
walletFile.delete() // cache is broken for some reason when recovering wallets. delete the file here. this happens in monerujo too.
|
||||||
|
if (ok == true) {
|
||||||
if (ok) {
|
(mainActivity as MainActivity).init(walletFile, walletPassword)
|
||||||
((MainActivity) mainActivity).init(walletFile, walletPassword);
|
mainActivity.runOnUiThread { mainActivity.onBackPressed() }
|
||||||
mainActivity.runOnUiThread(mainActivity::onBackPressed);
|
|
||||||
} else {
|
} else {
|
||||||
mainActivity.runOnUiThread(() -> {
|
mainActivity.runOnUiThread {
|
||||||
_enableCreateButton.postValue(true);
|
_enableCreateButton.postValue(true)
|
||||||
Toast.makeText(mainActivity, application.getString(R.string.create_wallet_failed, walletStatus.errorString), Toast.LENGTH_SHORT).show();
|
Toast.makeText(
|
||||||
});
|
mainActivity,
|
||||||
|
application.getString(
|
||||||
|
R.string.create_wallet_failed,
|
||||||
|
walletStatus?.errorString
|
||||||
|
),
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private long getNewRestoreHeight() {
|
private val newRestoreHeight: Long
|
||||||
Calendar restoreDate = Calendar.getInstance();
|
get() {
|
||||||
restoreDate.add(Calendar.DAY_OF_MONTH, 0);
|
val restoreDate = Calendar.getInstance()
|
||||||
return RestoreHeight.getInstance().getHeight(restoreDate.getTime());
|
restoreDate.add(Calendar.DAY_OF_MONTH, 0)
|
||||||
}
|
return RestoreHeight.instance?.getHeight(restoreDate.time) ?: 0
|
||||||
|
}
|
||||||
|
|
||||||
public SeedType getMnemonicType(String seed) {
|
private fun getMnemonicType(seed: String): SeedType {
|
||||||
String[] words = seed.split("\\s");
|
val words = seed.split("\\s".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
||||||
SeedType seedTypeValue = seedType.getValue();
|
val seedTypeValue = seedType.value ?: return SeedType.LEGACY
|
||||||
if (seedTypeValue == null) return SeedType.LEGACY;
|
return if (words.size == 16 && seedTypeValue == SeedType.POLYSEED) {
|
||||||
if (words.length == 16 && seedTypeValue == SeedType.POLYSEED) {
|
SeedType.POLYSEED
|
||||||
return SeedType.POLYSEED;
|
} else if (words.size == 25 && seedTypeValue == SeedType.LEGACY) {
|
||||||
} else if (words.length == 25 && seedTypeValue == SeedType.LEGACY) {
|
SeedType.LEGACY
|
||||||
return SeedType.LEGACY;
|
|
||||||
} else {
|
} else {
|
||||||
return SeedType.UNKNOWN;
|
SeedType.UNKNOWN
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Wallet createTempWallet(File tmpWalletFile) {
|
private fun createTempWallet(tmpWalletFile: File): Wallet? {
|
||||||
return WalletManager.getInstance().createWallet(tmpWalletFile, "", Constants.MNEMONIC_LANGUAGE, 0);
|
return WalletManager.instance?.createWallet(
|
||||||
|
tmpWalletFile,
|
||||||
|
"",
|
||||||
|
Constants.MNEMONIC_LANGUAGE,
|
||||||
|
0
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum SeedType {
|
enum class SeedType(val descResId: Int) {
|
||||||
LEGACY(R.string.seed_desc_legacy),
|
LEGACY(R.string.seed_desc_legacy), POLYSEED(R.string.seed_desc_polyseed), UNKNOWN(0)
|
||||||
POLYSEED(R.string.seed_desc_polyseed),
|
|
||||||
UNKNOWN(0);
|
|
||||||
|
|
||||||
private final int descResId;
|
|
||||||
|
|
||||||
SeedType(int descResId) {
|
|
||||||
this.descResId = descResId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getDescResId() {
|
|
||||||
return descResId;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -237,7 +237,10 @@ class SendFragment : Fragment() {
|
||||||
val address = if (destCount == 1) getAddressField(0).text.toString() else "Multiple"
|
val address = if (destCount == 1) getAddressField(0).text.toString() else "Multiple"
|
||||||
addressTextView?.text = getString(R.string.tx_address_text, address)
|
addressTextView?.text = getString(R.string.tx_address_text, address)
|
||||||
amountTextView?.text =
|
amountTextView?.text =
|
||||||
getString(R.string.tx_amount_text, Helper.getDisplayAmount(pendingTx.getAmount()))
|
getString(
|
||||||
|
R.string.tx_amount_text,
|
||||||
|
Helper.getDisplayAmount(pendingTx.getAmount())
|
||||||
|
)
|
||||||
feeTextView?.text =
|
feeTextView?.text =
|
||||||
getString(R.string.tx_fee_text, Helper.getDisplayAmount(pendingTx.getFee()))
|
getString(R.string.tx_fee_text, Helper.getDisplayAmount(pendingTx.getFee()))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,312 +1,291 @@
|
||||||
package net.mynero.wallet.fragment.settings;
|
package net.mynero.wallet.fragment.settings
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle
|
||||||
import android.text.Editable;
|
import android.text.Editable
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher
|
||||||
import android.util.Patterns;
|
import android.util.Patterns
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater
|
||||||
import android.view.View;
|
import android.view.View
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup
|
||||||
import android.widget.Button;
|
import android.widget.Button
|
||||||
import android.widget.EditText;
|
import android.widget.CompoundButton
|
||||||
import android.widget.TextView;
|
import android.widget.EditText
|
||||||
import android.widget.Toast;
|
import android.widget.TextView
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.appcompat.widget.SwitchCompat
|
||||||
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.navigation.fragment.NavHostFragment
|
||||||
|
import net.mynero.wallet.MoneroApplication
|
||||||
|
import net.mynero.wallet.R
|
||||||
|
import net.mynero.wallet.data.Node
|
||||||
|
import net.mynero.wallet.data.Node.Companion.fromJson
|
||||||
|
import net.mynero.wallet.fragment.dialog.AddNodeBottomSheetDialog
|
||||||
|
import net.mynero.wallet.fragment.dialog.AddNodeBottomSheetDialog.AddNodeListener
|
||||||
|
import net.mynero.wallet.fragment.dialog.EditNodeBottomSheetDialog
|
||||||
|
import net.mynero.wallet.fragment.dialog.EditNodeBottomSheetDialog.EditNodeListener
|
||||||
|
import net.mynero.wallet.fragment.dialog.NodeSelectionBottomSheetDialog
|
||||||
|
import net.mynero.wallet.fragment.dialog.NodeSelectionBottomSheetDialog.NodeSelectionDialogListener
|
||||||
|
import net.mynero.wallet.fragment.dialog.PasswordBottomSheetDialog
|
||||||
|
import net.mynero.wallet.fragment.dialog.PasswordBottomSheetDialog.PasswordListener
|
||||||
|
import net.mynero.wallet.fragment.dialog.WalletKeysBottomSheetDialog
|
||||||
|
import net.mynero.wallet.model.Wallet.ConnectionStatus
|
||||||
|
import net.mynero.wallet.model.WalletManager
|
||||||
|
import net.mynero.wallet.service.BalanceService
|
||||||
|
import net.mynero.wallet.service.BlockchainService
|
||||||
|
import net.mynero.wallet.service.HistoryService
|
||||||
|
import net.mynero.wallet.service.PrefService
|
||||||
|
import net.mynero.wallet.util.Constants
|
||||||
|
import org.json.JSONArray
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
class SettingsFragment : Fragment(), PasswordListener, NodeSelectionDialogListener, AddNodeListener,
|
||||||
import androidx.annotation.Nullable;
|
EditNodeListener {
|
||||||
import androidx.appcompat.widget.SwitchCompat;
|
private var mViewModel: SettingsViewModel? = null
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
private var proxyAddressListener: TextWatcher = object : TextWatcher {
|
||||||
import androidx.fragment.app.Fragment;
|
override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
|
||||||
import androidx.fragment.app.FragmentActivity;
|
override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
|
||||||
import androidx.fragment.app.FragmentManager;
|
override fun afterTextChanged(editable: Editable) {
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
|
||||||
import androidx.navigation.fragment.NavHostFragment;
|
|
||||||
|
|
||||||
import net.mynero.wallet.MoneroApplication;
|
|
||||||
import net.mynero.wallet.R;
|
|
||||||
import net.mynero.wallet.data.Node;
|
|
||||||
import net.mynero.wallet.fragment.dialog.AddNodeBottomSheetDialog;
|
|
||||||
import net.mynero.wallet.fragment.dialog.EditNodeBottomSheetDialog;
|
|
||||||
import net.mynero.wallet.fragment.dialog.NodeSelectionBottomSheetDialog;
|
|
||||||
import net.mynero.wallet.fragment.dialog.PasswordBottomSheetDialog;
|
|
||||||
import net.mynero.wallet.fragment.dialog.WalletKeysBottomSheetDialog;
|
|
||||||
import net.mynero.wallet.model.Wallet;
|
|
||||||
import net.mynero.wallet.model.WalletManager;
|
|
||||||
import net.mynero.wallet.service.BalanceService;
|
|
||||||
import net.mynero.wallet.service.BlockchainService;
|
|
||||||
import net.mynero.wallet.service.HistoryService;
|
|
||||||
import net.mynero.wallet.service.PrefService;
|
|
||||||
import net.mynero.wallet.util.Constants;
|
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
public class SettingsFragment extends Fragment implements PasswordBottomSheetDialog.PasswordListener, NodeSelectionBottomSheetDialog.NodeSelectionDialogListener, AddNodeBottomSheetDialog.AddNodeListener, EditNodeBottomSheetDialog.EditNodeListener {
|
|
||||||
|
|
||||||
private SettingsViewModel mViewModel;
|
|
||||||
TextWatcher proxyAddressListener = new TextWatcher() {
|
|
||||||
@Override
|
|
||||||
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterTextChanged(Editable editable) {
|
|
||||||
if (mViewModel != null) {
|
if (mViewModel != null) {
|
||||||
mViewModel.setProxyAddress(editable.toString());
|
mViewModel?.setProxyAddress(editable.toString())
|
||||||
mViewModel.updateProxy(((MoneroApplication) getActivity().getApplication()));
|
mViewModel?.updateProxy(activity?.application as MoneroApplication)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
TextWatcher proxyPortListener = new TextWatcher() {
|
private var proxyPortListener: TextWatcher = object : TextWatcher {
|
||||||
@Override
|
override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
|
||||||
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
|
||||||
}
|
override fun afterTextChanged(editable: Editable) {
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterTextChanged(Editable editable) {
|
|
||||||
if (mViewModel != null) {
|
if (mViewModel != null) {
|
||||||
mViewModel.setProxyPort(editable.toString());
|
mViewModel?.setProxyPort(editable.toString())
|
||||||
mViewModel.updateProxy(((MoneroApplication) getActivity().getApplication()));
|
mViewModel?.updateProxy(activity?.application as MoneroApplication)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
private EditText walletProxyAddressEditText;
|
private var walletProxyAddressEditText: EditText? = null
|
||||||
private EditText walletProxyPortEditText;
|
private var walletProxyPortEditText: EditText? = null
|
||||||
private Button selectNodeButton;
|
private var selectNodeButton: Button? = null
|
||||||
|
override fun onCreateView(
|
||||||
@Override
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
savedInstanceState: Bundle?
|
||||||
@Nullable Bundle savedInstanceState) {
|
): View? {
|
||||||
return inflater.inflate(R.layout.fragment_settings, container, false);
|
return inflater.inflate(R.layout.fragment_settings, container, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
super.onViewCreated(view, savedInstanceState)
|
||||||
super.onViewCreated(view, savedInstanceState);
|
mViewModel = ViewModelProvider(this)[SettingsViewModel::class.java]
|
||||||
mViewModel = new ViewModelProvider(this).get(SettingsViewModel.class);
|
val displaySeedButton = view.findViewById<Button>(R.id.display_seed_button)
|
||||||
Button displaySeedButton = view.findViewById(R.id.display_seed_button);
|
val displayUtxosButton = view.findViewById<Button>(R.id.display_utxos_button)
|
||||||
Button displayUtxosButton = view.findViewById(R.id.display_utxos_button);
|
selectNodeButton = view.findViewById(R.id.select_node_button)
|
||||||
|
val streetModeSwitch = view.findViewById<SwitchCompat>(R.id.street_mode_switch)
|
||||||
selectNodeButton = view.findViewById(R.id.select_node_button);
|
val monerochanSwitch = view.findViewById<SwitchCompat>(R.id.monerochan_switch)
|
||||||
SwitchCompat streetModeSwitch = view.findViewById(R.id.street_mode_switch);
|
val donationSwitch = view.findViewById<SwitchCompat>(R.id.donate_per_tx_switch)
|
||||||
SwitchCompat monerochanSwitch = view.findViewById(R.id.monerochan_switch);
|
val torSwitch = view.findViewById<SwitchCompat>(R.id.tor_switch)
|
||||||
SwitchCompat donationSwitch = view.findViewById(R.id.donate_per_tx_switch);
|
val proxySettingsLayout =
|
||||||
SwitchCompat torSwitch = view.findViewById(R.id.tor_switch);
|
view.findViewById<ConstraintLayout>(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);
|
walletProxyPortEditText = view.findViewById(R.id.wallet_proxy_port_edittext)
|
||||||
walletProxyPortEditText = view.findViewById(R.id.wallet_proxy_port_edittext);
|
streetModeSwitch.isChecked =
|
||||||
|
PrefService.instance?.getBoolean(Constants.PREF_STREET_MODE, false) == true
|
||||||
streetModeSwitch.setChecked(PrefService.getInstance().getBoolean(Constants.PREF_STREET_MODE, false));
|
streetModeSwitch.setOnCheckedChangeListener { _: CompoundButton?, b: Boolean ->
|
||||||
streetModeSwitch.setOnCheckedChangeListener((compoundButton, b) -> {
|
PrefService.instance?.edit()?.putBoolean(Constants.PREF_STREET_MODE, b)?.apply()
|
||||||
PrefService.getInstance().edit().putBoolean(Constants.PREF_STREET_MODE, b).apply();
|
BalanceService.instance?.refreshBalance()
|
||||||
BalanceService.instance.refreshBalance();
|
|
||||||
});
|
|
||||||
|
|
||||||
monerochanSwitch.setChecked(PrefService.getInstance().getBoolean(Constants.PREF_MONEROCHAN, true));
|
|
||||||
monerochanSwitch.setOnCheckedChangeListener((compoundButton, b) -> {
|
|
||||||
PrefService.getInstance().edit().putBoolean(Constants.PREF_MONEROCHAN, b).apply();
|
|
||||||
HistoryService.getInstance().refreshHistory();
|
|
||||||
});
|
|
||||||
|
|
||||||
donationSwitch.setChecked(PrefService.getInstance().getBoolean(Constants.PREF_DONATE_PER_TX, false));
|
|
||||||
donationSwitch.setOnCheckedChangeListener((compoundButton, b) -> PrefService.getInstance().edit().putBoolean(Constants.PREF_DONATE_PER_TX, b).apply());
|
|
||||||
|
|
||||||
PrefService prefService = PrefService.getInstance();
|
|
||||||
boolean usesProxy = prefService.getBoolean(Constants.PREF_USES_TOR, false);
|
|
||||||
if (prefService.hasProxySet()) {
|
|
||||||
String proxyAddress = prefService.getProxyAddress();
|
|
||||||
String proxyPort = prefService.getProxyPort();
|
|
||||||
initProxyStuff(proxyAddress, proxyPort);
|
|
||||||
}
|
}
|
||||||
torSwitch.setChecked(usesProxy);
|
monerochanSwitch.isChecked =
|
||||||
|
PrefService.instance?.getBoolean(Constants.PREF_MONEROCHAN, true) == true
|
||||||
|
monerochanSwitch.setOnCheckedChangeListener { _: CompoundButton?, b: Boolean ->
|
||||||
|
PrefService.instance?.edit()?.putBoolean(Constants.PREF_MONEROCHAN, b)?.apply()
|
||||||
|
HistoryService.instance?.refreshHistory()
|
||||||
|
}
|
||||||
|
donationSwitch.isChecked =
|
||||||
|
PrefService.instance?.getBoolean(Constants.PREF_DONATE_PER_TX, false) == true
|
||||||
|
donationSwitch.setOnCheckedChangeListener { _: CompoundButton?, b: Boolean ->
|
||||||
|
PrefService.instance?.edit()?.putBoolean(Constants.PREF_DONATE_PER_TX, b)?.apply()
|
||||||
|
}
|
||||||
|
val prefService = PrefService.instance
|
||||||
|
val usesProxy = prefService?.getBoolean(Constants.PREF_USES_TOR, false) == true
|
||||||
|
if (prefService?.hasProxySet() == true) {
|
||||||
|
val proxyAddress = prefService.proxyAddress
|
||||||
|
val proxyPort = prefService.proxyPort
|
||||||
|
initProxyStuff(proxyAddress, proxyPort)
|
||||||
|
}
|
||||||
|
torSwitch.isChecked = usesProxy
|
||||||
if (usesProxy) {
|
if (usesProxy) {
|
||||||
proxySettingsLayout.setVisibility(View.VISIBLE);
|
proxySettingsLayout.visibility = View.VISIBLE
|
||||||
} else {
|
} else {
|
||||||
proxySettingsLayout.setVisibility(View.GONE);
|
proxySettingsLayout.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
addProxyTextListeners()
|
||||||
addProxyTextListeners();
|
torSwitch.setOnCheckedChangeListener { _: CompoundButton?, b: Boolean ->
|
||||||
|
prefService?.edit()?.putBoolean(Constants.PREF_USES_TOR, b)?.apply()
|
||||||
torSwitch.setOnCheckedChangeListener((compoundButton, b) -> {
|
|
||||||
prefService.edit().putBoolean(Constants.PREF_USES_TOR, b).apply();
|
|
||||||
if (b) {
|
if (b) {
|
||||||
if (prefService.hasProxySet()) {
|
if (prefService?.hasProxySet() == true) {
|
||||||
removeProxyTextListeners();
|
removeProxyTextListeners()
|
||||||
|
val proxyAddress = prefService.proxyAddress
|
||||||
String proxyAddress = prefService.getProxyAddress();
|
val proxyPort = prefService.proxyPort
|
||||||
String proxyPort = prefService.getProxyPort();
|
initProxyStuff(proxyAddress, proxyPort)
|
||||||
initProxyStuff(proxyAddress, proxyPort);
|
addProxyTextListeners()
|
||||||
|
|
||||||
addProxyTextListeners();
|
|
||||||
}
|
}
|
||||||
proxySettingsLayout.setVisibility(View.VISIBLE);
|
proxySettingsLayout.visibility = View.VISIBLE
|
||||||
} else {
|
} else {
|
||||||
proxySettingsLayout.setVisibility(View.GONE);
|
proxySettingsLayout.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
mViewModel?.updateProxy(activity?.application as MoneroApplication)
|
||||||
mViewModel.updateProxy(((MoneroApplication) getActivity().getApplication()));
|
}
|
||||||
});
|
displaySeedButton.setOnClickListener {
|
||||||
|
val usesPassword =
|
||||||
displaySeedButton.setOnClickListener(view1 -> {
|
PrefService.instance?.getBoolean(Constants.PREF_USES_PASSWORD, false) == true
|
||||||
boolean usesPassword = PrefService.getInstance().getBoolean(Constants.PREF_USES_PASSWORD, false);
|
|
||||||
if (usesPassword) {
|
if (usesPassword) {
|
||||||
PasswordBottomSheetDialog passwordDialog = new PasswordBottomSheetDialog();
|
activity?.supportFragmentManager?.let { fragmentManager ->
|
||||||
passwordDialog.cancelable = true;
|
val passwordDialog = PasswordBottomSheetDialog()
|
||||||
passwordDialog.listener = this;
|
passwordDialog.cancelable = true
|
||||||
passwordDialog.show(getActivity().getSupportFragmentManager(), "password_dialog");
|
passwordDialog.listener = this
|
||||||
|
passwordDialog.show(fragmentManager, "password_dialog")
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
displaySeedDialog("");
|
displaySeedDialog("")
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
displayUtxosButton.setOnClickListener { navigate(R.id.nav_to_utxos) }
|
||||||
displayUtxosButton.setOnClickListener(view1 -> {
|
val statusTextView = view.findViewById<TextView>(R.id.status_textview)
|
||||||
navigate(R.id.nav_to_utxos);
|
BlockchainService.instance?.connectionStatus?.observe(viewLifecycleOwner) { connectionStatus: ConnectionStatus ->
|
||||||
});
|
if (connectionStatus === ConnectionStatus.ConnectionStatus_Connected) {
|
||||||
|
statusTextView.text = resources.getText(R.string.connected)
|
||||||
TextView statusTextView = view.findViewById(R.id.status_textview);
|
} else if (connectionStatus === ConnectionStatus.ConnectionStatus_Disconnected) {
|
||||||
BlockchainService.instance.connectionStatus.observe(getViewLifecycleOwner(), connectionStatus -> {
|
statusTextView.text = resources.getText(R.string.disconnected)
|
||||||
if (connectionStatus == Wallet.ConnectionStatus.ConnectionStatus_Connected) {
|
} else if (connectionStatus === ConnectionStatus.ConnectionStatus_WrongVersion) {
|
||||||
statusTextView.setText(getResources().getText(R.string.connected));
|
statusTextView.text = resources.getText(R.string.version_mismatch)
|
||||||
} else if (connectionStatus == Wallet.ConnectionStatus.ConnectionStatus_Disconnected) {
|
|
||||||
statusTextView.setText(getResources().getText(R.string.disconnected));
|
|
||||||
} else if (connectionStatus == Wallet.ConnectionStatus.ConnectionStatus_WrongVersion) {
|
|
||||||
statusTextView.setText(getResources().getText(R.string.version_mismatch));
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
Node node = PrefService.getInstance().getNode(); // shouldn't use default value here
|
val node = PrefService.instance?.node // shouldn't use default value here
|
||||||
selectNodeButton.setText(getString(R.string.node_button_text, node.getAddress()));
|
selectNodeButton?.text = getString(R.string.node_button_text, node?.address)
|
||||||
selectNodeButton.setOnClickListener(view1 -> {
|
selectNodeButton?.setOnClickListener {
|
||||||
NodeSelectionBottomSheetDialog dialog = new NodeSelectionBottomSheetDialog();
|
activity?.supportFragmentManager?.let { fragmentManager ->
|
||||||
dialog.listener = this;
|
val dialog = NodeSelectionBottomSheetDialog()
|
||||||
dialog.show(getActivity().getSupportFragmentManager(), "node_selection_dialog");
|
dialog.listener = this
|
||||||
});
|
dialog.show(fragmentManager, "node_selection_dialog")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void displaySeedDialog(String password) {
|
private fun displaySeedDialog(password: String) {
|
||||||
WalletKeysBottomSheetDialog informationDialog = new WalletKeysBottomSheetDialog();
|
activity?.supportFragmentManager?.let { fragmentManager ->
|
||||||
informationDialog.password = password;
|
val informationDialog = WalletKeysBottomSheetDialog()
|
||||||
informationDialog.show(getActivity().getSupportFragmentManager(), "information_seed_dialog");
|
informationDialog.password = password
|
||||||
|
informationDialog.show(fragmentManager, "information_seed_dialog")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun onPasswordSuccess(password: String) {
|
||||||
public void onPasswordSuccess(String password) {
|
displaySeedDialog(password)
|
||||||
displaySeedDialog(password);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun onPasswordFail() {
|
||||||
public void onPasswordFail() {
|
Toast.makeText(context, R.string.bad_password, Toast.LENGTH_SHORT).show()
|
||||||
Toast.makeText(getContext(), R.string.bad_password, Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initProxyStuff(String proxyAddress, String proxyPort) {
|
private fun initProxyStuff(proxyAddress: String, proxyPort: String) {
|
||||||
boolean validIpAddress = Patterns.IP_ADDRESS.matcher(proxyAddress).matches();
|
val validIpAddress = Patterns.IP_ADDRESS.matcher(proxyAddress).matches()
|
||||||
if (validIpAddress) {
|
if (validIpAddress) {
|
||||||
mViewModel.setProxyAddress(proxyAddress);
|
mViewModel?.setProxyAddress(proxyAddress)
|
||||||
mViewModel.setProxyPort(proxyPort);
|
mViewModel?.setProxyPort(proxyPort)
|
||||||
walletProxyAddressEditText.setText(proxyAddress);
|
walletProxyAddressEditText?.setText(proxyAddress)
|
||||||
walletProxyPortEditText.setText(proxyPort);
|
walletProxyPortEditText?.setText(proxyPort)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeProxyTextListeners() {
|
private fun removeProxyTextListeners() {
|
||||||
walletProxyAddressEditText.removeTextChangedListener(proxyAddressListener);
|
walletProxyAddressEditText?.removeTextChangedListener(proxyAddressListener)
|
||||||
walletProxyPortEditText.removeTextChangedListener(proxyPortListener);
|
walletProxyPortEditText?.removeTextChangedListener(proxyPortListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addProxyTextListeners() {
|
private fun addProxyTextListeners() {
|
||||||
walletProxyAddressEditText.addTextChangedListener(proxyAddressListener);
|
walletProxyAddressEditText?.addTextChangedListener(proxyAddressListener)
|
||||||
walletProxyPortEditText.addTextChangedListener(proxyPortListener);
|
walletProxyPortEditText?.addTextChangedListener(proxyPortListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun onNodeSelected() {
|
||||||
public void onNodeSelected() {
|
val node = PrefService.instance?.node
|
||||||
Node node = PrefService.getInstance().getNode();
|
selectNodeButton?.text = getString(R.string.node_button_text, node?.address)
|
||||||
selectNodeButton.setText(getString(R.string.node_button_text, node.getAddress()));
|
mViewModel?.updateProxy(activity?.application as MoneroApplication)
|
||||||
mViewModel.updateProxy(((MoneroApplication) getActivity().getApplication()));
|
(activity?.application as MoneroApplication).executor?.execute {
|
||||||
((MoneroApplication) getActivity().getApplication()).getExecutor().execute(() -> {
|
WalletManager.instance?.wallet?.init(0)
|
||||||
WalletManager.getInstance().getWallet().init(0);
|
WalletManager.instance?.wallet?.startRefresh()
|
||||||
WalletManager.getInstance().getWallet().startRefresh();
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun onClickedAddNode() {
|
||||||
public void onClickedAddNode() {
|
activity?.supportFragmentManager?.let { fragmentManager ->
|
||||||
AddNodeBottomSheetDialog addNodeDialog = new AddNodeBottomSheetDialog();
|
val addNodeDialog = AddNodeBottomSheetDialog()
|
||||||
addNodeDialog.listener = this;
|
addNodeDialog.listener = this
|
||||||
addNodeDialog.show(getActivity().getSupportFragmentManager(), "add_node_dialog");
|
addNodeDialog.show(fragmentManager, "add_node_dialog")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun onClickedEditNode(node: Node?) {
|
||||||
public void onClickedEditNode(Node node) {
|
activity?.supportFragmentManager?.let { fragmentManager ->
|
||||||
EditNodeBottomSheetDialog editNodeDialog = new EditNodeBottomSheetDialog();
|
val editNodeDialog = EditNodeBottomSheetDialog()
|
||||||
editNodeDialog.listener = this;
|
editNodeDialog.listener = this
|
||||||
editNodeDialog.node = node;
|
editNodeDialog.node = node
|
||||||
editNodeDialog.show(getActivity().getSupportFragmentManager(), "edit_node_dialog");
|
editNodeDialog.show(fragmentManager, "edit_node_dialog")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun onNodeAdded() {
|
||||||
public void onNodeAdded() {
|
activity?.supportFragmentManager?.let { fragmentManager ->
|
||||||
NodeSelectionBottomSheetDialog dialog = new NodeSelectionBottomSheetDialog();
|
val dialog = NodeSelectionBottomSheetDialog()
|
||||||
dialog.listener = this;
|
dialog.listener = this
|
||||||
dialog.show(getActivity().getSupportFragmentManager(), "node_selection_dialog");
|
dialog.show(fragmentManager, "node_selection_dialog")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void navigate(int destination) {
|
private fun navigate(destination: Int) {
|
||||||
FragmentActivity activity = getActivity();
|
val activity = activity
|
||||||
if (activity != null) {
|
if (activity != null) {
|
||||||
FragmentManager fm = activity.getSupportFragmentManager();
|
val fm = activity.supportFragmentManager
|
||||||
NavHostFragment navHostFragment =
|
val navHostFragment = fm.findFragmentById(R.id.nav_host_fragment) as NavHostFragment?
|
||||||
(NavHostFragment) fm.findFragmentById(R.id.nav_host_fragment);
|
navHostFragment?.navController?.navigate(destination)
|
||||||
if (navHostFragment != null) {
|
|
||||||
navHostFragment.getNavController().navigate(destination);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun onNodeDeleted(node: Node?) {
|
||||||
public void onNodeDeleted(Node node) {
|
|
||||||
try {
|
try {
|
||||||
String nodesArray = PrefService.getInstance().getString(Constants.PREF_CUSTOM_NODES, "[]");
|
val nodesArray = PrefService.instance?.getString(Constants.PREF_CUSTOM_NODES, "[]")
|
||||||
JSONArray jsonArray = new JSONArray(nodesArray);
|
val jsonArray = JSONArray(nodesArray)
|
||||||
for (int i = 0; i < jsonArray.length(); i++) {
|
for (i in 0 until jsonArray.length()) {
|
||||||
JSONObject nodeJsonObject = jsonArray.getJSONObject(i);
|
val nodeJsonObject = jsonArray.getJSONObject(i)
|
||||||
Node savedNode = Node.fromJson(nodeJsonObject);
|
val savedNode = fromJson(nodeJsonObject)
|
||||||
if (savedNode.toNodeString().equals(node.toNodeString()))
|
if (savedNode?.toNodeString() == node?.toNodeString()) jsonArray.remove(i)
|
||||||
jsonArray.remove(i);
|
|
||||||
}
|
}
|
||||||
saveNodesAndReopen(jsonArray);
|
saveNodesAndReopen(jsonArray)
|
||||||
} catch (Exception e) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace();
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun onNodeEdited(oldNode: Node?, newNode: Node?) {
|
||||||
public void onNodeEdited(Node oldNode, Node newNode) {
|
|
||||||
try {
|
try {
|
||||||
String nodesArray = PrefService.getInstance().getString(Constants.PREF_CUSTOM_NODES, "[]");
|
val nodesArray = PrefService.instance?.getString(Constants.PREF_CUSTOM_NODES, "[]")
|
||||||
JSONArray jsonArray = new JSONArray(nodesArray);
|
val jsonArray = JSONArray(nodesArray)
|
||||||
for (int i = 0; i < jsonArray.length(); i++) {
|
for (i in 0 until jsonArray.length()) {
|
||||||
JSONObject nodeJsonObject = jsonArray.getJSONObject(i);
|
val nodeJsonObject = jsonArray.getJSONObject(i)
|
||||||
Node savedNode = Node.fromJson(nodeJsonObject);
|
val savedNode = fromJson(nodeJsonObject)
|
||||||
if (savedNode.toNodeString().equals(oldNode.toNodeString()))
|
if (savedNode?.toNodeString() == oldNode?.toNodeString()) jsonArray.put(
|
||||||
jsonArray.put(i, newNode.toJson());
|
i,
|
||||||
|
newNode?.toJson()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
saveNodesAndReopen(jsonArray);
|
saveNodesAndReopen(jsonArray)
|
||||||
} catch (Exception e) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace();
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveNodesAndReopen(JSONArray jsonArray) {
|
private fun saveNodesAndReopen(jsonArray: JSONArray) {
|
||||||
PrefService.getInstance().edit().putString(Constants.PREF_CUSTOM_NODES, jsonArray.toString()).apply();
|
PrefService.instance?.edit()?.putString(Constants.PREF_CUSTOM_NODES, jsonArray.toString())
|
||||||
onNodeAdded();
|
?.apply()
|
||||||
|
onNodeAdded()
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,50 +1,43 @@
|
||||||
package net.mynero.wallet.fragment.settings;
|
package net.mynero.wallet.fragment.settings
|
||||||
|
|
||||||
import android.util.Patterns;
|
import android.util.Patterns
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.ViewModel;
|
import net.mynero.wallet.MoneroApplication
|
||||||
|
import net.mynero.wallet.model.WalletManager
|
||||||
import net.mynero.wallet.MoneroApplication;
|
import net.mynero.wallet.service.PrefService
|
||||||
import net.mynero.wallet.data.Node;
|
import net.mynero.wallet.util.Constants
|
||||||
import net.mynero.wallet.model.WalletManager;
|
|
||||||
import net.mynero.wallet.service.PrefService;
|
|
||||||
import net.mynero.wallet.util.Constants;
|
|
||||||
|
|
||||||
public class SettingsViewModel extends ViewModel {
|
|
||||||
|
|
||||||
private String proxyAddress = "";
|
|
||||||
private String proxyPort = "";
|
|
||||||
|
|
||||||
public void updateProxy(MoneroApplication application) {
|
|
||||||
application.getExecutor().execute(() -> {
|
|
||||||
boolean usesProxy = PrefService.getInstance().getBoolean(Constants.PREF_USES_TOR, false);
|
|
||||||
Node curretNode = PrefService.getInstance().getNode();
|
|
||||||
boolean isNodeLocalIp = curretNode.getAddress().startsWith("10.") || curretNode.getAddress().startsWith("192.168.") || curretNode.getAddress().equals("localhost") || curretNode.getAddress().equals("127.0.0.1");
|
|
||||||
|
|
||||||
|
class SettingsViewModel : ViewModel() {
|
||||||
|
private var proxyAddress = ""
|
||||||
|
private var proxyPort = ""
|
||||||
|
fun updateProxy(application: MoneroApplication) {
|
||||||
|
application.executor?.execute {
|
||||||
|
val usesProxy = PrefService.instance?.getBoolean(Constants.PREF_USES_TOR, false) == true
|
||||||
|
val curretNode = PrefService.instance?.node
|
||||||
|
val isNodeLocalIp =
|
||||||
|
curretNode?.address?.startsWith("10.") == true || curretNode?.address?.startsWith("192.168.") == true || curretNode?.address == "localhost" || curretNode?.address == "127.0.0.1"
|
||||||
if (!usesProxy || isNodeLocalIp) {
|
if (!usesProxy || isNodeLocalIp) {
|
||||||
WalletManager.getInstance().setProxy("");
|
WalletManager.instance?.setProxy("")
|
||||||
WalletManager.getInstance().getWallet().setProxy("");
|
WalletManager.instance?.wallet?.setProxy("")
|
||||||
return;
|
return@execute
|
||||||
}
|
}
|
||||||
|
if (proxyAddress.isEmpty()) proxyAddress = "127.0.0.1"
|
||||||
if (proxyAddress.isEmpty()) proxyAddress = "127.0.0.1";
|
if (proxyPort.isEmpty()) proxyPort = "9050"
|
||||||
if (proxyPort.isEmpty()) proxyPort = "9050";
|
val validIpAddress = Patterns.IP_ADDRESS.matcher(proxyAddress).matches()
|
||||||
boolean validIpAddress = Patterns.IP_ADDRESS.matcher(proxyAddress).matches();
|
|
||||||
|
|
||||||
if (validIpAddress) {
|
if (validIpAddress) {
|
||||||
String proxy = proxyAddress + ":" + proxyPort;
|
val proxy = "$proxyAddress:$proxyPort"
|
||||||
PrefService.getInstance().edit().putString(Constants.PREF_PROXY, proxy).apply();
|
PrefService.instance?.edit()?.putString(Constants.PREF_PROXY, proxy)?.apply()
|
||||||
WalletManager.getInstance().setProxy(proxy);
|
WalletManager.instance?.setProxy(proxy)
|
||||||
WalletManager.getInstance().getWallet().setProxy(proxy);
|
WalletManager.instance?.wallet?.setProxy(proxy)
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setProxyAddress(String address) {
|
fun setProxyAddress(address: String) {
|
||||||
this.proxyAddress = address;
|
proxyAddress = address
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setProxyPort(String port) {
|
fun setProxyPort(port: String) {
|
||||||
this.proxyPort = port;
|
proxyPort = port
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,162 +1,167 @@
|
||||||
package net.mynero.wallet.fragment.transaction;
|
package net.mynero.wallet.fragment.transaction
|
||||||
|
|
||||||
import static net.mynero.wallet.util.DateHelper.DATETIME_FORMATTER;
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.ImageButton
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import net.mynero.wallet.R
|
||||||
|
import net.mynero.wallet.model.TransactionInfo
|
||||||
|
import net.mynero.wallet.model.WalletManager
|
||||||
|
import net.mynero.wallet.service.HistoryService
|
||||||
|
import net.mynero.wallet.service.PrefService
|
||||||
|
import net.mynero.wallet.util.Constants
|
||||||
|
import net.mynero.wallet.util.DateHelper
|
||||||
|
import net.mynero.wallet.util.Helper
|
||||||
|
import java.util.Calendar
|
||||||
|
import java.util.Date
|
||||||
|
import java.util.Objects
|
||||||
|
|
||||||
import android.content.Context;
|
class TransactionFragment : Fragment() {
|
||||||
import android.os.Bundle;
|
private var mViewModel: TransactionViewModel? = null
|
||||||
import android.view.LayoutInflater;
|
private var transactionInfo: TransactionInfo? = null
|
||||||
import android.view.View;
|
override fun onCreateView(
|
||||||
import android.view.ViewGroup;
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
import android.widget.ImageButton;
|
savedInstanceState: Bundle?
|
||||||
import android.widget.TextView;
|
): View? {
|
||||||
|
return inflater.inflate(R.layout.fragment_transaction, container, false)
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.core.content.ContextCompat;
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
|
||||||
|
|
||||||
import net.mynero.wallet.R;
|
|
||||||
import net.mynero.wallet.model.TransactionInfo;
|
|
||||||
import net.mynero.wallet.model.Wallet;
|
|
||||||
import net.mynero.wallet.model.WalletManager;
|
|
||||||
import net.mynero.wallet.service.HistoryService;
|
|
||||||
import net.mynero.wallet.service.PrefService;
|
|
||||||
import net.mynero.wallet.util.Constants;
|
|
||||||
import net.mynero.wallet.util.Helper;
|
|
||||||
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.TimeZone;
|
|
||||||
|
|
||||||
public class TransactionFragment extends Fragment {
|
|
||||||
|
|
||||||
private TransactionViewModel mViewModel;
|
|
||||||
private TransactionInfo transactionInfo = null;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
|
||||||
@Nullable Bundle savedInstanceState) {
|
|
||||||
return inflater.inflate(R.layout.fragment_transaction, container, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
super.onViewCreated(view, savedInstanceState)
|
||||||
super.onViewCreated(view, savedInstanceState);
|
val cal = Calendar.getInstance()
|
||||||
Calendar cal = Calendar.getInstance();
|
val tz = cal.timeZone //get the local time zone.
|
||||||
TimeZone tz = cal.getTimeZone(); //get the local time zone.
|
DateHelper.DATETIME_FORMATTER.timeZone = tz
|
||||||
DATETIME_FORMATTER.setTimeZone(tz);
|
mViewModel = ViewModelProvider(this)[TransactionViewModel::class.java]
|
||||||
|
val args = arguments
|
||||||
mViewModel = new ViewModelProvider(this).get(TransactionViewModel.class);
|
|
||||||
Bundle args = getArguments();
|
|
||||||
if (args != null) {
|
if (args != null) {
|
||||||
this.transactionInfo = getArguments().getParcelable(Constants.NAV_ARG_TXINFO);
|
transactionInfo = arguments?.getParcelable(Constants.NAV_ARG_TXINFO)
|
||||||
}
|
}
|
||||||
|
bindObservers(view)
|
||||||
bindObservers(view);
|
bindListeners(view)
|
||||||
bindListeners(view);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindListeners(View view) {
|
private fun bindListeners(view: View) {
|
||||||
ImageButton copyTxHashImageButton = view.findViewById(R.id.copy_txhash_imagebutton);
|
val copyTxHashImageButton = view.findViewById<ImageButton>(R.id.copy_txhash_imagebutton)
|
||||||
copyTxHashImageButton.setOnClickListener(view1 -> {
|
copyTxHashImageButton.setOnClickListener {
|
||||||
TransactionInfo txInfo = this.transactionInfo;
|
val txInfo = transactionInfo
|
||||||
if (txInfo != null) {
|
if (txInfo != null) {
|
||||||
Helper.clipBoardCopy(getContext(), "transaction_hash", txInfo.hash);
|
Helper.clipBoardCopy(context, "transaction_hash", txInfo.hash)
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
val copyTxAddressImageButton =
|
||||||
ImageButton copyTxAddressImageButton = view.findViewById(R.id.copy_txaddress_imagebutton);
|
view.findViewById<ImageButton>(R.id.copy_txaddress_imagebutton)
|
||||||
TextView addressTextView = view.findViewById(R.id.transaction_address_textview);
|
val addressTextView = view.findViewById<TextView>(R.id.transaction_address_textview)
|
||||||
copyTxAddressImageButton.setOnClickListener(view1 -> {
|
copyTxAddressImageButton.setOnClickListener {
|
||||||
TransactionInfo txInfo = this.transactionInfo;
|
val txInfo = transactionInfo
|
||||||
if (txInfo != null) {
|
if (txInfo != null) {
|
||||||
String destination = addressTextView.getText().toString();
|
val destination = addressTextView.text.toString()
|
||||||
Helper.clipBoardCopy(getContext(), "transaction_address", destination);
|
Helper.clipBoardCopy(context, "transaction_address", destination)
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindObservers(View view) {
|
private fun bindObservers(view: View) {
|
||||||
TextView txActionTextView = view.findViewById(R.id.transaction_action_textview);
|
val txActionTextView = view.findViewById<TextView>(R.id.transaction_action_textview)
|
||||||
TextView confLabel2 = view.findViewById(R.id.transaction_conf_label2_textview);
|
val confLabel2 = view.findViewById<TextView>(R.id.transaction_conf_label2_textview)
|
||||||
TextView txHashTextView = view.findViewById(R.id.transaction_hash_textview);
|
val txHashTextView = view.findViewById<TextView>(R.id.transaction_hash_textview)
|
||||||
TextView txConfTextView = view.findViewById(R.id.transaction_conf_textview);
|
val txConfTextView = view.findViewById<TextView>(R.id.transaction_conf_textview)
|
||||||
TextView txAddressTextView = view.findViewById(R.id.transaction_address_textview);
|
val txAddressTextView = view.findViewById<TextView>(R.id.transaction_address_textview)
|
||||||
ImageButton copyTxAddressImageButton = view.findViewById(R.id.copy_txaddress_imagebutton);
|
val copyTxAddressImageButton =
|
||||||
TextView txDateTextView = view.findViewById(R.id.transaction_date_textview);
|
view.findViewById<ImageButton>(R.id.copy_txaddress_imagebutton)
|
||||||
TextView txAmountTextView = view.findViewById(R.id.transaction_amount_textview);
|
val txDateTextView = view.findViewById<TextView>(R.id.transaction_date_textview)
|
||||||
TextView blockHeightTextView = view.findViewById(R.id.tx_block_height_textview);
|
val txAmountTextView = view.findViewById<TextView>(R.id.transaction_amount_textview)
|
||||||
|
val blockHeightTextView = view.findViewById<TextView>(R.id.tx_block_height_textview)
|
||||||
HistoryService.getInstance().history.observe(getViewLifecycleOwner(), transactionInfos -> {
|
HistoryService.instance?.history?.observe(viewLifecycleOwner) { transactionInfos: List<TransactionInfo> ->
|
||||||
TransactionInfo newTransactionInfo = findNewestVersionOfTransaction(this.transactionInfo, transactionInfos);
|
val newTransactionInfo = findNewestVersionOfTransaction(
|
||||||
if (newTransactionInfo == null) return;
|
transactionInfo, transactionInfos
|
||||||
|
)
|
||||||
txHashTextView.setText(newTransactionInfo.hash);
|
?: return@observe
|
||||||
txConfTextView.setText("" + newTransactionInfo.confirmations);
|
txHashTextView.text = newTransactionInfo.hash
|
||||||
txDateTextView.setText(getDateTime(newTransactionInfo.timestamp));
|
txConfTextView.text = "${newTransactionInfo.confirmations}"
|
||||||
|
txDateTextView.text = getDateTime(newTransactionInfo.timestamp)
|
||||||
if (newTransactionInfo.confirmations > 1) {
|
if (newTransactionInfo.confirmations > 1) {
|
||||||
confLabel2.setText(getString(R.string.transaction_conf_desc2_confirmed));
|
confLabel2.text = getString(R.string.transaction_conf_desc2_confirmed)
|
||||||
blockHeightTextView.setText("" + newTransactionInfo.blockheight);
|
blockHeightTextView.text = "${newTransactionInfo.blockheight}"
|
||||||
blockHeightTextView.setVisibility(View.VISIBLE);
|
blockHeightTextView.visibility = View.VISIBLE
|
||||||
} else if (newTransactionInfo.confirmations == 1) {
|
} else if (newTransactionInfo.confirmations == 1L) {
|
||||||
confLabel2.setText(getString(R.string.transaction_conf_1_desc2_confirmed));
|
confLabel2.text = getString(R.string.transaction_conf_1_desc2_confirmed)
|
||||||
blockHeightTextView.setText("" + newTransactionInfo.blockheight);
|
blockHeightTextView.text = "${newTransactionInfo.blockheight}"
|
||||||
blockHeightTextView.setVisibility(View.VISIBLE);
|
blockHeightTextView.visibility = View.VISIBLE
|
||||||
} else {
|
} else {
|
||||||
blockHeightTextView.setVisibility(View.GONE);
|
blockHeightTextView.visibility = View.GONE
|
||||||
confLabel2.setText(getString(R.string.transaction_conf_desc2_unconfirmed));
|
confLabel2.text = getString(R.string.transaction_conf_desc2_unconfirmed)
|
||||||
}
|
}
|
||||||
|
val ctx = context
|
||||||
Context ctx = getContext();
|
|
||||||
if (ctx != null) {
|
if (ctx != null) {
|
||||||
boolean streetModeEnabled = PrefService.getInstance().getBoolean(Constants.PREF_STREET_MODE, false);
|
val streetModeEnabled =
|
||||||
String balanceString = streetModeEnabled ? Constants.STREET_MODE_BALANCE : Helper.getDisplayAmount(newTransactionInfo.amount, 12);
|
PrefService.instance?.getBoolean(Constants.PREF_STREET_MODE, false) == true
|
||||||
if (newTransactionInfo.direction == TransactionInfo.Direction.Direction_In) {
|
val balanceString =
|
||||||
txActionTextView.setText(getString(R.string.transaction_action_recv));
|
if (streetModeEnabled) Constants.STREET_MODE_BALANCE else Helper.getDisplayAmount(
|
||||||
txAmountTextView.setTextColor(ContextCompat.getColor(ctx, R.color.oled_positiveColor));
|
newTransactionInfo.amount,
|
||||||
|
12
|
||||||
|
)
|
||||||
|
if (newTransactionInfo.direction === TransactionInfo.Direction.Direction_In) {
|
||||||
|
txActionTextView.text = getString(R.string.transaction_action_recv)
|
||||||
|
txAmountTextView.setTextColor(
|
||||||
|
ContextCompat.getColor(
|
||||||
|
ctx,
|
||||||
|
R.color.oled_positiveColor
|
||||||
|
)
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
txActionTextView.setText(getString(R.string.transaction_action_sent));
|
txActionTextView.text = getString(R.string.transaction_action_sent)
|
||||||
txAmountTextView.setTextColor(ContextCompat.getColor(ctx, R.color.oled_negativeColor));
|
txAmountTextView.setTextColor(
|
||||||
|
ContextCompat.getColor(
|
||||||
|
ctx,
|
||||||
|
R.color.oled_negativeColor
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
txAmountTextView.setText(balanceString);
|
txAmountTextView.text = balanceString
|
||||||
}
|
}
|
||||||
|
var destination: String? = "-"
|
||||||
String destination = "-";
|
val wallet = WalletManager.instance?.wallet
|
||||||
Wallet wallet = WalletManager.getInstance().getWallet();
|
|
||||||
if (newTransactionInfo.txKey == null) {
|
if (newTransactionInfo.txKey == null) {
|
||||||
newTransactionInfo.txKey = wallet.getTxKey(newTransactionInfo.hash);
|
newTransactionInfo.txKey = wallet?.getTxKey(newTransactionInfo.hash)
|
||||||
}
|
}
|
||||||
if (newTransactionInfo.address == null && newTransactionInfo.direction == TransactionInfo.Direction.Direction_In) {
|
if (newTransactionInfo.address == null && newTransactionInfo.direction === TransactionInfo.Direction.Direction_In) {
|
||||||
destination = wallet.getSubaddress(newTransactionInfo.accountIndex, newTransactionInfo.addressIndex);
|
destination = wallet?.getSubaddress(
|
||||||
} else if (newTransactionInfo.address != null && newTransactionInfo.direction == TransactionInfo.Direction.Direction_In) {
|
newTransactionInfo.accountIndex,
|
||||||
destination = newTransactionInfo.address;
|
newTransactionInfo.addressIndex
|
||||||
} else if (newTransactionInfo.transfers != null && newTransactionInfo.direction == TransactionInfo.Direction.Direction_Out) {
|
)
|
||||||
if (newTransactionInfo.transfers.size() == 1) {
|
} else if (newTransactionInfo.address != null && newTransactionInfo.direction === TransactionInfo.Direction.Direction_In) {
|
||||||
destination = newTransactionInfo.transfers.get(0).address;
|
destination = newTransactionInfo.address
|
||||||
|
} else if (newTransactionInfo.transfers != null && newTransactionInfo.direction === TransactionInfo.Direction.Direction_Out) {
|
||||||
|
if (newTransactionInfo.transfers?.size == 1) {
|
||||||
|
destination = newTransactionInfo.transfers?.get(0)?.address
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
txAddressTextView.text = Objects.requireNonNullElse(destination, "-")
|
||||||
txAddressTextView.setText(Objects.requireNonNullElse(destination, "-"));
|
|
||||||
if (destination == null) {
|
if (destination == null) {
|
||||||
copyTxAddressImageButton.setVisibility(View.INVISIBLE);
|
copyTxAddressImageButton.visibility = View.INVISIBLE
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private TransactionInfo findNewestVersionOfTransaction(TransactionInfo oldTransactionInfo, List<TransactionInfo> transactionInfoList) {
|
|
||||||
for (TransactionInfo transactionInfo : transactionInfoList) {
|
|
||||||
if (transactionInfo.hash.equals(oldTransactionInfo.hash)) {
|
|
||||||
this.transactionInfo = transactionInfo;
|
|
||||||
return this.transactionInfo;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getDateTime(long time) {
|
private fun findNewestVersionOfTransaction(
|
||||||
return DATETIME_FORMATTER.format(new Date(time * 1000));
|
oldTransactionInfo: TransactionInfo?,
|
||||||
|
transactionInfoList: List<TransactionInfo>
|
||||||
|
): TransactionInfo? {
|
||||||
|
for (transactionInfo in transactionInfoList) {
|
||||||
|
if (transactionInfo.hash == oldTransactionInfo?.hash) {
|
||||||
|
this.transactionInfo = transactionInfo
|
||||||
|
return this.transactionInfo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getDateTime(time: Long): String {
|
||||||
|
return DateHelper.DATETIME_FORMATTER.format(Date(time * 1000))
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
package net.mynero.wallet.fragment.transaction;
|
package net.mynero.wallet.fragment.transaction
|
||||||
|
|
||||||
import androidx.lifecycle.ViewModel;
|
import androidx.lifecycle.ViewModel
|
||||||
|
|
||||||
public class TransactionViewModel extends ViewModel {
|
class TransactionViewModel : ViewModel()
|
||||||
}
|
|
|
@ -1,170 +1,166 @@
|
||||||
package net.mynero.wallet.fragment.utxos;
|
package net.mynero.wallet.fragment.utxos
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater
|
||||||
import android.view.View;
|
import android.view.View
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup
|
||||||
import android.widget.Button;
|
import android.widget.Button
|
||||||
import android.widget.Toast;
|
import android.widget.Toast
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import net.mynero.wallet.R
|
||||||
|
import net.mynero.wallet.adapter.CoinsInfoAdapter
|
||||||
|
import net.mynero.wallet.adapter.CoinsInfoAdapter.CoinsInfoAdapterListener
|
||||||
|
import net.mynero.wallet.fragment.dialog.SendBottomSheetDialog
|
||||||
|
import net.mynero.wallet.model.CoinsInfo
|
||||||
|
import net.mynero.wallet.service.AddressService
|
||||||
|
import net.mynero.wallet.service.UTXOService
|
||||||
|
import net.mynero.wallet.util.MoneroThreadPoolExecutor
|
||||||
|
import net.mynero.wallet.util.UriData
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
class UtxosFragment : Fragment(), CoinsInfoAdapterListener, SendBottomSheetDialog.Listener {
|
||||||
import androidx.annotation.Nullable;
|
private val adapter = CoinsInfoAdapter(this)
|
||||||
import androidx.fragment.app.Fragment;
|
private var mViewModel: UtxosViewModel? = null
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
private var sendUtxosButton: Button? = null
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
private var churnUtxosButton: Button? = null
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
private var freezeUtxosButton: Button? = null
|
||||||
|
override fun onCreateView(
|
||||||
import net.mynero.wallet.R;
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
import net.mynero.wallet.adapter.CoinsInfoAdapter;
|
savedInstanceState: Bundle?
|
||||||
import net.mynero.wallet.fragment.dialog.SendBottomSheetDialog;
|
): View? {
|
||||||
import net.mynero.wallet.model.CoinsInfo;
|
return inflater.inflate(R.layout.fragment_utxos, container, false)
|
||||||
import net.mynero.wallet.service.AddressService;
|
|
||||||
import net.mynero.wallet.service.UTXOService;
|
|
||||||
import net.mynero.wallet.util.MoneroThreadPoolExecutor;
|
|
||||||
import net.mynero.wallet.util.UriData;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
public class UtxosFragment extends Fragment implements CoinsInfoAdapter.CoinsInfoAdapterListener, SendBottomSheetDialog.Listener {
|
|
||||||
|
|
||||||
private final CoinsInfoAdapter adapter = new CoinsInfoAdapter(this);
|
|
||||||
private UtxosViewModel mViewModel;
|
|
||||||
private Button sendUtxosButton;
|
|
||||||
private Button churnUtxosButton;
|
|
||||||
private Button freezeUtxosButton;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
|
||||||
@Nullable Bundle savedInstanceState) {
|
|
||||||
return inflater.inflate(R.layout.fragment_utxos, container, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
super.onViewCreated(view, savedInstanceState)
|
||||||
super.onViewCreated(view, savedInstanceState);
|
mViewModel = ViewModelProvider(this)[UtxosViewModel::class.java]
|
||||||
mViewModel = new ViewModelProvider(this).get(UtxosViewModel.class);
|
bindListeners(view)
|
||||||
bindListeners(view);
|
bindObservers(view)
|
||||||
bindObservers(view);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindListeners(View view) {
|
private fun bindListeners(view: View) {
|
||||||
freezeUtxosButton = view.findViewById(R.id.freeze_utxos_button);
|
freezeUtxosButton = view.findViewById(R.id.freeze_utxos_button)
|
||||||
sendUtxosButton = view.findViewById(R.id.send_utxos_button);
|
sendUtxosButton = view.findViewById(R.id.send_utxos_button)
|
||||||
churnUtxosButton = view.findViewById(R.id.churn_utxos_button);
|
churnUtxosButton = view.findViewById(R.id.churn_utxos_button)
|
||||||
sendUtxosButton.setVisibility(View.GONE);
|
sendUtxosButton?.visibility = View.GONE
|
||||||
churnUtxosButton.setVisibility(View.GONE);
|
churnUtxosButton?.visibility = View.GONE
|
||||||
freezeUtxosButton.setVisibility(View.GONE);
|
freezeUtxosButton?.visibility = View.GONE
|
||||||
freezeUtxosButton.setOnClickListener(view1 -> {
|
freezeUtxosButton?.setOnClickListener {
|
||||||
Toast.makeText(getContext(), "Toggling freeze status, please wait.", Toast.LENGTH_SHORT).show();
|
Toast.makeText(context, "Toggling freeze status, please wait.", Toast.LENGTH_SHORT)
|
||||||
MoneroThreadPoolExecutor.MONERO_THREAD_POOL_EXECUTOR.execute(() -> {
|
.show()
|
||||||
UTXOService.getInstance().toggleFrozen(adapter.selectedUtxos);
|
MoneroThreadPoolExecutor.MONERO_THREAD_POOL_EXECUTOR?.execute {
|
||||||
getActivity().runOnUiThread(() -> {
|
UTXOService.instance?.toggleFrozen(adapter.selectedUtxos)
|
||||||
adapter.clear();
|
activity?.runOnUiThread {
|
||||||
sendUtxosButton.setVisibility(View.GONE);
|
adapter.clear()
|
||||||
churnUtxosButton.setVisibility(View.GONE);
|
sendUtxosButton?.visibility = View.GONE
|
||||||
freezeUtxosButton.setVisibility(View.GONE);
|
churnUtxosButton?.visibility = View.GONE
|
||||||
});
|
freezeUtxosButton?.visibility = View.GONE
|
||||||
});
|
}
|
||||||
});
|
|
||||||
sendUtxosButton.setOnClickListener(view1 -> {
|
|
||||||
ArrayList<String> selectedKeyImages = new ArrayList<>();
|
|
||||||
for (CoinsInfo coinsInfo : adapter.selectedUtxos.values()) {
|
|
||||||
selectedKeyImages.add(coinsInfo.getKeyImage());
|
|
||||||
}
|
}
|
||||||
SendBottomSheetDialog sendDialog = new SendBottomSheetDialog();
|
}
|
||||||
sendDialog.listener = this;
|
sendUtxosButton?.setOnClickListener {
|
||||||
sendDialog.selectedUtxos = selectedKeyImages;
|
val selectedKeyImages = ArrayList<String>()
|
||||||
sendDialog.show(getActivity().getSupportFragmentManager(), null);
|
for (coinsInfo in adapter.selectedUtxos.values) {
|
||||||
});
|
coinsInfo.keyImage?.let { keyImage -> selectedKeyImages.add(keyImage) }
|
||||||
churnUtxosButton.setOnClickListener(view1 -> {
|
}
|
||||||
ArrayList<String> selectedKeyImages = new ArrayList<>();
|
activity?.supportFragmentManager?.let { fragmentManager ->
|
||||||
for (CoinsInfo coinsInfo : adapter.selectedUtxos.values()) {
|
val sendDialog = SendBottomSheetDialog()
|
||||||
selectedKeyImages.add(coinsInfo.getKeyImage());
|
sendDialog.listener = this
|
||||||
|
sendDialog.selectedUtxos = selectedKeyImages
|
||||||
|
sendDialog.show(fragmentManager, null)
|
||||||
}
|
}
|
||||||
SendBottomSheetDialog sendDialog = new SendBottomSheetDialog();
|
|
||||||
sendDialog.listener = this;
|
|
||||||
sendDialog.isChurning = true;
|
|
||||||
sendDialog.uriData = UriData.parse(AddressService.instance.currentSubaddress().address);
|
|
||||||
sendDialog.selectedUtxos = selectedKeyImages;
|
|
||||||
sendDialog.show(getActivity().getSupportFragmentManager(), null);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void bindObservers(View view) {
|
}
|
||||||
RecyclerView utxosRecyclerView = view.findViewById(R.id.transaction_history_recyclerview);
|
churnUtxosButton?.setOnClickListener {
|
||||||
UTXOService utxoService = UTXOService.getInstance();
|
val selectedKeyImages = ArrayList<String>()
|
||||||
utxosRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
|
for (coinsInfo in adapter.selectedUtxos.values) {
|
||||||
utxosRecyclerView.setAdapter(adapter);
|
coinsInfo.keyImage?.let { keyImage -> selectedKeyImages.add(keyImage) }
|
||||||
if (utxoService != null) {
|
}
|
||||||
utxoService.utxos.observe(getViewLifecycleOwner(), utxos -> {
|
activity?.supportFragmentManager?.let { fragmentManager ->
|
||||||
HashMap<String, CoinsInfo> filteredUtxos = new HashMap<>();
|
val sendDialog = SendBottomSheetDialog()
|
||||||
for (CoinsInfo coinsInfo : utxos) {
|
sendDialog.listener = this
|
||||||
if (!coinsInfo.isSpent()) {
|
sendDialog.isChurning = true
|
||||||
filteredUtxos.put(coinsInfo.getPubKey(), coinsInfo);
|
sendDialog.uriData =
|
||||||
|
AddressService.instance?.currentSubaddress()?.address?.let { address ->
|
||||||
|
UriData.parse(address)
|
||||||
}
|
}
|
||||||
}
|
sendDialog.selectedUtxos = selectedKeyImages
|
||||||
if (filteredUtxos.isEmpty()) {
|
sendDialog.show(fragmentManager, null)
|
||||||
utxosRecyclerView.setVisibility(View.GONE);
|
}
|
||||||
} else {
|
|
||||||
adapter.submitList(filteredUtxos);
|
|
||||||
utxosRecyclerView.setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private fun bindObservers(view: View) {
|
||||||
public void onUtxoSelected(CoinsInfo coinsInfo) {
|
val utxosRecyclerView =
|
||||||
boolean selected = adapter.contains(coinsInfo);
|
view.findViewById<RecyclerView>(R.id.transaction_history_recyclerview)
|
||||||
if (selected) {
|
val utxoService = UTXOService.instance
|
||||||
adapter.deselectUtxo(coinsInfo);
|
utxosRecyclerView.layoutManager = LinearLayoutManager(activity)
|
||||||
} else {
|
utxosRecyclerView.adapter = adapter
|
||||||
adapter.selectUtxo(coinsInfo);
|
utxoService?.utxos?.observe(viewLifecycleOwner) { utxos: List<CoinsInfo> ->
|
||||||
}
|
val filteredUtxos = HashMap<String?, CoinsInfo>()
|
||||||
|
for (coinsInfo in utxos) {
|
||||||
boolean frozenExists = false, unfrozenExists = false, bothExist = false;
|
if (!coinsInfo.isSpent) {
|
||||||
for (CoinsInfo selectedUtxo : adapter.selectedUtxos.values()) {
|
filteredUtxos[coinsInfo.pubKey] = coinsInfo
|
||||||
if (selectedUtxo.isFrozen() || UTXOService.getInstance().isCoinFrozen(selectedUtxo))
|
}
|
||||||
frozenExists = true;
|
}
|
||||||
else {
|
if (filteredUtxos.isEmpty()) {
|
||||||
unfrozenExists = true;
|
utxosRecyclerView.visibility = View.GONE
|
||||||
|
} else {
|
||||||
|
adapter.submitList(filteredUtxos)
|
||||||
|
utxosRecyclerView.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bothExist = frozenExists && unfrozenExists;
|
}
|
||||||
|
|
||||||
|
override fun onUtxoSelected(coinsInfo: CoinsInfo) {
|
||||||
|
val selected = adapter.contains(coinsInfo)
|
||||||
|
if (selected) {
|
||||||
|
adapter.deselectUtxo(coinsInfo)
|
||||||
|
} else {
|
||||||
|
adapter.selectUtxo(coinsInfo)
|
||||||
|
}
|
||||||
|
var frozenExists = false
|
||||||
|
var unfrozenExists = false
|
||||||
|
for (selectedUtxo in adapter.selectedUtxos.values) {
|
||||||
|
if (selectedUtxo.isFrozen || UTXOService.instance?.isCoinFrozen(selectedUtxo) == true)
|
||||||
|
frozenExists = true
|
||||||
|
else {
|
||||||
|
unfrozenExists = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val bothExist: Boolean = frozenExists && unfrozenExists
|
||||||
if (adapter.selectedUtxos.isEmpty()) {
|
if (adapter.selectedUtxos.isEmpty()) {
|
||||||
sendUtxosButton.setVisibility(View.GONE);
|
sendUtxosButton?.visibility = View.GONE
|
||||||
churnUtxosButton.setVisibility(View.GONE);
|
churnUtxosButton?.visibility = View.GONE
|
||||||
freezeUtxosButton.setVisibility(View.GONE);
|
freezeUtxosButton?.visibility = View.GONE
|
||||||
freezeUtxosButton.setBackgroundResource(R.drawable.button_bg_left);
|
freezeUtxosButton?.setBackgroundResource(R.drawable.button_bg_left)
|
||||||
} else {
|
} else {
|
||||||
if (frozenExists) {
|
if (frozenExists) {
|
||||||
freezeUtxosButton.setBackgroundResource(R.drawable.button_bg);
|
freezeUtxosButton?.setBackgroundResource(R.drawable.button_bg)
|
||||||
sendUtxosButton.setVisibility(View.GONE);
|
sendUtxosButton?.visibility = View.GONE
|
||||||
churnUtxosButton.setVisibility(View.GONE);
|
churnUtxosButton?.visibility = View.GONE
|
||||||
} else {
|
} else {
|
||||||
freezeUtxosButton.setBackgroundResource(R.drawable.button_bg_left);
|
freezeUtxosButton?.setBackgroundResource(R.drawable.button_bg_left)
|
||||||
sendUtxosButton.setVisibility(View.VISIBLE);
|
sendUtxosButton?.visibility = View.VISIBLE
|
||||||
churnUtxosButton.setVisibility(View.VISIBLE);
|
churnUtxosButton?.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
freezeUtxosButton.setVisibility(View.VISIBLE);
|
freezeUtxosButton?.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bothExist) {
|
if (bothExist) {
|
||||||
freezeUtxosButton.setText(R.string.toggle_freeze);
|
freezeUtxosButton?.setText(R.string.toggle_freeze)
|
||||||
} else if (frozenExists) {
|
} else if (frozenExists) {
|
||||||
freezeUtxosButton.setText(R.string.unfreeze);
|
freezeUtxosButton?.setText(R.string.unfreeze)
|
||||||
} else if (unfrozenExists) {
|
} else if (unfrozenExists) {
|
||||||
freezeUtxosButton.setText(R.string.freeze);
|
freezeUtxosButton?.setText(R.string.freeze)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun onSentTransaction() {
|
||||||
public void onSentTransaction() {
|
adapter.clear()
|
||||||
adapter.clear();
|
churnUtxosButton?.visibility = View.GONE
|
||||||
churnUtxosButton.setVisibility(View.GONE);
|
sendUtxosButton?.visibility = View.GONE
|
||||||
sendUtxosButton.setVisibility(View.GONE);
|
freezeUtxosButton?.visibility = View.GONE
|
||||||
freezeUtxosButton.setVisibility(View.GONE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,7 +1,5 @@
|
||||||
package net.mynero.wallet.fragment.utxos;
|
package net.mynero.wallet.fragment.utxos
|
||||||
|
|
||||||
import androidx.lifecycle.ViewModel;
|
import androidx.lifecycle.ViewModel
|
||||||
|
|
||||||
public class UtxosViewModel extends ViewModel {
|
class UtxosViewModel : ViewModel()
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in a new issue