From a1c43db4db3216583492d0cff0c09f2f305c94ab Mon Sep 17 00:00:00 2001 From: pokkst Date: Wed, 6 Dec 2023 17:48:45 -0600 Subject: [PATCH] Convert remaining screens to Kotlin --- .../java/net/mynero/wallet/MainActivity.kt | 4 +- .../mynero/wallet/adapter/CoinsInfoAdapter.kt | 10 +- .../wallet/adapter/SubaddressAdapter.kt | 4 +- .../wallet/adapter/TransactionInfoAdapter.kt | 4 +- .../dialog/WalletKeysBottomSheetDialog.kt | 12 +- .../wallet/fragment/home/HomeFragment.kt | 5 +- .../fragment/onboarding/OnboardingFragment.kt | 503 +++++++++--------- .../onboarding/OnboardingViewModel.kt | 302 ++++++----- .../wallet/fragment/send/SendFragment.kt | 5 +- .../fragment/settings/SettingsFragment.kt | 479 ++++++++--------- .../fragment/settings/SettingsViewModel.kt | 69 ++- .../transaction/TransactionFragment.kt | 265 ++++----- .../transaction/TransactionViewModel.kt | 7 +- .../wallet/fragment/utxos/UtxosFragment.kt | 276 +++++----- .../wallet/fragment/utxos/UtxosViewModel.kt | 8 +- 15 files changed, 965 insertions(+), 988 deletions(-) diff --git a/app/src/main/java/net/mynero/wallet/MainActivity.kt b/app/src/main/java/net/mynero/wallet/MainActivity.kt index 596e9e0..d78c1a7 100644 --- a/app/src/main/java/net/mynero/wallet/MainActivity.kt +++ b/app/src/main/java/net/mynero/wallet/MainActivity.kt @@ -40,8 +40,8 @@ class MainActivity : AppCompatActivity(), MoneroHandlerThread.Listener, Password val walletKeysFile = File(applicationInfo.dataDir, Constants.WALLET_NAME + ".keys") if (walletKeysFile.exists()) { val promptPassword = - PrefService.instance?.getBoolean(Constants.PREF_USES_PASSWORD, false) - if (promptPassword == false) { + PrefService.instance?.getBoolean(Constants.PREF_USES_PASSWORD, false) == true + if (!promptPassword) { init(walletFile, "") } else { val passwordDialog = PasswordBottomSheetDialog() diff --git a/app/src/main/java/net/mynero/wallet/adapter/CoinsInfoAdapter.kt b/app/src/main/java/net/mynero/wallet/adapter/CoinsInfoAdapter.kt index afc088d..134a66b 100644 --- a/app/src/main/java/net/mynero/wallet/adapter/CoinsInfoAdapter.kt +++ b/app/src/main/java/net/mynero/wallet/adapter/CoinsInfoAdapter.kt @@ -96,7 +96,7 @@ class CoinsInfoAdapter(val listener: CoinsInfoAdapterListener?) : } interface CoinsInfoAdapterListener { - fun onUtxoSelected(coinsInfo: CoinsInfo?) + fun onUtxoSelected(coinsInfo: CoinsInfo) } /** @@ -127,9 +127,9 @@ class CoinsInfoAdapter(val listener: CoinsInfoAdapterListener?) : val globalIdxTextView = itemView.findViewById(R.id.utxo_global_index_textview) val outpointTextView = itemView.findViewById(R.id.utxo_outpoint_textview) val streetModeEnabled = - PrefService.instance?.getBoolean(Constants.PREF_STREET_MODE, false) + PrefService.instance?.getBoolean(Constants.PREF_STREET_MODE, false) == true val balanceString = - if (streetModeEnabled == true) Constants.STREET_MODE_BALANCE else Wallet.getDisplayAmount( + if (streetModeEnabled) Constants.STREET_MODE_BALANCE else Wallet.getDisplayAmount( coinsInfo.amount ) amountTextView.text = @@ -167,7 +167,7 @@ class CoinsInfoAdapter(val listener: CoinsInfoAdapterListener?) : if (!editing) return val unlocked = coinsInfo?.isUnlocked == true if (unlocked) { - listener?.onUtxoSelected(coinsInfo) + coinsInfo?.let { listener?.onUtxoSelected(it) } } } @@ -175,7 +175,7 @@ class CoinsInfoAdapter(val listener: CoinsInfoAdapterListener?) : if (editing) return false val unlocked = coinsInfo?.isUnlocked == true if (unlocked) { - listener?.onUtxoSelected(coinsInfo) + coinsInfo?.let { listener?.onUtxoSelected(it) } } return unlocked } diff --git a/app/src/main/java/net/mynero/wallet/adapter/SubaddressAdapter.kt b/app/src/main/java/net/mynero/wallet/adapter/SubaddressAdapter.kt index 433a47a..cd0acb3 100644 --- a/app/src/main/java/net/mynero/wallet/adapter/SubaddressAdapter.kt +++ b/app/src/main/java/net/mynero/wallet/adapter/SubaddressAdapter.kt @@ -91,8 +91,8 @@ class SubaddressAdapter(val listener: SubaddressAdapterListener?) : val amount = subaddress.amount if (amount > 0) { val streetMode = - PrefService.instance?.getBoolean(Constants.PREF_STREET_MODE, false) - if (streetMode == true) { + PrefService.instance?.getBoolean(Constants.PREF_STREET_MODE, false) == true + if (streetMode) { addressAmountTextView.text = itemView.context.getString( R.string.tx_list_amount_positive, Constants.STREET_MODE_BALANCE diff --git a/app/src/main/java/net/mynero/wallet/adapter/TransactionInfoAdapter.kt b/app/src/main/java/net/mynero/wallet/adapter/TransactionInfoAdapter.kt index e927523..03d9b09 100644 --- a/app/src/main/java/net/mynero/wallet/adapter/TransactionInfoAdapter.kt +++ b/app/src/main/java/net/mynero/wallet/adapter/TransactionInfoAdapter.kt @@ -94,9 +94,9 @@ class TransactionInfoAdapter(val listener: TxInfoAdapterListener?) : fun bind(txInfo: TransactionInfo) { val streetModeEnabled = - PrefService.instance?.getBoolean(Constants.PREF_STREET_MODE, false) + PrefService.instance?.getBoolean(Constants.PREF_STREET_MODE, false) == true val displayAmount = - if (streetModeEnabled == true) Constants.STREET_MODE_BALANCE else Helper.getDisplayAmount( + if (streetModeEnabled) Constants.STREET_MODE_BALANCE else Helper.getDisplayAmount( txInfo.amount, Helper.DISPLAY_DIGITS_INFO ) diff --git a/app/src/main/java/net/mynero/wallet/fragment/dialog/WalletKeysBottomSheetDialog.kt b/app/src/main/java/net/mynero/wallet/fragment/dialog/WalletKeysBottomSheetDialog.kt index 059b8de..0571aef 100644 --- a/app/src/main/java/net/mynero/wallet/fragment/dialog/WalletKeysBottomSheetDialog.kt +++ b/app/src/main/java/net/mynero/wallet/fragment/dialog/WalletKeysBottomSheetDialog.kt @@ -30,17 +30,17 @@ class WalletKeysBottomSheetDialog : BottomSheetDialogFragment() { val informationTextView = view.findViewById(R.id.information_textview) // seed val viewKeyTextView = view.findViewById(R.id.viewkey_textview) val restoreHeightTextView = view.findViewById(R.id.restore_height_textview) - val wallet = WalletManager.instance!!.wallet - var seed = wallet!!.getSeed("") - val usesOffset = PrefService.instance!!.getBoolean(Constants.PREF_USES_OFFSET, false) + val wallet = WalletManager.instance?.wallet + var seed = wallet?.getSeed("") + val usesOffset = PrefService.instance?.getBoolean(Constants.PREF_USES_OFFSET, false) == true if (usesOffset) { - seed = wallet.getSeed(password) + seed = wallet?.getSeed(password) view.findViewById(R.id.wallet_seed_offset_textview).visibility = View.VISIBLE } - val privateViewKey = wallet.getSecretViewKey() + val privateViewKey = wallet?.getSecretViewKey() informationTextView.text = seed viewKeyTextView.text = privateViewKey - restoreHeightTextView.text = "${wallet.getRestoreHeight()}" + restoreHeightTextView.text = "${wallet?.getRestoreHeight()}" copyViewKeyImageButton.setOnClickListener { clipBoardCopy( context, "private view-key", privateViewKey diff --git a/app/src/main/java/net/mynero/wallet/fragment/home/HomeFragment.kt b/app/src/main/java/net/mynero/wallet/fragment/home/HomeFragment.kt index 27bedf8..1ad4eb8 100644 --- a/app/src/main/java/net/mynero/wallet/fragment/home/HomeFragment.kt +++ b/app/src/main/java/net/mynero/wallet/fragment/home/HomeFragment.kt @@ -165,8 +165,9 @@ class HomeFragment : Fragment(), TxInfoAdapterListener { val botImageView = view.findViewById(R.id.monerochan_imageview) view.findViewById(R.id.no_history_layout).visibility = if (display) View.VISIBLE else View.GONE - val displayMonerochan = PrefService.instance?.getBoolean(Constants.PREF_MONEROCHAN, true) - if (displayMonerochan == true) { + val displayMonerochan = + PrefService.instance?.getBoolean(Constants.PREF_MONEROCHAN, true) == true + if (displayMonerochan) { botImageView.visibility = View.VISIBLE mnrjTextView.visibility = View.VISIBLE textView.visibility = View.GONE diff --git a/app/src/main/java/net/mynero/wallet/fragment/onboarding/OnboardingFragment.kt b/app/src/main/java/net/mynero/wallet/fragment/onboarding/OnboardingFragment.kt index 7518f64..27cffcf 100644 --- a/app/src/main/java/net/mynero/wallet/fragment/onboarding/OnboardingFragment.kt +++ b/app/src/main/java/net/mynero/wallet/fragment/onboarding/OnboardingFragment.kt @@ -1,326 +1,297 @@ -package net.mynero.wallet.fragment.onboarding; +package net.mynero.wallet.fragment.onboarding -import android.app.Activity; -import android.os.Bundle; -import android.text.Editable; -import android.text.TextWatcher; -import android.util.Patterns; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.CheckBox; -import android.widget.EditText; -import android.widget.ImageView; -import android.widget.TextView; +import android.app.Activity +import android.os.Bundle +import android.text.Editable +import android.text.TextWatcher +import android.util.Patterns +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Button +import android.widget.CheckBox +import android.widget.CompoundButton +import android.widget.EditText +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; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.widget.SwitchCompat; -import androidx.constraintlayout.widget.ConstraintLayout; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentActivity; -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) { +class OnboardingFragment : Fragment(), NodeSelectionDialogListener, AddNodeListener { + private var useOffset = true + private var mViewModel: OnboardingViewModel? = null + private var proxyAddressListener: TextWatcher = object : TextWatcher { + 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) { if (mViewModel != null) { - mViewModel.setProxyAddress(editable.toString()); - mViewModel.updateProxy(((MoneroApplication) getActivity().getApplication())); + mViewModel?.setProxyAddress(editable.toString()) + mViewModel?.updateProxy(activity?.application as MoneroApplication) } } - }; - TextWatcher proxyPortListener = 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) { + } + private var proxyPortListener: TextWatcher = object : TextWatcher { + 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) { if (mViewModel != null) { - mViewModel.setProxyPort(editable.toString()); - mViewModel.updateProxy(((MoneroApplication) getActivity().getApplication())); + mViewModel?.setProxyPort(editable.toString()) + mViewModel?.updateProxy(activity?.application as MoneroApplication) } } - }; - private EditText walletProxyAddressEditText; - private EditText walletProxyPortEditText; - private EditText walletPasswordEditText; - private EditText walletPasswordConfirmEditText; - private EditText walletSeedEditText; - private EditText walletRestoreHeightEditText; - private Button createWalletButton; - private TextView moreOptionsDropdownTextView; - private SwitchCompat torSwitch; - private ConstraintLayout advancedOptionsLayout; - private ImageView moreOptionsChevronImageView; - private CheckBox seedOffsetCheckbox; - private Button selectNodeButton; - private SwitchCompat showXmrchanSwitch; - private ImageView xmrchanOnboardingImage; - private Button seedTypeButton; - private TextView seedTypeDescTextView; - - @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, - @Nullable Bundle savedInstanceState) { - return inflater.inflate(R.layout.fragment_onboarding, container, false); + } + private var walletProxyAddressEditText: EditText? = null + private var walletProxyPortEditText: EditText? = null + private var walletPasswordEditText: EditText? = null + private var walletPasswordConfirmEditText: EditText? = null + private var walletSeedEditText: EditText? = null + private var walletRestoreHeightEditText: EditText? = null + private var createWalletButton: Button? = null + private var moreOptionsDropdownTextView: TextView? = null + private var torSwitch: SwitchCompat? = null + private var advancedOptionsLayout: ConstraintLayout? = null + private var moreOptionsChevronImageView: ImageView? = null + private var seedOffsetCheckbox: CheckBox? = null + private var selectNodeButton: Button? = null + private var showXmrchanSwitch: SwitchCompat? = null + private var xmrchanOnboardingImage: ImageView? = null + private var seedTypeButton: Button? = null + private var seedTypeDescTextView: TextView? = null + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + return inflater.inflate(R.layout.fragment_onboarding, container, false) } - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - mViewModel = new ViewModelProvider(this).get(OnboardingViewModel.class); - selectNodeButton = view.findViewById(R.id.select_node_button); - walletPasswordEditText = view.findViewById(R.id.wallet_password_edittext); - walletPasswordConfirmEditText = view.findViewById(R.id.wallet_password_confirm_edittext); - walletSeedEditText = view.findViewById(R.id.wallet_seed_edittext); - walletRestoreHeightEditText = view.findViewById(R.id.wallet_restore_height_edittext); - createWalletButton = view.findViewById(R.id.create_wallet_button); - moreOptionsDropdownTextView = view.findViewById(R.id.advanced_settings_dropdown_textview); - moreOptionsChevronImageView = view.findViewById(R.id.advanced_settings_chevron_imageview); - torSwitch = view.findViewById(R.id.tor_onboarding_switch); - seedOffsetCheckbox = view.findViewById(R.id.seed_offset_checkbox); - walletProxyAddressEditText = view.findViewById(R.id.wallet_proxy_address_edittext); - walletProxyPortEditText = view.findViewById(R.id.wallet_proxy_port_edittext); - advancedOptionsLayout = view.findViewById(R.id.more_options_layout); - showXmrchanSwitch = view.findViewById(R.id.show_xmrchan_switch); - xmrchanOnboardingImage = view.findViewById(R.id.xmrchan_onboarding_imageview); - seedTypeButton = view.findViewById(R.id.seed_type_button); - seedTypeDescTextView = view.findViewById(R.id.seed_type_desc_textview); - - bindListeners(); - bindObservers(); + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + mViewModel = ViewModelProvider(this)[OnboardingViewModel::class.java] + selectNodeButton = view.findViewById(R.id.select_node_button) + walletPasswordEditText = view.findViewById(R.id.wallet_password_edittext) + walletPasswordConfirmEditText = view.findViewById(R.id.wallet_password_confirm_edittext) + walletSeedEditText = view.findViewById(R.id.wallet_seed_edittext) + walletRestoreHeightEditText = view.findViewById(R.id.wallet_restore_height_edittext) + createWalletButton = view.findViewById(R.id.create_wallet_button) + moreOptionsDropdownTextView = view.findViewById(R.id.advanced_settings_dropdown_textview) + moreOptionsChevronImageView = view.findViewById(R.id.advanced_settings_chevron_imageview) + torSwitch = view.findViewById(R.id.tor_onboarding_switch) + seedOffsetCheckbox = view.findViewById(R.id.seed_offset_checkbox) + walletProxyAddressEditText = view.findViewById(R.id.wallet_proxy_address_edittext) + walletProxyPortEditText = view.findViewById(R.id.wallet_proxy_port_edittext) + advancedOptionsLayout = view.findViewById(R.id.more_options_layout) + showXmrchanSwitch = view.findViewById(R.id.show_xmrchan_switch) + xmrchanOnboardingImage = view.findViewById(R.id.xmrchan_onboarding_imageview) + seedTypeButton = view.findViewById(R.id.seed_type_button) + seedTypeDescTextView = view.findViewById(R.id.seed_type_desc_textview) + bindListeners() + bindObservers() } - private void bindObservers() { - mViewModel.showMoreOptions.observe(getViewLifecycleOwner(), show -> { + private fun bindObservers() { + mViewModel?.showMoreOptions?.observe(viewLifecycleOwner) { show: Boolean -> if (show) { - moreOptionsChevronImageView.setImageResource(R.drawable.ic_keyboard_arrow_up); - advancedOptionsLayout.setVisibility(View.VISIBLE); + moreOptionsChevronImageView?.setImageResource(R.drawable.ic_keyboard_arrow_up) + advancedOptionsLayout?.visibility = View.VISIBLE } else { - moreOptionsChevronImageView.setImageResource(R.drawable.ic_keyboard_arrow_down); - advancedOptionsLayout.setVisibility(View.GONE); + moreOptionsChevronImageView?.setImageResource(R.drawable.ic_keyboard_arrow_down) + advancedOptionsLayout?.visibility = View.GONE } - }); - - mViewModel.enableCreateButton.observe(getViewLifecycleOwner(), enable -> { - createWalletButton.setEnabled(enable); - }); - - mViewModel.seedType.observe(getViewLifecycleOwner(), seedType -> { - seedTypeButton.setText(seedType.toString()); - seedTypeDescTextView.setText(getText(seedType.getDescResId())); - if (seedType == OnboardingViewModel.SeedType.LEGACY) { - seedOffsetCheckbox.setVisibility(View.VISIBLE); - walletRestoreHeightEditText.setVisibility(View.VISIBLE); - walletPasswordEditText.setHint(getString(R.string.password_optional)); + } + mViewModel?.enableCreateButton?.observe(viewLifecycleOwner) { enable: Boolean -> + createWalletButton?.isEnabled = enable + } + mViewModel?.seedType?.observe(viewLifecycleOwner) { seedType: SeedType -> + seedTypeButton?.text = seedType.toString() + seedTypeDescTextView?.text = getText(seedType.descResId) + if (seedType == SeedType.LEGACY) { + seedOffsetCheckbox?.visibility = View.VISIBLE + walletRestoreHeightEditText?.visibility = View.VISIBLE + walletPasswordEditText?.hint = getString(R.string.password_optional) } else { - seedOffsetCheckbox.setVisibility(View.GONE); - walletRestoreHeightEditText.setVisibility(View.GONE); - walletPasswordEditText.setHint(getString(R.string.password_non_optional)); + seedOffsetCheckbox?.visibility = View.GONE + walletRestoreHeightEditText?.visibility = View.GONE + walletPasswordEditText?.hint = getString(R.string.password_non_optional) } - }); + } } - private void bindListeners() { - seedOffsetCheckbox.setChecked(useOffset); + private fun bindListeners() { + seedOffsetCheckbox?.isChecked = useOffset // Disable onBack click - OnBackPressedCallback onBackPressedCallback = new OnBackPressedCallback(true) { - @Override - public void handleOnBackPressed() { - } - }; - FragmentActivity activity = getActivity(); - if (activity != null) - activity.getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), onBackPressedCallback); - - moreOptionsDropdownTextView.setOnClickListener(view12 -> mViewModel.onMoreOptionsClicked()); - moreOptionsChevronImageView.setOnClickListener(view12 -> mViewModel.onMoreOptionsClicked()); - seedOffsetCheckbox.setOnCheckedChangeListener((compoundButton, b) -> useOffset = b); - - createWalletButton.setOnClickListener(view1 -> { - prepareDefaultNode(); - onBackPressedCallback.setEnabled(false); - ((MoneroApplication) getActivity().getApplication()).getExecutor().execute(() -> { + val onBackPressedCallback: OnBackPressedCallback = object : OnBackPressedCallback(true) { + override fun handleOnBackPressed() {} + } + val activity = activity + activity?.onBackPressedDispatcher?.addCallback(viewLifecycleOwner, onBackPressedCallback) + moreOptionsDropdownTextView?.setOnClickListener { mViewModel?.onMoreOptionsClicked() } + moreOptionsChevronImageView?.setOnClickListener { mViewModel?.onMoreOptionsClicked() } + seedOffsetCheckbox?.setOnCheckedChangeListener { _: CompoundButton?, b: Boolean -> + useOffset = b + } + createWalletButton?.setOnClickListener { + prepareDefaultNode() + onBackPressedCallback.isEnabled = false + (getActivity()?.application as MoneroApplication).executor?.execute { createOrImportWallet( - walletPasswordEditText.getText().toString(), - walletPasswordConfirmEditText.getText().toString(), - walletSeedEditText.getText().toString().trim(), - walletRestoreHeightEditText.getText().toString().trim() - ); - }); - }); - walletPasswordEditText.addTextChangedListener(new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { + walletPasswordEditText?.text.toString(), + walletPasswordConfirmEditText?.text.toString(), + walletSeedEditText?.text.toString().trim { it <= ' ' }, + walletRestoreHeightEditText?.text.toString().trim { it <= ' ' } + ) } - - @Override - public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { - } - - @Override - public void afterTextChanged(Editable editable) { - String text = editable.toString(); + } + walletPasswordEditText?.addTextChangedListener(object : TextWatcher { + 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) { + val text = editable.toString() if (text.isEmpty()) { - walletPasswordConfirmEditText.setText(null); - walletPasswordConfirmEditText.setVisibility(View.GONE); + walletPasswordConfirmEditText?.text = null + walletPasswordConfirmEditText?.visibility = View.GONE } else { - walletPasswordConfirmEditText.setVisibility(View.VISIBLE); + walletPasswordConfirmEditText?.visibility = View.VISIBLE } } - }); - walletSeedEditText.addTextChangedListener(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) { - String text = editable.toString(); - + }) + walletSeedEditText?.addTextChangedListener(object : TextWatcher { + 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) { + val text = editable.toString() if (text.isEmpty()) { - createWalletButton.setText(R.string.create_wallet); + createWalletButton?.setText(R.string.create_wallet) } else { - createWalletButton.setText(R.string.menu_restore); + createWalletButton?.setText(R.string.menu_restore) } } - }); - - seedTypeButton.setOnClickListener(v -> toggleSeedType()); - - torSwitch.setOnCheckedChangeListener((compoundButton, b) -> { - PrefService.getInstance().edit().putBoolean(Constants.PREF_USES_TOR, b).apply(); - removeProxyTextListeners(); + }) + seedTypeButton?.setOnClickListener { toggleSeedType() } + torSwitch?.setOnCheckedChangeListener { _: CompoundButton?, b: Boolean -> + PrefService.instance?.edit()?.putBoolean(Constants.PREF_USES_TOR, b)?.apply() + removeProxyTextListeners() if (b) { - if (PrefService.getInstance().hasProxySet()) { - String proxyAddress = PrefService.getInstance().getProxyAddress(); - String proxyPort = PrefService.getInstance().getProxyPort(); - initProxyStuff(proxyAddress, proxyPort); + if (PrefService.instance?.hasProxySet() == true) { + val proxyAddress = + PrefService.instance?.proxyAddress ?: return@setOnCheckedChangeListener + val proxyPort = + PrefService.instance?.proxyPort ?: return@setOnCheckedChangeListener + initProxyStuff(proxyAddress, proxyPort) } else { - initProxyStuff("127.0.0.1", "9050"); + initProxyStuff("127.0.0.1", "9050") } - addProxyTextListeners(); + addProxyTextListeners() } - - mViewModel.updateProxy(((MoneroApplication) getActivity().getApplication())); - }); - - showXmrchanSwitch.setChecked(PrefService.getInstance().getBoolean(Constants.PREF_MONEROCHAN, true)); - showXmrchanSwitch.setOnCheckedChangeListener((compoundButton, b) -> { - PrefService.getInstance().edit().putBoolean(Constants.PREF_MONEROCHAN, b).apply(); + mViewModel?.updateProxy(getActivity()?.application as MoneroApplication) + } + showXmrchanSwitch?.isChecked = + PrefService.instance?.getBoolean(Constants.PREF_MONEROCHAN, true) == true + showXmrchanSwitch?.setOnCheckedChangeListener { _: CompoundButton?, b: Boolean -> + PrefService.instance?.edit()?.putBoolean(Constants.PREF_MONEROCHAN, b)?.apply() if (b) { - xmrchanOnboardingImage.setVisibility(View.VISIBLE); + xmrchanOnboardingImage?.visibility = View.VISIBLE } 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() { - PrefService.getInstance().getNode(); + private fun toggleSeedType() { + 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) { - Activity activity = getActivity(); + private fun prepareDefaultNode() { + PrefService.instance?.node + } + + private fun createOrImportWallet( + walletPassword: String, + confirmedPassword: String, + walletSeed: String, + restoreHeightText: String + ) { + val activity: Activity? = activity if (activity != null) { - mViewModel.createOrImportWallet(activity, walletPassword, confirmedPassword, walletSeed, restoreHeightText, useOffset); + mViewModel?.createOrImportWallet( + activity, + walletPassword, + confirmedPassword, + walletSeed, + restoreHeightText, + useOffset + ) } } - private void removeProxyTextListeners() { - walletProxyAddressEditText.removeTextChangedListener(proxyAddressListener); - walletProxyPortEditText.removeTextChangedListener(proxyPortListener); + private fun removeProxyTextListeners() { + walletProxyAddressEditText?.removeTextChangedListener(proxyAddressListener) + walletProxyPortEditText?.removeTextChangedListener(proxyPortListener) } - private void addProxyTextListeners() { - walletProxyAddressEditText.addTextChangedListener(proxyAddressListener); - walletProxyPortEditText.addTextChangedListener(proxyPortListener); + private fun addProxyTextListeners() { + walletProxyAddressEditText?.addTextChangedListener(proxyAddressListener) + walletProxyPortEditText?.addTextChangedListener(proxyPortListener) } - private void initProxyStuff(String proxyAddress, String proxyPort) { - boolean validIpAddress = Patterns.IP_ADDRESS.matcher(proxyAddress).matches(); + private fun initProxyStuff(proxyAddress: String, proxyPort: String) { + val validIpAddress = Patterns.IP_ADDRESS.matcher(proxyAddress).matches() if (validIpAddress) { - mViewModel.setProxyAddress(proxyAddress); - mViewModel.setProxyPort(proxyPort); - walletProxyAddressEditText.setText(proxyAddress); - walletProxyPortEditText.setText(proxyPort); + mViewModel?.setProxyAddress(proxyAddress) + mViewModel?.setProxyPort(proxyPort) + walletProxyAddressEditText?.setText(proxyAddress) + walletProxyPortEditText?.setText(proxyPort) } } - @Override - public void onNodeSelected() { - Node node = PrefService.getInstance().getNode(); - selectNodeButton.setText(getString(R.string.node_button_text, node.getAddress())); - mViewModel.updateProxy(((MoneroApplication) getActivity().getApplication())); + override fun onNodeSelected() { + val node = PrefService.instance?.node + selectNodeButton?.text = getString(R.string.node_button_text, node?.address) + mViewModel?.updateProxy(activity?.application as MoneroApplication) } - @Override - public void onClickedEditNode(Node node) { + override fun onClickedEditNode(node: Node?) {} + override fun onClickedAddNode() { + activity?.supportFragmentManager?.let { fragmentManager -> + val addNodeDialog = AddNodeBottomSheetDialog() + addNodeDialog.listener = this + addNodeDialog.show(fragmentManager, "add_node_dialog") + } } - @Override - public void onClickedAddNode() { - AddNodeBottomSheetDialog addNodeDialog = new AddNodeBottomSheetDialog(); - addNodeDialog.listener = this; - addNodeDialog.show(getActivity().getSupportFragmentManager(), "add_node_dialog"); - } - - @Override - public void onNodeAdded() { - NodeSelectionBottomSheetDialog dialog = new NodeSelectionBottomSheetDialog(); - dialog.listener = this; - dialog.show(getActivity().getSupportFragmentManager(), "node_selection_dialog"); + override fun onNodeAdded() { + activity?.supportFragmentManager?.let { fragmentManager -> + val dialog = NodeSelectionBottomSheetDialog() + dialog.listener = this + dialog.show(fragmentManager, "node_selection_dialog") + } } } \ No newline at end of file diff --git a/app/src/main/java/net/mynero/wallet/fragment/onboarding/OnboardingViewModel.kt b/app/src/main/java/net/mynero/wallet/fragment/onboarding/OnboardingViewModel.kt index f20f789..cc5193b 100644 --- a/app/src/main/java/net/mynero/wallet/fragment/onboarding/OnboardingViewModel.kt +++ b/app/src/main/java/net/mynero/wallet/fragment/onboarding/OnboardingViewModel.kt @@ -1,179 +1,211 @@ -package net.mynero.wallet.fragment.onboarding; +package net.mynero.wallet.fragment.onboarding -import android.app.Activity; -import android.util.Patterns; -import android.widget.Toast; +import android.app.Activity +import android.util.Patterns +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; -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; - -public class OnboardingViewModel extends ViewModel { - private final MutableLiveData _showMoreOptions = new MutableLiveData<>(false); - private final MutableLiveData _enableCreateButton = new MutableLiveData<>(true); - private final MutableLiveData _seedType = new MutableLiveData<>(SeedType.POLYSEED); - public LiveData showMoreOptions = _showMoreOptions; - public LiveData enableCreateButton = _enableCreateButton; - public LiveData 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); +class OnboardingViewModel : ViewModel() { + private val _showMoreOptions = MutableLiveData(false) + private val _enableCreateButton = MutableLiveData(true) + private val _seedType = MutableLiveData(SeedType.POLYSEED) + var showMoreOptions: LiveData = _showMoreOptions + var enableCreateButton: LiveData = _enableCreateButton + var seedType: LiveData = _seedType + private var proxyAddress = "" + private var proxyPort = "" + fun onMoreOptionsClicked() { + val currentValue = showMoreOptions.value ?: false + val newValue = !currentValue + _showMoreOptions.value = newValue } - public void updateProxy(MoneroApplication application) { - application.getExecutor().execute(() -> { - boolean usesProxy = PrefService.getInstance().getBoolean(Constants.PREF_USES_TOR, false); - + fun updateProxy(application: MoneroApplication) { + application.executor?.execute { + val usesProxy = PrefService.instance?.getBoolean(Constants.PREF_USES_TOR, false) == true if (!usesProxy) { - return; + return@execute } - - if (proxyAddress.isEmpty()) proxyAddress = "127.0.0.1"; - if (proxyPort.isEmpty()) proxyPort = "9050"; - boolean validIpAddress = Patterns.IP_ADDRESS.matcher(proxyAddress).matches(); - + if (proxyAddress.isEmpty()) proxyAddress = "127.0.0.1" + if (proxyPort.isEmpty()) proxyPort = "9050" + val validIpAddress = Patterns.IP_ADDRESS.matcher(proxyAddress).matches() if (validIpAddress) { - String proxy = proxyAddress + ":" + proxyPort; - PrefService.getInstance().edit().putString(Constants.PREF_PROXY, proxy).apply(); + val proxy = "$proxyAddress:$proxyPort" + PrefService.instance?.edit()?.putString(Constants.PREF_PROXY, proxy)?.apply() } - }); + } } - public void setSeedType(SeedType seedType) { - this._seedType.setValue(seedType); + fun setSeedType(seedType: SeedType?) { + _seedType.value = seedType } - - public void setProxyAddress(String address) { - this.proxyAddress = address; + fun setProxyAddress(address: String) { + proxyAddress = address } - public void setProxyPort(String port) { - this.proxyPort = port; + fun setProxyPort(port: String) { + proxyPort = port } - public void createOrImportWallet(Activity mainActivity, String walletPassword, String confirmedPassword, String walletSeed, String restoreHeightText, boolean useOffset) { - MoneroApplication application = (MoneroApplication) mainActivity.getApplication(); - application.getExecutor().execute(() -> { - _enableCreateButton.postValue(false); - String offset = useOffset ? walletPassword : ""; - if (!walletPassword.isEmpty()) { - if (!walletPassword.equals(confirmedPassword)) { - _enableCreateButton.postValue(true); - mainActivity.runOnUiThread(() -> Toast.makeText(mainActivity, application.getString(R.string.invalid_confirmed_password), Toast.LENGTH_SHORT).show()); - return; + fun createOrImportWallet( + mainActivity: Activity, + walletPassword: String, + confirmedPassword: String, + walletSeed: String, + restoreHeightText: String, + useOffset: Boolean + ) { + val application = mainActivity.application as MoneroApplication + 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(); - File walletFile = new File(mainActivity.getApplicationInfo().dataDir, Constants.WALLET_NAME); - Wallet wallet = null; - if (!offset.isEmpty()) { - PrefService.getInstance().edit().putBoolean(Constants.PREF_USES_OFFSET, true).apply(); + var restoreHeight = newRestoreHeight + val walletFile = File(mainActivity.applicationInfo.dataDir, Constants.WALLET_NAME) + var wallet: Wallet? = null + if (offset.isNotEmpty()) { + PrefService.instance?.edit()?.putBoolean(Constants.PREF_USES_OFFSET, true)?.apply() } - if (walletSeed.isEmpty()) { - SeedType seedTypeValue = seedType.getValue(); - if (seedTypeValue == null) return; - + val seedTypeValue = seedType.value ?: return@execute if (seedTypeValue == SeedType.POLYSEED) { - if (offset.isEmpty()) { - mainActivity.runOnUiThread(() -> { - _enableCreateButton.postValue(true); - Toast.makeText(mainActivity, application.getString(R.string.invalid_empty_passphrase), Toast.LENGTH_SHORT).show(); - }); - return; + wallet = if (offset.isEmpty()) { + mainActivity.runOnUiThread { + _enableCreateButton.postValue(true) + Toast.makeText( + mainActivity, + application.getString(R.string.invalid_empty_passphrase), + Toast.LENGTH_SHORT + ).show() + } + return@execute } 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) { - File tmpWalletFile = new File(mainActivity.getApplicationInfo().dataDir, Constants.WALLET_NAME + "_tmp"); - Wallet tmpWallet = createTempWallet(tmpWalletFile); //we do this to get seed, then recover wallet so we can use seed offset - wallet = WalletManager.getInstance().recoveryWallet(walletFile, walletPassword, tmpWallet.getSeed(""), offset, restoreHeight); - tmpWalletFile.delete(); + val tmpWalletFile = + File(mainActivity.applicationInfo.dataDir, Constants.WALLET_NAME + "_tmp") + val tmpWallet = + 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 { if (getMnemonicType(walletSeed) == SeedType.UNKNOWN) { - mainActivity.runOnUiThread(() -> { - _enableCreateButton.postValue(true); - Toast.makeText(mainActivity, application.getString(R.string.invalid_mnemonic_code), Toast.LENGTH_SHORT).show(); - }); - return; + mainActivity.runOnUiThread { + _enableCreateButton.postValue(true) + Toast.makeText( + mainActivity, + application.getString(R.string.invalid_mnemonic_code), + Toast.LENGTH_SHORT + ).show() + } + return@execute } - if (!restoreHeightText.isEmpty()) { - restoreHeight = Long.parseLong(restoreHeightText); + if (restoreHeightText.isNotEmpty()) { + 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(); - wallet.close(); - boolean ok = walletStatus.isOk(); - walletFile.delete(); // cache is broken for some reason when recovering wallets. delete the file here. this happens in monerujo too. - - if (ok) { - ((MainActivity) mainActivity).init(walletFile, walletPassword); - mainActivity.runOnUiThread(mainActivity::onBackPressed); + val walletStatus = wallet?.status + wallet?.close() + val ok = walletStatus?.isOk + walletFile.delete() // cache is broken for some reason when recovering wallets. delete the file here. this happens in monerujo too. + if (ok == true) { + (mainActivity as MainActivity).init(walletFile, walletPassword) + mainActivity.runOnUiThread { mainActivity.onBackPressed() } } else { - mainActivity.runOnUiThread(() -> { - _enableCreateButton.postValue(true); - Toast.makeText(mainActivity, application.getString(R.string.create_wallet_failed, walletStatus.errorString), Toast.LENGTH_SHORT).show(); - }); + mainActivity.runOnUiThread { + _enableCreateButton.postValue(true) + Toast.makeText( + mainActivity, + application.getString( + R.string.create_wallet_failed, + walletStatus?.errorString + ), + Toast.LENGTH_SHORT + ).show() + } } - }); + } } - private long getNewRestoreHeight() { - Calendar restoreDate = Calendar.getInstance(); - restoreDate.add(Calendar.DAY_OF_MONTH, 0); - return RestoreHeight.getInstance().getHeight(restoreDate.getTime()); - } + private val newRestoreHeight: Long + get() { + val restoreDate = Calendar.getInstance() + restoreDate.add(Calendar.DAY_OF_MONTH, 0) + return RestoreHeight.instance?.getHeight(restoreDate.time) ?: 0 + } - public SeedType getMnemonicType(String seed) { - String[] words = seed.split("\\s"); - SeedType seedTypeValue = seedType.getValue(); - if (seedTypeValue == null) return SeedType.LEGACY; - if (words.length == 16 && seedTypeValue == SeedType.POLYSEED) { - return SeedType.POLYSEED; - } else if (words.length == 25 && seedTypeValue == SeedType.LEGACY) { - return SeedType.LEGACY; + private fun getMnemonicType(seed: String): SeedType { + val words = seed.split("\\s".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + val seedTypeValue = seedType.value ?: return SeedType.LEGACY + return if (words.size == 16 && seedTypeValue == SeedType.POLYSEED) { + SeedType.POLYSEED + } else if (words.size == 25 && seedTypeValue == SeedType.LEGACY) { + SeedType.LEGACY } else { - return SeedType.UNKNOWN; + SeedType.UNKNOWN } } - private Wallet createTempWallet(File tmpWalletFile) { - return WalletManager.getInstance().createWallet(tmpWalletFile, "", Constants.MNEMONIC_LANGUAGE, 0); + private fun createTempWallet(tmpWalletFile: File): Wallet? { + return WalletManager.instance?.createWallet( + tmpWalletFile, + "", + Constants.MNEMONIC_LANGUAGE, + 0 + ) } - public enum SeedType { - LEGACY(R.string.seed_desc_legacy), - POLYSEED(R.string.seed_desc_polyseed), - UNKNOWN(0); + enum class SeedType(val descResId: Int) { + LEGACY(R.string.seed_desc_legacy), POLYSEED(R.string.seed_desc_polyseed), UNKNOWN(0) - private final int descResId; - - SeedType(int descResId) { - this.descResId = descResId; - } - - public int getDescResId() { - return descResId; - } } } \ No newline at end of file diff --git a/app/src/main/java/net/mynero/wallet/fragment/send/SendFragment.kt b/app/src/main/java/net/mynero/wallet/fragment/send/SendFragment.kt index 8086f8c..c93562a 100644 --- a/app/src/main/java/net/mynero/wallet/fragment/send/SendFragment.kt +++ b/app/src/main/java/net/mynero/wallet/fragment/send/SendFragment.kt @@ -237,7 +237,10 @@ class SendFragment : Fragment() { val address = if (destCount == 1) getAddressField(0).text.toString() else "Multiple" addressTextView?.text = getString(R.string.tx_address_text, address) amountTextView?.text = - getString(R.string.tx_amount_text, Helper.getDisplayAmount(pendingTx.getAmount())) + getString( + R.string.tx_amount_text, + Helper.getDisplayAmount(pendingTx.getAmount()) + ) feeTextView?.text = getString(R.string.tx_fee_text, Helper.getDisplayAmount(pendingTx.getFee())) } diff --git a/app/src/main/java/net/mynero/wallet/fragment/settings/SettingsFragment.kt b/app/src/main/java/net/mynero/wallet/fragment/settings/SettingsFragment.kt index ac68b10..3631cb9 100644 --- a/app/src/main/java/net/mynero/wallet/fragment/settings/SettingsFragment.kt +++ b/app/src/main/java/net/mynero/wallet/fragment/settings/SettingsFragment.kt @@ -1,312 +1,291 @@ -package net.mynero.wallet.fragment.settings; +package net.mynero.wallet.fragment.settings -import android.os.Bundle; -import android.text.Editable; -import android.text.TextWatcher; -import android.util.Patterns; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.EditText; -import android.widget.TextView; -import android.widget.Toast; +import android.os.Bundle +import android.text.Editable +import android.text.TextWatcher +import android.util.Patterns +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Button +import android.widget.CompoundButton +import android.widget.EditText +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; -import androidx.annotation.Nullable; -import androidx.appcompat.widget.SwitchCompat; -import androidx.constraintlayout.widget.ConstraintLayout; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentActivity; -import androidx.fragment.app.FragmentManager; -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) { +class SettingsFragment : Fragment(), PasswordListener, NodeSelectionDialogListener, AddNodeListener, + EditNodeListener { + private var mViewModel: SettingsViewModel? = null + private var proxyAddressListener: TextWatcher = object : TextWatcher { + 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) { if (mViewModel != null) { - mViewModel.setProxyAddress(editable.toString()); - mViewModel.updateProxy(((MoneroApplication) getActivity().getApplication())); + mViewModel?.setProxyAddress(editable.toString()) + mViewModel?.updateProxy(activity?.application as MoneroApplication) } } - }; - TextWatcher proxyPortListener = 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) { + } + private var proxyPortListener: TextWatcher = object : TextWatcher { + 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) { if (mViewModel != null) { - mViewModel.setProxyPort(editable.toString()); - mViewModel.updateProxy(((MoneroApplication) getActivity().getApplication())); + mViewModel?.setProxyPort(editable.toString()) + mViewModel?.updateProxy(activity?.application as MoneroApplication) } } - }; - private EditText walletProxyAddressEditText; - private EditText walletProxyPortEditText; - private Button selectNodeButton; - - @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, - @Nullable Bundle savedInstanceState) { - return inflater.inflate(R.layout.fragment_settings, container, false); + } + private var walletProxyAddressEditText: EditText? = null + private var walletProxyPortEditText: EditText? = null + private var selectNodeButton: Button? = null + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + return inflater.inflate(R.layout.fragment_settings, container, false) } - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - mViewModel = new ViewModelProvider(this).get(SettingsViewModel.class); - Button displaySeedButton = view.findViewById(R.id.display_seed_button); - Button displayUtxosButton = view.findViewById(R.id.display_utxos_button); - - selectNodeButton = view.findViewById(R.id.select_node_button); - SwitchCompat streetModeSwitch = view.findViewById(R.id.street_mode_switch); - SwitchCompat monerochanSwitch = view.findViewById(R.id.monerochan_switch); - SwitchCompat donationSwitch = view.findViewById(R.id.donate_per_tx_switch); - SwitchCompat torSwitch = view.findViewById(R.id.tor_switch); - ConstraintLayout proxySettingsLayout = view.findViewById(R.id.wallet_proxy_settings_layout); - walletProxyAddressEditText = view.findViewById(R.id.wallet_proxy_address_edittext); - walletProxyPortEditText = view.findViewById(R.id.wallet_proxy_port_edittext); - - streetModeSwitch.setChecked(PrefService.getInstance().getBoolean(Constants.PREF_STREET_MODE, false)); - streetModeSwitch.setOnCheckedChangeListener((compoundButton, b) -> { - PrefService.getInstance().edit().putBoolean(Constants.PREF_STREET_MODE, b).apply(); - BalanceService.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); + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + mViewModel = ViewModelProvider(this)[SettingsViewModel::class.java] + val displaySeedButton = view.findViewById