Replace client-side JS with server-side relative timestamps
This commit is contained in:
parent
7c1a930355
commit
aec5cc4e3c
@ -17,6 +17,8 @@ type Article struct {
|
|||||||
Importance int `json:"importance"`
|
Importance int `json:"importance"`
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
BroadcastTime time.Time `json:"broadcastTime,omitempty"`
|
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 {
|
type LogEntry struct {
|
||||||
|
@ -235,7 +235,7 @@
|
|||||||
<td class="source">{{.Source}}</td>
|
<td class="source">{{.Source}}</td>
|
||||||
<td class="title">{{.Title}}</td>
|
<td class="title">{{.Title}}</td>
|
||||||
<td><a href="{{.Link}}" class="article-link" target="_blank">{{.Summary}}</a></td>
|
<td><a href="{{.Link}}" class="article-link" target="_blank">{{.Summary}}</a></td>
|
||||||
<td class="timestamp" title="{{.FirstSeen.Format "2006-01-02 15:04:05 MST"}}" data-timestamp="{{.FirstSeen.Unix}}"></td>
|
<td class="timestamp" title="{{.FirstSeen.Format "2006-01-02 15:04:05 MST"}}">{{.RelativeTime}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{{else}}
|
{{else}}
|
||||||
<tr>
|
<tr>
|
||||||
@ -263,7 +263,7 @@
|
|||||||
{{range .History}}
|
{{range .History}}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="id">{{.ID}}</td>
|
<td class="id">{{.ID}}</td>
|
||||||
<td class="timestamp" title="{{.BroadcastTime.Format "2006-01-02 15:04:05 MST"}}" data-timestamp="{{.BroadcastTime.Unix}}"></td>
|
<td class="timestamp" title="{{.BroadcastTime.Format "2006-01-02 15:04:05 MST"}}">{{.BroadcastRelativeTime}}</td>
|
||||||
<td class="importance {{if ge .Importance 70}}high{{else if ge .Importance 40}}medium{{else}}low{{end}}">{{.Importance}}</td>
|
<td class="importance {{if ge .Importance 70}}high{{else if ge .Importance 40}}medium{{else}}low{{end}}">{{.Importance}}</td>
|
||||||
<td class="source">{{.Source}}</td>
|
<td class="source">{{.Source}}</td>
|
||||||
<td class="title">{{.Title}}</td>
|
<td class="title">{{.Title}}</td>
|
||||||
@ -316,58 +316,5 @@
|
|||||||
<div class="footer">
|
<div class="footer">
|
||||||
<a href="https://git.eeqj.de/sneak/gomeshalerter">gomeshalerter</a> is a project by <a href="https://sneak.berlin">@sneak</a> and released under the WTFPL (<a href="https://git.eeqj.de/sneak/gomeshalerter">source</a>)
|
<a href="https://git.eeqj.de/sneak/gomeshalerter">gomeshalerter</a> is a project by <a href="https://sneak.berlin">@sneak</a> and released under the WTFPL (<a href="https://git.eeqj.de/sneak/gomeshalerter">source</a>)
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
|
||||||
// Function to format relative time
|
|
||||||
function formatRelativeTime(timestamp) {
|
|
||||||
const now = Math.floor(Date.now() / 1000);
|
|
||||||
const diff = now - timestamp;
|
|
||||||
|
|
||||||
// Less than a minute
|
|
||||||
if (diff < 60) {
|
|
||||||
return 'just now';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Less than an hour
|
|
||||||
if (diff < 3600) {
|
|
||||||
const minutes = Math.floor(diff / 60);
|
|
||||||
return `${minutes}m ago`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Less than a day
|
|
||||||
if (diff < 86400) {
|
|
||||||
const hours = Math.floor(diff / 3600);
|
|
||||||
return `${hours}h ago`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Less than a week
|
|
||||||
if (diff < 604800) {
|
|
||||||
const days = Math.floor(diff / 86400);
|
|
||||||
return `${days}d ago`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// More than a week
|
|
||||||
const weeks = Math.floor(diff / 604800);
|
|
||||||
return `${weeks}w ago`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update all timestamp elements
|
|
||||||
function updateRelativeTimes() {
|
|
||||||
const timestampElements = document.querySelectorAll('.timestamp[data-timestamp]');
|
|
||||||
|
|
||||||
timestampElements.forEach(el => {
|
|
||||||
const timestamp = parseInt(el.getAttribute('data-timestamp'), 10);
|
|
||||||
if (!isNaN(timestamp)) {
|
|
||||||
el.textContent = formatRelativeTime(timestamp);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update times on page load
|
|
||||||
document.addEventListener('DOMContentLoaded', updateRelativeTimes);
|
|
||||||
|
|
||||||
// Update times every minute
|
|
||||||
setInterval(updateRelativeTimes, 60000);
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
52
webserver.go
52
webserver.go
@ -175,6 +175,9 @@ func getDashboardData() (DashboardData, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return data, err
|
return data, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add relative time information to history articles
|
||||||
|
history = addRelativeTimes(history)
|
||||||
data.History = history
|
data.History = history
|
||||||
|
|
||||||
// Get next up articles (importance sorted, less than 24 hours old)
|
// Get next up articles (importance sorted, less than 24 hours old)
|
||||||
@ -182,6 +185,9 @@ func getDashboardData() (DashboardData, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return data, err
|
return data, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add relative time information to next up articles
|
||||||
|
nextUp = addRelativeTimes(nextUp)
|
||||||
data.NextUp = nextUp
|
data.NextUp = nextUp
|
||||||
|
|
||||||
// Get recent logs
|
// Get recent logs
|
||||||
@ -206,3 +212,49 @@ func isResponseHeaderWritten(err error) bool {
|
|||||||
strings.Contains(errStr, "write: connection reset by peer") ||
|
strings.Contains(errStr, "write: connection reset by peer") ||
|
||||||
strings.Contains(errStr, "http: superfluous response.WriteHeader")
|
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
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user