summaryrefslogtreecommitdiffci
path: root/views/pages
diff options
from:
to:
context:
space:
mode:
authorGravatar SayaAndy <saya.andy@posteo.com> 2025-08-31 18:12:51 +0700
committerGravatar SayaAndy <saya.andy@posteo.com> 2025-08-31 18:12:51 +0700
commit145e7e05f3aa6adbc71a0db5e7da160e626bacd3 (patch)
tree6864bf01bbeeeadbf06122b9ab5d993cffaf4062 /views/pages
parent5eb7b64b3da54e769cc6e52fd6918e4b465b8c0a (diff)
downloadweb-145e7e05f3aa6adbc71a0db5e7da160e626bacd3.tar.gz
web-145e7e05f3aa6adbc71a0db5e7da160e626bacd3.zip
feat: seamless single page application
Diffstat (limited to 'views/pages')
-rw-r--r--views/pages/blog-catalogue.html36
-rw-r--r--views/pages/blog-page.html79
2 files changed, 100 insertions, 15 deletions
diff --git a/views/pages/blog-catalogue.html b/views/pages/blog-catalogue.html
index ac2fb7d..a5f5256 100644
--- a/views/pages/blog-catalogue.html
+++ b/views/pages/blog-catalogue.html
@@ -98,6 +98,7 @@
function cleanHrefParams() {
const url = new URL(window.location.href);
url.search = '';
+
window.history.pushState({}, '', url.toString());
}
@@ -137,22 +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 d8fb118..e68fcab 100644
--- a/views/pages/blog-page.html
+++ b/views/pages/blog-page.html
@@ -1,3 +1,18 @@
+{{ define "top-embeds" }}
+<script>
+ var galleryMap = new Map();
+ var map;
+
+ window.addEventListener('popout', (e) => {
+ map.remove();
+ galleryMap.forEach((_, g, m) => {
+ g.destroy();
+ });
+ galleryMap.clear();
+ }, {once: true});
+</script>
+{{ end }}
+
{{ define "body" }}
<div class="bg-background-light flex flex-col inset-shadow p-[2.4vmin] overflow-y-auto">
{{ .ParsedMarkdown }}
@@ -5,6 +20,43 @@
<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>
<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: '&copy; <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 }}
@@ -12,3 +64,30 @@
{{ 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, {once: true});
+ });
+</script>
+{{ end }} \ No newline at end of file