Browse Source

Update design

master
BuildTools 2 years ago
parent
commit
5636fbbb98
9 changed files with 143 additions and 173 deletions
  1. +1
    -1
      public/index.html
  2. +10
    -11
      src/App.vue
  3. +10
    -66
      src/charts.js
  4. +1
    -0
      src/explorer.js
  5. +18
    -0
      src/main.js
  6. +17
    -15
      src/views/Block.vue
  7. +44
    -59
      src/views/Index.vue
  8. +23
    -21
      src/views/Tx.vue
  9. +19
    -0
      src/wasm.js

+ 1
- 1
public/index.html View File

@@ -5,7 +5,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta name="author" content="Slixe">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<link rel="icon" href="<%= BASE_URL %>logo.png">
<script src="/wasm_exec.js"></script>
<link href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700%7CMaterial+Icons' rel="stylesheet">
<title>DERO Explorer</title>


+ 10
- 11
src/App.vue View File

@@ -2,7 +2,7 @@
<div id="app">
<v-app>
<header>
<v-toolbar dark>
<v-toolbar color="secondary">
<v-spacer></v-spacer>
<v-avatar size="60" tile>
<v-img src="/logo.png">
@@ -25,7 +25,7 @@
<v-btn href="https://dero.io" text>Home</v-btn>
<v-btn href="https://wallet.dero.io" text>Web Wallet</v-btn>
<dropdown name="Stats" :items="this.statsItems"></dropdown>
<v-btn @click="changeTheme()" dark text><span><v-icon dark>invert_colors</v-icon></span></v-btn>
<v-btn @click="changeTheme()" dark text><span :style="this.$vuetify.theme.dark ? 'color: white;' : 'color: black;'"><v-icon>invert_colors</v-icon></span></v-btn>
</v-toolbar-items>
<v-spacer></v-spacer>
</v-toolbar>
@@ -41,14 +41,14 @@
flat
tile
width="100%"
dark
color="secondary"
class="text-center"
>
<v-card-text>
dERokevAZEZVJ2N7o39VH81BXBqX9ojtncnPTDMyiVbmYiTXQY93AUCLcor9xsWCKWhYy25ja89ikZWXWab9kXRB7LYfUmbQyS
</v-card-text>
<v-divider></v-divider>
<v-card-text class="white--text">
<v-card-text>
{{ new Date().getFullYear() }} — <strong>DERO Explorer</strong>
</v-card-text>
</v-card>
@@ -60,6 +60,7 @@
<script>
import dropdown from './components/Dropdown'
import * as explorer from './explorer'
import * as wasm from './wasm'

