diff options
Diffstat (limited to 'views')
| -rw-r--r-- | views/index.html | 2 | ||||
| -rw-r--r-- | views/layouts/general-page.html | 79 | ||||
| -rw-r--r-- | views/pages/blog-catalogue.html | 47 | ||||
| -rw-r--r-- | views/pages/blog-page.html | 122 | ||||
| -rw-r--r-- | views/pages/global-map.html | 18 | ||||
| -rw-r--r-- | views/pages/home-page.html | 99 | ||||
| -rw-r--r-- | views/partials/blog-page-like-button.html | 3 | ||||
| -rw-r--r-- | views/partials/catalogue-blog-cards.html | 5 | ||||
| -rw-r--r-- | views/partials/general-page-body.html | 2 | ||||
| -rw-r--r-- | views/partials/general-page-bottom-embeds.html | 1 | ||||
| -rw-r--r-- | views/partials/general-page-footer.html | 7 | ||||
| -rw-r--r-- | views/partials/general-page-header.html | 8 | ||||
| -rw-r--r-- | views/partials/general-page-top-embeds.html | 1 |
13 files changed, 269 insertions, 125 deletions
diff --git a/views/index.html b/views/index.html index 2b8c937..b52df94 100644 --- a/views/index.html +++ b/views/index.html @@ -106,7 +106,7 @@ <p class="font-patua mx-auto text-[2.5vmax] mt-[0.8vmin] mb-[0.8vmin]">saya.today</p> <div class="menu-inner-body grow bg-background-light flex flex-adaptive mx-auto opacity-100"> {{- range .AvailableLanguages }} - <img onclick="location.href='/{{ .Name }}/blog';" class="object-scale-down cursor-pointer flex-1 rounded-[20%] language-icon mx-auto my-auto relative" src="{{ .Flag }}" alt="{{ .Alt }}"> + <img onclick="location.href='/{{ .Name }}';" class="object-scale-down cursor-pointer flex-1 rounded-[20%] language-icon mx-auto my-auto relative" src="{{ .Flag }}" alt="{{ .Alt }}"> {{- end }} </div> <p class="font-spectral mx-auto text-[1.5vmax] text-secondary mt-[0.8vmin] mb-[0.8vmin]">Choose your language</p> diff --git a/views/layouts/general-page.html b/views/layouts/general-page.html index a7cf66e..60608f4 100644 --- a/views/layouts/general-page.html +++ b/views/layouts/general-page.html @@ -3,16 +3,28 @@ <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>SAYA TODAY // {{ .Title }}</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css"> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Spectral:ital,wght@0,200;0,300;0,400;0,500;0,600;0,700;0,800;1,200;1,300;1,400;1,500;1,600;1,700;1,800&family=Patua+One&display=swap" rel="stylesheet"> - {{ block "top-embeds" . }}{{ end }} + <link rel="stylesheet" href="https://f003.backblazeb2.com/file/sayana-static/libs/lightgallery/2.8.3/css/lightgallery.min.css"> + <link rel="stylesheet" href="https://f003.backblazeb2.com/file/sayana-static/libs/lightgallery/2.8.3/css/lg-zoom.min.css"> + <link rel="stylesheet" href="https://f003.backblazeb2.com/file/sayana-static/libs/lightgallery/2.8.3/css/lg-thumbnail.min.css"> + <link rel="stylesheet" href="https://f003.backblazeb2.com/file/sayana-static/libs/leaflet/1.9.4/leaflet.css"> <link href="/output.css" rel="stylesheet"> </head> -<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"> +<body data-theme="ram" class="font-spectral text-main-dark overflow-hidden bg-interlocked-hexagons h-screen flex flex-row ar-lt-1.1:flex-col"> + + <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()}`); + window.dispatchEvent(new Event('popstate')); + }; + </script> <script> function sfc32(a, b, c, d) { @@ -140,19 +152,24 @@ switchTheme(savedTheme); </script> + <div id="general-page-top-embeds" class="flex" + hx-get="/api/v1/general-page/top-embeds{{ if .QueryString }}?{{ .QueryString }}{{ end }}" hx-trigger="load" hx-target="this" hx-swap="innerHTML"> + </div> + <div id="general-page-top-embeds-trigger" hx-get="/api/v1/general-page/top-embeds{{ if .QueryString }}?{{ .QueryString }}{{ end }}" hx-trigger="popstate from:window" hx-target="#general-page-top-embeds" hx-swap="innerHTML"></div> + <script> const clientTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone; </script> - <div id="sidebar" class="bg-sidebar flex sticky flex-col ar-gt-0.8:items-center shadow-2xl z-20 w-[5vw] ar-lt-0.8:w-[90vw] ar-lt-0.4:w-[100vw] h-screen ar-lt-0.8:h-[8vh] ar-lt-0.8:ml-[5vw] ar-lt-0.4:ml-0"> - <div class="logo-custom ar-lt-0.8:hidden text-sidebar font-patua font-extrabold text-center relative z-20"> + <div id="sidebar" class="bg-sidebar flex sticky flex-col ar-gt-1.1:items-center shadow-2xl z-20 w-[5vw] ar-lt-1.1:w-[90vw] ar-lt-0.4:w-[100vw] h-screen ar-lt-1.1:h-[8vh] ar-lt-1.1:ml-[5vw] ar-lt-0.4:ml-0"> + <div class="logo-custom ar-lt-1.1:hidden text-sidebar font-patua font-extrabold text-center relative z-20"> saya.today </div> - <div class="text-[3vw] ar-lt-0.8:text-[5vh] 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='/';" class="fas fa-home w-[5vw] ar-lt-0.8:w-[8vh] h-[5vw] ar-lt-0.8:h-[8vh] 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-[5vw] ar-lt-0.8:w-[8vh] h-[5vw] ar-lt-0.8:h-[8vh] 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-[5vw] ar-lt-0.8:w-[8vh] h-[5vw] ar-lt-0.8:h-[8vh] 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-[5vw] ar-lt-0.8:w-[8vh] h-[5vw] ar-lt-0.8:h-[8vh] content-center text-center text-sidebar hover:bg-background-dark cursor-pointer transition-colors duration-300 flex rounded-lg"></i> + <div class="text-[3vw] ar-lt-1.1:text-[5vh] text-stroke-(--sidebar-stroke-color) text-stroke-[0.1vw] flex flex-col ar-lt-1.1:flex-row gap-0 relative z-20"> + <i onclick="changeUrl('/{{ .Lang }}');" class="fas fa-home w-[5vw] ar-lt-1.1:w-[8vh] h-[5vw] ar-lt-1.1:h-[8vh] content-center text-center text-sidebar hover:bg-background-dark cursor-pointer transition-colors duration-300 flex rounded-lg"></i> + <i onclick="changeUrl('/{{ .Lang }}/blog');" class="fas fa-search w-[5vw] ar-lt-1.1:w-[8vh] h-[5vw] ar-lt-1.1:h-[8vh] 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-[5vw] ar-lt-1.1:w-[8vh] h-[5vw] ar-lt-1.1:h-[8vh] 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-[5vw] ar-lt-1.1:w-[8vh] h-[5vw] ar-lt-1.1:h-[8vh] content-center text-center text-sidebar hover:bg-background-dark cursor-pointer transition-colors duration-300 flex rounded-lg"></i> </div> <div class="theme-wheel" id="theme-wheel"> <div class="theme-icon" data-theme="olive"></div> @@ -162,31 +179,26 @@ </div> </div> - <div class="bg-background-dark flex z-10 ar-lt-0.8:w-[90vw] ar-lt-0.4:w-[100vw] h-screen ar-lt-0.8:ml-[5vw] ar-lt-0.4:ml-0"> + <div class="bg-background-dark flex z-10 ar-lt-1.1:w-[90vw] ar-lt-0.4:w-[100vw] h-screen ar-lt-1.1:ml-[5vw] ar-lt-0.4:ml-0"> <div class="pl-[0.5vw] bg-background-dark border-r-[0.4vmin] border-dashed border-main-dark"></div> - <div class="ar-gt-0.8:min-w-fit ar-gt-0.8:max-w-[100vh] flex flex-col bg-background-dark relative pt-[1.6vmin] ml-[1.6vmin] pr-[1.6vmin]"> - <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-[0.4vmin]"> - <i onclick="location.pathname += location.pathname.endsWith('/') ? '../' : '/../';" class="fas fa-circle-left hover:bg-main-dark hover:bg-opacity-10 cursor-pointer transition-colors duration-300 rounded-md text-[2vmax] mt-auto mb-auto px-[0.8vmin]"></i> - <p class="text-[2vmax] font-spectral italic font-extrabold select-none mt-auto pl-[0.8vmin] pr-[1.2vmin]">//</p> - <p class="text-[2vmax] font-spectral italic text-left mt-auto">{{ .Title }}</p> - <p id="published-date" class="grow text-[1.5vmax] font-spectral text-secondary text-right mt-auto">{{ .PublishedDate }}</p> + <div class="ar-gt-1.1:w-[100vh] flex flex-col bg-background-dark relative pt-[1.6vmin] ml-[1.6vmin] pr-[1.6vmin]"> + <div id="general-page-header" class="flex flex-col" + hx-get="/api/v1/general-page/header{{ if .QueryString }}?{{ .QueryString }}{{ end }}" hx-trigger="load" hx-target="this" hx-swap="innerHTML"> </div> - {{ block "header" . }}{{ end }} + <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="border-t-4 border-dotted border-main-dark mb-[0.8vmin]"> - {{ block "body" . }}{{ end }} + <div id="general-page-body" class="flex flex-col max-h-[calc(100%-7vmax)] ar-lt-1.1:max-h-[calc(100%-25vh)] grow" + hx-get="/api/v1/general-page/body{{ if .QueryString }}?{{ .QueryString }}{{ end }}" hx-trigger="load" hx-target="this" hx-swap="innerHTML"> + </div> + <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 class="flex flex-row mt-[0.8vmin] mb-[0.4vmin]"> - {{ block "footer" . }}{{ end }} - <p class="grow content-center text-[1vmax]/[1] font-spectral italic text-right text-secondary mr-2"> - All the photos on <a href="https://saya.today/">saya.today</a> are licensed under <a href="https://creativecommons.org/licenses/by-sa/4.0/">CC BY-SA 4.0</a> by <a href="https://t.me/EarlInisMona">Saya Andy</a> © {{ .PublishedYear }} - </p> - <img class="max-w-[1vmax] max-h-[1vmax] self-center" src="https://mirrors.creativecommons.org/presskit/icons/cc.svg" alt="CC"> - <img class="max-w-[1vmax] max-h-[1vmax] self-center" src="https://mirrors.creativecommons.org/presskit/icons/by.svg" alt="BY"> - <img class="max-w-[1vmax] max-h-[1vmax] self-center" src="https://mirrors.creativecommons.org/presskit/icons/sa.svg" alt="SA"> + <div id="general-page-footer" class="flex flex-row mt-[0.8vmin] mb-[0.4vmin]" + hx-get="/api/v1/general-page/footer{{ if .QueryString }}?{{ .QueryString }}{{ end }}" hx-trigger="load" hx-target="this" hx-swap="innerHTML"> </div> + <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-dark mb-[0.8vmin]"> </div> @@ -195,6 +207,15 @@ </div> <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/lightgallery/2.8.3/lightgallery.min.js"></script> + <script src="https://f003.backblazeb2.com/file/sayana-static/libs/lightgallery/2.8.3/plugins/lg-zoom.min.js"></script> + <script src="https://f003.backblazeb2.com/file/sayana-static/libs/lightgallery/2.8.3/plugins/lg-thumbnail.min.js"></script> + <script src="https://f003.backblazeb2.com/file/sayana-static/libs/leaflet/1.9.4/leaflet.js"></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"> + </div> + <div id="general-page-bottom-embeds-trigger" hx-get="/api/v1/general-page/bottom-embeds{{ if .QueryString }}?{{ .QueryString }}{{ end }}" hx-trigger="popstate from:window" hx-target="#general-page-bottom-embeds" hx-swap="innerHTML"></div> <script> const themeWheel = document.getElementById('theme-wheel'); @@ -315,7 +336,5 @@ }); </script> - {{ block "bottom-embeds" . }}{{ end }} - </body> </html> diff --git a/views/pages/blog-catalogue.html b/views/pages/blog-catalogue.html index 1d0a2de..eccafd6 100644 --- a/views/pages/blog-catalogue.html +++ b/views/pages/blog-catalogue.html @@ -1,11 +1,11 @@ {{ define "body" }} -<div class="flex flex-row ar-lt-0.8:flex-col max-h-[calc(100%-7vmax)] ar-lt-0.8:max-h-[calc(100%-25vh)] flex-1 text-[1vmax]"> +<div class="flex flex-row ar-lt-1.1:flex-col text-[1vmax] h-[100%]"> <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-[10vh] ar-gt-0.8:max-w-[20vh] ar-gt-0.8:w-fit ar-lt-0.8:w-[100%] ar-lt-0.8:max-h-[25%] flex shrink-0 flex-col ar-gt-0.8:mr-[1.2vmin]"> + class="tags-list ar-gt-1.1:min-w-[10vh] ar-gt-1.1:max-w-[20vh] ar-gt-1.1:w-fit ar-lt-1.1:w-[100%] ar-lt-1.1:max-h-[25%] flex shrink-0 flex-col ar-gt-1.1:mr-[1.2vmin]"> <div class="flex flex-col overflow-y-auto"> <fieldset> <legend class="font-bold w-[100%] text-center">{{ .L.BlogSearch.TagsHeader }}</legend> - <div class="flex flex-col ar-lt-0.8:grid grid-cols-5 grid-flow-row-dense"> + <div class="flex flex-col ar-lt-1.1:grid grid-cols-5 grid-flow-row-dense"> <div class="m-[0.4vmin]"> <label class="font-bold"><input type="checkbox" id="tagsAllCheckbox" onclick="selectAll();"> {{ .L.BlogSearch.ChooseAllTags }}</label> </div> @@ -18,7 +18,7 @@ </fieldset> <fieldset class="mt-[0.8vmin]"> <legend class="font-bold w-[100%] 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="flex flex-col ar-lt-1.1:grid grid-cols-3 grid-rows-2 grid-flow-col"> <div class="m-[0.4vmin]"> <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> @@ -57,9 +57,7 @@ Loading... </div> </div> -{{ end }} -{{ define "bottom-embeds" }} <script> function selectAll() { const tagsContainers = document.querySelectorAll('form.tags-list'); @@ -100,6 +98,7 @@ function cleanHrefParams() { const url = new URL(window.location.href); url.search = ''; + window.history.pushState({}, '', url.toString()); } @@ -139,23 +138,27 @@ window.history.pushState({}, '', url.toString()); } - document.addEventListener('DOMContentLoaded', contextAll); -</script> + 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') { + contextAll(); -<script> - const tagsContainers = document.querySelectorAll('form.tags-list'); - tagsContainers.forEach(tagsContainer => { - const checkboxes = tagsContainer.querySelectorAll('input[type="checkbox"]'); - anyChecked = false; - checkboxes.forEach(checkbox => { - anyChecked = checkbox.checked ? true : anyChecked; - }); - if (!anyChecked) { - const selectAllCheckbox = tagsContainer.querySelector('#tagsAllCheckbox'); - selectAllCheckbox.checked = true; - selectAll(); + const tagsContainers = document.querySelectorAll('form.tags-list'); + tagsContainers.forEach(tagsContainer => { + const checkboxes = tagsContainer.querySelectorAll('input[type="checkbox"]'); + anyChecked = false; + checkboxes.forEach(checkbox => { + anyChecked = checkbox.checked ? true : anyChecked; + }); + if (!anyChecked) { + const selectAllCheckbox = tagsContainer.querySelector('#tagsAllCheckbox'); + selectAllCheckbox.checked = true; + selectAll(); + } + }); } - }); + }, {once: true}); </script> - {{ end }} diff --git a/views/pages/blog-page.html b/views/pages/blog-page.html index 65ee31d..863b417 100644 --- a/views/pages/blog-page.html +++ b/views/pages/blog-page.html @@ -1,30 +1,64 @@ {{ define "top-embeds" }} -<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/lightgallery/2.8.3/css/lightgallery.min.css"> -<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/lightgallery/2.8.3/css/lg-zoom.min.css"> -<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/lightgallery/2.8.3/css/lg-thumbnail.min.css"> -{{- if .MapLocationX }} -<link rel="stylesheet" href="https://f003.backblazeb2.com/file/sayana-static/libs/leaflet/1.9.4/leaflet.css"> -{{- end }} - -<style> - .map-container .leaflet-container { - width: 100% !important; - height: 100% !important; - } -</style> - <script> - const galleryMap = new Map(); + 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 grow overflow-y-auto inset-shadow p-[2.4vmin] max-h-[calc(100%-7vmax)] ar-lt-0.8:max-h-[calc(100%-25vh)]"> +<div class="bg-background-light flex flex-col inset-shadow p-[2.4vmin] overflow-y-auto"> {{ .ParsedMarkdown }} {{- if .MapLocationX }} <hr class="border-t-4 border-dotted border-main-dark mt-[0.8vmin] mb-[0.8vmin] w-[80%] ml-auto mr-auto"> - <div id="map-container" class="relative p-[0.8vmin] flex-none ml-auto mr-auto w-[60%] ar-lt-0.8:w-[80%] h-[40vh] ar-lt-0.8:h-[30vh]"></div> + <div id="map-container" class="relative p-[0.8vmin] flex-none ml-auto mr-auto w-[60%] ar-lt-1.1:w-[80%] h-[40vh] ar-lt-1.1:h-[30vh]"></div> <hr class="border-t-4 border-dotted border-main-dark mt-[0.8vmin] mb-[0.8vmin] w-[80%] ml-auto mr-auto"> + + <script> + 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: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>' + }).addTo(map); + + if (relativeErrorMeters != 0) { + var circle = L.circle([x, y], { + color: '#8a9d8a', + fillColor: '#8a9d8a', + fillOpacity: 0.15, + radius: relativeErrorMeters + }).addTo(map); + } + + var marker = L.marker([x, y], { + title: '{{ .Title }}', + }).addTo(map) + .bindPopup('<span><b>{{ .Title }}</b><br><a href="https://www.openstreetmap.org/#map=13/{{ .MapLocationX }}/{{ .MapLocationY }}">{{ .MapLocationX }}, {{ .MapLocationY }}</a></span>') + .openPopup(); + } + + document.addEventListener('htmx:afterRequest', (e) => { + if (e.detail.target.id == 'general-page-body') { + initLocationMap( + 'map-container', + {{ .MapLocationX }}, + {{ .MapLocationY }}, + {{ .MapLocationAreaMeters }} + ); + } + }, {once: true}); + </script> {{- end }} </div> {{ end }} @@ -34,51 +68,15 @@ {{ end }} {{ define "bottom-embeds" }} -<script src="https://f003.backblazeb2.com/file/sayana-static/libs/lightgallery/2.8.3/lightgallery.min.js"></script> -<script src="https://f003.backblazeb2.com/file/sayana-static/libs/lightgallery/2.8.3/plugins/lg-zoom.min.js"></script> -<script src="https://f003.backblazeb2.com/file/sayana-static/libs/lightgallery/2.8.3/plugins/lg-thumbnail.min.js"></script> -{{- if .MapLocationX }} -<script src="https://f003.backblazeb2.com/file/sayana-static/libs/leaflet/1.9.4/leaflet.js"></script> - <script> - var map; - - 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: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>' - }).addTo(map); - - if (relativeErrorMeters != 0) { - var circle = L.circle([x, y], { - color: '#8a9d8a', - fillColor: '#8a9d8a', - fillOpacity: 0.15, - radius: relativeErrorMeters - }).addTo(map); - } - - var marker = L.marker([x, y], { - title: '{{ .Title }}', - }).addTo(map) - .bindPopup('<span><b>{{ .Title }}</b><br><a href="https://www.openstreetmap.org/#map=13/{{ .MapLocationX }}/{{ .MapLocationY }}">{{ .MapLocationX }}, {{ .MapLocationY }}</a></span>') - .openPopup(); - } - - document.addEventListener('DOMContentLoaded', () => {initLocationMap( - 'map-container', - {{ .MapLocationX }}, - {{ .MapLocationY }}, - {{ .MapLocationAreaMeters }} - )}); - let galleryResizeTimeout; - window.addEventListener('resize', function() { + + function resizeCb() { clearTimeout(galleryResizeTimeout); galleryResizeTimeout = setTimeout(() => { - map.invalidateSize(); + if (map !== undefined) { + map.invalidateSize(); + } var oldGalleryMap = new Map(galleryMap); oldGalleryMap.forEach((createFunc, g, map) => { galleryMap.delete(g); @@ -86,7 +84,13 @@ createFunc(); }); }, 300); + } + + window.addEventListener('resize', resizeCb); + + document.addEventListener('popout', (e) => { + window.removeEventListener('resize', resizeCb); + galleryResizeTimeout = null; }); </script> -{{- end }} {{ end }}
\ No newline at end of file diff --git a/views/pages/global-map.html b/views/pages/global-map.html index 569166f..a844e06 100644 --- a/views/pages/global-map.html +++ b/views/pages/global-map.html @@ -15,7 +15,7 @@ <link rel="stylesheet" href="https://f003.backblazeb2.com/file/sayana-static/libs/leaflet.markercluster/1.4.1/MarkerCluster.Default.css"> </head> -<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"> +<body data-theme="ram" class="font-spectral text-main-dark overflow-hidden bg-interlocked-hexagons h-screen flex flex-row ar-lt-1.1:flex-col"> <script> function switchTheme(theme) { @@ -40,15 +40,15 @@ const clientTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone; </script> - <div id="sidebar" class="bg-sidebar flex sticky flex-col ar-gt-0.8:items-center shadow-2xl z-20 w-[5vw] ar-lt-0.8:w-screen h-screen ar-lt-0.8:h-[8vh]"> - <div class="logo-custom ar-lt-0.8:hidden text-sidebar font-patua font-extrabold text-center relative z-20"> + <div id="sidebar" class="bg-sidebar flex sticky flex-col ar-gt-1.1:items-center shadow-2xl z-20 w-[5vw] ar-lt-1.1:w-screen h-screen ar-lt-1.1:h-[8vh]"> + <div class="logo-custom ar-lt-1.1:hidden text-sidebar font-patua font-extrabold text-center relative z-20"> saya.today </div> - <div class="text-[3vw] ar-lt-0.8:text-[5vh] 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='/';" class="fas fa-home w-[5vw] ar-lt-0.8:w-[8vh] h-[5vw] ar-lt-0.8:h-[8vh] 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-[5vw] ar-lt-0.8:w-[8vh] h-[5vw] ar-lt-0.8:h-[8vh] 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-[5vw] ar-lt-0.8:w-[8vh] h-[5vw] ar-lt-0.8:h-[8vh] 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-[5vw] ar-lt-0.8:w-[8vh] h-[5vw] ar-lt-0.8:h-[8vh] content-center text-center text-sidebar hover:bg-background-dark cursor-pointer transition-colors duration-300 flex rounded-lg"></i> + <div class="text-[3vw] ar-lt-1.1:text-[5vh] text-stroke-(--sidebar-stroke-color) text-stroke-[0.1vw] flex flex-col ar-lt-1.1:flex-row gap-0 relative z-20"> + <i onclick="location.href='/{{ .Lang }}';" class="fas fa-home w-[5vw] ar-lt-1.1:w-[8vh] h-[5vw] ar-lt-1.1:h-[8vh] 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-[5vw] ar-lt-1.1:w-[8vh] h-[5vw] ar-lt-1.1:h-[8vh] 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-[5vw] ar-lt-1.1:w-[8vh] h-[5vw] ar-lt-1.1:h-[8vh] 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-[5vw] ar-lt-1.1:w-[8vh] h-[5vw] ar-lt-1.1:h-[8vh] content-center text-center text-sidebar hover:bg-background-dark cursor-pointer transition-colors duration-300 flex rounded-lg"></i> </div> <div class="theme-wheel" id="theme-wheel"> <div class="theme-icon" data-theme="olive"></div> @@ -58,7 +58,7 @@ </div> </div> - <div id="map-container" class="bg-background-dark flex z-10 w-[95vw] ar-lt-0.8:w-screen h-screen ar-lt-0.8:h-[92vh]"></div> + <div id="map-container" class="bg-background-dark flex z-10 w-[95vw] ar-lt-1.1:w-screen h-screen ar-lt-1.1:h-[92vh]"></div> <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> diff --git a/views/pages/home-page.html b/views/pages/home-page.html new file mode 100644 index 0000000..9775ac3 --- /dev/null +++ b/views/pages/home-page.html @@ -0,0 +1,99 @@ +{{ define "body" }} +<div class="bg-background-light flex flex-row ar-lt-0.6:flex-col w-full h-full inset-shadow overflow-y-auto text-[1vmax]/[2] tracking-[0.04vmin]"> + <div class="ar-gt-0.6:flex-3/5 justify-center content-start p-[5%]"> + <div class="flex flex-col justify-start items-start bg-background-dark mb-[2vmax]"> + <p class="text-[3vmax]/[2] tracking-[0.2vmin] uppercase w-full font-spectral italic text-left + border-l-[0.4vmax] border-solid border-(--background-dark-color) + bg-gradient-to-r from-(--background-dark-color) to-(--background-light-color)">{{ .L.HomePage.Hymn1 }}</p> + <hr class="w-full border-t-[0.2vmax] border-dotted border-main-dark mb-[0.8vmin]"> + <p class="text-[2vmax]/[2] -indent-[2vmax] ml-[2vmax] p-[0.4vmax]">{{ .L.HomePage.Hymn2 }}</p> + <p class="text-[2vmax]/[2] -indent-[2vmax] ml-[2vmax] p-[0.4vmax]">{{ .L.HomePage.Hymn3 }}</p> + <p class="text-[2vmax]/[2] -indent-[2vmax] ml-[2vmax] p-[0.4vmax]">{{ .L.HomePage.Hymn4 }}</p> + </div> + <div class="flex flex-col justify-center items-center"> + <p class="text-[2vmax] w-full font-spectral italic text-left + border-l-[0.4vmax] border-solid border-(--background-dark-color) + bg-gradient-to-r from-(--background-dark-color) to-(--background-light-color)">{{ .L.HomePage.DidYouKnowThat }}</p> + <hr class="w-full border-t-[0.2vmax] border-dotted border-main-dark mb-[0.8vmin]"> + <ul class="w-full text-left list-[circle]"> + <li class="ml-[2vmax] mb-[0.8vmin]">{{ index .FunFacts 0 }}</li> + <li class="ml-[2vmax] mb-[0.8vmin]">{{ index .FunFacts 1 }}</li> + <li class="ml-[2vmax]">{{ index .FunFacts 2 }}</li> + </ul> + </div> + </div> + + <div class="ar-gt-0.6:flex-2/5 justify-center content-start p-[5%]"> + <div class="flex relative aspect-square justify-center content-center mb-[2vmax]"> + {{- range $_ := iterate .FilledHeartCount }} + <div class="home-page-heart z-50">♥</div> + {{- end }} + {{- range $_ := iterate .OutlineHeartCount }} + <div class="home-page-heart z-50">♡</div> + {{- end }} + <img src="https://f003.backblazeb2.com/file/sayana-static/home-page-gifs/{{ .GifName }}" + class="home-page-gif z-49 -rotate-12 max-w-[70%] max-h-[70%] border-[1vmin] border-(--background-dark-color) border-inset"> + </div> + + <script> + function shuffleHearts() { + vmin = calculateVmin(1); + document.querySelectorAll('.home-page-heart').forEach((e) => { + let top, left; + do { + top = Math.floor(rand() * 90) + 5; + left = Math.floor(rand() * 90) + 5; + } while (top > 30 && top < 70 && left > 30 && left < 70); + const opacity = rand() * 0.7 + 0.2; + const size = rand() * 3.2 + 0.8; + e.style["top"] = `calc(${top}% - ${size}vmin / 2)`; + e.style["left"] = `calc(${left}% - ${size}vmin / 2)`; + e.style["opacity"] = `${opacity}`; + e.style["font-size"] = `${size}vmin`; + }); + } + + let shuffleHeartsResizeTimeout; + function shuffleHeartsResizeCb() { + clearTimeout(shuffleHeartsResizeTimeout); + shuffleHeartsResizeTimeout = setTimeout(shuffleHearts, 300); + } + window.addEventListener('resize', shuffleHeartsResizeCb); + + document.addEventListener('popout', (e) => { + window.removeEventListener('resize', shuffleHeartsResizeCb); + shuffleHeartsResizeCb = null; + }); + </script> + + <script> + 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') { + shuffleHearts(); + } + }, {once: true}); + </script> + + <div class="flex flex-col justify-center items-center"> + <p class="text-[2vmax] w-full font-spectral italic text-left + border-l-[0.4vmax] border-solid border-(--background-dark-color) + bg-gradient-to-r from-(--background-dark-color) to-(--background-light-color)">{{ .L.HomePage.SidebarDescription }}</p> + <hr class="w-full border-t-[0.2vmax] border-dotted border-main-dark mb-[0.8vmin]"> + <div class="w-full grid grid-cols-[1fr_4fr] content-center items-center + [&>*:nth-child(4n+2)]:bg-(--background-medium-color) [&>*:nth-child(4n+3)]:bg-(--background-medium-color)" style="container-type: inline-size;"> + <i class="fas fa-home w-full h-full text-[10cqi] content-center text-center text-main-dark"></i> + <p class="p-[0.4vmax]">{{ .L.HomePage.HomePageDescription }}</p> + <i class="fas fa-search w-full h-full text-[10cqi] content-center text-center text-main-dark"></i> + <p class="p-[0.4vmax]">{{ .L.HomePage.BlogSearchDescription }}</p> + <i class="fas fa-map w-full h-full text-[10cqi] content-center text-center text-main-dark"></i> + <p class="p-[0.4vmax]">{{ .L.HomePage.MarkerMapDescription }}</p> + <i class="fas fa-swatchbook w-full h-full text-[10cqi] content-center text-center text-main-dark"></i> + <p class="p-[0.4vmax]">{{ .L.HomePage.ThemeSwitchDescription }}</p> + </div> + </div> + </div> +</div> +{{ end }} diff --git a/views/partials/blog-page-like-button.html b/views/partials/blog-page-like-button.html index afc3027..a16e8c0 100644 --- a/views/partials/blog-page-like-button.html +++ b/views/partials/blog-page-like-button.html @@ -1,7 +1,6 @@ <button hx-put="/api/v1/like" hx-vals='{"like": {{ not .Liked }}}' hx-target="this" hx-swap="outerHTML" hx-trigger="click" class="text-[0.8vmax]/[0.9] font-spectral text-left px-[0.4vmax] py-[0.2vmax] {{ if .Liked }}bg-main-light hover:bg-main-medium text-background-dark border-inset{{ else }}bg-main-dark hover:bg-main-medium text-background-light border-outset{{ end }} cursor-pointer border-[0.2vmax] border-background-dark"> - <i class="fas fa-thumbs-up w-[0.8vmax] h-[0.8vmax] mr-[0.4vmax]"></i> - <span>{{ .L.LikeButton }}</span> + <i class="fas fa-thumbs-up w-[0.8vmax] h-[0.8vmax]"></i> <span class="italic ml-[0.2vmax] text-background-light">({{ .LikedCount }})</span> </button>
\ No newline at end of file diff --git a/views/partials/catalogue-blog-cards.html b/views/partials/catalogue-blog-cards.html index 35c7ad7..06d99d5 100644 --- a/views/partials/catalogue-blog-cards.html +++ b/views/partials/catalogue-blog-cards.html @@ -1,10 +1,10 @@ {{- range .BlogPages }} <hr class="first-of-type:hidden border-t-[0.3vh] my-[0.8vmin] border-dotted border-main-dark w-[80%] mx-auto"> <div class="m-[0.4vmin] flex flex-row justify-center justify-items-center"> - <img onclick="location.href='{{ .ArticleLink }}';" class="cursor-pointer object-cover rounded-[10%] select-none w-[10vmin] h-[10vmin] aspect-square my-[0.4vmin] mr-[0.8vmin]" src="https://f003.backblazeb2.com/file/sayana-photos/webp-320p/{{ .Thumbnail }}.webp"> + <img onclick="changeUrl('{{ .ArticleLink }}');" class="cursor-pointer object-cover rounded-[10%] select-none w-[10vmin] h-[10vmin] aspect-square my-[0.4vmin] mr-[0.8vmin]" src="https://f003.backblazeb2.com/file/sayana-photos/webp-320p/{{ .Thumbnail }}.webp"> <div class="grow my-[0.4vmin] mx-[0.8vmin] flex flex-col justify-center"> <div class="flex flex-row gap-[5%] max-w-[100%]"> - <a href="{{ .ArticleLink }}" class="flex-9/12 grow-0 block text-[1vmax] cursor-pointer"> + <a onclick="changeUrl('{{ .ArticleLink }}');" class="flex-9/12 grow-0 block text-[1vmax] cursor-pointer"> <span class="font-extrabold">{{ .Title }}</span> <span class="font-extrabold select-none text-secondary">//</span> <span class="italic text-secondary">{{ .ActionDate }}</span> @@ -12,6 +12,7 @@ <i class="fas fa-thumbs-up w-[1vmax] h-[1vmax]"></i> <span class="italic text-secondary">{{ .LikeCount }}</span> </a> + <div hx-trigger="click from:#user_search_bar" hx-get="/endpoint1" hx-target="#users-list"></div> <p class="flex-3/12 grow-0 text-[1vmax] italic text-secondary text-right">{{ .PublishedTime }}</p> </div> <p class="text-[1vmax] text-main-dark">{{ .ShortDescription }}</p> diff --git a/views/partials/general-page-body.html b/views/partials/general-page-body.html new file mode 100644 index 0000000..4686ea1 --- /dev/null +++ b/views/partials/general-page-body.html @@ -0,0 +1,2 @@ +<title>SAYA TODAY // {{ .Title }}</title> +{{ block "body" . }}{{ end }}
\ No newline at end of file diff --git a/views/partials/general-page-bottom-embeds.html b/views/partials/general-page-bottom-embeds.html new file mode 100644 index 0000000..4c36b26 --- /dev/null +++ b/views/partials/general-page-bottom-embeds.html @@ -0,0 +1 @@ +{{ block "bottom-embeds" . }}{{ end }}
\ No newline at end of file diff --git a/views/partials/general-page-footer.html b/views/partials/general-page-footer.html new file mode 100644 index 0000000..af6aec9 --- /dev/null +++ b/views/partials/general-page-footer.html @@ -0,0 +1,7 @@ +{{ block "footer" . }}{{ end }} +<p class="grow content-center text-[1vmax]/[1] font-spectral italic text-right text-secondary mr-2"> + All the photos on <a href="https://saya.today/">saya.today</a> are licensed under <a href="https://creativecommons.org/licenses/by-sa/4.0/">CC BY-SA 4.0</a> by <a href="https://t.me/EarlInisMona">Saya Andy</a> © {{ .PublishedYear }} +</p> +<img class="max-w-[1vmax] max-h-[1vmax] self-center" src="https://mirrors.creativecommons.org/presskit/icons/cc.svg" alt="CC"> +<img class="max-w-[1vmax] max-h-[1vmax] self-center" src="https://mirrors.creativecommons.org/presskit/icons/by.svg" alt="BY"> +<img class="max-w-[1vmax] max-h-[1vmax] self-center" src="https://mirrors.creativecommons.org/presskit/icons/sa.svg" alt="SA">
\ No newline at end of file diff --git a/views/partials/general-page-header.html b/views/partials/general-page-header.html new file mode 100644 index 0000000..63803bd --- /dev/null +++ b/views/partials/general-page-header.html @@ -0,0 +1,8 @@ +<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-[0.4vmin]"> + <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-[2vmax] mt-auto mb-auto px-[0.8vmin]"></i> + <p class="text-[2vmax] font-spectral italic font-extrabold select-none mt-auto pl-[0.8vmin] pr-[1.2vmin]">//</p> + <p class="text-[2vmax] font-spectral italic text-left mt-auto">{{ .Title }}</p> + <p id="published-date" class="grow text-[1.5vmax] font-spectral text-secondary text-right mt-auto">{{ .PublishedDate }}</p> +</div> +{{ block "header" . }}{{ end }} diff --git a/views/partials/general-page-top-embeds.html b/views/partials/general-page-top-embeds.html new file mode 100644 index 0000000..1407b50 --- /dev/null +++ b/views/partials/general-page-top-embeds.html @@ -0,0 +1 @@ +{{ block "top-embeds" . }}{{ end }}
\ No newline at end of file |