diff --git a/README.md b/README.md index 272a1d127..420b05784 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ Electron allows building a native application that can be installed on Windows, #### NPM scripts -- `npm run electron:dev` +- `npm run dev:electron` Run Electron in development mode, concurrently starts 3 processes with watch for changes: main (main Electron process), renderer (FE code) and Webpack for Electron (compiles main Electron process from TypeScript). @@ -55,15 +55,15 @@ The main process code for Electron, which includes preload functionality, is wri Prepare renderer (FE code) build, compile Electron main process code, install and build native dependencies, is used before packaging or publishing. -- `npm run electron:package:staging` +- `npm run electron:staging` Create packages for macOS, Windows and Linux in `dist-electron` folders with `APP_ENV` as `staging` (allows to open DevTools, includes sourcemaps and does not minify built JavaScript code), can be used for manual distribution and testing packaged application. -- `npm run electron:package:production` +- `npm run electron:production` Create packages for macOS, Windows and Linux in `dist-electron` folders with `APP_ENV` as `production` (disabled DevTools, minified built JavaScript code), can be used for manual distribution and testing packaged application. -- `npm run electron:publish` +- `npm run deploy:electron` Create packages for macOS, Windows and Linux in `dist-electron` folder and publish release to GitHub, which allows supporting autoupdates. See [GitHub release workflow](#github-release) for more info. @@ -80,7 +80,7 @@ More info in the [official documentation](https://www.electronjs.org/docs/latest #### Notarize on MacOS -Application notarization is done with [electron-builder-notarize](https://github.com/karaggeorge/electron-builder-notarize) module, which requires `APPLE_ID` and `APPLE_ID_PASSWORD` environment variables to be passed. +Application notarization is done automatically in [electron-builder](https://github.com/electron-userland/electron-builder/) module, which requires `APPLE_ID` and `APPLE_APP_SPECIFIC_PASSWORD` environment variables to be passed. How to obtain app-specific password: diff --git a/package-lock.json b/package-lock.json index c4a90b05c..d021e147d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,7 +35,6 @@ "@babel/preset-react": "^7.18.6", "@babel/preset-typescript": "^7.21.0", "@babel/register": "^7.21.0", - "@electron/rebuild": "^3.2.10", "@glen/jest-raw-loader": "^2.0.0", "@playwright/test": "^1.31.2", "@statoscope/cli": "^5.26.1", @@ -61,10 +60,10 @@ "css-loader": "^6.7.3", "dotenv": "^16.0.3", "electron": "^22.0.0", - "electron-builder": "^23.6.0", - "electron-builder-notarize": "^1.5.1", + "electron-builder": "^24.5.2", + "electron-context-menu": "^3.6.1", + "electron-store": "^8.1.0", "electron-updater": "^5.3.0", - "electron-window-state": "^5.0.3", "electronmon": "^2.0.2", "eslint": "^8.36.0", "eslint-config-airbnb": "^19.0.4", @@ -4855,6 +4854,33 @@ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" } }, + "node_modules/@electron/asar": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.2.4.tgz", + "integrity": "sha512-lykfY3TJRRWFeTxccEKdf1I6BLl2Plw81H0bbp4Fc5iEc67foDCa5pjJQULVgo0wF+Dli75f3xVcdb/67FFZ/g==", + "dev": true, + "dependencies": { + "chromium-pickle-js": "^0.2.0", + "commander": "^5.0.0", + "glob": "^7.1.6", + "minimatch": "^3.0.4" + }, + "bin": { + "asar": "bin/asar.js" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/@electron/asar/node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/@electron/get": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.2.tgz", @@ -4899,10 +4925,92 @@ "node": ">= 4.0.0" } }, + "node_modules/@electron/notarize": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@electron/notarize/-/notarize-1.2.4.tgz", + "integrity": "sha512-W5GQhJEosFNafewnS28d3bpQ37/s91CDWqxVchHfmv2dQSTWpOzNlUVQwYzC1ay5bChRV/A9BTL68yj0Pa+TSg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "fs-extra": "^9.0.1" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@electron/notarize/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@electron/notarize/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@electron/notarize/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@electron/osx-sign": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@electron/osx-sign/-/osx-sign-1.0.4.tgz", + "integrity": "sha512-xfhdEcIOfAZg7scZ9RQPya1G1lWo8/zMCwUXAulq0SfY7ONIW+b9qGyKdMyuMctNYwllrIS+vmxfijSfjeh97g==", + "dev": true, + "dependencies": { + "compare-version": "^0.1.2", + "debug": "^4.3.4", + "fs-extra": "^10.0.0", + "isbinaryfile": "^4.0.8", + "minimist": "^1.2.6", + "plist": "^3.0.5" + }, + "bin": { + "electron-osx-flat": "bin/electron-osx-flat.js", + "electron-osx-sign": "bin/electron-osx-sign.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@electron/osx-sign/node_modules/isbinaryfile": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", + "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", + "dev": true, + "engines": { + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, "node_modules/@electron/rebuild": { - "version": "3.2.10", - "resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.2.10.tgz", - "integrity": "sha512-SUBM6Mwi3yZaDFQjZzfGKpYTtOp9m60glounwX6tfGeVc/ZOl4jbquktUcyy7gYSLDWFLtKkftkY2xgMJZLQgg==", + "version": "3.2.13", + "resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.2.13.tgz", + "integrity": "sha512-DH9Ol4JCnHDYVOD0fKWq+Qqbn/0WU1O6QR0mIpMXEVU4YFM4PlaqNC9K36mGShNBxxGFotZCMDrB1wl/iHM12g==", "dev": true, "dependencies": { "@malept/cross-spawn-promise": "^2.0.0", @@ -4911,7 +5019,6 @@ "detect-libc": "^2.0.1", "fs-extra": "^10.0.0", "got": "^11.7.0", - "lzma-native": "^8.0.5", "node-abi": "^3.0.0", "node-api-version": "^0.1.4", "node-gyp": "^9.0.0", @@ -4921,7 +5028,7 @@ "yargs": "^17.0.1" }, "bin": { - "electron-rebuild": "lib/src/cli.js" + "electron-rebuild": "lib/cli.js" }, "engines": { "node": ">=12.13.0" @@ -5013,15 +5120,15 @@ } }, "node_modules/@electron/universal": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-1.2.1.tgz", - "integrity": "sha512-7323HyMh7KBAl/nPDppdLsC87G6RwRU02dy5FPeGB1eS7rUePh55+WNWiDPLhFQqqVPHzh77M69uhmoT8XnwMQ==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-1.3.4.tgz", + "integrity": "sha512-BdhBgm2ZBnYyYRLRgOjM5VHkyFItsbggJ0MHycOjKWdFGYwK97ZFXH54dTvUWEfha81vfvwr5On6XBjt99uDcg==", "dev": true, "dependencies": { + "@electron/asar": "^3.2.1", "@malept/cross-spawn-promise": "^1.1.0", - "asar": "^3.1.0", "debug": "^4.3.1", - "dir-compare": "^2.4.0", + "dir-compare": "^3.0.0", "fs-extra": "^9.0.1", "minimatch": "^3.0.4", "plist": "^3.0.4" @@ -6829,9 +6936,9 @@ "license": "MIT" }, "node_modules/@types/debug": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", - "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==", + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.8.tgz", + "integrity": "sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ==", "dev": true, "dependencies": { "@types/ms": "*" @@ -6890,17 +6997,6 @@ "@types/node": "*" } }, - "node_modules/@types/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", - "dev": true, - "optional": true, - "dependencies": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, "node_modules/@types/graceful-fs": { "version": "4.1.6", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", @@ -7001,13 +7097,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/minimatch": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", - "dev": true, - "optional": true - }, "node_modules/@types/minimist": { "version": "1.2.2", "dev": true, @@ -8246,46 +8335,83 @@ "dev": true }, "node_modules/app-builder-lib": { - "version": "23.6.0", - "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-23.6.0.tgz", - "integrity": "sha512-dQYDuqm/rmy8GSCE6Xl/3ShJg6Ab4bZJMT8KaTKGzT436gl1DN4REP3FCWfXoh75qGTJ+u+WsdnnpO9Jl8nyMA==", + "version": "24.5.2", + "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-24.5.2.tgz", + "integrity": "sha512-fZbUrFl3FW7yw92KiDpXV3Nd84EW+D7/WU7MEjX2eHDWM45Qx4hYOZpL9PaT9ZzZbaNfNLmt2EOnoqHQXHLdKw==", "dev": true, "dependencies": { "@develar/schema-utils": "~2.6.5", - "@electron/universal": "1.2.1", + "@electron/notarize": "^1.2.3", + "@electron/osx-sign": "^1.0.4", + "@electron/rebuild": "3.2.13", + "@electron/universal": "1.3.4", "@malept/flatpak-bundler": "^0.4.0", + "@types/fs-extra": "9.0.13", "7zip-bin": "~5.1.1", "async-exit-hook": "^2.0.1", "bluebird-lst": "^1.0.9", - "builder-util": "23.6.0", - "builder-util-runtime": "9.1.1", + "builder-util": "24.5.0", + "builder-util-runtime": "9.2.1", "chromium-pickle-js": "^0.2.0", "debug": "^4.3.4", - "ejs": "^3.1.7", - "electron-osx-sign": "^0.6.0", - "electron-publish": "23.6.0", + "ejs": "^3.1.8", + "electron-publish": "24.5.0", "form-data": "^4.0.0", "fs-extra": "^10.1.0", "hosted-git-info": "^4.1.0", "is-ci": "^3.0.0", - "isbinaryfile": "^4.0.10", + "isbinaryfile": "^5.0.0", "js-yaml": "^4.1.0", "lazy-val": "^1.0.5", - "minimatch": "^3.1.2", - "read-config-file": "6.2.0", + "minimatch": "^5.1.1", + "read-config-file": "6.3.2", "sanitize-filename": "^1.6.3", - "semver": "^7.3.7", - "tar": "^6.1.11", + "semver": "^7.3.8", + "tar": "^6.1.12", "temp-file": "^3.4.0" }, "engines": { "node": ">=14.0.0" } }, + "node_modules/app-builder-lib/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/app-builder-lib/node_modules/builder-util-runtime": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.1.tgz", + "integrity": "sha512-2rLv/uQD2x+dJ0J3xtsmI12AlRyk7p45TEbE/6o/fbb633e/S3pPgm+ct+JHsoY7r39dKHnGEFk/AASRFdnXmA==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "sax": "^1.2.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/app-builder-lib/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/app-builder-lib/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -8449,37 +8575,6 @@ "node": ">=0.10.0" } }, - "node_modules/asar": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/asar/-/asar-3.2.0.tgz", - "integrity": "sha512-COdw2ZQvKdFGFxXwX3oYh2/sOsJWJegrdJCGxnN4MZ7IULgRBp9P6665aqj9z1v9VwP4oP1hRBojRDQ//IGgAg==", - "deprecated": "Please use @electron/asar moving forward. There is no API change, just a package name change", - "dev": true, - "dependencies": { - "chromium-pickle-js": "^0.2.0", - "commander": "^5.0.0", - "glob": "^7.1.6", - "minimatch": "^3.0.4" - }, - "bin": { - "asar": "bin/asar.js" - }, - "engines": { - "node": ">=10.12.0" - }, - "optionalDependencies": { - "@types/glob": "^7.1.1" - } - }, - "node_modules/asar/node_modules/commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, "node_modules/assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", @@ -8539,6 +8634,15 @@ "node": ">= 4.0.0" } }, + "node_modules/atomically": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/atomically/-/atomically-1.7.0.tgz", + "integrity": "sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w==", + "dev": true, + "engines": { + "node": ">=10.12.0" + } + }, "node_modules/autoprefixer": { "version": "10.4.14", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz", @@ -9228,22 +9332,6 @@ "ieee754": "^1.2.1" } }, - "node_modules/buffer-alloc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", - "dev": true, - "dependencies": { - "buffer-alloc-unsafe": "^1.1.0", - "buffer-fill": "^1.0.0" - } - }, - "node_modules/buffer-alloc-unsafe": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", - "dev": true - }, "node_modules/buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", @@ -9254,43 +9342,39 @@ } }, "node_modules/buffer-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", - "integrity": "sha512-tcBWO2Dl4e7Asr9hTGcpVrCe+F7DubpmqWCTbj4FHLmjqO2hIaC383acQubWtRJhdceqs5uBHs6Es+Sk//RKiQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.1.tgz", + "integrity": "sha512-QoV3ptgEaQpvVwbXdSO39iqPQTCxSF7A5U99AxbHYqUdCizL/lH2Z0A2y6nbZucxMEOtNyZfG2s6gsVugGpKkg==", "dev": true, "engines": { - "node": ">=0.4.0" + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/buffer-fill": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==", - "dev": true - }, "node_modules/buffer-from": { "version": "1.1.2", "dev": true, "license": "MIT" }, "node_modules/builder-util": { - "version": "23.6.0", - "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-23.6.0.tgz", - "integrity": "sha512-QiQHweYsh8o+U/KNCZFSvISRnvRctb8m/2rB2I1JdByzvNKxPeFLlHFRPQRXab6aYeXc18j9LpsDLJ3sGQmWTQ==", + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-24.5.0.tgz", + "integrity": "sha512-STnBmZN/M5vGcv01u/K8l+H+kplTaq4PAIn3yeuufUKSpcdro0DhJWxPI81k5XcNfC//bjM3+n9nr8F9uV4uAQ==", "dev": true, "dependencies": { "@types/debug": "^4.1.6", - "@types/fs-extra": "^9.0.11", "7zip-bin": "~5.1.1", "app-builder-bin": "4.0.0", "bluebird-lst": "^1.0.9", - "builder-util-runtime": "9.1.1", - "chalk": "^4.1.1", + "builder-util-runtime": "9.2.1", + "chalk": "^4.1.2", "cross-spawn": "^7.0.3", "debug": "^4.3.4", - "fs-extra": "^10.0.0", + "fs-extra": "^10.1.0", "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", "is-ci": "^3.0.0", "js-yaml": "^4.1.0", "source-map-support": "^0.5.19", @@ -9326,6 +9410,19 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/builder-util/node_modules/builder-util-runtime": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.1.tgz", + "integrity": "sha512-2rLv/uQD2x+dJ0J3xtsmI12AlRyk7p45TEbE/6o/fbb633e/S3pPgm+ct+JHsoY7r39dKHnGEFk/AASRFdnXmA==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "sax": "^1.2.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/builder-util/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -9998,15 +10095,6 @@ "dev": true, "license": "MIT" }, - "node_modules/colors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", - "integrity": "sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==", - "dev": true, - "engines": { - "node": ">=0.1.90" - } - }, "node_modules/combined-stream": { "version": "1.0.8", "dev": true, @@ -10198,6 +10286,90 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/conf": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/conf/-/conf-10.2.0.tgz", + "integrity": "sha512-8fLl9F04EJqjSqH+QjITQfJF8BrOVaYr1jewVgSRAEWePfxT0sku4w2hrGQ60BC/TNLGQ2pgxNlTbWQmMPFvXg==", + "dev": true, + "dependencies": { + "ajv": "^8.6.3", + "ajv-formats": "^2.1.1", + "atomically": "^1.7.0", + "debounce-fn": "^4.0.0", + "dot-prop": "^6.0.1", + "env-paths": "^2.2.1", + "json-schema-typed": "^7.0.3", + "onetime": "^5.1.2", + "pkg-up": "^3.1.0", + "semver": "^7.3.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/conf/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/conf/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/conf/node_modules/semver": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", + "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/config-file-ts": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/config-file-ts/-/config-file-ts-0.2.4.tgz", + "integrity": "sha512-cKSW0BfrSaAUnxpgvpXPLaaW/umg4bqg4k3GO1JqlRfpx+d5W0GDXznCMkWotJQek5Mmz1MJVChQnz3IVaeMZQ==", + "dev": true, + "dependencies": { + "glob": "^7.1.6", + "typescript": "^4.0.2" + } + }, + "node_modules/config-file-ts/node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, "node_modules/confusing-browser-globals": { "version": "1.0.11", "dev": true, @@ -10507,6 +10679,30 @@ "url": "https://opencollective.com/date-fns" } }, + "node_modules/debounce-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/debounce-fn/-/debounce-fn-4.0.0.tgz", + "integrity": "sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/debounce-fn/node_modules/mimic-fn": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", + "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/debug": { "version": "4.3.4", "dev": true, @@ -10758,42 +10954,13 @@ } }, "node_modules/dir-compare": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-2.4.0.tgz", - "integrity": "sha512-l9hmu8x/rjVC9Z2zmGzkhOEowZvW7pmYws5CWHutg8u1JgvsKWMx7Q/UODeu4djLZ4FgW5besw5yvMQnBHzuCA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-3.3.0.tgz", + "integrity": "sha512-J7/et3WlGUCxjdnD3HAAzQ6nsnc0WL6DD7WcwJb7c39iH1+AWfg+9OqzJNaI6PkBwBvm1mhZNL9iY/nRiZXlPg==", "dev": true, "dependencies": { - "buffer-equal": "1.0.0", - "colors": "1.0.3", - "commander": "2.9.0", - "minimatch": "3.0.4" - }, - "bin": { - "dircompare": "src/cli/dircompare.js" - } - }, - "node_modules/dir-compare/node_modules/commander": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", - "integrity": "sha512-bmkUukX8wAOjHdN26xj5c4ctEV22TQ7dQYhSmuckKhToXrkUn0iIaolHdIxYYqD55nhpSPA9zPQ1yP57GdXP2A==", - "dev": true, - "dependencies": { - "graceful-readlink": ">= 1.0.0" - }, - "engines": { - "node": ">= 0.6.x" - } - }, - "node_modules/dir-compare/node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" + "buffer-equal": "^1.0.0", + "minimatch": "^3.0.4" } }, "node_modules/dir-glob": { @@ -10808,15 +10975,15 @@ } }, "node_modules/dmg-builder": { - "version": "23.6.0", - "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-23.6.0.tgz", - "integrity": "sha512-jFZvY1JohyHarIAlTbfQOk+HnceGjjAdFjVn3n8xlDWKsYNqbO4muca6qXEZTfGXeQMG7TYim6CeS5XKSfSsGA==", + "version": "24.5.2", + "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-24.5.2.tgz", + "integrity": "sha512-4qWGO3OM+1ipqvrKvskZRLDEvAPZdZwil6e40Tb8dKogpEhabrzcjpwoRycBy8FAx8R2EBQaFCtIp5rBO/DM8A==", "dev": true, "dependencies": { - "app-builder-lib": "23.6.0", - "builder-util": "23.6.0", - "builder-util-runtime": "9.1.1", - "fs-extra": "^10.0.0", + "app-builder-lib": "24.5.2", + "builder-util": "24.5.0", + "builder-util-runtime": "9.2.1", + "fs-extra": "^10.1.0", "iconv-lite": "^0.6.2", "js-yaml": "^4.1.0" }, @@ -10824,6 +10991,19 @@ "dmg-license": "^1.0.11" } }, + "node_modules/dmg-builder/node_modules/builder-util-runtime": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.1.tgz", + "integrity": "sha512-2rLv/uQD2x+dJ0J3xtsmI12AlRyk7p45TEbE/6o/fbb633e/S3pPgm+ct+JHsoY7r39dKHnGEFk/AASRFdnXmA==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "sax": "^1.2.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/dmg-builder/node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -10981,6 +11161,21 @@ "tslib": "^2.0.3" } }, + "node_modules/dot-prop": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", + "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", + "dev": true, + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/dotenv": { "version": "16.0.3", "dev": true, @@ -11012,9 +11207,9 @@ "license": "MIT" }, "node_modules/ejs": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz", - "integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", + "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", "dev": true, "dependencies": { "jake": "^10.8.5" @@ -11045,23 +11240,22 @@ } }, "node_modules/electron-builder": { - "version": "23.6.0", - "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-23.6.0.tgz", - "integrity": "sha512-y8D4zO+HXGCNxFBV/JlyhFnoQ0Y0K7/sFH+XwIbj47pqaW8S6PGYQbjoObolKBR1ddQFPt4rwp4CnwMJrW3HAw==", + "version": "24.5.2", + "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-24.5.2.tgz", + "integrity": "sha512-rxlUSSqziRMdTSSzti7It4R7wmuttouMhgTiF0HmoTXvaBKlmHPgkQjaI8ZFIZ0Rg+2TFPlPdMu2BwX3+6HJCg==", "dev": true, "dependencies": { - "@types/yargs": "^17.0.1", - "app-builder-lib": "23.6.0", - "builder-util": "23.6.0", - "builder-util-runtime": "9.1.1", - "chalk": "^4.1.1", - "dmg-builder": "23.6.0", - "fs-extra": "^10.0.0", + "app-builder-lib": "24.5.2", + "builder-util": "24.5.0", + "builder-util-runtime": "9.2.1", + "chalk": "^4.1.2", + "dmg-builder": "24.5.2", + "fs-extra": "^10.1.0", "is-ci": "^3.0.0", "lazy-val": "^1.0.5", - "read-config-file": "6.2.0", - "simple-update-notifier": "^1.0.7", - "yargs": "^17.5.1" + "read-config-file": "6.3.2", + "simple-update-notifier": "^1.1.0", + "yargs": "^17.6.2" }, "bin": { "electron-builder": "cli.js", @@ -11071,55 +11265,6 @@ "node": ">=14.0.0" } }, - "node_modules/electron-builder-notarize": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/electron-builder-notarize/-/electron-builder-notarize-1.5.1.tgz", - "integrity": "sha512-xS7s9gE+1AcJIuJ4DU/LqCrmRypE1zOR/6b66egKzgP/UVh9YSa7rINos34gF/KcueNDQU39HcXcCEKiEI5wPQ==", - "dev": true, - "dependencies": { - "dotenv": "^8.2.0", - "electron-notarize": "^1.1.1", - "js-yaml": "^3.14.0", - "read-pkg-up": "^7.0.0" - }, - "engines": { - "node": ">=8" - }, - "peerDependencies": { - "electron-builder": ">= 20.44.4" - } - }, - "node_modules/electron-builder-notarize/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/electron-builder-notarize/node_modules/dotenv": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", - "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/electron-builder-notarize/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/electron-builder/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -11135,6 +11280,19 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/electron-builder/node_modules/builder-util-runtime": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.1.tgz", + "integrity": "sha512-2rLv/uQD2x+dJ0J3xtsmI12AlRyk7p45TEbE/6o/fbb633e/S3pPgm+ct+JHsoY7r39dKHnGEFk/AASRFdnXmA==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "sax": "^1.2.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/electron-builder/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -11190,116 +11348,146 @@ "node": ">=8" } }, - "node_modules/electron-notarize": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/electron-notarize/-/electron-notarize-1.2.2.tgz", - "integrity": "sha512-ZStVWYcWI7g87/PgjPJSIIhwQXOaw4/XeXU+pWqMMktSLHaGMLHdyPPN7Cmao7+Cr7fYufA16npdtMndYciHNw==", - "deprecated": "Please use @electron/notarize moving forward. There is no API change, just a package name change", + "node_modules/electron-context-menu": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/electron-context-menu/-/electron-context-menu-3.6.1.tgz", + "integrity": "sha512-lcpO6tzzKUROeirhzBjdBWNqayEThmdW+2I2s6H6QMrwqTVyT3EK47jW3Nxm60KTxl5/bWfEoIruoUNn57/QkQ==", "dev": true, "dependencies": { - "debug": "^4.1.1", - "fs-extra": "^9.0.1" + "cli-truncate": "^2.1.0", + "electron-dl": "^3.2.1", + "electron-is-dev": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/electron-context-menu/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" }, "engines": { - "node": ">= 10.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/electron-notarize/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "node_modules/electron-context-menu/node_modules/cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", "dev": true, "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" }, "engines": { - "node": ">=10" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/electron-notarize/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "node_modules/electron-context-menu/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/electron-notarize/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/electron-osx-sign": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.6.0.tgz", - "integrity": "sha512-+hiIEb2Xxk6eDKJ2FFlpofCnemCbjbT5jz+BKGpVBrRNT3kWTGs4DfNX6IzGwgi33hUcXF+kFs9JW+r6Wc1LRg==", - "deprecated": "Please use @electron/osx-sign moving forward. Be aware the API is slightly different", - "dev": true, - "dependencies": { - "bluebird": "^3.5.0", - "compare-version": "^0.1.2", - "debug": "^2.6.8", - "isbinaryfile": "^3.0.2", - "minimist": "^1.2.0", - "plist": "^3.0.1" - }, - "bin": { - "electron-osx-flat": "bin/electron-osx-flat.js", - "electron-osx-sign": "bin/electron-osx-sign.js" + "color-name": "~1.1.4" }, "engines": { - "node": ">=4.0.0" + "node": ">=7.0.0" } }, - "node_modules/electron-osx-sign/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/electron-osx-sign/node_modules/isbinaryfile": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.3.tgz", - "integrity": "sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw==", - "dev": true, - "dependencies": { - "buffer-alloc": "^1.2.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/electron-osx-sign/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "node_modules/electron-context-menu/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/electron-context-menu/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/electron-context-menu/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/electron-context-menu/node_modules/slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/electron-context-menu/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/electron-dl": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/electron-dl/-/electron-dl-3.5.0.tgz", + "integrity": "sha512-Oj+VSuScVx8hEKM2HEvTQswTX6G3MLh7UoAz/oZuvKyNDfudNi1zY6PK/UnFoK1nCl9DF6k+3PFwElKbtZlDig==", + "dev": true, + "dependencies": { + "ext-name": "^5.0.0", + "pupa": "^2.0.1", + "unused-filename": "^2.1.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/electron-is-dev": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/electron-is-dev/-/electron-is-dev-2.0.0.tgz", + "integrity": "sha512-3X99K852Yoqu9AcW50qz3ibYBWY79/pBhlMCab8ToEWS48R0T9tyxRiQhwylE7zQdXrMnx2JKqUJyMPmt5FBqA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/electron-publish": { - "version": "23.6.0", - "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-23.6.0.tgz", - "integrity": "sha512-jPj3y+eIZQJF/+t5SLvsI5eS4mazCbNYqatv5JihbqOstIM13k0d1Z3vAWntvtt13Itl61SO6seicWdioOU5dg==", + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-24.5.0.tgz", + "integrity": "sha512-zwo70suH15L15B4ZWNDoEg27HIYoPsGJUF7xevLJLSI7JUPC8l2yLBdLGwqueJ5XkDL7ucYyRZzxJVR8ElV9BA==", "dev": true, "dependencies": { "@types/fs-extra": "^9.0.11", - "builder-util": "23.6.0", - "builder-util-runtime": "9.1.1", - "chalk": "^4.1.1", - "fs-extra": "^10.0.0", + "builder-util": "24.5.0", + "builder-util-runtime": "9.2.1", + "chalk": "^4.1.2", + "fs-extra": "^10.1.0", "lazy-val": "^1.0.5", "mime": "^2.5.2" } @@ -11319,6 +11507,19 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/electron-publish/node_modules/builder-util-runtime": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.1.tgz", + "integrity": "sha512-2rLv/uQD2x+dJ0J3xtsmI12AlRyk7p45TEbE/6o/fbb633e/S3pPgm+ct+JHsoY7r39dKHnGEFk/AASRFdnXmA==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "sax": "^1.2.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/electron-publish/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -11386,6 +11587,31 @@ "node": ">=8" } }, + "node_modules/electron-store": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/electron-store/-/electron-store-8.1.0.tgz", + "integrity": "sha512-2clHg/juMjOH0GT9cQ6qtmIvK183B39ZXR0bUoPwKwYHJsEF3quqyDzMFUAu+0OP8ijmN2CbPRAelhNbWUbzwA==", + "dev": true, + "dependencies": { + "conf": "^10.2.0", + "type-fest": "^2.17.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/electron-store/node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/electron-to-chromium": { "version": "1.4.284", "dev": true, @@ -11423,19 +11649,6 @@ "node": ">=10" } }, - "node_modules/electron-window-state": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/electron-window-state/-/electron-window-state-5.0.3.tgz", - "integrity": "sha512-1mNTwCfkolXl3kMf50yW3vE2lZj0y92P/HYWFBrb+v2S/pCka5mdwN3cagKm458A7NjndSwijynXgcLWRodsVg==", - "dev": true, - "dependencies": { - "jsonfile": "^4.0.0", - "mkdirp": "^0.5.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/electron/node_modules/@types/node": { "version": "16.18.14", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.14.tgz", @@ -11747,6 +11960,15 @@ "node": ">=6" } }, + "node_modules/escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/escape-html": { "version": "1.0.3", "dev": true, @@ -12725,6 +12947,31 @@ ], "license": "MIT" }, + "node_modules/ext-list": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz", + "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==", + "dev": true, + "dependencies": { + "mime-db": "^1.28.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ext-name": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz", + "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==", + "dev": true, + "dependencies": { + "ext-list": "^2.0.0", + "sort-keys-length": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/extract-zip": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", @@ -13522,12 +13769,6 @@ "dev": true, "license": "ISC" }, - "node_modules/graceful-readlink": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w==", - "dev": true - }, "node_modules/grapheme-splitter": { "version": "1.0.4", "dev": true, @@ -14498,6 +14739,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-path-inside": { "version": "3.0.3", "dev": true, @@ -14688,12 +14938,12 @@ "license": "MIT" }, "node_modules/isbinaryfile": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", - "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.0.tgz", + "integrity": "sha512-UDdnyGvMajJUWCkib7Cei/dvyJrrvo4FIrsvSFWdPpXSUorzXrDJ0S+X5Q4ZlasfPjca4yqCNNsjbCeiy8FFeg==", "dev": true, "engines": { - "node": ">= 8.0.0" + "node": ">= 14.0.0" }, "funding": { "url": "https://github.com/sponsors/gjtorikian/" @@ -14800,15 +15050,15 @@ } }, "node_modules/jake": { - "version": "10.8.5", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", - "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==", + "version": "10.8.7", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", + "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", "dev": true, "dependencies": { "async": "^3.2.3", "chalk": "^4.0.2", - "filelist": "^1.0.1", - "minimatch": "^3.0.4" + "filelist": "^1.0.4", + "minimatch": "^3.1.2" }, "bin": { "jake": "bin/cli.js" @@ -16566,6 +16816,12 @@ "dev": true, "license": "MIT" }, + "node_modules/json-schema-typed": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-7.0.3.tgz", + "integrity": "sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A==", + "dev": true + }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "dev": true, @@ -17320,30 +17576,6 @@ "node": ">=10" } }, - "node_modules/lzma-native": { - "version": "8.0.6", - "resolved": "https://registry.npmjs.org/lzma-native/-/lzma-native-8.0.6.tgz", - "integrity": "sha512-09xfg67mkL2Lz20PrrDeNYZxzeW7ADtpYFbwSQh9U8+76RIzx5QsJBMy8qikv3hbUPfpy6hqwxt6FcGK81g9AA==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "node-addon-api": "^3.1.0", - "node-gyp-build": "^4.2.1", - "readable-stream": "^3.6.0" - }, - "bin": { - "lzmajs": "bin/lzmajs" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/lzma-native/node_modules/node-addon-api": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", - "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", - "dev": true - }, "node_modules/make-dir": { "version": "3.1.0", "dev": true, @@ -17758,16 +17990,13 @@ "node": ">= 8" } }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "node_modules/modify-filename": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/modify-filename/-/modify-filename-1.1.0.tgz", + "integrity": "sha512-EickqnKq3kVVaZisYuCxhtKbZjInCuwgwZWyAmRIp1NTMhri7r3380/uqwrUHfaDiPzLVTuoNy4whX66bxPVog==", "dev": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" + "engines": { + "node": ">=0.10.0" } }, "node_modules/mp4box": { @@ -17925,17 +18154,6 @@ "node": "^12.13 || ^14.13 || >=16" } }, - "node_modules/node-gyp-build": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", - "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", - "dev": true, - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, "node_modules/node-gyp/node_modules/semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", @@ -18671,6 +18889,79 @@ "node": ">=8" } }, + "node_modules/pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "dev": true, + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-up/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-up/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/playwright-core": { "version": "1.31.2", "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.31.2.tgz", @@ -19061,6 +19352,18 @@ "dev": true, "license": "MIT" }, + "node_modules/pupa": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "dev": true, + "dependencies": { + "escape-goat": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/pure-rand": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.1.tgz", @@ -19216,11 +19519,12 @@ "license": "MIT" }, "node_modules/read-config-file": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/read-config-file/-/read-config-file-6.2.0.tgz", - "integrity": "sha512-gx7Pgr5I56JtYz+WuqEbQHj/xWo+5Vwua2jhb1VwM4Wid5PqYmZ4i00ZB0YEGIfkVBsCv9UrjgyqCiQfS/Oosg==", + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/read-config-file/-/read-config-file-6.3.2.tgz", + "integrity": "sha512-M80lpCjnE6Wt6zb98DoW8WHR09nzMSpu8XHtPkiTHrJ5Az9CybfeQhTJ8D7saeBHpGhLPIVyA8lcL6ZmdKwY6Q==", "dev": true, "dependencies": { + "config-file-ts": "^0.2.4", "dotenv": "^9.0.2", "dotenv-expand": "^5.1.0", "js-yaml": "^4.1.0", @@ -20373,6 +20677,30 @@ "node": ">= 10" } }, + "node_modules/sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==", + "dev": true, + "dependencies": { + "is-plain-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sort-keys-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz", + "integrity": "sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==", + "dev": true, + "dependencies": { + "sort-keys": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map": { "version": "0.6.1", "dev": true, @@ -21664,6 +21992,19 @@ "node": ">= 0.8" } }, + "node_modules/unused-filename": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unused-filename/-/unused-filename-2.1.0.tgz", + "integrity": "sha512-BMiNwJbuWmqCpAM1FqxCTD7lXF97AvfQC8Kr/DIeA6VtvhJaMDupZ82+inbjl5yVP44PcxOuCSxye1QMS0wZyg==", + "dev": true, + "dependencies": { + "modify-filename": "^1.1.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/update-browserslist-db": { "version": "1.0.10", "dev": true, diff --git a/package.json b/package.json index d662c54c1..14da9b99c 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,6 @@ "@babel/preset-react": "^7.18.6", "@babel/preset-typescript": "^7.21.0", "@babel/register": "^7.21.0", - "@electron/rebuild": "^3.2.10", "@glen/jest-raw-loader": "^2.0.0", "@playwright/test": "^1.31.2", "@statoscope/cli": "^5.26.1", @@ -86,10 +85,10 @@ "css-loader": "^6.7.3", "dotenv": "^16.0.3", "electron": "^22.0.0", - "electron-builder": "^23.6.0", - "electron-builder-notarize": "^1.5.1", + "electron-builder": "^24.5.2", + "electron-context-menu": "^3.6.1", + "electron-store": "^8.1.0", "electron-updater": "^5.3.0", - "electron-window-state": "^5.0.3", "electronmon": "^2.0.2", "eslint": "^8.36.0", "eslint-config-airbnb": "^19.0.4", diff --git a/public/electron-entitlements.mac.plist b/public/electron-entitlements.mac.plist index a06663bbc..d221a7278 100644 --- a/public/electron-entitlements.mac.plist +++ b/public/electron-entitlements.mac.plist @@ -2,11 +2,17 @@ - com.apple.security.cs.allow-unsigned-executable-memory - com.apple.security.cs.allow-jit - com.apple.security.cs.disable-library-validation + com.apple.security.device.camera + + com.apple.security.device.microphone + + com.apple.security.device.audio-input + + com.apple.security.device.print + + com.apple.security.personal-information.location diff --git a/public/icon-electron-macos.icns b/public/icon-electron-macos.icns index aa3d9fe23..56fd6b79f 100644 Binary files a/public/icon-electron-macos.icns and b/public/icon-electron-macos.icns differ diff --git a/public/icon-electron-windows.ico b/public/icon-electron-windows.ico index 270e8a98e..0b02fb121 100644 Binary files a/public/icon-electron-windows.ico and b/public/icon-electron-windows.ico differ diff --git a/src/components/auth/Auth.scss b/src/components/auth/Auth.scss index 68ff291e5..4cc68796d 100644 --- a/src/components/auth/Auth.scss +++ b/src/components/auth/Auth.scss @@ -31,6 +31,12 @@ height: 10rem; margin-bottom: 2.5rem; } + + body.is-electron & { + width: 6rem; + height: 6rem; + margin-bottom: 1.75rem; + } } #logo { diff --git a/src/components/calls/ActiveCallHeader.tsx b/src/components/calls/ActiveCallHeader.tsx index 8bba9a3a1..97cf922d3 100644 --- a/src/components/calls/ActiveCallHeader.tsx +++ b/src/components/calls/ActiveCallHeader.tsx @@ -28,9 +28,11 @@ const ActiveCallHeader: FC = ({ useEffect(() => { document.body.classList.toggle('has-call-header', Boolean(isCallPanelVisible)); + window.electron?.setTrafficLightPosition(isCallPanelVisible ? 'lowered' : 'standard'); return () => { document.body.classList.toggle('has-call-header', false); + window.electron?.setTrafficLightPosition('standard'); }; }, [isCallPanelVisible]); diff --git a/src/components/calls/group/GroupCall.module.scss b/src/components/calls/group/GroupCall.module.scss index e6d9cb57d..990ec8d01 100644 --- a/src/components/calls/group/GroupCall.module.scss +++ b/src/components/calls/group/GroupCall.module.scss @@ -81,6 +81,10 @@ &.scrolled { border-bottom-color: var(--group-call-panel-header-border-color); } + + :global(body.is-electron) .root.fullscreen:not(.landscape) & { + padding-left: 5rem; + } } .headerButton { diff --git a/src/components/common/AnimatedSticker.tsx b/src/components/common/AnimatedSticker.tsx index bb1a817a2..da196f0d3 100644 --- a/src/components/common/AnimatedSticker.tsx +++ b/src/components/common/AnimatedSticker.tsx @@ -8,6 +8,8 @@ import React, { useEffect, useRef, memo, useState, } from '../../lib/teact/teact'; +import { IS_ELECTRON } from '../../config'; + import buildClassName from '../../util/buildClassName'; import buildStyle from '../../util/buildStyle'; import generateUniqueId from '../../util/generateUniqueId'; @@ -255,7 +257,7 @@ const AnimatedSticker: FC = ({ className={buildClassName('AnimatedSticker', className)} style={buildStyle( size !== undefined && `width: ${size}px; height: ${size}px;`, - onClick && 'cursor: pointer', + onClick && !IS_ELECTRON && 'cursor: pointer', colorFilter, style, )} diff --git a/src/components/common/hooks/useAnimatedEmoji.ts b/src/components/common/hooks/useAnimatedEmoji.ts index 0484d2aa6..ad7c99bfd 100644 --- a/src/components/common/hooks/useAnimatedEmoji.ts +++ b/src/components/common/hooks/useAnimatedEmoji.ts @@ -3,6 +3,8 @@ import { getActions } from '../../../global'; import type { ActiveEmojiInteraction } from '../../../global/types'; +import { IS_ELECTRON } from '../../../config'; + import safePlay from '../../../util/safePlay'; import buildStyle from '../../../util/buildStyle'; import { REM } from '../helpers/mediaDimensions'; @@ -37,7 +39,7 @@ export default function useAnimatedEmoji( const soundMediaData = useMedia(soundId ? `document${soundId}` : undefined, !soundId); const size = preferredSize || SIZE; - const style = buildStyle(`width: ${size}px`, `height: ${size}px`, emoji && 'cursor: pointer'); + const style = buildStyle(`width: ${size}px`, `height: ${size}px`, emoji && !IS_ELECTRON && 'cursor: pointer'); const interactions = useRef(undefined); const startedInteractions = useRef(undefined); diff --git a/src/components/left/main/LeftMainHeader.tsx b/src/components/left/main/LeftMainHeader.tsx index 65d4a1d5c..5eda65291 100644 --- a/src/components/left/main/LeftMainHeader.tsx +++ b/src/components/left/main/LeftMainHeader.tsx @@ -21,7 +21,7 @@ import { IS_TEST, PRODUCTION_HOSTNAME, } from '../../../config'; -import { IS_APP } from '../../../util/windowEnvironment'; +import { IS_APP, IS_MAC_OS } from '../../../util/windowEnvironment'; import { INITIAL_PERFORMANCE_STATE_MAX, INITIAL_PERFORMANCE_STATE_MID, @@ -421,7 +421,7 @@ const LeftMainHeader: FC = ({ shouldDisableDropdownMenuTransitionRef.current && lang.isRtl && 'disable-transition', )} positionX={shouldHideSearch && lang.isRtl ? 'right' : 'left'} - transformOriginX={IS_ELECTRON && !isFullscreen ? 90 : undefined} + transformOriginX={IS_ELECTRON && IS_MAC_OS && !isFullscreen ? 90 : undefined} onTransitionEnd={lang.isRtl ? handleDropdownMenuTransitionEnd : undefined} > {menuItems} diff --git a/src/components/main/Main.tsx b/src/components/main/Main.tsx index 45166e7c6..60905e5d2 100644 --- a/src/components/main/Main.tsx +++ b/src/components/main/Main.tsx @@ -282,11 +282,11 @@ const Main: FC = ({ return undefined; } - const removeUpdateDownloadedListener = window.electron?.on(ElectronEvent.UPDATE_DOWNLOADED, () => { + const removeUpdateDownloadedListener = window.electron!.on(ElectronEvent.UPDATE_DOWNLOADED, () => { setIsAppUpdateAvailable(true); }); - const removeUpdateErrorListener = window.electron?.on(ElectronEvent.UPDATE_ERROR, () => { + const removeUpdateErrorListener = window.electron!.on(ElectronEvent.UPDATE_ERROR, () => { setIsAppUpdateAvailable(false); removeUpdateDownloadedListener?.(); }); @@ -501,7 +501,7 @@ const Main: FC = ({ }); // Online status and browser tab indicators - useBackgroundMode(handleBlur, handleFocus); + useBackgroundMode(handleBlur, handleFocus, !!IS_ELECTRON); useBeforeUnload(handleBlur); usePreventPinchZoomGesture(isMediaViewerOpen); diff --git a/src/components/mediaViewer/SeekLine.module.scss b/src/components/mediaViewer/SeekLine.module.scss index f69ccfbed..59016f768 100644 --- a/src/components/mediaViewer/SeekLine.module.scss +++ b/src/components/mediaViewer/SeekLine.module.scss @@ -5,7 +5,11 @@ top: 1rem; height: 1rem; touch-action: none; - cursor: pointer; + cursor: var(--custom-cursor, pointer); + + :global(body.is-electron) & { + cursor: auto; + } } .preview { diff --git a/src/components/right/RightHeader.scss b/src/components/right/RightHeader.scss index 915510901..b849f66fc 100644 --- a/src/components/right/RightHeader.scss +++ b/src/components/right/RightHeader.scss @@ -47,6 +47,14 @@ margin-left: auto; } + body.is-electron.is-macos & { + -webkit-app-region: drag; + + .SearchInput { + -webkit-app-region: no-drag; + } + } + body.is-electron.is-macos #Main:not(.is-fullscreen) & { @media (max-width: 600px) { padding-left: 5rem; diff --git a/src/electron/autoUpdates.ts b/src/electron/autoUpdates.ts new file mode 100644 index 000000000..85dc3b3a8 --- /dev/null +++ b/src/electron/autoUpdates.ts @@ -0,0 +1,42 @@ +import { ipcMain } from 'electron'; +import type { BrowserWindow } from 'electron'; +import type { UpdateInfo } from 'electron-updater'; +import { autoUpdater } from 'electron-updater'; + +import { ElectronAction, ElectronEvent } from '../types/electron'; +import { IS_MAC_OS, forceQuit, windows } from './utils'; +import type { WindowState } from './windowState'; + +let interval: NodeJS.Timer; +const CHECK_UPDATE_INTERVAL = 5 * 60 * 1000; + +export default function setupAutoUpdates(window: BrowserWindow, state: WindowState) { + if (!interval) { + autoUpdater.autoDownload = true; + autoUpdater.autoInstallOnAppQuit = true; + autoUpdater.checkForUpdates(); + + interval = setInterval(() => autoUpdater.checkForUpdates(), CHECK_UPDATE_INTERVAL); + + ipcMain.handle(ElectronAction.INSTALL_UPDATE, () => { + state.saveLastUrlHash(); + + if (IS_MAC_OS) { + forceQuit.enable(); + } + + return autoUpdater.quitAndInstall(); + }); + } + + autoUpdater.on('error', (error: Error) => { + if (windows.has(window)) { + window.webContents.send(ElectronEvent.UPDATE_ERROR, error); + } + }); + autoUpdater.on('update-downloaded', (info: UpdateInfo) => { + if (windows.has(window)) { + window.webContents.send(ElectronEvent.UPDATE_DOWNLOADED, info); + } + }); +} diff --git a/src/electron/config.yml b/src/electron/config.yml index 286eefb73..650a8652c 100644 --- a/src/electron/config.yml +++ b/src/electron/config.yml @@ -1,9 +1,9 @@ productName: "Telegram A" -artifactName: "${productName}-${arch}-${version}.${ext}" +artifactName: "${productName}-${arch}.${ext}" appId: "org.telegram.TelegramA" -afterSign: "electron-builder-notarize" extraMetadata: main: "./dist/electron.js" + productName: "Telegram A" files: - "dist" - "package.json" @@ -20,15 +20,22 @@ publish: provider: "github" owner: "Ajaxy" repo: "telegram-tt" + releaseType: "release" win: target: "nsis" icon: "public/icon-electron-windows.ico" +nsis: + oneClick: false + createDesktopShortcut: true + createStartMenuShortcut: true mac: target: target: "default" arch: ["x64", "arm64"] entitlements: "public/electron-entitlements.mac.plist" icon: "public/icon-electron-macos.icns" + notarize: + teamId: "Y54Z4K69Z9" linux: category: "Community" target: ["AppImage"] diff --git a/src/electron/main.ts b/src/electron/main.ts index 05e530b19..9c3c033f0 100644 --- a/src/electron/main.ts +++ b/src/electron/main.ts @@ -1,11 +1,20 @@ import 'v8-compile-cache'; import { app, nativeImage } from 'electron'; +import contextMenu from 'electron-context-menu'; import path from 'path'; import { createWindow, setupCloseHandlers, setupElectronActionHandlers } from './window'; import { IS_MAC_OS, IS_WINDOWS } from './utils'; +contextMenu({ + showLearnSpelling: false, + showLookUpSelection: false, + showSearchWithGoogle: false, + showCopyImage: false, + showSelectAll: true, +}); + app.on('ready', () => { if (IS_MAC_OS) { app.dock.setIcon(nativeImage.createFromPath(path.resolve(__dirname, '../public/icon-electron-macos.png'))); diff --git a/src/electron/preload.ts b/src/electron/preload.ts index 941c6fdaf..3c74bbaba 100644 --- a/src/electron/preload.ts +++ b/src/electron/preload.ts @@ -1,7 +1,7 @@ import { contextBridge, ipcRenderer } from 'electron'; import type { IpcRendererEvent } from 'electron'; -import type { ElectronApi, ElectronEvent } from '../types/electron'; +import type { ElectronApi, ElectronEvent, TrafficLightPosition } from '../types/electron'; import { ElectronAction } from '../types/electron'; const electronApi: ElectronApi = { @@ -9,6 +9,9 @@ const electronApi: ElectronApi = { installUpdate: () => ipcRenderer.invoke(ElectronAction.INSTALL_UPDATE), handleDoubleClick: () => ipcRenderer.invoke(ElectronAction.HANDLE_DOUBLE_CLICK), openNewWindow: (url: string) => ipcRenderer.invoke(ElectronAction.OPEN_NEW_WINDOW, url), + setWindowTitle: (title?: string) => ipcRenderer.invoke(ElectronAction.SET_WINDOW_TITLE, title), + setTrafficLightPosition: + (position: TrafficLightPosition) => ipcRenderer.invoke(ElectronAction.SET_TRAFFIC_LIGHT_POSITION, position), on: (eventName: ElectronEvent, callback) => { const subscription = (event: IpcRendererEvent, ...args: any) => callback(...args); diff --git a/src/electron/utils.ts b/src/electron/utils.ts index 1b902dc5c..469522cdc 100644 --- a/src/electron/utils.ts +++ b/src/electron/utils.ts @@ -1,3 +1,41 @@ +import { app } from 'electron'; +import type { BrowserWindow, Point } from 'electron'; + +import type { TrafficLightPosition } from '../types/electron'; + +export const windows = new Set(); + export const IS_MAC_OS = process.platform === 'darwin'; export const IS_WINDOWS = process.platform === 'win32'; export const IS_LINUX = process.platform === 'linux'; + +export function getAppTitle(chatTitle?: string): string { + const appName = app.getName(); + + if (!chatTitle) { + return appName; + } + + return `${chatTitle} ยท ${appName}`; +} + +export const TRAFFIC_LIGHT_POSITION: Record = { + standard: { x: 10, y: 20 }, + lowered: { x: 10, y: 52 }, +}; + +export const forceQuit = { + value: false, + + enable() { + this.value = true; + }, + + disable() { + this.value = false; + }, + + get isEnabled(): boolean { + return this.value; + }, +}; diff --git a/src/electron/window.ts b/src/electron/window.ts index ffd4ff88b..dab5415ed 100644 --- a/src/electron/window.ts +++ b/src/electron/window.ts @@ -2,24 +2,22 @@ import { app, BrowserWindow, ipcMain, shell, systemPreferences, } from 'electron'; import type { HandlerDetails } from 'electron'; -import type { UpdateInfo } from 'electron-updater'; -import { autoUpdater } from 'electron-updater'; -import windowStateKeeper from 'electron-window-state'; import path from 'path'; import { ElectronAction, ElectronEvent } from '../types/electron'; -import { IS_MAC_OS } from './utils'; +import type { TrafficLightPosition } from '../types/electron'; +import setupAutoUpdates from './autoUpdates'; +import { + forceQuit, getAppTitle, IS_MAC_OS, TRAFFIC_LIGHT_POSITION, windows, +} from './utils'; +import windowStateKeeper from './windowState'; -let forceQuit = false; -let interval: NodeJS.Timer; - -const windows = new Set(); -const CHECK_UPDATE_INTERVAL = 10 * 60 * 1000; +const ALLOWED_DEVICE_ORIGINS = ['http://localhost:1234', 'file://']; export function createWindow(url?: string) { const windowState = windowStateKeeper({ defaultWidth: 1088, - defaultHeight: IS_MAC_OS ? 700 : 750, + defaultHeight: 700, }); let x; @@ -55,14 +53,14 @@ export function createWindow(url?: string) { minWidth: 360, width, height, - title: 'Telegram A', + title: getAppTitle(), webPreferences: { preload: path.join(__dirname, 'preload.js'), devTools: process.env.APP_ENV !== 'production', }, ...(IS_MAC_OS && { titleBarStyle: 'hidden', - trafficLightPosition: { x: 10, y: 20 }, + trafficLightPosition: TRAFFIC_LIGHT_POSITION.standard, }), }); @@ -77,6 +75,10 @@ export function createWindow(url?: string) { return { action: 'deny' }; }); + window.webContents.session.setDevicePermissionHandler(({ deviceType, origin }) => { + return deviceType === 'hid' && ALLOWED_DEVICE_ORIGINS.includes(origin); + }); + window.on('enter-full-screen', () => { window.webContents.send(ElectronEvent.FULLSCREEN_CHANGE, true); }); @@ -87,14 +89,15 @@ export function createWindow(url?: string) { window.on('close', (event) => { if (IS_MAC_OS) { - if (forceQuit) { + if (forceQuit.isEnabled) { app.exit(0); - forceQuit = false; + forceQuit.disable(); } else { const hasExtraWindows = BrowserWindow.getAllWindows().length > 1; if (hasExtraWindows) { windows.delete(window); + windowState.unmanage(); } else { event.preventDefault(); window.hide(); @@ -106,12 +109,14 @@ export function createWindow(url?: string) { if (url) { window.loadURL(url); } else if (app.isPackaged) { - window.loadURL(`file://${__dirname}/index.html`); + window.loadURL(`file://${__dirname}/index.html${windowState.urlHash}`); } else { - window.loadURL('http://localhost:1234'); + window.loadURL(`http://localhost:1234${windowState.urlHash}`); window.webContents.openDevTools(); } + windowState.clearLastUrlHash(); + if (!IS_MAC_OS) { window.removeMenu(); } @@ -120,45 +125,21 @@ export function createWindow(url?: string) { window.show(); if (process.env.APP_ENV === 'production') { - setupAutoUpdates(window); + setupAutoUpdates(window, windowState); } }); windows.add(window); } -function setupAutoUpdates(window: BrowserWindow) { - if (!interval) { - autoUpdater.autoDownload = true; - autoUpdater.autoInstallOnAppQuit = true; - autoUpdater.checkForUpdates(); - - interval = setInterval(() => autoUpdater.checkForUpdates(), CHECK_UPDATE_INTERVAL); - - ipcMain.handle(ElectronAction.INSTALL_UPDATE, () => { - if (IS_MAC_OS) { - forceQuit = true; - } - - return autoUpdater.quitAndInstall(); - }); - } - - autoUpdater.on('error', (error: Error) => { - if (windows.has(window)) { - window.webContents.send(ElectronEvent.UPDATE_ERROR, error); - } - }); - autoUpdater.on('update-downloaded', (info: UpdateInfo) => { - if (windows.has(window)) { - window.webContents.send(ElectronEvent.UPDATE_DOWNLOADED, info); - } - }); -} - export function setupElectronActionHandlers() { - ipcMain.handle(ElectronAction.OPEN_NEW_WINDOW, (_, newWindowUrl: string) => { - createWindow(newWindowUrl); + ipcMain.handle(ElectronAction.OPEN_NEW_WINDOW, (_, url: string) => { + createWindow(url); + }); + + ipcMain.handle(ElectronAction.SET_WINDOW_TITLE, (_, newTitle?: string) => { + const currentWindow = BrowserWindow.getFocusedWindow(); + currentWindow?.setTitle(getAppTitle(newTitle)); }); ipcMain.handle(ElectronAction.GET_IS_FULLSCREEN, () => { @@ -180,6 +161,15 @@ export function setupElectronActionHandlers() { } } }); + + ipcMain.handle(ElectronAction.SET_TRAFFIC_LIGHT_POSITION, (_, position: TrafficLightPosition) => { + if (!IS_MAC_OS) { + return; + } + + const currentWindow = BrowserWindow.getFocusedWindow(); + currentWindow?.setTrafficLightPosition(TRAFFIC_LIGHT_POSITION[position]); + }); } export function setupCloseHandlers() { @@ -190,9 +180,9 @@ export function setupCloseHandlers() { }); app.on('before-quit', (event) => { - if (IS_MAC_OS && !forceQuit) { + if (IS_MAC_OS && !forceQuit.isEnabled) { event.preventDefault(); - forceQuit = true; + forceQuit.enable(); app.quit(); } }); @@ -203,7 +193,7 @@ export function setupCloseHandlers() { if (!hasActiveWindow) { createWindow(); } else if (IS_MAC_OS) { - forceQuit = false; + forceQuit.disable(); const currentWindow = Array.from(windows).pop(); currentWindow?.show(); diff --git a/src/electron/windowState.ts b/src/electron/windowState.ts new file mode 100644 index 000000000..3bc56f3ca --- /dev/null +++ b/src/electron/windowState.ts @@ -0,0 +1,205 @@ +import type { BrowserWindow, Rectangle } from 'electron'; + +import { screen } from 'electron'; +import Store from 'electron-store'; + +type Options = { + defaultHeight?: number; + defaultWidth?: number; + fullScreen?: boolean; + maximize?: boolean; +}; + +type State = { + displayBounds: { + height: number; + width: number; + }; + width: number; + height: number; + x: number; + y: number; + isFullScreen: boolean; + isMaximized: boolean; + urlHash: string; +}; + +export type WindowState = State & { + manage: (window: Electron.BrowserWindow) => void; + unmanage: () => void; + resetStateToDefault: () => void; + saveLastUrlHash: () => void; + clearLastUrlHash: () => void; +}; + +const EVENT_HANDLING_DELAY = 100; +const STORE_KEY = 'window-state'; +const DEFAULT_OPTIONS = { + defaultHeight: 600, + defaultWidth: 800, + maximize: true, + fullScreen: true, +}; + +const store: Store = new Store(); + +function windowStateKeeper(options: Options): WindowState { + let state: State; + let winRef: BrowserWindow | undefined; + let stateChangeTimer: NodeJS.Timer | number; + + options = { + ...DEFAULT_OPTIONS, + ...options, + }; + + function isNormal(win: BrowserWindow): boolean { + return !win.isMaximized() && !win.isMinimized() && !win.isFullScreen(); + } + + function hasBounds(): boolean { + return state + && Number.isInteger(state.x) + && Number.isInteger(state.y) + && Number.isInteger(state.width) && state.width > 0 + && Number.isInteger(state.height) && state.height > 0; + } + + function resetStateToDefault() { + const displayBounds = screen.getPrimaryDisplay().bounds; + + state = { + width: options.defaultWidth!, + height: options.defaultHeight!, + x: 0, + y: 0, + displayBounds, + isMaximized: false, + isFullScreen: false, + urlHash: '', + }; + } + + function windowWithinBounds(bounds: Rectangle) { + return state.x >= bounds.x + && state.y >= bounds.y + && state.x + state.width <= bounds.x + bounds.width + && state.y + state.height <= bounds.y + bounds.height; + } + + function ensureWindowVisibleOnSomeDisplay() { + const visible = screen.getAllDisplays().some((display) => windowWithinBounds(display.bounds)); + + if (!visible) { + resetStateToDefault(); + } + } + + function validateState() { + const isValid = state && (hasBounds() || state.isMaximized || state.isFullScreen); + + if (!isValid) { + resetStateToDefault(); + return; + } + + if (hasBounds() && state.displayBounds) { + ensureWindowVisibleOnSomeDisplay(); + } + } + + function updateState() { + if (!winRef) { + return; + } + + // Don't throw an error when window was closed + try { + const winBounds = winRef.getBounds(); + if (isNormal(winRef)) { + state.x = winBounds.x; + state.y = winBounds.y; + state.width = winBounds.width; + state.height = winBounds.height; + } + state.isMaximized = winRef.isMaximized(); + state.isFullScreen = winRef.isFullScreen(); + state.displayBounds = screen.getDisplayMatching(winBounds).bounds; + } catch (err) { + // Handler not supported, ignoring + } + } + + function handleStateChange() { + clearTimeout(stateChangeTimer); + stateChangeTimer = setTimeout(updateState, EVENT_HANDLING_DELAY); + } + + function handleClose() { + updateState(); + } + + function handleClosed() { + unmanage(); + store.set(STORE_KEY, state); + } + + function manage(win: BrowserWindow) { + if (options.maximize && state.isMaximized) { + win.maximize(); + } + if (options.fullScreen && state.isFullScreen) { + win.setFullScreen(true); + } + win.on('resize', handleStateChange); + win.on('move', handleStateChange); + win.on('close', handleClose); + win.on('closed', handleClosed); + winRef = win; + } + + function unmanage() { + if (winRef) { + winRef.removeListener('resize', handleStateChange); + winRef.removeListener('move', handleStateChange); + clearTimeout(stateChangeTimer); + winRef.removeListener('close', handleClose); + winRef.removeListener('closed', handleClosed); + winRef = undefined; + } + } + + function saveLastUrlHash() { + if (winRef) { + const { hash } = new URL(winRef.webContents.getURL()); + + state.urlHash = hash; + } + } + + function clearLastUrlHash() { + state.urlHash = ''; + } + + state = store.get(STORE_KEY) as State; + + validateState(); + + return { + get x() { return state.x; }, + get y() { return state.y; }, + get width() { return state.width; }, + get height() { return state.height; }, + get displayBounds() { return state.displayBounds; }, + get isMaximized() { return state.isMaximized; }, + get isFullScreen() { return state.isFullScreen; }, + get urlHash() { return state.urlHash || ''; }, + unmanage, + manage, + resetStateToDefault, + saveLastUrlHash, + clearLastUrlHash, + }; +} + +export default windowStateKeeper; diff --git a/src/global/actions/ui/chats.ts b/src/global/actions/ui/chats.ts index 7080f1bda..bc6bb80aa 100644 --- a/src/global/actions/ui/chats.ts +++ b/src/global/actions/ui/chats.ts @@ -82,6 +82,7 @@ addActionHandler('openChatInNewTab', (global, actions, payload): ActionReturnTyp const { chatId, threadId = MAIN_THREAD_ID } = payload; const hashUrl = createMessageHashUrl(chatId, 'thread', threadId); + if (IS_ELECTRON) { window.electron!.openNewWindow(hashUrl); } else { diff --git a/src/global/actions/ui/misc.ts b/src/global/actions/ui/misc.ts index 481f4db6e..5632120cf 100644 --- a/src/global/actions/ui/misc.ts +++ b/src/global/actions/ui/misc.ts @@ -694,7 +694,7 @@ addActionHandler('updatePageTitle', (global, actions, payload): ActionReturnType } } - setPageTitleInstant(PAGE_TITLE); + setPageTitleInstant(IS_ELECTRON ? '' : PAGE_TITLE); }); let prevIsScreenLocked: boolean | undefined; diff --git a/src/styles/index.scss b/src/styles/index.scss index 456eeecc2..9dd9f9daa 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -71,6 +71,10 @@ body.is-ios { --border-radius-messages-small: 0.5rem; } +body.is-electron { + --custom-cursor: default; +} + body.cursor-grabbing { --custom-cursor: grabbing; cursor: grabbing !important; diff --git a/src/types/electron.ts b/src/types/electron.ts index 10602a92a..517ba14e6 100644 --- a/src/types/electron.ts +++ b/src/types/electron.ts @@ -9,13 +9,19 @@ export enum ElectronAction { INSTALL_UPDATE = 'install-update', HANDLE_DOUBLE_CLICK = 'handle-double-click', OPEN_NEW_WINDOW = 'open-new-window', + SET_WINDOW_TITLE = 'set-window-title', + SET_TRAFFIC_LIGHT_POSITION = 'set-traffic-light-position', } +export type TrafficLightPosition = 'standard' | 'lowered'; + export interface ElectronApi { isFullscreen: () => Promise; installUpdate: () => Promise; handleDoubleClick: () => Promise; - openNewWindow: (url: string) => Promise; + openNewWindow: (url: string, title?: string) => Promise; + setWindowTitle: (title?: string) => Promise; + setTrafficLightPosition: (position: TrafficLightPosition) => Promise; on: (eventName: ElectronEvent, callback: any) => VoidFunction; } diff --git a/src/util/notifications.ts b/src/util/notifications.ts index 255e82dd0..88fec1a61 100644 --- a/src/util/notifications.ts +++ b/src/util/notifications.ts @@ -346,9 +346,9 @@ function getNotificationContent(chat: ApiChat, message: ApiMessage, reaction?: A !isScreenLocked && selectShouldShowMessagePreview(chat, selectNotifySettings(global), selectNotifyExceptions(global)) ) { - if (isActionMessage(message)) { - const isChat = chat && (isChatChannel(chat) || message.senderId === message.chatId); + const isChat = chat && (isChatChannel(chat) || message.senderId === message.chatId); + if (isActionMessage(message)) { body = renderActionMessageText( translate, message, diff --git a/src/util/updatePageTitle.ts b/src/util/updatePageTitle.ts index 0b1655297..d3f72f489 100644 --- a/src/util/updatePageTitle.ts +++ b/src/util/updatePageTitle.ts @@ -1,3 +1,4 @@ +import { IS_ELECTRON } from '../config'; import { debounce } from './schedulers'; const UPDATE_DEBOUNCE_MS = 200; @@ -5,6 +6,12 @@ const UPDATE_DEBOUNCE_MS = 200; // For some reason setting `document.title` to the same value // causes increment of Chrome Dev Tools > Performance Monitor > DOM Nodes counter export function setPageTitleInstant(nextTitle: string) { + if (IS_ELECTRON) { + window.electron!.setWindowTitle(nextTitle); + + return; + } + if (document.title !== nextTitle) { document.title = nextTitle; }