export default {
name: 'app',
@@ -77,11 +78,7 @@ export default {
{
title: "Retro Stats",
href: "https://network.dero.io"
}/*,
{
title: "Stats",
to: "/stats"
}*/
}
],
menu: [
{ icon: 'home', title: 'Link A' },
@@ -93,13 +90,14 @@ export default {
}
},
mounted() {
wasm.useWASM()
if (localStorage.theme) {
this.$vuetify.theme.dark = localStorage.theme == "dark"
} else {
this.$vuetify.theme.dark = true
}
},
methods: { /* eslint-disable no-console */
methods: {
async searchFunc() {
if (this.search) {
let block = await explorer.loadBlock(this.search)
@@ -108,7 +106,7 @@ export default {
}
else if (this.search.length == 64) {
let tx = explorer.loadTxs(this.search)
// TODO, fix loadTxs first.
if (tx && tx.status != "TX NOT FOUND") {
this.$router.push('/tx/' + this.search)
}
@@ -140,6 +138,7 @@ export default {
#app {
text-align: center;
color: white;
background: var(--v-anchor-base);
}

* {


+ 10
- 66
src/charts.js View File

@@ -19,9 +19,7 @@ function createChart(title, name, categories = [], data = [])
{
const options = {
chart: {
//height: 500,
type: 'line',
background: '#424242',
toolbar: {
show: false
},
@@ -32,7 +30,7 @@ function createChart(title, name, categories = [], data = [])
left: 2,
blur: 3,
opacity: 1
},
}
},
theme: {
mode: 'dark',
@@ -44,10 +42,7 @@ function createChart(title, name, categories = [], data = [])
shadeIntensity: 0.65
},
},
/*stroke: {
width: 7,
curve: 'smooth'
},*/
xaxis: {
type: 'string',
categories: [],
@@ -55,16 +50,12 @@ function createChart(title, name, categories = [], data = [])
show: false
}
},
/*title: {
text: 'No Text',
align: 'center',
style: {
fontSize: "24px"
}
},*/
markers: {
colors: ['black']
},
fill: {
type: 'gradient',
gradient: {
type: 'solid',
/*gradient: {
shade: 'dark',
gradientToColors: ['#FDD835'],
shadeIntensity: 1,
@@ -72,22 +63,9 @@ function createChart(title, name, categories = [], data = [])
opacityFrom: 1,
opacityTo: 1,
stops: [0, 100, 100, 100]
},
}/*,
markers: {
size: 4,
opacity: 0.9,
colors: ["#FFA41B"],
strokeColor: "#fff",
strokeWidth: 2,
hover: {
size: 7,
}
}*/
},*/
}
}

//options.title.text = title
title = ""
options.xaxis.categories = categories

return {
@@ -98,26 +76,6 @@ function createChart(title, name, categories = [], data = [])
options: options
}
}
/*
export function networkChart()
{
const categories = []
const datas = []
let val = getNetwork()
let diff = []
let hashrate = []
for (let i = 0; i < cache.depth; i++)
{
categories.push(explorer.formatSupply(val[i].height))
diff.push(val[i].difficulty)
hashrate.push(val[i].hashrate)
}

datas.push({name: "Difficulty", data: diff}, {name: "MH/s", data: hashrate})

return createChart("Network Chart", "", categories, datas)
}*/

export function difficultyChart()
{
@@ -201,18 +159,4 @@ function getRewards()
}

return array
}

/*
function getNetwork()
{
const array = []

for (let i = 0; i < cache.depth; i++)
{
let block = cache.blocks[i]
array.push({height: block.height, difficulty: block.difficulty, hashrate: (block.difficulty/(cache.info.target*1000*1000)).toFixed(2)})
}

return array
}*/
}

+ 1
- 0
src/explorer.js View File

@@ -56,6 +56,7 @@ export async function loadBlocks(pos, size)
for (let i = 0; i < size; i++)
{
let block = await loadBlock(pos - i)
console.log(block)
if (block) {
blocks.push(block)
}


+ 18
- 0
src/main.js View File

@@ -15,6 +15,24 @@ new Vue({
icons: {
iconfont: 'md',
},
theme: {
options: {
customProperties: true,
},
themes: {
dark: {
primary: '#2A2D2F',
secondary: '#383B3E',
anchor: '#45484B',
},
light: {
primary: '#DCDCDC',
secondary: '#DCDCDC',
anchor: '#BDBDBD',
}
},
dark: true
}
}),
}).$mount('#app')

+ 17
- 15
src/views/Block.vue View File

