From 2c13227809ad735f20a63f46ecf53aa66c3ff5d8 Mon Sep 17 00:00:00 2001
From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com>
Date: Sat, 17 Sep 2022 11:16:38 +0200
Subject: [PATCH] update nodes list with names and import / export
---
.../functional-components/settings-page.js | 191 ++++++++++++++++--
.../src/redux/app/actions/node-config.js | 31 +--
2 files changed, 174 insertions(+), 48 deletions(-)
diff --git a/qortal-ui-core/src/functional-components/settings-page.js b/qortal-ui-core/src/functional-components/settings-page.js
index 83520f5d..2540f5d7 100644
--- a/qortal-ui-core/src/functional-components/settings-page.js
+++ b/qortal-ui-core/src/functional-components/settings-page.js
@@ -1,11 +1,12 @@
import { LitElement, html, css } from 'lit'
import { connect } from 'pwa-helpers'
import { store } from '../store.js'
-import { doAddNode, doSetNode } from '../redux/app/app-actions.js'
+import { doAddNode, doSetNode, doLoadNodeConfig } from '../redux/app/app-actions.js'
+import { get, translate, translateUnsafeHTML } from 'lit-translate'
+import FileSaver from 'file-saver'
import snackbar from './snackbar.js'
-import { translate, translateUnsafeHTML } from 'lit-translate'
import '../components/language-selector.js'
-
+import '../custom-elements/frag-file-input.js'
import '@material/mwc-dialog'
import '@material/mwc-button'
import '@material/mwc-select'
@@ -32,6 +33,9 @@ class SettingsPage extends connect(store)(LitElement) {
--mdc-dialog-content-ink-color: var(--black);
--mdc-theme-surface: var(--white);
--mdc-theme-text-primary-on-background: var(--black);
+ --mdc-dialog-min-width: 300px;
+ --mdc-dialog-max-width: 650px;
+ --mdc-dialog-max-height: 700px;
}
#main {
@@ -45,16 +49,40 @@ class SettingsPage extends connect(store)(LitElement) {
--mdc-icon-size: 36px;
}
+ span.name {
+ display: inline-block;
+ width: 150px;
+ font-weight: 600;
+ color: #03a9f4;
+ border: 1px solid transparent;
+ }
+
.red {
--mdc-theme-primary: red;
}
+
+ .buttonred {
+ color: #f44336;
+ }
+
+ .buttongreen {
+ color: #03c851;
+ }
+
+ .floatleft {
+ float: left;
+ }
+
+ .floatright {
+ float: right;
+ }
`
}
constructor() {
super()
this.nodeConfig = {}
- this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light';
+ this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
}
render() {
@@ -65,16 +93,25 @@ class SettingsPage extends connect(store)(LitElement) {
-
+
this.nodeSelected(e)}" style="min-width: 130px; max-width:100%; width:100%;">
${this.nodeConfig.knownNodes.map((n, index) => html`
- ${n.protocol + '://' + n.domain + ':' + n.port}
+
+ ${n.name}
+ ${n.protocol + '://' + n.domain + ':' + n.port}
+
`)}
-
${translate("settings.nodehint")}
+
${translate("settings.nodehint")}
- this.shadowRoot.querySelector('#addNodeDialog').show()}">add${translate("settings.addcustomnode")}
+ this.shadowRoot.querySelector('#addNodeDialog').show()}">add${translate("settings.addcustomnode")}
+
+ this.removeList()}">remove${translate("settings.deletecustomnode")}
+
+
+
${this.renderExportNodesListButton()}
${this.renderImportNodesListButton()}
+
@@ -99,7 +136,9 @@ class SettingsPage extends connect(store)(LitElement) {
-
+
+
+
http
https
@@ -120,6 +159,26 @@ class SettingsPage extends connect(store)(LitElement) {
${translate("settings.addandsave")}
+
+
+
+
${translate("settings.import")}
+
+
+
+
+ this.importQortalNodesList(e.detail.result)}">
+
${translate("walletpage.wchange56")}
+ ${translate("settings.warning")}
+
+
+ ${translate("general.close")}
+
+
`
}
@@ -127,15 +186,46 @@ class SettingsPage extends connect(store)(LitElement) {
// ...
}
- stateChanged(state) {
- this.config = state.config
- this.nodeConfig = state.app.nodeConfig
- }
-
show() {
this.shadowRoot.getElementById('settingsDialog').show()
}
+ close() {
+ this.shadowRoot.getElementById('settingsDialog').close()
+ }
+
+ removeList() {
+ localStorage.removeItem("myQortalNodes")
+
+ const obj1 = {
+ name: 'Local Node',
+ protocol: 'http',
+ domain: '127.0.0.1',
+ port: 12391,
+ enableManagement: true
+ }
+
+ const obj2 = {
+ name: 'Local Testnet',
+ protocol: 'http',
+ domain: '127.0.0.1',
+ port: 62391,
+ enableManagement: true
+ }
+
+ var renewNodes = [];
+ renewNodes.push(obj1,obj2)
+ localStorage.setItem('myQortalNodes', JSON.stringify(renewNodes))
+
+ let snack1string = get("settings.snack1")
+ snackbar.add({
+ labelText: `${snack1string}`,
+ dismiss: true
+ })
+
+ store.dispatch(doLoadNodeConfig())
+ }
+
nodeSelected(e) {
const selectedNodeIndex = this.shadowRoot.getElementById('nodeSelect').value
const selectedNode = this.nodeConfig.knownNodes[selectedNodeIndex]
@@ -144,22 +234,26 @@ class SettingsPage extends connect(store)(LitElement) {
const index = parseInt(selectedNodeIndex)
if (isNaN(index)) return
- // Set selected node
store.dispatch(doSetNode(selectedNodeIndex))
+
+ let snack2string = get("settings.snack2")
snackbar.add({
- labelText: `UI Set To Node : ${selectedNodeUrl}`,
+ labelText: `${snack2string} : ${selectedNodeUrl}`,
dismiss: true
})
+
this.shadowRoot.querySelector('#settingsDialog').close()
}
addNode() {
+ const nameInput = this.shadowRoot.getElementById('nameInput').value
const protocolList = this.shadowRoot.getElementById('protocolList').value
const domainInput = this.shadowRoot.getElementById('domainInput').value
const portInput = this.shadowRoot.getElementById('portInput').value
if (protocolList.length >= 4 && domainInput.length >= 3 && portInput.length >= 4) {
const nodeObject = {
+ name: nameInput,
protocol: protocolList,
domain: domainInput,
port: portInput,
@@ -168,19 +262,21 @@ class SettingsPage extends connect(store)(LitElement) {
store.dispatch(doAddNode(nodeObject))
- const haveNodes = JSON.parse(localStorage.getItem('myQortalNodes'));
+ const haveNodes = JSON.parse(localStorage.getItem('myQortalNodes'))
if (haveNodes === null || haveNodes.length === 0) {
var savedNodes = [];
savedNodes.push(nodeObject);
- localStorage.setItem('myQortalNodes', JSON.stringify(savedNodes));
+ localStorage.setItem('myQortalNodes', JSON.stringify(savedNodes))
+ let snack3string = get("settings.snack3")
snackbar.add({
- labelText: 'Successfully Added And Saved Custom Node',
+ labelText: `${snack3string}`,
dismiss: true
})
+ this.shadowRoot.getElementById('nameInput').value = ''
this.shadowRoot.getElementById('protocolList').value = ''
this.shadowRoot.getElementById('domainInput').value = ''
this.shadowRoot.getElementById('portInput').value = ''
@@ -193,11 +289,13 @@ class SettingsPage extends connect(store)(LitElement) {
stored.push(nodeObject);
localStorage.setItem('myQortalNodes', JSON.stringify(stored));
+ let snack3string = get("settings.snack3")
snackbar.add({
- labelText: 'Successfully Added And Saved Custom Node',
+ labelText: `${snack3string}`,
dismiss: true
})
+ this.shadowRoot.getElementById('nameInput').value = ''
this.shadowRoot.getElementById('protocolList').value = ''
this.shadowRoot.getElementById('domainInput').value = ''
this.shadowRoot.getElementById('portInput').value = ''
@@ -206,6 +304,59 @@ class SettingsPage extends connect(store)(LitElement) {
}
}
}
+
+ openImportNodesDialog() {
+ this.shadowRoot.querySelector("#importQortalNodesListDialog").show()
+ }
+
+ closeImportNodesDialog() {
+ this.shadowRoot.querySelector("#importQortalNodesListDialog").close()
+ }
+
+ renderExportNodesListButton() {
+ return html`
+ this.exportQortalNodesList()}">
+ `
+ }
+
+ exportQortalNodesList() {
+ const qortalNodesList = JSON.stringify(localStorage.getItem("myQortalNodes"))
+ const qortalNodesListSave = JSON.parse((qortalNodesList) || "[]")
+ const blob = new Blob([qortalNodesListSave], { type: 'text/plain;charset=utf-8' })
+ FileSaver.saveAs(blob, `qortal.nodes`)
+
+ let snack4string = get("settings.snack4")
+ snackbar.add({
+ labelText: `${snack4string} qortal.nodes`,
+ dismiss: true
+ })
+ }
+
+ renderImportNodesListButton() {
+ return html`
+ this.openImportNodesDialog()}">
+ `
+ }
+
+ async importQortalNodesList(file) {
+ localStorage.removeItem("myQortalNodes")
+ const newItems = JSON.parse((file) || "[]")
+ localStorage.setItem("myQortalNodes", JSON.stringify(newItems))
+ this.shadowRoot.querySelector('#importQortalNodesListDialog').close()
+
+ let snack5string = get("settings.snack5")
+ snackbar.add({
+ labelText: `${snack5string}`,
+ dismiss: true
+ })
+
+ store.dispatch(doLoadNodeConfig())
+ }
+
+ stateChanged(state) {
+ this.config = state.config
+ this.nodeConfig = state.app.nodeConfig
+ }
}
window.customElements.define('settings-page', SettingsPage)
diff --git a/qortal-ui-core/src/redux/app/actions/node-config.js b/qortal-ui-core/src/redux/app/actions/node-config.js
index 7c4be8c4..8181553f 100644
--- a/qortal-ui-core/src/redux/app/actions/node-config.js
+++ b/qortal-ui-core/src/redux/app/actions/node-config.js
@@ -23,7 +23,7 @@ export const doLoadNodeConfig = () => {
if (checkNodes === null || checkNodes.length === 0) {
var saveNode = [];
- saveNode.push(obj1,obj2,obj3,obj4,obj5,obj6);
+ saveNode.push(obj1,obj2);
localStorage.setItem('myQortalNodes', JSON.stringify(saveNode));
nodeConfig.knownNodes = JSON.parse(localStorage.getItem('myQortalNodes'));
} else{
@@ -73,6 +73,7 @@ const addNode = (payload) => {
}
const obj1 = {
+ name: 'Local Node',
protocol: 'http',
domain: '127.0.0.1',
port: 12391,
@@ -80,36 +81,10 @@ const obj1 = {
}
const obj2 = {
- protocol: 'http',
- domain: 'node1.qortal.org',
- port: 12391,
- enableManagement: false
-}
-
-const obj3 = {
- protocol: 'http',
- domain: 'node2.qortal.org',
- port: 12391,
- enableManagement: false
-}
-
-const obj4 = {
+ name: 'Local Testnet',
protocol: 'http',
domain: '127.0.0.1',
port: 62391,
enableManagement: true
}
-const obj5 = {
- protocol: 'http',
- domain: 'node1.qortal.org',
- port: 62391,
- enableManagement: false
-}
-
-const obj6 = {
- protocol: 'http',
- domain: 'node2.qortal.org',
- port: 62391,
- enableManagement: false
-}