From 5ef1d2acb24e7b9ec8566ba29ae4dd025c78d7cb Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Wed, 11 Jun 2025 21:09:11 -0500 Subject: stupid huge update lots of cool stuff --- package-lock.json | 679 ++++++++++++++++++++- package.json | 4 +- postcss.config.js | 7 +- public/index.html | 28 +- src/albums.js | 16 +- src/connector.js | 19 +- src/icons.js | 7 +- ...rcle_24dp_E3E3E3_FILL1_wght400_GRAD0_opsz24.svg | 1 + ...lect_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg | 1 + ..._new_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg | 1 + src/icons/removefill.sh | 3 + ...arch_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg | 1 + ..._all_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg | 1 + src/index.js | 2 +- src/slides.js | 37 +- src/style.css | 97 ++- webpack.config.js | 13 +- 17 files changed, 870 insertions(+), 47 deletions(-) create mode 100644 src/icons/check_circle_24dp_E3E3E3_FILL1_wght400_GRAD0_opsz24.svg create mode 100644 src/icons/deselect_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg create mode 100644 src/icons/open_in_new_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg create mode 100644 src/icons/search_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg create mode 100644 src/icons/select_all_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg diff --git a/package-lock.json b/package-lock.json index a2bc97d..eefecf6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "socket.io-client": "^4.8.1" }, "devDependencies": { + "@tailwindcss/postcss": "^4.1.10", "autoprefixer": "^10.4.21", "css-loader": "^7.1.2", "postcss": "^8.5.3", @@ -17,11 +18,39 @@ "postcss-nested": "^7.0.2", "style-loader": "^4.0.0", "svg-sprite-loader": "^6.0.11", - "webpack": "^5.99.7", + "tailwindcss": "^4.1.10", + "webpack": "^5.99.9", "webpack-cli": "^6.0.1", "webpack-dev-server": "^5.2.1" } }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@babel/code-frame": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", @@ -66,6 +95,19 @@ "url": "https://github.com/sponsors/ayuhito" } }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.8", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", @@ -200,6 +242,292 @@ "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", "license": "MIT" }, + "node_modules/@tailwindcss/node": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.10.tgz", + "integrity": "sha512-2ACf1znY5fpRBwRhMgj9ZXvb2XZW8qs+oTfotJ2C5xR0/WNL7UHZ7zXl6s+rUqedL1mNi+0O+WQr5awGowS3PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.3.0", + "enhanced-resolve": "^5.18.1", + "jiti": "^2.4.2", + "lightningcss": "1.30.1", + "magic-string": "^0.30.17", + "source-map-js": "^1.2.1", + "tailwindcss": "4.1.10" + } + }, + "node_modules/@tailwindcss/node/node_modules/jiti": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", + "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.10.tgz", + "integrity": "sha512-v0C43s7Pjw+B9w21htrQwuFObSkio2aV/qPx/mhrRldbqxbWJK6KizM+q7BF1/1CmuLqZqX3CeYF7s7P9fbA8Q==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.4", + "tar": "^7.4.3" + }, + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.1.10", + "@tailwindcss/oxide-darwin-arm64": "4.1.10", + "@tailwindcss/oxide-darwin-x64": "4.1.10", + "@tailwindcss/oxide-freebsd-x64": "4.1.10", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.10", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.10", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.10", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.10", + "@tailwindcss/oxide-linux-x64-musl": "4.1.10", + "@tailwindcss/oxide-wasm32-wasi": "4.1.10", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.10", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.10" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.10.tgz", + "integrity": "sha512-VGLazCoRQ7rtsCzThaI1UyDu/XRYVyH4/EWiaSX6tFglE+xZB5cvtC5Omt0OQ+FfiIVP98su16jDVHDEIuH4iQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.10.tgz", + "integrity": "sha512-ZIFqvR1irX2yNjWJzKCqTCcHZbgkSkSkZKbRM3BPzhDL/18idA8uWCoopYA2CSDdSGFlDAxYdU2yBHwAwx8euQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.10.tgz", + "integrity": "sha512-eCA4zbIhWUFDXoamNztmS0MjXHSEJYlvATzWnRiTqJkcUteSjO94PoRHJy1Xbwp9bptjeIxxBHh+zBWFhttbrQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.10.tgz", + "integrity": "sha512-8/392Xu12R0cc93DpiJvNpJ4wYVSiciUlkiOHOSOQNH3adq9Gi/dtySK7dVQjXIOzlpSHjeCL89RUUI8/GTI6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.10.tgz", + "integrity": "sha512-t9rhmLT6EqeuPT+MXhWhlRYIMSfh5LZ6kBrC4FS6/+M1yXwfCtp24UumgCWOAJVyjQwG+lYva6wWZxrfvB+NhQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.10.tgz", + "integrity": "sha512-3oWrlNlxLRxXejQ8zImzrVLuZ/9Z2SeKoLhtCu0hpo38hTO2iL86eFOu4sVR8cZc6n3z7eRXXqtHJECa6mFOvA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.10.tgz", + "integrity": "sha512-saScU0cmWvg/Ez4gUmQWr9pvY9Kssxt+Xenfx1LG7LmqjcrvBnw4r9VjkFcqmbBb7GCBwYNcZi9X3/oMda9sqQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.10.tgz", + "integrity": "sha512-/G3ao/ybV9YEEgAXeEg28dyH6gs1QG8tvdN9c2MNZdUXYBaIY/Gx0N6RlJzfLy/7Nkdok4kaxKPHKJUlAaoTdA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.10.tgz", + "integrity": "sha512-LNr7X8fTiKGRtQGOerSayc2pWJp/9ptRYAa4G+U+cjw9kJZvkopav1AQc5HHD+U364f71tZv6XamaHKgrIoVzA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.10.tgz", + "integrity": "sha512-d6ekQpopFQJAcIK2i7ZzWOYGZ+A6NzzvQ3ozBvWFdeyqfOZdYHU66g5yr+/HC4ipP1ZgWsqa80+ISNILk+ae/Q==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@emnapi/wasi-threads": "^1.0.2", + "@napi-rs/wasm-runtime": "^0.2.10", + "@tybys/wasm-util": "^0.9.0", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.10.tgz", + "integrity": "sha512-i1Iwg9gRbwNVOCYmnigWCCgow8nDWSFmeTUU5nbNx3rqbe4p0kRbEqLwLJbYZKmSSp23g4N6rCDmm7OuPBXhDA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.10.tgz", + "integrity": "sha512-sGiJTjcBSfGq2DVRtaSljq5ZgZS2SDHSIfhOylkBvHVjwOsodBhnb3HdmiKkVuUGKD0I7G63abMOVaskj1KpOA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/postcss": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.10.tgz", + "integrity": "sha512-B+7r7ABZbkXJwpvt2VMnS6ujcDoR2OOcFaqrLIo1xbcdxje4Vf+VgJdBzNNbrAjBj/rLZ66/tlQ1knIGNLKOBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "@tailwindcss/node": "4.1.10", + "@tailwindcss/oxide": "4.1.10", + "postcss": "^8.4.41", + "tailwindcss": "4.1.10" + } + }, "node_modules/@types/body-parser": { "version": "1.19.5", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", @@ -1281,6 +1609,16 @@ "fsevents": "~2.3.2" } }, + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, "node_modules/chrome-trace-event": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", @@ -1784,6 +2122,16 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/detect-libc": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, "node_modules/detect-node": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", @@ -3966,6 +4314,245 @@ "shell-quote": "^1.8.1" } }, + "node_modules/lightningcss": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", + "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-darwin-arm64": "1.30.1", + "lightningcss-darwin-x64": "1.30.1", + "lightningcss-freebsd-x64": "1.30.1", + "lightningcss-linux-arm-gnueabihf": "1.30.1", + "lightningcss-linux-arm64-gnu": "1.30.1", + "lightningcss-linux-arm64-musl": "1.30.1", + "lightningcss-linux-x64-gnu": "1.30.1", + "lightningcss-linux-x64-musl": "1.30.1", + "lightningcss-win32-arm64-msvc": "1.30.1", + "lightningcss-win32-x64-msvc": "1.30.1" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz", + "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz", + "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz", + "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz", + "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz", + "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz", + "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz", + "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz", + "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz", + "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz", + "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -4011,6 +4598,16 @@ "node": ">=8" } }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, "node_modules/map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", @@ -4191,6 +4788,29 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minizlib": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz", + "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, "node_modules/mitt": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/mitt/-/mitt-1.1.2.tgz", @@ -4225,6 +4845,22 @@ "node": ">=0.10.0" } }, + "node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -6638,6 +7274,13 @@ "node": ">=6" } }, + "node_modules/tailwindcss": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.10.tgz", + "integrity": "sha512-P3nr6WkvKV/ONsTzj6Gb57sWPMX29EPNPopo7+FcpkQaNsrNpZ1pv8QmrYI2RqEKD7mlGqLnGovlcYnBK0IqUA==", + "dev": true, + "license": "MIT" + }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -6648,6 +7291,24 @@ "node": ">=6" } }, + "node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/terser": { "version": "5.39.0", "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.0.tgz", @@ -7228,9 +7889,9 @@ } }, "node_modules/webpack": { - "version": "5.99.7", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.7.tgz", - "integrity": "sha512-CNqKBRMQjwcmKR0idID5va1qlhrqVUKpovi+Ec79ksW8ux7iS1+A6VqzfZXgVYCFRKl7XL5ap3ZoMpwBJxcg0w==", + "version": "5.99.9", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.9.tgz", + "integrity": "sha512-brOPwM3JnmOa+7kd3NsmOUOwbDAj8FT9xDsG3IW0MgbN9yZV7Oi/s/+MNQ/EcSMqw7qfoRyXPoeEWT8zLVdVGg==", "dev": true, "license": "MIT", "dependencies": { @@ -7614,6 +8275,16 @@ "engines": { "node": ">=0.4.0" } + }, + "node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } } } } diff --git a/package.json b/package.json index 7034250..e27733c 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "socket.io-client": "^4.8.1" }, "devDependencies": { + "@tailwindcss/postcss": "^4.1.10", "autoprefixer": "^10.4.21", "css-loader": "^7.1.2", "postcss": "^8.5.3", @@ -16,7 +17,8 @@ "postcss-nested": "^7.0.2", "style-loader": "^4.0.0", "svg-sprite-loader": "^6.0.11", - "webpack": "^5.99.7", + "tailwindcss": "^4.1.10", + "webpack": "^5.99.9", "webpack-cli": "^6.0.1", "webpack-dev-server": "^5.2.1" } diff --git a/postcss.config.js b/postcss.config.js index 5307961..52b9b4b 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -1,6 +1,5 @@ module.exports = { - plugins: [ - require("autoprefixer"), - require("postcss-nested"), - ], + plugins: { + '@tailwindcss/postcss': {}, + }, } diff --git a/public/index.html b/public/index.html index 20f210b..df128f2 100644 --- a/public/index.html +++ b/public/index.html @@ -16,13 +16,10 @@ - + +
@@ -30,15 +27,22 @@
diff --git a/src/albums.js b/src/albums.js index e10dd54..19602df 100644 --- a/src/albums.js +++ b/src/albums.js @@ -8,7 +8,8 @@ export default async function initAlbums(albumsPageContainer) { async function createAlbum(res) { console.log(res.albumName, res.id, res.startDate, res.endDate, res.assetCount, res.shared) const albumClone = albumTemplate.content.cloneNode(true) - albumClone.querySelector(".album-thumb").src = apiConnector.albumThumbSrc(res.albumThumbnailAssetId) + albumClone.querySelector(".album").dataset.key = res.id + albumClone.querySelector(".album-thumb").src = apiConnector.assetThumbnailSrc(res.albumThumbnailAssetId) albumClone.querySelector(".album-name").textContent = res.albumName albumClone.querySelector(".album-assets-count").textContent = res.assetCount.toLocaleString() if (!res.shared) @@ -22,5 +23,18 @@ export default async function initAlbums(albumsPageContainer) { for (const res of albumsResponse) createAlbum(res) + albumsContainer.addEventListener("click", e => { + // find album element + let album = e.target + while (album && !album.classList.contains("album")) + album = album.parentElement + + if (album === null) + return + + console.log(album) + album.classList.toggle("selected") + }) + return true } diff --git a/src/connector.js b/src/connector.js index 6c557a8..03e6f3d 100644 --- a/src/connector.js +++ b/src/connector.js @@ -6,16 +6,14 @@ class APIConnector { this.socket = io(url) this.asset_index = 0 - this.asset = null - this.prevAssets = null - this.nextAssets = null + this.movement = 0 + this.assets = null this.seekCallbacks = [] this.socket.on("seek", e => { - this.asset_index = e.asset_index - this.asset = e.asset - this.prevAssets = e.prev_assets - this.nextAssets = e.next_assets + this.assetIndex = e.asset_index + this.movement = e.movement + this.assets = e.assets for (const cb of this.seekCallbacks) cb() }) @@ -46,12 +44,11 @@ class APIConnector { } fetchAlbums() { - return this.fetch("/albums/get") + return this.fetch("/albums") } - albumThumbSrc(key) { - return `${this.url}/api/albums/thumb/${key}` - } + assetSrc(key) { return `${this.url}/api/asset/${key}` } + assetThumbnailSrc(key) { return `${this.url}/api/asset/${key}/thumbnail` } } const apiConnector = new APIConnector("http://localhost:5000") diff --git a/src/icons.js b/src/icons.js index dd75a4a..099db45 100644 --- a/src/icons.js +++ b/src/icons.js @@ -1,11 +1,16 @@ +import "./icons/check_circle_24dp_E3E3E3_FILL1_wght400_GRAD0_opsz24.svg" +import "./icons/deselect_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg" import "./icons/download_24dp_FFFFFF_FILL0_wght400_GRAD0_opsz24.svg" import "./icons/image_24dp_FFFFFF_FILL1_wght400_GRAD0_opsz24.svg" +import "./icons/open_in_new_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg" import "./icons/pause_24dp_FFFFFF_FILL1_wght400_GRAD0_opsz24.svg" import "./icons/photo_album_24dp_FFFFFF_FILL1_wght400_GRAD0_opsz24.svg" import "./icons/photo_frame_24dp_FFFFFF_FILL1_wght400_GRAD0_opsz24.svg" import "./icons/play_arrow_24dp_FFFFFF_FILL1_wght400_GRAD0_opsz24.svg" -import "./icons/share_24dp_FFFFFF_FILL0_wght400_GRAD0_opsz24.svg" +import "./icons/search_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg" +import "./icons/select_all_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg" import "./icons/settings_24dp_FFFFFF_FILL1_wght400_GRAD0_opsz24.svg" +import "./icons/share_24dp_FFFFFF_FILL0_wght400_GRAD0_opsz24.svg" import "./icons/skip_next_24dp_FFFFFF_FILL1_wght400_GRAD0_opsz24.svg" import "./icons/skip_previous_24dp_FFFFFF_FILL1_wght400_GRAD0_opsz24.svg" import "./icons/slideshow_24dp_FFFFFF_FILL1_wght400_GRAD0_opsz24.svg" diff --git a/src/icons/check_circle_24dp_E3E3E3_FILL1_wght400_GRAD0_opsz24.svg b/src/icons/check_circle_24dp_E3E3E3_FILL1_wght400_GRAD0_opsz24.svg new file mode 100644 index 0000000..028526b --- /dev/null +++ b/src/icons/check_circle_24dp_E3E3E3_FILL1_wght400_GRAD0_opsz24.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/deselect_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg b/src/icons/deselect_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg new file mode 100644 index 0000000..dd46e14 --- /dev/null +++ b/src/icons/deselect_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/open_in_new_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg b/src/icons/open_in_new_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg new file mode 100644 index 0000000..12e0802 --- /dev/null +++ b/src/icons/open_in_new_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/removefill.sh b/src/icons/removefill.sh index c61fd98..399e8e4 100755 --- a/src/icons/removefill.sh +++ b/src/icons/removefill.sh @@ -1,3 +1,6 @@ #!/bin/sh # Google Material Icons -- complete default settings sed -Ei 's/ ?fill="#[0-9a-fA-F]{6}"//' *.svg +for svg in *.svg; do + echo "import \"./icons/$svg\"" +done diff --git a/src/icons/search_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg b/src/icons/search_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg new file mode 100644 index 0000000..1d95298 --- /dev/null +++ b/src/icons/search_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/select_all_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg b/src/icons/select_all_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg new file mode 100644 index 0000000..3a6618e --- /dev/null +++ b/src/icons/select_all_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/index.js b/src/index.js index a6d2130..d27c8db 100644 --- a/src/index.js +++ b/src/index.js @@ -20,7 +20,7 @@ function softRedirect(e) { e.preventDefault() let a = e.target if (a === null) return - while (a.tagName !== "A" && a !== null) + while (a !== null && a.tagName !== "A") a = a.parentElement if (a === null) return Page.softRedirect(a.href) diff --git a/src/slides.js b/src/slides.js index 94af74e..fad6472 100644 --- a/src/slides.js +++ b/src/slides.js @@ -6,11 +6,19 @@ class Slides { constructor(slidesContainer) { /* previous selected index */ this.selectedIndex = 0 + this.assetIndex = 0 this.slidesContainer = slidesContainer + /* append 11 cells to carousel */ + const carousel = this.slidesContainer.querySelector("#slideshow-carousel") + const cellTemplate = this.slidesContainer.querySelector("#carousel-cell-template") + this.cells = [] + for (let i = 0; i < 11; i++) + carousel.appendChild(cellTemplate.content.cloneNode(true)) + /* initialize slides */ - this.flickity = new Flickity("#slideshow-carousel", { + this.flickity = new Flickity(carousel, { wrapAround: true, prevNextButtons: false, pageDots: false, @@ -29,6 +37,9 @@ class Slides { seekPrevButton.addEventListener("click", () => { this.flickity.previous() ; this.seek() }) seekNextButton.addEventListener("click", () => { this.flickity.next() ; this.seek() }) + + /* initialize seek callback */ + apiConnector.seekCallbacks.push(c => { this.seekCallback() }) } seek() { @@ -40,9 +51,31 @@ class Slides { this.flickity.cells.length - this.selectedIndex, // wrap forwards (-1 -> 0) ].reduce((key, v) => Math.abs(v) < Math.abs(key) ? v : key) this.selectedIndex = this.flickity.selectedIndex + this.assetIndex += increment apiConnector.seek(increment) } + seekCallback() { + let i + if (this.assetIndex !== apiConnector.assetIndex) { + this.assetIndex = apiConnector.assetIndex + i = apiConnector.movement + + for (; i > 0; i--) this.flickity.next() + for (; i < 0; i++) this.flickity.previous() + this.selectedIndex = this.flickity.selectedIndex + } + + // load new imgs + // TODO need to make the 11 cells a constant somehow + for (i = 0; i < this.flickity.cells.length; i++) { + const x = (i + this.selectedIndex + 6) % this.flickity.cells.length + const e = this.flickity.cells[x].element + const img = e.firstElementChild + img.src = apiConnector.assetSrc(apiConnector.assets[i]) + } + } + /* Flickity function for scrolling to ensure next and prev pics are always * visible and to transition between states */ scroll(progress) { @@ -89,7 +122,7 @@ class Slides { for (let i = 0; i < imgs.length; i++) { const img = imgs[i] img.dataset.index = i - img.addEventListener("load", this.imageLoaded) + img.addEventListener("load", e => { this.imageLoaded(e) }) if (img.complete) this.positionImageStatic(img) } diff --git a/src/style.css b/src/style.css index e84921e..f370f2c 100644 --- a/src/style.css +++ b/src/style.css @@ -1,11 +1,21 @@ +@import "tailwindcss" source(none); +@source "../public/*.html"; + :root { --immich-dark-primary: rgb(172 203 250); + --immich-dark-secondary: rgb(33 33 33); + --immich-dark-secondary-border: rgb(33 33 33 / .1); + --selected-bg: rgb(172 203 250 / .1); + --selected-border: rgb(172 203 250 / .1); + --immich-dark-hover-bg: rgb(17 24 39); + --immich-dark-hover-border: rgb(31 41 55); } .font-bold { font-weight: 700 } body { background: black; + color-scheme: dark; color: white; height: 100vh; max-height: 100vh; @@ -13,18 +23,25 @@ body { flex-direction: column; margin: 0; font-family: "Overpass", sans-serif; + overflow: hidden; } main, #slideshow { height: 100%; display: flex; flex-direction: column; + overflow: hidden; } svg { fill: white; width: 100%; height: 100%; + + &.p24 { + width: 24px; + height: 24px; + } } /* slideshow */ @@ -35,10 +52,7 @@ svg { .carousel-cell { height: 100%; width: 80vw; - margin: 24px; - - } .carousel-cell img { @@ -86,26 +100,91 @@ svg { /* albums */ #albums { - width: 100%; height: 100%; overflow: scroll; + margin-inline: 1rem; +} +#album-search { + display: block; + padding: 1rem; + border-radius: 1rem; + border: 0; + margin: 1rem auto; + width: 100%; + max-width: 768px; + background-color: var(--immich-dark-secondary); + font-family: "Overpass", sans-serif; + + &:focus { outline: 2px solid rgb(55, 65, 81) } } #albums-container { display: grid; - grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); - gap: 2.5rem; - max-width: 1366px; + grid-template-columns: repeat(auto-fill, minmax(768px, 1fr)); + 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); + /*border-bottom: 1px solid var(--immich-dark-hover-border);*/ + + .album-selector { + opacity: 0; + border-radius: 50%; + align-self: center + } + + &.selected { + background: var(--selected-bg); + } + + &:hover { + cursor: pointer; + background: var(--immich-dark-hover-bg); + border: 1px solid var(--immich-dark-hover-border); + + .album-selector { opacity: .5 } + .album-thumb { + box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 15px -3px, rgba(0, 0, 0, 0.1) 0px 4px 6px -4px; + } + .album-name { color: var(--immich-dark-primary) } + .album-open { opacity: 1 } + } + + + &.selected .album-selector { + opacity: 1; + fill: var(--immich-dark-primary); + background: black; + } + } + .album-thumb { - width: 100%; aspect-ratio: 1/1; object-fit: cover; border-radius: 1rem; - margin-bottom: 1rem; } + .album-desc-grid { + display: flex; + justify-content: space-between; + align-self: center; + font-size: 18px; + } + + .album-open { + position: absolute; + bottom: 1rem; + right: 1rem; + opacity: 0; + } } @media (max-width: 512px) { diff --git a/webpack.config.js b/webpack.config.js index 529e222..ba6756e 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -8,7 +8,18 @@ module.exports = { use: [ "style-loader", "css-loader", - "postcss-loader", + { + loader: "postcss-loader", + options: { + postcssOptions: { + plugins: [ + require("autoprefixer"), + require("postcss-nested"), + require("@tailwindcss/postcss"), + ] + } + } + }, ], }, { -- cgit v1.2.3