@@ -1,14 +1,14 @@
<template>
<div id="block">
<div id="main">
<h2 :class="{ 'title-color': !$vuetify.theme.dark }" class="title">Block<a :href="previous()"><v-icon>keyboard_arrow_left</v-icon></a>{{block.TopoHeight}}<a :href="next()"><v-icon>keyboard_arrow_right</v-icon></a><small class="bh">{{block.Hash}}</small></h2>
<h2 :style="this.$vuetify.theme.dark ? 'color: white;' : 'color: black;'" class="title">Block<a :href="previous()"><v-icon>keyboard_arrow_left</v-icon></a>{{block.TopoHeight}}<a :href="next()"><v-icon>keyboard_arrow_right</v-icon></a><small class="bh">{{block.Hash}}</small></h2>
<div v-for="(hash, i) in block.Tips" :key="i">
<h5 :class="{ 'title-color': !$vuetify.theme.dark }" class="previous-block">Previous Block: <small @click="goTo('/block/' + hash)">{{ hash }}</small></h5>
<h5 :style="$vuetify.theme.dark ? 'color: white;' : 'color: black;'" class="previous-block" >Previous Block: <small @click="goTo('/block/' + hash)">{{ hash }}</small></h5>
</div>
</div>
<v-divider class="div"></v-divider>
<div id="boxes">
<v-card dark class="block-info">
<v-card color="primary" class="block-info">
<ul>
<li>Topo Height (unique): <span>{{explorer.formatSupply(block.TopoHeight)}}</span></li>
<li>Block Height: <span>{{explorer.formatSupply(block.Height)}}</span></li>
@@ -16,7 +16,7 @@
<li>Timestamp: <span>{{new Date(block.Timestamp * 1000).toLocaleString()}}</span></li>
</ul>
</v-card>
<v-card dark class="block-info">
<v-card color="primary" class="block-info">
<ul>
<li>Hashrate: <span>{{ explorer.formatSupply((block.Difficulty/(info.target*1000*1000)).toFixed(2)) }} MH/s</span></li>
<li>Difficulty: <span>{{explorer.formatSupply(block.Difficulty)}}</span></li>
@@ -24,7 +24,7 @@
<li>Nonce: <span>{{explorer.formatSupply(block.Nonce)}}</span></li>
</ul>
</v-card>
<v-card dark class="block-info">
<v-card color="primary" class="block-info">
<ul>
<li>Minor / Major Version: <span>{{ block.Minor_Version }} / {{ block.Major_Version }}</span></li>
<li>Block Size: <span>{{ block.Size }} kB</span></li>
@@ -35,8 +35,8 @@
</div>
<v-divider class="div"></v-divider>
<div>
<h1 :class="{ 'title-color': !$vuetify.theme.dark }">Miner reward transaction</h1>
<v-simple-table dark id="table">
<h1 :style="this.$vuetify.theme.dark ? 'color: white;' : 'color: black;'">Miner reward transaction</h1>
<v-simple-table id="table">
<template v-slot:default>
<thead>
<tr>
@@ -59,8 +59,8 @@
</div>
<v-divider class="div"></v-divider>
<div>
<h1 :class="{ 'title-color': !$vuetify.theme.dark }">{{ block.Tx_Count }} Transactions</h1>
<v-simple-table dark id="table">
<h1 :style="this.$vuetify.theme.dark ? 'color: white;' : 'color: black;'">{{ block.Tx_Count }} Transactions</h1>
<v-simple-table id="table">
<template v-slot:default>
<thead>
<tr>
@@ -107,8 +107,8 @@ export default {
}
},
async mounted() {
await wasm.waitWASM()
this.info = await explorer.getInfo()
await wasm.useWASM()
this.block = await wasm.loadFullBlock(this.blockID)
},
methods: {
@@ -176,14 +176,9 @@ ul {
}

a:link, a:visited, a:active {
color: white;
text-decoration: none;
}

span {
color: hsla(0,0%,100%,.7);
}

.bh {
font-size: 1rem;
}
@@ -197,6 +192,13 @@ span {
margin-bottom: 1%;
}

.theme--dark.v-data-table {
background-color: var(--v-primary-base);
}
.theme--light.v-data-table {
background-color: var(--v-primary-base);
}

.previous-block {
margin-left: 15%;
text-align: left;


+ 44
- 59
src/views/Index.vue View File

@@ -1,7 +1,7 @@
<template>
<div id="index">
<div id="boxes">
<v-card class="box" dark elevation="10">
<v-card class="box" :loading="!infoReady ? 'info' : false" color="primary" elevation="10">
<v-card-title>NETWORK INFORMATION</v-card-title>
<v-divider></v-divider>
<v-card-text>
@@ -17,7 +17,7 @@
</v-card-text>
</v-card>

<v-card class="box" dark elevation="10">
<v-card class="box" :loading="!poolReady ? 'info' : false" color="primary" elevation="10">
<v-card-title>MEM POOL<h5 class="subtitle">({{ txs.length }} transactions)</h5></v-card-title>
<v-divider></v-divider>
<v-card-text>
@@ -26,32 +26,18 @@
</ul>
</v-card-text>
</v-card>
<v-card dark class="box" elevation="10">
<v-card class="box" :loading="!chartReady ? 'info' : false" color="primary" elevation="10">
<v-card-title>HASHRATE CHART</v-card-title>
<v-divider></v-divider>
<div v-if="ready">
<div v-if="chartReady">
<apexchart type="line" :options="networkChart.options" :series="networkChart.datas"></apexchart>
</div>
</v-card>
<!--<v-card dark class="box" elevation="10">
<v-card-title>PRICE INFORMATION</v-card-title>
<v-divider></v-divider>
<v-card-text>
<ul class="net-info">
<li><strong>Rank:</strong> {{ explorer.formatSupply(coinGecko.market_cap_rank) }}</li>
<li><strong>Market Cap:</strong> {{ explorer.formatSupply(coinGecko.marketcap) }} USD</li>
<li><strong>Price:</strong> {{ coinGecko.priceUSD }} USD / {{ coinGecko.priceBTC }} BTC</li>
<li><strong>ATH:</strong> {{ coinGecko.ATHpriceUSD }} USD / {{ coinGecko.ATHpriceBTC }} BTC</li>
<li><strong>ATL:</strong> {{ coinGecko.ATLpriceUSD }} USD / {{ coinGecko.ATLpriceBTC }} BTC</li>
<li><strong>24h Volume:</strong> {{ explorer.formatSupply(coinGecko.volume24hUSD) }} USD / {{ explorer.formatSupply(coinGecko.volume24hBTC) }} BTC</li>
</ul>
</v-card-text>
</v-card>-->
</div>
<v-divider></v-divider>
<div class="lb"> <!-- Latest blocks -->
<h1 :class="{ 'title-color': !$vuetify.theme.dark }">LATEST BLOCKS</h1>
<v-simple-table dark id="table">
<h1 :style="this.$vuetify.theme.dark ? 'color: white;' : 'color: black;'">LATEST BLOCKS</h1>
<v-simple-table id="table">
<template v-slot:default>
<thead>
<tr>
@@ -61,7 +47,6 @@
<th class="text-center">Tx</th>
<th class="text-center">Block Hash</th>
<th class="text-center">Block Reward</th>
<!--<th class="text-center">Size (kB)</th>-->
</tr>
</thead>
<tbody>
@@ -72,7 +57,6 @@
<td>{{ block.block_header.txcount }}</td>
<td>{{ block.block_header.hash }}</td>
<td>{{ (block.block_header.reward / 1000000000000).toFixed(4) }} <img src="/logo.png" align="center" height="25px" width="25px" /></td>
<!--<td>0</td>-->
</tr>
</tbody>
</template>
@@ -95,49 +79,41 @@ export default {
txs: [],
info: {},
blocks: [],
/*coinGecko: {
priceUSD: 0,
priceBTC: 0,
volume24hUSD: 0,
volume24hBTC: 0,
ATHpriceUSD: 0,
ATHpriceBTC: 0,
ATLpriceUSD: 0,
ATLpriceBTC: 0,
marketcap: 0,
market_cap_rank: 0,
},*/
explorer,
networkChart: {},
ready: false
poolReady: false,
infoReady: false,
chartReady: false
}
},
async mounted() {
/*fetch("https://api.coingecko.com/api/v3/coins/dero?localization=en&tickers=false&market_data=true&community_data=false&developer_data=false&sparkline=false")
.then(result => result.json()).then(result => {
this.coinGecko.priceUSD = result.market_data.current_price.usd
this.coinGecko.priceBTC = result.market_data.current_price.btc
this.coinGecko.volume24hUSD = result.market_data.total_volume.usd
this.coinGecko.volume24hBTC = result.market_data.total_volume.btc
this.coinGecko.ATHpriceUSD = result.market_data.ath.usd
this.coinGecko.ATHpriceBTC = result.market_data.ath.btc
this.coinGecko.ATLpriceUSD = result.market_data.atl.usd
this.coinGecko.ATLpriceBTC = result.market_data.atl.btc
this.coinGecko.marketcap = result.market_data.market_cap.usd
this.coinGecko.market_cap_rank = result.market_data.market_cap_rank
})*/

let pool = await explorer.getTxsPool()

if (pool.txs)
this.txs = pool.txs

this.info = await explorer.getInfo()
this.blocks = await explorer.loadBlocks(this.info.topoheight, 15)
async mounted() {
explorer.getTxsPool().then(pool => {
if (pool.txs)
this.txs = pool.txs
this.poolReady = true
})

explorer.getInfo().then(info => {
this.info = info
this.infoReady = true

explorer.loadBlocks(this.info.topoheight, 15).then(blocks => {
this.blocks = blocks
})
})

await chart.init()
this.networkChart = chart.hashrateChart()
this.ready = true

//...
if (this.$vuetify.theme.dark) {
this.networkChart.options.chart.background = this.$vuetify.theme.themes.dark.primary
} else {
this.networkChart.options.chart.background = this.$vuetify.theme.themes.light.primary
this.networkChart.options.chart.foreColor = "black"
}
this.chartReady = true

setInterval(() => {
explorer.getInfo().then(info => {
@@ -205,6 +181,16 @@ ul li {
padding: 0;
margin-bottom: 2%;
}
h1 {
color: black;
}

.theme--dark.v-data-table {
background-color: var(--v-primary-base);
}
.theme--light.v-data-table {
background-color: var(--v-primary-base);
}

.mempool {
text-align: center;
@@ -219,7 +205,6 @@ ul li {
font-weight: 400;
line-height: 1.375rem;
letter-spacing: .0071428571em;
color: hsla(0,0%,100%,.7);
}

.lb {


+ 23
- 21
src/views/Tx.vue View File

@@ -1,14 +1,14 @@
<template>
<div id="tx">
<div id="main" class="extra">
<h2 :class="{ 'title-color': !$vuetify.theme.dark }" class="title">Tx Hash: <small class="bh">{{tx.Hash}}</small></h2>
<h5 :class="{ 'title-color': !$vuetify.theme.dark }" class="sub-title">Prefix Hash: <small>{{tx.PrefixHash}}</small></h5>
<h2 :style="this.$vuetify.theme.dark ? 'color: white;' : 'color: black;'" class="title">Tx Hash: <small class="bh">{{tx.Hash}}</small></h2>
<h5 :style="this.$vuetify.theme.dark ? 'color: white;' : 'color: black;'" class="sub-title">Prefix Hash: <small>{{tx.PrefixHash}}</small></h5>
<!--<h5 class="sub-title">Block (valid): <small>{{tx.ValidBlock}}</small></h5>-->
<h5 :class="{ 'title-color': !$vuetify.theme.dark }" class="sub-title">Public Key: <small>{{tx.TXpublickey}}</small></h5>
<h5 :style="this.$vuetify.theme.dark ? 'color: white;' : 'color: black;'" class="sub-title">Public Key: <small>{{tx.TXpublickey}}</small></h5>
</div>
<v-divider class="div"></v-divider>
<div id="card">
<v-card dark class="tx-info">
<v-card color="primary" class="tx-info">
<ul>
<li>Timestamp: <span>{{new Date(tx.Timestamp * 1000).toLocaleString()}}</span></li>
<li>Block Topo Height: <span>{{ explorer.formatSupply(tx.Height) }}</span></li>
@@ -16,7 +16,7 @@
<li>Signature Type: <span>{{ tx.Type }}</span></li>
</ul>
</v-card>
<v-card dark class="tx-info">
<v-card color="primary" class="tx-info">
<ul>
<li>Fee: <span>{{ parseFloat(tx.Feeuint64 / 1000000000000).toFixed(5) }} DERO</span></li>
<li>No of Confirmations: <span>{{ tx.Depth }}</span></li>
@@ -27,14 +27,14 @@
</div>
<v-divider class="div"></v-divider>
<div class="extra">
<h4 :class="{ 'title-color': !$vuetify.theme.dark }" v-if="tx.PayID8 != ''">Encrypted PaymentID: <small class="bh">{{ tx.PayID8 }}</small></h4>
<h4 :class="{ 'title-color': !$vuetify.theme.dark }" v-if="tx.PayID32 != ''">PaymentID: <small class="bh">{{ tx.PayID32 }}</small></h4>
<h4 :class="{ 'title-color': !$vuetify.theme.dark }">Extra: <small class="bh">{{ tx.Extra }}</small></h4>
<h4 :style="this.$vuetify.theme.dark ? 'color: white;' : 'color: black;'" v-if="tx.PayID8 != ''">Encrypted PaymentID: <small class="bh">{{ tx.PayID8 }}</small></h4>
<h4 :style="this.$vuetify.theme.dark ? 'color: white;' : 'color: black;'" v-if="tx.PayID32 != ''">PaymentID: <small class="bh">{{ tx.PayID32 }}</small></h4>
<h4 :style="this.$vuetify.theme.dark ? 'color: white;' : 'color: black;'">Extra: <small class="bh">{{ tx.Extra }}</small></h4>
</div>
<v-divider class="div"></v-divider>
<div>
<h1 :class="{ 'title-color': !$vuetify.theme.dark }">Block</h1>
<v-simple-table dark id="table">
<h1 :style="this.$vuetify.theme.dark ? 'color: white;' : 'color: black;'">Block</h1>
<v-simple-table id="table">
<template v-slot:default>
<thead>
<tr>
@@ -54,8 +54,8 @@
</div>
<v-divider class="div"></v-divider>
<div>
<h1 :class="{ 'title-color': !$vuetify.theme.dark }">Outputs ({{ tx.OutAddress.length }})</h1>
<v-simple-table dark id="table">
<h1 :style="this.$vuetify.theme.dark ? 'color: white;' : 'color: black;'">Outputs ({{ tx.OutAddress.length }})</h1>
<v-simple-table id="table">
<template v-slot:default>
<thead>
<tr>
@@ -76,10 +76,10 @@
</div>
<v-divider v-show="tx.Keyimages.length > 0" class="div"></v-divider>
<div v-show="tx.Keyimages.length > 0">
<h1 :class="{ 'title-color': !$vuetify.theme.dark }">Inputs ({{ tx.Keyimages.length }})</h1>
<h1 :style="this.$vuetify.theme.dark ? 'color: white;' : 'color: black;'">Inputs ({{ tx.Keyimages.length }})</h1>
<div v-for="(ki, i) in tx.Keyimages" :key="i">
<h5 :class="{ 'title-color': !$vuetify.theme.dark }" class="ki">{{ i }}: Key Image {{ ki }}</h5>
<v-simple-table dark id="table">
<h5 :style="$vuetify.theme.dark ? 'color: white;' : 'color: black;'" class="ki">{{ i }}: Key Image {{ ki }}</h5>
<v-simple-table id="table">
<template v-slot:default>
<thead>
<tr>
@@ -123,10 +123,9 @@ export default {

if (this.txHash.length == 64)
{
await wasm.useWASM()
await wasm.waitWASM()
let result = await wasm.parseTx(this.txHash)
/* eslint-disable no-console */
console.log(result)
this.tx = result[0]

if (!this.tx.Keyimages)
@@ -190,15 +189,18 @@ ul {
margin-top: 2%;
}

span {
color: hsla(0,0%,100%,.7);
}

.sub-title {
text-align: left;
margin-left: 15%;
}

.theme--dark.v-data-table {
background-color: var(--v-primary-base);
}
.theme--light.v-data-table {
background-color: var(--v-primary-base);
}

.tx-info {
width: 28%;
text-align: left;


+ 19
- 0
src/wasm.js View File

@@ -1,9 +1,14 @@
import * as explorer from './explorer'
/* eslint-disable */
const go = new Go();
let wasmReady = false

export async function useWASM()
{
if (wasmReady) {
console.log("WASM already ready!!")
}

if (!WebAssembly.instantiateStreaming) { // polyfill
WebAssembly.instantiateStreaming = async (resp, importObject) => {
const source = await (await resp).arrayBuffer();
@@ -14,6 +19,20 @@ export async function useWASM()
let result = await WebAssembly.instantiateStreaming(fetch("/main.wasm"), go.importObject)
go.run(result.instance);
console.log(testWASM())
wasmReady = true
}

function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}

export async function waitWASM()
{
while (!wasmReady)
{
console.log("Waiting WASM...")
await sleep(150)
}
}

export function addMinerTxToBlock(block)


Loading…
Cancel
Save