mirror of
https://codeberg.org/r4v3r23/mysu.git
synced 2024-11-09 20:53:47 +01:00
Add feature to edit/delete nodes from list
This commit is contained in:
parent
2b92660dcb
commit
58329e5212
@ -20,6 +20,7 @@ import android.view.LayoutInflater;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
@ -79,6 +80,7 @@ public class NodeSelectionAdapter extends RecyclerView.Adapter<NodeSelectionAdap
|
|||||||
|
|
||||||
public interface NodeSelectionAdapterListener {
|
public interface NodeSelectionAdapterListener {
|
||||||
void onSelectNode(Node node);
|
void onSelectNode(Node node);
|
||||||
|
boolean onSelectEditNode(Node node);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -108,8 +110,29 @@ public class NodeSelectionAdapter extends RecyclerView.Adapter<NodeSelectionAdap
|
|||||||
nodeNameTextView.setText(node.getName());
|
nodeNameTextView.setText(node.getName());
|
||||||
nodeAddressTextView.setText(node.getAddress());
|
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));
|
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();
|
listener.onNodeSelected();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onSelectEditNode(Node node) {
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onClickedEditNode(node.toNodeString());
|
||||||
|
}
|
||||||
|
dismiss();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public interface NodeSelectionDialogListener {
|
public interface NodeSelectionDialogListener {
|
||||||
void onNodeSelected();
|
void onNodeSelected();
|
||||||
|
void onClickedEditNode(String nodeString);
|
||||||
void onClickedAddNode();
|
void onClickedAddNode();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -27,6 +27,7 @@ import net.mynero.wallet.R;
|
|||||||
import net.mynero.wallet.data.DefaultNodes;
|
import net.mynero.wallet.data.DefaultNodes;
|
||||||
import net.mynero.wallet.data.Node;
|
import net.mynero.wallet.data.Node;
|
||||||
import net.mynero.wallet.fragment.dialog.AddNodeBottomSheetDialog;
|
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.WalletKeysBottomSheetDialog;
|
||||||
import net.mynero.wallet.fragment.dialog.NodeSelectionBottomSheetDialog;
|
import net.mynero.wallet.fragment.dialog.NodeSelectionBottomSheetDialog;
|
||||||
import net.mynero.wallet.fragment.dialog.PasswordBottomSheetDialog;
|
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.DayNightMode;
|
||||||
import net.mynero.wallet.util.NightmodeHelper;
|
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;
|
private SettingsViewModel mViewModel;
|
||||||
TextWatcher proxyAddressListener = new TextWatcher() {
|
TextWatcher proxyAddressListener = new TextWatcher() {
|
||||||
@ -235,6 +238,14 @@ public class SettingsFragment extends Fragment implements PasswordBottomSheetDia
|
|||||||
addNodeDialog.show(getActivity().getSupportFragmentManager(), "add_node_dialog");
|
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
|
@Override
|
||||||
public void onNodeAdded() {
|
public void onNodeAdded() {
|
||||||
NodeSelectionBottomSheetDialog dialog = new NodeSelectionBottomSheetDialog();
|
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="create_wallet_failed">Create wallet failed: %1$s</string>
|
||||||
<string name="wallet_keys_label">Wallet Keys</string>
|
<string name="wallet_keys_label">Wallet Keys</string>
|
||||||
<string name="max_subaddresses_warning">Max subaddresses. Please receive funds first.</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>
|
</resources>
|
||||||
|
Loading…
Reference in New Issue
Block a user