diff --git a/CHANGELOG.md b/CHANGELOG.md index 685a09c3..2ac1bbe8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# Unreleased +* Added support for ImJoy +* Added a setting to disable the gallery + # [v2.10.0b0](https://gitlab.com/openflexure/openflexure-microscope-server/compare/v2.9.3...v2.10.0b0) (2021-05-18) ## New features diff --git a/openflexure_microscope/api/static/.env.development b/openflexure_microscope/api/static/.env.development index 284c703f..0fd381c8 100644 --- a/openflexure_microscope/api/static/.env.development +++ b/openflexure_microscope/api/static/.env.development @@ -1,3 +1,5 @@ NODE_ENV=development +VUE_APP_MODE=development VUE_APP_PLATFORM=web -VUE_APP_TARGET=web \ No newline at end of file +VUE_APP_TARGET=web +VUE_APP_ENABLE_IMJOY=true \ No newline at end of file diff --git a/openflexure_microscope/api/static/.env.production b/openflexure_microscope/api/static/.env.production index e9a62687..ed3afd8e 100644 --- a/openflexure_microscope/api/static/.env.production +++ b/openflexure_microscope/api/static/.env.production @@ -1,3 +1,5 @@ NODE_ENV=production +VUE_APP_MODE=production VUE_APP_PLATFORM=web -VUE_APP_TARGET=web \ No newline at end of file +VUE_APP_TARGET=web +VUE_APP_ENABLE_IMJOY=true diff --git a/openflexure_microscope/api/static/package-lock.json b/openflexure_microscope/api/static/package-lock.json index 364ee484..eb4170dd 100644 --- a/openflexure_microscope/api/static/package-lock.json +++ b/openflexure_microscope/api/static/package-lock.json @@ -2276,6 +2276,11 @@ "@types/node": "*" } }, + "@types/component-emitter": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.10.tgz", + "integrity": "sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg==" + }, "@types/connect": { "version": "3.4.33", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.33.tgz", @@ -3578,6 +3583,11 @@ "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==", "dev": true }, + "after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=" + }, "aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -3592,7 +3602,6 @@ "version": "6.10.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", - "dev": true, "requires": { "fast-deep-equal": "^2.0.1", "fast-json-stable-stringify": "^2.0.0", @@ -3705,11 +3714,15 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, "requires": { "sprintf-js": "~1.0.2" } }, + "argsarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/argsarray/-/argsarray-0.0.1.tgz", + "integrity": "sha1-bnIHtOzbObCviDA/pa4ivajfYcs=" + }, "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", @@ -3755,6 +3768,11 @@ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, + "arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==" + }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", @@ -4047,6 +4065,11 @@ "resolve": "^1.4.0" } }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -4108,6 +4131,11 @@ } } }, + "base64-arraybuffer": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz", + "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI=" + }, "base64-js": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", @@ -4163,6 +4191,11 @@ "file-uri-to-path": "1.0.0" } }, + "blob": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==" + }, "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -5076,11 +5109,20 @@ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, + "component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=" + }, "component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + }, + "component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=" }, "compressible": { "version": "2.0.18", @@ -6091,6 +6133,11 @@ "domelementtype": "1" } }, + "dompurify": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.2.8.tgz", + "integrity": "sha512-9H0UL59EkDLgY3dUFjLV6IEUaHm5qp3mxSqWw7Yyx4Zhk2Jn2cmLe+CNPP3xy13zl8Bqg+0NehQzkdMoVhGRww==" + }, "domutils": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", @@ -6224,6 +6271,50 @@ "once": "^1.4.0" } }, + "engine.io-client": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-5.1.1.tgz", + "integrity": "sha512-jPFpw2HLL0lhZ2KY0BpZhIJdleQcUO9W1xkIpo0h3d6s+5D6+EV/xgQw9qWOmymszv2WXef/6KUUehyxEKomlQ==", + "requires": { + "base64-arraybuffer": "0.1.4", + "component-emitter": "~1.3.0", + "debug": "~4.3.1", + "engine.io-parser": "~4.0.1", + "has-cors": "1.1.0", + "parseqs": "0.0.6", + "parseuri": "0.0.6", + "ws": "~7.4.2", + "yeast": "0.1.2" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "ws": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", + "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==" + } + } + }, + "engine.io-parser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.2.tgz", + "integrity": "sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==", + "requires": { + "base64-arraybuffer": "0.1.4" + } + }, "enhanced-resolve": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz", @@ -6660,8 +6751,7 @@ "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" }, "esquery": { "version": "1.0.1", @@ -6974,8 +7064,7 @@ "fast-deep-equal": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" }, "fast-diff": { "version": "1.2.0", @@ -7000,8 +7089,7 @@ "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", - "dev": true + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" }, "fast-levenshtein": { "version": "2.0.6", @@ -7089,6 +7177,11 @@ } } }, + "file-saver": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-1.3.8.tgz", + "integrity": "sha512-spKHSBQIxxS81N/O21WmuXA2F6wppUCsutpzenOeZzOCCJ5gEfcbqJP983IrpLXzYmXnMUa6J03SubcNPdKrlg==" + }, "file-uri-to-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", @@ -7236,8 +7329,7 @@ "follow-redirects": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz", - "integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==", - "dev": true + "integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==" }, "for-in": { "version": "1.0.2", @@ -8087,6 +8179,26 @@ "ansi-regex": "^2.0.0" } }, + "has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "requires": { + "isarray": "2.0.1" + }, + "dependencies": { + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + } + } + }, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -8483,6 +8595,77 @@ "dev": true, "optional": true }, + "imjoy-core": { + "version": "0.13.74", + "resolved": "https://registry.npmjs.org/imjoy-core/-/imjoy-core-0.13.74.tgz", + "integrity": "sha512-eXKRw4vpK8E8DnKrc1G8dLq8zGQsOddLubVpomIzs5CtOktAhQOqr5kOEucmM4V3uEDd24UGbMydv1MzP2KWBQ==", + "requires": { + "ajv": "^6.9.1", + "axios": "^0.21.1", + "dompurify": "^2.0.8", + "file-saver": "^1.3.3", + "imjoy-rpc": "^0.3.6", + "js-yaml": "^3.13.1", + "lodash": "^4.17.15", + "lz-string": "^1.4.4", + "minibus": "^3.1.0", + "pouchdb-browser": "^7.0.0", + "socket.io-client": "^2.3.0", + "spark-md5": "^3.0.0" + }, + "dependencies": { + "axios": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", + "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "requires": { + "follow-redirects": "^1.10.0" + } + } + } + }, + "imjoy-rpc": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/imjoy-rpc/-/imjoy-rpc-0.3.9.tgz", + "integrity": "sha512-dWyEIFlHKEGkyTLhGvKMnY7Tus26cOgfPMj3plEfcwNIfiatD8kfwdmdu4yoWUTdOnOUY4KtY06c9UnNT04k/Q==", + "requires": { + "socket.io-client": "^4.0.1" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "socket.io-client": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.1.1.tgz", + "integrity": "sha512-avzRzFZIkmyNxqvhmm5ns0Itq5dgEkesDPB6Tl0Yben47U08MvdFnVXAuFDULQhDXjuYdCb6QUEILYLUKQEuGg==", + "requires": { + "@types/component-emitter": "^1.2.10", + "backo2": "~1.0.2", + "component-emitter": "~1.3.0", + "debug": "~4.3.1", + "engine.io-client": "~5.1.1", + "parseuri": "0.0.6", + "socket.io-parser": "~4.0.4" + } + } + } + }, + "immediate": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", + "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==" + }, "import-cwd": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", @@ -8539,6 +8722,11 @@ "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", "dev": true }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" + }, "infer-owner": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", @@ -8558,8 +8746,7 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "inquirer": { "version": "7.3.3", @@ -9154,7 +9341,6 @@ "version": "3.13.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, "requires": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -9193,8 +9379,7 @@ "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -9446,8 +9631,7 @@ "lodash": { "version": "4.17.20", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", - "dev": true + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" }, "lodash.defaultsdeep": { "version": "4.6.1", @@ -9524,6 +9708,11 @@ "yallist": "^3.0.2" } }, + "lz-string": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", + "integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=" + }, "make-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", @@ -9754,6 +9943,11 @@ } } }, + "minibus": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minibus/-/minibus-3.1.0.tgz", + "integrity": "sha1-/UKe2XWj/U5VbwxumqyaTqy80ZM=" + }, "minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -10607,6 +10801,16 @@ } } }, + "parseqs": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz", + "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==" + }, + "parseuri": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz", + "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==" + }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -11409,6 +11613,26 @@ "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", "dev": true }, + "pouchdb-browser": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/pouchdb-browser/-/pouchdb-browser-7.2.2.tgz", + "integrity": "sha512-90pkngk9/F95knUwOhGQ0xuNzG51uIecF5kD5AfNdhqqrV9wbngz+I3QA7u/9eVyZRVyOrTrT3oaKcNqAB7Brg==", + "requires": { + "argsarray": "0.0.1", + "immediate": "3.3.0", + "inherits": "2.0.4", + "spark-md5": "3.0.1", + "uuid": "8.1.0", + "vuvuzela": "1.0.3" + }, + "dependencies": { + "uuid": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.1.0.tgz", + "integrity": "sha512-CI18flHDznR0lq54xBycOVmphdCYnQLKn8abKn7PXUiKUGdEd+/l9LWNJmugXel4hXq7S+RMNl34ecyC9TntWg==" + } + } + }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -11562,8 +11786,7 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "q": { "version": "1.5.1", @@ -12456,6 +12679,114 @@ } } }, + "socket.io-client": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.4.0.tgz", + "integrity": "sha512-M6xhnKQHuuZd4Ba9vltCLT9oa+YvTsP8j9NcEiLElfIg8KeYPyhWOes6x4t+LTAC8enQbE/995AdTem2uNyKKQ==", + "requires": { + "backo2": "1.0.2", + "component-bind": "1.0.0", + "component-emitter": "~1.3.0", + "debug": "~3.1.0", + "engine.io-client": "~3.5.0", + "has-binary2": "~1.0.2", + "indexof": "0.0.1", + "parseqs": "0.0.6", + "parseuri": "0.0.6", + "socket.io-parser": "~3.3.0", + "to-array": "0.1.4" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "engine.io-client": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.5.2.tgz", + "integrity": "sha512-QEqIp+gJ/kMHeUun7f5Vv3bteRHppHH/FMBQX/esFj/fuYfjyUKWGMo3VCvIP/V8bE9KcjHmRZrhIz2Z9oNsDA==", + "requires": { + "component-emitter": "~1.3.0", + "component-inherit": "0.0.3", + "debug": "~3.1.0", + "engine.io-parser": "~2.2.0", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.6", + "parseuri": "0.0.6", + "ws": "~7.4.2", + "xmlhttprequest-ssl": "~1.6.2", + "yeast": "0.1.2" + } + }, + "engine.io-parser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.1.tgz", + "integrity": "sha512-x+dN/fBH8Ro8TFwJ+rkB2AmuVw9Yu2mockR/p3W8f8YtExwFgDvBDi0GWyb4ZLkpahtDGZgtr3zLovanJghPqg==", + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.4", + "blob": "0.0.5", + "has-binary2": "~1.0.2" + } + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "socket.io-parser": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.2.tgz", + "integrity": "sha512-FJvDBuOALxdCI9qwRrO/Rfp9yfndRtc1jSgVgV8FDraihmSP/MLGD5PEuJrNfjALvcQ+vMDM/33AWOYP/JSjDg==", + "requires": { + "component-emitter": "~1.3.0", + "debug": "~3.1.0", + "isarray": "2.0.1" + } + }, + "ws": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", + "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==" + } + } + }, + "socket.io-parser": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz", + "integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==", + "requires": { + "@types/component-emitter": "^1.2.10", + "component-emitter": "~1.3.0", + "debug": "~4.3.1" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "sockjs": { "version": "0.3.20", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.20.tgz", @@ -12567,6 +12898,11 @@ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", "dev": true }, + "spark-md5": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.1.tgz", + "integrity": "sha512-0tF3AGSD1ppQeuffsLDIOWlKUd3lS92tFxcsrh5Pe3ZphhnoK+oXIBTzOAThZCiuINZLvpiLH/1VS1/ANEJVig==" + }, "spdx-correct": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", @@ -12651,8 +12987,7 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, "sshpk": { "version": "1.16.1", @@ -13136,6 +13471,11 @@ "os-tmpdir": "~1.0.2" } }, + "to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=" + }, "to-arraybuffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", @@ -13464,7 +13804,6 @@ "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "dev": true, "requires": { "punycode": "^2.1.0" } @@ -13848,6 +14187,11 @@ "integrity": "sha512-W74OO2vCJPs9/YjNjW8lLbj+jzT24waTo2KShI8jLvJW8OaIkgb3wuAMA7D+ZiUxDOx3ubwSZTaJBip9G8a3aQ==", "dev": true }, + "vuvuzela": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/vuvuzela/-/vuvuzela-1.0.3.tgz", + "integrity": "sha1-O+FF5YJxxzylUnndhR8SpoIRSws=" + }, "watchpack": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.4.tgz", @@ -14517,6 +14861,11 @@ "async-limiter": "~1.0.0" } }, + "xmlhttprequest-ssl": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.2.tgz", + "integrity": "sha512-tYOaldF/0BLfKuoA39QMwD4j2m8lq4DIncqj1yuNELX4vz9+z/ieG/vwmctjJce+boFHXstqhWnHSxc4W8f4qg==" + }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -14653,6 +15002,11 @@ "decamelize": "^1.2.0" } }, + "yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=" + }, "yorkie": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/yorkie/-/yorkie-2.0.0.tgz", diff --git a/openflexure_microscope/api/static/package.json b/openflexure_microscope/api/static/package.json index af3524c4..a49b434f 100644 --- a/openflexure_microscope/api/static/package.json +++ b/openflexure_microscope/api/static/package.json @@ -6,11 +6,14 @@ "author": "OpenFlexure (https://www.openflexure.org)", "scripts": { "serve": "vue-cli-service serve --mode development", + "serve-without-imjoy": "VUE_APP_ENABLE_IMJOY=false vue-cli-service serve --mode development", "build": "vue-cli-service build --mode production", + "build-without-imjoy": "VUE_APP_ENABLE_IMJOY=false vue-cli-service build --mode production", "lint": "vue-cli-service lint", "lint:fix": "vue-cli-service lint --fix" }, "dependencies": { + "imjoy-core": "^0.13.74", "material-design-icons": "^3.0.1", "mousetrap": "^1.6.5", "vue-observe-visibility": "^0.4.6" diff --git a/openflexure_microscope/api/static/public/ListServices.imjoy.html b/openflexure_microscope/api/static/public/ListServices.imjoy.html new file mode 100644 index 00000000..e4492765 --- /dev/null +++ b/openflexure_microscope/api/static/public/ListServices.imjoy.html @@ -0,0 +1,43 @@ + +[TODO: write documentation for this plugin.] + + + +{ + "name": "List services", + "type": "web-worker", + "tags": [], + "ui": "", + "version": "0.1.0", + "cover": "", + "description": "List the available ImJoy services in the console", + "icon": "extension", + "inputs": null, + "outputs": null, + "api_version": "0.1.8", + "env": "", + "permissions": [], + "requirements": [], + "dependencies": [] +} + + + diff --git a/openflexure_microscope/api/static/public/OpenFlexureScriptEditor.imjoy.html b/openflexure_microscope/api/static/public/OpenFlexureScriptEditor.imjoy.html new file mode 100644 index 00000000..9e18873f --- /dev/null +++ b/openflexure_microscope/api/static/public/OpenFlexureScriptEditor.imjoy.html @@ -0,0 +1,131 @@ + +{ + "name": "Script Editor", + "type": "web-worker", + "tags": [], + "ui": "", + "version": "0.1.0", + "cover": "", + "description": "A Script Editor for Controlling OpenFlexure Microscope with ImJoy", + "icon": "extension", + "inputs": null, + "outputs": null, + "api_version": "0.1.8", + "env": "", + "permissions": [], + "requirements": [], + "dependencies": [] +} + + + \ No newline at end of file diff --git a/openflexure_microscope/api/static/public/OpenFlexureSnapImageTemplate.imjoy.html b/openflexure_microscope/api/static/public/OpenFlexureSnapImageTemplate.imjoy.html new file mode 100644 index 00000000..34eff749 --- /dev/null +++ b/openflexure_microscope/api/static/public/OpenFlexureSnapImageTemplate.imjoy.html @@ -0,0 +1,43 @@ + +[TODO: write documentation for this plugin.] + + + +{ + "name": "OpenFlexureSnapImageTemplate", + "type": "web-worker", + "tags": [], + "ui": "", + "version": "0.1.0", + "cover": "", + "description": "[TODO: describe this plugin with one sentence.]", + "icon": "extension", + "inputs": null, + "outputs": null, + "api_version": "0.1.8", + "env": "", + "permissions": [], + "requirements": [], + "dependencies": [] +} + + + diff --git a/openflexure_microscope/api/static/public/OpenFlexureTestMoveStage.imjoy.html b/openflexure_microscope/api/static/public/OpenFlexureTestMoveStage.imjoy.html new file mode 100644 index 00000000..3d1cf4b9 --- /dev/null +++ b/openflexure_microscope/api/static/public/OpenFlexureTestMoveStage.imjoy.html @@ -0,0 +1,50 @@ + +[TODO: write documentation for this plugin.] + + + +{ + "name": "Test OFM Stage", + "type": "web-worker", + "tags": [], + "ui": "", + "version": "0.1.0", + "cover": "", + "description": "Move the OFM stage to test the API works", + "icon": "extension", + "inputs": null, + "outputs": null, + "api_version": "0.1.8", + "env": "", + "permissions": [], + "requirements": [], + "dependencies": [] +} + + + diff --git a/openflexure_microscope/api/static/src/assets/less/theme.less b/openflexure_microscope/api/static/src/assets/less/theme.less index e3984a21..81c1f136 100644 --- a/openflexure_microscope/api/static/src/assets/less/theme.less +++ b/openflexure_microscope/api/static/src/assets/less/theme.less @@ -10,8 +10,8 @@ // Colors // -@global-color: #666; -@global-emphasis-color: #333; +@global-color: #000; +@global-emphasis-color: #C32280; @global-muted-color: #666; @global-primary-background: #C32280; @@ -33,7 +33,7 @@ @global-medium-font-size: 20px; @global-small-font-size: 14px; -@global-emphasis-color: #222; + // // Base diff --git a/openflexure_microscope/api/static/src/components/appContent.vue b/openflexure_microscope/api/static/src/components/appContent.vue index fbc12e8d..5fa51647 100644 --- a/openflexure_microscope/api/static/src/components/appContent.vue +++ b/openflexure_microscope/api/static/src/components/appContent.vue @@ -28,7 +28,14 @@ :class="item.class" @set-tab="setTab" > - {{ item.icon }} + + + {{ item.icon }} +
@@ -48,6 +55,25 @@ {{ plugin.icon || "extension" }} + + + + {{ imjoyTab.iconName || "extension" }} + + +
@@ -104,6 +130,16 @@ /> + +
Loading...
+
+ import axios from "axios"; +import { mapState } from "vuex"; // Import generic components import tabIcon from "./genericComponents/tabIcon"; @@ -132,15 +169,22 @@ import captureContent from "./tabContentComponents/captureContent.vue"; import slideScanContent from "./tabContentComponents/slideScanContent.vue"; import viewContent from "./tabContentComponents/viewContent.vue"; import settingsContent from "./tabContentComponents/settingsContent.vue"; -import galleryContent from "./tabContentComponents/galleryContent.vue"; import extensionContent from "./tabContentComponents/extensionContent.vue"; import aboutContent from "./tabContentComponents/aboutContent.vue"; import loggingContent from "./tabContentComponents/loggingContent.vue"; +// ImJoy and the gallery are loaded asynchronously to allow them to be disabled if needed +const galleryContent = () => + import( + /* webpackChunkName: "gallery" */ "./tabContentComponents/galleryContent.vue" + ); +const imjoyContent = () => + import( + /* webpackChunkName: "imjoy" */ "./tabContentComponents/imjoyContent.vue" + ); // Import modal components for device initialisation import calibrationModal from "./modalComponents/calibrationModal.vue"; - -import { mapState } from "vuex"; +import TabIcon from "./genericComponents/tabIcon.vue"; // Export main app export default { @@ -158,38 +202,14 @@ export default { extensionContent, calibrationModal, aboutContent, - loggingContent + loggingContent, + TabIcon, + imjoyContent }, - data: function() { return { plugins: [], currentTab: "view", - unwatchStoreFunction: null, - topTabs: [ - { - id: "view", - icon: "visibility", - component: viewContent - }, - { - id: "gallery", - icon: "photo_library", - component: galleryContent, - divide: true // Add a divider after this tab icon - }, - { - id: "navigate", - icon: "gamepad", - component: navigateContent - }, - { - id: "capture", - icon: "camera_alt", - component: captureContent, - divide: true // Add a divider after this tab icon - } - ], bottomTabs: [ { id: "settings", @@ -241,25 +261,64 @@ export default { return ind; }, + topTabs: function() { + let tabs = [ + { + id: "view", + icon: "visibility", + component: viewContent + }, + { + id: "gallery", + icon: "photo_library", + component: galleryContent, + divide: true // Add a divider after this tab icon + }, + { + id: "navigate", + icon: "gamepad", + component: navigateContent + }, + { + id: "capture", + icon: "camera_alt", + component: captureContent, + divide: true // Add a divider after this tab icon + } + ]; + if (!this.$store.state.galleryEnabled) { + tabs = tabs.filter(tab => tab.id != "gallery"); + } + if (this.$store.state.IHIEnabled) { + tabs.push({ + id: "slidescan", + icon: "settings_overscan", + component: slideScanContent, + divide: true + }); + } + if (this.$store.state.imjoyEnabled) { + tabs.push({ + id: "imjoy", + iconURL: "https://imjoy.io/static/img/imjoy-icon.svg", + component: imjoyContent, + divide: true + }); + } + return tabs; + }, + currentTabIndex: function() { return this.tabOrder.indexOf(this.currentTab); }, - // Map the setting for IHI's interface so we can watch it - ...mapState(["IHIEnabled"]) - }, - - watch: { - // Update the interface when the IHI interface is enabled/disabled - IHIEnabled: function(newValue) { - this.updateTopTabs(newValue); - } + // Map the tabs from ImJoy's store module so we can display them + ...mapState("imjoy", { imjoyTabs: "tabs" }), + ...mapState({ imjoyEnabled: "imjoyEnabled" }) }, created: function() { if (this.$store.getters.ready) { - // Update top tabs - this.updateTopTabs(this.$store.state.IHIEnabled); // Update plugins this.updatePlugins().then(() => { // Start initialisation modals @@ -284,19 +343,6 @@ export default { }, methods: { - updateTopTabs: function(IHIEnabled) { - if (IHIEnabled) { - this.topTabs.push({ - id: "slidescan", - icon: "settings_overscan", - component: slideScanContent, - divide: true - }); - } else { - // If the connection is now disconnected, empty capture list - this.topTabs = this.topTabs.filter(tab => tab.id != "slidescan"); - } - }, updatePlugins: function() { return axios .get(this.pluginsUri) @@ -331,6 +377,10 @@ export default { diff --git a/openflexure_microscope/api/static/src/components/tabContentComponents/settingsComponents/featuresSettings.vue b/openflexure_microscope/api/static/src/components/tabContentComponents/settingsComponents/featuresSettings.vue index 581d7c0f..4fc9b74e 100644 --- a/openflexure_microscope/api/static/src/components/tabContentComponents/settingsComponents/featuresSettings.vue +++ b/openflexure_microscope/api/static/src/components/tabContentComponents/settingsComponents/featuresSettings.vue @@ -14,6 +14,36 @@ for use in clinics acquiring blood smear samples using a 100x oil-immersion objective, with a Raspberry Pi Camera v2.

