mirror of
https://codeberg.org/anoncontributorxmr/mysu.git
synced 2024-11-25 08:52:28 +00:00
Add user/pass to node settings, cleanup node parsing, fix quite a few bugs
This commit is contained in:
parent
ecdd6d12d3
commit
480cbd11f1
13 changed files with 330 additions and 88 deletions
|
@ -109,7 +109,6 @@ public class NodeSelectionAdapter extends RecyclerView.Adapter<NodeSelectionAdap
|
|||
TextView nodeAddressTextView = itemView.findViewById(R.id.node_uri_textview);
|
||||
nodeNameTextView.setText(node.getName());
|
||||
nodeAddressTextView.setText(node.getAddress());
|
||||
|
||||
ImageView nodeAnonymityNetworkImageView = itemView.findViewById(R.id.anonymity_network_imageview);
|
||||
|
||||
if(node.isOnion()) {
|
||||
|
@ -125,10 +124,10 @@ public class NodeSelectionAdapter extends RecyclerView.Adapter<NodeSelectionAdap
|
|||
itemView.setOnLongClickListener(view -> {
|
||||
if(match) {
|
||||
Toast.makeText(itemView.getContext(), itemView.getResources().getString(R.string.cant_edit_current_node), Toast.LENGTH_SHORT).show();
|
||||
return false;
|
||||
return true;
|
||||
} else if(isDefaultNode(node)) {
|
||||
Toast.makeText(itemView.getContext(), itemView.getResources().getString(R.string.cant_edit_default_nodes), Toast.LENGTH_SHORT).show();
|
||||
return false;
|
||||
return true;
|
||||
} else {
|
||||
return listener.onSelectEditNode(node);
|
||||
}
|
||||
|
|
|
@ -223,7 +223,9 @@ public class Node {
|
|||
return (host.equals(anotherNode.host)
|
||||
&& (getAddress().equals(anotherNode.getAddress()))
|
||||
&& (rpcPort == anotherNode.rpcPort)
|
||||
&& (networkType == anotherNode.networkType));
|
||||
&& (networkType == anotherNode.networkType))
|
||||
&& (username.equals(anotherNode.getUsername()))
|
||||
&& (password.equals(anotherNode.getPassword()));
|
||||
}
|
||||
|
||||
public boolean isOnion() {
|
||||
|
|
|
@ -2,6 +2,8 @@ package net.mynero.wallet.fragment.dialog;
|
|||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Patterns;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
@ -9,6 +11,7 @@ import android.view.ViewGroup;
|
|||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
@ -16,6 +19,7 @@ import androidx.annotation.Nullable;
|
|||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
|
||||
|
||||
import net.mynero.wallet.R;
|
||||
import net.mynero.wallet.data.Node;
|
||||
import net.mynero.wallet.service.PrefService;
|
||||
import net.mynero.wallet.util.Constants;
|
||||
import net.mynero.wallet.util.Helper;
|
||||
|
@ -37,67 +41,89 @@ public class AddNodeBottomSheetDialog extends BottomSheetDialogFragment {
|
|||
Button addNodeButton = view.findViewById(R.id.add_node_button);
|
||||
EditText addressEditText = view.findViewById(R.id.address_edittext);
|
||||
EditText nodeNameEditText = view.findViewById(R.id.node_name_edittext);
|
||||
ImageButton pasteAddressImageButton = view.findViewById(R.id.paste_address_imagebutton);
|
||||
pasteAddressImageButton.setOnClickListener(view1 -> {
|
||||
Context ctx = getContext();
|
||||
if (ctx != null) {
|
||||
addressEditText.setText(Helper.getClipBoardText(ctx));
|
||||
EditText usernameEditText = view.findViewById(R.id.username_edittext);
|
||||
EditText passwordEditText = view.findViewById(R.id.password_edittext);
|
||||
ImageButton pastePasswordImageButton = view.findViewById(R.id.paste_password_imagebutton);
|
||||
|
||||
usernameEditText.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) {
|
||||
if(editable.toString().isEmpty()) {
|
||||
passwordEditText.setText(null);
|
||||
passwordEditText.setVisibility(View.GONE);
|
||||
pastePasswordImageButton.setVisibility(View.GONE);
|
||||
} else {
|
||||
passwordEditText.setVisibility(View.VISIBLE);
|
||||
pastePasswordImageButton.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
addPasteListener(view, addressEditText, R.id.paste_address_imagebutton);
|
||||
addPasteListener(view, usernameEditText, R.id.paste_username_imagebutton);
|
||||
addPasteListener(view, passwordEditText, R.id.paste_password_imagebutton);
|
||||
|
||||
addNodeButton.setOnClickListener(view1 -> {
|
||||
String node = addressEditText.getText().toString();
|
||||
String name = nodeNameEditText.getText().toString();
|
||||
String user = usernameEditText.getText().toString();
|
||||
String pass = passwordEditText.getText().toString();
|
||||
try {
|
||||
String auth = "";
|
||||
if(!user.isEmpty() && !pass.isEmpty()) {
|
||||
auth = user + ":" + pass + "@";
|
||||
} else if(!user.isEmpty()) {
|
||||
Toast.makeText(getContext(), "Enter password", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.contains(":") && !name.isEmpty()) {
|
||||
String[] nodeParts = node.split(":");
|
||||
if (nodeParts.length == 2) {
|
||||
String address = nodeParts[0];
|
||||
int port = Integer.parseInt(nodeParts[1]);
|
||||
String newNodeString = address + ":" + port + "/mainnet/" + name;
|
||||
boolean validAddress = Patterns.IP_ADDRESS.matcher(address).matches() || Patterns.DOMAIN_NAME.matcher(address).matches() || address.endsWith(".b32.i2p");
|
||||
if (validAddress) {
|
||||
String nodesArray = PrefService.getInstance().getString(Constants.PREF_CUSTOM_NODES, "[]");
|
||||
JSONArray jsonArray = new JSONArray(nodesArray);
|
||||
boolean exists = false;
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
String nodeString = jsonArray.getString(i);
|
||||
if (nodeString.equals(newNodeString))
|
||||
exists = true;
|
||||
}
|
||||
StringBuilder nodeStringBuilder = new StringBuilder();
|
||||
nodeStringBuilder.append(auth);
|
||||
|
||||
if (!exists) {
|
||||
jsonArray.put(newNodeString);
|
||||
if(!name.isEmpty()) {
|
||||
if(!node.isEmpty()) {
|
||||
if (node.contains(":")) {
|
||||
String[] nodeParts = node.split(":");
|
||||
if (nodeParts.length == 2) {
|
||||
String address = nodeParts[0];
|
||||
int port = Integer.parseInt(nodeParts[1]);
|
||||
nodeStringBuilder.append(address).append(":").append(port);
|
||||
}
|
||||
|
||||
PrefService.getInstance().edit().putString(Constants.PREF_CUSTOM_NODES, jsonArray.toString()).apply();
|
||||
if (listener != null) {
|
||||
listener.onNodeAdded();
|
||||
}
|
||||
dismiss();
|
||||
} else {
|
||||
nodeStringBuilder.append(node);
|
||||
}
|
||||
|
||||
nodeStringBuilder.append("/mainnet/").append(name);
|
||||
} else {
|
||||
Toast.makeText(getContext(), "Enter node address", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
} else if(node.endsWith(".b32.i2p")) {
|
||||
String newNodeString = node + "/mainnet/" + name;
|
||||
String nodesArray = PrefService.getInstance().getString(Constants.PREF_CUSTOM_NODES, "[]");
|
||||
JSONArray jsonArray = new JSONArray(nodesArray);
|
||||
boolean exists = false;
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
String nodeString = jsonArray.getString(i);
|
||||
if (nodeString.equals(newNodeString))
|
||||
exists = true;
|
||||
}
|
||||
} else {
|
||||
Toast.makeText(getContext(), "Enter node name", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!exists) {
|
||||
jsonArray.put(newNodeString);
|
||||
}
|
||||
String nodesArray = PrefService.getInstance().getString(Constants.PREF_CUSTOM_NODES, "[]");
|
||||
JSONArray jsonArray = new JSONArray(nodesArray);
|
||||
boolean exists = false;
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
String nodeString = jsonArray.getString(i);
|
||||
if (nodeString.equals(nodeStringBuilder.toString()))
|
||||
exists = true;
|
||||
}
|
||||
|
||||
PrefService.getInstance().edit().putString(Constants.PREF_CUSTOM_NODES, jsonArray.toString()).apply();
|
||||
if (listener != null) {
|
||||
listener.onNodeAdded();
|
||||
}
|
||||
dismiss();
|
||||
if (!exists) {
|
||||
jsonArray.put(nodeStringBuilder.toString());
|
||||
} else {
|
||||
Toast.makeText(getContext(), "Node already exists", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
PrefService.getInstance().edit().putString(Constants.PREF_CUSTOM_NODES, jsonArray.toString()).apply();
|
||||
if (listener != null) {
|
||||
listener.onNodeAdded();
|
||||
}
|
||||
} catch (NumberFormatException | JSONException e) {
|
||||
e.printStackTrace();
|
||||
|
@ -105,6 +131,16 @@ public class AddNodeBottomSheetDialog extends BottomSheetDialogFragment {
|
|||
});
|
||||
}
|
||||
|
||||
private void addPasteListener(View root, EditText editText, int layoutId) {
|
||||
ImageButton pasteImageButton = root.findViewById(layoutId);
|
||||
pasteImageButton.setOnClickListener(view1 -> {
|
||||
Context ctx = getContext();
|
||||
if (ctx != null) {
|
||||
editText.setText(Helper.getClipBoardText(ctx));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public interface AddNodeListener {
|
||||
void onNodeAdded();
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@ package net.mynero.wallet.fragment.dialog;
|
|||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Patterns;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
@ -9,6 +11,7 @@ import android.view.ViewGroup;
|
|||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
@ -40,18 +43,40 @@ public class EditNodeBottomSheetDialog extends BottomSheetDialogFragment {
|
|||
Button doneEditingButton = view.findViewById(R.id.done_editing_button);
|
||||
EditText addressEditText = view.findViewById(R.id.address_edittext);
|
||||
EditText nodeNameEditText = view.findViewById(R.id.node_name_edittext);
|
||||
ImageButton pasteAddressImageButton = view.findViewById(R.id.paste_address_imagebutton);
|
||||
EditText usernameEditText = view.findViewById(R.id.username_edittext);
|
||||
EditText passwordEditText = view.findViewById(R.id.password_edittext);
|
||||
ImageButton pastePasswordImageButton = view.findViewById(R.id.paste_password_imagebutton);
|
||||
|
||||
Node node = Node.fromString(nodeString);
|
||||
addressEditText.setText(node.getAddress());
|
||||
nodeNameEditText.setText(node.getName());
|
||||
usernameEditText.setText(node.getUsername());
|
||||
if(!node.getPassword().isEmpty()) {
|
||||
passwordEditText.setText(node.getPassword());
|
||||
passwordEditText.setVisibility(View.VISIBLE);
|
||||
pastePasswordImageButton.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
pasteAddressImageButton.setOnClickListener(view1 -> {
|
||||
Context ctx = getContext();
|
||||
if (ctx != null) {
|
||||
addressEditText.setText(Helper.getClipBoardText(ctx));
|
||||
usernameEditText.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) {
|
||||
if(editable.toString().isEmpty()) {
|
||||
passwordEditText.setText(null);
|
||||
passwordEditText.setVisibility(View.GONE);
|
||||
pastePasswordImageButton.setVisibility(View.GONE);
|
||||
} else {
|
||||
passwordEditText.setVisibility(View.VISIBLE);
|
||||
pastePasswordImageButton.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
addPasteListener(view, addressEditText, R.id.paste_address_imagebutton);
|
||||
addPasteListener(view, usernameEditText, R.id.paste_username_imagebutton);
|
||||
addPasteListener(view, passwordEditText, R.id.paste_password_imagebutton);
|
||||
|
||||
deleteNodeButton.setOnClickListener(view1 -> {
|
||||
listener.onNodeDeleted(Node.fromString(nodeString));
|
||||
dismiss();
|
||||
|
@ -59,19 +84,57 @@ public class EditNodeBottomSheetDialog extends BottomSheetDialogFragment {
|
|||
doneEditingButton.setOnClickListener(view1 -> {
|
||||
String nodeAddress = addressEditText.getText().toString();
|
||||
String nodeName = nodeNameEditText.getText().toString();
|
||||
if (nodeAddress.contains(":") && !nodeName.isEmpty()) {
|
||||
String[] nodeParts = nodeAddress.split(":");
|
||||
if (nodeParts.length == 2) {
|
||||
String address = nodeParts[0];
|
||||
int port = Integer.parseInt(nodeParts[1]);
|
||||
String newNodeString = address + ":" + port + "/mainnet/" + nodeName;
|
||||
listener.onNodeEdited(Node.fromString(nodeString), Node.fromString(newNodeString));
|
||||
String user = usernameEditText.getText().toString();
|
||||
String pass = passwordEditText.getText().toString();
|
||||
|
||||
String auth = "";
|
||||
if(!user.isEmpty() && !pass.isEmpty()) {
|
||||
auth = user + ":" + pass + "@";
|
||||
} else if(!user.isEmpty()) {
|
||||
Toast.makeText(getContext(), "Enter password", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
StringBuilder nodeStringBuilder = new StringBuilder();
|
||||
nodeStringBuilder.append(auth);
|
||||
|
||||
if(!nodeName.isEmpty()) {
|
||||
if(!nodeAddress.isEmpty()) {
|
||||
if (nodeAddress.contains(":")) {
|
||||
String[] nodeParts = nodeAddress.split(":");
|
||||
if (nodeParts.length == 2) {
|
||||
String address = nodeParts[0];
|
||||
int port = Integer.parseInt(nodeParts[1]);
|
||||
nodeStringBuilder.append(address).append(":").append(port);
|
||||
}
|
||||
} else {
|
||||
nodeStringBuilder.append(nodeAddress);
|
||||
}
|
||||
|
||||
nodeStringBuilder.append("/mainnet/").append(nodeName);
|
||||
listener.onNodeEdited(Node.fromString(nodeString), Node.fromString(nodeStringBuilder.toString()));
|
||||
} else {
|
||||
Toast.makeText(getContext(), "Enter node address", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
Toast.makeText(getContext(), "Enter node name", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
dismiss();
|
||||
});
|
||||
}
|
||||
|
||||
private void addPasteListener(View root, EditText editText, int layoutId) {
|
||||
ImageButton pasteImageButton = root.findViewById(layoutId);
|
||||
pasteImageButton.setOnClickListener(view1 -> {
|
||||
Context ctx = getContext();
|
||||
if (ctx != null) {
|
||||
editText.setText(Helper.getClipBoardText(ctx));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public interface EditNodeListener {
|
||||
void onNodeDeleted(Node node);
|
||||
void onNodeEdited(Node oldNode, Node newNode);
|
||||
|
|
|
@ -5,10 +5,12 @@ import androidx.lifecycle.MutableLiveData;
|
|||
import androidx.lifecycle.ViewModel;
|
||||
|
||||
import net.mynero.wallet.data.Subaddress;
|
||||
import net.mynero.wallet.model.Wallet;
|
||||
import net.mynero.wallet.model.WalletManager;
|
||||
import net.mynero.wallet.service.AddressService;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class ReceiveViewModel extends ViewModel {
|
||||
|
@ -23,12 +25,13 @@ public class ReceiveViewModel extends ViewModel {
|
|||
}
|
||||
|
||||
private List<Subaddress> getSubaddresses() {
|
||||
Wallet wallet = WalletManager.getInstance().getWallet();
|
||||
ArrayList<Subaddress> subaddresses = new ArrayList<>();
|
||||
int addressesSize = AddressService.getInstance().getLatestAddressIndex();
|
||||
for(int i = 0; i < addressesSize; i++) {
|
||||
subaddresses.add(WalletManager.getInstance().getWallet().getSubaddressObject(i));
|
||||
for(int i = addressesSize - 1; i >= 0; i--) {
|
||||
subaddresses.add(wallet.getSubaddressObject(i));
|
||||
}
|
||||
return subaddresses;
|
||||
return Collections.unmodifiableList(subaddresses);
|
||||
}
|
||||
|
||||
public void getFreshSubaddress() {
|
||||
|
|
|
@ -90,9 +90,9 @@ public class MoneroHandlerThread extends Thread implements WalletListener {
|
|||
|
||||
@Override
|
||||
public void newBlock(long height) {
|
||||
if(isEveryNthBlock(height, 100)) { // refresh services every 100 blocks downloaded
|
||||
refresh(false, height);
|
||||
} else if(isEveryNthBlock(height, 2160)) { // save wallet every 2160 blocks (~3 days)
|
||||
if(isEveryNthBlock(height, 5)) { // refresh services every 5 blocks downloaded
|
||||
refresh(height);
|
||||
} else if(isEveryNthBlock(height, 720)) { // save wallet every 720 blocks (~1 day), we also save upon finishing sync (in refreshed())
|
||||
wallet.store();
|
||||
}
|
||||
BlockchainService.getInstance().setDaemonHeight(wallet.isSynchronized() ? height : 0);
|
||||
|
@ -100,7 +100,7 @@ public class MoneroHandlerThread extends Thread implements WalletListener {
|
|||
|
||||
@Override
|
||||
public void updated() {
|
||||
refresh(false, BlockchainService.GETHEIGHT_FETCH);
|
||||
refresh(BlockchainService.GETHEIGHT_FETCH);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -118,17 +118,15 @@ public class MoneroHandlerThread extends Thread implements WalletListener {
|
|||
BlockchainService.getInstance().setDaemonHeight(height);
|
||||
wallet.setSynchronized();
|
||||
wallet.store();
|
||||
refresh(true, height);
|
||||
refresh(height);
|
||||
}
|
||||
|
||||
BlockchainService.getInstance().setConnectionStatus(status);
|
||||
}
|
||||
|
||||
private void refresh(boolean refreshCoins, long height) {
|
||||
private void refresh(long height) {
|
||||
wallet.refreshHistory();
|
||||
if (refreshCoins) {
|
||||
wallet.refreshCoins();
|
||||
}
|
||||
wallet.refreshCoins();
|
||||
listener.onRefresh(height);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
android:id="@+id/node_name_edittext"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:background="@drawable/edittext_bg"
|
||||
android:ellipsize="middle"
|
||||
android:hint="@string/node_name_hint"
|
||||
|
@ -63,11 +63,12 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:background="@drawable/edittext_bg"
|
||||
android:hint="@string/node_address_hint"
|
||||
android:inputType="text"
|
||||
android:digits="-QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm1234567890.:"
|
||||
app:layout_constraintBottom_toTopOf="@id/add_node_button"
|
||||
app:layout_constraintBottom_toTopOf="@id/username_edittext"
|
||||
app:layout_constraintEnd_toStartOf="@id/paste_address_imagebutton"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
|
@ -75,11 +76,75 @@
|
|||
android:id="@+id/add_node_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="32dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:background="@drawable/button_bg"
|
||||
android:text="@string/add_node"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/address_edittext" />
|
||||
app:layout_constraintTop_toBottomOf="@id/password_edittext" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/username_edittext"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:background="@drawable/edittext_bg"
|
||||
android:hint="@string/node_username_hint"
|
||||
android:inputType="text"
|
||||
android:digits="-QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm1234567890.:"
|
||||
app:layout_constraintBottom_toTopOf="@id/password_edittext"
|
||||
app:layout_constraintEnd_toStartOf="@id/paste_username_imagebutton"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/paste_username_imagebutton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:background="@android:color/transparent"
|
||||
android:minWidth="24dp"
|
||||
android:minHeight="24dp"
|
||||
android:padding="8dp"
|
||||
android:src="@drawable/ic_content_paste_24dp"
|
||||
app:layout_constraintBottom_toBottomOf="@id/username_edittext"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/username_edittext"
|
||||
app:layout_constraintTop_toTopOf="@id/username_edittext"
|
||||
tools:ignore="SpeakableTextPresentCheck" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/password_edittext"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:background="@drawable/edittext_bg"
|
||||
android:hint="@string/node_password_hint"
|
||||
android:inputType="textPassword"
|
||||
android:visibility="gone"
|
||||
android:digits="-QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm1234567890.:"
|
||||
app:layout_constraintBottom_toTopOf="@id/add_node_button"
|
||||
app:layout_constraintEnd_toStartOf="@id/paste_password_imagebutton"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/paste_password_imagebutton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:background="@android:color/transparent"
|
||||
android:minWidth="24dp"
|
||||
android:minHeight="24dp"
|
||||
android:padding="8dp"
|
||||
android:visibility="gone"
|
||||
android:src="@drawable/ic_content_paste_24dp"
|
||||
app:layout_constraintBottom_toBottomOf="@id/password_edittext"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/password_edittext"
|
||||
app:layout_constraintTop_toTopOf="@id/password_edittext"
|
||||
tools:ignore="SpeakableTextPresentCheck" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</ScrollView>
|
|
@ -4,7 +4,9 @@
|
|||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp">
|
||||
android:layout_marginBottom="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:paddingStart="8dp">
|
||||
<TextView
|
||||
android:id="@+id/address_item_address_textview"
|
||||
android:layout_width="0dp"
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
android:id="@+id/node_name_edittext"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:background="@drawable/edittext_bg"
|
||||
android:ellipsize="middle"
|
||||
android:hint="@string/node_name_hint"
|
||||
|
@ -67,32 +67,97 @@
|
|||
android:hint="@string/node_address_hint"
|
||||
android:inputType="text"
|
||||
android:digits="-QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm1234567890.:"
|
||||
app:layout_constraintBottom_toTopOf="@id/delete_node_button"
|
||||
app:layout_constraintBottom_toTopOf="@id/username_edittext"
|
||||
app:layout_constraintEnd_toStartOf="@id/paste_address_imagebutton"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/username_edittext"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:background="@drawable/edittext_bg"
|
||||
android:hint="@string/node_username_hint"
|
||||
android:inputType="text"
|
||||
android:digits="-QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm1234567890.:"
|
||||
app:layout_constraintTop_toBottomOf="@id/address_edittext"
|
||||
app:layout_constraintEnd_toStartOf="@id/paste_username_imagebutton"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/paste_username_imagebutton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:background="@android:color/transparent"
|
||||
android:minWidth="24dp"
|
||||
android:minHeight="24dp"
|
||||
android:padding="8dp"
|
||||
android:src="@drawable/ic_content_paste_24dp"
|
||||
app:layout_constraintBottom_toBottomOf="@id/username_edittext"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/username_edittext"
|
||||
app:layout_constraintTop_toTopOf="@id/username_edittext"
|
||||
tools:ignore="SpeakableTextPresentCheck" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/password_edittext"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:background="@drawable/edittext_bg"
|
||||
android:hint="@string/node_password_hint"
|
||||
android:inputType="textPassword"
|
||||
android:visibility="gone"
|
||||
android:digits="-QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm1234567890.:"
|
||||
app:layout_constraintTop_toBottomOf="@id/username_edittext"
|
||||
app:layout_constraintBottom_toTopOf="@id/delete_node_button"
|
||||
app:layout_constraintEnd_toStartOf="@id/paste_password_imagebutton"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/paste_password_imagebutton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:background="@android:color/transparent"
|
||||
android:minWidth="24dp"
|
||||
android:minHeight="24dp"
|
||||
android:padding="8dp"
|
||||
android:visibility="gone"
|
||||
android:src="@drawable/ic_content_paste_24dp"
|
||||
app:layout_constraintBottom_toBottomOf="@id/password_edittext"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/password_edittext"
|
||||
app:layout_constraintTop_toTopOf="@id/password_edittext"
|
||||
tools:ignore="SpeakableTextPresentCheck" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/delete_node_button"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="32dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginEnd="1dp"
|
||||
android:background="@drawable/button_bg_left"
|
||||
android:text="@string/delete"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/done_editing_button"
|
||||
app:layout_constraintTop_toBottomOf="@id/address_edittext" />
|
||||
app:layout_constraintTop_toBottomOf="@id/password_edittext" />
|
||||
<Button
|
||||
android:id="@+id/done_editing_button"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="32dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginStart="1dp"
|
||||
android:background="@drawable/button_bg_right"
|
||||
android:text="@string/done"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/delete_node_button"
|
||||
app:layout_constraintTop_toBottomOf="@id/address_edittext" />
|
||||
app:layout_constraintTop_toBottomOf="@id/password_edittext" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</ScrollView>
|
|
@ -118,9 +118,7 @@
|
|||
android:layout_height="0dp"
|
||||
android:background="@drawable/round_bg"
|
||||
android:layout_marginTop="64dp"
|
||||
android:paddingTop="8dp"
|
||||
android:clipToPadding="true"
|
||||
android:paddingBottom="8dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
|
|
|
@ -30,6 +30,9 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/button_bg"
|
||||
android:text="@string/add_node"
|
||||
android:textSize="12sp"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
app:layout_constraintStart_toEndOf="@id/nodes_textview"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@id/node_selection_recyclerview"
|
||||
|
|
|
@ -47,6 +47,8 @@
|
|||
android:textSize="12sp"
|
||||
android:textColor="#f00"
|
||||
android:text="@string/wallet_seed_desc"
|
||||
app:layout_constraintVertical_bias="0.0"
|
||||
app:layout_constraintBottom_toTopOf="@id/information_textview"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/wallet_seed_label_textview" />
|
||||
|
@ -95,8 +97,10 @@
|
|||
android:textSize="12sp"
|
||||
android:textColor="#f80"
|
||||
android:text="@string/wallet_viewkey_desc"
|
||||
app:layout_constraintVertical_bias="0.0"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@id/copy_viewkey_imagebutton"
|
||||
app:layout_constraintTop_toBottomOf="@id/wallet_viewkey_label_textview" />
|
||||
|
||||
<TextView
|
||||
|
@ -121,6 +125,8 @@
|
|||
android:padding="8dp"
|
||||
android:src="@drawable/ic_content_copy_24dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintVertical_bias="0.0"
|
||||
app:layout_constraintBottom_toTopOf="@id/wallet_restore_height_label_textview"
|
||||
app:layout_constraintStart_toEndOf="@id/viewkey_textview"
|
||||
app:layout_constraintTop_toBottomOf="@id/wallet_viewkey_desc_textview" />
|
||||
<TextView
|
||||
|
|
|
@ -78,6 +78,8 @@
|
|||
<string name="nodes">Nodes</string>
|
||||
<string name="node_name_hint">My Monero Node</string>
|
||||
<string name="node_address_hint">127.0.0.1:18081</string>
|
||||
<string name="node_username_hint">Username (optional)</string>
|
||||
<string name="node_password_hint">Password</string>
|
||||
<string name="transaction">Transaction</string>
|
||||
<string name="amount_label">Amount</string>
|
||||
<string name="tx_amount_no_prefix">%1$s XMR</string>
|
||||
|
|
Loading…
Reference in a new issue