diff --git a/app/templates/layouts/app.html.slim b/app/templates/layouts/app.html.slim index 320a1be..01826bb 100644 --- a/app/templates/layouts/app.html.slim +++ b/app/templates/layouts/app.html.slim @@ -25,6 +25,7 @@ html link rel="icon" type="image/x-icon" href="/assets/favicon.ico" script data-domain="dnitza.com" src="https://stats.dnitza.com/js/script.js" defer="true" + script src="/assets/gallery.js" script src="/assets/index.js" script src="https://unpkg.com/htmx.org@1.8.4" integrity="sha384-wg5Y/JwF7VxGk4zLsJEcAojRtlVp1FKKdGy1qN+OMtdq72WRvX/EdRdqg/LOhYeV" crossorigin="anonymous" @@ -32,7 +33,7 @@ html - if Hanami.app.settings.micropub_pub_key link rel="pgpkey" href="/key" - body class="bg-white dark:bg-black selection:bg-blue-100 selection:text-blue-900 dark:selection:bg-blue-600 dark:selection:text-blue-100" + body class="bg-white dark:bg-black selection:bg-blue-100 selection:text-blue-900 dark:selection:bg-blue-600 dark:selection:text-blue-100" x-data="{ imgModal : false, imgModalSrc : '', imgModalDesc : '' }" x-on:keydown.escape="imgModal=false" main class="pb-8 px-4 pt-4 md:pt-8" header class="mb-12 max-w-screen-md mx-auto" div class="flex items-center mb-8 md:mb-12 text-lg md:text-xl text-gray-400 dark:text-gray-600" diff --git a/app/templates/posts/show.html.slim b/app/templates/posts/show.html.slim index 5a5ea39..0c2256b 100644 --- a/app/templates/posts/show.html.slim +++ b/app/templates/posts/show.html.slim @@ -1,4 +1,14 @@ article class="h-entry" + template @img-modal.window="imgModal = true; imgModalSrc = $event.detail.imgModalSrc; imgModalDesc = $event.detail.imgModalDesc;" x-if="imgModal" + div @mousedown.outside="imgModalSrc = ''" class="p-2 fixed w-full h-100 inset-0 z-50 overflow-hidden flex justify-center items-center bg-black bg-opacity-75" + div @mousedown.outside="imgModal = ''" class="flex flex-col max-w-3xl max-h-full overflow-auto" + div class="z-50" + button @click="imgModal = ''" class="float-right pt-2 pr-2 outline-none focus:outline-none" + svg class="fill-current text-white" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18" + path d="M14.53 4.53l-1.06-1.06L9 7.94 4.53 3.47 3.47 4.53 7.94 9l-4.47 4.47 1.06 1.06L9 10.06l4.47 4.47 1.06-1.06L10.06 9z"> + div class="p-2" + img class="rounded object-contain h-1/2-screen shadow-solid shadow-pink-100 dark:shadow-pink-200 mb-4" :src="imgModalSrc" :alt="imgModalSrc" + p x-text="imgModalDesc" class="text-center text-white" div class="mb-12 prose dark:prose-invert max-w-prose mx-auto text-gray-800 dark:text-gray-200" h1 class="p-name mb-2" a class="u-url" href=post.permalink diff --git a/public/assets/gallery.js b/public/assets/gallery.js new file mode 100644 index 0000000..8ff6fc3 --- /dev/null +++ b/public/assets/gallery.js @@ -0,0 +1,103 @@ +/* +Markdown Gallery +-- v1.0 2016 +-- Created by Lee Penney +-- Released under GPLv3 +*/ + +function md_gallery(config) { + var config = config || {}, + list_type = config.list_type || 'ul', + class_name = config.class_name || 'gallery', + tag_type = config.tag_type || 'div'; + + function find_lists(list_type) { + var lists = document.getElementsByTagName(list_type), matching_lists = []; + for (var i = 0; i < lists.length; i++) { + var list_elements = lists[i].children; + var total_matches = 0; + for (var c = 0; c < list_elements.length; c++) { + if (!list_elements[c].textContent.length && (list_elements[c].firstChild.tagName == 'A' || list_elements[c].firstChild.tagName == 'IMG') && (!list_elements[c].firstChild.firstChild || (list_elements[c].firstChild.firstChild && list_elements[c].firstChild.firstChild.tagName == 'IMG') )) { + total_matches++; + } + } + if (total_matches == list_elements.length) { + matching_lists[matching_lists.length] = lists[i]; + } + } + return matching_lists; + } + + function prepend_tag(img_lists, list_tag, prepend_tag, class_name) { + for (var i = 0; i < img_lists.length; i++) { + // add_figure_tags(img_lists[i]); + add_anchor(img_lists[i]); + wrap_tag(img_lists[i], prepend_tag, class_name, null, true); + strip_tag(img_lists[i], 'li'); + strip_tag(img_lists[i].parentNode, list_tag); + } + } + + function append_caption(el) { + if ((el.tagName == 'A' && el.firstChild.tagName == 'IMG' && el.firstChild.hasAttribute('alt') && el.firstChild.getAttribute('alt').length > 0) || (el.tagName == 'IMG' && el.hasAttribute('alt') && el.getAttribute('alt').length > 0)) { + var caption = document.createElement('figcaption'); + try { + caption.textContent = el.firstChild.getAttribute('alt') + el.appendChild(caption); + } catch (e) { + caption.textContent = el.getAttribute('alt'); + el.parentNode.appendChild(caption); + } + } + } + + function strip_tag(el, tag_type) { + var start_tag_regex = new RegExp('<'+tag_type+'>', 'gi'); + var end_tag_regex = new RegExp('<\/'+tag_type+'>', 'gi'); + el.innerHTML = el.innerHTML.replace(start_tag_regex,'').replace(end_tag_regex,''); + } + + function add_figure_tags(img_list) { + var list_elements = img_list.children; + for (var i = 0; i < list_elements.length; i++) { + append_caption(list_elements[i].firstChild); + wrap_tag(list_elements[i], 'figure'); + } + } + + function add_anchor(img_list) { + var list_elements = img_list.children; + for (var i = 0; i < list_elements.length; i++) { + let img = list_elements[i].getElementsByTagName('img')[0]; + let src = img.getAttribute("src"); + let alt = img.getAttribute("alt"); + wrap_tag(list_elements[i], + 'a', + 'hover:cursor-pointer', + "$dispatch('img-modal', { imgModalSrc: '" + src + "', imgModalDesc: '" + alt + "' })", + false + ); + } + } + + function wrap_tag(el, tag_type, class_name, click, root) { + var wrap = document.createElement(tag_type); + if (root) { + wrap.setAttribute('x-data', "{}"); + } + if (class_name) { + wrap.setAttribute('class', class_name); + } + if (click) { + wrap.setAttribute('x-on:click.prevent', click); + wrap.setAttribute('href', '#'); + } + el.parentNode.replaceChild(wrap, el); + wrap.appendChild(el); + } + + var found_img_lists = find_lists(list_type); + if (found_img_lists.length) { + prepend_tag(found_img_lists, list_type, tag_type, class_name); + } +} \ No newline at end of file diff --git a/public/assets/index.css b/public/assets/index.css index 92f919a..447fe5e 100644 --- a/public/assets/index.css +++ b/public/assets/index.css @@ -516,6 +516,40 @@ video { --tw-backdrop-sepia: ; } +.container { + width: 100%; +} + +@media (min-width: 640px) { + .container { + max-width: 640px; + } +} + +@media (min-width: 768px) { + .container { + max-width: 768px; + } +} + +@media (min-width: 1024px) { + .container { + max-width: 1024px; + } +} + +@media (min-width: 1280px) { + .container { + max-width: 1280px; + } +} + +@media (min-width: 1536px) { + .container { + max-width: 1536px; + } +} + .prose { color: var(--tw-prose-body); max-width: 65ch; @@ -974,6 +1008,10 @@ video { margin-bottom: 0; } +.fixed { + position: fixed; +} + .absolute { position: absolute; } @@ -982,10 +1020,18 @@ video { position: relative; } +.inset-0 { + inset: 0px; +} + .-top-4 { top: -1rem; } +.z-50 { + z-index: 50; +} + .col-span-1 { grid-column: span 1 / span 1; } @@ -1140,6 +1186,10 @@ video { max-height: 3rem; } +.max-h-full { + max-height: 100%; +} + .w-1 { width: 0.25rem; } @@ -1172,6 +1222,14 @@ video { width: 1.5rem; } +.w-full { + width: 100%; +} + +.max-w-3xl { + max-width: 48rem; +} + .max-w-prose { max-width: 65ch; } @@ -1221,6 +1279,10 @@ video { grid-auto-flow: column; } +.grid-cols-2 { + grid-template-columns: repeat(2, minmax(0, 1fr)); +} + .grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } @@ -1241,6 +1303,10 @@ video { grid-template-rows: repeat(1, minmax(0, 1fr)); } +.flex-col { + flex-direction: column; +} + .content-center { align-content: center; } @@ -1249,6 +1315,10 @@ video { align-items: center; } +.justify-center { + justify-content: center; +} + .justify-between { justify-content: space-between; } @@ -1267,6 +1337,14 @@ video { margin-left: calc(0.25rem * calc(1 - var(--tw-space-x-reverse))); } +.overflow-auto { + overflow: auto; +} + +.overflow-hidden { + overflow: hidden; +} + .break-normal { overflow-wrap: normal; word-break: normal; @@ -1332,6 +1410,11 @@ video { border-color: transparent; } +.bg-black { + --tw-bg-opacity: 1; + background-color: rgb(0 0 0 / var(--tw-bg-opacity)); +} + .bg-blue-100 { --tw-bg-opacity: 1; background-color: rgb(219 234 254 / var(--tw-bg-opacity)); @@ -1381,10 +1464,18 @@ video { background-color: rgb(254 249 195 / 0.6); } +.bg-opacity-75 { + --tw-bg-opacity: 0.75; +} + .fill-blue-100 { fill: #dbeafe; } +.fill-current { + fill: currentColor; +} + .fill-pink-100 { fill: #fce7f3; } @@ -1393,6 +1484,11 @@ video { fill: #f3e8ff; } +.object-contain { + -o-object-fit: contain; + object-fit: contain; +} + .object-cover { -o-object-fit: cover; object-fit: cover; @@ -1442,6 +1538,14 @@ video { padding-left: 1.5rem; } +.pr-2 { + padding-right: 0.5rem; +} + +.pt-2 { + padding-top: 0.5rem; +} + .pt-4 { padding-top: 1rem; } @@ -1550,6 +1654,11 @@ video { color: rgb(220 38 38 / var(--tw-text-opacity)); } +.text-white { + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity)); +} + .underline { text-decoration-line: underline; } @@ -1573,6 +1682,11 @@ video { --tw-shadow: var(--tw-shadow-colored); } +.outline-none { + outline: 2px solid transparent; + outline-offset: 2px; +} + .transition-colors { transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); @@ -1795,6 +1909,11 @@ h1, h2, h3, h4, h5, h6, h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { opacity: 0.8; } +.focus\:outline-none:focus { + outline: 2px solid transparent; + outline-offset: 2px; +} + .prose-p\:mb-0 :is(:where(p):not(:where([class~="not-prose"] *))) { margin-bottom: 0px; } @@ -1868,6 +1987,10 @@ h1, h2, h3, h4, h5, h6, h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { padding-left: 0px; } +.prose-img\:m-0 :is(:where(img):not(:where([class~="not-prose"] *))) { + margin: 0px; +} + .prose-img\:my-2 :is(:where(img):not(:where([class~="not-prose"] *))) { margin-top: 0.5rem; margin-bottom: 0.5rem; diff --git a/public/assets/index.js b/public/assets/index.js index 7a98d1a..c28f04d 100644 --- a/public/assets/index.js +++ b/public/assets/index.js @@ -9,6 +9,10 @@ times.forEach((time) => { const oldDtime = Date.parse(time.dateTime); time.innerHTML = new Date(oldDtime).toLocaleDateString(navigator.language, { weekday:"long", year:"numeric", month:"short", day:"numeric"}); + + md_gallery({ + "class_name": "grid gap-4 grid-cols-2 prose-img:m-0" + }); }); // mapboxgl.accessToken = 'pk.eyJ1IjoiZG5pdHphIiwiYSI6ImNsZWIyY3ZzaTE0cjUzdm4xdnZ6czRlYjUifQ.FRETOXYRID6T2IoB7qqRLg'; // var map = new mapboxgl.Map({ diff --git a/tailwind.config.js b/tailwind.config.js index 9453cdd..95ce749 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -3,7 +3,7 @@ const colors = require("tailwindcss/colors"); module.exports = { - content: ["./app/templates/**/*.slim"], + content: ["./app/templates/**/*.slim", "./public/assets/index.js"], theme: { fontSize: { xsm: '0.75rem',