From aec5cc4e3c508a4fda2d6b8f311be4ebd42aedca Mon Sep 17 00:00:00 2001 From: sneak Date: Thu, 22 May 2025 09:21:52 -0700 Subject: [PATCH] Replace client-side JS with server-side relative timestamps --- models.go | 26 ++++++++++---------- templates/index.html | 57 ++------------------------------------------ webserver.go | 52 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 67 deletions(-) diff --git a/models.go b/models.go index fdac7a8..c481a3d 100644 --- a/models.go +++ b/models.go @@ -5,18 +5,20 @@ import ( ) type Article struct { - Title string `json:"title"` - Description string `json:"description"` - Link string `json:"link"` - Published time.Time `json:"published"` // When we first saw the article - OriginalDate time.Time `json:"originalDate"` // Original publication date from the feed - Source string `json:"source"` - FirstSeen time.Time `json:"firstseen"` - Seen time.Time `json:"seen"` - Summary string `json:"summary"` - Importance int `json:"importance"` - ID string `json:"id"` - BroadcastTime time.Time `json:"broadcastTime,omitempty"` + Title string `json:"title"` + Description string `json:"description"` + Link string `json:"link"` + Published time.Time `json:"published"` // When we first saw the article + OriginalDate time.Time `json:"originalDate"` // Original publication date from the feed + Source string `json:"source"` + FirstSeen time.Time `json:"firstseen"` + Seen time.Time `json:"seen"` + Summary string `json:"summary"` + Importance int `json:"importance"` + ID string `json:"id"` + BroadcastTime time.Time `json:"broadcastTime,omitempty"` + RelativeTime string `json:"-"` // Relative time for FirstSeen (calculated field, not stored) + BroadcastRelativeTime string `json:"-"` // Relative time for BroadcastTime (calculated field, not stored) } type LogEntry struct { diff --git a/templates/index.html b/templates/index.html index 1c4698b..3d0a06b 100644 --- a/templates/index.html +++ b/templates/index.html @@ -235,7 +235,7 @@ {{.Source}} {{.Title}} {{.Summary}} - + {{.RelativeTime}} {{else}} @@ -263,7 +263,7 @@ {{range .History}} {{.ID}} - + {{.BroadcastRelativeTime}} {{.Importance}} {{.Source}} {{.Title}} @@ -316,58 +316,5 @@ - - \ No newline at end of file diff --git a/webserver.go b/webserver.go index 07e5019..6776da8 100644 --- a/webserver.go +++ b/webserver.go @@ -175,6 +175,9 @@ func getDashboardData() (DashboardData, error) { if err != nil { return data, err } + + // Add relative time information to history articles + history = addRelativeTimes(history) data.History = history // Get next up articles (importance sorted, less than 24 hours old) @@ -182,6 +185,9 @@ func getDashboardData() (DashboardData, error) { if err != nil { return data, err } + + // Add relative time information to next up articles + nextUp = addRelativeTimes(nextUp) data.NextUp = nextUp // Get recent logs @@ -206,3 +212,49 @@ func isResponseHeaderWritten(err error) bool { strings.Contains(errStr, "write: connection reset by peer") || strings.Contains(errStr, "http: superfluous response.WriteHeader") } + +// formatRelativeTime returns a human-readable relative time string +func formatRelativeTime(t time.Time) string { + if t.IsZero() { + return "" + } + + now := time.Now() + diff := now.Sub(t) + + // Less than a minute + if diff < time.Minute { + return "just now" + } + + // Less than an hour + if diff < time.Hour { + minutes := int(diff.Minutes()) + return fmt.Sprintf("%dm ago", minutes) + } + + // Less than a day + if diff < 24*time.Hour { + hours := int(diff.Hours()) + return fmt.Sprintf("%dh ago", hours) + } + + // Less than a week + if diff < 7*24*time.Hour { + days := int(diff.Hours() / 24) + return fmt.Sprintf("%dd ago", days) + } + + // More than a week + weeks := int(diff.Hours() / 24 / 7) + return fmt.Sprintf("%dw ago", weeks) +} + +// Add relative time information to articles +func addRelativeTimes(articles []Article) []Article { + for i := range articles { + articles[i].RelativeTime = formatRelativeTime(articles[i].FirstSeen) + articles[i].BroadcastRelativeTime = formatRelativeTime(articles[i].BroadcastTime) + } + return articles +}