diff --git a/internal/handler/views/remote_nodes.templ b/internal/handler/views/remote_nodes.templ
index e93e1cd..9461056 100644
--- a/internal/handler/views/remote_nodes.templ
+++ b/internal/handler/views/remote_nodes.templ
@@ -329,10 +329,10 @@ templ TableLogs(hxPath string, data monero.FetchLogs, q monero.QueryLogs, p pagi
{ fmt.Sprintf("%d", row.ProberID) } |
if row.Status == 1 {
OK |
- { fmt.Sprintf("%d", row.Height) } |
+ { fmt.Sprintf("%d", row.Height) } |
{ time.Unix(row.AdjustedTime, 0).UTC().Format("Jan 2, 2006 15:04 MST") } |
- { fmt.Sprintf("%d", row.DatabaseSize) } |
- { fmt.Sprintf("%d", row.Difficulty) } |
+ { utils.FormatBytes(row.DatabaseSize, 0) } |
+ { utils.FormatHashes(float64(row.Difficulty)) } |
{ fmt.Sprintf("%d", row.EstimateFee) } |
} else {
ERR |
diff --git a/internal/handler/views/remote_nodes_templ.go b/internal/handler/views/remote_nodes_templ.go
index 4bba9a3..ec048b8 100644
--- a/internal/handler/views/remote_nodes_templ.go
+++ b/internal/handler/views/remote_nodes_templ.go
@@ -865,14 +865,14 @@ func TableLogs(hxPath string, data monero.FetchLogs, q monero.QueryLogs, p pagin
return templ_7745c5c3_Err
}
if row.Status == 1 {
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("OK | ")
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" | OK | ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var35 string
templ_7745c5c3_Var35, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", row.Height))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/handler/views/remote_nodes.templ`, Line: 332, Col: 43}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/handler/views/remote_nodes.templ`, Line: 332, Col: 62}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var35))
if templ_7745c5c3_Err != nil {
@@ -896,9 +896,9 @@ func TableLogs(hxPath string, data monero.FetchLogs, q monero.QueryLogs, p pagin
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var37 string
- templ_7745c5c3_Var37, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", row.DatabaseSize))
+ templ_7745c5c3_Var37, templ_7745c5c3_Err = templ.JoinStringErrs(utils.FormatBytes(row.DatabaseSize, 0))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/handler/views/remote_nodes.templ`, Line: 334, Col: 49}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/handler/views/remote_nodes.templ`, Line: 334, Col: 52}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var37))
if templ_7745c5c3_Err != nil {
@@ -909,9 +909,9 @@ func TableLogs(hxPath string, data monero.FetchLogs, q monero.QueryLogs, p pagin
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var38 string
- templ_7745c5c3_Var38, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", row.Difficulty))
+ templ_7745c5c3_Var38, templ_7745c5c3_Err = templ.JoinStringErrs(utils.FormatHashes(float64(row.Difficulty)))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/handler/views/remote_nodes.templ`, Line: 335, Col: 47}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/handler/views/remote_nodes.templ`, Line: 335, Col: 57}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var38))
if templ_7745c5c3_Err != nil {
diff --git a/utils/human_readable.go b/utils/human_readable.go
index 2c739a3..10c1898 100644
--- a/utils/human_readable.go
+++ b/utils/human_readable.go
@@ -2,15 +2,11 @@ package utils
import (
"fmt"
+ "math"
"strconv"
"time"
)
-// Convert the float to a string, trimming unnecessary zeros
-func FormatFloat(f float64) string {
- return strconv.FormatFloat(f, 'f', -1, 64)
-}
-
// TimeSince converts an int64 timestamp to a relative time string
func TimeSince(timestamp int64) string {
var duration time.Duration
@@ -45,3 +41,68 @@ func TimeSince(timestamp int64) string {
return fmt.Sprintf("%d months %s", months, suffix)
}
}
+
+// Convert the float to a string, trimming unnecessary zeros
+func FormatFloat(f float64) string {
+ return strconv.FormatFloat(f, 'f', -1, 64)
+}
+
+// Formats bytes as a human-readable string with the specified number of decimal places.
+func FormatBytes(bytes, decimals int) string {
+ if bytes == 0 {
+ return "0 Bytes"
+ }
+
+ const k float64 = 1024
+ sizes := []string{"Bytes", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"}
+
+ i := int(math.Floor(math.Log(float64(bytes)) / math.Log(k)))
+ dm := decimals
+ if dm < 0 {
+ dm = 0
+ }
+
+ value := float64(bytes) / math.Pow(k, float64(i))
+ return fmt.Sprintf("%.*f %s", dm, value, sizes[i])
+}
+
+// Formats a hash value (h) into human readable format.
+//
+// This function was adapted from jtgrassie/monero-pool project.
+// Source: https://github.com/jtgrassie/monero-pool/blob/master/src/webui-embed.html
+//
+// Copyright (c) 2018, The Monero Project
+func FormatHashes(h float64) string {
+ switch {
+ case h < 1e-12:
+ return "0 H"
+ case h < 1e-9:
+ return fmt.Sprintf("%.0f pH", maxPrecision(h*1e12, 0))
+ case h < 1e-6:
+ return fmt.Sprintf("%.0f nH", maxPrecision(h*1e9, 0))
+ case h < 1e-3:
+ return fmt.Sprintf("%.0f μH", maxPrecision(h*1e6, 0))
+ case h < 1:
+ return fmt.Sprintf("%.0f mH", maxPrecision(h*1e3, 0))
+ case h < 1e3:
+ return fmt.Sprintf("%.0f H", h)
+ case h < 1e6:
+ return fmt.Sprintf("%.2f KH", maxPrecision(h*1e-3, 2))
+ case h < 1e9:
+ return fmt.Sprintf("%.2f MH", maxPrecision(h*1e-6, 2))
+ default:
+ return fmt.Sprintf("%.2f GH", maxPrecision(h*1e-9, 2))
+ }
+}
+
+// Returns a number with a maximum precision.
+//
+// This function was adapted from jtgrassie/monero-pool project.
+// Source: https://github.com/jtgrassie/monero-pool/blob/master/src/webui-embed.html
+//
+// Copyright (c) 2018, The Monero Project
+func maxPrecision(n float64, p int) float64 {
+ format := "%." + strconv.Itoa(p) + "f"
+ result, _ := strconv.ParseFloat(fmt.Sprintf(format, n), 64)
+ return result
+}
|