pretty print dates on artworks + add _hyperscript

This commit is contained in:
perennial
2024-12-04 21:03:06 +11:00
parent 0b6d489ce0
commit 81dd0b4e27
5 changed files with 87 additions and 3 deletions
File diff suppressed because one or more lines are too long
+19 -2
View File
@@ -255,9 +255,26 @@
<div class="me-3 mb-2 mb-lg-0">
<i class="bi bi-hand-thumbs-up me-2"></i>{{- .Likes }}
</div>
<div class="me-3 mb-2 mb-lg-0">
<i class="bi bi-calendar me-2"></i>{{- parseTime: .Date }}
{* Date and time info *}
{* NOTE: the _hyperscript is intended for use by mobile users;
the "title" attribute is offered as a no-JS alternative *}
{* TODO: convey this affordance where the user can switch between the two date formats *}
<div class="me-3 mb-2 mb-lg-0" _="on click
toggle .d-none on me
toggle .d-none on next <div/>"
title="{{ naturalTime: .Date }}"
>
<i class="bi bi-calendar me-2"></i>{{ relativeTime: .Date }}
</div>
<div class="me-3 mb-2 mb-lg-0 d-none" _="on click
toggle .d-none on me
toggle .d-none on previous <div/>"
title="{{ relativeTime: .Date }}"
>
<i class="bi bi-calendar me-2"></i>{{ naturalTime: .Date }}
</div>
{{- if .Images[0].Width != 0 && .Images[0].Height != 0 }}
<div>
<i class="bi bi-arrows-angle-expand me-2"></i>{{ .Images[0].Width }}x{{ .Images[0].Height }}
+1
View File
@@ -19,6 +19,7 @@
<link href="/img/favicon.png" rel="icon" />
<script src="/js/htmx@1.9.10.min.js" integrity="sha384-D1Kt99CQMDuVetoL1lrYwg5t+9QdHe7NLX/SoJYkXDFfX37iInKRy5xLSi8nO7UC"></script>
<script src="/js/hyperscript.org@0.9.13.min.js" integrity="sha384-5yQ5JTatiFEgeiEB4mfkRI3oTGtaNpbJGdcciZ4IEYFpLGt8yDsGAd7tKiMwnX9b"></script>
<!-- <script src="/js/idiomorph@0.3.0.js"></script> -->
<script src="/js/on-page-load.js" integrity="sha384-FBakXYEa42a0uP3tfUR9CyQRC/Alh/X+9boxQmVFZ7D6KV35lCzL3PhPwRSs+09n"></script>
<script src="/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"></script>
+1 -1
View File
@@ -38,7 +38,7 @@ func SetPrivacyHeaders(h http.Handler) http.Handler {
// TODO: remove style-src 'unsafe-inline'
// NOTE: default-src 'self' is required for rel="prefetch" to work on Firefox
if !strings.HasPrefix(r.URL.Path, "/diagnostics") {
header.Add("Content-Security-Policy", fmt.Sprintf("base-uri 'self'; default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: %s; media-src 'self' %s; font-src 'self'; connect-src 'self'; form-action 'self'; frame-ancestors 'none';", proxyOrigin, proxyOrigin))
header.Add("Content-Security-Policy", fmt.Sprintf("base-uri 'self'; default-src 'self'; script-src 'self'; script-src-elem 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: %s; media-src 'self' %s; font-src 'self'; connect-src 'self'; form-action 'self'; frame-ancestors 'none';", proxyOrigin, proxyOrigin))
}
h.ServeHTTP(w, r)
})
+65
View File
@@ -169,6 +169,65 @@ func ParseTimeCustomFormat(date time.Time, format string) string {
return date.Format(format)
}
// NaturalTime formats a time.Time value as a natural language string
// TODO: tailor this per locale
func NaturalTime(date time.Time) string {
return date.Format("Monday, 2 January 2006, at 3:04 PM")
}
// RelativeTime formats a time.Time value
// TODO: tailor this per locale
func RelativeTime(date time.Time) string {
now := time.Now()
duration := now.Sub(date)
// Handle future dates
if duration < 0 {
return date.Format("2 January 2006 3:04 PM")
}
// Within last minute
if duration < time.Minute {
return "Just now"
}
// Within last hour
if duration < time.Hour {
minutes := int(duration.Minutes())
if minutes == 1 {
return "1 minute ago"
}
return fmt.Sprintf("%d minutes ago", minutes)
}
// Within last 24 hours
if duration < 24*time.Hour {
hours := int(duration.Hours())
if hours == 1 {
return "1 hour ago"
}
return fmt.Sprintf("%d hours ago", hours)
}
// Check if yesterday
yesterday := now.AddDate(0, 0, -1)
if date.Year() == yesterday.Year() && date.Month() == yesterday.Month() && date.Day() == yesterday.Day() {
return fmt.Sprintf("Yesterday at %s", date.Format("3:04 PM"))
}
// Within last week
if duration < 7*24*time.Hour {
days := int(duration.Hours() / 24)
if days == 1 {
return "1 day ago"
}
return fmt.Sprintf("%d days ago", days)
}
// Older than a week
return date.Format("2 January 2006 3:04 PM")
}
// CreatePaginator generates pagination data based on the current page and maximum number of pages.
// It returns a PaginationData struct containing all necessary information for rendering pagination controls.
//
@@ -405,6 +464,12 @@ func GetTemplateFunctions() map[string]any {
"parseTimeCustomFormat": func(date time.Time, format string) string {
return ParseTimeCustomFormat(date, format)
},
"naturalTime": func(date time.Time) string {
return NaturalTime(date)
},
"relativeTime": func(date time.Time) string {
return RelativeTime(date)
},
"createPaginator": func(base, ending string, current_page, max_page, page_margin, dropdown_offset int) PaginationData {
paginationData, err := CreatePaginator(base, ending, current_page, max_page, page_margin, dropdown_offset)
if err != nil {