Display amounts in secondary currency in explorer
This commit is contained in:
parent
715567d7f3
commit
86743cfca5
262
server/public.go
262
server/public.go
@ -30,6 +30,8 @@ const blocksOnPage = 50
|
||||
const mempoolTxsOnPage = 50
|
||||
const txsInAPI = 1000
|
||||
|
||||
const secondaryCoinCookieName = "secondary_coin"
|
||||
|
||||
const (
|
||||
_ = iota
|
||||
apiV1
|
||||
@ -330,8 +332,8 @@ func (s *PublicServer) jsonHandler(handler func(r *http.Request, apiVersion int)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *PublicServer) newTemplateData() *TemplateData {
|
||||
return &TemplateData{
|
||||
func (s *PublicServer) newTemplateData(r *http.Request) *TemplateData {
|
||||
t := &TemplateData{
|
||||
CoinName: s.is.Coin,
|
||||
CoinShortcut: s.is.CoinShortcut,
|
||||
CoinLabel: s.is.CoinLabel,
|
||||
@ -339,10 +341,47 @@ func (s *PublicServer) newTemplateData() *TemplateData {
|
||||
InternalExplorer: s.internalExplorer && !s.is.InitialSync,
|
||||
TOSLink: api.Text.TOSLink,
|
||||
}
|
||||
if s.is.HasFiatRates {
|
||||
// get the secondary coin and if it should be shown either from query parameters "secondary" and "use_secondary"
|
||||
// or from the cookie "secondary_coin" in the format secondary=use_secondary, for example EUR=true
|
||||
// the query parameters take precedence over the cookie
|
||||
var cookieSecondary string
|
||||
var cookieUseSecondary bool
|
||||
cookie, _ := r.Cookie(secondaryCoinCookieName)
|
||||
if cookie != nil {
|
||||
a := strings.Split(cookie.Value, "=")
|
||||
if len(a) == 2 {
|
||||
cookieSecondary = a[0]
|
||||
cookieUseSecondary, _ = strconv.ParseBool(a[1])
|
||||
}
|
||||
}
|
||||
secondary := strings.ToLower(r.URL.Query().Get("secondary"))
|
||||
if secondary == "" {
|
||||
if cookieSecondary != "" {
|
||||
secondary = strings.ToLower(cookieSecondary)
|
||||
} else {
|
||||
secondary = "usd"
|
||||
}
|
||||
}
|
||||
ticker := s.is.GetCurrentTicker(secondary, "")
|
||||
if ticker == nil && secondary != "usd" {
|
||||
secondary = "usd"
|
||||
ticker = s.is.GetCurrentTicker(secondary, "")
|
||||
}
|
||||
if ticker != nil {
|
||||
t.SecondaryCoin = strings.ToUpper(secondary)
|
||||
t.CurrentSecondaryCoinRate = float64(ticker.Rates[secondary])
|
||||
t.UseSecondaryCoin, _ = strconv.ParseBool(r.URL.Query().Get("use_secondary"))
|
||||
if !t.UseSecondaryCoin {
|
||||
t.UseSecondaryCoin = cookieUseSecondary
|
||||
}
|
||||
}
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
func (s *PublicServer) newTemplateDataWithError(text string) *TemplateData {
|
||||
td := s.newTemplateData()
|
||||
func (s *PublicServer) newTemplateDataWithError(text string, r *http.Request) *TemplateData {
|
||||
td := s.newTemplateData(r)
|
||||
td.Error = &api.APIError{Text: text}
|
||||
return td
|
||||
}
|
||||
@ -359,9 +398,9 @@ func (s *PublicServer) htmlTemplateHandler(handler func(w http.ResponseWriter, r
|
||||
debug.PrintStack()
|
||||
t = errorInternalTpl
|
||||
if s.debug {
|
||||
data = s.newTemplateDataWithError(fmt.Sprint("Internal server error: recovered from panic ", e))
|
||||
data = s.newTemplateDataWithError(fmt.Sprint("Internal server error: recovered from panic ", e), r)
|
||||
} else {
|
||||
data = s.newTemplateDataWithError("Internal server error")
|
||||
data = s.newTemplateDataWithError("Internal server error", r)
|
||||
}
|
||||
}
|
||||
// noTpl means the handler completely handled the request
|
||||
@ -387,7 +426,7 @@ func (s *PublicServer) htmlTemplateHandler(handler func(w http.ResponseWriter, r
|
||||
if err != nil || (data == nil && t != noTpl) {
|
||||
t = errorInternalTpl
|
||||
if apiErr, ok := err.(*api.APIError); ok {
|
||||
data = s.newTemplateData()
|
||||
data = s.newTemplateData(r)
|
||||
data.Error = apiErr
|
||||
if apiErr.Public {
|
||||
t = errorTpl
|
||||
@ -397,12 +436,16 @@ func (s *PublicServer) htmlTemplateHandler(handler func(w http.ResponseWriter, r
|
||||
glog.Error(handlerName, " error: ", err)
|
||||
}
|
||||
if s.debug {
|
||||
data = s.newTemplateDataWithError(fmt.Sprintf("Internal server error: %v, data %+v", err, data))
|
||||
data = s.newTemplateDataWithError(fmt.Sprintf("Internal server error: %v, data %+v", err, data), r)
|
||||
} else {
|
||||
data = s.newTemplateDataWithError("Internal server error")
|
||||
data = s.newTemplateDataWithError("Internal server error", r)
|
||||
}
|
||||
}
|
||||
}
|
||||
// if SecondaryCoin is specified, set secondary_coin cookie
|
||||
if data != nil && data.SecondaryCoin != "" {
|
||||
http.SetCookie(w, &http.Cookie{Name: secondaryCoinCookieName, Value: data.SecondaryCoin + "=" + strconv.FormatBool(data.UseSecondaryCoin), Path: "/"})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -427,31 +470,37 @@ const (
|
||||
|
||||
// TemplateData is used to transfer data to the templates
|
||||
type TemplateData struct {
|
||||
CoinName string
|
||||
CoinShortcut string
|
||||
CoinLabel string
|
||||
InternalExplorer bool
|
||||
ChainType bchain.ChainType
|
||||
Address *api.Address
|
||||
AddrStr string
|
||||
Tx *api.Tx
|
||||
Error *api.APIError
|
||||
Blocks *api.Blocks
|
||||
Block *api.Block
|
||||
Info *api.SystemInfo
|
||||
MempoolTxids *api.MempoolTxids
|
||||
Page int
|
||||
PrevPage int
|
||||
NextPage int
|
||||
PagingRange []int
|
||||
PageParams template.URL
|
||||
TOSLink string
|
||||
SendTxHex string
|
||||
Status string
|
||||
NonZeroBalanceTokens bool
|
||||
TokenId string
|
||||
URI string
|
||||
ContractInfo *bchain.ContractInfo
|
||||
CoinName string
|
||||
CoinShortcut string
|
||||
CoinLabel string
|
||||
InternalExplorer bool
|
||||
ChainType bchain.ChainType
|
||||
Address *api.Address
|
||||
AddrStr string
|
||||
Tx *api.Tx
|
||||
Error *api.APIError
|
||||
Blocks *api.Blocks
|
||||
Block *api.Block
|
||||
Info *api.SystemInfo
|
||||
MempoolTxids *api.MempoolTxids
|
||||
Page int
|
||||
PrevPage int
|
||||
NextPage int
|
||||
PagingRange []int
|
||||
PageParams template.URL
|
||||
TOSLink string
|
||||
SendTxHex string
|
||||
Status string
|
||||
NonZeroBalanceTokens bool
|
||||
TokenId string
|
||||
URI string
|
||||
ContractInfo *bchain.ContractInfo
|
||||
SecondaryCoin string
|
||||
UseSecondaryCoin bool
|
||||
CurrentSecondaryCoinRate float64
|
||||
TxBlocktime int64
|
||||
TxDate string
|
||||
TxBlocktimeSecondaryCoinRate float64
|
||||
}
|
||||
|
||||
func (s *PublicServer) parseTemplates() []*template.Template {
|
||||
@ -460,6 +509,7 @@ func (s *PublicServer) parseTemplates() []*template.Template {
|
||||
"formatUnixTime": formatUnixTime,
|
||||
"formatAmount": s.formatAmount,
|
||||
"formatAmountWithDecimals": formatAmountWithDecimals,
|
||||
"amount": s.amount,
|
||||
"formatInt64": formatInt64,
|
||||
"formatInt": formatInt,
|
||||
"formatUint32": formatUint32,
|
||||
@ -605,8 +655,6 @@ func toJSON(data interface{}) string {
|
||||
return string(json)
|
||||
}
|
||||
|
||||
// for now return the string as it is
|
||||
// in future could be used to do coin specific formatting
|
||||
func (s *PublicServer) formatAmount(a *api.Amount) string {
|
||||
if a == nil {
|
||||
return "0"
|
||||
@ -621,6 +669,79 @@ func formatAmountWithDecimals(a *api.Amount, d int) string {
|
||||
return a.DecimalString(d)
|
||||
}
|
||||
|
||||
func appendAmountSpan(rv *strings.Builder, class, amount, shortcut, txDate string) {
|
||||
rv.WriteString(`<span class="`)
|
||||
rv.WriteString(class)
|
||||
rv.WriteString(`"`)
|
||||
if txDate != "" {
|
||||
rv.WriteString(` tm="`)
|
||||
rv.WriteString(txDate)
|
||||
rv.WriteString(`"`)
|
||||
}
|
||||
rv.WriteString(">")
|
||||
i := strings.IndexByte(amount, '.')
|
||||
if i < 0 {
|
||||
appendSeparatedNumberSpans(rv, amount, "nc")
|
||||
} else {
|
||||
appendSeparatedNumberSpans(rv, amount[:i], "nc")
|
||||
rv.WriteString(`.`)
|
||||
rv.WriteString(`<span class="amt-dec">`)
|
||||
appendLeftSeparatedNumberSpans(rv, amount[i+1:], "ns")
|
||||
rv.WriteString("</span>")
|
||||
}
|
||||
rv.WriteString(" ")
|
||||
rv.WriteString(shortcut)
|
||||
rv.WriteString("</span>")
|
||||
}
|
||||
|
||||
func (s *PublicServer) amount(a *api.Amount, td *TemplateData, classes string) template.HTML {
|
||||
primary := s.formatAmount(a)
|
||||
var rv strings.Builder
|
||||
rv.WriteString(`<span class="amt`)
|
||||
if classes != "" {
|
||||
rv.WriteString(` `)
|
||||
rv.WriteString(classes)
|
||||
}
|
||||
rv.WriteString(`" cc="`)
|
||||
rv.WriteString(primary)
|
||||
rv.WriteString(" ")
|
||||
rv.WriteString(td.CoinShortcut)
|
||||
rv.WriteString(`">`)
|
||||
appendAmountSpan(&rv, "prim-amt", primary, td.CoinShortcut, "")
|
||||
if td.SecondaryCoin != "" {
|
||||
base, err := strconv.ParseFloat(primary, 64)
|
||||
if err == nil {
|
||||
currentSecondary := strconv.FormatFloat(base*td.CurrentSecondaryCoinRate, 'f', 2, 64)
|
||||
blocktimeSecondary := ""
|
||||
// if tx is specified, secondary amount is at the time of tx and current amount with class "csec-amt"
|
||||
if td.Tx != nil {
|
||||
if td.Tx.Blocktime != td.TxBlocktime {
|
||||
td.TxBlocktime = td.Tx.Blocktime
|
||||
date := time.Unix(td.Tx.Blocktime, 0).UTC()
|
||||
secondary := strings.ToLower(td.SecondaryCoin)
|
||||
ticker, _ := s.db.FiatRatesFindTicker(&date, secondary, "")
|
||||
if ticker != nil {
|
||||
td.TxBlocktimeSecondaryCoinRate = float64(ticker.Rates[secondary])
|
||||
// the ticker is from the midnight, valid for the whole day before
|
||||
td.TxDate = date.Add(-1 * time.Second).Format("2006-01-02")
|
||||
}
|
||||
}
|
||||
if td.TxBlocktimeSecondaryCoinRate != 0 {
|
||||
blocktimeSecondary = strconv.FormatFloat(base*td.TxBlocktimeSecondaryCoinRate, 'f', 2, 64)
|
||||
}
|
||||
}
|
||||
if blocktimeSecondary != "" {
|
||||
appendAmountSpan(&rv, "sec-amt", blocktimeSecondary, td.SecondaryCoin, td.TxDate)
|
||||
appendAmountSpan(&rv, "csec-amt", currentSecondary, td.SecondaryCoin, "")
|
||||
} else {
|
||||
appendAmountSpan(&rv, "sec-amt", currentSecondary, td.SecondaryCoin, "")
|
||||
}
|
||||
}
|
||||
}
|
||||
rv.WriteString("</span>")
|
||||
return template.HTML(rv.String())
|
||||
}
|
||||
|
||||
func formatInt(i int) template.HTML {
|
||||
return formatInt64(int64(i))
|
||||
}
|
||||
@ -629,23 +750,58 @@ func formatUint32(i uint32) template.HTML {
|
||||
return formatInt64(int64(i))
|
||||
}
|
||||
|
||||
func formatInt64(i int64) template.HTML {
|
||||
s := strconv.FormatInt(i, 10)
|
||||
func appendSeparatedNumberSpans(rv *strings.Builder, s, separatorClass string) {
|
||||
t := (len(s) - 1) / 3
|
||||
if t <= 0 {
|
||||
return template.HTML(s)
|
||||
rv.WriteString(s)
|
||||
} else {
|
||||
t *= 3
|
||||
rv.WriteString(s[:len(s)-t])
|
||||
for i := len(s) - t; i < len(s); i += 3 {
|
||||
rv.WriteString(`<span class="`)
|
||||
rv.WriteString(separatorClass)
|
||||
rv.WriteString(`">`)
|
||||
rv.WriteString(s[i : i+3])
|
||||
rv.WriteString("</span>")
|
||||
}
|
||||
}
|
||||
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>"
|
||||
}
|
||||
|
||||
func appendLeftSeparatedNumberSpans(rv *strings.Builder, s, separatorClass string) {
|
||||
l := len(s)
|
||||
if l <= 3 {
|
||||
rv.WriteString(s)
|
||||
} else {
|
||||
rv.WriteString(s[:3])
|
||||
for i := 3; i < len(s); i += 3 {
|
||||
rv.WriteString(`<span class="`)
|
||||
rv.WriteString(separatorClass)
|
||||
rv.WriteString(`">`)
|
||||
e := i + 3
|
||||
if e > l {
|
||||
e = l
|
||||
}
|
||||
rv.WriteString(s[i:e])
|
||||
rv.WriteString("</span>")
|
||||
}
|
||||
}
|
||||
return template.HTML(rv)
|
||||
}
|
||||
|
||||
func formatInt64(i int64) template.HTML {
|
||||
s := strconv.FormatInt(i, 10)
|
||||
var rv strings.Builder
|
||||
appendSeparatedNumberSpans(&rv, s, "ns")
|
||||
return template.HTML(rv.String())
|
||||
}
|
||||
|
||||
// called from template to support txdetail.html functionality
|
||||
func setTxToTemplateData(td *TemplateData, tx *api.Tx) *TemplateData {
|
||||
td.Tx = tx
|
||||
// reset the TxBlocktimeSecondaryCoinRate if different Blocktime
|
||||
if td.TxBlocktime != tx.Blocktime {
|
||||
td.TxBlocktime = 0
|
||||
td.TxBlocktimeSecondaryCoinRate = 0
|
||||
}
|
||||
return td
|
||||
}
|
||||
|
||||
@ -704,7 +860,7 @@ func (s *PublicServer) explorerTx(w http.ResponseWriter, r *http.Request) (tpl,
|
||||
return errorTpl, nil, err
|
||||
}
|
||||
}
|
||||
data := s.newTemplateData()
|
||||
data := s.newTemplateData(r)
|
||||
data.Tx = tx
|
||||
return txTpl, data, nil
|
||||
}
|
||||
@ -814,7 +970,7 @@ func (s *PublicServer) explorerAddress(w http.ResponseWriter, r *http.Request) (
|
||||
if err != nil {
|
||||
return errorTpl, nil, err
|
||||
}
|
||||
data := s.newTemplateData()
|
||||
data := s.newTemplateData(r)
|
||||
data.AddrStr = address.AddrStr
|
||||
data.Address = address
|
||||
data.Page = address.Page
|
||||
@ -844,7 +1000,7 @@ func (s *PublicServer) explorerNftDetail(w http.ResponseWriter, r *http.Request)
|
||||
if ci == nil {
|
||||
return errorTpl, nil, api.NewAPIError(fmt.Sprintf("Unknown contract %s", contract), true)
|
||||
}
|
||||
data := s.newTemplateData()
|
||||
data := s.newTemplateData(r)
|
||||
data.TokenId = tokenId
|
||||
data.ContractInfo = ci
|
||||
data.URI = uri
|
||||
@ -870,7 +1026,7 @@ func (s *PublicServer) explorerXpub(w http.ResponseWriter, r *http.Request) (tpl
|
||||
}
|
||||
return errorTpl, nil, err
|
||||
}
|
||||
data := s.newTemplateData()
|
||||
data := s.newTemplateData(r)
|
||||
data.AddrStr = address.AddrStr
|
||||
data.Address = address
|
||||
data.Page = address.Page
|
||||
@ -895,7 +1051,7 @@ func (s *PublicServer) explorerBlocks(w http.ResponseWriter, r *http.Request) (t
|
||||
if err != nil {
|
||||
return errorTpl, nil, err
|
||||
}
|
||||
data := s.newTemplateData()
|
||||
data := s.newTemplateData(r)
|
||||
data.Blocks = blocks
|
||||
data.Page = blocks.Page
|
||||
data.PagingRange, data.PrevPage, data.NextPage = getPagingRange(blocks.Page, blocks.TotalPages)
|
||||
@ -916,7 +1072,7 @@ func (s *PublicServer) explorerBlock(w http.ResponseWriter, r *http.Request) (tp
|
||||
return errorTpl, nil, err
|
||||
}
|
||||
}
|
||||
data := s.newTemplateData()
|
||||
data := s.newTemplateData(r)
|
||||
data.Block = block
|
||||
data.Page = block.Page
|
||||
data.PagingRange, data.PrevPage, data.NextPage = getPagingRange(block.Page, block.TotalPages)
|
||||
@ -931,7 +1087,7 @@ func (s *PublicServer) explorerIndex(w http.ResponseWriter, r *http.Request) (tp
|
||||
if err != nil {
|
||||
return errorTpl, nil, err
|
||||
}
|
||||
data := s.newTemplateData()
|
||||
data := s.newTemplateData(r)
|
||||
data.Info = si
|
||||
return indexTpl, data, nil
|
||||
}
|
||||
@ -970,7 +1126,7 @@ func (s *PublicServer) explorerSearch(w http.ResponseWriter, r *http.Request) (t
|
||||
|
||||
func (s *PublicServer) explorerSendTx(w http.ResponseWriter, r *http.Request) (tpl, *TemplateData, error) {
|
||||
s.metrics.ExplorerViews.With(common.Labels{"action": "sendtx"}).Inc()
|
||||
data := s.newTemplateData()
|
||||
data := s.newTemplateData(r)
|
||||
if r.Method == http.MethodPost {
|
||||
err := r.ParseForm()
|
||||
if err != nil {
|
||||
@ -1002,7 +1158,7 @@ func (s *PublicServer) explorerMempool(w http.ResponseWriter, r *http.Request) (
|
||||
if err != nil {
|
||||
return errorTpl, nil, err
|
||||
}
|
||||
data := s.newTemplateData()
|
||||
data := s.newTemplateData(r)
|
||||
data.MempoolTxids = mempoolTxids
|
||||
data.Page = mempoolTxids.Page
|
||||
data.PagingRange, data.PrevPage, data.NextPage = getPagingRange(mempoolTxids.Page, mempoolTxids.TotalPages)
|
||||
|
||||
@ -1,86 +1,32 @@
|
||||
html, body {
|
||||
@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 {
|
||||
width: 100%;
|
||||
min-height: 100%;
|
||||
background-color: #ffffff;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Helvetica Neue", Arial, sans-serif;
|
||||
font-size: 11px;
|
||||
margin: 0;
|
||||
background: linear-gradient(to bottom, #f6f6f6 300px, #e5e5e5 0), #e5e5e5;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #428bca;
|
||||
color: #00854d;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
h1 small {
|
||||
font-size: 65%;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.octicon {
|
||||
color: #777;
|
||||
display: inline-block;
|
||||
vertical-align: text-top;
|
||||
fill: currentColor;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.navbar-form {
|
||||
padding-bottom: 1px;
|
||||
}
|
||||
|
||||
.navbar-form .form-control {
|
||||
background-color: gray;
|
||||
color: #fff;
|
||||
border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
border: 0;
|
||||
-webkit-box-shadow: 1px 1px 0 0 rgba(255, 255, 255, .41), inset 1px 1px 3px 0 rgba(0, 0, 0, .10);
|
||||
-moz-box-shadow: 1px 1px 0 0 rgba(255, 255, 255, .41), inset 1px 1px 3px 0 rgba(0, 0, 0, .10);
|
||||
box-shadow: 1px 1px 0 0 rgba(255, 255, 255, .41), inset 1px 1px 3px 0 rgba(0, 0, 0, .10);
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.container {
|
||||
max-width: 750px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 992px) {
|
||||
body {
|
||||
font-size: 12px;
|
||||
}
|
||||
.container {
|
||||
max-width: 970px;
|
||||
}
|
||||
.octicon {
|
||||
height: 24px;
|
||||
}
|
||||
.navbar-form .form-control {
|
||||
width: 230px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
body {
|
||||
font-size: 14px;
|
||||
}
|
||||
.container {
|
||||
max-width: 1170px;
|
||||
}
|
||||
.octicon {
|
||||
height: 32px;
|
||||
}
|
||||
.navbar-form .form-control {
|
||||
width: 360px;
|
||||
}
|
||||
a:hover {
|
||||
color: #00854d;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#header {
|
||||
@ -91,121 +37,136 @@ h3 {
|
||||
margin: 0;
|
||||
padding-bottom: 0;
|
||||
padding-top: 0;
|
||||
background-color: #212121;
|
||||
background-color: white;
|
||||
border: 0;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.bg-trezor {
|
||||
background-color: #212121!important;
|
||||
padding-top: 3px;
|
||||
padding-bottom: 2px;
|
||||
z-index: 2;
|
||||
#header .navbar {
|
||||
--bs-navbar-padding-y: 0.7rem;
|
||||
}
|
||||
|
||||
.bg-trezor .navbar-brand {
|
||||
color: rgba(255, 255, 255);
|
||||
#header .form-control-lg {
|
||||
font-size: 1rem;
|
||||
padding: 0.75rem 1rem;
|
||||
}
|
||||
|
||||
#header .container {
|
||||
min-height: 50px;
|
||||
}
|
||||
|
||||
.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;
|
||||
font-size: 19px;
|
||||
fill: #FFFFFF;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.navbar {
|
||||
font-size: 14px;
|
||||
}
|
||||
.bg-trezor .navbar-brand {
|
||||
font-weight: normal;
|
||||
font-size: 14px;
|
||||
}
|
||||
.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: 75px 0;
|
||||
margin: 0 auto -42px;
|
||||
padding: 112px 0 75px 0;
|
||||
margin: 0 auto -56px;
|
||||
}
|
||||
|
||||
#footer {
|
||||
background-color: #212121;
|
||||
color: #fff;
|
||||
height: 42px;
|
||||
background-color: black;
|
||||
color: #757575;
|
||||
height: 56px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.alert-data {
|
||||
color: #383d41;
|
||||
background-color: #f4f4f4;
|
||||
border-color: #d6d8db;
|
||||
padding: 15px;
|
||||
.navbar-form {
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
.line-top {
|
||||
border-top: 1px solid #EAEAEA;
|
||||
padding: 10px 0 0;
|
||||
.navbar-form button {
|
||||
margin-left: -50px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.line-mid {
|
||||
padding: 15px;
|
||||
.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");
|
||||
}
|
||||
|
||||
.line-bot {
|
||||
border-bottom: 2px solid #EAEAEA;
|
||||
padding: 0 0 15px;
|
||||
}
|
||||
|
||||
.txvalues {
|
||||
display: inline-block;
|
||||
padding: .7em 2em;
|
||||
font-size: 13px;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
vertical-align: baseline;
|
||||
border-radius: .25em;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.txvalues:not(:last-child) {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.txvalues-default {
|
||||
background-color: #EBEBEB;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.txvalues-success {
|
||||
background-color: dimgray;
|
||||
}
|
||||
|
||||
.txvalues-primary {
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
.txvalues-danger {
|
||||
background-color: #AC0015;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.tx-own {
|
||||
background-color: #fbf8f0;
|
||||
}
|
||||
|
||||
.tx-amt {
|
||||
float: right!important;
|
||||
}
|
||||
|
||||
.tx-in .tx-own .tx-amt {
|
||||
color: #dc3545!important;
|
||||
}
|
||||
|
||||
.tx-out .tx-own .tx-amt {
|
||||
color: #28a745!important;
|
||||
}
|
||||
|
||||
.tx-addr {
|
||||
float: left!important;
|
||||
.navbar-form ::placeholder {
|
||||
color: #e2e2e2;
|
||||
}
|
||||
|
||||
.ellipsis {
|
||||
@ -214,97 +175,359 @@ h3 {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.data-div {
|
||||
margin: 20px 0 30px 0;
|
||||
}
|
||||
|
||||
.data-div .col-md-10 {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.data-table {
|
||||
table-layout: fixed;
|
||||
border-radius: .25rem;
|
||||
background: white;
|
||||
overflow-wrap: break-word;
|
||||
margin-left: 8px;
|
||||
margin-top: 2rem;
|
||||
margin-bottom: 2rem;
|
||||
width: calc(100% - 16px);
|
||||
}
|
||||
|
||||
.data-table td, .data-table th {
|
||||
padding: .4rem;
|
||||
.data-table thead {
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.data-table span.ellipsis {
|
||||
max-width: 100%;
|
||||
.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);
|
||||
}
|
||||
|
||||
.data {
|
||||
font-weight: bold;
|
||||
.table.data-table>thead>*>* {
|
||||
padding-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
table.data-table table.data-table th {
|
||||
border-top: 0;
|
||||
.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;
|
||||
}
|
||||
|
||||
.alert .data-table {
|
||||
margin: 0;
|
||||
.data-table tbody {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 0 0 8px white;
|
||||
}
|
||||
|
||||
::-webkit-input-placeholder {
|
||||
color: #CCC!important;
|
||||
font-style: italic;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
::-moz-placeholder {
|
||||
color: #CCC!important;
|
||||
font-style: italic;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.h-container ul, .h-container h3 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.h-container h5 {
|
||||
margin-top: 6px;
|
||||
.data-table h3,
|
||||
.data-table h6 {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.page-link {
|
||||
color: #428bca;
|
||||
.data-table h3 {
|
||||
color: black;
|
||||
}
|
||||
|
||||
.page-text {
|
||||
.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: " ";
|
||||
}
|
||||
|
||||
.nc:before {
|
||||
content: ",";
|
||||
}
|
||||
|
||||
.trezor-logo {
|
||||
width: 128px;
|
||||
height: 32px;
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
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");
|
||||
}
|
||||
|
||||
.copyable::before,
|
||||
.copied::before {
|
||||
width: 18px;
|
||||
height: 16px;
|
||||
margin: 3px -18px;
|
||||
content: "";
|
||||
position: absolute;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.copyable::before {
|
||||
display: none;
|
||||
cursor: copy;
|
||||
background-image: url("data:image/svg+xml,%3Csvg width='18' height='16' viewBox='0 0 18 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");
|
||||
}
|
||||
|
||||
.copyable:hover::before {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.copied::before {
|
||||
transition: all 0.4s ease;
|
||||
transform: scale(1.2);
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='16' viewBox='-30 -30 330 330'%3E%3Cpath d='M 30,180 90,240 240,30' style='stroke:%2300854D; stroke-width:32; fill:none'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.h-data {
|
||||
letter-spacing: 0.12em;
|
||||
font-weight: normal !important;
|
||||
}
|
||||
|
||||
.tx-detail {
|
||||
background: #f6f6f6;
|
||||
color: #757575;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 0 0 10px white;
|
||||
width: calc(100% - 20px);
|
||||
margin-left: 10px;
|
||||
margin-top: 3rem;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.tx-detail:first-child {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.tx-detail:last-child {
|
||||
margin-bottom: 3rem;
|
||||
}
|
||||
|
||||
.tx-detail span.ellipsis,
|
||||
.tx-detail a.ellipsis {
|
||||
display: block;
|
||||
padding: .5rem .3rem;
|
||||
line-height: 1.25;
|
||||
float: left;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.page-link {
|
||||
color: #428bca;
|
||||
.tx-detail>.head {
|
||||
padding: 1.5rem;
|
||||
border-radius: 10px 10px 0 0;
|
||||
--bs-gutter-x: 0;
|
||||
}
|
||||
|
||||
.page-item.active .page-link {
|
||||
background-color: #428bca;
|
||||
.tx-detail .txid {
|
||||
font-size: 106%;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
#txSpecific {
|
||||
margin: 0;
|
||||
.tx-detail>.body {
|
||||
padding: 0 1.5rem;
|
||||
--bs-gutter-x: 0;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
.string {
|
||||
color: darkgreen;
|
||||
.tx-detail>.footer {
|
||||
padding: 1.5rem;
|
||||
--bs-gutter-x: 0;
|
||||
}
|
||||
|
||||
.number, .boolean {
|
||||
color: darkred;
|
||||
.tx-in .col-12,
|
||||
.tx-out .col-12 {
|
||||
background-color: white;
|
||||
padding: 1.2rem 1.3rem;
|
||||
border-bottom: 1px solid #f6f6f6;
|
||||
}
|
||||
|
||||
.null {
|
||||
.tx-in .col-12:last-child,
|
||||
.tx-out .co-12l:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.tx-own {
|
||||
background-color: #fff9e3 !important;
|
||||
}
|
||||
|
||||
.tx-amt {
|
||||
float: right !important;
|
||||
}
|
||||
|
||||
.spent {
|
||||
color: #dc3545 !important;
|
||||
}
|
||||
|
||||
.unspent {
|
||||
color: #28a745 !important;
|
||||
}
|
||||
|
||||
.outpoint {
|
||||
color: #757575 !important;
|
||||
}
|
||||
|
||||
.spent,
|
||||
.unspent,
|
||||
.outpoint {
|
||||
display: inline-block;
|
||||
text-align: right;
|
||||
min-width: 18px;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
.octicon {
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
margin-left: -12px;
|
||||
margin-top: 19px;
|
||||
position: absolute;
|
||||
background-size: cover;
|
||||
background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M9 4.5L16.5 12L9 19.5' stroke='%23AFAFAF' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E%0A");
|
||||
}
|
||||
|
||||
.txvalue {
|
||||
color: var(--bs-body-color);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.tx-amt .amt:hover,
|
||||
.tx-amt.amt:hover {
|
||||
color: var(--bs-body-color);
|
||||
}
|
||||
|
||||
.prim-amt {
|
||||
display: initial;
|
||||
}
|
||||
|
||||
.sec-amt {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.csec-amt {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
--bs-tooltip-opacity: 1;
|
||||
--bs-tooltip-max-width: 320px;
|
||||
--bs-tooltip-bg: #fff;
|
||||
--bs-tooltip-color: var(--bs-body-color);
|
||||
--bs-tooltip-padding-x: 1rem;
|
||||
--bs-tooltip-padding-y: 0.8rem;
|
||||
filter: drop-shadow(0px 24px 64px rgba(22, 27, 45, 0.25));
|
||||
}
|
||||
|
||||
.amt-tooltip {
|
||||
text-align: start;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.amt-tooltip .prim-amt,
|
||||
.amt-tooltip .sec-amt,
|
||||
.amt-tooltip .csec-amt {
|
||||
display: initial;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.amt-dec {
|
||||
font-size: 97%;
|
||||
}
|
||||
|
||||
.amt-tooltip .amt-time {
|
||||
padding-right: 3rem;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.unconfirmed {
|
||||
color: white;
|
||||
background-color: #c51e13;
|
||||
padding: 0.7rem 1.2rem;
|
||||
border-radius: 1.4rem;
|
||||
}
|
||||
|
||||
.json {
|
||||
word-wrap: break-word;
|
||||
font-size: smaller;
|
||||
background: #002b31;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
#raw {
|
||||
padding: 1.5rem 2rem;
|
||||
color: #ffffff;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
#raw .string {
|
||||
color: #2bca87;
|
||||
}
|
||||
|
||||
#raw .number,
|
||||
#raw .boolean {
|
||||
color: #efc941;
|
||||
}
|
||||
|
||||
#raw .null {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.key {
|
||||
color: #333;
|
||||
@media (max-width: 768px) {
|
||||
body {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.octicon {
|
||||
scale: 60% !important;
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
--bs-btn-font-size: 0.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 991px) {
|
||||
#header .container {
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
.trezor-logo {
|
||||
top: 10px;
|
||||
}
|
||||
|
||||
.octicon {
|
||||
scale: 80%;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
}
|
||||
@ -1,483 +0,0 @@
|
||||
@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;
|
||||
}
|
||||
|
||||
#header .container {
|
||||
min-height: 50px;
|
||||
}
|
||||
|
||||
.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: 16px;
|
||||
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");
|
||||
}
|
||||
|
||||
.copyable::before,
|
||||
.copied::before {
|
||||
width: 18px;
|
||||
height: 16px;
|
||||
margin: 3px -18px;
|
||||
content: "";
|
||||
position: absolute;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.copyable::before {
|
||||
display: none;
|
||||
cursor: pointer;
|
||||
background-image: url("data:image/svg+xml,%3Csvg width='18' height='16' viewBox='0 0 18 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");
|
||||
}
|
||||
|
||||
.copyable:hover::before {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.copied::before {
|
||||
transition: all 0.4s ease;
|
||||
transform: scale(1.2);
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='16' viewBox='-30 -30 330 330'%3E%3Cpath d='M 30,180 90,240 240,30' style='stroke:%2300854D; stroke-width:32; fill:none'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.h-data {
|
||||
letter-spacing: 0.12em;
|
||||
font-weight: normal !important;
|
||||
}
|
||||
|
||||
.tx-detail {
|
||||
background: #F6F6F6;
|
||||
color: #757575;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 0 0 10px white;
|
||||
width: calc(100% - 20px);
|
||||
margin-left: 10px;
|
||||
margin-top: 3rem;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.tx-detail:first-child {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.tx-detail:last-child {
|
||||
margin-bottom: 3rem;
|
||||
}
|
||||
|
||||
.tx-detail span.ellipsis,
|
||||
.tx-detail a.ellipsis {
|
||||
display: block;
|
||||
float: left;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.tx-detail>.head {
|
||||
padding: 1.5rem;
|
||||
border-radius: 10px 10px 0 0;
|
||||
--bs-gutter-x: 0;
|
||||
}
|
||||
|
||||
.tx-detail .txid {
|
||||
font-size: 106%;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
.tx-detail>.body {
|
||||
padding: 0 1.5rem;
|
||||
--bs-gutter-x: 0;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
.tx-detail>.footer {
|
||||
padding: 1.5rem;
|
||||
--bs-gutter-x: 0;
|
||||
}
|
||||
|
||||
.tx-in .col-12,
|
||||
.tx-out .col-12 {
|
||||
background-color: white;
|
||||
padding: 1.2rem 1.3rem;
|
||||
border-bottom: 1px solid #F6F6F6;
|
||||
}
|
||||
|
||||
.tx-in .col-12:last-child,
|
||||
.tx-out .co-12l:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.tx-own {
|
||||
background-color: #FFF9E3 !important;
|
||||
}
|
||||
|
||||
.tx-amt {
|
||||
float: right !important;
|
||||
}
|
||||
|
||||
.tx-in .tx-own .tx-amt,
|
||||
.spent {
|
||||
color: #dc3545 !important;
|
||||
}
|
||||
|
||||
.tx-out .tx-own .tx-amt,
|
||||
.unspent {
|
||||
color: #28a745 !important;
|
||||
}
|
||||
|
||||
.outpoint {
|
||||
color: #757575 !important;
|
||||
}
|
||||
|
||||
.spent,
|
||||
.unspent,
|
||||
.outpoint {
|
||||
display: inline-block;
|
||||
text-align: right;
|
||||
min-width: 18px;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
.octicon {
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
margin-left: -12px;
|
||||
margin-top: 19px;
|
||||
position: absolute;
|
||||
background-size: cover;
|
||||
background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M9 4.5L16.5 12L9 19.5' stroke='%23AFAFAF' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E%0A");
|
||||
}
|
||||
|
||||
.txvalue {
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.unconfirmed {
|
||||
color: white;
|
||||
background-color: #C51E13;
|
||||
padding: 0.7rem 1.2rem;
|
||||
border-radius: 1.4rem;
|
||||
}
|
||||
|
||||
.json {
|
||||
word-wrap: break-word;
|
||||
font-size: smaller;
|
||||
background: #002B31;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
#raw {
|
||||
padding: 1.5rem 2rem;
|
||||
color: #FFFFFF;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
#raw .string {
|
||||
color: #2BCA87;
|
||||
}
|
||||
|
||||
#raw .number,
|
||||
#raw .boolean {
|
||||
color: #EFC941;
|
||||
}
|
||||
|
||||
#raw .null {
|
||||
color: red;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
body {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.octicon {
|
||||
scale: 60% !important;
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
--bs-btn-font-size: 0.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 991px) {
|
||||
#header .container {
|
||||
min-height: 40px
|
||||
}
|
||||
|
||||
.trezor-logo {
|
||||
top: 10px;
|
||||
}
|
||||
|
||||
.octicon {
|
||||
scale: 80%;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
}
|
||||
116
static/js/main.js
Normal file
116
static/js/main.js
Normal file
@ -0,0 +1,116 @@
|
||||
function syntaxHighlight(json) {
|
||||
json = JSON.stringify(json, undefined, 2);
|
||||
json = json
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">");
|
||||
return json.replace(
|
||||
/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g,
|
||||
(match) => {
|
||||
let cls = "number";
|
||||
if (/^"/.test(match)) {
|
||||
if (/:$/.test(match)) {
|
||||
cls = "key";
|
||||
} else {
|
||||
cls = "string";
|
||||
}
|
||||
} else if (/true|false/.test(match)) {
|
||||
cls = "boolean";
|
||||
} else if (/null/.test(match)) {
|
||||
cls = "null";
|
||||
}
|
||||
return `<span class="${cls}">${match}</span>`;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function getCoinCookie() {
|
||||
return document.cookie
|
||||
.split("; ")
|
||||
.find((row) => row.startsWith("secondary_coin="))
|
||||
?.split("=");
|
||||
}
|
||||
|
||||
function changeCSSStyle(selector, cssProp, cssVal) {
|
||||
const mIndex = 1;
|
||||
const cssRules = document.all ? "rules" : "cssRules";
|
||||
for (
|
||||
i = 0, len = document.styleSheets[mIndex][cssRules].length;
|
||||
i < len;
|
||||
i++
|
||||
) {
|
||||
if (document.styleSheets[mIndex][cssRules][i].selectorText === selector) {
|
||||
document.styleSheets[mIndex][cssRules][i].style[cssProp] = cssVal;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function amountTooltip() {
|
||||
const prim = this.querySelector(".prim-amt");
|
||||
const sec = this.querySelector(".sec-amt");
|
||||
const csec = this.querySelector(".csec-amt");
|
||||
let s = `${prim.outerHTML}<br>`;
|
||||
if (sec) {
|
||||
let t = sec.getAttribute("tm");
|
||||
if (!t) {
|
||||
t = "now";
|
||||
}
|
||||
s += `<span class="amt-time">${t}</span>${sec.outerHTML}<br>`;
|
||||
}
|
||||
if (csec) {
|
||||
s += `<span class="amt-time">now</span>${csec.outerHTML}`;
|
||||
}
|
||||
return `<span class="amt-tooltip">${s}</span>`;
|
||||
}
|
||||
|
||||
window.addEventListener("DOMContentLoaded", () => {
|
||||
const a = getCoinCookie();
|
||||
if (a?.length === 3) {
|
||||
if (a[2] === "true") {
|
||||
changeCSSStyle(".prim-amt", "display", "none");
|
||||
changeCSSStyle(".sec-amt", "display", "initial");
|
||||
}
|
||||
document
|
||||
.querySelectorAll(".amt")
|
||||
.forEach(
|
||||
(e) => new bootstrap.Tooltip(e, { title: amountTooltip, html: true })
|
||||
);
|
||||
}
|
||||
|
||||
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", (e) => {
|
||||
const a = getCoinCookie();
|
||||
const sc = e.target.id === "secondary-coin";
|
||||
if (a?.length === 3 && (a[2] === "true") !== sc) {
|
||||
document.cookie = `${a[0]}=${a[1]}=${sc}; Path=/`;
|
||||
changeCSSStyle(".prim-amt", "display", sc ? "none" : "initial");
|
||||
changeCSSStyle(".sec-amt", "display", sc ? "initial" : "none");
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
document.querySelectorAll(".copyable").forEach((e) =>
|
||||
e.addEventListener("click", (e) => {
|
||||
if (e.clientX < e.target.getBoundingClientRect().x) {
|
||||
let t = e.target.getAttribute("cc");
|
||||
if (!t) t = e.target.innerText;
|
||||
navigator.clipboard.writeText(t);
|
||||
e.target.className = e.target.className.replace("copyable", "copied");
|
||||
setTimeout(
|
||||
() =>
|
||||
(e.target.className = e.target.className.replace(
|
||||
"copied",
|
||||
"copyable"
|
||||
)),
|
||||
1000
|
||||
);
|
||||
e.preventDefault();
|
||||
}
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -5,47 +5,12 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0,shrink-to-fit=no">
|
||||
<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">
|
||||
<link rel="stylesheet" href="/static/css/main.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>
|
||||
<script src="/static/js/main.js"></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">
|
||||
function syntaxHighlight(json) {
|
||||
json = JSON.stringify(json, undefined, 2);
|
||||
json = json.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
||||
return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
|
||||
var cls = 'number';
|
||||
if (/^"/.test(match)) {
|
||||
if (/:$/.test(match)) {
|
||||
cls = 'key';
|
||||
} else {
|
||||
cls = 'string';
|
||||
}
|
||||
} else if (/true|false/.test(match)) {
|
||||
cls = 'boolean';
|
||||
} else if (/null/.test(match)) {
|
||||
cls = 'null';
|
||||
}
|
||||
return '<span class="' + cls + '">' + match + '</span>';
|
||||
});
|
||||
}
|
||||
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',e=>console.log("clicked",e.target.id)));
|
||||
document.querySelectorAll('.copyable').forEach(e=>e.addEventListener('click',e=>{
|
||||
console.log("clicked",e.clientX<e.target.getBoundingClientRect().x,e.offsetX, e.clientX, e.target.getBoundingClientRect(), e);
|
||||
if(e.clientX<e.target.getBoundingClientRect().x){
|
||||
let t=e.target.getAttribute("copy-content");
|
||||
if(!t) t=e.target.innerText;
|
||||
navigator.clipboard.writeText(t);
|
||||
e.target.className=e.target.className.replace('copyable','copied');
|
||||
setTimeout(()=>e.target.className=e.target.className.replace('copied','copyable'),1000);
|
||||
e.preventDefault();
|
||||
}
|
||||
}));
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -77,12 +42,14 @@
|
||||
</button>
|
||||
</form>
|
||||
</span>
|
||||
{{if .SecondaryCoin}}
|
||||
<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>
|
||||
<input type="radio" class="btn-check" name="btnradio" id="primary-coin" autocomplete="off"{{if not .UseSecondaryCoin}} checked{{end}}>
|
||||
<label class="btn" for="primary-coin">{{.CoinShortcut}}</label>
|
||||
<input type="radio" class="btn-check" name="btnradio" id="secondary-coin" autocomplete="off"{{if .UseSecondaryCoin}} checked{{end}}>
|
||||
<label class="btn" for="secondary-coin">{{.SecondaryCoin}}</label>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
{{define "txdetail"}}{{$cs := .CoinShortcut}}{{$addr := .AddrStr}}{{$tx := .Tx}}{{$data := .}}
|
||||
{{define "txdetail"}}{{$addr := .AddrStr}}{{$tx := .Tx}}{{$data := .}}
|
||||
<div class="tx-detail">
|
||||
<div class="row head">
|
||||
<div class="col-xs-7 col-md-8">
|
||||
@ -22,7 +22,7 @@
|
||||
{{if $vin.Txid}}
|
||||
<a class="outpoint" href="/tx/{{$vin.Txid}}" tt="Outpoint {{$vin.Txid}},{{$vin.Vout}}">←</a>
|
||||
{{end}}
|
||||
{{if $vin.Addresses}}<span class="tx-amt copyable">{{formatAmount $vin.ValueSat}} {{$cs}}</span>{{end}}
|
||||
{{if $vin.Addresses}}{{amount $vin.ValueSat $data "tx-amt copyable"}}{{end}}
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="col-12">No Inputs</div>
|
||||
@ -42,7 +42,7 @@
|
||||
<span class="tx-addr">Unparsed address</span>
|
||||
{{- end -}}
|
||||
<span class="tx-amt">
|
||||
<span class="copyable">{{formatAmount $vout.ValueSat}} {{$cs}}</span>{{if $vout.Spent}}<a class="spent" href="{{if $vout.SpentTxID}}/tx/{{$vout.SpentTxID}}{{else}}/spending/{{$tx.Txid}}/{{$vout.N}}{{end}}" tt="Spent">→</a>{{else}}<span class="unspent" tt="Unspent">×</span>
|
||||
{{amount $vout.ValueSat $data "copyable"}}{{if $vout.Spent}}<a class="spent" href="{{if $vout.SpentTxID}}/tx/{{$vout.SpentTxID}}{{else}}/spending/{{$tx.Txid}}/{{$vout.N}}{{end}}" tt="Spent">→</a>{{else}}<span class="unspent" tt="Unspent">×</span>
|
||||
{{end}}
|
||||
</span>
|
||||
</td>
|
||||
@ -56,18 +56,18 @@
|
||||
<div class="row footer">
|
||||
<div class="col-sm-12 col-md-4">
|
||||
{{- if $tx.FeesSat -}}
|
||||
Fee: <span class="txvalue">{{formatAmount $tx.FeesSat}} {{$cs}}</span>
|
||||
Fee {{amount $tx.FeesSat $data "txvalue copyable ms-3"}}
|
||||
{{- end -}}
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-8 text-end">
|
||||
<span class="me-4">
|
||||
{{- if $tx.Confirmations -}}
|
||||
<span class="txvalue">{{formatUint32 $tx.Confirmations}}</span> Confirmations
|
||||
<span class="txvalue">{{formatUint32 $tx.Confirmations}}</span> confirmations
|
||||
{{- else -}}
|
||||
<span class="txvalue unconfirmed">Unconfirmed Transaction!</span>
|
||||
{{- end -}}
|
||||
</span>
|
||||
<span class="txvalue">{{formatAmount $tx.ValueOutSat}} {{$cs}}</span>
|
||||
{{amount $tx.ValueOutSat $data "txvalue copyable"}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user