summaryrefslogtreecommitdiff
diff options
from:
to:
context:
space:
mode:
-rw-r--r--internal/glightbox/html_renderer.go2
-rw-r--r--internal/tailwind/link_renderer.go49
-rw-r--r--internal/tailwind/transformer.go7
-rw-r--r--internal/templatemanager/templatemanager.go4
-rw-r--r--main.go14
-rw-r--r--static/input.css31
-rw-r--r--views/layouts/general-page.html27
-rw-r--r--views/pages/blog-page.html66
-rw-r--r--views/pages/global-map.html16
-rw-r--r--views/partials/catalogue-blog-cards.html8
-rw-r--r--views/partials/general-page-header.html6
11 files changed, 131 insertions, 99 deletions
diff --git a/internal/glightbox/html_renderer.go b/internal/glightbox/html_renderer.go
index 3b6a533..43d4790 100644
--- a/internal/glightbox/html_renderer.go
+++ b/internal/glightbox/html_renderer.go
@@ -81,7 +81,7 @@ func (r *GLightboxHTMLRenderer) renderGLightbox(w util.BufWriter, source []byte,
elements = append(elements, fmt.Sprintf(`
<a href="https://f003.backblazeb2.com/file/sayana-photos/full/%s" class="glightbox-%s grid-item grid-item-%s"
data-gallery="gallery-%s" data-title="%s" %s>
- <img src="https://f003.backblazeb2.com/file/sayana-photos/webp-320p/%s.webp" class="rounded-md p-0.5" alt="webp thumbnail" />
+ <img src="https://f003.backblazeb2.com/file/sayana-photos/webp-320p/%s.webp" class="rounded-md p-1" alt="webp thumbnail" />
</a>`, img.URL, galleryID, galleryID, galleryID, dayDate.Format("2006-01-02 15:04:05 -07:00"), dataDescriptionAttribute, imageUrlWithoutExt))
if glightboxDescId != "" {
diff --git a/internal/tailwind/link_renderer.go b/internal/tailwind/link_renderer.go
new file mode 100644
index 0000000..ff3d437
--- /dev/null
+++ b/internal/tailwind/link_renderer.go
@@ -0,0 +1,49 @@
+package tailwind
+
+import (
+ "github.com/yuin/goldmark/ast"
+ "github.com/yuin/goldmark/renderer"
+ "github.com/yuin/goldmark/renderer/html"
+ "github.com/yuin/goldmark/util"
+)
+
+type CustomLinkRenderer struct {
+ html.Config
+}
+
+func NewCustomLinkRenderer(opts ...html.Option) renderer.NodeRenderer {
+ r := &CustomLinkRenderer{
+ Config: html.NewConfig(),
+ }
+ for _, opt := range opts {
+ opt.SetHTMLOption(&r.Config)
+ }
+ return r
+}
+
+func (r *CustomLinkRenderer) renderLink(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
+ n := node.(*ast.Link)
+ if entering {
+ _, _ = w.WriteString("<a href=\"")
+ if r.Unsafe || !html.IsDangerousURL(n.Destination) {
+ _, _ = w.Write(util.EscapeHTML(util.URLEscape(n.Destination, true)))
+ }
+ _, _ = w.WriteString(`"`)
+ if n.Title != nil {
+ _, _ = w.WriteString(` title="`)
+ _, _ = w.Write(util.EscapeHTML(n.Title))
+ _, _ = w.WriteString(`"`)
+ }
+ if n.Attributes() != nil {
+ html.RenderAttributes(w, n, nil)
+ }
+ _, _ = w.WriteString(">")
+ } else {
+ _, _ = w.WriteString("</a>")
+ }
+ return ast.WalkContinue, nil
+}
+
+func (r *CustomLinkRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) {
+ reg.Register(ast.KindLink, r.renderLink)
+}
diff --git a/internal/tailwind/transformer.go b/internal/tailwind/transformer.go
index f932533..23ba1a3 100644
--- a/internal/tailwind/transformer.go
+++ b/internal/tailwind/transformer.go
@@ -1,6 +1,9 @@
package tailwind
import (
+ "bytes"
+ "fmt"
+
"github.com/yuin/goldmark/ast"
"github.com/yuin/goldmark/parser"
"github.com/yuin/goldmark/text"
@@ -51,6 +54,10 @@ func (t *TailwindTransformer) Transform(node *ast.Document, reader text.Reader,
node.SetAttribute([]byte("class"), []byte("bg-background-dark p-1 rounded-lg overflow-x-auto mb-4"))
case *ast.Link:
+ if bytes.HasPrefix(node.Destination, []byte{'.', '/'}) {
+ onclickAttr := fmt.Appendf(make([]byte, 0, 21+len(node.Destination)), "return changeUrl('%s');", node.Destination)
+ node.SetAttribute([]byte("onclick"), onclickAttr)
+ }
node.SetAttribute([]byte("class"), []byte("text-secondary hover:text-main-dark underline"))
case *ast.Image:
diff --git a/internal/templatemanager/templatemanager.go b/internal/templatemanager/templatemanager.go
index 4bf9a49..eebc297 100644
--- a/internal/templatemanager/templatemanager.go
+++ b/internal/templatemanager/templatemanager.go
@@ -37,7 +37,7 @@ func NewTemplateManager(templates ...TemplateManagerTemplates) (*TemplateManager
templateMap := make(map[string]templateManagerRender)
for _, tmplStruct := range templates {
- tmpl := template.New("").Funcs(templateFuncMap)
+ tmpl := template.New(tmplStruct.Name).Funcs(templateFuncMap)
tmpl, err := tmpl.ParseFiles(tmplStruct.Files...)
if err != nil {
return nil, err
@@ -84,7 +84,7 @@ func (tm *TemplateManager) Add(name string, files ...string) error {
return fmt.Errorf("you can't add template without any files")
}
- tmpl := template.New("").Funcs(templateFuncMap)
+ tmpl := template.New(name).Funcs(templateFuncMap)
tmpl, err := tmpl.ParseFiles(files...)
if err != nil {
diff --git a/main.go b/main.go
index 53dbb74..a6a30b0 100644
--- a/main.go
+++ b/main.go
@@ -23,7 +23,9 @@ import (
"github.com/golang-migrate/migrate/v4/database/sqlite3"
"github.com/yuin/goldmark"
"github.com/yuin/goldmark/parser"
- gmhtml "github.com/yuin/goldmark/renderer/html"
+ "github.com/yuin/goldmark/renderer"
+ "github.com/yuin/goldmark/renderer/html"
+ "github.com/yuin/goldmark/util"
_ "github.com/golang-migrate/migrate/v4/source/file"
_ "github.com/mattn/go-sqlite3"
@@ -37,9 +39,15 @@ var (
),
goldmark.WithParserOptions(
parser.WithAutoHeadingID(),
+ parser.WithAttribute(),
),
- goldmark.WithRendererOptions(
- gmhtml.WithXHTML(),
+ goldmark.WithRenderer(
+ renderer.NewRenderer(
+ renderer.WithNodeRenderers(
+ util.Prioritized(tailwind.NewCustomLinkRenderer(html.WithUnsafe(), html.WithXHTML()), 50),
+ util.Prioritized(html.NewRenderer(html.WithXHTML()), 100),
+ ),
+ ),
),
)
b2Client *b2.B2Client
diff --git a/static/input.css b/static/input.css
index 36d17b2..1e7f9fc 100644
--- a/static/input.css
+++ b/static/input.css
@@ -236,37 +236,22 @@ a:hover {
border-style: outset;
}
-.desktop-sidebar-custom {
- width: 5vw;
- background-size: calc(var(--squares-and-triangles-background-size) * 1vw);
-}
-
.bg-sidebar {
background-image: var(--squares-and-triangles-background);
background-repeat: var(--squares-and-triangles-background-repeat);
- background-size: calc(var(--squares-and-triangles-background-width-coef) * 1vw) calc(var(--squares-and-triangles-background-height-coef) * 1vw);
+ background-size: calc(var(--squares-and-triangles-background-width-coef) * 1dvw) calc(var(--squares-and-triangles-background-height-coef) * 1dvw);
}
.logo-custom {
- width: 3.5vw;
- height: 20vw;
- font-size: 2.5vw;
- -webkit-text-stroke: 0.1vw var(--sidebar-stroke-color);
+ width: 3.5dvw;
+ height: 20dvw;
+ font-size: 2.5dvw;
+ -webkit-text-stroke: 0.1dvw var(--sidebar-stroke-color);
writing-mode: sideways-lr;
text-orientation: mixed;
display: block;
}
-.border-left-custom {
- width: 0.5vw;
- border-right: 0.3vh dashed var(--main-dark-color);
-}
-
-.border-right-custom {
- width: 0.5vw;
- border-left: 0.5vh dotted var(--main-dark-color);
-}
-
.inset-shadow {
box-shadow: inset 0vh 1vh 1vh -1vh rgba(75, 81, 58, 0.5),
inset 1vh 0vh 1vh -1vh rgba(75, 81, 58, 0.5),
@@ -278,8 +263,8 @@ a:hover {
-webkit-text-stroke-color: var(--sidebar-stroke-color);
}
-.text-stroke-\[0\.1vw\] {
- -webkit-text-stroke-width: 0.1vw;
+.text-stroke-\[0\.1dvw\] {
+ -webkit-text-stroke-width: 0.1dvw;
}
.theme-wheel {
@@ -411,7 +396,7 @@ body[data-theme~="ram"] .leaflet-tile {
@media (max-aspect-ratio: 0.8/1) {
.bg-sidebar {
- background-size: calc(var(--squares-and-triangles-background-width-coef) * 1.6vh) calc(var(--squares-and-triangles-background-height-coef) * 1.6vh);
+ background-size: calc(var(--squares-and-triangles-background-width-coef) * 1.6dvh) calc(var(--squares-and-triangles-background-height-coef) * 1.6dvh);
}
.ar-lt-0\.8\:bg-background-light {
diff --git a/views/layouts/general-page.html b/views/layouts/general-page.html
index 88c5de5..b163387 100644
--- a/views/layouts/general-page.html
+++ b/views/layouts/general-page.html
@@ -15,12 +15,21 @@
<body data-theme="ram" class="font-spectral text-main-dark overflow-hidden bg-interlocked-hexagons h-screen flex flex-row ar-lt-0.8:flex-col">
<script>
+ let map = null;
+ </script>
+
+ <script>
function changeUrl(path, toAppend = false) {
const urlParams = new URLSearchParams(window.location.search);
const newPathname = location.pathname.endsWith('/') ? location.pathname.slice(0, -1) : location.pathname;
const newPath = toAppend ? `${newPathname}${path}` : `${path}`;
+
history.pushState({}, '', `${newPath}${urlParams.entries.length == 0 ? '' : '?' + urlParams.toString()}`);
+ if (location.pathname == "" || location.pathname == "/") {
+ return true;
+ }
window.dispatchEvent(new Event('popstate'));
+ return false;
};
</script>
@@ -165,12 +174,20 @@
<div class="logo-custom ar-lt-0.8:hidden text-sidebar font-patua font-extrabold text-center relative z-20">
saya.today
</div>
- <div class="text-[3dvw] ar-lt-0.8:text-[5dvh] text-stroke-(--sidebar-stroke-color) text-stroke-[0.1vw] flex flex-col ar-lt-0.8:flex-row gap-0 relative z-20">
- <i onclick="changeUrl('/{{ .Lang }}');" class="fas fa-home flex w-[5dvw] ar-lt-0.8:w-[8dvh] h-[5dvw] ar-lt-0.8:h-[8dvh] content-center text-center text-sidebar hover:bg-background-dark cursor-pointer transition-colors duration-300 rounded-lg"></i>
- <i onclick="changeUrl('/{{ .Lang }}/blog');" class="fas fa-search flex w-[5dvw] ar-lt-0.8:w-[8dvh] h-[5dvw] ar-lt-0.8:h-[8dvh] content-center text-center text-sidebar hover:bg-background-dark cursor-pointer transition-colors duration-300 rounded-lg"></i>
- <i onclick="location.href='/{{ .Lang }}/map';" class="fas fa-map flex w-[5dvw] ar-lt-0.8:w-[8dvh] h-[5dvw] ar-lt-0.8:h-[8dvh] content-center text-center text-sidebar hover:bg-background-dark cursor-pointer transition-colors duration-300 rounded-lg"></i>
+ <div class="text-[3dvw] ar-lt-0.8:text-[5dvh] text-stroke-(--sidebar-stroke-color) text-stroke-[0.1dvw] flex flex-col ar-lt-0.8:flex-row gap-0 relative z-20">
+ <a href="/{{ .Lang }}" class="w-[5dvw] ar-lt-0.8:w-[8dvh] h-[5dvw] ar-lt-0.8:h-[8dvh]">
+ <i onclick="return changeUrl('/{{ .Lang }}');" class="fas fa-home flex w-full h-full content-center text-center text-sidebar hover:bg-background-dark transition-colors duration-300 rounded-lg"></i>
+ </a>
+ <a href="/{{ .Lang }}/blog" class="w-[5dvw] ar-lt-0.8:w-[8dvh] h-[5dvw] ar-lt-0.8:h-[8dvh]">
+ <i onclick="return changeUrl('/{{ .Lang }}/blog');" class="fas fa-search flex w-full h-full content-center text-center text-sidebar hover:bg-background-dark transition-colors duration-300 rounded-lg"></i>
+ </a>
+ <a href="/{{ .Lang }}/map" class="w-[5dvw] ar-lt-0.8:w-[8dvh] h-[5dvw] ar-lt-0.8:h-[8dvh]">
+ <i class="fas fa-map flex w-full h-full content-center text-center text-sidebar hover:bg-background-dark transition-colors duration-300 rounded-lg"></i>
+ </a>
<i onclick="toggleThemeWheel();" id="theme-button" class="fas fa-swatchbook flex w-[5dvw] ar-lt-0.8:w-[8dvh] h-[5dvw] ar-lt-0.8:h-[8dvh] content-center text-center text-sidebar hover:bg-background-dark cursor-pointer transition-colors duration-300 rounded-lg"></i>
- <i onclick="changeUrl('/../', true);" class="fas fa-circle-left flex xs:!hidden w-[5dvw] ar-lt-0.8:w-[8dvh] h-[5dvw] ar-lt-0.8:h-[8dvh] content-center text-center text-sidebar hover:bg-background-dark cursor-pointer transition-colors duration-300 rounded-lg"></i>
+ <a href="./" class="xs:!hidden w-[5dvw] ar-lt-0.8:w-[8dvh] h-[5dvw] ar-lt-0.8:h-[8dvh]">
+ <i onclick="return changeUrl('/../', true);" class="fas fa-circle-left flex w-full h-full content-center text-center text-sidebar hover:bg-background-dark transition-colors duration-300 rounded-lg"></i>
+ </a>
</div>
<div class="theme-wheel" id="theme-wheel">
<div class="theme-icon" data-theme="olive"></div>
diff --git a/views/pages/blog-page.html b/views/pages/blog-page.html
index aadebac..9704502 100644
--- a/views/pages/blog-page.html
+++ b/views/pages/blog-page.html
@@ -1,20 +1,3 @@
-{{ define "top-embeds" }}
-<script>
- let galleryMap = new Map();
- let map;
-
- window.addEventListener('popout', (e) => {
- map.remove();
- galleryMap.forEach((_, g, m) => {
- g.destroy();
- });
- galleryMap.clear();
- map = null;
- galleryMap = null;
- }, {once: true});
-</script>
-{{ end }}
-
{{ define "body" }}
<div class="bg-background-light flex flex-col inset-shadow px-8 py-4 overflow-y-auto">
<p class="xs:hidden font-spectral text-2xl font-bold italic text-main-dark tracking-[.0125rem] mb-1">{{ .Title }}</p>
@@ -52,16 +35,17 @@
.openPopup();
}
- document.addEventListener('htmx:afterRequest', (e) => {
- if (e.detail.target.id == 'general-page-body') {
- initLocationMap(
- 'map-container',
- {{ .MapLocationX }},
- {{ .MapLocationY }},
- {{ .MapLocationAreaMeters }}
- );
- }
- }, {once: true});
+ if (map) {
+ map.remove();
+ map = null;
+ }
+
+ setTimeout(() => initLocationMap(
+ 'map-container',
+ {{ .MapLocationX }},
+ {{ .MapLocationY }},
+ {{ .MapLocationAreaMeters }}
+ ), 1000);
</script>
{{- end }}
</div>
@@ -70,31 +54,3 @@
{{ define "footer" }}
<div hx-get="/api/v1/like" hx-target="this" hx-swap="outerHTML" hx-trigger="load"></div>
{{ end }}
-
-{{ define "bottom-embeds" }}
-<script>
- let galleryResizeTimeout;
-
- function resizeCb() {
- clearTimeout(galleryResizeTimeout);
- galleryResizeTimeout = setTimeout(() => {
- if (map !== undefined) {
- map.invalidateSize();
- }
- var oldGalleryMap = new Map(galleryMap);
- oldGalleryMap.forEach((createFunc, g, map) => {
- galleryMap.delete(g);
- g.destroy();
- createFunc();
- });
- }, 300);
- }
-
- window.addEventListener('resize', resizeCb);
-
- document.addEventListener('popout', (e) => {
- window.removeEventListener('resize', resizeCb);
- galleryResizeTimeout = null;
- });
-</script>
-{{ end }}
diff --git a/views/pages/global-map.html b/views/pages/global-map.html
index 4c6fb5e..27c8a73 100644
--- a/views/pages/global-map.html
+++ b/views/pages/global-map.html
@@ -44,11 +44,17 @@
<div class="logo-custom ar-lt-0.8:hidden text-sidebar font-patua font-extrabold text-center relative z-20">
saya.today
</div>
- <div class="text-[3dvw] sm:text-2xl ar-lt-0.8:text-[5dvh] text-stroke-(--sidebar-stroke-color) text-stroke-[0.1vw] flex flex-col ar-lt-0.8:flex-row gap-0 relative z-20">
- <i onclick="location.href='/{{ .Lang }}';" class="fas fa-home w-[5dvw] ar-lt-0.8:w-[8dvh] h-[5dvw] ar-lt-0.8:h-[8dvh] content-center text-center text-sidebar hover:bg-background-dark cursor-pointer transition-colors duration-300 flex rounded-lg"></i>
- <i onclick="location.href='/{{ .Lang }}/blog';" class="fas fa-search w-[5dvw] ar-lt-0.8:w-[8dvh] h-[5dvw] ar-lt-0.8:h-[8dvh] content-center text-center text-sidebar hover:bg-background-dark cursor-pointer transition-colors duration-300 flex rounded-lg"></i>
- <i onclick="location.href='/{{ .Lang }}/map';" class="fas fa-map w-[5dvw] ar-lt-0.8:w-[8dvh] h-[5dvw] ar-lt-0.8:h-[8dvh] content-center text-center text-sidebar hover:bg-background-dark cursor-pointer transition-colors duration-300 flex rounded-lg"></i>
- <i onclick="toggleThemeWheel();" id="theme-button" class="fas fa-swatchbook w-[5dvw] ar-lt-0.8:w-[8dvh] h-[5dvw] ar-lt-0.8:h-[8dvh] content-center text-center text-sidebar hover:bg-background-dark cursor-pointer transition-colors duration-300 flex rounded-lg"></i>
+ <div class="text-[3dvw] ar-lt-0.8:text-[5dvh] text-stroke-(--sidebar-stroke-color) text-stroke-[0.1dvw] flex flex-col ar-lt-0.8:flex-row gap-0 relative z-20">
+ <a href="/{{ .Lang }}" class="w-[5dvw] ar-lt-0.8:w-[8dvh] h-[5dvw] ar-lt-0.8:h-[8dvh]">
+ <i class="fas fa-home flex w-full h-full content-center text-center text-sidebar hover:bg-background-dark transition-colors duration-300 rounded-lg"></i>
+ </a>
+ <a href="/{{ .Lang }}/blog" class="w-[5dvw] ar-lt-0.8:w-[8dvh] h-[5dvw] ar-lt-0.8:h-[8dvh]">
+ <i class="fas fa-search flex w-full h-full content-center text-center text-sidebar hover:bg-background-dark transition-colors duration-300 rounded-lg"></i>
+ </a>
+ <a href="/{{ .Lang }}/map" class="w-[5dvw] ar-lt-0.8:w-[8dvh] h-[5dvw] ar-lt-0.8:h-[8dvh]">
+ <i class="fas fa-map flex w-full h-full content-center text-center text-sidebar hover:bg-background-dark transition-colors duration-300 rounded-lg"></i>
+ </a>
+ <i onclick="toggleThemeWheel();" id="theme-button" class="fas fa-swatchbook flex w-[5dvw] ar-lt-0.8:w-[8dvh] h-[5dvw] ar-lt-0.8:h-[8dvh] content-center text-center text-sidebar hover:bg-background-dark cursor-pointer transition-colors duration-300 rounded-lg"></i>
</div>
<div class="theme-wheel" id="theme-wheel">
<div class="theme-icon" data-theme="olive"></div>
diff --git a/views/partials/catalogue-blog-cards.html b/views/partials/catalogue-blog-cards.html
index 041f3c8..5c3bb95 100644
--- a/views/partials/catalogue-blog-cards.html
+++ b/views/partials/catalogue-blog-cards.html
@@ -1,10 +1,12 @@
{{- range .BlogPages }}
-<hr class="first-of-type:hidden border-t-1 mx-auto">
+<hr class="first-of-type:hidden my-1 border-t-2 border-dotted border-main-dark">
<div class="m-1 flex flex-row justify-center justify-items-center">
- <img onclick="changeUrl('{{ .ArticleLink }}');" class="cursor-pointer object-cover rounded-lg select-none w-24 h-24 aspect-square my-2.5 mr-2" src="https://f003.backblazeb2.com/file/sayana-photos/webp-320p/{{ .Thumbnail }}.webp">
+ <a href="{{ .ArticleLink }}" class="w-24 h-24 basis-24 shrink-0 my-2.5 mr-2">
+ <img onclick="return changeUrl('{{ .ArticleLink }}');" class="w-full h-full aspect-square cursor-pointer object-cover rounded-lg select-none" src="https://f003.backblazeb2.com/file/sayana-photos/webp-320p/{{ .Thumbnail }}.webp">
+ </a>
<div class="grow my-0.5 mx-1 flex flex-col justify-center">
<div class="flex flex-row gap-2 max-w-[100%]">
- <a onclick="changeUrl('{{ .ArticleLink }}');" class="grow text-base cursor-pointer">
+ <a href="{{ .ArticleLink }}" onclick="return changeUrl('{{ .ArticleLink }}');" class="grow text-base cursor-pointer">
<span class="font-extrabold">{{ .Title }}</span>
<span class="font-extrabold select-none text-secondary">//</span>
<span class="italic text-secondary">{{ .ActionDate }}</span>
diff --git a/views/partials/general-page-header.html b/views/partials/general-page-header.html
index 7f6ab8a..e5488b4 100644
--- a/views/partials/general-page-header.html
+++ b/views/partials/general-page-header.html
@@ -1,7 +1,9 @@
<div {{ if .PublishedDate }} hx-get="/api/v1/tz" hx-vals='js:{timestamp: "{{ .PublishedDate }}", tz: clientTimeZone}' hx-target="#published-date" hx-swap="innerHTML" hx-trigger="load" {{ end }}
class="flex flex-row mb-2">
- <i onclick="changeUrl('/../', true);" class="fas fa-circle-left hover:bg-main-dark hover:bg-opacity-10 cursor-pointer transition-colors duration-300 rounded-md text-4xl mt-auto mb-auto px-1"></i>
- <p class="text-4xl font-spectral italic font-extrabold select-none mt-auto mb-auto pl-3 pr-3">//</p>
+ <a href="./" class="w-(--text-4xl) h-(--text-4xl) mx-1 my-auto">
+ <i onclick="return changeUrl('/../', true);" class="fas fa-circle-left hover:bg-main-dark hover:bg-opacity-10 cursor-pointer transition-colors duration-300 rounded-md text-4xl"></i>
+ </a>
+ <p class="text-4xl font-spectral italic font-extrabold select-none my-auto pl-3 pr-3">//</p>
<p class="text-4xl font-spectral italic text-left mt-auto">{{ .Title }}</p>
<p id="published-date" class="grow text-2xl font-spectral text-secondary text-right mt-auto">{{ .PublishedDate }}</p>
</div>