mirror of
https://github.com/Qortal/qortal-ui.git
synced 2025-05-07 18:27:53 +00:00
305 lines
11 KiB
JavaScript
305 lines
11 KiB
JavaScript
import { LitElement, html, css } from 'lit'
|
|
import { connect } from 'pwa-helpers'
|
|
import { store } from '../store.js'
|
|
import { doPageUrl } from '../redux/app/app-actions.js'
|
|
import { translate, translateUnsafeHTML } from 'lit-translate'
|
|
import WebWorker from 'web-worker:./computePowWorker.js';
|
|
import { routes } from '../plugins/routes.js';
|
|
|
|
import '@material/mwc-icon'
|
|
import '@material/mwc-button'
|
|
|
|
class AppInfo extends connect(store)(LitElement) {
|
|
static get properties() {
|
|
return {
|
|
blockInfo: { type: Object },
|
|
nodeStatus: { type: Object },
|
|
nodeInfo: { type: Array },
|
|
coreInfo: { type: Array },
|
|
nodeConfig: { type: Object },
|
|
pageUrl: { type: String },
|
|
publicizeAddress: { type: String },
|
|
theme: { type: String, reflect: true }
|
|
}
|
|
}
|
|
|
|
static get styles() {
|
|
return [
|
|
css`
|
|
* {
|
|
--mdc-theme-primary: rgb(3, 169, 244);
|
|
--paper-input-container-focus-color: var(--mdc-theme-primary);
|
|
}
|
|
.normal {
|
|
--mdc-theme-primary: rgb(3, 169, 244);
|
|
}
|
|
|
|
.normal-button {
|
|
--mdc-theme-primary: rgb(3, 169, 244);
|
|
--mdc-theme-on-primary: white;
|
|
}
|
|
|
|
mwc-button.normal-button {
|
|
--mdc-theme-primary: rgb(3, 169, 244);
|
|
--mdc-theme-on-primary: white;
|
|
}
|
|
.test-net {
|
|
--mdc-theme-primary: black;
|
|
}
|
|
|
|
.test-net-button {
|
|
--mdc-theme-primary: black;
|
|
--mdc-theme-on-primary: white;
|
|
}
|
|
|
|
mwc-button.test-net-button {
|
|
--mdc-theme-primary: black;
|
|
--mdc-theme-on-primary: white;
|
|
}
|
|
#profileInMenu {
|
|
flex: 0 0 100px;
|
|
padding:12px;
|
|
border-top: 1px solid var(--border);
|
|
background: var(--sidetopbar);
|
|
}
|
|
.info {
|
|
margin: 0;
|
|
font-size: 14px;
|
|
font-weight:100;
|
|
display: inline-block;
|
|
width:100%;
|
|
padding-bottom:8px;
|
|
color: var(--black);
|
|
}
|
|
.blue {
|
|
color: #03a9f4;
|
|
margin: 0;
|
|
font-size: 14px;
|
|
font-weight:200;
|
|
display: inline;
|
|
}
|
|
.black {
|
|
color: var(--black);
|
|
margin: 0;
|
|
font-size: 14px;
|
|
font-weight:200;
|
|
display: inline;
|
|
}
|
|
`
|
|
]
|
|
}
|
|
|
|
constructor() {
|
|
super()
|
|
this.blockInfo = {}
|
|
this.nodeInfo = []
|
|
this.coreInfo = []
|
|
this.nodeStatus = {}
|
|
this.pageUrl = ''
|
|
this.publicizeAddress = ''
|
|
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
|
this.publicKeyisOnChainConfirmation = false
|
|
this.interval
|
|
}
|
|
|
|
render() {
|
|
return html`
|
|
<div id="profileInMenu">
|
|
<span class="info">${translate("appinfo.uiversion")}: ${this.nodeConfig.version ? this.nodeConfig.version : ''}</span>
|
|
${this._renderCoreVersion()}
|
|
<span class="info">${translate("appinfo.blockheight")}: ${this.nodeInfo.height ? this.nodeInfo.height : ''} <span class=${this.cssStatus}>${this._renderStatus()}</span></span>
|
|
<span class="info">${translate("appinfo.peers")}: ${this.nodeInfo.numberOfConnections ? this.nodeInfo.numberOfConnections : ''}
|
|
<a id="pageLink"></a>
|
|
</div>
|
|
`
|
|
}
|
|
|
|
firstUpdated() {
|
|
this.publicizeAddress = store.getState().app.selectedAddress.address + '_publicize'
|
|
this.setStorage()
|
|
this.getNodeInfo()
|
|
this.getCoreInfo()
|
|
try {
|
|
this.confirmPublicKeyOnChain(store.getState().app.selectedAddress.address)
|
|
} catch (error) {
|
|
console.error(error)
|
|
}
|
|
|
|
setInterval(() => {
|
|
this.getNodeInfo()
|
|
this.getCoreInfo()
|
|
}, 30000)
|
|
}
|
|
|
|
setStorage() {
|
|
if (localStorage.getItem(this.publicizeAddress) === null) {
|
|
localStorage.setItem(this.publicizeAddress, 'false')
|
|
}
|
|
}
|
|
|
|
async confirmPublicKeyOnChain(address) {
|
|
const _computePow2 = async (chatBytes) => {
|
|
const difficulty = 14
|
|
const path = window.parent.location.origin + '/memory-pow/memory-pow.wasm.full'
|
|
const worker = new WebWorker();
|
|
let nonce = null
|
|
let chatBytesArray = null
|
|
await new Promise((res, rej) => {
|
|
worker.postMessage({chatBytes, path, difficulty})
|
|
|
|
worker.onmessage = e => {
|
|
worker.terminate()
|
|
chatBytesArray = e.data.chatBytesArray
|
|
nonce = e.data.nonce
|
|
res()
|
|
}
|
|
})
|
|
|
|
let _response = await routes.sign_chat({
|
|
data: {
|
|
nonce: store.getState().app.selectedAddress.nonce,
|
|
chatBytesArray: chatBytesArray,
|
|
chatNonce: nonce
|
|
},
|
|
})
|
|
return _response
|
|
}
|
|
|
|
let stop = false
|
|
const checkPublicKey = async () => {
|
|
if (!stop) {
|
|
stop = true
|
|
try {
|
|
if(localStorage.getItem(this.publicizeAddress) === 'true') {
|
|
clearInterval(this.interval)
|
|
return
|
|
}
|
|
const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
|
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
|
const url = `${nodeUrl}/addresses/publickey/${address}`
|
|
const res = await fetch(url)
|
|
let data = ''
|
|
try {
|
|
data = await res.text()
|
|
} catch (error) {
|
|
data = {
|
|
error: 'error'
|
|
}
|
|
}
|
|
if(data === 'false' && this.nodeInfo.isSynchronizing !== true) {
|
|
let _reference = new Uint8Array(64)
|
|
window.crypto.getRandomValues(_reference)
|
|
let reference = window.parent.Base58.encode(_reference)
|
|
const chatRes = await routes.chat({
|
|
data: {
|
|
type: 19,
|
|
nonce: store.getState().app.selectedAddress.nonce,
|
|
params: {
|
|
lastReference: reference,
|
|
proofOfWorkNonce: 0,
|
|
fee: 0,
|
|
timestamp: Date.now(),
|
|
},
|
|
disableModal: true
|
|
},
|
|
disableModal: true,
|
|
});
|
|
|
|
try {
|
|
const powRes = await _computePow2(chatRes)
|
|
if(powRes === true) {
|
|
clearInterval(this.interval)
|
|
localStorage.removeItem(this.publicizeAddress)
|
|
localStorage.setItem(this.publicizeAddress, 'true')
|
|
}
|
|
} catch (error) {
|
|
console.error(error)
|
|
}
|
|
}
|
|
|
|
if (!data.error && data !== 'false' && data) {
|
|
clearInterval(this.interval)
|
|
localStorage.removeItem(this.publicizeAddress)
|
|
localStorage.setItem(this.publicizeAddress, 'true')
|
|
}
|
|
|
|
} catch (error) {
|
|
}
|
|
stop = false
|
|
}
|
|
}
|
|
this.interval = setInterval(checkPublicKey, 5000);
|
|
}
|
|
|
|
async getNodeInfo() {
|
|
const appinfoNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
|
const appinfoUrl = appinfoNode.protocol + '://' + appinfoNode.domain + ':' + appinfoNode.port
|
|
const url = `${appinfoUrl}/admin/status`
|
|
await fetch(url).then(response => {
|
|
return response.json()
|
|
})
|
|
.then(data => {
|
|
this.nodeInfo = data
|
|
})
|
|
.catch(err => {
|
|
console.error('Request failed', err)
|
|
})
|
|
}
|
|
|
|
async getCoreInfo() {
|
|
const appinfoNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
|
const appinfoUrl = appinfoNode.protocol + '://' + appinfoNode.domain + ':' + appinfoNode.port
|
|
const url = `${appinfoUrl}/admin/info`
|
|
await fetch(url).then(response => {
|
|
return response.json()
|
|
})
|
|
.then(data => {
|
|
this.coreInfo = data
|
|
})
|
|
.catch(err => {
|
|
console.error('Request failed', err)
|
|
})
|
|
}
|
|
|
|
_renderStatus() {
|
|
if (this.nodeInfo.isMintingPossible === true && this.nodeInfo.isSynchronizing === true) {
|
|
this.cssStatus = 'blue'
|
|
return html`${translate("appinfo.minting")}`
|
|
} else if (this.nodeInfo.isMintingPossible === true && this.nodeInfo.isSynchronizing === false) {
|
|
this.cssStatus = 'blue'
|
|
return html`${translate("appinfo.minting")}`
|
|
} else if (this.nodeInfo.isMintingPossible === false && this.nodeInfo.isSynchronizing === true) {
|
|
this.cssStatus = 'black'
|
|
return html`(${translate("appinfo.synchronizing")}... ${this.nodeInfo.syncPercent !== undefined ? this.nodeInfo.syncPercent + '%' : ''})`
|
|
} else if (this.nodeInfo.isMintingPossible === false && this.nodeInfo.isSynchronizing === false) {
|
|
this.cssStatus = 'black'
|
|
return ''
|
|
} else {
|
|
return ''
|
|
}
|
|
}
|
|
|
|
_renderCoreVersion() {
|
|
return html`<span class="info">${translate("appinfo.coreversion")}: ${this.coreInfo.buildVersion ? this.coreInfo.buildVersion : ''}</span>`
|
|
}
|
|
|
|
gotoPage(url) {
|
|
const myLink = this.shadowRoot.querySelector('#pageLink')
|
|
myLink.href = url
|
|
myLink.click()
|
|
store.dispatch(doPageUrl(''))
|
|
}
|
|
|
|
stateChanged(state) {
|
|
this.blockInfo = state.app.blockInfo
|
|
this.nodeStatus = state.app.nodeStatus
|
|
this.nodeConfig = state.app.nodeConfig
|
|
this.pageUrl = state.app.pageUrl
|
|
if (this.pageUrl.length > 5) {
|
|
this.gotoPage(this.pageUrl)
|
|
}
|
|
}
|
|
}
|
|
|
|
window.customElements.define('app-info', AppInfo)
|