diff --git a/api/worker.go b/api/worker.go index 405e57a9..7320134d 100644 --- a/api/worker.go +++ b/api/worker.go @@ -182,7 +182,9 @@ func (w *Worker) GetTransaction(txid string, bestheight uint32, spendingTxs bool Vin: vins, Vout: vouts, } - glog.Info("GetTransaction ", txid, " finished in ", time.Since(start)) + if spendingTxs { + glog.Info("GetTransaction ", txid, " finished in ", time.Since(start)) + } return r, nil } @@ -297,6 +299,7 @@ func (w *Worker) txFromTxAddress(txid string, ta *db.TxAddresses, bi *db.BlockIn // GetAddress computes address value and gets transactions for given address func (w *Worker) GetAddress(address string, page int, txsOnPage int, onlyTxids bool) (*Address, error) { start := time.Now() + page-- if page < 0 { page = 0 } @@ -340,7 +343,10 @@ func (w *Worker) GetAddress(address string, page int, txsOnPage int, onlyTxids b } // paging from := page * txsOnPage - totalPages := len(txc) / txsOnPage + totalPages := (len(txc) - 1) / txsOnPage + if totalPages < 0 { + totalPages = 0 + } if from >= len(txc) { page = totalPages - 1 if page < 0 { @@ -370,7 +376,7 @@ func (w *Worker) GetAddress(address string, page int, txsOnPage int, onlyTxids b } else { uBalSat.Add(&uBalSat, tx.getAddrVoutValue(addrDesc)) uBalSat.Sub(&uBalSat, tx.getAddrVinValue(addrDesc)) - if page > 0 { + if page == 0 { if onlyTxids { txids[txi] = tx.Txid } else { @@ -408,7 +414,9 @@ func (w *Worker) GetAddress(address string, page int, txsOnPage int, onlyTxids b } txi++ } - if !onlyTxids { + if onlyTxids { + txids = txids[:txi] + } else { txs = txs[:txi] } r := &Address{ @@ -421,8 +429,8 @@ func (w *Worker) GetAddress(address string, page int, txsOnPage int, onlyTxids b UnconfirmedTxApperances: len(txm), Transactions: txs, Txids: txids, - Page: page, - TotalPages: totalPages, + Page: page + 1, + TotalPages: totalPages + 1, TxsOnPage: txsOnPage, } glog.Info("GetAddress ", address, " finished in ", time.Since(start)) diff --git a/server/public.go b/server/public.go index 9b9800b7..7224f61a 100644 --- a/server/public.go +++ b/server/public.go @@ -20,7 +20,7 @@ import ( ) const blockbookAbout = "Blockbook - blockchain indexer for TREZOR wallet https://trezor.io/. Do not use for any other purpose." -const txsOnPage = 30 +const txsOnPage = 25 const txsInAPI = 1000 // PublicServer is a handle to public http server @@ -272,6 +272,8 @@ const ( errorTpl = tpl(iota) txTpl addressTpl + + tplCount ) type TemplateData struct { @@ -281,6 +283,10 @@ type TemplateData struct { AddrStr string Tx *api.Tx Error *api.ApiError + Page int + PrevPage int + NextPage int + PagingRange []int } func parseTemplates() []*template.Template { @@ -290,10 +296,10 @@ func parseTemplates() []*template.Template { "setTxToTemplateData": setTxToTemplateData, "stringInSlice": stringInSlice, } - t := make([]*template.Template, 3) - t[errorTpl] = template.Must(template.New("tx").Funcs(templateFuncMap).ParseFiles("./static/templates/error.html", "./static/templates/base.html")) + t := make([]*template.Template, tplCount) + t[errorTpl] = template.Must(template.New("error").Funcs(templateFuncMap).ParseFiles("./static/templates/error.html", "./static/templates/base.html")) t[txTpl] = template.Must(template.New("tx").Funcs(templateFuncMap).ParseFiles("./static/templates/tx.html", "./static/templates/txdetail.html", "./static/templates/base.html")) - t[addressTpl] = template.Must(template.New("address").Funcs(templateFuncMap).ParseFiles("./static/templates/address.html", "./static/templates/txdetail.html", "./static/templates/base.html")) + t[addressTpl] = template.Must(template.New("address").Funcs(templateFuncMap).ParseFiles("./static/templates/address.html", "./static/templates/txdetail.html", "./static/templates/paging.html", "./static/templates/base.html")) return t } @@ -346,9 +352,65 @@ func (s *PublicServer) explorerAddress(r *http.Request) (tpl, *TemplateData, err data := s.newTemplateData() data.AddrStr = address.AddrStr data.Address = address + data.Page = address.Page + data.PagingRange, data.PrevPage, data.NextPage = getPagingRange(address.Page, address.TotalPages) return addressTpl, data, nil } +func getPagingRange(page int, total int) ([]int, int, int) { + if total < 2 { + return nil, 0, 0 + } + pp, np := page-1, page+1 + if np > total { + np = total + } + if pp < 1 { + pp = 1 + } + r := make([]int, 0, 8) + if total < 6 { + for i := 1; i <= total; i++ { + r = append(r, i) + } + } else { + r = append(r, 1) + if page > 3 { + r = append(r, 0) + } + if pp == 1 { + if page == 1 { + r = append(r, np) + r = append(r, np+1) + r = append(r, np+2) + } else { + r = append(r, page) + r = append(r, np) + r = append(r, np+1) + } + } else if np == total { + if page == total { + r = append(r, pp-2) + r = append(r, pp-1) + r = append(r, pp) + } else { + r = append(r, pp-1) + r = append(r, pp) + r = append(r, page) + } + } else { + r = append(r, pp) + r = append(r, page) + r = append(r, np) + } + if page <= total-3 { + r = append(r, 0) + } + r = append(r, total) + } + return r, pp, np +} + type resAboutBlockbookPublic struct { Coin string `json:"coin"` Host string `json:"host"` diff --git a/static/css/main.css b/static/css/main.css index e2905211..f2ad1378 100644 --- a/static/css/main.css +++ b/static/css/main.css @@ -192,4 +192,38 @@ h3 { .navbar-nav .nav-link { padding-right: 0; padding-left: .25rem; +} + +.h-container { + display: -webkit-box; + display: -ms-flexbox; + -ms-flex-wrap: wrap; + flex-wrap: wrap; +} + +.h-container-6 { + width: 50%; + margin: 0; +} + +.h-container ul { + margin: 0; +} + +.page-link { + color: #428bca; +} + +.page-text { + display: block; + padding: .5rem .3rem; + line-height: 1.25; +} + +.page-link { + color: #428bca; +} + +.page-item.active .page-link { + background-color: #428bca; } \ No newline at end of file diff --git a/static/templates/address.html b/static/templates/address.html index 3a457703..b9100cb7 100644 --- a/static/templates/address.html +++ b/static/templates/address.html @@ -28,7 +28,7 @@ -{{if $addr.UnconfirmedTxApperances}} +{{- if $addr.UnconfirmedTxApperances -}}