From 0acc959e4d9d5c3b3ab4e4fdf9673a7286a8f821 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Fri, 8 Jan 2021 14:08:11 -0400 Subject: [PATCH] Save new networks --- src/app/profile/views/network.nim | 3 + src/status/network.nim | 22 ++ .../Profile/Sections/NetworksModal.qml | 200 ++++++++++++++++++ 3 files changed, 225 insertions(+) diff --git a/src/app/profile/views/network.nim b/src/app/profile/views/network.nim index 5c27181530..7fd338e5ac 100644 --- a/src/app/profile/views/network.nim +++ b/src/app/profile/views/network.nim @@ -1,5 +1,6 @@ import NimQml, chronicles import ../../../status/status +import ../../../status/network logScope: topics = "network-view" @@ -43,4 +44,6 @@ QtObject: write = setNetworkAndPersist notify = networkChanged + proc add*(self: NetworkView, name: string, endpoint: string, networkId: int, networkType: string) {.slot.} = + self.status.network.addNetwork(name, endpoint, networkId, networkType) diff --git a/src/status/network.nim b/src/status/network.nim index 9c4851f7a1..fe66ebc07f 100644 --- a/src/status/network.nim +++ b/src/status/network.nim @@ -1,5 +1,10 @@ import chronicles import ../eventemitter +import libstatus/settings +import json +import uuids +import json_serialization +import libstatus/types logScope: topics = "network-model" @@ -30,3 +35,20 @@ proc peerSummaryChange*(self: NetworkModel, peers: seq[string]) = proc peerCount*(self: NetworkModel): int = self.peers.len proc isConnected*(self: NetworkModel): bool = self.connected + +proc addNetwork*(self: NetworkModel, name: string, endpoint: string, networkId: int, networkType: string) = + var networks = getSetting[JsonNode](Setting.Networks_Networks) + let id = genUUID() + networks.elems.add(%*{ + "id": $genUUID(), + "name": name, + "config": { + "NetworkId": networkId, + "DataDir": "/ethereum/" & networkType, + "UpstreamConfig": { + "Enabled": true, + "URL": endpoint + } + } + }) + discard saveSetting(Setting.Networks_Networks, $networks) diff --git a/ui/app/AppLayouts/Profile/Sections/NetworksModal.qml b/ui/app/AppLayouts/Profile/Sections/NetworksModal.qml index 1ea8b4d367..5ab6efb49c 100644 --- a/ui/app/AppLayouts/Profile/Sections/NetworksModal.qml +++ b/ui/app/AppLayouts/Profile/Sections/NetworksModal.qml @@ -18,6 +18,198 @@ ModalPopup { ButtonGroup { id: networkSettings } + Item { + id: addNetwork + width: parent.width + height: addButton.height + + StatusRoundButton { + id: addButton + icon.name: "plusSign" + size: "medium" + anchors.verticalCenter: parent.verticalCenter + } + + ButtonGroup { + id: networkChainGroup + } + + StyledText { + id: usernameText + text: qsTr("Add network") + color: Style.current.blue + anchors.left: addButton.right + anchors.leftMargin: Style.current.padding + anchors.verticalCenter: addButton.verticalCenter + font.pixelSize: 15 + } + + MouseArea { + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + onClicked: addNetworkPopup.open() + } + + ModalPopup { + id: addNetworkPopup + title: qsTr("Add network") + height: 600 + + property string nameValidationError: "" + property string rpcValidationError: "" + property int networkId: 1; + property string networkType: Constants.networkMainnet + + function validate() { + nameValidationError = "" + rpcValidationError = "" + + if (nameInput.text === "") { + nameValidationError = qsTr("You need to enter a name") + } + + if (rpcInput.text === "") { + rpcValidationError = qsTr("You need to enter the RPC endpoint URL") + } else if(!Utils.isURL(rpcInput.text)) { + rpcValidationError = qsTr("Invalid URL") + } + + return !nameValidationError && !rpcValidationError + } + + onOpened: { + nameInput.text = ""; + rpcInput.text = ""; + mainnetRadioBtn.checked = true; + addNetworkPopup.networkId = 1; + addNetworkPopup.networkType = Constants.networkMainnet; + + nameValidationError = ""; + rpcValidationError = ""; + } + + footer: StyledButton { + anchors.right: parent.right + anchors.rightMargin: Style.current.smallPadding + label: qsTr("Save") + anchors.bottom: parent.bottom + disabled: nameInput.text == "" || rpcInput.text == "" + onClicked: { + if (!addNetworkPopup.validate()) { + return; + } + profileModel.network.add(nameInput.text, rpcInput.text, addNetworkPopup.networkId, addNetworkPopup.networkType) + addNetworkPopup.close() + } + } + + Input { + id: nameInput + label: qsTr("Name") + placeholderText: qsTr("Specify a name") + validationError: addNetworkPopup.nameValidationError + } + + Input { + id: rpcInput + label: qsTr("RPC URL") + placeholderText: qsTr("Specify a RPC URL") + validationError: addNetworkPopup.rpcValidationError + anchors.top: nameInput.bottom + anchors.topMargin: Style.current.bigPadding + } + + StatusSectionHeadline { + id: networkChainHeadline + text: qsTr("Network chain") + anchors.top: rpcInput.bottom + anchors.topMargin: Style.current.bigPadding + } + + Column { + spacing: Style.current.padding + anchors.top: networkChainHeadline.bottom + anchors.topMargin: Style.current.smallPadding + anchors.left: parent.left + anchors.right: parent.right + + RowLayout { + width: parent.width + StyledText { + text: qsTr("Main network") + font.pixelSize: 15 + } + + StatusRadioButton { + id: mainnetRadioBtn + Layout.alignment: Qt.AlignRight + ButtonGroup.group: networkChainGroup + rightPadding: 0 + checked: true + onClicked: { + addNetworkPopup.networkId = 1; + addNetworkPopup.networkType = Constants.networkMainnet; + } + } + } + + RowLayout { + width: parent.width + StyledText { + text: qsTr("Ropsten test network") + font.pixelSize: 15 + } + StatusRadioButton { + id: ropstenRadioBtn + Layout.alignment: Qt.AlignRight + ButtonGroup.group: networkChainGroup + rightPadding: 0 + onClicked: { + addNetworkPopup.networkId = 3; + addNetworkPopup.networkType = Constants.networkRopsten; + } + } + } + + RowLayout { + width: parent.width + StyledText { + text: qsTr("Rinkeby test network") + font.pixelSize: 15 + } + StatusRadioButton { + id: rinkebyRadioBtn + Layout.alignment: Qt.AlignRight + ButtonGroup.group: networkChainGroup + rightPadding: 0 + onClicked: { + addNetworkPopup.networkId = 4; + addNetworkPopup.networkType = Constants.networkRinkeby; + } + } + } + + RowLayout { + width: parent.width + StyledText { + text: qsTr("Custom") + font.pixelSize: 15 + } + StatusRadioButton { + id: customRadioBtn + Layout.alignment: Qt.AlignRight + ButtonGroup.group: networkChainGroup + rightPadding: 0 + onClicked: { + addNetworkPopup.networkId = 55; // TODO + addNetworkPopup.networkType = ""; + } + } + } + } + } + } + StatusSectionHeadline { text: qsTr("Main networks") } @@ -49,6 +241,14 @@ ModalPopup { NetworkRadioSelector { network: Constants.networkRopsten } + + StatusSectionHeadline { + text: qsTr("Custom Networks") + } + + NetworkRadioSelector { + network: "SOME NETWORK" + } } StyledText {