From 6dc84b3e5d40c16c60ac5998905c15c35a4d919b Mon Sep 17 00:00:00 2001 From: Devin Binnie <52460000+devinbinnie@users.noreply.github.com> Date: Mon, 20 Sep 2021 14:10:01 -0400 Subject: [PATCH] [MM-33112] Add support for multiple custom spellchecking languages (#1743) * [MM-33112] Add support for multiple custom spellchecking languages * Styles and other formatting * Type and lint fixes * Update wording --- package-lock.json | 493 ++++++++++++++----- package.json | 2 + src/common/communication.ts | 2 + src/common/config/defaultPreferences.ts | 2 +- src/common/config/index.ts | 4 +- src/common/config/upgradePreferences.ts | 1 + src/common/utils/constants.ts | 232 +++++++++ src/main/Validator.ts | 4 +- src/main/main.ts | 13 + src/renderer/components/SettingsPage.tsx | 127 ++--- src/renderer/css/lazy/settings-dark.lazy.css | 18 +- src/renderer/css/settings.css | 6 + src/types/config.ts | 2 +- 13 files changed, 732 insertions(+), 174 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9a5b9d5a..57c41d1b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,7 @@ "react-beautiful-dnd": "^13.1.0", "react-bootstrap": "^1.6.1", "react-dom": "^16.14.0", + "react-select": "4.3.1", "react-transition-group": "^2.5.0", "sass": "^1.35.1", "semver": "^5.5.0", @@ -51,6 +52,7 @@ "@types/react": "^17.0.11", "@types/react-beautiful-dnd": "^13.0.0", "@types/react-dom": "^17.0.8", + "@types/react-select": "^4.0.17", "@types/underscore": "^1.11.2", "@types/valid-url": "^1.0.3", "@types/winreg": "^1.2.30", @@ -162,7 +164,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/highlight": "^7.14.5" }, @@ -174,7 +176,7 @@ "version": "7.14.7", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.7.tgz", "integrity": "sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6.9.0" } @@ -183,7 +185,7 @@ "version": "7.14.6", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.6.tgz", "integrity": "sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/code-frame": "^7.14.5", "@babel/generator": "^7.14.5", @@ -213,7 +215,7 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, + "devOptional": true, "bin": { "semver": "bin/semver.js" } @@ -222,7 +224,7 @@ "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -231,7 +233,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz", "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/types": "^7.14.5", "jsesc": "^2.5.1", @@ -245,7 +247,7 @@ "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -279,7 +281,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.5.tgz", "integrity": "sha512-v+QtZqXEiOnpO6EYvlImB6zCD2Lel06RzOPzmkz/D/XgQiUu3C/Jb1LOqSt/AIA34TYi/Q+KlT8vTQrgdxkbLw==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/compat-data": "^7.14.5", "@babel/helper-validator-option": "^7.14.5", @@ -297,7 +299,7 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, + "devOptional": true, "bin": { "semver": "bin/semver.js" } @@ -382,7 +384,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/helper-get-function-arity": "^7.14.5", "@babel/template": "^7.14.5", @@ -396,7 +398,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/types": "^7.14.5" }, @@ -408,7 +410,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz", "integrity": "sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/types": "^7.14.5" }, @@ -420,7 +422,7 @@ "version": "7.14.7", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.7.tgz", "integrity": "sha512-TMUt4xKxJn6ccjcOW7c4hlwyJArizskAhoSTOCkA0uZ+KghIaci0Qg9R043kUMWI9mtQfgny+NQ5QATnZ+paaA==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/types": "^7.14.5" }, @@ -432,7 +434,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz", "integrity": "sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/types": "^7.14.5" }, @@ -444,7 +446,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.5.tgz", "integrity": "sha512-iXpX4KW8LVODuAieD7MzhNjmM6dzYY5tfRqT+R9HDXWl0jPn/djKmA+G9s/2C2T9zggw5tK1QNqZ70USfedOwA==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/helper-module-imports": "^7.14.5", "@babel/helper-replace-supers": "^7.14.5", @@ -463,7 +465,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz", "integrity": "sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/types": "^7.14.5" }, @@ -498,7 +500,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz", "integrity": "sha512-3i1Qe9/8x/hCHINujn+iuHy+mMRLoc77b2nI9TB0zjH1hvn9qGlXjWlggdwUcju36PkPCy/lpM7LLUdcTyH4Ow==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/helper-member-expression-to-functions": "^7.14.5", "@babel/helper-optimise-call-expression": "^7.14.5", @@ -513,7 +515,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.5.tgz", "integrity": "sha512-nfBN9xvmCt6nrMZjfhkl7i0oTV3yxR4/FztsbOASyTvVcoYd0TRHh7eMLdlEcCqobydC0LAF3LtC92Iwxo0wyw==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/types": "^7.14.5" }, @@ -537,7 +539,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/types": "^7.14.5" }, @@ -549,7 +551,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6.9.0" } @@ -558,7 +560,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6.9.0" } @@ -582,7 +584,7 @@ "version": "7.14.6", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.6.tgz", "integrity": "sha512-yesp1ENQBiLI+iYHSJdoZKUtRpfTlL1grDIX9NRlAVppljLw/4tTyYupIB7uIYmC3stW/imAv8EqaKaS/ibmeA==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/template": "^7.14.5", "@babel/traverse": "^7.14.5", @@ -596,7 +598,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/helper-validator-identifier": "^7.14.5", "chalk": "^2.0.0", @@ -610,7 +612,7 @@ "version": "7.14.7", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz", "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==", - "dev": true, + "devOptional": true, "bin": { "parser": "bin/babel-parser.js" }, @@ -1971,7 +1973,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/code-frame": "^7.14.5", "@babel/parser": "^7.14.5", @@ -1985,7 +1987,7 @@ "version": "7.14.7", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.7.tgz", "integrity": "sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/code-frame": "^7.14.5", "@babel/generator": "^7.14.5", @@ -2005,7 +2007,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/helper-validator-identifier": "^7.14.5", "to-fast-properties": "^2.0.0" @@ -2198,14 +2200,12 @@ "node_modules/@emotion/hash": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", - "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==", - "dev": true + "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" }, "node_modules/@emotion/memoize": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", - "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", - "dev": true + "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==" }, "node_modules/@emotion/serialize": { "version": "0.11.16", @@ -2241,8 +2241,7 @@ "node_modules/@emotion/unitless": { "version": "0.7.5", "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", - "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==", - "dev": true + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" }, "node_modules/@emotion/utils": { "version": "0.11.3", @@ -2253,8 +2252,7 @@ "node_modules/@emotion/weak-memoize": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz", - "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==", - "dev": true + "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==" }, "node_modules/@eslint/eslintrc": { "version": "0.3.0", @@ -5443,6 +5441,37 @@ "redux": "^4.0.0" } }, + "node_modules/@types/react-select": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/@types/react-select/-/react-select-4.0.17.tgz", + "integrity": "sha512-ZK5wcBhJaqC8ntQl0CJvK2KXNNsk1k5flM7jO+vNPPlceRzdJQazA6zTtQUyNr6exp5yrAiwiudtYxgGlgGHLg==", + "dev": true, + "dependencies": { + "@emotion/serialize": "^1.0.0", + "@types/react": "*", + "@types/react-dom": "*", + "@types/react-transition-group": "*" + } + }, + "node_modules/@types/react-select/node_modules/@emotion/serialize": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.0.2.tgz", + "integrity": "sha512-95MgNJ9+/ajxU7QIAruiOAdYNjxZX7G2mhgrtDWswA21VviYIRP1R5QilZ/bDY42xiKsaktP4egJb3QdYQZi1A==", + "dev": true, + "dependencies": { + "@emotion/hash": "^0.8.0", + "@emotion/memoize": "^0.7.4", + "@emotion/unitless": "^0.7.5", + "@emotion/utils": "^1.0.0", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-select/node_modules/@emotion/utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.0.0.tgz", + "integrity": "sha512-mQC2b3XLDs6QCW+pDQDiyO/EdGZYOygE8s5N5rrzjSI4M3IejPE/JPndCBwRT9z982aqQNi6beWs1UeayrQxxA==", + "dev": true + }, "node_modules/@types/react-syntax-highlighter": { "version": "11.0.5", "resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-11.0.5.tgz", @@ -8542,7 +8571,7 @@ "version": "4.16.7", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.7.tgz", "integrity": "sha512-7I4qVwqZltJ7j37wObBe3SoTz+nS8APaNcrBOlgoirb6/HbEU2XxW/LpUDTCngM6iauwFqmRTuOMfyKnFGY5JA==", - "dev": true, + "devOptional": true, "dependencies": { "caniuse-lite": "^1.0.30001248", "colorette": "^1.2.2", @@ -9203,7 +9232,7 @@ "version": "1.0.30001249", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001249.tgz", "integrity": "sha512-vcX4U8lwVXPdqzPWi6cAJ3FnQaqXbBqy/GZseKNQzRj37J7qZdGcBtxq/QLFNLLlfsoXLUdHw8Iwenri86Tagw==", - "dev": true, + "devOptional": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/browserslist" @@ -9255,7 +9284,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, + "devOptional": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -9269,7 +9298,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, + "devOptional": true, "dependencies": { "color-convert": "^1.9.0" }, @@ -9281,7 +9310,7 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, + "devOptional": true, "dependencies": { "color-name": "1.1.3" } @@ -9290,7 +9319,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "devOptional": true }, "node_modules/character-entities": { "version": "1.2.4", @@ -9696,7 +9725,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", - "dev": true + "devOptional": true }, "node_modules/colors": { "version": "1.4.0", @@ -9974,7 +10003,7 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dev": true, + "devOptional": true, "dependencies": { "safe-buffer": "~5.1.1" } @@ -11045,7 +11074,7 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, + "devOptional": true, "dependencies": { "ms": "2.1.2" }, @@ -13329,7 +13358,7 @@ "version": "1.3.801", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.801.tgz", "integrity": "sha512-xapG8ekC+IAHtJrGBMQSImNuN+dm+zl7UP1YbhvTkwQn8zf/yYuoxfTSAEiJ9VDD+kjvXaAhNDPSxJ+VImtAJA==", - "dev": true + "devOptional": true }, "node_modules/electron-updater": { "version": "4.3.9", @@ -13715,7 +13744,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6" } @@ -13738,7 +13767,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.8.0" } @@ -15770,7 +15799,7 @@ "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6.9.0" } @@ -16161,7 +16190,7 @@ "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, + "devOptional": true, "engines": { "node": ">=4" } @@ -16380,7 +16409,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, + "devOptional": true, "engines": { "node": ">=4" } @@ -18335,7 +18364,7 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, + "devOptional": true, "bin": { "jsesc": "bin/jsesc" }, @@ -18390,7 +18419,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, + "devOptional": true, "dependencies": { "minimist": "^1.2.5" }, @@ -20018,7 +20047,7 @@ "version": "1.1.73", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz", "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==", - "dev": true + "devOptional": true }, "node_modules/normalize-package-data": { "version": "2.5.0", @@ -22929,6 +22958,119 @@ "node": ">=0.10.0" } }, + "node_modules/react-select": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/react-select/-/react-select-4.3.1.tgz", + "integrity": "sha512-HBBd0dYwkF5aZk1zP81Wx5UsLIIT2lSvAY2JiJo199LjoLHoivjn9//KsmvQMEFGNhe58xyuOITjfxKCcGc62Q==", + "dependencies": { + "@babel/runtime": "^7.12.0", + "@emotion/cache": "^11.4.0", + "@emotion/react": "^11.1.1", + "memoize-one": "^5.0.0", + "prop-types": "^15.6.0", + "react-input-autosize": "^3.0.0", + "react-transition-group": "^4.3.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0", + "react-dom": "^16.8.0 || ^17.0.0" + } + }, + "node_modules/react-select/node_modules/@emotion/cache": { + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.4.0.tgz", + "integrity": "sha512-Zx70bjE7LErRO9OaZrhf22Qye1y4F7iDl+ITjet0J+i+B88PrAOBkKvaAWhxsZf72tDLajwCgfCjJ2dvH77C3g==", + "dependencies": { + "@emotion/memoize": "^0.7.4", + "@emotion/sheet": "^1.0.0", + "@emotion/utils": "^1.0.0", + "@emotion/weak-memoize": "^0.2.5", + "stylis": "^4.0.3" + } + }, + "node_modules/react-select/node_modules/@emotion/react": { + "version": "11.4.1", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.4.1.tgz", + "integrity": "sha512-pRegcsuGYj4FCdZN6j5vqCALkNytdrKw3TZMekTzNXixRg4wkLsU5QEaBG5LC6l01Vppxlp7FE3aTHpIG5phLg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@emotion/cache": "^11.4.0", + "@emotion/serialize": "^1.0.2", + "@emotion/sheet": "^1.0.2", + "@emotion/utils": "^1.0.0", + "@emotion/weak-memoize": "^0.2.5", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-select/node_modules/@emotion/serialize": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.0.2.tgz", + "integrity": "sha512-95MgNJ9+/ajxU7QIAruiOAdYNjxZX7G2mhgrtDWswA21VviYIRP1R5QilZ/bDY42xiKsaktP4egJb3QdYQZi1A==", + "dependencies": { + "@emotion/hash": "^0.8.0", + "@emotion/memoize": "^0.7.4", + "@emotion/unitless": "^0.7.5", + "@emotion/utils": "^1.0.0", + "csstype": "^3.0.2" + } + }, + "node_modules/react-select/node_modules/@emotion/sheet": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.0.2.tgz", + "integrity": "sha512-QQPB1B70JEVUHuNtzjHftMGv6eC3Y9wqavyarj4x4lg47RACkeSfNo5pxIOKizwS9AEFLohsqoaxGQj4p0vSIw==" + }, + "node_modules/react-select/node_modules/@emotion/utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.0.0.tgz", + "integrity": "sha512-mQC2b3XLDs6QCW+pDQDiyO/EdGZYOygE8s5N5rrzjSI4M3IejPE/JPndCBwRT9z982aqQNi6beWs1UeayrQxxA==" + }, + "node_modules/react-select/node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/react-select/node_modules/react-input-autosize": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/react-input-autosize/-/react-input-autosize-3.0.0.tgz", + "integrity": "sha512-nL9uS7jEs/zu8sqwFE5MAPx6pPkNAriACQ2rGLlqmKr2sPGtN7TXTyDdQt4lbNXVx7Uzadb40x8qotIuru6Rhg==", + "dependencies": { + "prop-types": "^15.5.8" + }, + "peerDependencies": { + "react": "^16.3.0 || ^17.0.0" + } + }, + "node_modules/react-select/node_modules/react-transition-group": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz", + "integrity": "sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, "node_modules/react-sizeme": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/react-sizeme/-/react-sizeme-3.0.1.tgz", @@ -25265,6 +25407,11 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/stylis": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.10.tgz", + "integrity": "sha512-m3k+dk7QeJw660eIKRRn3xPF6uuvHs/FFzjX3HQ5ove0qYsiygoAhwn5a3IYKaZPo5LrYD0rfVmtv1gNY1uYwg==" + }, "node_modules/sumchecker": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", @@ -25281,7 +25428,7 @@ "version": "5.4.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, + "devOptional": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -25842,7 +25989,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true, + "devOptional": true, "engines": { "node": ">=4" } @@ -28509,7 +28656,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", - "dev": true, + "devOptional": true, "requires": { "@babel/highlight": "^7.14.5" } @@ -28518,13 +28665,13 @@ "version": "7.14.7", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.7.tgz", "integrity": "sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw==", - "dev": true + "devOptional": true }, "@babel/core": { "version": "7.14.6", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.6.tgz", "integrity": "sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA==", - "dev": true, + "devOptional": true, "requires": { "@babel/code-frame": "^7.14.5", "@babel/generator": "^7.14.5", @@ -28547,13 +28694,13 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "devOptional": true }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + "devOptional": true } } }, @@ -28561,7 +28708,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz", "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==", - "dev": true, + "devOptional": true, "requires": { "@babel/types": "^7.14.5", "jsesc": "^2.5.1", @@ -28572,7 +28719,7 @@ "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + "devOptional": true } } }, @@ -28599,7 +28746,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.5.tgz", "integrity": "sha512-v+QtZqXEiOnpO6EYvlImB6zCD2Lel06RzOPzmkz/D/XgQiUu3C/Jb1LOqSt/AIA34TYi/Q+KlT8vTQrgdxkbLw==", - "dev": true, + "devOptional": true, "requires": { "@babel/compat-data": "^7.14.5", "@babel/helper-validator-option": "^7.14.5", @@ -28611,7 +28758,7 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "devOptional": true } } }, @@ -28676,7 +28823,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", - "dev": true, + "devOptional": true, "requires": { "@babel/helper-get-function-arity": "^7.14.5", "@babel/template": "^7.14.5", @@ -28687,7 +28834,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", - "dev": true, + "devOptional": true, "requires": { "@babel/types": "^7.14.5" } @@ -28696,7 +28843,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz", "integrity": "sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ==", - "dev": true, + "devOptional": true, "requires": { "@babel/types": "^7.14.5" } @@ -28705,7 +28852,7 @@ "version": "7.14.7", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.7.tgz", "integrity": "sha512-TMUt4xKxJn6ccjcOW7c4hlwyJArizskAhoSTOCkA0uZ+KghIaci0Qg9R043kUMWI9mtQfgny+NQ5QATnZ+paaA==", - "dev": true, + "devOptional": true, "requires": { "@babel/types": "^7.14.5" } @@ -28714,7 +28861,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz", "integrity": "sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==", - "dev": true, + "devOptional": true, "requires": { "@babel/types": "^7.14.5" } @@ -28723,7 +28870,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.5.tgz", "integrity": "sha512-iXpX4KW8LVODuAieD7MzhNjmM6dzYY5tfRqT+R9HDXWl0jPn/djKmA+G9s/2C2T9zggw5tK1QNqZ70USfedOwA==", - "dev": true, + "devOptional": true, "requires": { "@babel/helper-module-imports": "^7.14.5", "@babel/helper-replace-supers": "^7.14.5", @@ -28739,7 +28886,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz", "integrity": "sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA==", - "dev": true, + "devOptional": true, "requires": { "@babel/types": "^7.14.5" } @@ -28765,7 +28912,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz", "integrity": "sha512-3i1Qe9/8x/hCHINujn+iuHy+mMRLoc77b2nI9TB0zjH1hvn9qGlXjWlggdwUcju36PkPCy/lpM7LLUdcTyH4Ow==", - "dev": true, + "devOptional": true, "requires": { "@babel/helper-member-expression-to-functions": "^7.14.5", "@babel/helper-optimise-call-expression": "^7.14.5", @@ -28777,7 +28924,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.5.tgz", "integrity": "sha512-nfBN9xvmCt6nrMZjfhkl7i0oTV3yxR4/FztsbOASyTvVcoYd0TRHh7eMLdlEcCqobydC0LAF3LtC92Iwxo0wyw==", - "dev": true, + "devOptional": true, "requires": { "@babel/types": "^7.14.5" } @@ -28795,7 +28942,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", - "dev": true, + "devOptional": true, "requires": { "@babel/types": "^7.14.5" } @@ -28804,13 +28951,13 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", - "dev": true + "devOptional": true }, "@babel/helper-validator-option": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", - "dev": true + "devOptional": true }, "@babel/helper-wrap-function": { "version": "7.14.5", @@ -28828,7 +28975,7 @@ "version": "7.14.6", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.6.tgz", "integrity": "sha512-yesp1ENQBiLI+iYHSJdoZKUtRpfTlL1grDIX9NRlAVppljLw/4tTyYupIB7uIYmC3stW/imAv8EqaKaS/ibmeA==", - "dev": true, + "devOptional": true, "requires": { "@babel/template": "^7.14.5", "@babel/traverse": "^7.14.5", @@ -28839,7 +28986,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", - "dev": true, + "devOptional": true, "requires": { "@babel/helper-validator-identifier": "^7.14.5", "chalk": "^2.0.0", @@ -28850,7 +28997,7 @@ "version": "7.14.7", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz", "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==", - "dev": true + "devOptional": true }, "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { "version": "7.14.5", @@ -29760,7 +29907,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", - "dev": true, + "devOptional": true, "requires": { "@babel/code-frame": "^7.14.5", "@babel/parser": "^7.14.5", @@ -29771,7 +29918,7 @@ "version": "7.14.7", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.7.tgz", "integrity": "sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==", - "dev": true, + "devOptional": true, "requires": { "@babel/code-frame": "^7.14.5", "@babel/generator": "^7.14.5", @@ -29788,7 +29935,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", - "dev": true, + "devOptional": true, "requires": { "@babel/helper-validator-identifier": "^7.14.5", "to-fast-properties": "^2.0.0" @@ -29943,14 +30090,12 @@ "@emotion/hash": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", - "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==", - "dev": true + "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" }, "@emotion/memoize": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", - "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", - "dev": true + "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==" }, "@emotion/serialize": { "version": "0.11.16", @@ -29988,8 +30133,7 @@ "@emotion/unitless": { "version": "0.7.5", "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", - "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==", - "dev": true + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" }, "@emotion/utils": { "version": "0.11.3", @@ -30000,8 +30144,7 @@ "@emotion/weak-memoize": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz", - "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==", - "dev": true + "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==" }, "@eslint/eslintrc": { "version": "0.3.0", @@ -32432,6 +32575,39 @@ "redux": "^4.0.0" } }, + "@types/react-select": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/@types/react-select/-/react-select-4.0.17.tgz", + "integrity": "sha512-ZK5wcBhJaqC8ntQl0CJvK2KXNNsk1k5flM7jO+vNPPlceRzdJQazA6zTtQUyNr6exp5yrAiwiudtYxgGlgGHLg==", + "dev": true, + "requires": { + "@emotion/serialize": "^1.0.0", + "@types/react": "*", + "@types/react-dom": "*", + "@types/react-transition-group": "*" + }, + "dependencies": { + "@emotion/serialize": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.0.2.tgz", + "integrity": "sha512-95MgNJ9+/ajxU7QIAruiOAdYNjxZX7G2mhgrtDWswA21VviYIRP1R5QilZ/bDY42xiKsaktP4egJb3QdYQZi1A==", + "dev": true, + "requires": { + "@emotion/hash": "^0.8.0", + "@emotion/memoize": "^0.7.4", + "@emotion/unitless": "^0.7.5", + "@emotion/utils": "^1.0.0", + "csstype": "^3.0.2" + } + }, + "@emotion/utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.0.0.tgz", + "integrity": "sha512-mQC2b3XLDs6QCW+pDQDiyO/EdGZYOygE8s5N5rrzjSI4M3IejPE/JPndCBwRT9z982aqQNi6beWs1UeayrQxxA==", + "dev": true + } + } + }, "@types/react-syntax-highlighter": { "version": "11.0.5", "resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-11.0.5.tgz", @@ -34972,7 +35148,7 @@ "version": "4.16.7", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.7.tgz", "integrity": "sha512-7I4qVwqZltJ7j37wObBe3SoTz+nS8APaNcrBOlgoirb6/HbEU2XxW/LpUDTCngM6iauwFqmRTuOMfyKnFGY5JA==", - "dev": true, + "devOptional": true, "requires": { "caniuse-lite": "^1.0.30001248", "colorette": "^1.2.2", @@ -35496,7 +35672,7 @@ "version": "1.0.30001249", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001249.tgz", "integrity": "sha512-vcX4U8lwVXPdqzPWi6cAJ3FnQaqXbBqy/GZseKNQzRj37J7qZdGcBtxq/QLFNLLlfsoXLUdHw8Iwenri86Tagw==", - "dev": true + "devOptional": true }, "case-sensitive-paths-webpack-plugin": { "version": "2.4.0", @@ -35535,7 +35711,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, + "devOptional": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -35546,7 +35722,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, + "devOptional": true, "requires": { "color-convert": "^1.9.0" } @@ -35555,7 +35731,7 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, + "devOptional": true, "requires": { "color-name": "1.1.3" } @@ -35564,7 +35740,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "devOptional": true } } }, @@ -35887,7 +36063,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", - "dev": true + "devOptional": true }, "colors": { "version": "1.4.0", @@ -36122,7 +36298,7 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dev": true, + "devOptional": true, "requires": { "safe-buffer": "~5.1.1" } @@ -36964,7 +37140,7 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, + "devOptional": true, "requires": { "ms": "2.1.2" } @@ -38778,7 +38954,7 @@ "version": "1.3.801", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.801.tgz", "integrity": "sha512-xapG8ekC+IAHtJrGBMQSImNuN+dm+zl7UP1YbhvTkwQn8zf/yYuoxfTSAEiJ9VDD+kjvXaAhNDPSxJ+VImtAJA==", - "dev": true + "devOptional": true }, "electron-updater": { "version": "4.3.9", @@ -39111,7 +39287,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true + "devOptional": true }, "escape-goat": { "version": "2.1.1", @@ -39128,7 +39304,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "devOptional": true }, "eslint": { "version": "7.19.0", @@ -40785,7 +40961,7 @@ "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true + "devOptional": true }, "get-caller-file": { "version": "2.0.5", @@ -41098,7 +41274,7 @@ "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true + "devOptional": true }, "globalthis": { "version": "1.0.1", @@ -41278,7 +41454,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "devOptional": true }, "has-glob": { "version": "1.0.0", @@ -42811,7 +42987,7 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true + "devOptional": true }, "json-buffer": { "version": "3.0.0", @@ -42860,7 +43036,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, + "devOptional": true, "requires": { "minimist": "^1.2.5" } @@ -44230,7 +44406,7 @@ "version": "1.1.73", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz", "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==", - "dev": true + "devOptional": true }, "normalize-package-data": { "version": "2.5.0", @@ -46524,6 +46700,98 @@ "integrity": "sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg==", "dev": true }, + "react-select": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/react-select/-/react-select-4.3.1.tgz", + "integrity": "sha512-HBBd0dYwkF5aZk1zP81Wx5UsLIIT2lSvAY2JiJo199LjoLHoivjn9//KsmvQMEFGNhe58xyuOITjfxKCcGc62Q==", + "requires": { + "@babel/runtime": "^7.12.0", + "@emotion/cache": "^11.4.0", + "@emotion/react": "^11.1.1", + "memoize-one": "^5.0.0", + "prop-types": "^15.6.0", + "react-input-autosize": "^3.0.0", + "react-transition-group": "^4.3.0" + }, + "dependencies": { + "@emotion/cache": { + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.4.0.tgz", + "integrity": "sha512-Zx70bjE7LErRO9OaZrhf22Qye1y4F7iDl+ITjet0J+i+B88PrAOBkKvaAWhxsZf72tDLajwCgfCjJ2dvH77C3g==", + "requires": { + "@emotion/memoize": "^0.7.4", + "@emotion/sheet": "^1.0.0", + "@emotion/utils": "^1.0.0", + "@emotion/weak-memoize": "^0.2.5", + "stylis": "^4.0.3" + } + }, + "@emotion/react": { + "version": "11.4.1", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.4.1.tgz", + "integrity": "sha512-pRegcsuGYj4FCdZN6j5vqCALkNytdrKw3TZMekTzNXixRg4wkLsU5QEaBG5LC6l01Vppxlp7FE3aTHpIG5phLg==", + "requires": { + "@babel/runtime": "^7.13.10", + "@emotion/cache": "^11.4.0", + "@emotion/serialize": "^1.0.2", + "@emotion/sheet": "^1.0.2", + "@emotion/utils": "^1.0.0", + "@emotion/weak-memoize": "^0.2.5", + "hoist-non-react-statics": "^3.3.1" + } + }, + "@emotion/serialize": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.0.2.tgz", + "integrity": "sha512-95MgNJ9+/ajxU7QIAruiOAdYNjxZX7G2mhgrtDWswA21VviYIRP1R5QilZ/bDY42xiKsaktP4egJb3QdYQZi1A==", + "requires": { + "@emotion/hash": "^0.8.0", + "@emotion/memoize": "^0.7.4", + "@emotion/unitless": "^0.7.5", + "@emotion/utils": "^1.0.0", + "csstype": "^3.0.2" + } + }, + "@emotion/sheet": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.0.2.tgz", + "integrity": "sha512-QQPB1B70JEVUHuNtzjHftMGv6eC3Y9wqavyarj4x4lg47RACkeSfNo5pxIOKizwS9AEFLohsqoaxGQj4p0vSIw==" + }, + "@emotion/utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.0.0.tgz", + "integrity": "sha512-mQC2b3XLDs6QCW+pDQDiyO/EdGZYOygE8s5N5rrzjSI4M3IejPE/JPndCBwRT9z982aqQNi6beWs1UeayrQxxA==" + }, + "dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "requires": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "react-input-autosize": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/react-input-autosize/-/react-input-autosize-3.0.0.tgz", + "integrity": "sha512-nL9uS7jEs/zu8sqwFE5MAPx6pPkNAriACQ2rGLlqmKr2sPGtN7TXTyDdQt4lbNXVx7Uzadb40x8qotIuru6Rhg==", + "requires": { + "prop-types": "^15.5.8" + } + }, + "react-transition-group": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz", + "integrity": "sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==", + "requires": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + } + } + } + }, "react-sizeme": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/react-sizeme/-/react-sizeme-3.0.1.tgz", @@ -48442,6 +48710,11 @@ } } }, + "stylis": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.10.tgz", + "integrity": "sha512-m3k+dk7QeJw660eIKRRn3xPF6uuvHs/FFzjX3HQ5ove0qYsiygoAhwn5a3IYKaZPo5LrYD0rfVmtv1gNY1uYwg==" + }, "sumchecker": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", @@ -48455,7 +48728,7 @@ "version": "5.4.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, + "devOptional": true, "requires": { "has-flag": "^3.0.0" } @@ -48919,7 +49192,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true + "devOptional": true }, "to-object-path": { "version": "0.3.0", diff --git a/package.json b/package.json index d91fa414..e5364e9d 100644 --- a/package.json +++ b/package.json @@ -73,6 +73,7 @@ "@types/react": "^17.0.11", "@types/react-beautiful-dnd": "^13.0.0", "@types/react-dom": "^17.0.8", + "@types/react-select": "^4.0.17", "@types/underscore": "^1.11.2", "@types/valid-url": "^1.0.3", "@types/winreg": "^1.2.30", @@ -138,6 +139,7 @@ "react-beautiful-dnd": "^13.1.0", "react-bootstrap": "^1.6.1", "react-dom": "^16.14.0", + "react-select": "4.3.1", "react-transition-group": "^2.5.0", "sass": "^1.35.1", "semver": "^5.5.0", diff --git a/src/common/communication.ts b/src/common/communication.ts index 68388c7d..379ac335 100644 --- a/src/common/communication.ts +++ b/src/common/communication.ts @@ -98,3 +98,5 @@ export const SEND_DROPDOWN_MENU_SIZE = 'send-dropdown-menu-size'; export const BROWSER_HISTORY_PUSH = 'browser-history-push'; export const APP_LOGGED_IN = 'app-logged-in'; + +export const GET_AVAILABLE_SPELL_CHECKER_LANGUAGES = 'get-available-spell-checker-languages'; diff --git a/src/common/config/defaultPreferences.ts b/src/common/config/defaultPreferences.ts index 79dd76c5..c6bb8533 100644 --- a/src/common/config/defaultPreferences.ts +++ b/src/common/config/defaultPreferences.ts @@ -31,7 +31,7 @@ const defaultPreferences: ConfigV3 = { useSpellChecker: true, enableHardwareAcceleration: true, autostart: true, - spellCheckerLocale: 'en-US', + spellCheckerLocales: [], darkMode: false, downloadLocation: getDefaultDownloadLocation(), }; diff --git a/src/common/config/index.ts b/src/common/config/index.ts index c54b2da1..3eb0412b 100644 --- a/src/common/config/index.ts +++ b/src/common/config/index.ts @@ -235,8 +235,8 @@ export default class Config extends EventEmitter { return this.combinedData?.spellCheckerURL; } - get spellCheckerLocale() { - return this.combinedData?.spellCheckerLocale ?? defaultPreferences.spellCheckerLocale; + get spellCheckerLocales() { + return this.combinedData?.spellCheckerLocales ?? defaultPreferences.spellCheckerLocales; } get showTrayIcon() { return this.combinedData?.showTrayIcon ?? defaultPreferences.showTrayIcon; diff --git a/src/common/config/upgradePreferences.ts b/src/common/config/upgradePreferences.ts index 27a120e6..b94737e4 100644 --- a/src/common/config/upgradePreferences.ts +++ b/src/common/config/upgradePreferences.ts @@ -43,6 +43,7 @@ function upgradeV2toV3(configV2: ConfigV2) { }; }); config.lastActiveTeam = 0; + config.spellCheckerLocales = []; return config; } diff --git a/src/common/utils/constants.ts b/src/common/utils/constants.ts index 0bd96efe..097a8804 100644 --- a/src/common/utils/constants.ts +++ b/src/common/utils/constants.ts @@ -1,5 +1,6 @@ // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. +/* eslint-disable quote-props */ export const PRODUCTION = 'production'; export const DEVELOPMENT = 'development'; @@ -21,3 +22,234 @@ export const DEFAULT_WINDOW_WIDTH = 1000; export const DEFAULT_WINDOW_HEIGHT = 700; export const MINIMUM_WINDOW_WIDTH = 700; export const MINIMUM_WINDOW_HEIGHT = 240; + +export const localeTranslations: Record = { + 'af': 'Afrikaans', + 'af-ZA': 'Afrikaans (South Africa)', + 'ar': 'Arabic', + 'ar-AE': 'Arabic (U.A.E.)', + 'ar-BH': 'Arabic (Bahrain)', + 'ar-DZ': 'Arabic (Algeria)', + 'ar-EG': 'Arabic (Egypt)', + 'ar-IQ': 'Arabic (Iraq)', + 'ar-JO': 'Arabic (Jordan)', + 'ar-KW': 'Arabic (Kuwait)', + 'ar-LB': 'Arabic (Lebanon)', + 'ar-LY': 'Arabic (Libya)', + 'ar-MA': 'Arabic (Morocco)', + 'ar-OM': 'Arabic (Oman)', + 'ar-QA': 'Arabic (Qatar)', + 'ar-SA': 'Arabic (Saudi Arabia)', + 'ar-SY': 'Arabic (Syria)', + 'ar-TN': 'Arabic (Tunisia)', + 'ar-YE': 'Arabic (Yemen)', + 'az': 'Azeri (Latin)', + 'az-AZ': 'Azeri (Azerbaijan)', + 'be': 'Belarusian', + 'be-BY': 'Belarusian (Belarus)', + 'bg': 'Bulgarian', + 'bg-BG': 'Bulgarian (Bulgaria)', + 'bs-BA': 'Bosnian (Bosnia and Herzegovina)', + 'ca': 'Catalan', + 'ca-ES': 'Catalan (Spain)', + 'cs': 'Czech', + 'cs-CZ': 'Czech (Czech Republic)', + 'cy': 'Welsh', + 'cy-GB': 'Welsh (United Kingdom)', + 'da': 'Danish', + 'da-DK': 'Danish (Denmark)', + 'de': 'German', + 'de-AT': 'German (Austria)', + 'de-CH': 'German (Switzerland)', + 'de-DE': 'German (Germany)', + 'de-LI': 'German (Liechtenstein)', + 'de-LU': 'German (Luxembourg)', + 'dv': 'Divehi', + 'dv-MV': 'Divehi (Maldives)', + 'el': 'Greek', + 'el-GR': 'Greek (Greece)', + 'en': 'English', + 'en-AU': 'English (Australia)', + 'en-BZ': 'English (Belize)', + 'en-CA': 'English (Canada)', + 'en-CB': 'English (Caribbean)', + 'en-GB': 'English (United Kingdom)', + 'en-IE': 'English (Ireland)', + 'en-JM': 'English (Jamaica)', + 'en-NZ': 'English (New Zealand)', + 'en-PH': 'English (Republic of the Philippines)', + 'en-TT': 'English (Trinidad and Tobago)', + 'en-US': 'English (United States)', + 'en-ZA': 'English (South Africa)', + 'en-ZW': 'English (Zimbabwe)', + 'eo': 'Esperanto', + 'es': 'Spanish', + 'es-AR': 'Spanish (Argentina)', + 'es-BO': 'Spanish (Bolivia)', + 'es-CL': 'Spanish (Chile)', + 'es-CO': 'Spanish (Colombia)', + 'es-CR': 'Spanish (Costa Rica)', + 'es-DO': 'Spanish (Dominican Republic)', + 'es-EC': 'Spanish (Ecuador)', + 'es-ES': 'Spanish (Spain)', + 'es-GT': 'Spanish (Guatemala)', + 'es-HN': 'Spanish (Honduras)', + 'es-MX': 'Spanish (Mexico)', + 'es-NI': 'Spanish (Nicaragua)', + 'es-PA': 'Spanish (Panama)', + 'es-PE': 'Spanish (Peru)', + 'es-PR': 'Spanish (Puerto Rico)', + 'es-PY': 'Spanish (Paraguay)', + 'es-SV': 'Spanish (El Salvador)', + 'es-UY': 'Spanish (Uruguay)', + 'es-VE': 'Spanish (Venezuela)', + 'et': 'Estonian', + 'et-EE': 'Estonian (Estonia)', + 'eu': 'Basque', + 'eu-ES': 'Basque (Spain)', + 'fa': 'Farsi', + 'fa-IR': 'Farsi (Iran)', + 'fi': 'Finnish', + 'fi-FI': 'Finnish (Finland)', + 'fo': 'Faroese', + 'fo-FO': 'Faroese (Faroe Islands)', + 'fr': 'French', + 'fr-BE': 'French (Belgium)', + 'fr-CA': 'French (Canada)', + 'fr-CH': 'French (Switzerland)', + 'fr-FR': 'French (France)', + 'fr-LU': 'French (Luxembourg)', + 'fr-MC': 'French (Principality of Monaco)', + 'gl': 'Galician', + 'gl-ES': 'Galician (Spain)', + 'gu': 'Gujarati', + 'gu-IN': 'Gujarati (India)', + 'he': 'Hebrew', + 'he-IL': 'Hebrew (Israel)', + 'hi': 'Hindi', + 'hi-IN': 'Hindi (India)', + 'hr': 'Croatian', + 'hr-BA': 'Croatian (Bosnia and Herzegovina)', + 'hr-HR': 'Croatian (Croatia)', + 'hu': 'Hungarian', + 'hu-HU': 'Hungarian (Hungary)', + 'hy': 'Armenian', + 'hy-AM': 'Armenian (Armenia)', + 'id': 'Indonesian', + 'id-ID': 'Indonesian (Indonesia)', + 'is': 'Icelandic', + 'is-IS': 'Icelandic (Iceland)', + 'it': 'Italian', + 'it-CH': 'Italian (Switzerland)', + 'it-IT': 'Italian (Italy)', + 'ja': 'Japanese', + 'ja-JP': 'Japanese (Japan)', + 'ka': 'Georgian', + 'ka-GE': 'Georgian (Georgia)', + 'kk': 'Kazakh', + 'kk-KZ': 'Kazakh (Kazakhstan)', + 'kn': 'Kannada', + 'kn-IN': 'Kannada (India)', + 'ko': 'Korean', + 'ko-KR': 'Korean (Korea)', + 'kok': 'Konkani', + 'kok-IN': 'Konkani (India)', + 'ky': 'Kyrgyz', + 'ky-KG': 'Kyrgyz (Kyrgyzstan)', + 'lt': 'Lithuanian', + 'lt-LT': 'Lithuanian (Lithuania)', + 'lv': 'Latvian', + 'lv-LV': 'Latvian (Latvia)', + 'mi': 'Maori', + 'mi-NZ': 'Maori (New Zealand)', + 'mk': 'FYRO Macedonian', + 'mk-MK': 'FYRO Macedonian (Former Yugoslav Republic of Macedonia)', + 'mn': 'Mongolian', + 'mn-MN': 'Mongolian (Mongolia)', + 'mr': 'Marathi', + 'mr-IN': 'Marathi (India)', + 'ms': 'Malay', + 'ms-BN': 'Malay (Brunei Darussalam)', + 'ms-MY': 'Malay (Malaysia)', + 'mt': 'Maltese', + 'mt-MT': 'Maltese (Malta)', + 'nb': 'Norwegian (Bokm?l)', + 'nb-NO': 'Norwegian (Bokm?l) (Norway)', + 'nl': 'Dutch', + 'nl-BE': 'Dutch (Belgium)', + 'nl-NL': 'Dutch (Netherlands)', + 'nn-NO': 'Norwegian (Nynorsk) (Norway)', + 'ns': 'Northern Sotho', + 'ns-ZA': 'Northern Sotho (South Africa)', + 'pa': 'Punjabi', + 'pa-IN': 'Punjabi (India)', + 'pl': 'Polish', + 'pl-PL': 'Polish (Poland)', + 'ps': 'Pashto', + 'ps-AR': 'Pashto (Afghanistan)', + 'pt': 'Portuguese', + 'pt-BR': 'Portuguese (Brazil)', + 'pt-PT': 'Portuguese (Portugal)', + 'qu': 'Quechua', + 'qu-BO': 'Quechua (Bolivia)', + 'qu-EC': 'Quechua (Ecuador)', + 'qu-PE': 'Quechua (Peru)', + 'ro': 'Romanian', + 'ro-RO': 'Romanian (Romania)', + 'ru': 'Russian', + 'ru-RU': 'Russian (Russia)', + 'sa': 'Sanskrit', + 'sa-IN': 'Sanskrit (India)', + 'se': 'Sami (Northern)', + 'se-FI': 'Sami (Finland)', + 'se-NO': 'Sami (Norway)', + 'se-SE': 'Sami (Sweden)', + 'sk': 'Slovak', + 'sk-SK': 'Slovak (Slovakia)', + 'sl': 'Slovenian', + 'sl-SI': 'Slovenian (Slovenia)', + 'sq': 'Albanian', + 'sq-AL': 'Albanian (Albania)', + 'sr-BA': 'Serbian (Bosnia and Herzegovina)', + 'sr-SP': 'Serbian (Serbia and Montenegro)', + 'sv': 'Swedish', + 'sv-FI': 'Swedish (Finland)', + 'sv-SE': 'Swedish (Sweden)', + 'sw': 'Swahili', + 'sw-KE': 'Swahili (Kenya)', + 'syr': 'Syriac', + 'syr-SY': 'Syriac (Syria)', + 'ta': 'Tamil', + 'ta-IN': 'Tamil (India)', + 'te': 'Telugu', + 'te-IN': 'Telugu (India)', + 'th': 'Thai', + 'th-TH': 'Thai (Thailand)', + 'tl': 'Tagalog', + 'tl-PH': 'Tagalog (Philippines)', + 'tn': 'Tswana', + 'tn-ZA': 'Tswana (South Africa)', + 'tr': 'Turkish', + 'tr-TR': 'Turkish (Turkey)', + 'tt': 'Tatar', + 'tt-RU': 'Tatar (Russia)', + 'ts': 'Tsonga', + 'uk': 'Ukrainian', + 'uk-UA': 'Ukrainian (Ukraine)', + 'ur': 'Urdu', + 'ur-PK': 'Urdu (Islamic Republic of Pakistan)', + 'uz': 'Uzbek (Latin)', + 'uz-UZ': 'Uzbek (Uzbekistan)', + 'vi': 'Vietnamese', + 'vi-VN': 'Vietnamese (Viet Nam)', + 'xh': 'Xhosa', + 'xh-ZA': 'Xhosa (South Africa)', + 'zh': 'Chinese', + 'zh-CN': 'Chinese (S)', + 'zh-HK': 'Chinese (Hong Kong)', + 'zh-MO': 'Chinese (Macau)', + 'zh-SG': 'Chinese (Singapore)', + 'zh-TW': 'Chinese (T)', + 'zu': 'Zulu', + 'zu-ZA': 'Zulu (South Africa)', +}; diff --git a/src/main/Validator.ts b/src/main/Validator.ts index f641a31e..c7ae5f05 100644 --- a/src/main/Validator.ts +++ b/src/main/Validator.ts @@ -88,7 +88,7 @@ const configDataSchemaV2 = Joi.object({ useSpellChecker: Joi.boolean().default(true), enableHardwareAcceleration: Joi.boolean().default(true), autostart: Joi.boolean().default(true), - spellCheckerLocale: Joi.string().regex(/^[a-z]{2}-[A-Z]{2}$/).default('en-US'), + spellCheckerLocale: Joi.string().default('en-US'), spellCheckerURL: Joi.string().allow(null), darkMode: Joi.boolean().default(false), downloadLocation: Joi.string(), @@ -119,7 +119,7 @@ const configDataSchemaV3 = Joi.object({ useSpellChecker: Joi.boolean().default(true), enableHardwareAcceleration: Joi.boolean().default(true), autostart: Joi.boolean().default(true), - spellCheckerLocale: Joi.string().regex(/^[a-z]{2}-[A-Z]{2}$/).default('en-US'), + spellCheckerLocales: Joi.array().items(Joi.string().regex(/^[a-z]{2}-[A-Z]{2}$/)).default([]), spellCheckerURL: Joi.string().allow(null), darkMode: Joi.boolean().default(false), downloadLocation: Joi.string(), diff --git a/src/main/main.ts b/src/main/main.ts index 38df03ee..549edecf 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -43,6 +43,7 @@ import { UPDATE_SHORTCUT_MENU, OPEN_TEAMS_DROPDOWN, UPDATE_LAST_ACTIVE, + GET_AVAILABLE_SPELL_CHECKER_LANGUAGES, } from 'common/communication'; import Config from 'common/config'; import {MattermostServer} from 'common/servers/MattermostServer'; @@ -265,6 +266,7 @@ function initializeInterCommunicationEventListeners() { ipcMain.on(WINDOW_MINIMIZE, WindowManager.minimize); ipcMain.on(WINDOW_RESTORE, WindowManager.restore); ipcMain.on(SHOW_SETTINGS_WINDOW, WindowManager.showSettingsWindow); + ipcMain.handle(GET_AVAILABLE_SPELL_CHECKER_LANGUAGES, handleGetAvailableSpellCheckerLanguages); ipcMain.handle(GET_DOWNLOAD_LOCATION, handleSelectDownload); } @@ -289,6 +291,7 @@ function handleConfigUpdate(newConfig: CombinedConfig) { authManager.handleConfigUpdate(newConfig); } setUnreadBadgeSetting(newConfig && newConfig.showUnreadBadge); + updateSpellCheckerLocales(); } ipcMain.emit('update-menu', true, config); @@ -639,6 +642,12 @@ function handleRemoveServerModal(e: IpcMainEvent, name: string) { } } +function updateSpellCheckerLocales() { + if (config.data?.spellCheckerLocales.length && app.isReady()) { + session.defaultSession.setSpellCheckerLanguages(config.data?.spellCheckerLocales); + } +} + function initializeAfterAppReady() { updateServerInfos(config.teams); app.setAppUserModelId('Mattermost.Desktop'); // Use explicit AppUserModelID @@ -662,6 +671,7 @@ function initializeAfterAppReady() { log.info(`Dictionary definitions downloaded successfully for ${lang}`); }); } + updateSpellCheckerLocales(); } const appVersionJson = path.join(app.getPath('userData'), 'app-state.json'); @@ -975,3 +985,6 @@ function handleUpdateLastActive(event: IpcMainEvent, serverName: string, viewNam config.set('lastActiveTeam', teams.find((team) => team.name === serverName)?.order || 0); } +function handleGetAvailableSpellCheckerLanguages() { + return session.defaultSession.availableSpellCheckerLanguages; +} diff --git a/src/renderer/components/SettingsPage.tsx b/src/renderer/components/SettingsPage.tsx index efabba46..8e69340e 100644 --- a/src/renderer/components/SettingsPage.tsx +++ b/src/renderer/components/SettingsPage.tsx @@ -8,13 +8,23 @@ import 'renderer/css/settings.css'; import React from 'react'; import {FormCheck, Col, FormGroup, FormText, Container, Row, Button} from 'react-bootstrap'; +import ReactSelect, {ActionMeta, OptionsType} from 'react-select'; import {debounce} from 'underscore'; -import {CombinedConfig, LocalConfiguration, Team} from 'types/config'; +import {CombinedConfig, LocalConfiguration} from 'types/config'; import {DeepPartial} from 'types/utils'; -import {GET_LOCAL_CONFIGURATION, UPDATE_CONFIGURATION, DOUBLE_CLICK_ON_WINDOW, GET_DOWNLOAD_LOCATION, ADD_SERVER, RELOAD_CONFIGURATION} from 'common/communication'; +import {localeTranslations} from 'common/utils/constants'; + +import { + GET_LOCAL_CONFIGURATION, + UPDATE_CONFIGURATION, + DOUBLE_CLICK_ON_WINDOW, + GET_DOWNLOAD_LOCATION, + RELOAD_CONFIGURATION, + GET_AVAILABLE_SPELL_CHECKER_LANGUAGES, +} from 'common/communication'; import AutoSaveIndicator, {SavingState} from './AutoSaveIndicator'; @@ -26,13 +36,11 @@ type ConfigType = typeof CONFIG_TYPE_SERVERS | typeof CONFIG_TYPE_APP_OPTIONS; type State = DeepPartial & { ready: boolean; maximized?: boolean; - teams?: Team[]; - showAddTeamForm: boolean; trayWasVisible?: boolean; - firstRun?: boolean; savingState: SavingStateItems; userOpenedDownloadDialog: boolean; allowSaveSpellCheckerURL: boolean; + availableLanguages: Array<{label: string; value: string}>; } type SavingStateItems = { @@ -61,18 +69,19 @@ export default class SettingsPage extends React.PureComponent; + constructor(props: Record) { super(props); this.state = { ready: false, - teams: [], - showAddTeamForm: false, savingState: { appOptions: SavingState.SAVING_STATE_DONE, servers: SavingState.SAVING_STATE_DONE, }, userOpenedDownloadDialog: false, allowSaveSpellCheckerURL: false, + availableLanguages: [], }; this.getConfig(); @@ -89,19 +98,20 @@ export default class SettingsPage extends React.PureComponent { - this.setState({ - showAddTeamForm: true, - }); - }); - window.ipcRenderer.on(RELOAD_CONFIGURATION, () => { this.updateSaveState(); this.getConfig(); }); + + window.ipcRenderer.invoke(GET_AVAILABLE_SPELL_CHECKER_LANGUAGES).then((languages: string[]) => { + const availableLanguages = languages.filter((language) => localeTranslations[language]).map((language) => ({label: localeTranslations[language], value: language})); + availableLanguages.sort((a, b) => a.label.localeCompare(b.label)); + this.setState({availableLanguages}); + }); } getConfig = () => { @@ -112,16 +122,12 @@ export default class SettingsPage extends React.PureComponent, currentState: Partial = {}) => { const newState = Object.assign({} as State, configData); - newState.showAddTeamForm = currentState.showAddTeamForm || false; newState.trayWasVisible = currentState.trayWasVisible || false; - if (newState.teams?.length === 0 && currentState.firstRun !== false) { - newState.firstRun = false; - newState.showAddTeamForm = true; - } newState.savingState = currentState.savingState || { appOptions: SavingState.SAVING_STATE_DONE, servers: SavingState.SAVING_STATE_DONE, }; + this.selectedSpellCheckerLocales = configData.spellCheckerLocales?.map((language: string) => ({label: localeTranslations[language] || language, value: language})) || []; return newState; } @@ -172,17 +178,6 @@ export default class SettingsPage extends React.PureComponent { - window.timers.setImmediate(this.saveSetting, CONFIG_TYPE_SERVERS, {key: 'teams', data: teams}); - this.setState({ - showAddTeamForm: false, - teams, - }); - if (teams.length === 0) { - this.setState({showAddTeamForm: true}); - } - } - handleChangeShowTrayIcon = () => { const shouldShowTrayIcon = this.showTrayIconRef.current?.checked; window.timers.setImmediate(this.saveSetting, CONFIG_TYPE_APP_OPTIONS, {key: 'showTrayIcon', data: shouldShowTrayIcon}); @@ -220,19 +215,6 @@ export default class SettingsPage extends React.PureComponent { - this.setState({ - showAddTeamForm: !this.state.showAddTeamForm, - }); - (document.activeElement as HTMLElement).blur(); - } - - setShowTeamFormVisibility = (val: boolean) => { - this.setState({ - showAddTeamForm: val, - }); - } - handleFlashWindow = () => { window.timers.setImmediate(this.saveSetting, CONFIG_TYPE_APP_OPTIONS, { key: 'notifications', @@ -295,6 +277,22 @@ export default class SettingsPage extends React.PureComponent, actionMeta: ActionMeta<{label: string; value: string}>) => { + switch (actionMeta.action) { + case 'select-option': + this.selectedSpellCheckerLocales = [...value]; + break; + case 'remove-value': + this.selectedSpellCheckerLocales = this.selectedSpellCheckerLocales.filter((language) => language.value !== actionMeta.removedValue.value); + } + + const values = this.selectedSpellCheckerLocales.map((language) => language.value); + window.timers.setImmediate(this.saveSetting, CONFIG_TYPE_APP_OPTIONS, {key: 'spellCheckerLocales', data: values}); + this.setState({ + spellCheckerLocales: values, + }); + } + handleChangeEnableHardwareAcceleration = () => { window.timers.setImmediate(this.saveSetting, CONFIG_TYPE_APP_OPTIONS, {key: 'enableHardwareAcceleration', data: this.enableHardwareAccelerationRef.current?.checked}); this.setState({ @@ -426,21 +424,36 @@ export default class SettingsPage extends React.PureComponent - - {'Check spelling'} - - {'Highlight misspelled words in your messages based on your system language configuration. '} - {'Setting takes effect after restarting the app.'} - - ); + <> + + + {'Check spelling'} + + {'Highlight misspelled words in your messages based on your system language or language preference. '} + {'Setting takes effect after restarting the app.'} + + + {this.state.useSpellChecker && + + } + , + ); if (process.platform !== 'darwin') { if (this.state.spellCheckerURL === null || typeof this.state.spellCheckerURL === 'undefined') { options.push( diff --git a/src/renderer/css/lazy/settings-dark.lazy.css b/src/renderer/css/lazy/settings-dark.lazy.css index 02e72ce4..66d35288 100644 --- a/src/renderer/css/lazy/settings-dark.lazy.css +++ b/src/renderer/css/lazy/settings-dark.lazy.css @@ -2,4 +2,20 @@ .TeamListItem:hover { background: #242a30; -} \ No newline at end of file +} + +.SettingsPage__spellCheckerLocalesDropdown .SettingsPage__spellCheckerLocalesDropdown__control { + background: #242a30; +} + +.SettingsPage__spellCheckerLocalesDropdown .SettingsPage__spellCheckerLocalesDropdown__menu { + background: #242a30; +} + +.SettingsPage__spellCheckerLocalesDropdown .SettingsPage__spellCheckerLocalesDropdown__option { + background: #242a30; +} + +.SettingsPage__spellCheckerLocalesDropdown .SettingsPage__spellCheckerLocalesDropdown__option:hover { + background: rgba(255, 255, 255, 0.16); +} diff --git a/src/renderer/css/settings.css b/src/renderer/css/settings.css index 1d57cbf3..5b6d86d6 100644 --- a/src/renderer/css/settings.css +++ b/src/renderer/css/settings.css @@ -35,3 +35,9 @@ body { background-color: #166de0; border-color: #166de0; } + +.SettingsPage__spellCheckerLocalesDropdown { + margin-top: 8px; + margin-left: 16px; + width: 50%; +} diff --git a/src/types/config.ts b/src/types/config.ts index c073c397..f2f03be9 100644 --- a/src/types/config.ts +++ b/src/types/config.ts @@ -34,7 +34,7 @@ export type ConfigV3 = { useSpellChecker: boolean; enableHardwareAcceleration: boolean; autostart: boolean; - spellCheckerLocale: string; + spellCheckerLocales: string[]; darkMode: boolean; downloadLocation: string; spellCheckerURL?: string;