summaryrefslogtreecommitdiff
path: root/internal/lightgallery
diff options
from:
to:
context:
space:
mode:
authorGravatar Saya Andy <145215889+SayaAndy@users.noreply.github.com> 2025-10-17 19:28:37 +0700
committerGravatar GitHub <noreply@github.com> 2025-10-17 19:28:37 +0700
commitfa2d3009ed93c28e05758d52367b25fd6a04a2b7 (patch)
treec4a05a93b5b5a1c586f0ed8a9eea2ef2f90dd3c6 /internal/lightgallery
parent2e93141f1f53410d6c38122b918972581ec4aa8d (diff)
parent152bbebe8d2d0a07ab6958a74b5f53159c79e45f (diff)
downloadweb-0.9.0.tar.gz
web-0.9.0.zip
v0.9.0 (#10)v0.9.0
- [feat: implement new prototype gallery](https://github.com/SayaAndy/saya-today-web/commit/44fe2478478225450becb77ad5d273462c9b400a) (masonry + glightbox instead of lightgallery) - A simpler column gallery, expandable between 2 and 5 columns; - Allows highlighting images via tags; - A simpler lightbox layout with wider image, especially on mobile devices; - Displays tooltips; - [feat: adapted layouts for mobile/tablet devices](https://github.com/SayaAndy/saya-today-web/commit/d3ffefbd3d9de2378b564e4c6f965c03a5a06113) - [feat: switched most length units to absolute in layouts](https://github.com/SayaAndy/saya-today-web/commit/454e2f3cd84b6c0b02a0c2936a574d3d9c35c5a1) - [feat: use dvw/dvh instead of vw/vh](https://github.com/SayaAndy/saya-today-web/commit/e231d8a3074853fbdbae9b368976bd902a1428f7) - [feat: add onclick links in blog post links](https://github.com/SayaAndy/saya-today-web/commit/db174993127a8b2faf863a670fd6ce8ca8d7c1af) - feat: add href for any onclick links/icons - feat: use page-first layout for page titles (like "{page-header} // SAYA TODAY", not vice versa) - chore: rm any remains of old lightgallery - fix: map redefining
Diffstat (limited to 'internal/lightgallery')
-rw-r--r--internal/lightgallery/block.go31
-rw-r--r--internal/lightgallery/extension.go28
-rw-r--r--internal/lightgallery/html_renderer.go145
-rw-r--r--internal/lightgallery/parser.go88
4 files changed, 0 insertions, 292 deletions
diff --git a/internal/lightgallery/block.go b/internal/lightgallery/block.go
deleted file mode 100644
index 8eb7c9e..0000000
--- a/internal/lightgallery/block.go
+++ /dev/null
@@ -1,31 +0,0 @@
-package lightgallery
-
-import (
- "time"
-
- "github.com/yuin/goldmark/ast"
-)
-
-// LightGalleryBlock represents a light gallery block in the AST
-type LightGalleryBlock struct {
- ast.BaseBlock
- Images []LightGalleryImage
- Location *time.Location
-}
-
-type LightGalleryImage struct {
- URL string
- Caption []byte
-}
-
-var KindLightGalleryBlock = ast.NewNodeKind("LightGalleryBlock")
-
-// Dump implements ast.Node.Dump
-func (n *LightGalleryBlock) Dump(source []byte, level int) {
- ast.DumpHelper(n, source, level, nil, nil)
-}
-
-// Kind implements ast.Node.Kind
-func (n *LightGalleryBlock) Kind() ast.NodeKind {
- return KindLightGalleryBlock
-}
diff --git a/internal/lightgallery/extension.go b/internal/lightgallery/extension.go
deleted file mode 100644
index 761dc05..0000000
--- a/internal/lightgallery/extension.go
+++ /dev/null
@@ -1,28 +0,0 @@
-package lightgallery
-
-import (
- "github.com/yuin/goldmark"
- "github.com/yuin/goldmark/parser"
- "github.com/yuin/goldmark/renderer"
- "github.com/yuin/goldmark/util"
-)
-
-// Extension that combines parser and renderer
-type LightGalleryExtension struct{}
-
-func NewLightGalleryExtension() goldmark.Extender {
- return &LightGalleryExtension{}
-}
-
-func (e *LightGalleryExtension) Extend(m goldmark.Markdown) {
- m.Parser().AddOptions(
- parser.WithBlockParsers(
- util.Prioritized(NewLightGalleryParser(), 500),
- ),
- )
- m.Renderer().AddOptions(
- renderer.WithNodeRenderers(
- util.Prioritized(NewLightGalleryHTMLRenderer(), 500),
- ),
- )
-}
diff --git a/internal/lightgallery/html_renderer.go b/internal/lightgallery/html_renderer.go
deleted file mode 100644
index 8e184e0..0000000
--- a/internal/lightgallery/html_renderer.go
+++ /dev/null
@@ -1,145 +0,0 @@
-package lightgallery
-
-import (
- "bytes"
- "fmt"
- "math/rand"
- "strings"
- "time"
-
- "github.com/yuin/goldmark"
- "github.com/yuin/goldmark/ast"
- "github.com/yuin/goldmark/renderer"
- "github.com/yuin/goldmark/renderer/html"
- "github.com/yuin/goldmark/util"
-)
-
-type LightGalleryHTMLRenderer struct {
- html.Config
- md goldmark.Markdown
-}
-
-func NewLightGalleryHTMLRenderer(opts ...html.Option) renderer.NodeRenderer {
- r := &LightGalleryHTMLRenderer{
- Config: html.NewConfig(),
- md: goldmark.New(
- goldmark.WithRendererOptions(
- html.WithHardWraps(),
- html.WithXHTML(),
- ),
- ),
- }
- for _, opt := range opts {
- opt.SetHTMLOption(&r.Config)
- }
- return r
-}
-
-func (r *LightGalleryHTMLRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) {
- reg.Register(KindLightGalleryBlock, r.renderLightGallery)
-}
-
-func (r *LightGalleryHTMLRenderer) renderLightGallery(w util.BufWriter, source []byte, n ast.Node, entering bool) (ast.WalkStatus, error) {
- if entering {
- gallery := n.(*LightGalleryBlock)
-
- if len(gallery.Images) == 0 {
- return ast.WalkContinue, nil
- }
-
- galleryID := generateDivId(8)
-
- w.WriteString(fmt.Sprintf(`
-<div class="justify-content-center display-block m-2">
- <hr class="border-t-4 border-dotted border-main-dark mt-[0.8vmin] mb-[0.8vmin] w-[80%%] ml-auto mr-auto">
- <div id="lg-%s" class="inline-gallery-container relative ml-auto mr-auto"></div>
- <hr class="border-t-4 border-dotted border-main-dark mt-[0.8vmin] mb-[0.8vmin] w-[80%%] ml-auto mr-auto">
-</div>`, galleryID))
-
- var dynamicElements []string
- for _, img := range gallery.Images {
- imageUrlSegments := strings.Split(img.URL, ".")
- imageUrlWithoutExt := strings.Join(imageUrlSegments[:len(imageUrlSegments)-1], ".")
- imageUrlParts := strings.Split(imageUrlWithoutExt, "/")
- imageNameParts := strings.Split(imageUrlParts[len(imageUrlParts)-1], "-")
-
- var captionBuf bytes.Buffer
- captionHTML := img.Caption
- if err := r.md.Convert(img.Caption, &captionBuf); err == nil {
- captionHTML = captionBuf.Bytes()
- captionHTML = bytes.TrimPrefix(captionHTML, []byte("<p>"))
- captionHTML = bytes.TrimSuffix(captionHTML, []byte("</p>\n"))
- captionHTML = bytes.TrimSuffix(captionHTML, []byte("</p>"))
- }
-
- dayDate, _ := time.Parse("20060102 150405", imageNameParts[len(imageNameParts)-2]+" "+imageNameParts[len(imageNameParts)-1])
- dayDate = dayDate.In(gallery.Location)
- dynamicElements = append(dynamicElements, fmt.Sprintf(`{
- src:
- "https://f003.backblazeb2.com/file/sayana-photos/full/%s",
- downloadUrl:
- "https://f003.backblazeb2.com/file/sayana-photos/full/%s",
- alt: "%s",
- responsive: "https://f003.backblazeb2.com/file/sayana-photos/webp-320p/%s.webp 384, https://f003.backblazeb2.com/file/sayana-photos/webp-560p/%s.webp 672, https://f003.backblazeb2.com/file/sayana-photos/webp-800p/%s.webp 960, https://f003.backblazeb2.com/file/sayana-photos/webp-1200p/%s.webp 1440, https://f003.backblazeb2.com/file/sayana-photos/webp-1600p/%s.webp 1920",
- thumb:
- "https://f003.backblazeb2.com/file/sayana-photos/webp-320p/%s.webp",
- subHtml: `+"`"+`<div class="flex flex-row light-gallery-captions">
- <p class="grow !text-[1vmax]/[1] text-left font-spectral text-main-dark">%s</p>
- <p class="!text-[1vmax]/[1] text-right font-spectral text-secondary">%s</p>
- </div>`+"`"+`
- }`, img.URL, img.URL, util.EscapeHTML(captionHTML), imageUrlWithoutExt, imageUrlWithoutExt, imageUrlWithoutExt, imageUrlWithoutExt, imageUrlWithoutExt, imageUrlWithoutExt, captionHTML, dayDate.Format("2006-01-02 15:04:05 -07:00")))
- }
-
- w.WriteString(fmt.Sprintf(`
-<script>
-function createLightGallery%s() {
- const $lgContainer = document.getElementById('lg-%s');
- const config = {
- container: $lgContainer,
- dynamic: true,
- dynamicEl: [%s],
- width: "100%%",
- height: "50vmin",
- hash: false,
- closable: false,
- showMaximizeIcon: true,
- appendSubHtmlTo: ".lg-sub-html",
- isMobile: () => false,
- slideDelay: 0,
- plugins: [lgZoom, lgThumbnail],
- thumbWidth: calculateVmin(10),
- thumbHeight: "10vmin",
- thumbMargin: 4
- };
- const inlineGallery = lightGallery($lgContainer, config);
-
- setTimeout(() => {
- inlineGallery.openGallery();
- }, 200);
-
- galleryMap.set(inlineGallery, createLightGallery%s);
-}
-
-document.addEventListener('htmx:afterRequest', (e) => {
- if (e.detail.xhr.status == 404 || e.detail.successful != true) {
- return console.error(e);
- }
- if (e.detail.target.id == 'general-page-body') {
- createLightGallery%s();
- }
-}, {once: true});
-</script>`, galleryID, galleryID, strings.Join(dynamicElements, ","), galleryID, galleryID))
- }
-
- return ast.WalkContinue, nil
-}
-
-func generateDivId(length int) string {
- const charset = "abcdefghijklmnopqrstuvwxyz"
- seededRand := rand.New(rand.NewSource(time.Now().UnixNano())) // Seed with current time
- b := make([]byte, length)
- for i := range b {
- b[i] = charset[seededRand.Intn(len(charset))]
- }
- return string(b)
-}
diff --git a/internal/lightgallery/parser.go b/internal/lightgallery/parser.go
deleted file mode 100644
index daec797..0000000
--- a/internal/lightgallery/parser.go
+++ /dev/null
@@ -1,88 +0,0 @@
-package lightgallery
-
-import (
- "bytes"
- "log/slog"
- "regexp"
- "time"
-
- "github.com/yuin/goldmark/ast"
- "github.com/yuin/goldmark/parser"
- "github.com/yuin/goldmark/text"
-)
-
-type LightGalleryParser struct{}
-
-func NewLightGalleryParser() parser.BlockParser {
- return &LightGalleryParser{}
-}
-
-func (p *LightGalleryParser) Trigger() []byte {
- return []byte{'{'}
-}
-
-func (p *LightGalleryParser) Open(parent ast.Node, reader text.Reader, pc parser.Context) (ast.Node, parser.State) {
- line, _ := reader.PeekLine()
-
- if !bytes.HasPrefix(line, []byte("{Gallery:")) {
- return nil, parser.NoChildren
- }
-
- r := regexp.MustCompile(`^\{Gallery:([A-Za-z0-9\+\-/]+)\}$`)
-
- trimmed := bytes.TrimSpace(line)
- parts := r.FindSubmatch(trimmed)
- if len(parts) < 2 {
- slog.Warn("invalid gallery header format", slog.String("line", string(trimmed)), slog.Int("submatch_count", len(parts)))
- return nil, parser.NoChildren
- }
-
- loc, err := time.LoadLocation(string(parts[1]))
- if err != nil {
- slog.Warn("invalid location specified for a gallery", slog.String("error", err.Error()), slog.String("line", string(trimmed)), slog.String("location", string(parts[1])))
- return nil, parser.NoChildren
- }
-
- return &LightGalleryBlock{Location: loc}, parser.NoChildren
-}
-
-func (p *LightGalleryParser) Continue(node ast.Node, reader text.Reader, pc parser.Context) parser.State {
- line, segment := reader.PeekLine()
- if len(line) == 0 || segment.Len() == 0 {
- return parser.Continue | parser.NoChildren
- }
-
- trimmed := bytes.TrimSpace(line)
- if bytes.Equal(trimmed, []byte("{Gallery}")) || bytes.Equal(trimmed, []byte("{/Gallery}")) {
- reader.AdvanceLine()
- return parser.Close
- }
-
- gallery := node.(*LightGalleryBlock)
-
- parts := bytes.SplitN(trimmed, []byte{'|'}, 2)
- url := bytes.TrimSpace(parts[0])
-
- caption := make([]byte, 0)
- if len(parts) > 1 {
- caption = bytes.TrimSpace(parts[1])
- }
-
- gallery.Images = append(gallery.Images, LightGalleryImage{
- URL: string(url),
- Caption: caption,
- })
-
- return parser.Continue | parser.NoChildren
-}
-
-func (p *LightGalleryParser) Close(node ast.Node, reader text.Reader, pc parser.Context) {
-}
-
-func (p *LightGalleryParser) CanInterruptParagraph() bool {
- return true
-}
-
-func (p *LightGalleryParser) CanAcceptIndentedLine() bool {
- return false
-}