From c07da125bc5b0bb65f58c4edce912874e46f6ed8 Mon Sep 17 00:00:00 2001 From: SayaAndy Date: Fri, 15 May 2026 21:09:56 +0700 Subject: feat: subheader for blog pages with medley-related ones fix: inline shadow now sticks to scrolling feat: multitone backgrounds implementation refactor: convert color vars into oklch --- internal/router/handlers/api-v1-blog-search.go | 57 +++++++++++++++++--------- internal/router/handlers/lang-blog-title.go | 2 + 2 files changed, 40 insertions(+), 19 deletions(-) (limited to 'internal') diff --git a/internal/router/handlers/api-v1-blog-search.go b/internal/router/handlers/api-v1-blog-search.go index 38004a1..c48b40a 100644 --- a/internal/router/handlers/api-v1-blog-search.go +++ b/internal/router/handlers/api-v1-blog-search.go @@ -1,6 +1,7 @@ package handlers import ( + "cmp" "encoding/json" "fmt" "log/slog" @@ -51,6 +52,15 @@ func (r *BlogSearchHandler) RateLimiter() *fiber.Handler { func (r *BlogSearchHandler) Render(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (statusCode int, err error) { sort := c.Query("sort") tz := c.Query("tz") + medley := c.Query("medley") + referer := c.Get("Referer") + refererParts := strings.Split(referer, "/") + refererPage := "" + if len(refererParts) >= 1 { + refererPage = refererParts[len(refererParts)-1] + } + hideTags := c.QueryBool("hideTags", false) + hidePublishedTime := c.QueryBool("hidePublishedTime", false) loc, err := time.LoadLocation(tz) if err != nil { @@ -85,21 +95,26 @@ func (r *BlogSearchHandler) Render(c *fiber.Ctx, supplements *router.Supplements for _, page := range pages { for _, tag := range page.Metadata.Tags { if len(tags) == 0 || slices.Contains(tags, tag) { - pageMeta = append(pageMeta, fiber.Map{ - "Link": page.Link, - "ArticleLink": "/" + lang + "/blog/" + page.FileName, - "Title": page.Metadata.Title, - "PublishedTime": page.Metadata.PublishedTime.In(loc).Format("2006-01-02 15:04:05 -07:00"), - "ActionDate": page.Metadata.ActionDate, - "ShortDescription": page.Metadata.ShortDescription, - "Thumbnail": page.Metadata.Thumbnail, - "Tags": page.Metadata.Tags, - "LikeCount": supplements.ClientCache.GetLikeCount(page.FileName), - "Liked": supplements.ClientCache.GetLikeStatus(c.IP(), page.FileName), - "ViewCount": supplements.ClientCache.GetViewCount(page.FileName), - "Viewed": supplements.ClientCache.GetViewStatus(c.IP(), page.FileName), - }) - break + if medley == "" || medley == page.Metadata.Medley { + pageMeta = append(pageMeta, fiber.Map{ + "Link": page.Link, + "ArticleLink": "/" + lang + "/blog/" + page.FileName, + "Title": page.Metadata.Title, + "PublishedTime": page.Metadata.PublishedTime.In(loc).Format("2006-01-02 15:04:05 -07:00"), + "ActionDate": page.Metadata.ActionDate, + "ShortDescription": page.Metadata.ShortDescription, + "Thumbnail": page.Metadata.Thumbnail, + "Tags": page.Metadata.Tags, + "LikeCount": supplements.ClientCache.GetLikeCount(page.FileName), + "Liked": supplements.ClientCache.GetLikeStatus(c.IP(), page.FileName), + "ViewCount": supplements.ClientCache.GetViewCount(page.FileName), + "Viewed": supplements.ClientCache.GetViewStatus(c.IP(), page.FileName), + "Medley": page.Metadata.Medley, + "MedleyPart": page.Metadata.MedleyPart, + "ToHighlight": page.FileName == refererPage, + }) + break + } } } } @@ -107,13 +122,13 @@ func (r *BlogSearchHandler) Render(c *fiber.Ctx, supplements *router.Supplements slices.SortFunc(pageMeta, func(a, b fiber.Map) int { switch sort { case "titleAsc": - return strings.Compare(a["Title"].(string), b["Title"].(string)) + return cmp.Compare(a["Title"].(string), b["Title"].(string)) case "titleDesc": - return strings.Compare(b["Title"].(string), a["Title"].(string)) + return cmp.Compare(b["Title"].(string), a["Title"].(string)) case "actionDateAsc": - return strings.Compare(a["ActionDate"].(string), b["ActionDate"].(string)) + return cmp.Compare(a["ActionDate"].(string), b["ActionDate"].(string)) case "actionDateDesc": - return strings.Compare(b["ActionDate"].(string), a["ActionDate"].(string)) + return cmp.Compare(b["ActionDate"].(string), a["ActionDate"].(string)) case "publicationDateAsc": publishedTimeA, _ := time.Parse("2006-01-02 15:04:05 -07:00", a["PublishedTime"].(string)) publishedTimeB, _ := time.Parse("2006-01-02 15:04:05 -07:00", b["PublishedTime"].(string)) @@ -122,11 +137,15 @@ func (r *BlogSearchHandler) Render(c *fiber.Ctx, supplements *router.Supplements publishedTimeA, _ := time.Parse("2006-01-02 15:04:05 -07:00", a["PublishedTime"].(string)) publishedTimeB, _ := time.Parse("2006-01-02 15:04:05 -07:00", b["PublishedTime"].(string)) return publishedTimeB.Compare(publishedTimeA) + case "medley": + return cmp.Compare(a["MedleyPart"].(int), b["MedleyPart"].(int)) } return 0 }) templateMap["BlogPages"] = pageMeta + templateMap["HideTags"] = hideTags + templateMap["HidePublishedTime"] = hidePublishedTime return fiber.StatusOK, nil } diff --git a/internal/router/handlers/lang-blog-title.go b/internal/router/handlers/lang-blog-title.go index 49744c1..f7cd019 100644 --- a/internal/router/handlers/lang-blog-title.go +++ b/internal/router/handlers/lang-blog-title.go @@ -126,6 +126,8 @@ func (r *BlogPageHandler) RenderBody(c *fiber.Ctx, supplements *router.Supplemen templateMap["PublishedDate"] = metadata.PublishedTime.Format("2006-01-02 15:04:05 -07:00") templateMap["ActionDate"] = metadata.ActionDate templateMap["ShortDescription"] = metadata.ShortDescription + templateMap["Thumbnail"] = metadata.Thumbnail + templateMap["Medley"] = metadata.Medley go supplements.ClientCache.View(c.IP(), pathParts[2]) -- cgit v1.3.1+13 From 551295ecacebbb94019def022f70397f74c44775 Mon Sep 17 00:00:00 2001 From: SayaAndy Date: Sat, 16 May 2026 02:06:12 +0700 Subject: fix: font in like button on smartphone screens feat: some margin-left for medley title refactor: explicit highlight query for blog search api --- internal/router/handlers/api-v1-blog-search.go | 10 ++-------- internal/router/handlers/lang-blog-title.go | 8 +++++--- views/pages/blog-page.html | 4 ++-- views/partials/blog-page-like-button.html | 4 ++-- 4 files changed, 11 insertions(+), 15 deletions(-) (limited to 'internal') diff --git a/internal/router/handlers/api-v1-blog-search.go b/internal/router/handlers/api-v1-blog-search.go index c48b40a..b59f09a 100644 --- a/internal/router/handlers/api-v1-blog-search.go +++ b/internal/router/handlers/api-v1-blog-search.go @@ -8,7 +8,6 @@ import ( "net/url" "regexp" "slices" - "strings" "time" "github.com/SayaAndy/saya-today-web/internal/blog" @@ -53,12 +52,7 @@ func (r *BlogSearchHandler) Render(c *fiber.Ctx, supplements *router.Supplements sort := c.Query("sort") tz := c.Query("tz") medley := c.Query("medley") - referer := c.Get("Referer") - refererParts := strings.Split(referer, "/") - refererPage := "" - if len(refererParts) >= 1 { - refererPage = refererParts[len(refererParts)-1] - } + highlight := c.Query("highlight") hideTags := c.QueryBool("hideTags", false) hidePublishedTime := c.QueryBool("hidePublishedTime", false) @@ -111,7 +105,7 @@ func (r *BlogSearchHandler) Render(c *fiber.Ctx, supplements *router.Supplements "Viewed": supplements.ClientCache.GetViewStatus(c.IP(), page.FileName), "Medley": page.Metadata.Medley, "MedleyPart": page.Metadata.MedleyPart, - "ToHighlight": page.FileName == refererPage, + "ToHighlight": page.FileName == highlight, }) break } diff --git a/internal/router/handlers/lang-blog-title.go b/internal/router/handlers/lang-blog-title.go index f7cd019..eac317a 100644 --- a/internal/router/handlers/lang-blog-title.go +++ b/internal/router/handlers/lang-blog-title.go @@ -102,10 +102,11 @@ func (r *BlogPageHandler) RenderBody(c *fiber.Ctx, supplements *router.Supplemen if err != nil { return fiber.StatusBadRequest, fmt.Errorf("failed to get path from referer: %w", err) } + title := pathParts[2] - metadata, parsedMarkdown, err := readBlogPost(supplements.MarkdownRenderer, supplements.BlogClient, lang+"/"+pathParts[2]) + metadata, parsedMarkdown, err := readBlogPost(supplements.MarkdownRenderer, supplements.BlogClient, lang+"/"+title) if err != nil { - return fiber.StatusNotFound, fmt.Errorf("failed to find '%s' post: %w", pathParts[2], err) + return fiber.StatusNotFound, fmt.Errorf("failed to find '%s' post: %w", title, err) } geolocationParts := strings.Split(metadata.Geolocation, " ") @@ -122,6 +123,7 @@ func (r *BlogPageHandler) RenderBody(c *fiber.Ctx, supplements *router.Supplemen templateMap["MapLocationY"] = y templateMap["MapLocationAreaMeters"] = areaError templateMap["Title"] = metadata.Title + templateMap["Codename"] = title templateMap["ParsedMarkdown"] = template.HTML(parsedMarkdown) templateMap["PublishedDate"] = metadata.PublishedTime.Format("2006-01-02 15:04:05 -07:00") templateMap["ActionDate"] = metadata.ActionDate @@ -129,7 +131,7 @@ func (r *BlogPageHandler) RenderBody(c *fiber.Ctx, supplements *router.Supplemen templateMap["Thumbnail"] = metadata.Thumbnail templateMap["Medley"] = metadata.Medley - go supplements.ClientCache.View(c.IP(), pathParts[2]) + go supplements.ClientCache.View(c.IP(), title) return fiber.StatusOK, nil } diff --git a/views/pages/blog-page.html b/views/pages/blog-page.html index dd716fb..2a1d5d4 100644 --- a/views/pages/blog-page.html +++ b/views/pages/blog-page.html @@ -23,11 +23,11 @@
{{- if .Medley }}
-

+

{{ .Medley }}


-
Loading...
diff --git a/views/partials/blog-page-like-button.html b/views/partials/blog-page-like-button.html index 54b2914..af668e6 100644 --- a/views/partials/blog-page-like-button.html +++ b/views/partials/blog-page-like-button.html @@ -12,7 +12,7 @@ -
{{ .LikedCount }}
+
{{ .LikedCount }}
{{ else }} @@ -23,6 +23,6 @@ -
{{ .LikedCount }}
+
{{ .LikedCount }}
{{ end }} -- cgit v1.3.1+13 From ed476a1f0d3f970f977626688ac316f8b251d3a0 Mon Sep 17 00:00:00 2001 From: SayaAndy Date: Sat, 16 May 2026 14:01:14 +0700 Subject: feat: highlight the blog page visited earlier in blog catalogue --- internal/router/handlers/lang-blog.go | 7 +++---- internal/router/router.go | 3 ++- views/layouts/general-page.html | 1 + views/pages/blog-catalogue.html | 2 +- views/pages/blog-page.html | 1 + views/partials/general-page-body.html | 1 + 6 files changed, 9 insertions(+), 6 deletions(-) (limited to 'internal') diff --git a/internal/router/handlers/lang-blog.go b/internal/router/handlers/lang-blog.go index 79ec9f3..9f7947b 100644 --- a/internal/router/handlers/lang-blog.go +++ b/internal/router/handlers/lang-blog.go @@ -65,10 +65,8 @@ func (r *CatalogueHandler) AddMeta(c *fiber.Ctx, supplements *router.Supplements } func (r *CatalogueHandler) RenderBody(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (statusCode int, err error) { - querySort := c.Query("sort") - if querySort == "" { - querySort = "publicationDateDesc" - } + querySort := c.Query("sort", "publicationDateDesc") + previousBlogPage := c.Query("codename") encodedQuery := c.Request().URI().QueryString() decodedQuery, _ := url.QueryUnescape(string(encodedQuery)) @@ -88,6 +86,7 @@ func (r *CatalogueHandler) RenderBody(c *fiber.Ctx, supplements *router.Suppleme templateMap["QuerySort"] = querySort templateMap["QueryTags"] = strings.Join(queryTags, ",") templateMap["Title"] = supplements.Localization[lang].BlogSearch.Header + templateMap["PreviousBlogPage"] = previousBlogPage return fiber.StatusOK, nil } diff --git a/internal/router/router.go b/internal/router/router.go index 7f3511a..a1208e0 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -576,11 +576,12 @@ func (r *Router) generalPageSegment(c *fiber.Ctx, part string) error { cacheKey := "" trimmedPath := strings.Trim(path, "/") + requestQuery := string(c.Request().URI().QueryString()) switch route.ToCache() { case ByUrlOnly: cacheKey = fmt.Sprintf("%s.%s.%s", method, part, trimmedPath) case ByUrlAndQuery: - cacheKey = fmt.Sprintf("%s.%s.%s.%s", method, part, trimmedPath, queryString) + cacheKey = fmt.Sprintf("%s.%s.%s.%s.%s", method, part, trimmedPath, queryString, requestQuery) } if route.ToCache() != Disabled { diff --git a/views/layouts/general-page.html b/views/layouts/general-page.html index 491c652..3392ff7 100644 --- a/views/layouts/general-page.html +++ b/views/layouts/general-page.html @@ -659,6 +659,7 @@ hx-trigger="popstate from:window" hx-target="#general-page-body" hx-swap="innerHTML" + hx-include="#general-page-body .htmx-exit-trigger" >