From 81ce440269a29d70de5c806f03d064b0897cf7db Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Thu, 12 Jun 2025 22:23:55 -0500 Subject: integrate tailwind more and a few other minor features --- src/albums.js | 1 + src/connector.js | 1 + src/immich.js | 48 ---------------------------- src/index.js | 2 -- src/pages.js | 19 ++++++++++-- src/style.css | 95 +++++++++++++------------------------------------------- 6 files changed, 40 insertions(+), 126 deletions(-) delete mode 100644 src/immich.js (limited to 'src') diff --git a/src/albums.js b/src/albums.js index 529a02e..f8b5ed1 100644 --- a/src/albums.js +++ b/src/albums.js @@ -9,6 +9,7 @@ export default async function initAlbums(albumsPageContainer) { console.log(res.albumName, res.id, res.startDate, res.endDate, res.assetCount, res.shared) const albumClone = albumTemplate.content.cloneNode(true) albumClone.firstElementChild.dataset.key = res.id + albumClone.querySelector("a").href = apiConnector.albumSrc(res.id) albumClone.querySelector("img").src = apiConnector.assetThumbnailSrc(res.albumThumbnailAssetId) albumClone.querySelector(".album-name").textContent = res.albumName albumClone.querySelector(".album-assets-count").textContent = res.assetCount.toLocaleString() diff --git a/src/connector.js b/src/connector.js index 03e6f3d..97071c6 100644 --- a/src/connector.js +++ b/src/connector.js @@ -47,6 +47,7 @@ class APIConnector { return this.fetch("/albums") } + albumSrc(key) { return `${this.url}/api/redirect/albums/${key}` } assetSrc(key) { return `${this.url}/api/asset/${key}` } assetThumbnailSrc(key) { return `${this.url}/api/asset/${key}/thumbnail` } } diff --git a/src/immich.js b/src/immich.js deleted file mode 100644 index d938fea..0000000 --- a/src/immich.js +++ /dev/null @@ -1,48 +0,0 @@ -class ImmichConnector { - constructor(url, apiKey) { - this.url = url - this.apiKey = apiKey - } - - fetchAlbums() { - return this.fetch("/albums") - } - - #fetch(endpoint) { - return fetch(this.url + "/api" + endpoint, { - headers: { "x-api-key": this.apiKey } - }) - } - - fetch(endpoint) { - return this.#fetch(endpoint) - .then(response => { - if (!response.ok) - throw new Error(`HTTP error! Status: ${response.status}`) - return response.json() - }) - .then(data => { - return data - }) - .catch(error => { - console.error("Fetch error:", error) - }) - } - - fetchImageSrc(key, size) { - const url = `/assets/${key}/thumbnail` + (this.size ? `?size=${this.size}` : "") - return this.#fetch(url) - .then(response => { - if (!response.ok) - throw new Error(`HTTP error! Status: ${response.status}`) - return response.blob() - }) - .then(blob => { - return URL.createObjectURL(blob) - }) - } -} - -const immichConnector = new ImmichConnector("http://192.168.1.13", "m5nqOoBc4uhAba21gZdCP3z8D3JT4GPxDXL2psd52EA") -document.immichConnector = immichConnector // FIXME TEMP -export default immichConnector diff --git a/src/index.js b/src/index.js index d27c8db..dea0b97 100644 --- a/src/index.js +++ b/src/index.js @@ -1,8 +1,6 @@ import "@fontsource/overpass" -import "@fontsource/overpass/500.css" import "@fontsource/overpass/700.css" import "./style.css" -import immichConnector from "./immich.js" import Page from "./pages.js" import "./icons.js" import initSlides from "./slides.js" diff --git a/src/pages.js b/src/pages.js index 0576684..f6a8b9b 100644 --- a/src/pages.js +++ b/src/pages.js @@ -1,3 +1,5 @@ +const menu = document.querySelector("#menu") + export default class Page { static pages = {} static currentPage = null @@ -33,9 +35,20 @@ export default class Page { } setVisible(visible) { - this.pageContainer.style.display = visible ? null : "none" + this.pageContainer.classList.toggle("hidden!", !visible) this.visible = visible - if (visible && !this.initialized && this.initialize) - this.initialized = this.initialize(this.pageContainer) + if (this.visible) { + /* initialize page */ + if (!this.initialized && this.initialize) + this.initialized = this.initialize(this.pageContainer) + + /* set selected attribute on the link */ + for (const a of menu.querySelectorAll("a")) { + if (this.endpoints.includes(a.getAttribute("href"))) + a.dataset.selected = "1" + else + delete a.dataset.selected + } + } } } diff --git a/src/style.css b/src/style.css index 14d8ed1..39e320b 100644 --- a/src/style.css +++ b/src/style.css @@ -2,6 +2,7 @@ @source "../public/index.html"; :root { + --font-sans: "Overpass", sans-serif; --immich-dark-primary: rgb(172 203 250); --immich-dark-secondary: rgb(33 33 33); --immich-dark-secondary-border: rgb(33 33 33 / .1); @@ -11,19 +12,6 @@ --immich-dark-hover-border: rgb(31 41 55); } -body { - background: black; - color-scheme: dark; - color: white; - height: 100vh; - max-height: 100vh; - display: flex; - flex-direction: column; - margin: 0; - font-family: "Overpass", sans-serif; - overflow: hidden; -} - main, #slideshow { height: 100%; display: flex; @@ -31,37 +19,17 @@ main, #slideshow { overflow: hidden; } -/* slideshow */ -#slideshow-carousel { - height: 100% +.svgbtn { + @apply bg-none border-0 p-0 cursor-pointer; } +/* slideshow */ .carousel-cell { - height: 100%; - width: 80vw; - margin: 24px; -} - -.carousel-cell img { - vertical-align: middle; -/* border-radius: 10px; */ - height: 100%; - max-width: 100%; - object-fit: contain; -} - -#slideshow-share button, -#slideshow-bottom-controls button { - background: none; - border: none; - padding: 0; -} + @apply h-full w-[70vw] m-3 md:w-[80vw] md:m-6; -#slideshow-share svg { height: 24px; width: 24px; } -#slideshow-share button { - padding: 12px; - width: 48px; - height: 48px; + img { + @apply align-middle h-full max-w-full object-contain; + } } #slideshow-share, @@ -99,7 +67,6 @@ main, #slideshow { width: 100%; max-width: 768px; background-color: var(--immich-dark-secondary); - font-family: "Overpass", sans-serif; &:focus { outline: 2px solid rgb(55, 65, 81) } } @@ -109,17 +76,16 @@ main, #slideshow { width: max-content; margin: auto; padding: 2rem; +} - .album { - position: relative; - display: flex; - height: 10rem; - gap: 1.5em; - padding: 1rem; - border: 1px solid transparent; - border-bottom: 1px solid var(--selected-border); - border-top: 1px solid var(--selected-border); - } +#albums-container .album { + border: 1px solid transparent; + border-bottom: 1px solid var(--selected-border); + border-top: 1px solid var(--selected-border); + @apply flex relative h-40 gap-6 p-4 cursor-pointer + data-selected:bg-slate-950 data-selected:hover:bg-slate-900 + hover:bg-gray-900 + ; } @media (max-width: 512px) { @@ -130,26 +96,9 @@ main, #slideshow { } } -@media (max-width: 768px) { - .carousel-cell { - width: 70vw; - margin: 12px; - } -} - -#menu { - a { - display: flex; - align-items: center; - justify-content: center; - text-decoration: none; - width: 100%; - gap: 1rem; - - span { - font-size: .875rem; - line-height: 1.25rem; - font-weight: 500; - } - } +#menu a { + @apply flex items-center justify-center no-underline w-full gap-4 + hover:text-blue-300 hover:fill-blue-300 + data-selected:text-blue-300 data-selected:fill-blue-300 + ; } -- cgit v1.2.3