diff --git a/app/src/main/java/com/m2049r/xmrwallet/MainActivity.java b/app/src/main/java/com/m2049r/xmrwallet/MainActivity.java
index 9ce3c14..34e2e71 100644
--- a/app/src/main/java/com/m2049r/xmrwallet/MainActivity.java
+++ b/app/src/main/java/com/m2049r/xmrwallet/MainActivity.java
@@ -93,7 +93,7 @@ public class MainActivity extends AppCompatActivity implements MoneroHandlerThre
@Override
public void onConnectionFail() {
- Toast.makeText(this, R.string.connection_failed, Toast.LENGTH_SHORT).show();
+ runOnUiThread(() -> Toast.makeText(getApplication(), R.string.connection_failed, Toast.LENGTH_SHORT).show());
}
@Override
@@ -105,6 +105,6 @@ public class MainActivity extends AppCompatActivity implements MoneroHandlerThre
@Override
public void onPasswordFail() {
- Toast.makeText(this, R.string.bad_password, Toast.LENGTH_SHORT).show();
+ runOnUiThread(() -> Toast.makeText(getApplication(), R.string.bad_password, Toast.LENGTH_SHORT).show());
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/m2049r/xmrwallet/data/DefaultNodes.java b/app/src/main/java/com/m2049r/xmrwallet/data/DefaultNodes.java
index 49aab3e..3fe1306 100644
--- a/app/src/main/java/com/m2049r/xmrwallet/data/DefaultNodes.java
+++ b/app/src/main/java/com/m2049r/xmrwallet/data/DefaultNodes.java
@@ -32,7 +32,8 @@ public enum DefaultNodes {
MONERUJO_ONION("monerujods7mbghwe6cobdr6ujih6c22zu5rl7zshmizz2udf7v7fsad.onion:18081/mainnet/monerujo.onion"),
Criminales78("56wl7y2ebhamkkiza4b7il4mrzwtyvpdym7bm2bkg3jrei2je646k3qd.onion:18089/mainnet/Criminales78.onion"),
xmrfail("mxcd4577fldb3ppzy7obmmhnu3tf57gbcbd4qhwr2kxyjj2qi3dnbfqd.onion:18081/mainnet/xmrfail.onion"),
- boldsuck("6dsdenp6vjkvqzy4wzsnzn6wixkdzihx3khiumyzieauxuxslmcaeiad.onion:18081/mainnet/boldsuck.onion");
+ boldsuck("6dsdenp6vjkvqzy4wzsnzn6wixkdzihx3khiumyzieauxuxslmcaeiad.onion:18081/mainnet/boldsuck.onion"),
+ SAMOURAI("446unwib5vc7pfbzflosy6m6vtyuhddnalr3hutyavwe4esfuu5g6ryd.onion:18089/mainnet/samourai.onion");
@Getter
private final String uri;
diff --git a/app/src/main/java/com/m2049r/xmrwallet/fragment/onboarding/OnboardingFragment.java b/app/src/main/java/com/m2049r/xmrwallet/fragment/onboarding/OnboardingFragment.java
index e58fcc9..6588abd 100644
--- a/app/src/main/java/com/m2049r/xmrwallet/fragment/onboarding/OnboardingFragment.java
+++ b/app/src/main/java/com/m2049r/xmrwallet/fragment/onboarding/OnboardingFragment.java
@@ -51,6 +51,7 @@ public class OnboardingFragment extends Fragment {
ImageView moreOptionsChevronImageView = view.findViewById(R.id.advanced_settings_chevron_imageview);
moreOptionsDropdownTextView.setOnClickListener(view12 -> mViewModel.onMoreOptionsClicked());
+ moreOptionsChevronImageView.setOnClickListener(view12 -> mViewModel.onMoreOptionsClicked());
createWalletButton.setOnClickListener(view1 -> {
String walletPassword = walletPasswordEditText.getText().toString();
diff --git a/app/src/main/java/com/m2049r/xmrwallet/fragment/settings/SettingsFragment.java b/app/src/main/java/com/m2049r/xmrwallet/fragment/settings/SettingsFragment.java
index 1be59df..32f681d 100644
--- a/app/src/main/java/com/m2049r/xmrwallet/fragment/settings/SettingsFragment.java
+++ b/app/src/main/java/com/m2049r/xmrwallet/fragment/settings/SettingsFragment.java
@@ -1,15 +1,20 @@
package com.m2049r.xmrwallet.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.Toast;
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.lifecycle.ViewModelProvider;
@@ -25,6 +30,28 @@ import com.m2049r.xmrwallet.util.NightmodeHelper;
public class SettingsFragment extends Fragment implements PasswordBottomSheetDialog.PasswordListener {
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) {
+ mViewModel.setProxyAddress(editable.toString());
+ mViewModel.updateProxy();
+ }
+ }
+ };
+ 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) {
+ if(mViewModel != null) {
+ mViewModel.setProxyPort(editable.toString());
+ mViewModel.updateProxy();
+ }
+ }
+ };
+ private EditText walletProxyAddressEditText;
+ private EditText walletProxyPortEditText;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@@ -39,6 +66,9 @@ public class SettingsFragment extends Fragment implements PasswordBottomSheetDia
Button displaySeedButton = view.findViewById(R.id.display_seed_button);
SwitchCompat nightModeSwitch = view.findViewById(R.id.day_night_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);
nightModeSwitch.setChecked(NightmodeHelper.getPreferredNightmode() == DayNightMode.NIGHT);
nightModeSwitch.setOnCheckedChangeListener((compoundButton, b) -> {
@@ -49,14 +79,41 @@ public class SettingsFragment extends Fragment implements PasswordBottomSheetDia
}
});
- torSwitch.setChecked(PrefService.getInstance().getBoolean(Constants.PREF_USES_TOR, false));
+ boolean usesProxy = PrefService.getInstance().getBoolean(Constants.PREF_USES_TOR, false);
+ String proxy = PrefService.getInstance().getString(Constants.PREF_PROXY, "");
+ if(proxy.contains(":")) {
+ String proxyAddress = proxy.split(":")[0];
+ String proxyPort = proxy.split(":")[1];
+ initProxyStuff(proxyAddress, proxyPort);
+ }
+ torSwitch.setChecked(usesProxy);
+ if(usesProxy) {
+ proxySettingsLayout.setVisibility(View.VISIBLE);
+ } else {
+ proxySettingsLayout.setVisibility(View.GONE);
+ }
+
+ addProxyTextListeners();
+
torSwitch.setOnCheckedChangeListener((compoundButton, b) -> {
PrefService.getInstance().edit().putBoolean(Constants.PREF_USES_TOR, b).apply();
+ if(b) {
+ String proxyString = PrefService.getInstance().getString(Constants.PREF_PROXY, "");
+ if(proxyString.contains(":")) {
+ removeProxyTextListeners();
- // TODO display "Advanced" settings mode when enabled to configure specific proxy address and port
- String proxy = b ? "127.0.0.1:9050" : "";
- WalletManager.getInstance().setProxy(proxy);
- WalletManager.getInstance().getWallet().setProxy(proxy);
+ String proxyAddress = proxyString.split(":")[0];
+ String proxyPort = proxyString.split(":")[1];
+ initProxyStuff(proxyAddress, proxyPort);
+
+ addProxyTextListeners();
+ }
+ proxySettingsLayout.setVisibility(View.VISIBLE);
+ } else {
+ proxySettingsLayout.setVisibility(View.GONE);
+ }
+
+ mViewModel.updateProxy();
});
displaySeedButton.setOnClickListener(view1 -> {
@@ -87,4 +144,24 @@ public class SettingsFragment extends Fragment implements PasswordBottomSheetDia
public void onPasswordFail() {
Toast.makeText(getContext(), R.string.bad_password, Toast.LENGTH_SHORT).show();
}
+
+ private void initProxyStuff(String proxyAddress, String proxyPort) {
+ boolean validIpAddress = Patterns.IP_ADDRESS.matcher(proxyAddress).matches();
+ if(validIpAddress) {
+ mViewModel.setProxyAddress(proxyAddress);
+ mViewModel.setProxyPort(proxyPort);
+ walletProxyAddressEditText.setText(proxyAddress);
+ walletProxyPortEditText.setText(proxyPort);
+ }
+ }
+
+ private void removeProxyTextListeners() {
+ walletProxyAddressEditText.removeTextChangedListener(proxyAddressListener);
+ walletProxyPortEditText.removeTextChangedListener(proxyPortListener);
+ }
+
+ private void addProxyTextListeners() {
+ walletProxyAddressEditText.addTextChangedListener(proxyAddressListener);
+ walletProxyPortEditText.addTextChangedListener(proxyPortListener);
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/m2049r/xmrwallet/fragment/settings/SettingsViewModel.java b/app/src/main/java/com/m2049r/xmrwallet/fragment/settings/SettingsViewModel.java
index e599710..729206a 100644
--- a/app/src/main/java/com/m2049r/xmrwallet/fragment/settings/SettingsViewModel.java
+++ b/app/src/main/java/com/m2049r/xmrwallet/fragment/settings/SettingsViewModel.java
@@ -1,7 +1,48 @@
package com.m2049r.xmrwallet.fragment.settings;
+import android.app.Activity;
+import android.os.AsyncTask;
+import android.util.Patterns;
+import android.widget.Toast;
+
import androidx.lifecycle.ViewModel;
+import com.m2049r.xmrwallet.R;
+import com.m2049r.xmrwallet.model.WalletManager;
+import com.m2049r.xmrwallet.service.PrefService;
+import com.m2049r.xmrwallet.service.TxService;
+import com.m2049r.xmrwallet.util.Constants;
+
public class SettingsViewModel extends ViewModel {
+ private String proxyAddress = "";
+ private String proxyPort = "";
+ public void updateProxy() {
+ AsyncTask.execute(() -> {
+ boolean usesProxy = PrefService.getInstance().getBoolean(Constants.PREF_USES_TOR, false);
+ if(!usesProxy) {
+ WalletManager.getInstance().setProxy("");
+ WalletManager.getInstance().getWallet().setProxy("");
+ return;
+ }
+
+ if(proxyAddress.isEmpty()) proxyAddress = "127.0.0.1";
+ if(proxyPort.isEmpty()) proxyPort = "9050";
+ boolean validIpAddress = Patterns.IP_ADDRESS.matcher(proxyAddress).matches();
+ if(validIpAddress) {
+ String proxy = proxyAddress + ":" + proxyPort;
+ PrefService.getInstance().edit().putString(Constants.PREF_PROXY, proxy).apply();
+ WalletManager.getInstance().setProxy(proxy);
+ WalletManager.getInstance().getWallet().setProxy(proxy);
+ }
+ });
+ }
+
+ public void setProxyAddress(String address) {
+ this.proxyAddress = address;
+ }
+
+ public void setProxyPort(String port) {
+ this.proxyPort = port;
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/m2049r/xmrwallet/service/MoneroHandlerThread.java b/app/src/main/java/com/m2049r/xmrwallet/service/MoneroHandlerThread.java
index 5613cd4..8be796d 100644
--- a/app/src/main/java/com/m2049r/xmrwallet/service/MoneroHandlerThread.java
+++ b/app/src/main/java/com/m2049r/xmrwallet/service/MoneroHandlerThread.java
@@ -57,9 +57,9 @@ public class MoneroHandlerThread extends Thread implements WalletListener {
public void run() {
boolean usesTor = PrefService.getInstance().getBoolean(Constants.PREF_USES_TOR, false);
if (usesTor) {
- String proxy = "127.0.0.1:9050";
+ String proxy = PrefService.getInstance().getString(Constants.PREF_PROXY, "");
WalletManager.getInstance().setProxy(proxy);
- WalletManager.getInstance().setDaemon(Node.fromString(DefaultNodes.boldsuck.getUri()));
+ WalletManager.getInstance().setDaemon(Node.fromString(DefaultNodes.SAMOURAI.getUri()));
wallet.setProxy(proxy);
} else {
WalletManager.getInstance().setDaemon(Node.fromString(DefaultNodes.XMRTW.getUri()));
diff --git a/app/src/main/java/com/m2049r/xmrwallet/util/Constants.java b/app/src/main/java/com/m2049r/xmrwallet/util/Constants.java
index 496356a..c0f0679 100644
--- a/app/src/main/java/com/m2049r/xmrwallet/util/Constants.java
+++ b/app/src/main/java/com/m2049r/xmrwallet/util/Constants.java
@@ -6,4 +6,5 @@ public class Constants {
public static final String PREF_USES_PASSWORD = "pref_uses_password";
public static final String PREF_USES_TOR = "pref_uses_tor";
public static final String PREF_NIGHT_MODE = "pref_night_mode";
+ public static final String PREF_PROXY = "pref_proxy";
}
diff --git a/app/src/main/res/layout/fragment_onboarding.xml b/app/src/main/res/layout/fragment_onboarding.xml
index af885ef..99d4b3a 100644
--- a/app/src/main/res/layout/fragment_onboarding.xml
+++ b/app/src/main/res/layout/fragment_onboarding.xml
@@ -41,6 +41,7 @@
android:layout_marginBottom="8dp"
android:text="@string/more_options"
android:textStyle="bold"
+ android:padding="4dp"
app:layout_constraintBottom_toTopOf="@id/wallet_seed_edittext"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
@@ -51,6 +52,8 @@
android:id="@+id/advanced_settings_chevron_imageview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:minWidth="24dp"
+ android:minHeight="24dp"
android:src="@drawable/ic_keyboard_arrow_down"
app:layout_constraintBottom_toBottomOf="@id/advanced_settings_dropdown_textview"
app:layout_constraintStart_toEndOf="@id/advanced_settings_dropdown_textview"
diff --git a/app/src/main/res/layout/fragment_settings.xml b/app/src/main/res/layout/fragment_settings.xml
index 1312824..e403b7d 100644
--- a/app/src/main/res/layout/fragment_settings.xml
+++ b/app/src/main/res/layout/fragment_settings.xml
@@ -109,4 +109,38 @@
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/network_settings_textview" />
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 8b00d36..31803d6 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -76,4 +76,8 @@
Wallet
Appearance
Network
+
+ 127.0.0.1
+ 9050
+ Invalid IP address