+

+ +

+

+ ImJoy enables integration with a wide + variety of microscopy and image analysis applications, including ImageJ.JS + and Kaibu. Support for ImJoy within the OFM software is currently + experimental, and it may slow down loading of the application. +

+

+ ImJoy plugins are disabled in this build of the OpenFlexure software. +

+

+ +

+

+ The "gallery" tab can cause performance issues; un-tick the box above to + disable it. +

@@ -34,18 +64,50 @@ export default { set(value) { this.$store.commit("changeIHIEnabled", value); } + }, + imjoyEnabled: { + get() { + return this.$store.state.imjoyEnabled; + }, + set(value) { + this.$store.commit("changeImjoyEnabled", value); + } + }, + galleryEnabled: { + get() { + return this.$store.state.galleryEnabled; + }, + set(value) { + this.$store.commit("changeGalleryEnabled", value); + } + }, + imjoyPermitted: function() { + // ImJoy may be disabled using an environment variable. + // If this function returns false, it is never possible to + // use ImJoy, so we should gray out the option. + return process.env.VUE_APP_ENABLE_IMJOY === "true"; } }, watch: { IHIEnabled: function() { this.setLocalStorageObj("IHIEnabled", this.IHIEnabled); + }, + imjoyEnabled: function() { + this.setLocalStorageObj("imjoyEnabled", this.imjoyEnabled); + }, + galleryEnabled: function() { + this.setLocalStorageObj("galleryEnabled", this.galleryEnabled); } }, mounted() { // Try loading settings from localStorage. If null, don't change. this.IHIEnabled = this.getLocalStorageObj("IHIEnabled") || this.IHIEnabled; + this.imjoyEnabled = + this.getLocalStorageObj("imjoyEnabled") || this.imjoyEnabled; + this.galleryEnabled = + this.getLocalStorageObj("galleryEnabled") || this.galleryEnabled; } }; diff --git a/openflexure_microscope/api/static/src/components/tabContentComponents/settingsComponents/streamSettings.vue b/openflexure_microscope/api/static/src/components/tabContentComponents/settingsComponents/streamSettings.vue index 60b7cdb7..660d276a 100644 --- a/openflexure_microscope/api/static/src/components/tabContentComponents/settingsComponents/streamSettings.vue +++ b/openflexure_microscope/api/static/src/components/tabContentComponents/settingsComponents/streamSettings.vue @@ -95,21 +95,12 @@ export default { // Cache the stream settings to local storage for persistence // (the next 3 functions all relate to this) disableStream: function(newValue) { - console.log( - `disableStream updated to ${newValue} and saved in local storage` - ); this.setLocalStorageObj("disableStream", newValue); }, autoGpuPreview: function(newValue) { - console.log( - `GPU preview updated to ${newValue} and saved in local storage` - ); this.setLocalStorageObj("autoGpuPreview", newValue); }, trackWindow: function(newValue) { - console.log( - `trackWindow updated to ${newValue} and saved in local storage` - ); this.setLocalStorageObj("trackWindow", newValue); } }, diff --git a/openflexure_microscope/api/static/src/store.js b/openflexure_microscope/api/static/src/store.js index f8255fdc..1be58fdb 100644 --- a/openflexure_microscope/api/static/src/store.js +++ b/openflexure_microscope/api/static/src/store.js @@ -3,6 +3,64 @@ import Vuex from "vuex"; Vue.use(Vuex); +const moduleImjoy = { + namespaced: true, + state: () => ({ + tabs: [], + openImageMenu: [], + openScanMenu: [] + }), + mutations: { + addOpenImageItem(state, newItem) { + state.openImageMenu.push(newItem); + }, // TODO: add a mutation to remove items when plugins are unloaded + addOpenScanItem(state, newItem) { + state.openScanMenu.push(newItem); + }, // TODO: add a mutation to remove items when plugins are unloaded + clearMenus(state) { + // This is primarily useful to reset the state in hot-reloads of + // imjoyContent.vue + state.openImageMenu = []; + state.openScanMenu = []; + }, + addTab(state, newItem) { + // Add a tab to the list of ImJoy tabs + state.tabs.push(newItem); + }, + removeTab(state, tabToRemove) { + const index = state.tabs.indexOf(tabToRemove); + if (index > -1) { + state.tabs.splice(index, 1); + } else { + console.warn( + `Attempted to remove a non-existing ImJoy tab ${tabToRemove}` + ); + } + }, + /** + * Set a parameter on the tab with a given id + * + * Payload should contain: + * tab: ID of the tab to modify (not window_id) + * key: name of the property to add/change + * value: value of the property to add/change + */ + setTabProperty(state, payload) { + let tab = payload.tab; + let key = payload.key; + let value = payload.value; + state.tabs = state.tabs.map(t => { + if (t.id === tab) { + t[key] = value; + } + return t; + }); + } + }, + actions: {}, + getters: {} +}; + function getOriginFromLocation() { // This will default to the same origin that's serving // the web app - but can be overridden by the URL. @@ -17,6 +75,9 @@ function getOriginFromLocation() { } export default new Vuex.Store({ + modules: { + imjoy: moduleImjoy + }, state: { origin: getOriginFromLocation(), available: false, @@ -26,6 +87,8 @@ export default new Vuex.Store({ autoGpuPreview: false, trackWindow: true, IHIEnabled: false, + imjoyEnabled: false, + galleryEnabled: true, appTheme: "system", activeStreams: {} }, @@ -52,6 +115,20 @@ export default new Vuex.Store({ changeIHIEnabled(state, enabled) { state.IHIEnabled = enabled; }, + changeImjoyEnabled(state, enabled) { + if (process.env.VUE_APP_ENABLE_IMJOY === "true") { + state.imjoyEnabled = enabled; + } else { + state.imjoyEnabled = false; + if (enabled) + console.warn( + "Attempted to enable ImJoy, but it's disabled by VUE_APP_ENABLE_IMJOY." + ); + } + }, + changeGalleryEnabled(state, enabled) { + state.galleryEnabled = enabled; + }, resetState(state) { state.waiting = false; state.available = false;