webapi: Footer update time relative not absolute.

Using a relative time rather than absolute requires far less effort for
a reader to understand, e.g. compare "25 Oct 2024 11:12:49 UTC" to "3
minutes ago".

As a nice side-effect this also fixes a minor privacy issue where using
the full absolute timestamp would expose the server timezone to the
public.
This commit is contained in:
jholdstock 2024-10-25 12:30:01 +01:00 committed by Jamie Holdstock
parent ddd7fd5bee
commit b0fb5469c0
4 changed files with 19 additions and 4 deletions

View File

@ -1,4 +1,4 @@
// Copyright (c) 2020-2023 The Decred developers
// Copyright (c) 2020-2024 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
@ -34,7 +34,7 @@ type cacheData struct {
// the first time.
Initialized bool
UpdateTime string
UpdateTime time.Time
PubKey string
DatabaseSize string
Voting int64
@ -118,7 +118,7 @@ func (c *cache) update() error {
defer c.mtx.Unlock()
c.data.Initialized = true
c.data.UpdateTime = dateTime(time.Now().Unix())
c.data.UpdateTime = time.Now()
c.data.DatabaseSize = humanize.Bytes(dbSize)
c.data.Voting = voting
c.data.Voted = voted

View File

@ -1,3 +1,7 @@
// Copyright (c) 2020-2024 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package webapi
import (
@ -9,6 +13,7 @@ import (
"github.com/decred/dcrd/dcrutil/v4"
"github.com/decred/slog"
"github.com/dustin/go-humanize"
)
func addressURL(blockExplorerURL string) func(string) string {
@ -29,10 +34,19 @@ func blockURL(blockExplorerURL string) func(int64) string {
}
}
// dateTime returns a human readable representation of the provided unix
// timestamp. It includes the local timezone of the server so use on public
// webpages is not recommended.
func dateTime(t int64) string {
return time.Unix(t, 0).Format("2 Jan 2006 15:04:05 MST")
}
// timeAgo compares the provided unix timestamp to the current time to return a
// string like "3 minutes ago".
func timeAgo(t time.Time) string {
return humanize.Time(t)
}
func stripWss(input string) string {
input = strings.ReplaceAll(input, "wss://", "")
input = strings.ReplaceAll(input, "/ws", "")

View File

@ -5,7 +5,7 @@
<footer class="row m-0">
<div class="col-md-8 col-12 d-flex justify-content-center align-items-center">
<p class="py-4 m-0">
<strong>Stats&nbsp;updated:</strong>&nbsp;{{ .WebApiCache.UpdateTime }}
<strong>Stats&nbsp;updated:</strong>&nbsp;{{ timeAgo .WebApiCache.UpdateTime }}
<br />
<strong>Support:</strong>&nbsp;<a href="mailto:{{ .WebApiCfg.SupportEmail }}" rel="noopener noreferrer">{{ .WebApiCfg.SupportEmail }}</a>
<br />

View File

@ -210,6 +210,7 @@ func (w *WebAPI) router(cookieSecret []byte, dcrd rpc.DcrdConnect, wallets rpc.W
"addressURL": addressURL(explorerURL),
"blockURL": blockURL(explorerURL),
"dateTime": dateTime,
"timeAgo": timeAgo,
"stripWss": stripWss,
"indentJSON": indentJSON(w.log),
"atomsToDCR": atomsToDCR,