mirror of
https://codeberg.org/VnPower/PixivFE
synced 2024-12-06 19:16:23 +01:00
pretty print dates on artworks + add _hyperscript
This commit is contained in:
+1
File diff suppressed because one or more lines are too long
@@ -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 }}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user