Explorer redesign part 1

This commit is contained in:
Martin Boehm 2022-10-20 19:24:53 +02:00 committed by Martin
parent 096bab30a8
commit a939b2d93f
30 changed files with 589 additions and 130 deletions

View File

@ -460,6 +460,9 @@ func (s *PublicServer) parseTemplates() []*template.Template {
"formatUnixTime": formatUnixTime,
"formatAmount": s.formatAmount,
"formatAmountWithDecimals": formatAmountWithDecimals,
"formatInt64": formatInt64,
"formatInt": formatInt,
"formatUint32": formatUint32,
"setTxToTemplateData": setTxToTemplateData,
"feePerByte": feePerByte,
"isOwnAddress": isOwnAddress,
@ -528,16 +531,70 @@ func (s *PublicServer) parseTemplates() []*template.Template {
return t
}
func formatUnixTime(ut int64) string {
func relativeTime(d int64) string {
var u string
if d < 60 {
if d == 1 {
u = " sec"
} else {
u = " secs"
}
} else if d < 3600 {
d /= 60
if d == 1 {
u = " min"
} else {
u = " mins"
}
} else if d < 3600*24 {
d /= 3600
if d == 1 {
u = " hour"
} else {
u = " hours"
}
} else {
d /= 3600 * 24
if d == 1 {
u = " day"
} else {
u = " days"
}
}
return strconv.FormatInt(d, 10) + u
}
func formatUnixTime(ut int64) template.HTML {
t := time.Unix(ut, 0)
return formatTime(&t)
}
func formatTime(t *time.Time) string {
func formatTime(t *time.Time) template.HTML {
if t == nil {
return ""
}
return t.Format(time.RFC1123)
u := t.Unix()
if u <= 0 {
return ""
}
d := time.Now().Unix() - u
f := t.UTC().Format("2006-01-02 15:04:05")
if d < 0 {
return template.HTML(f)
}
r := relativeTime(d)
if d > 3600*24 {
d = d % (3600 * 24)
if d >= 3600 {
r += " " + relativeTime(d)
}
} else if d > 3600 {
d = d % 3600
if d >= 60 {
r += " " + relativeTime(d)
}
}
return template.HTML(`<span tt="` + f + `">` + r + " ago</span>")
}
func toJSON(data interface{}) string {
@ -564,6 +621,28 @@ func formatAmountWithDecimals(a *api.Amount, d int) string {
return a.DecimalString(d)
}
func formatInt(i int) template.HTML {
return formatInt64(int64(i))
}
func formatUint32(i uint32) template.HTML {
return formatInt64(int64(i))
}
func formatInt64(i int64) template.HTML {
s := strconv.FormatInt(i, 10)
t := (len(s) - 1) / 3
if t <= 0 {
return template.HTML(s)
}
t *= 3
rv := s[:len(s)-t]
for i := len(s) - t; i < len(s); i += 3 {
rv += `<span class="ns">` + s[i:i+3] + "</span>"
}
return template.HTML(rv)
}
// called from template to support txdetail.html functionality
func setTxToTemplateData(td *TemplateData, tx *api.Tx) *TemplateData {
td.Tx = tx

View File

@ -4,11 +4,13 @@ package server
import (
"encoding/json"
"html/template"
"io/ioutil"
"net/http"
"net/http/httptest"
"net/url"
"os"
"reflect"
"strconv"
"strings"
"testing"
@ -1607,3 +1609,29 @@ func Test_PublicServer_BitcoinType(t *testing.T) {
socketioTestsBitcoinType(t, ts)
websocketTestsBitcoinType(t, ts)
}
func Test_formatInt64(t *testing.T) {
tests := []struct {
name string
n int64
want template.HTML
}{
{"1", 1, "1"},
{"13", 13, "13"},
{"123", 123, "123"},
{"1234", 1234, `1<span class="ns">234</span>`},
{"91234", 91234, `91<span class="ns">234</span>`},
{"891234", 891234, `891<span class="ns">234</span>`},
{"7891234", 7891234, `7<span class="ns">891</span><span class="ns">234</span>`},
{"67891234", 67891234, `67<span class="ns">891</span><span class="ns">234</span>`},
{"567891234", 567891234, `567<span class="ns">891</span><span class="ns">234</span>`},
{"4567891234", 4567891234, `4<span class="ns">567</span><span class="ns">891</span><span class="ns">234</span>`},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := formatInt64(tt.n); !reflect.DeepEqual(got, tt.want) {
t.Errorf("formatInt64() = %v, want %v", got, tt.want)
}
})
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,39 @@
@font-face {
font-family: 'TT Hoves';
src: url('./TTHoves-Bold.woff2') format('woff2'),
url('./TTHoves-Bold.woff') format('woff');
font-weight: bold;
font-style: normal;
}
@font-face {
font-family: 'TT Hoves';
src: url('./TTHoves-Regular.woff2') format('woff2'),
url('./TTHoves-Regular.woff') format('woff');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'TT Hoves';
src: url('./TTHoves-Light.woff2') format('woff2'),
url('./TTHoves-Light.woff') format('woff');
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: 'TT Hoves';
src: url('./TTHoves-DemiBold.woff2') format('woff2'),
url('./TTHoves-DemiBold.woff') format('woff');
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: 'TT Hoves';
src: url('./TTHoves-Medium.woff2') format('woff2'),
url('./TTHoves-Medium.woff') format('woff');
font-weight: 500;
font-style: normal;
}

303
static/css/main2.css Normal file
View File

@ -0,0 +1,303 @@
@import "TTHoves/TTHoves.css";
* {
margin: 0px;
padding: 0px;
outline: none;
font-family: "TT Hoves", -apple-system, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
}
html,
body {
height: 100%;
}
body {
min-height: 100%;
margin: 0;
background: linear-gradient(to bottom, #F6F6F6 300px, #E5E5E5 0), #E5E5E5;
background-repeat: no-repeat;
}
a {
color: #00854D;
text-decoration: none;
}
a:hover {
color: #00854D;
text-decoration: underline;
}
#header {
position: absolute;
top: 0;
left: 0;
width: 100%;
margin: 0;
padding-bottom: 0;
padding-top: 0;
background-color: white;
border: 0;
z-index: 10;
}
#header .navbar {
--bs-navbar-padding-y: 0.7rem;
}
#header .form-control-lg {
font-size: 1rem;
padding: 0.75rem 1rem;
}
.bb-group {
border: 0.6rem solid #F6F6F6;
background-color: #F6F6F6;
border-radius: 0.5rem;
position: relative;
display: inline-flex;
vertical-align: middle;
}
.bb-group>.btn {
--bs-btn-padding-x: 0.5rem;
--bs-btn-padding-y: 0.22rem;
--bs-btn-border-radius: 0.3rem;
--bs-btn-border-width: 0;
color: #545454;
}
.bb-group>.btn-check:checked+.btn,
.bb-group .btn.active {
color: black;
font-weight: bold;
background-color: white;
}
.paging {
display: flex;
}
.paging .bb-group>.btn {
min-width: 2rem;
margin-left: 0.1rem;
margin-right: 0.1rem;
}
.paging .bb-group>.btn:hover {
background-color: white;
}
.paging a {
text-decoration: none;
}
.btn-paging {
--bs-btn-color: #757575;
--bs-btn-border-color: #E2E2E2;
--bs-btn-hover-color: black;
--bs-btn-hover-bg: #F6F6F6;
--bs-btn-hover-border-color: #E2E2E2;
--bs-btn-focus-shadow-rgb: 108, 117, 125;
--bs-btn-active-color: #fff;
--bs-btn-active-bg: #E2E2E2;
--bs-btn-active-border-color: #E2E2E2;
--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
--bs-gradient: none;
--bs-btn-padding-y: 0.75rem;
--bs-btn-padding-x: 1.1rem;
--bs-btn-border-radius: 0.5rem;
--bs-btn-font-weight: bold;
background-color: #F6F6F6;
}
span.btn-paging {
cursor: initial;
}
span.btn-paging:hover {
color: #757575;
}
.paging-group {
border: 1px solid #E2E2E2;
border-radius: 0.5rem;
}
.paging-group>.bb-group {
border: 0.53rem solid #F6F6F6;
}
#wrap {
min-height: 100%;
height: auto;
padding: 112px 0 75px 0;
margin: 0 auto -56px;
}
#footer {
background-color: black;
color: #757575;
height: 56px;
overflow: hidden;
}
.navbar-form {
width: 60%;
}
.navbar-form button {
margin-left: -50px;
position: relative;
}
.search-icon {
width: 16px;
height: 16px;
position: absolute;
top: 16px;
background-size: cover;
background-image: url("data:image/svg+xml, %3Csvg style='background: white%3B' width='16' height='16' viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M7.24976 12.5C10.1493 12.5 12.4998 10.1495 12.4998 7.25C12.4998 4.35051 10.1493 2 7.24976 2C4.35026 2 1.99976 4.35051 1.99976 7.25C1.99976 10.1495 4.35026 12.5 7.24976 12.5Z' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round' /%3E%3Cpath d='M10.962 10.9625L13.9996 14.0001' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round' /%3E%3C/svg%3E");
}
.navbar-form ::placeholder {
color: #E2E2E2;
}
.ellipsis {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.data-table {
table-layout: fixed;
overflow-wrap: break-word;
margin-left: 8px;
margin-top: 2rem;
margin-bottom: 2rem;
width: calc(100% - 16px);
}
.data-table thead {
padding-bottom: 20px;
}
.table.data-table>:not(caption)>*>* {
padding: 0.8rem 0.8rem;
background-color: var(--bs-table-bg);
border-bottom-width: 1px;
box-shadow: inset 0 0 0 9999px var(--bs-table-accent-bg);
}
.table.data-table>thead>*>* {
padding-bottom: 1.5rem;
}
.table.data-table>*>*:last-child>* {
border-bottom: none;
}
.data-table thead,
.data-table thead tr,
.data-table thead th {
color: #757575;
border: none;
font-weight: normal;
}
.data-table tbody {
background: white;
border-radius: 8px;
box-shadow: 0 0 0 8px white;
}
.data-table h3,
.data-table h6 {
margin-bottom: 0;
}
.data-table h3 {
color: black;
}
.info-table tbody {
display: inline-table;
width: 100%;
}
.info-table td {
font-weight: bold;
}
.info-table tr>td:first-child {
font-weight: normal;
color: #757575;
}
.ns:before {
content: "";
}
.trezor-logo {
width: 128px;
height: 32px;
position: absolute;
top: 15px;
background-size: cover;
background-image: url("data:image/svg+xml, %3Csvg style='width: 128px%3B' version='1.1' xmlns='http://www.w3.org/2000/svg' x='0px' y='0px' viewBox='0 0 163.7 41.9' space='preserve'%3E%3Cpolygon points='101.1 12.8 118.2 12.8 118.2 17.3 108.9 29.9 118.2 29.9 118.2 35.2 101.1 35.2 101.1 30.7 110.4 18.1 101.1 18.1'%3E%3C/polygon%3E%3Cpath d='M158.8 26.9c2.1-0.8 4.3-2.9 4.3-6.6c0-4.5-3.1-7.4-7.7-7.4h-10.5v22.3h5.8v-7.5h2.2l4.1 7.5h6.7L158.8 26.9z M154.7 22.5h-4V18h4c1.5 0 2.5 0.9 2.5 2.2C157.2 21.6 156.2 22.5 154.7 22.5z'%3E%3C/path%3E%3Cpath d='M130.8 12.5c-6.8 0-11.6 4.9-11.6 11.5s4.9 11.5 11.6 11.5s11.7-4.9 11.7-11.5S137.6 12.5 130.8 12.5z M130.8 30.3c-3.4 0-5.7-2.6-5.7-6.3c0-3.8 2.3-6.3 5.7-6.3c3.4 0 5.8 2.6 5.8 6.3C136.6 27.7 134.2 30.3 130.8 30.3z'%3E%3C/path%3E%3Cpolygon points='82.1 12.8 98.3 12.8 98.3 18 87.9 18 87.9 21.3 98 21.3 98 26.4 87.9 26.4 87.9 30 98.3 30 98.3 35.2 82.1 35.2'%3E%3C/polygon%3E%3Cpath d='M24.6 9.7C24.6 4.4 20 0 14.4 0S4.2 4.4 4.2 9.7v3.1H0v22.3h0l14.4 6.7l14.4-6.7h0V12.9h-4.2V9.7z M9.4 9.7c0-2.5 2.2-4.5 5-4.5s5 2 5 4.5v3.1H9.4V9.7z M23 31.5l-8.6 4l-8.6-4V18.1H23V31.5z'%3E%3C/path%3E%3Cpath d='M79.4 20.3c0-4.5-3.1-7.4-7.7-7.4H61.2v22.3H67v-7.5h2.2l4.1 7.5H80l-4.9-8.3C77.2 26.1 79.4 24 79.4 20.3z M71 22.5h-4V18h4c1.5 0 2.5 0.9 2.5 2.2C73.5 21.6 72.5 22.5 71 22.5z'%3E%3C/path%3E%3Cpolygon points='40.5 12.8 58.6 12.8 58.6 18.1 52.4 18.1 52.4 35.2 46.6 35.2 46.6 18.1 40.5 18.1'%3E%3C/polygon%3E%3C/svg%3E");
}
.copy-icon {
width: 16px;
height: 16px;
background-size: cover;
background-image: url("data:image/svg+xml,%3Csvg width='16' height='16' viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M10.5 10.4996H13.5V2.49963H5.5V5.49963' stroke='%2300854D' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M10.4998 5.49976H2.49976V13.4998H10.4998V5.49976Z' stroke='%2300854D' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
@media (max-width: 768px) {
body {
font-size: 0.8rem;
}
.btn {
--bs-btn-font-size: 0.8rem;
}
}
@media (max-width: 991px) {
.trezor-logo {
top: 10px;
}
.table.data-table>:not(caption)>*>* {
padding: 0.8rem 0.4rem;
}
}
@media (min-width: 769px) {
body {
font-size: 0.9rem;
}
.btn {
--bs-btn-font-size: 0.9rem;
}
}
@media (min-width: 1200px) {
.h1,
h1 {
font-size: 2.4rem;
}
body {
font-size: 1rem;
}
.btn {
--bs-btn-font-size: 1rem;
}
}

View File

@ -203,11 +203,11 @@
{{- end -}}
</select>
<div class="col-md-6">
<nav>{{template "paging" $data}}</nav>
{{template "paging" $data}}
</div>
</div>
<div class="data-div">
{{- range $tx := $addr.Transactions}}{{$data := setTxToTemplateData $data $tx}}{{template "txdetail" $data}}{{end -}}
</div>
<nav>{{template "paging" $data }}</nav>
{{template "paging" $data }}
{{end}}{{end}}

View File

@ -4,90 +4,92 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,shrink-to-fit=no">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<link rel="stylesheet" href="/static/css/main.css">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
<link rel="stylesheet" href="/static/css/main2.css">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3" crossorigin="anonymous"></script>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="description" content="Trezor {{.CoinLabel}} Explorer">
<title>Trezor {{.CoinLabel}} Explorer</title>
<script type="text/javascript">
window.onload=()=>{
document.querySelectorAll('[tt]').forEach(e=>new bootstrap.Tooltip(e,{title:e.getAttribute("tt")}));
document.querySelectorAll("#header .bb-group>.btn-check").forEach(e=>e.addEventListener('click',(x)=>console.log("clicked",x.target.id)));
}
</script>
</head>
<body>
<header id="header">
<div class="container">
<nav class="navbar navbar-expand-md navbar-dark bg-trezor">
<nav class="navbar navbar-expand-lg">
<div class="container">
<a class="navbar-brand" href="/" title="Home">
<div alt="Trezor Wallet" style="margin-top: 3px;">
<svg width="100" version="1.1" id="logotyp" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 163.7 41.9" space="preserve">
<polygon points="101.1,12.8 118.2,12.8 118.2,17.3 108.9,29.9 118.2,29.9 118.2,35.2 101.1,35.2 101.1,30.7 110.4,18.1 101.1,18.1"></polygon>
<path d="M158.8,26.9c2.1-0.8,4.3-2.9,4.3-6.6c0-4.5-3.1-7.4-7.7-7.4h-10.5v22.3h5.8v-7.5h2.2l4.1,7.5h6.7L158.8,26.9z M154.7,22.5h-4V18h4c1.5,0,2.5,0.9,2.5,2.2C157.2,21.6,156.2,22.5,154.7,22.5z"></path>
<path d="M130.8,12.5c-6.8,0-11.6,4.9-11.6,11.5s4.9,11.5,11.6,11.5s11.7-4.9,11.7-11.5S137.6,12.5,130.8,12.5z M130.8,30.3c-3.4,0-5.7-2.6-5.7-6.3c0-3.8,2.3-6.3,5.7-6.3c3.4,0,5.8,2.6,5.8,6.3C136.6,27.7,134.2,30.3,130.8,30.3z"></path>
<polygon points="82.1,12.8 98.3,12.8 98.3,18 87.9,18 87.9,21.3 98,21.3 98,26.4 87.9,26.4 87.9,30 98.3,30 98.3,35.2 82.1,35.2"></polygon>
<path d="M24.6,9.7C24.6,4.4,20,0,14.4,0S4.2,4.4,4.2,9.7v3.1H0v22.3h0l14.4,6.7l14.4-6.7h0V12.9h-4.2V9.7z M9.4,9.7c0-2.5,2.2-4.5,5-4.5s5,2,5,4.5v3.1H9.4V9.7z M23,31.5l-8.6,4l-8.6-4V18.1H23V31.5z"></path>
<path d="M79.4,20.3c0-4.5-3.1-7.4-7.7-7.4H61.2v22.3H67v-7.5h2.2l4.1,7.5H80l-4.9-8.3C77.2,26.1,79.4,24,79.4,20.3z M71,22.5h-4V18h4c1.5,0,2.5,0.9,2.5,2.2C73.5,21.6,72.5,22.5,71,22.5z"></path>
<polygon points="40.5,12.8 58.6,12.8 58.6,18.1 52.4,18.1 52.4,35.2 46.6,35.2 46.6,18.1 40.5,18.1"></polygon>
</svg>
</div>
<span class="trezor-logo"></span>
<span style="padding-left: 140px;">{{.CoinLabel}} Explorer</span>
</a>
<a class="navbar-brand" href="/">
{{.CoinLabel}} Explorer
</a>
<button class="navbar-toggler" type="button" onclick="if(document.getElementById('toggler').className.indexOf('show')>0){document.getElementById('toggler').className='navbar-collapse collapse'}else{document.getElementById('toggler').className='navbar-collapse show'}">
{{if .InternalExplorer}}
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse" id="toggler">
{{- if .InternalExplorer -}}
<ul class="navbar-nav ml-md-auto">
<li class="nav-item">
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav m-md-auto">
<li class="nav-item pe-xl-4">
<a href="/blocks" class="nav-link">Blocks</a>
</li>
<li class="nav-item">
<a href="/" class="nav-link">Status</a>
</li>
</ul>
<span class="navbar-form ml-md-auto">
<form id="search" action="/search" method="get">
<input name="q" type="text" class="form-control" placeholder="Search for block, transaction, address or xpub" focus="true">
<span class="navbar-form">
<form class="d-flex" id="search" action="/search" method="get">
<input name="q" type="text" class="form-control form-control-lg" placeholder="Search for block, transaction, address or xpub" focus="true">
<button class="btn" type="submit">
<span class="search-icon"></span>
</button>
</form>
</span>
{{- end -}}
<ul class="navbar-nav ml-md-auto">
<li class="nav-item">
<a class="nav-link" href="https://trezor.io/" target="_blank" rel="noopener noreferrer">Trezor</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://suite.trezor.io/" target="_blank" rel="noopener noreferrer">Suite</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://trezor.io/support" target="_blank" rel="noopener noreferrer">Support</a>
</li>
</ul>
<div class="bb-group ms-lg-2 mt-2 mt-lg-0" role="group" aria-label="Currency switch">
<input type="radio" class="btn-check" name="btnradio" id="primary-currency" autocomplete="off" checked>
<label class="btn" for="primary-currency">tGOR</label>
<input type="radio" class="btn-check" name="btnradio" id="secondary-currency" autocomplete="off">
<label class="btn" for="secondary-currency">USD</label>
</div>
</div>
</nav>
</div>
{{end}}
</div>
</nav>
</header>
<main id="wrap">
<div class="container">
{{- template "specific" . -}}
</div>
</main>
<footer id="footer" class="footer">
<footer id="footer">
<div class="container">
<nav class="navbar navbar-expand-lg navbar-dark bg-trezor">
<nav class="navbar navbar-dark">
<span class="navbar-nav">
<a class="nav-link" href="https://satoshilabs.com/" target="_blank" rel="noopener noreferrer">© 2017-2022 SatoshiLabs</a>
<a class="nav-link" href="https://satoshilabs.com/" target="_blank" rel="noopener noreferrer">©2022 SatoshiLabs</a>
</span>
<span class="navbar-nav ml-md-auto">
<a class="nav-link" href="{{- .TOSLink -}}" target="_blank" rel="noopener noreferrer">Terms of Use</a>
</span>
<span class="navbar-nav ml-md-auto d-md-flex d-none">
<a class="nav-link" href="https://trezor.io/" target="_blank" rel="noopener noreferrer">Trezor</a>
</span>
<span class="navbar-nav ml-md-auto d-md-flex d-none">
<a class="nav-link" href="https://suite.trezor.io/" target="_blank" rel="noopener noreferrer">Suite</a>
</span>
<span class="navbar-nav ml-md-auto d-md-flex d-none">
<a class="nav-link" href="https://trezor.io/support" target="_blank" rel="noopener noreferrer">Support</a>
</span>
<span class="navbar-nav ml-md-auto">
<a class="nav-link" href="/sendtx">Send Transaction</a>
</span>
<span class="navbar-nav ml-md-auto d-md-flex d-none">
<a class="nav-link active" href="http://shop.trezor.io" target="_blank" rel="noopener noreferrer">Don't have a Trezor? Get one!</a>
<span class="navbar-nav ml-md-auto d-lg-flex d-none">
<a class="nav-link" href="http://shop.trezor.io" target="_blank" rel="noopener noreferrer">Don't have a Trezor? Get one!</a>
</span>
</nav>
</div>
</footer>
</body>
</html>
</html>

View File

@ -1,15 +1,13 @@
{{define "specific"}}{{$cs := .CoinShortcut}}{{$b := .Block}}{{$data := . -}}
<h1>Block {{$b.Height}}</h1>
<h1>Block {{formatUint32 $b.Height}}</h1>
<div class="alert alert-data ellipsis">
<span class="data">{{$b.Hash}}</span>
</div>
<div class="row h-container">
<h3 class="col-md-6 col-sm-12">Summary</h3>
<nav class="col-md-6 col-sm-12">
<ul class="pagination justify-content-end">
<li class="page-item">{{if $b.Prev}}<a class="page-link" href="/block/{{$b.Prev}}">Previous Block</a>{{else}}<span class="page-link text-muted disabled">Previous Block</span>{{end}}</li>
<li class="page-item">{{if $b.Next}}<a class="page-link" href="/block/{{$b.Next}}">Next Block</a>{{else}}<span class="page-link text-muted disabled">Next Block</span>{{end}}</li>
</ul>
<h3 class="col-md-6">Summary</h3>
<nav class="col-md-6 paging justify-content-end">
{{if $b.Prev}}<a class="btn btn-paging" href="/block/{{$b.Prev}}">Previous Block</a>{{else}}<span class="btn btn-paging">Previous Block</span>{{end}}
{{if $b.Next}}<a class="btn btn-paging ms-2" href="/block/{{$b.Next}}">Next Block</a>{{else}}<span class="btn btn-paging ms-2">Next Block</span>{{end}}
</nav>
</div>
<div class="data-div row">
@ -69,10 +67,10 @@
{{- if $b.Transactions -}}
<div class="row h-container">
<h3 class="col-md-6 col-sm-12">Transactions</h3>
<nav class="col-md-6 col-sm-12">{{template "paging" $data}}</nav>
<div class="col-md-6 col-sm-12">{{template "paging" $data}}</div>
</div>
<div class="data-div">
{{- range $tx := $b.Transactions}}{{$data := setTxToTemplateData $data $tx}}{{template "txdetail" $data}}{{end -}}
</div>
<nav>{{template "paging" $data }}</nav>
{{template "paging" $data }}
{{end}}{{end}}

View File

@ -1,31 +1,32 @@
{{define "specific"}}{{$blocks := .Blocks}}{{$data := .}}
<h1>Blocks <small class="text-muted">by date</small>
</h1>
<div class="row">
<div class="col-md-6"><h1>Blocks</h1></div>
<div class="col-md-6">{{if $blocks.Blocks}}{{template "paging" $data }}{{end}}</div>
</row>
{{if $blocks.Blocks -}}
<nav>{{template "paging" $data }}</nav>
<div class="data-div">
<table class="table table-striped data-table table-hover">
<div>
<table class="table table-hover data-table">
<thead>
<tr>
<th style="width: 10%;">Height</th>
<th style="width: 48%;">Hash</th>
<th>Timestamp</span></th>
<th class="text-right" style="width: 10%;">Transactions</th>
<th class="text-right" style="width: 10%;">Size</th>
<th>Height</th>
<th class="col-md-6">Hash</th>
<th class="col-md-2">Timestamp</span></th>
<th class="text-end">Transactions</th>
<th class="text-end">Size</th>
</tr>
</thead>
<tbody>
{{- range $b := $blocks.Blocks -}}
<tr>
<td><a href="/block/{{$b.Height}}">{{$b.Height}}</a></td>
<td><a href="/block/{{$b.Height}}">{{formatUint32 $b.Height}}</a></td>
<td class="ellipsis">{{$b.Hash}}</td>
<td>{{formatUnixTime $b.Time}}</td>
<td class="text-right">{{$b.Txs}}</td>
<td class="text-right">{{$b.Size}}</td>
<td class="text-end">{{formatUint32 $b.Txs}}</td>
<td class="text-end">{{formatUint32 $b.Size}}</td>
</tr>
{{- end -}}
</tbody>
</table>
</div>
<nav>{{template "paging" $data }}</nav>
{{template "paging" $data }}
{{end}}{{end}}

View File

@ -1,129 +1,135 @@
{{define "specific"}}{{$cs := .CoinShortcut}}{{$bb := .Info.Blockbook}}{{$be := .Info.Backend}}
<h1>Application status</h1>
{{- if $bb.InitialSync -}}
<h3 class="bg-danger text-white" style="padding: 20px;">Application is now in initial synchronization and does not provide any data.</h3>
<h3><span class="badge bg-danger text-white p-3 w-100" style="white-space: break-spaces;">Application is now in initial synchronization and does not provide any data.</span></h3>
{{- end -}}
{{- if not $bb.SyncMode -}}
<h3 class="bg-warning text-white" style="padding: 20px;">Synchronization with backend is disabled, the state of index is not up to date.</h3>
<h3><span class="badge bg-warning text-white p-3 w-100" style="white-space: break-spaces;">Synchronization with backend is disabled, the state of index is not up to date.</span></h3>
{{- end -}}
<div class="row">
<div class="col-md-6">
<h3>Blockbook</h3>
<table class="table data-table">
<div class="col-lg-6">
<table class="table data-table info-table">
<tbody>
<tr>
<td style="width: 33%;">Coin</td>
<td class="data">{{$bb.Coin}}</td>
<td style="white-space: nowrap;"><h3>Blockbook</h3></td>
<td></td>
</tr>
<tr>
<td>Coin</td>
<td>{{$bb.Coin}}</td>
</tr>
<tr>
<td>Host</td>
<td class="data">{{$bb.Host}}</td>
<td>{{$bb.Host}}</td>
</tr>
<tr>
<td>Version / Commit / Build</td>
<td class="data">{{$bb.Version}} / <a href="https://github.com/trezor/blockbook/commit/{{$bb.GitCommit}}" target="_blank" rel="noopener noreferrer">{{$bb.GitCommit}}</a> / {{$bb.BuildTime}}</td>
<td>{{$bb.Version}} / <a href="https://github.com/trezor/blockbook/commit/{{$bb.GitCommit}}" target="_blank" rel="noopener noreferrer">{{$bb.GitCommit}}</a> / {{$bb.BuildTime}}</td>
</tr>
<tr>
<td>Synchronized</td>
<td class="data {{if not $bb.InSync}}text-danger{{else}}text-success{{end}}">{{$bb.InSync}}</td>
<td><h6 class="badge {{if not $bb.InSync}}bg-danger{{else}}bg-success{{end}}">{{$bb.InSync}}</h6></td>
</tr>
<tr>
<td>Last Block</td>
<td class="data">{{if .InternalExplorer}}<a href="/block/{{$bb.BestHeight}}">{{$bb.BestHeight}}</a>{{else}}{{$bb.BestHeight}}{{end}}</td>
<td>{{if .InternalExplorer}}<a href="/block/{{$bb.BestHeight}}">{{formatUint32 $bb.BestHeight}}</a>{{else}}{{formatUint32 $bb.BestHeight}}{{end}}</td>
</tr>
<tr>
<td>Last Block Update</td>
<td class="data">{{formatTime $bb.LastBlockTime}}</td>
<td>{{formatTime $bb.LastBlockTime}}</td>
</tr>
<tr>
<td>Mempool in Sync</td>
<td class="data {{if not $bb.InSyncMempool}}text-danger{{else}}text-success{{end}}">{{$bb.InSyncMempool}}</td>
<td><h6 class="badge {{if not $bb.InSyncMempool}}bg-danger{{else}}bg-success{{end}}">{{$bb.InSyncMempool}}</h6></td>
</tr>
<tr>
<td>Last Mempool Update</td>
<td class="data">{{formatTime $bb.LastMempoolTime}}</td>
<td>{{formatTime $bb.LastMempoolTime}}</td>
</tr>
<tr>
<td>Transactions in Mempool</td>
<td class="data">{{if .InternalExplorer}}<a href="/mempool">{{$bb.MempoolSize}}</a>{{else}}{{$bb.MempoolSize}}{{end}}</td>
<td>{{if .InternalExplorer}}<a href="/mempool">{{$bb.MempoolSize}}</a>{{else}}{{formatInt $bb.MempoolSize}}{{end}}</td>
</tr>
{{- if $bb.HasFiatRates -}}
<tr>
<td>Current Fiat rates</td>
<td class="data">{{formatTime $bb.CurrentFiatRatesTime}}</td>
<td>{{formatTime $bb.CurrentFiatRatesTime}}</td>
</tr>
<tr>
<td>Historical Fiat rates</td>
<td class="data">{{formatTime $bb.HistoricalFiatRatesTime}}{{if $bb.HasTokenFiatRates}}<br>tokens {{formatTime $bb.HistoricalTokenFiatRatesTime}}{{end}}</td>
<td>{{formatTime $bb.HistoricalFiatRatesTime}}{{if $bb.HasTokenFiatRates}}<br>tokens {{formatTime $bb.HistoricalTokenFiatRatesTime}}{{end}}</td>
</tr>
{{- end -}}
<tr>
<td>Size On Disk</td>
<td class="data">{{$bb.DbSize}}</td>
<td>{{formatInt64 $bb.DbSize}}</td>
</tr>
</tbody>
</table>
</div>
<div class="col-md-6">
<h3>Backend</h3>
<table class="table data-table">
<div class="col-lg-6">
<table class="table data-table info-table">
<tbody>
<tr>
<td style="white-space: nowrap;"><h3>Backend</h3></td>
<td></td>
</tr>
{{- if $be.BackendError -}}
<tr>
<td style="width: 30%;">Backend Error</td>
<td>Backend Error</td>
<td class="data text-danger">{{$be.BackendError}}</td>
</tr>
{{- end -}}
<tr>
<td style="width: 30%;">Chain</td>
<td class="data">{{$be.Chain}}</td>
<td>Chain</td>
<td>{{$be.Chain}}</td>
</tr>
<tr>
<td>Version</td>
<td class="data">{{$be.Version}}</td>
<td>{{$be.Version}}</td>
</tr>
{{- if $be.Subversion -}}
<tr>
<td>Subversion</td>
<td class="data">{{$be.Subversion}}</td>
<td>{{$be.Subversion}}</td>
</tr>
{{- end -}}
{{- if $be.ProtocolVersion -}}
<tr>
<td>Protocol Version</td>
<td class="data">{{$be.ProtocolVersion}}</td>
<td>{{$be.ProtocolVersion}}</td>
</tr>
{{- end -}}
{{- if $be.ConsensusVersion -}}
<tr>
<td>Consensus Version</td>
<td class="data">{{$be.ConsensusVersion}}</td>
<td>{{$be.ConsensusVersion}}</td>
</tr>
{{- end -}}
<tr>
<td>Last Block</td>
<td class="data">{{$be.Blocks}}</td>
<td>{{formatInt $be.Blocks}}</td>
</tr>
<tr>
<td>Difficulty</td>
<td class="data">{{$be.Difficulty}}</td>
<td>{{$be.Difficulty}}</td>
</tr>
{{- if $be.Timeoffset -}}
<tr>
<td>Timeoffset</td>
<td class="data">{{$be.Timeoffset}}</td>
<td>{{$be.Timeoffset}}</td>
</tr>
{{- end -}}
{{- if $be.SizeOnDisk -}}
<tr>
<td>Size On Disk</td>
<td class="data">{{$be.SizeOnDisk}}</td>
<td>{{formatInt64 $be.SizeOnDisk}}</td>
</tr>
{{- end -}}
{{- if $be.Consensus -}}
<tr>
<td>Consensus</td>
<td class="data">{{toJSON $be.Consensus}}</td>
<td>{{toJSON $be.Consensus}}</td>
</tr>
{{- end -}}
{{- if $be.Warnings -}}

View File

@ -1,16 +1,14 @@
{{define "specific"}}{{$txs := .MempoolTxids.Mempool}}{{$data := .}}
<h1>Mempool Transactions <small class="text-muted">by time of appearance</small>
</h1>
<div class="row h-container">
<h5 class="col-md-6 col-sm-12">{{$.MempoolTxids.MempoolSize}} transactions in mempool</h5>
<nav class="col-md-6 col-sm-12">{{template "paging" $data }}</nav>
</div>
<div class="data-div">
<table class="table table-striped data-table table-hover">
<div class="row">
<div class="col-lg-6"><h1>Mempool Transactions</h1><h5 class="mb-lg-0">{{$.MempoolTxids.MempoolSize}} transactions in mempool</h5></div>
<div class="col-lg-6">{{if $txs}}{{template "paging" $data }}{{end}}</div>
</row>
<div>
<table class="table data-table table-hover">
<thead>
<tr>
<th style="width: 70%;">Transaction</th>
<th style="width: 30%;">Time</th>
<th style="width: 30%;">Time of appearance</th>
</tr>
</thead>
<tbody>
@ -23,5 +21,5 @@
</tbody>
</table>
</div>
<nav>{{template "paging" $data }}</nav>
{{template "paging" $data }}
{{end}}

View File

@ -1,11 +1,16 @@
{{- define "paging"}}{{$data := .}}{{if $data.PrevPage -}}
<ul class="pagination justify-content-end">
<li class="page-item"><a class="page-link" href="?page={{$data.PrevPage}}{{$data.PageParams}}">&lt;</a></li>
{{- range $p := $data.PagingRange -}}
<li class="page-item{{if eq $data.Page $p}} active{{end}}">
{{- if $p}}<a class="page-link" href="?page={{$p}}{{$data.PageParams}}">{{$p}}</a>
{{- else}}<span class="page-text">...</span>{{end -}}
</li>{{- end -}}
<li class="page-item"><a class="page-link" href="?page={{$data.NextPage}}{{$data.PageParams}}">&gt;</a></li>
</ul>
{{- end}}{{end -}}
{{define "paging"}}{{$data := .}}{{if $data.PrevPage}}
<nav class="paging justify-content-end">
<a class="btn btn-paging" href="?page={{$data.PrevPage}}{{$data.PageParams}}">Previous</a>
{{if $data.PagingRange}}
<div class="paging-group mx-2">
<div class="bb-group">
{{range $p := $data.PagingRange}}
{{if $p}}<a class="btn{{if eq $data.Page $p}} active{{end}}" href="?page={{$p}}{{$data.PageParams}}">{{$p}}</a>
{{else}}<span>...</span>{{end}}
{{end}}
</div>
</div>
{{end}}
<a class="btn btn-paging" href="?page={{$data.NextPage}}{{$data.PageParams}}">Next</a>
</nav>
{{end}}{{end}}

View File

@ -97,11 +97,11 @@
<option {{if eq $addr.Filter "outputs" -}} selected{{end}} value="outputs">XPUB addresses on output side</option>
</select>
<div class="col-md-6">
<nav>{{template "paging" $data}}</nav>
{{template "paging" $data}}
</div>
</div>
<div class="data-div">
{{- range $tx := $addr.Transactions}}{{$data := setTxToTemplateData $data $tx}}{{template "txdetail" $data}}{{end -}}
</div>
<nav>{{template "paging" $data }}</nav>
{{template "paging" $data }}
{{end}}{{end}}