diff --git a/generate/build.tsx b/generate/build.tsx index bab9dc0..b938b45 100644 --- a/generate/build.tsx +++ b/generate/build.tsx @@ -8,6 +8,7 @@ import exec from "child_process"; import Base from "./templates/Base"; import Header from "./templates/Header"; import YearPhotos from "./templates/YearPhotos"; +import Tags from "./templates/Tags"; const log = new Log(); @@ -123,6 +124,7 @@ Object.keys(items).forEach((year) => { const html = renderToString(
+
{Object.keys(items).sort().reverse().map((year) => ( =16.0.0" } }, "sha512-ey8Ls/+Di31eqzUxC46h8MksNuGx/n0AAC8uKpwFau4RPDYLuE3EXTp8N8G2vX2N7UC/+IXeNUnlWBGGcAG+Ig=="], + "proto3-json-serializer": ["proto3-json-serializer@2.0.2", "", { "dependencies": { "protobufjs": "^7.2.5" } }, "sha512-SAzp/O4Yh02jGdRc+uIrGoe87dkN/XtwxfZ4ZyafJHymd79ozp5VG5nyZ7ygqPM5+cpLDjjGnYFUkngonyDPOQ=="], "protobufjs": ["protobufjs@7.4.0", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw=="], @@ -539,6 +546,8 @@ "stubs": ["stubs@3.0.0", "", {}, "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw=="], + "tailwind-scrollbar": ["tailwind-scrollbar@4.0.0", "", { "dependencies": { "prism-react-renderer": "^2.4.1" }, "peerDependencies": { "tailwindcss": "4.x" } }, "sha512-elqx9m09VHY8gkrMiyimFO09JlS3AyLFXT0eaLaWPi7ImwHlbZj1ce/AxSis2LtR+ewBGEyUV7URNEMcjP1Z2w=="], + "tailwindcss": ["tailwindcss@4.0.7", "", {}, "sha512-yH5bPPyapavo7L+547h3c4jcBXcrKwybQRjwdEIVAd9iXRvy/3T1CC6XSQEgZtRySjKfqvo3Cc0ZF1DTheuIdA=="], "tapable": ["tapable@2.2.1", "", {}, "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ=="], diff --git a/generate/package.json b/generate/package.json index 117fd03..48f3a66 100644 --- a/generate/package.json +++ b/generate/package.json @@ -20,6 +20,7 @@ "picocolors": "^1.1.1", "react": "^19.0.0", "react-dom": "^19.0.0", + "tailwind-scrollbar": "^4.0.0", "tailwindcss": "^4.0.7", "ws": "^8.18.0" } diff --git a/generate/static/css/tailwind.css b/generate/static/css/tailwind.css index 5f772da..cdbd03d 100644 --- a/generate/static/css/tailwind.css +++ b/generate/static/css/tailwind.css @@ -521,11 +521,8 @@ .collapse { visibility: collapse; } - .absolute { - position: absolute; - } - .fixed { - position: fixed; + .invisible { + visibility: hidden; } .relative { position: relative; @@ -533,12 +530,6 @@ .static { position: static; } - .\[grid-column\:span_2\] { - grid-column: span 2; - } - .\[grid-row\:span_2\] { - grid-row: span 2; - } .container { width: 100%; @media (width >= 40rem) { @@ -563,6 +554,27 @@ .mb-4 { margin-bottom: calc(var(--spacing) * 4); } + .scrollbar-thin { + &::-webkit-scrollbar-track { + background-color: var(--scrollbar-track); + border-radius: var(--scrollbar-track-radius); + } + &::-webkit-scrollbar-thumb { + background-color: var(--scrollbar-thumb); + border-radius: var(--scrollbar-thumb-radius); + } + &::-webkit-scrollbar-corner { + background-color: var(--scrollbar-corner); + border-radius: var(--scrollbar-corner-radius); + } + scrollbar-width: thin; + scrollbar-color: var(--scrollbar-thumb, initial) var(--scrollbar-track, initial); + &::-webkit-scrollbar { + display: block; + width: 8px; + height: 8px; + } + } .block { display: block; } @@ -575,9 +587,6 @@ .hidden { display: none; } - .inline-block { - display: inline-block; - } .inline-flex { display: inline-flex; } @@ -587,12 +596,6 @@ .table { display: table; } - .aspect-\[1\/2\] { - aspect-ratio: 1/2; - } - .aspect-\[2\/1\] { - aspect-ratio: 2/1; - } .aspect-square { aspect-ratio: 1 / 1; } @@ -620,33 +623,9 @@ .grid-flow-row-dense { grid-auto-flow: row dense; } - .\[grid-template-columns\:repeat\(auto-fill\,minmax\(256px\,1fr\)\)\] { - grid-template-columns: repeat(auto-fill,minmax(256px,1fr)); - } - .grid-cols-1 { - grid-template-columns: repeat(1, minmax(0, 1fr)); - } .grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } - .grid-cols-3 { - grid-template-columns: repeat(3, minmax(0, 1fr)); - } - .grid-cols-4 { - grid-template-columns: repeat(4, minmax(0, 1fr)); - } - .grid-cols-5 { - grid-template-columns: repeat(5, minmax(0, 1fr)); - } - .grid-cols-6 { - grid-template-columns: repeat(6, minmax(0, 1fr)); - } - .grid-cols-7 { - grid-template-columns: repeat(7, minmax(0, 1fr)); - } - .grid-cols-8 { - grid-template-columns: repeat(8, minmax(0, 1fr)); - } .flex-col { flex-direction: column; } @@ -659,8 +638,11 @@ .gap-4 { gap: calc(var(--spacing) * 4); } - .gap-8 { - gap: calc(var(--spacing) * 8); + .overflow-x-auto { + overflow-x: auto; + } + .rounded-full { + border-radius: calc(infinity * 1px); } .rounded-lg { border-radius: var(--radius-lg); @@ -682,16 +664,38 @@ .bg-\[\#FF478B\] { background-color: #FF478B; } + .bg-gray-600 { + background-color: var(--color-gray-600); + } + .bg-gray-800 { + background-color: var(--color-gray-800); + } .object-cover { object-fit: cover; } .p-4 { padding: calc(var(--spacing) * 4); } + .px-3 { + padding-inline: calc(var(--spacing) * 3); + } + .px-8 { + padding-inline: calc(var(--spacing) * 8); + } + .py-1 { + padding-block: calc(var(--spacing) * 1); + } + .py-2 { + padding-block: calc(var(--spacing) * 2); + } .text-2xl { font-size: var(--text-2xl); line-height: var(--tw-leading, var(--text-2xl--line-height)); } + .text-sm { + font-size: var(--text-sm); + line-height: var(--tw-leading, var(--text-sm--line-height)); + } .font-bold { --tw-font-weight: var(--font-weight-bold); font-weight: var(--font-weight-bold); @@ -702,107 +706,34 @@ .underline { text-decoration-line: underline; } - .antialiased { - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - } .outline { outline-style: var(--tw-outline-style); outline-width: 1px; } - .blur { - --tw-blur: blur(8px); - filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,); - } - .grayscale { - --tw-grayscale: grayscale(100%); - filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,); - } .filter { filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,); } - .backdrop-filter { - -webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,); - backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,); + .scrollbar-thumb-gray-700 { + --scrollbar-thumb: oklch(0.373 0.034 259.733); } - .transition { - transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter; - transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); - transition-duration: var(--tw-duration, var(--default-transition-duration)); - } - .ease-in { - --tw-ease: var(--ease-in); - transition-timing-function: var(--ease-in); - } - .ease-out { - --tw-ease: var(--ease-out); - transition-timing-function: var(--ease-out); - } - .sm\:\[grid-column\:span_2\] { - @media (width >= 40rem) { - grid-column: span 2; - } - } - .sm\:\[grid-template-columns\:repeat\(auto-fill\,minmax\(256px\,1fr\)\)\] { - @media (width >= 40rem) { - grid-template-columns: repeat(auto-fill,minmax(256px,1fr)); - } - } - .md\:\[grid-column\:span_2\] { - @media (width >= 48rem) { - grid-column: span 2; - } + .scrollbar-track-gray-900 { + --scrollbar-track: oklch(0.21 0.034 264.665); } .lg\:\[grid-column\:span_2\] { @media (width >= 64rem) { grid-column: span 2; } } - .lg\:grid-cols-3 { - @media (width >= 64rem) { - grid-template-columns: repeat(3, minmax(0, 1fr)); - } - } - .lg\:grid-cols-4 { - @media (width >= 64rem) { - grid-template-columns: repeat(4, minmax(0, 1fr)); - } - } .lg\:grid-cols-5 { @media (width >= 64rem) { grid-template-columns: repeat(5, minmax(0, 1fr)); } } - .xl\:\[grid-column\:span_2\] { - @media (width >= 80rem) { - grid-column: span 2; - } - } - .xl\:\[grid-template-columns\:repeat\(auto-fill\,minmax\(128px\,1fr\)\)\] { - @media (width >= 80rem) { - grid-template-columns: repeat(auto-fill,minmax(128px,1fr)); - } - } - .xl\:\[grid-template-columns\:repeat\(auto-fill\,minmax\(200px\,1fr\)\)\] { - @media (width >= 80rem) { - grid-template-columns: repeat(auto-fill,minmax(200px,1fr)); - } - } - .xl\:\[grid-template-columns\:repeat\(auto-fill\,minmax\(512px\,1fr\)\)\] { - @media (width >= 80rem) { - grid-template-columns: repeat(auto-fill,minmax(512px,1fr)); - } - } .xl\:grid-cols-7 { @media (width >= 80rem) { grid-template-columns: repeat(7, minmax(0, 1fr)); } } - .xl\:grid-cols-8 { - @media (width >= 80rem) { - grid-template-columns: repeat(8, minmax(0, 1fr)); - } - } .xl\:text-3xl { @media (width >= 80rem) { font-size: var(--text-3xl); @@ -822,6 +753,12 @@ font-weight: 600; font-style: normal; } +@layer base { + * { + scrollbar-color: initial; + scrollbar-width: initial; + } +} @keyframes spin { to { transform: rotate(360deg); @@ -927,43 +864,3 @@ syntax: "*"; inherits: false; } -@property --tw-backdrop-blur { - syntax: "*"; - inherits: false; -} -@property --tw-backdrop-brightness { - syntax: "*"; - inherits: false; -} -@property --tw-backdrop-contrast { - syntax: "*"; - inherits: false; -} -@property --tw-backdrop-grayscale { - syntax: "*"; - inherits: false; -} -@property --tw-backdrop-hue-rotate { - syntax: "*"; - inherits: false; -} -@property --tw-backdrop-invert { - syntax: "*"; - inherits: false; -} -@property --tw-backdrop-opacity { - syntax: "*"; - inherits: false; -} -@property --tw-backdrop-saturate { - syntax: "*"; - inherits: false; -} -@property --tw-backdrop-sepia { - syntax: "*"; - inherits: false; -} -@property --tw-ease { - syntax: "*"; - inherits: false; -} diff --git a/generate/static/js/initGalleries.js b/generate/static/js/initGalleries.js index 348a0b3..c96180c 100644 --- a/generate/static/js/initGalleries.js +++ b/generate/static/js/initGalleries.js @@ -1,17 +1,103 @@ +const url = new URL(window.location.href); +let tags = url.searchParams.get("tag") || ""; +if (tags.length > 0) { + tags = tags.split(","); +} else { + tags = []; +} +let availableTags = []; + const galleries = document.querySelectorAll('[data-type="gallery"]'); +let tagsButtons = document.querySelectorAll('[data-type="tag"]'); +let allTagsButton = document.querySelector('[data-type="tag"][data-tag="all"]'); +let Images = document.querySelectorAll('[data-type="image"]'); + +Images.forEach((item) => { + const imTags = item.dataset.tags.split(",") || []; + const foundTags = []; + + for (let i = 0; i < imTags.length; i++) { + if (tags.includes(imTags[i]) || tags.length == 0) { + foundTags.push(imTags[i]); + } + } + + if (foundTags.length == 0 || foundTags.length < tags.length) { + item.remove(); + } else { + item.classList.remove("hidden"); + for (let i = 0; i < imTags.length; i++) { + if (!availableTags.includes(imTags[i])) { + availableTags.push(imTags[i]); + } + } + } +}); + +allTagsButton.addEventListener("click", () => { + removeTags(); +}); + +if (tags.length == 0) { + allTagsButton.classList.remove("bg-gray-800"); + allTagsButton.classList.add("bg-gray-600"); +} + +tagsButtons.forEach((item) => { + if (item.dataset.tag != "all") { + item.addEventListener("click", () => { + toggleTag(item.dataset.tag); + }); + } + if (tags.includes(item.dataset.tag)) { + item.classList.remove("bg-gray-800"); + item.classList.add("bg-gray-600"); + } + if (!availableTags.includes(item.dataset.tag) && item.dataset.tag != "all") { + item.remove(); + } else { + item.classList.remove("hidden"); + } +}); + +function removeTags() { + const url = new URL(window.location.href); + url.searchParams.delete("tag"); + window.history.pushState({}, "", url); + window.location.reload(); +} + +function toggleTag(tag) { + if (tags.includes(tag)) { + tags = tags.filter((item) => item !== tag); + } else { + tags.push(tag); + } + + tags = tags.join(","); + url.searchParams.set("tag", tags); + window.history.pushState({}, "", url); + window.location.reload(); +} galleries.forEach((item, idx) => { - lightGallery(item, { - plugins: [lgThumbnail, lgHash, lgShare, lgFullscreen, lgZoom], - speed: 500, - thumbnail: true, - download: true, - animateThumb: true, - zoomFromOrigin: false, - toggleThumb: false, - galleryId: Number(item.getAttribute('data-year')), - hash: true, - customSlideName: true, - mobileSettings: { controls: true, showCloseIcon: true, download: true } - }); + if (item.children.length == 0) { + item.parentElement.remove(); + } else { + item.parentElement.classList.remove("hidden"); + + lightGallery(item, { + plugins: [lgThumbnail, lgHash, lgShare, lgFullscreen, lgZoom], + speed: 500, + thumbnail: true, + download: true, + animateThumb: true, + zoomFromOrigin: false, + toggleThumb: false, + galleryId: Number(item.getAttribute("data-year")), + hash: true, + customSlideName: true, + mobileSettings: { controls: true, showCloseIcon: true, download: true }, + }); + } }); diff --git a/generate/static_dev/input.css b/generate/static_dev/input.css index c29fd2c..bb1e1d4 100644 --- a/generate/static_dev/input.css +++ b/generate/static_dev/input.css @@ -1,4 +1,5 @@ @import "tailwindcss"; +@plugin 'tailwind-scrollbar'; .inter-semibold { font-family: "Inter", serif; diff --git a/generate/templates/Tags.tsx b/generate/templates/Tags.tsx new file mode 100644 index 0000000..b00999f --- /dev/null +++ b/generate/templates/Tags.tsx @@ -0,0 +1,26 @@ +export default function Tags({ tags }: { tags: string[] }) { + return ( +
+
+ + {tags.map((tag) => ( + + ))} +
+
+ ); +} diff --git a/generate/templates/YearPhotos.tsx b/generate/templates/YearPhotos.tsx index e22d5ac..5b47eee 100644 --- a/generate/templates/YearPhotos.tsx +++ b/generate/templates/YearPhotos.tsx @@ -7,7 +7,7 @@ interface YearPhotosProps { export default function YearPhotos({ year, images }: YearPhotosProps) { return ( -
+