diff --git a/CHANGELOG.md b/CHANGELOG.md index 0cdbc6e..1757c8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,18 @@ # Change Log -## [0.2.5] - 2022-04-28 +## [0.2.6] - 2022-06-23 +### Added +- Gallery supports collapsible subfolders +- Sort subfolders and files by alphanumeric order + +## [0.2.5] - 2022-05-14 ### Added - Sort filenames by alphanumeric order by default - Added additional configuration for sorting in settings -## [0.2.3] - 2022-04-28 +## [0.2.4] - 2022-05-12 + +## [0.2.3] - 2022-05-01 ### Added - Display filename as tab title in the viewer - Display filename underneath each image in gallery diff --git a/README.md b/README.md index c05a03a..aa1f204 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ A light-weighted extension that brings you the best image browsing experience in - Smooth panning and zooming - Gallery view of images - Lazily load images as they are scrolled into view +- Collapsible subfolders - Clicking on an image opens it up in a viewer tab - Auto-refresh when modified - Extension size less than 1 MB diff --git a/media/gallery.css b/media/gallery.css index 80359aa..d2c3be6 100644 --- a/media/gallery.css +++ b/media/gallery.css @@ -4,6 +4,7 @@ html { scroll-behavior: smooth; + overflow-y: scroll; } .grid { @@ -12,7 +13,7 @@ html { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); grid-auto-rows: 250px; grid-gap: 10px; - padding: 10px + padding: 10px; } .image-container { @@ -56,4 +57,24 @@ html { text-overflow: ellipsis; overflow: hidden; white-space: nowrap; +} + +.folder { + margin-top: 5px; + padding: 15px; + display: flex; + width: 100%; + background-color: hsl(0, 0%, 17%); + color: white; + border: 0; +} + +.folder-title { + padding-left: 10px; + text-align: left; + flex-grow: 1; +} + +.folder:hover { + box-shadow: 0 0 10px hsl(60, 65%, 90%); } \ No newline at end of file diff --git a/media/gallery.js b/media/gallery.js index 7ae7963..250a7b7 100644 --- a/media/gallery.js +++ b/media/gallery.js @@ -2,7 +2,6 @@ (function () { const vscode = acquireVsCodeApi(); - let grid = document.getElementsByClassName("grid")[0]; let lazyloadImages = document.querySelectorAll(".lazy"); let imageObserver = new IntersectionObserver((entries, observer) => { entries.forEach(entry => { @@ -14,9 +13,6 @@ image.classList.remove("lazy"); image.classList.add("loaded"); }; - if (lazyloadImages[lazyloadImages.length - 1].src === image.src) { - imageObserver.disconnect(); - } } }); }); @@ -24,27 +20,48 @@ lazyloadImages.forEach((image) => { imageObserver.observe(image); }); - + document.addEventListener('click', event => { let node = event && event.target; + const folderHeader = ['folder','folder-title','folder-arrow']; + if (folderHeader.some(el => node.classList.contains(el))) { + console.log(node); + let id = ''; + if (node.classList.contains('folder')) { + id = node.id; + } else { + let lastIndexToSplit = node.id.lastIndexOf('-'); + id = node.id.slice(0, lastIndexToSplit); + + } + + let folderGrid = document.getElementById(id + '-grid'); + let folderArrow = document.getElementById(id + '-arrow'); + console.log({folderGrid, folderArrow}); + folderGrid.style.display = folderGrid.style.display === "none" ? "" : "none"; + folderArrow.textContent = folderArrow.textContent === "⮟" ? "⮞" : "⮟"; + } if (!node.classList.contains('image')) { return; } vscode.postMessage({ command: 'vscodeImageGallery.openViewer', src: node.src, }); + }, true); + window.addEventListener('message', event => { const message = event.data; switch (message.command) { case 'vscodeImageGallery.addImage': + let addedTimestamp = new Date().getTime(); let imgNode = document.createElement("img"); imgNode.setAttribute("class", "image loaded"); imgNode.setAttribute("id", message.imgPath); - imgNode.setAttribute("src", message.imgSrc); - imgNode.setAttribute("data-src", message.imgSrc); + imgNode.setAttribute("src", `${message.imgSrc}?t=${addedTimestamp}`); + imgNode.setAttribute("data-src", `${message.imgSrc}?t=${addedTimestamp}`); let divNode = document.createElement("div"); divNode.setAttribute("class", "filename"); @@ -55,13 +72,15 @@ containerNode.setAttribute("class", "image-container"); containerNode.appendChild(imgNode); containerNode.appendChild(divNode); + + let grid = document.getElementById(`${Object.keys(message.pathsBySubFolders)[0]}-grid`); grid.appendChild(containerNode); break; case 'vscodeImageGallery.changeImage': - let timestamp = new Date().getTime(); + let changedTimestamp = new Date().getTime(); let changeImage = document.getElementById(message.imgPath); - changeImage.setAttribute("src", message.imgSrc + "?t=" + timestamp); - changeImage.setAttribute("data-src", message.imgSrc + "?t=" + timestamp); + changeImage.setAttribute("src", `${message.imgSrc}?t=${changedTimestamp}`); + changeImage.setAttribute("data-src", `${message.imgSrc}?t=${changedTimestamp}`); let changeFilename = document.getElementById(message.imgPath + "-filename"); changeFilename.setAttribute("class", "filename"); diff --git a/package-lock.json b/package-lock.json index 74cdb04..703475a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "vscode-image-gallery", - "version": "0.2.4", + "version": "0.2.5", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "vscode-image-gallery", - "version": "0.2.4", + "version": "0.2.5", "dependencies": { "panzoom": "^9.4.2" }, @@ -219,16 +219,6 @@ "integrity": "sha512-wQhExnh2nEzpjDMSKhUvnNmz3ucpd3E+R7wJkOhBNK3No6fG3VUdmVmMOKD0A8NDZDDDiQcLNxe3oGmX5SjJ5w==", "dev": true }, - "node_modules/@types/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", - "dev": true, - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "5.16.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.16.0.tgz", @@ -1347,15 +1337,6 @@ "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", "dev": true }, - "node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true, - "engines": { - "node": ">=0.1.90" - } - }, "node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -2138,41 +2119,6 @@ "node": ">=6" } }, - "node_modules/extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" - }, - "engines": { - "node": ">= 10.17.0" - }, - "optionalDependencies": { - "@types/yauzl": "^2.9.1" - } - }, - "node_modules/extract-zip/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -2849,12 +2795,6 @@ "node": ">= 0.10" } }, - "node_modules/ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "dev": true - }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -3034,12 +2974,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/jpeg-js": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.3.tgz", - "integrity": "sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q==", - "dev": true - }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -3415,18 +3349,6 @@ "node": ">=8.6" } }, - "node_modules/mime": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", - "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", - "dev": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -4081,27 +4003,6 @@ "node": ">=0.10.0" } }, - "node_modules/pixelmatch": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-5.2.1.tgz", - "integrity": "sha512-WjcAdYSnKrrdDdqTcVEY7aB7UhhwjYQKYhHiBXdJef0MOaQeYpUdQ+iVyBLa5YBKS8MPVPPMX7rpOByISLpeEQ==", - "dev": true, - "dependencies": { - "pngjs": "^4.0.1" - }, - "bin": { - "pixelmatch": "bin/pixelmatch" - } - }, - "node_modules/pixelmatch/node_modules/pngjs": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-4.0.1.tgz", - "integrity": "sha512-rf5+2/ioHeQxR6IxuYNYGFytUyG3lma/WW1nsmjeHlWwtb2aByla6dkVc8pmJ9nplzkTA0q2xx7mMWrOTqT4Gg==", - "dev": true, - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -4167,86 +4068,31 @@ } }, "node_modules/playwright": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.21.0.tgz", - "integrity": "sha512-OH5ZFoiS0HkBZzhb7HPVeE8lEx3PO/AaKgoQfgs1NbmwFPqHgPzfKFa3fO+VM27WqTLjtYOL6hM03sWnJhT3ig==", + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.22.2.tgz", + "integrity": "sha512-hUTpg7LytIl3/O4t0AQJS1V6hWsaSY5uZ7w1oCC8r3a1AQN5d6otIdCkiB3cbzgQkcMaRxisinjMFMVqZkybdQ==", "dev": true, "hasInstallScript": true, "dependencies": { - "playwright-core": "1.21.0" + "playwright-core": "1.22.2" }, "bin": { "playwright": "cli.js" }, "engines": { - "node": ">=12" + "node": ">=14" } }, "node_modules/playwright-core": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.21.0.tgz", - "integrity": "sha512-yDGVs9qaaW6WiefgR7wH1CGt9D6D/X4U3jNpIzH0FjjrrWLCOYQo78Tu3SkW8X+/kWlBpj49iWf3QNSxhYc12Q==", + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.22.2.tgz", + "integrity": "sha512-w/hc/Ld0RM4pmsNeE6aL/fPNWw8BWit2tg+TfqJ3+p59c6s3B6C8mXvXrIPmfQEobkcFDc+4KirNzOQ+uBSP1Q==", "dev": true, - "dependencies": { - "colors": "1.4.0", - "commander": "8.3.0", - "debug": "4.3.3", - "extract-zip": "2.0.1", - "https-proxy-agent": "5.0.0", - "jpeg-js": "0.4.3", - "mime": "3.0.0", - "pixelmatch": "5.2.1", - "pngjs": "6.0.0", - "progress": "2.0.3", - "proper-lockfile": "4.1.2", - "proxy-from-env": "1.1.0", - "rimraf": "3.0.2", - "socks-proxy-agent": "6.1.1", - "stack-utils": "2.0.5", - "ws": "8.4.2", - "yauzl": "2.10.0", - "yazl": "2.5.1" - }, "bin": { "playwright": "cli.js" }, "engines": { - "node": ">=12" - } - }, - "node_modules/playwright-core/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "dev": true, - "engines": { - "node": ">= 12" - } - }, - "node_modules/playwright-core/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/pngjs": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-6.0.0.tgz", - "integrity": "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==", - "dev": true, - "engines": { - "node": ">=12.13.0" + "node": ">=14" } }, "node_modules/prebuild-install": { @@ -4291,32 +4137,6 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/proper-lockfile": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", - "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.4", - "retry": "^0.12.0", - "signal-exit": "^3.0.2" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true - }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -4569,15 +4389,6 @@ "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", "dev": true }, - "node_modules/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", - "dev": true, - "engines": { - "node": ">= 4" - } - }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -4832,44 +4643,6 @@ "node": ">=8" } }, - "node_modules/smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "dev": true, - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz", - "integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==", - "dev": true, - "dependencies": { - "ip": "^1.1.5", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.13.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks-proxy-agent": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.1.1.tgz", - "integrity": "sha512-t8J0kG3csjA4g6FTbsMOWws+7R7vuRC8aQ/wy3/1OWmsgwA68zs/+cExQ0koSitUDXqhufF/YJr9wtNMZHw5Ew==", - "dev": true, - "dependencies": { - "agent-base": "^6.0.2", - "debug": "^4.3.1", - "socks": "^2.6.1" - }, - "engines": { - "node": ">= 10" - } - }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -4889,27 +4662,6 @@ "source-map": "^0.6.0" } }, - "node_modules/stack-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", @@ -5770,27 +5522,6 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "node_modules/ws": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.4.2.tgz", - "integrity": "sha512-Kbk4Nxyq7/ZWqr/tarI9yIt/+iNNFOjBXEWgTb4ydaNHBNGgvf2QHbS9fdfsndfjFlFwEd4Al+mw83YkaD10ZA==", - "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/xml2js": { "version": "0.4.23", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", @@ -6081,16 +5812,6 @@ "integrity": "sha512-wQhExnh2nEzpjDMSKhUvnNmz3ucpd3E+R7wJkOhBNK3No6fG3VUdmVmMOKD0A8NDZDDDiQcLNxe3oGmX5SjJ5w==", "dev": true }, - "@types/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", - "dev": true, - "optional": true, - "requires": { - "@types/node": "*" - } - }, "@typescript-eslint/eslint-plugin": { "version": "5.16.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.16.0.tgz", @@ -6919,12 +6640,6 @@ "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", "dev": true }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true - }, "commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -7518,29 +7233,6 @@ "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", "dev": true }, - "extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dev": true, - "requires": { - "@types/yauzl": "^2.9.1", - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "dependencies": { - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - } - } - }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -8048,12 +7740,6 @@ "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", "dev": true }, - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "dev": true - }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -8181,12 +7867,6 @@ } } }, - "jpeg-js": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.3.tgz", - "integrity": "sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q==", - "dev": true - }, "js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -8494,12 +8174,6 @@ "picomatch": "^2.3.1" } }, - "mime": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", - "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", - "dev": true - }, "mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -9008,23 +8682,6 @@ "pinkie": "^2.0.0" } }, - "pixelmatch": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-5.2.1.tgz", - "integrity": "sha512-WjcAdYSnKrrdDdqTcVEY7aB7UhhwjYQKYhHiBXdJef0MOaQeYpUdQ+iVyBLa5YBKS8MPVPPMX7rpOByISLpeEQ==", - "dev": true, - "requires": { - "pngjs": "^4.0.1" - }, - "dependencies": { - "pngjs": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-4.0.1.tgz", - "integrity": "sha512-rf5+2/ioHeQxR6IxuYNYGFytUyG3lma/WW1nsmjeHlWwtb2aByla6dkVc8pmJ9nplzkTA0q2xx7mMWrOTqT4Gg==", - "dev": true - } - } - }, "pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -9074,61 +8731,18 @@ } }, "playwright": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.21.0.tgz", - "integrity": "sha512-OH5ZFoiS0HkBZzhb7HPVeE8lEx3PO/AaKgoQfgs1NbmwFPqHgPzfKFa3fO+VM27WqTLjtYOL6hM03sWnJhT3ig==", + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.22.2.tgz", + "integrity": "sha512-hUTpg7LytIl3/O4t0AQJS1V6hWsaSY5uZ7w1oCC8r3a1AQN5d6otIdCkiB3cbzgQkcMaRxisinjMFMVqZkybdQ==", "dev": true, "requires": { - "playwright-core": "1.21.0" + "playwright-core": "1.22.2" } }, "playwright-core": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.21.0.tgz", - "integrity": "sha512-yDGVs9qaaW6WiefgR7wH1CGt9D6D/X4U3jNpIzH0FjjrrWLCOYQo78Tu3SkW8X+/kWlBpj49iWf3QNSxhYc12Q==", - "dev": true, - "requires": { - "colors": "1.4.0", - "commander": "8.3.0", - "debug": "4.3.3", - "extract-zip": "2.0.1", - "https-proxy-agent": "5.0.0", - "jpeg-js": "0.4.3", - "mime": "3.0.0", - "pixelmatch": "5.2.1", - "pngjs": "6.0.0", - "progress": "2.0.3", - "proper-lockfile": "4.1.2", - "proxy-from-env": "1.1.0", - "rimraf": "3.0.2", - "socks-proxy-agent": "6.1.1", - "stack-utils": "2.0.5", - "ws": "8.4.2", - "yauzl": "2.10.0", - "yazl": "2.5.1" - }, - "dependencies": { - "commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "dev": true - }, - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - } - } - }, - "pngjs": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-6.0.0.tgz", - "integrity": "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==", + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.22.2.tgz", + "integrity": "sha512-w/hc/Ld0RM4pmsNeE6aL/fPNWw8BWit2tg+TfqJ3+p59c6s3B6C8mXvXrIPmfQEobkcFDc+4KirNzOQ+uBSP1Q==", "dev": true }, "prebuild-install": { @@ -9164,29 +8778,6 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "proper-lockfile": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", - "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.4", - "retry": "^0.12.0", - "signal-exit": "^3.0.2" - } - }, - "proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true - }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -9379,12 +8970,6 @@ } } }, - "retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", - "dev": true - }, "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -9541,33 +9126,6 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, - "smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "dev": true - }, - "socks": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz", - "integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==", - "dev": true, - "requires": { - "ip": "^1.1.5", - "smart-buffer": "^4.2.0" - } - }, - "socks-proxy-agent": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.1.1.tgz", - "integrity": "sha512-t8J0kG3csjA4g6FTbsMOWws+7R7vuRC8aQ/wy3/1OWmsgwA68zs/+cExQ0koSitUDXqhufF/YJr9wtNMZHw5Ew==", - "dev": true, - "requires": { - "agent-base": "^6.0.2", - "debug": "^4.3.1", - "socks": "^2.6.1" - } - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -9584,23 +9142,6 @@ "source-map": "^0.6.0" } }, - "stack-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - } - } - }, "statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", @@ -10248,13 +9789,6 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "ws": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.4.2.tgz", - "integrity": "sha512-Kbk4Nxyq7/ZWqr/tarI9yIt/+iNNFOjBXEWgTb4ydaNHBNGgvf2QHbS9fdfsndfjFlFwEd4Al+mw83YkaD10ZA==", - "dev": true, - "requires": {} - }, "xml2js": { "version": "0.4.23", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", diff --git a/package.json b/package.json index b514730..f966fb1 100644 --- a/package.json +++ b/package.json @@ -2,13 +2,17 @@ "name": "vscode-image-gallery", "displayName": "Image Gallery", "description": "An extension that enhances image browsing experience.", - "version": "0.2.5", + "version": "0.2.6", "publisher": "GeriYoco", "repository": { "type": "git", "url": "https://github.com/geriyoco/vscode-image-gallery" }, "icon": "docs/logo-128.png", + "galleryBanner": { + "color": "#000000", + "theme": "dark" + }, "engines": { "vscode": "^1.65.0" }, diff --git a/src/file_watcher.ts b/src/file_watcher.ts index 79ea514..a83c4f9 100644 --- a/src/file_watcher.ts +++ b/src/file_watcher.ts @@ -5,24 +5,30 @@ export function galleryFileWatcher(mainPanel: vscode.WebviewPanel, galleryFolder let globPattern = utils.getGlob(); const watcher = vscode.workspace.createFileSystemWatcher(galleryFolder ? new vscode.RelativePattern(galleryFolder, globPattern) : globPattern); watcher.onDidChange(uri => { + let pathsBySubFolders = utils.getPathsBySubFolders([uri]); mainPanel.webview.postMessage({ command: 'vscodeImageGallery.changeImage', imgSrc: mainPanel.webview.asWebviewUri(uri).toString(), imgPath: uri.path, + pathsBySubFolders: pathsBySubFolders, }); }); watcher.onDidCreate(uri => { + let pathsBySubFolders = utils.getPathsBySubFolders([uri]); mainPanel.webview.postMessage({ command: 'vscodeImageGallery.addImage', imgSrc: mainPanel.webview.asWebviewUri(uri).toString(), imgPath: uri.path, + pathsBySubFolders: pathsBySubFolders, }); }); watcher.onDidDelete(uri => { + let pathsBySubFolders = utils.getPathsBySubFolders([uri]); mainPanel.webview.postMessage({ command: 'vscodeImageGallery.deleteImage', imgSrc: mainPanel.webview.asWebviewUri(uri).toString(), imgPath: uri.path, + pathsBySubFolders: pathsBySubFolders, }); }); diff --git a/src/main_panel.ts b/src/main_panel.ts index c3205eb..a4365c1 100644 --- a/src/main_panel.ts +++ b/src/main_panel.ts @@ -13,6 +13,23 @@ export async function createPanel(context: vscode.ExtensionContext, galleryFolde ); const imgPaths = await getImagePaths(galleryFolder); + let pathsBySubFolders = utils.getPathsBySubFolders(imgPaths); + pathsBySubFolders = sortPathsBySubFolders(pathsBySubFolders); + + panel.webview.html = getWebviewContent(context, panel.webview, pathsBySubFolders); + + return panel; +} + +export async function getImagePaths(galleryFolder?: vscode.Uri) { + const globPattern = utils.getGlob(); + const files = await vscode.workspace.findFiles( + galleryFolder ? new vscode.RelativePattern(galleryFolder, globPattern) : globPattern + ); + return files; +} + +export function sortPathsBySubFolders(pathsBySubFolders: { [key: string]: Array }): { [key: string]: Array } { const config = vscode.workspace.getConfiguration('sorting.byPathOptions'); const keys = [ 'localeMatcher', @@ -22,40 +39,48 @@ export async function createPanel(context: vscode.ExtensionContext, galleryFolde 'caseFirst', 'collation', ]; - imgPaths.sort((path1, path2) => { - return path1.path.localeCompare( - path2.path, + const comparator = (a: string, b: string) => { + return a.localeCompare( + b, undefined, - Object.fromEntries( - keys.map(key => [key, config.get(key)]) - ) + Object.fromEntries(keys.map(key => [key, config.get(key)])) ); - }); - panel.webview.html = getWebviewContent(context, panel.webview, imgPaths); - - return panel; -} + }; -export async function getImagePaths(galleryFolder?: vscode.Uri) { - const globPattern = utils.getGlob(); - const files = await vscode.workspace.findFiles( - galleryFolder ? new vscode.RelativePattern(galleryFolder, globPattern) : globPattern + const sortedResult: { [key: string]: Array } = {}; + Object.keys(pathsBySubFolders).sort(comparator).forEach( + subfolder => { + sortedResult[subfolder] = pathsBySubFolders[subfolder].sort( + (path1: vscode.Uri, path2: vscode.Uri) => path1.path.localeCompare(path2.path) + ); + } ); - return files; + + return sortedResult; } export function getWebviewContent( context: vscode.ExtensionContext, webview: vscode.Webview, - imgWebviewUris: vscode.Uri[], + pathsBySubFolders: { [key: string]: Array }, ) { const placeholderUrl = webview.asWebviewUri(vscode.Uri.joinPath(context.extensionUri, 'media', 'placeholder.jpg')); - const imgHtml = imgWebviewUris.map( - img => { + const imgHtml = Object.keys(pathsBySubFolders).map( + folder => { return ` -
- -
${utils.getFilename(img.path)}
+ +
+ ${pathsBySubFolders[folder].map(img => { + return ` +
+ +
${utils.getFilename(img.path)}
+
+ `; + }).join('')}
`; } @@ -75,9 +100,9 @@ export function getWebviewContent( Image Gallery - ${imgWebviewUris.length === 0 ? '

No image found in this folder.

' : `
${imgHtml}
`} + ${Object.keys(pathsBySubFolders).length === 0 ? '

No image found in this folder.

' : `${imgHtml}`} ` ); -} \ No newline at end of file +} diff --git a/src/utils.ts b/src/utils.ts index cd47bee..23f81c9 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -62,7 +62,7 @@ export function getGlob() { 'svgz', ]; let upperCaseImg = imgExtensions.map(ext => ext.toUpperCase()); - const globPattern = '**/*.{' + [...imgExtensions, ...upperCaseImg].join(',') + '}'; + const globPattern = `**/*.{${[...imgExtensions, ...upperCaseImg].join(',')}}`; return globPattern; } @@ -73,4 +73,26 @@ export function getFilename(imgPath: string) { return filename.split("?").shift(); } return filename; +} + +export function getPathsBySubFolders(imgPaths: vscode.Uri[]) { + let pathsBySubFolders: { [key: string]: Array } = {}; + if (vscode.workspace.workspaceFolders) { + vscode.workspace.workspaceFolders?.forEach(workspaceFolder => { + imgPaths.forEach(imgPath => { + if (imgPath.toString().includes(workspaceFolder.uri.toString())) { + let fsPath = imgPath.toString().replace(`${workspaceFolder.uri.toString()}/`, ''); + let pathElements = fsPath.split('/'); + pathElements.pop(); + let folderElements = pathElements.join('/'); + let key = `${workspaceFolder.uri.path}/${folderElements}`; + if (!pathsBySubFolders[key]) { + pathsBySubFolders[key] = []; + } + pathsBySubFolders[key].push(imgPath); + } + }); + }); + } + return pathsBySubFolders; } \ No newline at end of file