diff --git a/docs/assets/app-bar.png b/docs/assets/app-bar.png index d5f2876..fcd66b3 100644 Binary files a/docs/assets/app-bar.png and b/docs/assets/app-bar.png differ diff --git a/ui/package-lock.json b/ui/package-lock.json index 0f4b99a..602faeb 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -17,8 +17,11 @@ "balm-ui": "^10.9.0", "copy-image-clipboard": "^1.0.1", "date-fns": "^2.28.0", + "deep-iterator": "^1.1.0", + "fast-deep-equal": "^3.1.3", "ol": "^6.15.1", "overlayscrollbars": "^1.13.2", + "overlayscrollbars-vue": "^0.3.0", "plyr": "^3.7.2", "qs": "^6.11.0", "swrv": "^1.0.0-beta.8", @@ -1220,6 +1223,22 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==", + "dependencies": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "node_modules/babel-runtime/node_modules/core-js": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", + "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", + "hasInstallScript": true + }, "node_modules/balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -1445,6 +1464,14 @@ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, + "node_modules/deep-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/deep-iterator/-/deep-iterator-1.1.0.tgz", + "integrity": "sha512-abVT7x3Gk6oQI/lgAtcnzjqNvHCE/0hmF2O+oWYNcgo24km2ZUG5tlagvTxG99rZ6S4lctPEGN6sEQz4d6vRGQ==", + "dependencies": { + "babel-runtime": "^6.20.0" + } + }, "node_modules/deepmerge": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", @@ -2088,8 +2115,7 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-diff": { "version": "1.1.2", @@ -2782,6 +2808,15 @@ "resolved": "https://registry.npmjs.org/overlayscrollbars/-/overlayscrollbars-1.13.2.tgz", "integrity": "sha512-xk9eJ8fpuh28WABSDpMpOv90aDQk+x5wLeqU4AGbJg56eGLeKxVPQzMxeX6+BM2dsIIOcBj3Fwvn8A0EzhHN3g==" }, + "node_modules/overlayscrollbars-vue": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/overlayscrollbars-vue/-/overlayscrollbars-vue-0.3.0.tgz", + "integrity": "sha512-AiWwKqB6bEoro6W2n+4K0ktT7V81LY6MO3PXUBdxANy9SXU0NAqoj1PS57rP0BWD8hDCOIm4E1UgVFJc5Nolpg==", + "peerDependencies": { + "overlayscrollbars": "^1.10.0", + "vue": "^3.0.0" + } + }, "node_modules/pako": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/pako/-/pako-2.0.4.tgz", @@ -2978,6 +3013,11 @@ "quickselect": "^2.0.0" } }, + "node_modules/regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + }, "node_modules/regexp.prototype.flags": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", @@ -4708,6 +4748,22 @@ "color-convert": "^2.0.1" } }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==", + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + }, + "dependencies": { + "core-js": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==" + } + } + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -4883,6 +4939,14 @@ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, + "deep-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/deep-iterator/-/deep-iterator-1.1.0.tgz", + "integrity": "sha512-abVT7x3Gk6oQI/lgAtcnzjqNvHCE/0hmF2O+oWYNcgo24km2ZUG5tlagvTxG99rZ6S4lctPEGN6sEQz4d6vRGQ==", + "requires": { + "babel-runtime": "^6.20.0" + } + }, "deepmerge": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", @@ -5264,8 +5328,7 @@ "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "fast-diff": { "version": "1.1.2", @@ -5801,6 +5864,12 @@ "resolved": "https://registry.npmjs.org/overlayscrollbars/-/overlayscrollbars-1.13.2.tgz", "integrity": "sha512-xk9eJ8fpuh28WABSDpMpOv90aDQk+x5wLeqU4AGbJg56eGLeKxVPQzMxeX6+BM2dsIIOcBj3Fwvn8A0EzhHN3g==" }, + "overlayscrollbars-vue": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/overlayscrollbars-vue/-/overlayscrollbars-vue-0.3.0.tgz", + "integrity": "sha512-AiWwKqB6bEoro6W2n+4K0ktT7V81LY6MO3PXUBdxANy9SXU0NAqoj1PS57rP0BWD8hDCOIm4E1UgVFJc5Nolpg==", + "requires": {} + }, "pako": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/pako/-/pako-2.0.4.tgz", @@ -5954,6 +6023,11 @@ "quickselect": "^2.0.0" } }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + }, "regexp.prototype.flags": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", diff --git a/ui/package.json b/ui/package.json index a1a6c98..bf091e4 100644 --- a/ui/package.json +++ b/ui/package.json @@ -15,8 +15,11 @@ "balm-ui": "^10.9.0", "copy-image-clipboard": "^1.0.1", "date-fns": "^2.28.0", + "deep-iterator": "^1.1.0", + "fast-deep-equal": "^3.1.3", "ol": "^6.15.1", "overlayscrollbars": "^1.13.2", + "overlayscrollbars-vue": "^0.3.0", "plyr": "^3.7.2", "qs": "^6.11.0", "swrv": "^1.0.0-beta.8", diff --git a/ui/src/App.vue b/ui/src/App.vue index dc10bdf..55d1e88 100644 --- a/ui/src/App.vue +++ b/ui/src/App.vue @@ -3,114 +3,77 @@ - - Photos - - - chevron_right {{ collection.name }} + Photos + + {{ collection.name }} + + {{ collectionExpanded ? 'expand_less' : 'expand_more' }} + + + - - - - - Photos - - {{ collections?.length }} collections - - - - - - - {{ c.name }} - - - - -
import { createTask, useApi, useTasks } from './api'; +import { computed, toRef } from 'vue'; +import { useRoute, useRouter } from 'vue-router'; import NaturalViewer from './components/NaturalViewer.vue' import ExpandButton from './components/ExpandButton.vue' import SearchInput from './components/SearchInput.vue' -import { computed, toRef } from 'vue'; -import { useRoute, useRouter } from 'vue-router'; +import DisplaySettings from './components/DisplaySettings.vue' +import TaskList from './components/TaskList.vue'; +import CollectionPanel from './components/CollectionPanel.vue'; export default { name: 'App', @@ -214,7 +129,10 @@ export default { NaturalViewer, ExpandButton, SearchInput, - }, + DisplaySettings, + TaskList, + CollectionPanel, +}, props: [ "collectionId", @@ -222,16 +140,10 @@ export default { data() { return { - settings: { - debug: { - overdraw: false, - thumbnails: false, - }, - }, settingsExpanded: false, - settingsExtraExpanded: false, tasksExpanded: false, collectionExpanded: false, + collectionExpandedPending: false, load: { image: 0, }, @@ -260,12 +172,21 @@ export default { const route = useRoute(); const query = computed(() => route.query); - const setQuery = (key, value) => { - if (value == "" || (key == "layout" && value == "DEFAULT")) { - value = undefined; - } + const goHome = () => { + router.push("/"); + } + + const setQuery = (patch) => { const query = Object.assign({}, route.query); - query[key] = value; + Object.assign(query, patch); + for (const key in patch) { + if (Object.hasOwnProperty.call(patch, key)) { + const value = patch[key]; + if (value == "" || (key == "layout" && value == "DEFAULT")) { + query[key] = undefined; + } + } + } router.push({ query }); } @@ -285,6 +206,7 @@ export default { const collection = computed(() => collectionId.value && fetchedCollection.value); return { + goHome, query, setQuery, layoutOptions, @@ -341,20 +263,13 @@ export default { } return null; }, - fileCount() { - if (this.collection) { - for (const task of this.tasks) { - if (task.type != "INDEX") continue; - if (task.collection_id != this.collection.id) continue; - return task.done.toLocaleString(); - } - } - return this.scene?.file_count !== undefined ? - this.scene.file_count.toLocaleString() : - null; - }, }, methods: { + toggleFocus() { + if (!this.collectionExpandedPending) return; + this.$refs.collectionPanel.$el.focus(); + this.collectionExpandedPending = false; + }, recreateScene() { this.$bus.emit("recreate-scene"); }, @@ -403,23 +318,98 @@ export default { \ No newline at end of file diff --git a/ui/src/components/CollectionPanel.vue b/ui/src/components/CollectionPanel.vue index 30f7ee1..d9d18cc 100644 --- a/ui/src/components/CollectionPanel.vue +++ b/ui/src/components/CollectionPanel.vue @@ -1,30 +1,92 @@ - \ No newline at end of file diff --git a/ui/src/components/CollectionSettings.vue b/ui/src/components/CollectionSettings.vue new file mode 100644 index 0000000..1429fc7 --- /dev/null +++ b/ui/src/components/CollectionSettings.vue @@ -0,0 +1,116 @@ + + + + + \ No newline at end of file diff --git a/ui/src/components/DisplaySettings.vue b/ui/src/components/DisplaySettings.vue new file mode 100644 index 0000000..ca9cc0a --- /dev/null +++ b/ui/src/components/DisplaySettings.vue @@ -0,0 +1,98 @@ + + + + + \ No newline at end of file diff --git a/ui/src/components/Home.vue b/ui/src/components/Home.vue index 19f780d..4607db6 100644 --- a/ui/src/components/Home.vue +++ b/ui/src/components/Home.vue @@ -3,12 +3,12 @@
- + >
@@ -16,13 +16,13 @@ + + \ No newline at end of file diff --git a/ui/src/components/TileViewer.vue b/ui/src/components/TileViewer.vue index 36c68c7..f9ffc6e 100644 --- a/ui/src/components/TileViewer.vue +++ b/ui/src/components/TileViewer.vue @@ -15,6 +15,7 @@ import XYZ from 'ol/source/XYZ'; import TileLayer from 'ol/layer/Tile'; import View from 'ol/View'; import Projection from 'ol/proj/Projection'; +import equal from 'fast-deep-equal'; import PhotoSkeleton from './PhotoSkeleton.vue'; @@ -54,11 +55,8 @@ export default { async created() { }, async mounted() { - this.reset(); }, - unmounted() { - }, watch: { scene(newScene, oldScene) { @@ -78,7 +76,8 @@ export default { debug: { deep: true, - handler() { + handler(newValue, oldValue) { + if (equal(newValue, oldValue)) return; this.reload(); }, },