mirror of
https://codeberg.org/anoncontributorxmr/mysu.git
synced 2024-12-22 21:17:47 +00:00
Add feature to edit/delete nodes from list
This commit is contained in:
parent
2b92660dcb
commit
58329e5212
6 changed files with 265 additions and 2 deletions
|
@ -20,6 +20,7 @@ import android.view.LayoutInflater;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
|
@ -79,6 +80,7 @@ public class NodeSelectionAdapter extends RecyclerView.Adapter<NodeSelectionAdap
|
|||
|
||||
public interface NodeSelectionAdapterListener {
|
||||
void onSelectNode(Node node);
|
||||
boolean onSelectEditNode(Node node);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -108,8 +110,29 @@ public class NodeSelectionAdapter extends RecyclerView.Adapter<NodeSelectionAdap
|
|||
nodeNameTextView.setText(node.getName());
|
||||
nodeAddressTextView.setText(node.getAddress());
|
||||
|
||||
itemView.setOnLongClickListener(view -> {
|
||||
if(match) {
|
||||
Toast.makeText(itemView.getContext(), itemView.getResources().getString(R.string.cant_edit_current_node), Toast.LENGTH_SHORT).show();
|
||||
return false;
|
||||
} else if(isDefaultNode(node)) {
|
||||
Toast.makeText(itemView.getContext(), itemView.getResources().getString(R.string.cant_edit_default_nodes), Toast.LENGTH_SHORT).show();
|
||||
return false;
|
||||
} else {
|
||||
return listener.onSelectEditNode(node);
|
||||
}
|
||||
});
|
||||
itemView.setOnClickListener(view -> listener.onSelectNode(node));
|
||||
}
|
||||
|
||||
private boolean isDefaultNode(Node currentNode) {
|
||||
boolean isDefault = false;
|
||||
for(DefaultNodes defaultNode : DefaultNodes.values()) {
|
||||
if(currentNode.toNodeString().equals(defaultNode.getUri()))
|
||||
isDefault = true;
|
||||
}
|
||||
|
||||
return isDefault;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
package net.mynero.wallet.fragment.dialog;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
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.ImageButton;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
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;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
|
||||
public class EditNodeBottomSheetDialog extends BottomSheetDialogFragment {
|
||||
public EditNodeListener listener = null;
|
||||
public String nodeString = "";
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.edit_node_bottom_sheet_dialog, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
Button deleteNodeButton = view.findViewById(R.id.delete_node_button);
|
||||
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);
|
||||
|
||||
Node node = Node.fromString(nodeString);
|
||||
addressEditText.setText(node.getAddress());
|
||||
nodeNameEditText.setText(node.getName());
|
||||
|
||||
pasteAddressImageButton.setOnClickListener(view1 -> {
|
||||
Context ctx = getContext();
|
||||
if (ctx != null) {
|
||||
addressEditText.setText(Helper.getClipBoardText(ctx));
|
||||
}
|
||||
});
|
||||
deleteNodeButton.setOnClickListener(view1 -> {
|
||||
listener.onNodeDeleted(Node.fromString(nodeString));
|
||||
dismiss();
|
||||
});
|
||||
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));
|
||||
}
|
||||
}
|
||||
dismiss();
|
||||
});
|
||||
}
|
||||
|
||||
public interface EditNodeListener {
|
||||
void onNodeDeleted(Node node);
|
||||
void onNodeEdited(Node oldNode, Node newNode);
|
||||
}
|
||||
}
|
|
@ -89,9 +89,18 @@ public class NodeSelectionBottomSheetDialog extends BottomSheetDialogFragment im
|
|||
listener.onNodeSelected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSelectEditNode(Node node) {
|
||||
if (listener != null) {
|
||||
listener.onClickedEditNode(node.toNodeString());
|
||||
}
|
||||
dismiss();
|
||||
return true;
|
||||
}
|
||||
|
||||
public interface NodeSelectionDialogListener {
|
||||
void onNodeSelected();
|
||||
|
||||
void onClickedEditNode(String nodeString);
|
||||
void onClickedAddNode();
|
||||
}
|
||||
}
|
|
@ -27,6 +27,7 @@ import net.mynero.wallet.R;
|
|||
import net.mynero.wallet.data.DefaultNodes;
|
||||
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.WalletKeysBottomSheetDialog;
|
||||
import net.mynero.wallet.fragment.dialog.NodeSelectionBottomSheetDialog;
|
||||
import net.mynero.wallet.fragment.dialog.PasswordBottomSheetDialog;
|
||||
|
@ -38,7 +39,9 @@ import net.mynero.wallet.util.Constants;
|
|||
import net.mynero.wallet.util.DayNightMode;
|
||||
import net.mynero.wallet.util.NightmodeHelper;
|
||||
|
||||
public class SettingsFragment extends Fragment implements PasswordBottomSheetDialog.PasswordListener, NodeSelectionBottomSheetDialog.NodeSelectionDialogListener, AddNodeBottomSheetDialog.AddNodeListener {
|
||||
import org.json.JSONArray;
|
||||
|
||||
public class SettingsFragment extends Fragment implements PasswordBottomSheetDialog.PasswordListener, NodeSelectionBottomSheetDialog.NodeSelectionDialogListener, AddNodeBottomSheetDialog.AddNodeListener, EditNodeBottomSheetDialog.EditNodeListener {
|
||||
|
||||
private SettingsViewModel mViewModel;
|
||||
TextWatcher proxyAddressListener = new TextWatcher() {
|
||||
|
@ -235,6 +238,14 @@ public class SettingsFragment extends Fragment implements PasswordBottomSheetDia
|
|||
addNodeDialog.show(getActivity().getSupportFragmentManager(), "add_node_dialog");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClickedEditNode(String nodeString) {
|
||||
EditNodeBottomSheetDialog editNodeDialog = new EditNodeBottomSheetDialog();
|
||||
editNodeDialog.listener = this;
|
||||
editNodeDialog.nodeString = nodeString;
|
||||
editNodeDialog.show(getActivity().getSupportFragmentManager(), "edit_node_dialog");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNodeAdded() {
|
||||
NodeSelectionBottomSheetDialog dialog = new NodeSelectionBottomSheetDialog();
|
||||
|
@ -253,4 +264,43 @@ public class SettingsFragment extends Fragment implements PasswordBottomSheetDia
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNodeDeleted(Node node) {
|
||||
try {
|
||||
String nodesArray = PrefService.getInstance().getString(Constants.PREF_CUSTOM_NODES, "[]");
|
||||
JSONArray jsonArray = new JSONArray(nodesArray);
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
String jsonNodeString = jsonArray.getString(i);
|
||||
Node savedNode = Node.fromString(jsonNodeString);
|
||||
if (savedNode.toNodeString().equals(node.toNodeString()))
|
||||
jsonArray.remove(i);
|
||||
}
|
||||
saveNodesAndReopen(jsonArray);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNodeEdited(Node oldNode, Node newNode) {
|
||||
try {
|
||||
String nodesArray = PrefService.getInstance().getString(Constants.PREF_CUSTOM_NODES, "[]");
|
||||
JSONArray jsonArray = new JSONArray(nodesArray);
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
String jsonNodeString = jsonArray.getString(i);
|
||||
Node savedNode = Node.fromString(jsonNodeString);
|
||||
if (savedNode.toNodeString().equals(oldNode.toNodeString()))
|
||||
jsonArray.put(i, newNode.toNodeString());
|
||||
}
|
||||
saveNodesAndReopen(jsonArray);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void saveNodesAndReopen(JSONArray jsonArray) {
|
||||
PrefService.getInstance().edit().putString(Constants.PREF_CUSTOM_NODES, jsonArray.toString()).apply();
|
||||
onNodeAdded();
|
||||
}
|
||||
}
|
97
app/src/main/res/layout/edit_node_bottom_sheet_dialog.xml
Normal file
97
app/src/main/res/layout/edit_node_bottom_sheet_dialog.xml
Normal file
|
@ -0,0 +1,97 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fillViewport="true"
|
||||
android:fitsSystemWindows="true"
|
||||
android:padding="24dp">
|
||||
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<!-- CREATE LAYOUT -->
|
||||
<TextView
|
||||
android:id="@+id/send_monero_textview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:text="@string/edit_node"
|
||||
android:textSize="32sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toTopOf="@id/node_name_edittext"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/node_name_edittext"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:background="@drawable/edittext_bg"
|
||||
android:ellipsize="middle"
|
||||
android:hint="@string/node_name_hint"
|
||||
android:singleLine="true"
|
||||
app:layout_constraintBottom_toTopOf="@id/address_edittext"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/send_monero_textview" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/paste_address_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/address_edittext"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/address_edittext"
|
||||
app:layout_constraintTop_toTopOf="@id/address_edittext"
|
||||
tools:ignore="SpeakableTextPresentCheck" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/address_edittext"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:background="@drawable/edittext_bg"
|
||||
android:hint="@string/node_address_hint"
|
||||
android:inputType="text"
|
||||
android:digits="-QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm1234567890.:"
|
||||
app:layout_constraintBottom_toTopOf="@id/delete_node_button"
|
||||
app:layout_constraintEnd_toStartOf="@id/paste_address_imagebutton"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/delete_node_button"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="32dp"
|
||||
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" />
|
||||
<Button
|
||||
android:id="@+id/done_editing_button"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="32dp"
|
||||
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" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</ScrollView>
|
|
@ -99,4 +99,9 @@
|
|||
<string name="create_wallet_failed">Create wallet failed: %1$s</string>
|
||||
<string name="wallet_keys_label">Wallet Keys</string>
|
||||
<string name="max_subaddresses_warning">Max subaddresses. Please receive funds first.</string>
|
||||
<string name="done">Done</string>
|
||||
<string name="delete">Delete</string>
|
||||
<string name="cant_edit_current_node">Cannot edit current node.</string>
|
||||
<string name="cant_edit_default_nodes">Cannot edit default node.</string>
|
||||
<string name="edit_node">Edit Node</string>
|
||||
</resources>
|
||||
|
|
Loading…
Reference in a new issue