summaryrefslogtreecommitdiff
path: root/views
diff refs
from: back
to: back
| flip
diff options
context:
space:
mode:
Diffstat (limited to 'views')
-rw-r--r--views/layouts/general-page.html105
-rw-r--r--views/pages/blog-catalogue.html107
-rw-r--r--views/pages/blog-page.html27
-rw-r--r--views/pages/global-map.html71
-rw-r--r--views/pages/home-page.html19
-rw-r--r--views/pages/language-pick.html2
-rw-r--r--views/pages/robots.txt5
-rw-r--r--views/pages/sitemap.xml10
-rw-r--r--views/pages/unsubscribe-page.html1
-rw-r--r--views/pages/user-page.html3
-rw-r--r--views/partials/blog-page-like-button.html9
-rw-r--r--views/partials/general-page-header.html10
12 files changed, 228 insertions, 141 deletions
diff --git a/views/layouts/general-page.html b/views/layouts/general-page.html
index 62360ad..2d3bff3 100644
--- a/views/layouts/general-page.html
+++ b/views/layouts/general-page.html
@@ -3,10 +3,24 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
+ {{- range .Meta }}
+ <meta {{with .Name}}name="{{.}}" {{end}}{{with .Property}}property="{{.}}" {{end}}{{with .Content}}content="{{.}}"{{end}}>
+ {{- if eq .Property "og:description" }}
+ <meta name="description" content="{{.Content}}">
+ {{- end }}
+ {{- if eq .Property "og:url" }}
+ <link rel="canonical" href="{{.Content}}">
+ {{- end }}
+ {{- end }}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css">
<link rel="stylesheet" href="https://f003.backblazeb2.com/file/sayana-static/libs/leaflet/1.9.4/leaflet.css">
<link rel="stylesheet" href="https://f003.backblazeb2.com/file/sayana-static/libs/glightbox/3.3.0/css/glightbox.min.css">
<link href="/output.css" rel="stylesheet">
+ {{- with .LinkedData }}
+ <script type="application/ld+json">
+ {{ . }}
+ </script>
+ {{- end }}
</head>
<body data-theme="ram" class="font-andika text-main-hard overflow-hidden bg-interlocked-hexagons h-dvh flex flex-row">
@@ -137,6 +151,7 @@
document.body.append(frame);
}
break;
+ case "lilac": break;
}
}
@@ -171,26 +186,31 @@
<div class="grow bg-split-left"></div>
- <div class="flex flex-col [@media(max-height:32rem)]:flex-row">
- <div id="sidebar" class="bg-sidebar flex sticky flex-col z-20 w-dvw xs:w-[90dvw] sm:w-[80dvw] md:w-[75dvw] lg:w-[70dvw] xl:w-[65dvw] 2xl:w-[60dvw] [@media(max-height:32rem)]:w-20 h-20 [@media(max-height:32rem)]:h-dvh shadow-[0_0_1rem_black]">
- <div class="text-[3rem] text-stroke-(--sidebar-stroke-color) text-stroke-[0.1dvw] flex flex-row [@media(max-height:32rem)]:flex-col gap-0 relative z-20">
- <a href="./" id="sidebar-back-button" class="w-20 h-20 hidden">
- <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>
+ <div class="flex flex-col sm:flex-row">
+ <div id="sidebar" class="bg-sidebar flex
+ flex-row sticky w-dvw h-fit xs:w-[90dvw]
+ sm:left-0 sm:flex-col sm:fixed sm:w-fit
+ z-20 shadow-[0_0_1rem_black]">
+ <nav aria-label="Main navigation" class="text-[3rem] flex flex-row sm:flex-col gap-0 relative z-20">
+ <a onclick="return changeUrl('/../', true);" href="./" id="sidebar-back-button" class="themed-button themed-button-sidebar w-fit h-fit hidden" draggable="false">
+ <i class="fas fa-circle-left flex w-18 h-18 content-center text-center text-sidebar"></i>
</a>
- <a href="/{{ .Lang }}" id="sidebar-home-button" class="w-20 h-20 hidden">
- <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 onclick="return changeUrl('/{{ .Lang }}');" href="/{{ .Lang }}" id="sidebar-home-button" class="themed-button themed-button-sidebar w-fit h-fit hidden" draggable="false">
+ <i class="fas fa-home flex w-18 h-18 content-center text-center text-sidebar"></i>
</a>
- <a href="/{{ .Lang }}/blog" id="sidebar-blog-button" class="w-20 h-20 hidden">
- <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 onclick="return changeUrl('/{{ .Lang }}/blog');" href="/{{ .Lang }}/blog" id="sidebar-blog-button" class="themed-button themed-button-sidebar w-fit h-fit hidden" draggable="false">
+ <i class="fas fa-search flex w-18 h-18 content-center text-center text-sidebar"></i>
</a>
- <a href="/{{ .Lang }}/map" id="sidebar-map-button" class="w-20 h-20 hidden">
- <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 href="/{{ .Lang }}/map" id="sidebar-map-button" class="themed-button themed-button-sidebar w-fit h-fit hidden" draggable="false">
+ <i class="fas fa-map flex w-18 h-18 content-center text-center text-sidebar"></i>
</a>
- <i onclick="toggleThemeWheel();" id="sidebar-theme-button" class="fas fa-swatchbook flex w-20 h-20 content-center text-center text-sidebar hover:bg-background-dark cursor-pointer transition-colors duration-300 rounded-lg"></i>
- <a href="/{{ .Lang }}/user" id="sidebar-user-button" class="w-20 h-20 hidden">
- <i onclick="return changeUrl('/{{ .Lang }}/user');" class="fas fa-user flex w-full h-full content-center text-center text-sidebar hover:bg-background-dark transition-colors duration-300 rounded-lg"></i>
+ <div id="toolbar-theme-button" onclick="toggleThemeWheel();" class="themed-button themed-button-sidebar w-fit h-fit" draggable="false">
+ <i id="toolbar-theme-button-content" class="fas fa-swatchbook flex w-18 h-18 content-center text-center text-sidebar"></i>
+ </div>
+ <a onclick="return changeUrl('/{{ .Lang }}/user');" href="/{{ .Lang }}/user" id="sidebar-user-button" class="themed-button themed-button-sidebar w-fit h-fit hidden" draggable="false">
+ <i class="fas fa-user flex w-18 h-18 content-center text-center text-sidebar"></i>
</a>
- </div>
+ </nav>
<div class="theme-wheel" id="theme-wheel">
<div class="theme-icon" data-theme="olive"></div>
<div class="theme-icon" data-theme="lettuce"></div>
@@ -234,25 +254,25 @@
</script>
</div>
- <div class="bg-background-dark @container/main flex z-10 w-dvw xs:w-[90dvw] sm:w-[80dvw] md:w-[75dvw] lg:w-[70dvw] xl:w-[65dvw] 2xl:w-[60dvw] grow-0 h-[calc(100dvh-5rem)] [@media(max-height:32rem)]:h-dvh shadow-[0_0_1rem_black]">
+ <div class="bg-background-dark @container/main flex z-10 w-dvw xs:w-[90dvw] sm:w-[85dvw] md:w-[80dvw] lg:w-[75dvw] xl:w-[70dvw] 2xl:w-[60dvw] 3xl:w-[50dvw] grow-0 h-[calc(100dvh-5rem)] sm:h-dvh shadow-[0_0_1rem_black]">
<div class="bg-background-dark border-r-2 border-dashed border-main-hard"></div>
- <div class="max-h-100% flex flex-col grow bg-background-dark relative pt-4 ml-8 pr-4">
- <div id="general-page-header" class="max-xs:hidden [@media(max-height:32rem)]:hidden flex flex-col basis-8"
+ <div class="max-h-full max-w-full flex flex-col grow bg-background-dark relative pt-4 ml-8 pr-4">
+ <header id="general-page-header" class="max-xs:hidden [@media(max-height:32rem)]:hidden flex flex-col basis-8"
hx-get="/api/v1/general-page/header{{ if .QueryString }}?{{ .QueryString }}{{ end }}" hx-trigger="load" hx-target="this" hx-swap="innerHTML">
- </div>
+ </header>
<div id="general-page-header-trigger" hx-get="/api/v1/general-page/header{{ if .QueryString }}?{{ .QueryString }}{{ end }}" hx-trigger="popstate from:window" hx-target="#general-page-header" hx-swap="innerHTML"></div>
<hr class="max-xs:hidden [@media(max-height:32rem)]:hidden border-t-4 border-dotted border-main-hard mb-2">
- <div id="general-page-body" class="flex flex-col grow overflow-y-auto"
+ <main id="general-page-body" class="relative flex flex-col grow overflow-y-auto"
hx-get="/api/v1/general-page/body{{ if .QueryString }}?{{ .QueryString }}{{ end }}" hx-trigger="load" hx-target="this" hx-swap="innerHTML">
- </div>
+ </main>
<div id="general-page-body-trigger" hx-get="/api/v1/general-page/body{{ if .QueryString }}?{{ .QueryString }}{{ end }}" hx-trigger="popstate from:window" hx-target="#general-page-body" hx-swap="innerHTML"></div>
- <div id="general-page-footer" class="flex flex-row basis-4 my-1"
+ <footer id="general-page-footer" class="flex flex-row basis-4 my-1"
hx-get="/api/v1/general-page/footer{{ if .QueryString }}?{{ .QueryString }}{{ end }}" hx-trigger="load" hx-target="this" hx-swap="innerHTML">
- </div>
+ </footer>
<div id="general-page-footer-trigger" hx-get="/api/v1/general-page/footer{{ if .QueryString }}?{{ .QueryString }}{{ end }}" hx-trigger="popstate from:window" hx-target="#general-page-footer" hx-swap="innerHTML"></div>
<hr class="border-t-4 border-dotted border-main-hard mb-2">
@@ -267,7 +287,40 @@
<script src="https://f003.backblazeb2.com/file/sayana-static/libs/htmx/2.0.6/htmx.min.js"></script>
<script src="https://f003.backblazeb2.com/file/sayana-static/libs/leaflet/1.9.4/leaflet.js"></script>
<script src="https://f003.backblazeb2.com/file/sayana-static/libs/imagesloaded/5.0.0/imagesloaded.pkgd.min.js"></script>
- <script src="https://f003.backblazeb2.com/file/sayana-static/libs/masonry-layout/4.2.2/masonry.pkgd.min.js"></script>
+ <script src="https://f003.backblazeb2.com/file/sayana-static/libs/packery/3.0.0/dist/packery.pkgd.min.js"></script>
+
+ <script>
+ // Enable fitWidth-like attribute for Packery. Source: https://codepen.io/desandro/pen/kVmLYz
+ var __resetLayout = Packery.prototype._resetLayout;
+ Packery.prototype._resetLayout = function() {
+ __resetLayout.call( this );
+ var parentSize = getSize( this.element.parentNode );
+ var colW = this.columnWidth + this.gutter;
+ this.fitWidth = Math.floor( ( parentSize.innerWidth + this.gutter ) / colW ) * colW;
+ this.packer.width = this.fitWidth;
+ this.packer.height = Number.POSITIVE_INFINITY;
+ this.packer.reset();
+ };
+
+ Packery.prototype._getContainerSize = function() {
+ var emptyWidth = 0;
+ for ( var i=0, len = this.packer.spaces.length; i < len; i++ ) {
+ var space = this.packer.spaces[i];
+ if ( space.y === 0 && space.height === Number.POSITIVE_INFINITY ) {
+ emptyWidth += space.width;
+ }
+ }
+
+ return {
+ width: this.fitWidth - this.gutter - emptyWidth,
+ height: this.maxY - this.gutter
+ };
+ };
+
+ Packery.prototype.needsResizeLayout = function() {
+ return true;
+ };
+ </script>
<div id="general-page-bottom-embeds" class="flex"
hx-get="/api/v1/general-page/bottom-embeds{{ if .QueryString }}?{{ .QueryString }}{{ end }}" hx-trigger="load" hx-target="this" hx-swap="innerHTML">
@@ -276,7 +329,7 @@
<script>
const themeWheel = document.getElementById('theme-wheel');
- const themeButton = document.getElementById('sidebar-theme-button');
+ const themeButton = document.getElementById('toolbar-theme-button');
const themeIcons = document.querySelectorAll('.theme-icon');
const themeWheelRadius = convertRemToPixels(6);
@@ -392,7 +445,7 @@
themeWheel.addEventListener('mouseleave', hideThemeWheel);
document.addEventListener('click', (e) => {
- if (!themeWheel.contains(e.target) && e.target !== themeButton) {
+ if (!themeWheel.contains(e.target) && e.target !== themeButton && !e.target.classList.contains("toolbar-theme-button-content")) {
hideThemeWheel();
}
});
diff --git a/views/pages/blog-catalogue.html b/views/pages/blog-catalogue.html
index d209205..d2c74ae 100644
--- a/views/pages/blog-catalogue.html
+++ b/views/pages/blog-catalogue.html
@@ -1,61 +1,68 @@
{{ define "body" }}
<div class="flex flex-row ar-lt-0.8:flex-col text-base h-full">
- <form hx-get="/api/v1/blog-search" hx-vals='{"lang": "{{ .Lang }}"}' hx-target=".blog-cards" hx-swap="innerHTML"
- class="tags-list ar-gt-0.8:min-w-[10dvh] ar-gt-0.8:max-w-[20dvh] ar-gt-0.8:w-fit ar-lt-0.8:w-full ar-lt-0.8:max-h-[30%] flex shrink-0 flex-col ar-gt-0.8:mr-6 bg-background-light inset-shadow-[0_0_0.4rem_black]">
- <div class="flex flex-col overflow-y-auto">
- <fieldset>
- <legend class="font-bold w-full text-center">{{ .L.BlogSearch.TagsHeader }}</legend>
- <div class="flex flex-col ar-lt-0.8:grid grid-cols-3 xs:grid-cols-4 sm:grid-cols-5 grid-flow-row-dense">
- <div class="m-1">
- <label class="font-bold"><input type="checkbox" id="tagsAllCheckbox" onclick="selectAll();"> {{ .L.BlogSearch.ChooseAllTags }}</label>
+ <div class="relative flex shrink-0 ar-gt-0.8:min-w-[10dvh] ar-gt-0.8:max-w-[20dvh] ar-gt-0.8:w-fit ar-lt-0.8:w-full ar-lt-0.8:max-h-[30%] ar-gt-0.8:mr-6">
+ <div class="absolute w-full h-full inset-shadow-[0_0_0.4rem_black] pointer-events-none z-20"></div>
+ <form hx-get="/api/v1/blog-search" hx-vals='{"lang": "{{ .Lang }}"}' hx-target=".blog-cards" hx-swap="innerHTML"
+ class="tags-list relative flex flex-col w-full bg-background-light">
+ <div class="flex flex-col overflow-y-auto">
+ <fieldset>
+ <legend class="font-bold w-full text-center">{{ .L.BlogSearch.TagsHeader }}</legend>
+ <div class="flex flex-col ar-lt-0.8:grid grid-cols-3 xs:grid-cols-4 sm:grid-cols-5 grid-flow-row-dense">
+ <div class="m-1">
+ <label class="font-bold"><input type="checkbox" id="tagsAllCheckbox" onclick="selectAll();"> {{ .L.BlogSearch.ChooseAllTags }}</label>
+ </div>
+ {{- range .Tags }}
+ <div class="m-1">
+ <label><input type="checkbox" id="tag{{ .Name }}Checkbox" name="tags[]" value="{{ .Name }}" onclick="contextAll();" {{ if contains $.QueryTags .Name }}checked{{ end }}> {{ .Name }} <span class="text-secondary italic">{{ .Count }}</span></label>
+ </div>
+ {{- end }}
</div>
- {{- range .Tags }}
- <div class="m-1">
- <label><input type="checkbox" id="tag{{ .Name }}Checkbox" name="tags[]" value="{{ .Name }}" onclick="contextAll();" {{ if contains $.QueryTags .Name }}checked{{ end }}> {{ .Name }} <span class="text-secondary italic">{{ .Count }}</span></label>
+ </fieldset>
+ <fieldset class="mt-1">
+ <legend class="font-bold w-full text-center">{{ .L.BlogSearch.OrderByHeader }}</legend>
+ <div class="flex flex-col ar-lt-0.8:grid grid-cols-3 grid-rows-2 grid-flow-col">
+ <div class="m-1">
+ <label><input type="radio" id="sortTitleAsc" name="sort" value="titleAsc" {{ if eq .QuerySort "titleAsc" }}checked{{ end }}> {{ .L.BlogSearch.TitleOrdered }} <i class="fas fa-arrow-down-a-z"></i></label>
+ </div>
+ <div class="m-1">
+ <label><input type="radio" id="sortTitleDesc" name="sort" value="titleDesc" {{ if eq .QuerySort "titleDesc" }}checked{{ end }}> {{ .L.BlogSearch.TitleOrdered }} <i class="fas fa-arrow-down-z-a"></i></label>
+ </div>
+ <div class="m-1">
+ <label><input type="radio" id="sortActionDateAsc" name="sort" value="actionDateAsc" {{ if eq .QuerySort "actionDateAsc" }}checked{{ end }}> {{ .L.BlogSearch.ActionDateOrdered }} <i class="fas fa-arrow-down-1-9"></i></label>
+ </div>
+ <div class="m-1">
+ <label><input type="radio" id="sortActionDateDesc" name="sort" value="actionDateDesc" {{ if eq .QuerySort "actionDateDesc" }}checked{{ end }}> {{ .L.BlogSearch.ActionDateOrdered }} <i class="fas fa-arrow-down-9-1"></i></label>
+ </div>
+ <div class="m-1">
+ <label><input type="radio" id="sortPublicationDateAsc" name="sort" value="publicationDateAsc" {{ if eq .QuerySort "publicationDateAsc" }}checked{{ end }}> {{ .L.BlogSearch.PublicationDateOrdered }} <i class="fas fa-arrow-down-1-9"></i></label>
+ </div>
+ <div class="m-1">
+ <label><input type="radio" id="sortPublicationDateDesc" name="sort" value="publicationDateDesc" {{ if eq .QuerySort "publicationDateDesc" }}checked{{ end }}> {{ .L.BlogSearch.PublicationDateOrdered }} <i class="fas fa-arrow-down-9-1"></i></label>
+ </div>
</div>
- {{- end }}
- </div>
- </fieldset>
- <fieldset class="mt-1">
- <legend class="font-bold w-full text-center">{{ .L.BlogSearch.OrderByHeader }}</legend>
- <div class="flex flex-col ar-lt-0.8:grid grid-cols-3 grid-rows-2 grid-flow-col">
- <div class="m-1">
- <label><input type="radio" id="sortTitleAsc" name="sort" value="titleAsc" {{ if eq .QuerySort "titleAsc" }}checked{{ end }}> {{ .L.BlogSearch.TitleOrdered }} <i class="fas fa-arrow-down-a-z"></i></label>
- </div>
- <div class="m-1">
- <label><input type="radio" id="sortTitleDesc" name="sort" value="titleDesc" {{ if eq .QuerySort "titleDesc" }}checked{{ end }}> {{ .L.BlogSearch.TitleOrdered }} <i class="fas fa-arrow-down-z-a"></i></label>
- </div>
- <div class="m-1">
- <label><input type="radio" id="sortActionDateAsc" name="sort" value="actionDateAsc" {{ if eq .QuerySort "actionDateAsc" }}checked{{ end }}> {{ .L.BlogSearch.ActionDateOrdered }} <i class="fas fa-arrow-down-1-9"></i></label>
- </div>
- <div class="m-1">
- <label><input type="radio" id="sortActionDateDesc" name="sort" value="actionDateDesc" {{ if eq .QuerySort "actionDateDesc" }}checked{{ end }}> {{ .L.BlogSearch.ActionDateOrdered }} <i class="fas fa-arrow-down-9-1"></i></label>
- </div>
- <div class="m-1">
- <label><input type="radio" id="sortPublicationDateAsc" name="sort" value="publicationDateAsc" {{ if eq .QuerySort "publicationDateAsc" }}checked{{ end }}> {{ .L.BlogSearch.PublicationDateOrdered }} <i class="fas fa-arrow-down-1-9"></i></label>
- </div>
- <div class="m-1">
- <label><input type="radio" id="sortPublicationDateDesc" name="sort" value="publicationDateDesc" {{ if eq .QuerySort "publicationDateDesc" }}checked{{ end }}> {{ .L.BlogSearch.PublicationDateOrdered }} <i class="fas fa-arrow-down-9-1"></i></label>
- </div>
- </div>
- </fieldset>
- </div>
- <hr class="border-t-2 border-dotted border-main-hard my-0.5">
- <div class="flex flex-row bg-background-dark my-2 p-0.5 rounded-1 justify-items-center">
- <i onclick="defaultSearchParams(); cleanHrefParams();" class="fas fa-rotate-left flex-1 text-center text-2xl hover:bg-background-light cursor-pointer transition-colors duration-300"></i>
- <div class="w-1 bg-background-light grow-0"></div>
- <button class="flex-1" type="submit">
- <i onclick="setHrefParams();" class="fas fa-magnifying-glass text-center text-2xl hover:bg-background-light cursor-pointer transition-colors duration-300"></i>
- </button>
- </div>
- </form>
+ </fieldset>
+ </div>
+ <hr class="border-t-2 border-dotted border-main-hard my-0.5">
+ <div class="flex flex-row bg-background-dark my-2 p-0.5 rounded-1 justify-items-center">
+ <i onclick="defaultSearchParams(); cleanHrefParams();" class="fas fa-rotate-left flex-1 text-center text-2xl hover:bg-background-light cursor-pointer transition-colors duration-300"></i>
+ <div class="w-1 bg-background-light grow-0"></div>
+ <button class="flex-1" type="submit">
+ <i onclick="setHrefParams();" class="fas fa-magnifying-glass text-center text-2xl hover:bg-background-light cursor-pointer transition-colors duration-300"></i>
+ </button>
+ </div>
+ </form>
+ </div>
<div class="w-[0.5dvh] border-r-2 border-dotted border-main-hard bg-background-dark"></div>
- <div hx-get="/api/v1/blog-search" hx-vals='js:{lang: "{{ .Lang }}", tz: clientTimeZone}' hx-target="this" hx-swap="innerHTML" hx-trigger="load" hx-include=".tags-list"
- class="blog-cards grow flex flex-col overflow-y-auto bg-background-light inset-shadow-[0_0_0.4rem_black] p-6">
- Loading...
+ <div class="relative flex grow h-full">
+ <div class="absolute w-full h-full inset-0 inset-shadow-[0_0_0.4rem_black] pointer-events-none z-20"></div>
+ <div hx-get="/api/v1/blog-search" hx-vals='js:{lang: "{{ .Lang }}", tz: clientTimeZone}' hx-target="this" hx-swap="innerHTML" hx-trigger="load" hx-include=".tags-list"
+ class="blog-cards relative grow flex flex-col overflow-y-auto bg-background-light p-6">
+ Loading...
+ </div>
</div>
+
</div>
<script>
diff --git a/views/pages/blog-page.html b/views/pages/blog-page.html
index 7170ad8..3fc4526 100644
--- a/views/pages/blog-page.html
+++ b/views/pages/blog-page.html
@@ -1,9 +1,16 @@
{{ define "body" }}
-<div class="bg-background-light flex flex-col inset-shadow-[0_0_0.4rem_black] px-8 py-4 overflow-y-auto">
- <p class="max-xs:block [@media(max-height:32rem)]:block hidden font-andika text-2xl font-bold italic text-main-hard tracking-[.0125rem] mb-1">{{ .Title }}</p>
- <p class="max-xs:block [@media(max-height:32rem)]:block hidden grow text-lg font-andika text-secondary">{{ .L.Metadata.Published }}: {{ .PublishedDate }}</p>
- <p class="max-xs:block [@media(max-height:32rem)]:block hidden grow text-lg font-andika text-secondary">{{ .L.Metadata.Action }}: {{ .ActionDate }}</p>
- <hr class="max-xs:block [@media(max-height:32rem)]:block hidden border-t-2 border-dotted border-main-hard mt-1 mb-2 w-full ml-auto mr-auto">
+<div class="absolute w-full h-full inset-0 inset-shadow-[0_0_0.4rem_black] pointer-events-none z-20"></div>
+<article class="relative bg-background-light flex flex-col px-8 py-4 overflow-y-auto">
+ <h1 class="max-xs:block [@media(max-height:32rem)]:block hidden font-andika text-2xl font-bold italic text-main-hard tracking-[.0125rem] mb-1">{{ .Title }}</h1>
+ <p class="block grow text-lg font-andika text-secondary">
+ <b>{{ .L.Metadata.Published }}</b>:
+ <time datetime="{{ .PublishedDate }}" hx-get="/api/v1/tz" hx-vals='js:{timestamp: "{{ .PublishedDate }}", tz: clientTimeZone}' hx-target="this" hx-swap="innerHTML" hx-trigger="load">
+ {{ .PublishedDate }}
+ </time>
+ </p>
+ <p class="block grow text-lg font-andika text-secondary"><b>{{ .L.Metadata.Action }}</b>: {{ .ActionDate }}</p>
+ <p class="block grow text-md font-andika italic text-main-hard">{{ .ShortDescription }}</p>
+ <hr class="block border-t-2 border-dotted border-main-hard mt-1 mb-2 w-full ml-auto mr-auto">
{{ .ParsedMarkdown }}
{{- if .MapLocationX }}
<hr class="border-t-3 border-dotted border-main-hard mt-1 mb-2 w-[80%] ml-auto mr-auto">
@@ -14,9 +21,9 @@
function initLocationMap(id, x, y, relativeErrorMeters = 0) {
map = L.map(id).setView([x, y], 8);
- L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
- maxZoom: 18,
- attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
+ L.tileLayer('https://{s}.tile-cyclosm.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png', {
+ maxZoom: 20,
+ attribution: '<a href="https://github.com/cyclosm/cyclosm-cartocss-style/releases" title="CyclOSM - Open Bicycle render">CyclOSM</a> | Map data: &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
if (relativeErrorMeters != 0) {
@@ -53,9 +60,9 @@
});
</script>
{{- end }}
-</div>
+</article>
{{ end }}
-{{ define "footer" }}
+{{ define "header" }}
<div hx-get="/api/v1/like" hx-target="this" hx-swap="outerHTML" hx-trigger="load"></div>
{{ end }}
diff --git a/views/pages/global-map.html b/views/pages/global-map.html
index 306f442..604b52e 100644
--- a/views/pages/global-map.html
+++ b/views/pages/global-map.html
@@ -3,7 +3,13 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <meta name="description" content="{{ .L.GlobalMap.Description }}">
+ <meta property="og:title" content="{{ .L.GlobalMap.Header }}">
+ <meta property="og:description" content="{{ .L.GlobalMap.Description }}">
+ <meta property="og:url" content="{{ .CanonicalEndpoint }}/{{ .Lang }}/map">
+ <meta property="og:type" content="site">
<title>{{ .L.GlobalMap.Header }} // SAYA TODAY</title>
+ <link rel="canonical" href="{{ .CanonicalEndpoint }}/{{ .Lang }}/map">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css">
{{ block "header" . }}{{ end }}
<link href="/output.css" rel="stylesheet">
@@ -42,23 +48,25 @@
}
</script>
- <div id="sidebar" class="bg-sidebar block fixed shadow-[0_0_0.4rem_black] z-1001 w-[5rem] h-auto">
- <div class="text-[3rem] text-stroke-(--sidebar-stroke-color) text-stroke-[0.1dvw] flex flex-col gap-0 relative z-1001">
- <a href="./" class="w-[5rem] h-[5rem]">
- <i 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>
+ <div id="sidebar" class="bg-sidebar block fixed shadow-[0_0_0.4rem_black] z-1001 w-fit h-auto">
+ <div class="text-[3rem] flex flex-col gap-0 relative z-1001">
+ <a href="./" class="themed-button themed-button-sidebar w-fit h-fit" draggable="false">
+ <i class="fas fa-circle-left flex w-18 h-18 content-center text-center text-sidebar"></i>
</a>
- <a href="/{{ .Lang }}" class="w-[5rem] h-[5rem]">
- <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 href="/{{ .Lang }}" class="themed-button themed-button-sidebar w-fit h-fit" draggable="false">
+ <i class="fas fa-home flex w-18 h-18 content-center text-center text-sidebar"></i>
</a>
- <a href="/{{ .Lang }}/blog" class="w-[5rem] h-[5rem]">
- <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 href="/{{ .Lang }}/blog" class="themed-button themed-button-sidebar w-fit h-fit" draggable="false">
+ <i class="fas fa-search flex w-18 h-18 content-center text-center text-sidebar"></i>
</a>
- <a href="/{{ .Lang }}/map" class="w-[5rem] h-[5rem]">
- <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 href="/{{ .Lang }}/map" class="themed-button themed-button-sidebar w-fit h-fit" draggable="false">
+ <i class="fas fa-map flex w-18 h-18 content-center text-center text-sidebar"></i>
</a>
- <i onclick="toggleThemeWheel();" id="theme-button" class="fas fa-swatchbook flex w-[5rem] h-[5rem] content-center text-center text-sidebar hover:bg-background-dark cursor-pointer transition-colors duration-300 rounded-lg"></i>
- <a href="/{{ .Lang }}/user" id="sidebar-user-button" class="w-[5rem] h-[5rem]">
- <i onclick="return changeUrl('/{{ .Lang }}/user');" class="fas fa-user flex w-full h-full content-center text-center text-sidebar hover:bg-background-dark transition-colors duration-300 rounded-lg"></i>
+ <div id="toolbar-theme-button" onclick="toggleThemeWheel();" class="themed-button themed-button-sidebar w-fit h-fit" draggable="false">
+ <i id="toolbar-theme-button-content" class="fas fa-swatchbook flex w-18 h-18 content-center text-center text-sidebar"></i>
+ </div>
+ <a href="/{{ .Lang }}/user" id="sidebar-user-button" class="themed-button themed-button-sidebar w-fit h-fit" draggable="false">
+ <i onclick="return changeUrl('/{{ .Lang }}/user');" class="fas fa-user flex w-18 h-18 content-center text-center text-sidebar"></i>
</a>
</div>
<div class="theme-wheel" id="theme-wheel">
@@ -79,7 +87,7 @@
<script>
const themeWheel = document.getElementById('theme-wheel');
- const themeButton = document.getElementById('theme-button');
+ const themeButton = document.getElementById('toolbar-theme-button');
const themeIcons = document.querySelectorAll('.theme-icon');
const themeWheelRadius = convertRemToPixels(6);
@@ -195,7 +203,7 @@
themeWheel.addEventListener('mouseleave', hideThemeWheel);
document.addEventListener('click', (e) => {
- if (!themeWheel.contains(e.target) && e.target !== themeButton) {
+ if (!themeWheel.contains(e.target) && e.target !== themeButton && !e.target.classList.contains("toolbar-theme-button-content")) {
hideThemeWheel();
}
});
@@ -228,9 +236,9 @@
function initLocationMap() {
map = L.map('map-container').setView([{{ .MapLocationLat }}, {{ .MapLocationLong }}], 4);
- L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
- maxZoom: 18,
- attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
+ L.tileLayer('https://{s}.tile-cyclosm.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png', {
+ maxZoom: 20,
+ attribution: '<a href="https://github.com/cyclosm/cyclosm-cartocss-style/releases" title="CyclOSM - Open Bicycle render">CyclOSM</a> | Map data: &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
zoomControl: false
}).addTo(map);
@@ -241,35 +249,32 @@
map.addLayer(markers);
}
- function stringToColor(str) {
+ function markerToHsl(str, newCoef) {
let hash = 0;
- for (let i = 0; i < str.length; i++) {
+ for (let i = 0; i < str.length / 2; i++) {
hash = str.charCodeAt(i) + ((hash << 5) - hash);
+ hash = str.charCodeAt(str.length - i - 1) + ((hash << 5) - hash);
+ hash %= 360;
}
- let color = '#';
- for (let i = 0; i < 3; i++) {
- const value = (hash >> (i * 8)) & 0xFF;
- color += ('00' + value.toString(16)).substr(-2);
- }
-
- return color;
+ return [hash, (20 + newCoef * 80).toFixed(0), (20 + newCoef * 75).toFixed(0)];
}
- function mapAddMarker(x, y, relativeErrorMeters = 0, title = "", link = "", thumbnail = "") {
- const titleColor = stringToColor(title);
+ function mapAddMarker(x, y, relativeErrorMeters = 0, title = "", link = "", thumbnail = "", newCoef = 1) {
+ const [h, s, l] = markerToHsl(title, newCoef);
+ const color = `hsl(${h} ${s}% ${l}%)`;
if (relativeErrorMeters != 0) {
var circle = L.circle([x, y], {
- color: titleColor,
- fillColor: titleColor,
+ color: color,
+ fillColor: color,
fillOpacity: 0.15,
radius: relativeErrorMeters
}).addTo(map);
}
var marker = L.marker([x, y], {
- icon: createCustomIcon(titleColor),
+ icon: createCustomIcon(color),
title: title,
}).bindPopup(`
<div class="flex flex-row justify-center justify-items-center">
@@ -283,7 +288,7 @@
document.addEventListener('DOMContentLoaded', () => {
initLocationMap();
{{- range .MapMarkers }}
- mapAddMarker({{ .Lat }}, {{ .Long }}, {{ .AccuracyMeters }}, {{ .Title }}, {{ .PageLink }}, {{ .Thumbnail }});
+ mapAddMarker({{ .Lat }}, {{ .Long }}, {{ .AccuracyMeters }}, {{ .Title }}, {{ .PageLink }}, {{ .Thumbnail }}, {{ fdiv .Index (len $.MapMarkers) }});
{{- end }}
});
diff --git a/views/pages/home-page.html b/views/pages/home-page.html
index 11d0f7b..6d397fa 100644
--- a/views/pages/home-page.html
+++ b/views/pages/home-page.html
@@ -1,20 +1,21 @@
{{ define "body" }}
-<div class="bg-background-light flex flex-row ar-lt-0.6:flex-col w-full h-full inset-shadow-[0_0_0.4rem_black] overflow-y-auto text-base/[2] tracking-wide">
+<div class="absolute w-full h-full inset-0 inset-shadow-[0_0_0.4rem_black] pointer-events-none z-20"></div>
+<div class="relative bg-background-light flex flex-row ar-lt-0.6:flex-col w-full h-full overflow-y-auto text-base/loose tracking-wide z-10">
<div class="ar-gt-0.6:flex-3/5 justify-center content-start p-8">
<div class="flex flex-col justify-start items-start bg-background-dark mb-8 shadow-[0.4rem_0.4rem_0.4rem_black]">
- <p class="text-3xl/[2] sm:text-4xl/[2] lg:text-5xl/[2] tracking-widest uppercase w-full font-andika italic text-left
+ <p class="text-3xl/loose sm:text-4xl/loose lg:text-5xl/loose tracking-widest uppercase w-full font-andika italic text-left
border-l-4 border-solid border-(--background-dark-color)
- bg-gradient-to-r from-(--background-dark-color) to-(--background-light-color)">{{ .L.HomePage.Hymn1 }}</p>
+ bg-linear-to-r from-(--background-dark-color) to-(--background-light-color)">{{ .L.HomePage.Hymn1 }}</p>
<hr class="w-full border-t-2 border-dotted border-main-hard mb-1">
- <p class="text-xl/[2] sm:text-2xl/[2] lg:text-3xl/[2] -indent-8 ml-12 p-1">{{ .L.HomePage.Hymn2 }}</p>
- <p class="text-xl/[2] sm:text-2xl/[2] lg:text-3xl/[2] -indent-8 ml-12 p-1">{{ .L.HomePage.Hymn3 }}</p>
- <p class="text-xl/[2] sm:text-2xl/[2] lg:text-3xl/[2] -indent-8 ml-12 p-1">{{ .L.HomePage.Hymn4 }}</p>
+ <p class="text-xl/loose sm:text-2xl/loose lg:text-3xl/loose -indent-8 ml-12 p-1">{{ .L.HomePage.Hymn2 }}</p>
+ <p class="text-xl/loose sm:text-2xl/loose lg:text-3xl/loose -indent-8 ml-12 p-1">{{ .L.HomePage.Hymn3 }}</p>
+ <p class="text-xl/loose sm:text-2xl/loose lg:text-3xl/loose -indent-8 ml-12 p-1">{{ .L.HomePage.Hymn4 }}</p>
</div>
<div class="flex flex-col justify-center items-center">
<p class="text-xl sm:text-2xl lg:text-3xl p-1 w-full font-andika italic text-left
border-l-1.5 border-solid border-(--background-dark-color)
- bg-gradient-to-r from-(--background-dark-color) to-(--background-light-color)">{{ .L.HomePage.DidYouKnowThat }}</p>
+ bg-linear-to-r from-(--background-dark-color) to-(--background-light-color)">{{ .L.HomePage.DidYouKnowThat }}</p>
<hr class="w-full border-t-2 border-dotted border-main-hard mb-1">
<ul class="w-full text-left list-[circle]">
<li class="ml-4 mb-1">{{ index .FunFacts 0 }}</li>
@@ -28,7 +29,7 @@
<div class="flex flex-col justify-center items-start mb-4">
<p class="text-xl sm:text-2xl lg:text-3xl p-1 w-full font-andika italic text-left
border-l-1.5 border-solid border-(--background-dark-color)
- bg-gradient-to-r from-(--background-dark-color) to-(--background-light-color)">{{ .L.HomePage.Contacts }}</p>
+ bg-linear-to-r from-(--background-dark-color) to-(--background-light-color)">{{ .L.HomePage.Contacts }}</p>
<hr class="w-full border-t-2 border-dotted border-main-hard mb-1">
<a href="https://t.me/EarlInisMona">
<i class="fa-brands fa-telegram w-4 h-4 mr-1"></i>
@@ -103,7 +104,7 @@
<div class="flex flex-col justify-center items-center">
<p class="text-xl sm:text-2xl lg:text-3xl p-1 w-full font-andika italic text-left
border-l-1.5 border-solid border-(--background-dark-color)
- bg-gradient-to-r from-(--background-dark-color) to-(--background-light-color)">{{ .L.HomePage.SidebarDescription }}</p>
+ bg-linear-to-r from-(--background-dark-color) to-(--background-light-color)">{{ .L.HomePage.SidebarDescription }}</p>
<hr class="w-full border-t-2 border-dotted border-main-hard mb-1">
<div class="w-full grid grid-cols-[1fr_4fr] content-center items-center
[&>*:nth-child(4n+2)]:bg-(--background-medium-color)/50 [&>*:nth-child(4n+3)]:bg-(--background-medium-color)/50" style="container-type: inline-size;">
diff --git a/views/pages/language-pick.html b/views/pages/language-pick.html
index 5a9d229..775c18e 100644
--- a/views/pages/language-pick.html
+++ b/views/pages/language-pick.html
@@ -1,5 +1,5 @@
{{ define "body" }}
-<div class="flex flex-col justify-center text-3xl h-[100%]">
+<div class="flex flex-col justify-center text-3xl h-full">
{{- range .AvailableLanguages }}
<hr class="border-t-2 border-dotted border-main-hard">
<div class="nth-[2n+1_of_div]:bg-(--background-medium-color)/50 nth-[2n_of_div]:bg-(--background-light-color)/50 p-2.5 flex flex-row justify-center justify-items-center">
diff --git a/views/pages/robots.txt b/views/pages/robots.txt
new file mode 100644
index 0000000..1e5bebb
--- /dev/null
+++ b/views/pages/robots.txt
@@ -0,0 +1,5 @@
+User-agent: *
+Allow: /
+Disallow: /api/
+
+Sitemap: {{ .CanonicalEndpoint }}/sitemap.xml \ No newline at end of file
diff --git a/views/pages/sitemap.xml b/views/pages/sitemap.xml
new file mode 100644
index 0000000..1474a56
--- /dev/null
+++ b/views/pages/sitemap.xml
@@ -0,0 +1,10 @@
+<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
+ {{- range .URLs }}
+ <url>
+ <loc>{{ $.CanonicalEndpoint }}{{ .Loc }}</loc>
+ <lastmod>{{ .LastModified.UTC.Format "2006-01-02T15:04:05Z" }}</lastmod>
+ <changefreq>{{ .ChangeFreq }}</changefreq>
+ <priority>{{ printf "%.1f" .Priority }}</priority>
+ </url>
+ {{- end }}
+</urlset>
diff --git a/views/pages/unsubscribe-page.html b/views/pages/unsubscribe-page.html
index 3876818..c1db9d6 100644
--- a/views/pages/unsubscribe-page.html
+++ b/views/pages/unsubscribe-page.html
@@ -3,6 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <meta name="robots" content="noindex,nofollow">
<title>{{ .L.UnsubscribePage.Header }} // SAYA TODAY</title>
<style>
html {
diff --git a/views/pages/user-page.html b/views/pages/user-page.html
index 7d39825..fda7e66 100644
--- a/views/pages/user-page.html
+++ b/views/pages/user-page.html
@@ -1,5 +1,6 @@
{{ define "body" }}
-<div class="bg-background-light flex flex-col inset-shadow-[0_0_0.4rem_black] px-8 py-4">
+<div class="absolute w-full h-full inset-0 inset-shadow-[0_0_0.4rem_black] pointer-events-none z-20"></div>
+<div class="relative bg-background-light flex flex-col px-8 py-4">
<form id="email-form" class="w-full mb-2 flex flex-col relative crossable"
hx-get="/api/v1/email/is-in-verification" hx-target="#email-message" hx-swap="outerHTML" hx-trigger="load" hx-indicator="this">
<div class="flex flex-row w-full mb-4 z-21">
diff --git a/views/partials/blog-page-like-button.html b/views/partials/blog-page-like-button.html
index 8d555da..8da52a6 100644
--- a/views/partials/blog-page-like-button.html
+++ b/views/partials/blog-page-like-button.html
@@ -1,6 +1,5 @@
-<button
- hx-put="/api/v1/like" hx-vals='{"like": {{ not .Liked }}}' hx-target="this" hx-swap="outerHTML" hx-trigger="click"
- class="text-sm/[0.9] shrink-0 font-andika text-left px-1 py-0.5 {{ if .Liked }}bg-main-soft hover:bg-main-medium text-background-dark border-inset{{ else }}bg-main-hard hover:bg-main-medium text-background-light border-outset{{ end }} cursor-pointer border-2 border-background-dark">
- <i class="fas fa-thumbs-up w-3 h-3"></i>
- <span class="italic ml-0.5 text-background-light">({{ .LikedCount }})</span>
+<button hx-put="/api/v1/like" hx-vals='{"like": {{ not .Liked }}}' hx-target="this" hx-swap="outerHTML" hx-trigger="click"
+ class="themed-button themed-button-like flex flex-col shrink-0 w-fit h-fit mr-2 my-auto{{ if .Liked }} active{{ end }}">
+ <i class="fas fa-thumbs-up w-8 h-fit py-0.5 content-center text-center"></i>
+ <div class="h-fit px-0.5 content-center bg-(--background-medium-color) text-(--main-hard-color)">{{ .LikedCount }}</div>
</button> \ No newline at end of file
diff --git a/views/partials/general-page-header.html b/views/partials/general-page-header.html
index 90180de..e019d3b 100644
--- a/views/partials/general-page-header.html
+++ b/views/partials/general-page-header.html
@@ -1,7 +1,5 @@
<title>{{ .Title }} // SAYA TODAY</title>
-<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">
- <p class="text-4xl font-andika font-light italic text-shadow-[0_2px_2px_var(--main-soft-color)] text-left mt-auto">{{ .Title }}</p>
- <p id="published-date" class="grow text-2xl font-andika italic text-secondary text-right mt-auto">{{ .PublishedDate }}</p>
-</div>
-{{ block "header" . }}{{ end }}
+<div class="flex flex-row mb-2">
+ {{ block "header" . }}{{ end }}
+ <p class="text-4xl font-andika font-light italic text-shadow-[0_2px_2px_var(--main-soft-color)] text-left my-auto">{{ .Title }}</p>
+</div> \ No newline at end of file