summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Stefan Malzner <stefan@adlk.io>2018-12-13 14:01:33 +0100
committerLibravatar Stefan Malzner <stefan@adlk.io>2018-12-13 14:01:33 +0100
commitb5937bd427e02d64b675c9c4719ec8148c68c224 (patch)
tree3e67ca01935eb36ab6d40a1e197d7c2c0f38b587
parentUpdate CHANGELOG.md (diff)
parentIgnore clicks on premium elements (diff)
downloadferdium-app-5.0.0-beta.21.tar.gz
ferdium-app-5.0.0-beta.21.tar.zst
ferdium-app-5.0.0-beta.21.zip
Merge branch 'develop'v5.0.0-beta.21
-rw-r--r--.eslintrc20
-rw-r--r--.travis.yml3
-rw-r--r--CHANGELOG.md25
-rw-r--r--electron-builder.yml2
-rw-r--r--gulpfile.babel.js23
-rw-r--r--package-lock.json1482
-rw-r--r--package.json52
-rw-r--r--src/api/server/ServerApi.js13
-rw-r--r--src/app.js4
-rw-r--r--src/components/auth/AuthLayout.js27
-rw-r--r--src/components/auth/Invite.js32
-rw-r--r--src/components/auth/Login.js9
-rw-r--r--src/components/auth/Pricing.js23
-rw-r--r--src/components/auth/Signup.js3
-rw-r--r--src/components/layout/AppLayout.js136
-rw-r--r--src/components/layout/Sidebar.js3
-rw-r--r--src/components/services/content/ErrorHandlers/WebviewErrorHandler.js84
-rw-r--r--src/components/services/content/ErrorHandlers/styles.js25
-rw-r--r--src/components/services/content/ServiceDisabled.js1
-rw-r--r--src/components/services/content/ServiceWebview.js65
-rw-r--r--src/components/services/content/Services.js6
-rw-r--r--src/components/services/content/WebviewCrashHandler.js24
-rw-r--r--src/components/settings/SettingsLayout.js23
-rw-r--r--src/components/settings/account/AccountDashboard.js48
-rw-r--r--src/components/settings/navigation/SettingsNavigation.js5
-rw-r--r--src/components/settings/recipes/RecipeItem.js1
-rw-r--r--src/components/settings/recipes/RecipesDashboard.js10
-rw-r--r--src/components/settings/services/EditServiceForm.js53
-rw-r--r--src/components/settings/services/ServiceItem.js1
-rw-r--r--src/components/settings/services/ServicesDashboard.js20
-rw-r--r--src/components/settings/settings/EditSettingsForm.js14
-rw-r--r--src/components/settings/user/EditUserForm.js4
-rw-r--r--src/components/subscription/SubscriptionForm.js49
-rw-r--r--src/components/subscription/SubscriptionPopup.js4
-rw-r--r--src/components/ui/AppLoader.js15
-rw-r--r--src/components/ui/AppLoader/index.js70
-rw-r--r--src/components/ui/AppLoader/styles.js16
-rw-r--r--src/components/ui/Button.js3
-rw-r--r--src/components/ui/FullscreenLoader/index.js56
-rw-r--r--src/components/ui/FullscreenLoader/styles.js23
-rw-r--r--src/components/ui/ImageUpload.js10
-rw-r--r--src/components/ui/InfoBar.js4
-rw-r--r--src/components/ui/Infobox.js2
-rw-r--r--src/components/ui/Input.js6
-rw-r--r--src/components/ui/Link.js1
-rw-r--r--src/components/ui/PremiumFeatureContainer/index.js1
-rw-r--r--src/components/ui/PremiumFeatureContainer/styles.js2
-rw-r--r--src/components/ui/Radio.js4
-rw-r--r--src/components/ui/SearchInput.js27
-rw-r--r--src/components/ui/Select.js8
-rw-r--r--src/components/ui/StatusBarTargetUrl.js3
-rw-r--r--src/components/ui/Tabs/TabItem.js4
-rw-r--r--src/components/ui/WebviewLoader/index.js25
-rw-r--r--src/components/ui/WebviewLoader/styles.js9
-rw-r--r--src/components/util/ErrorBoundary/index.js60
-rw-r--r--src/components/util/ErrorBoundary/styles.js13
-rw-r--r--src/config.js3
-rw-r--r--src/containers/auth/AuthLayoutContainer.js4
-rw-r--r--src/containers/layout/AppLayoutContainer.js5
-rw-r--r--src/containers/settings/AccountScreen.js35
-rw-r--r--src/containers/settings/EditServiceScreen.js65
-rw-r--r--src/containers/settings/EditSettingsScreen.js49
-rw-r--r--src/containers/settings/EditUserScreen.js19
-rw-r--r--src/containers/settings/InviteScreen.js16
-rw-r--r--src/containers/settings/RecipesScreen.js40
-rw-r--r--src/containers/settings/ServicesScreen.js31
-rw-r--r--src/containers/settings/SettingsWindow.js15
-rw-r--r--src/containers/subscription/SubscriptionFormScreen.js2
-rw-r--r--src/electron/Settings.js1
-rw-r--r--src/electron/ipc-api/download.js2
-rw-r--r--src/features/delayApp/Component.js23
-rw-r--r--src/features/delayApp/index.js1
-rw-r--r--src/features/serviceProxy/index.js8
-rw-r--r--src/helpers/array-helpers.js4
-rw-r--r--src/helpers/i18n-helpers.js30
-rw-r--r--src/i18n/locales/ca.json45
-rw-r--r--src/i18n/locales/cs.json13
-rw-r--r--src/i18n/locales/de.json25
-rw-r--r--src/i18n/locales/el.json13
-rw-r--r--src/i18n/locales/en-US.json15
-rw-r--r--src/i18n/locales/es.json41
-rw-r--r--src/i18n/locales/fr.json45
-rw-r--r--src/i18n/locales/ga.json13
-rw-r--r--src/i18n/locales/hr.json13
-rw-r--r--src/i18n/locales/hu.json13
-rw-r--r--src/i18n/locales/id.json49
-rw-r--r--src/i18n/locales/it.json23
-rw-r--r--src/i18n/locales/ja.json45
-rw-r--r--src/i18n/locales/ka.json13
-rw-r--r--src/i18n/locales/nl-BE.json13
-rw-r--r--src/i18n/locales/nl.json41
-rw-r--r--src/i18n/locales/pl.json37
-rw-r--r--src/i18n/locales/pt-BR.json39
-rw-r--r--src/i18n/locales/pt.json13
-rw-r--r--src/i18n/locales/ru.json13
-rw-r--r--src/i18n/locales/sk.json13
-rw-r--r--src/i18n/locales/sr.json13
-rw-r--r--src/i18n/locales/tr.json21
-rw-r--r--src/i18n/locales/uk.json13
-rw-r--r--src/i18n/locales/zh-TW.json33
-rw-r--r--src/index.js8
-rw-r--r--src/lib/Tray.js10
-rw-r--r--src/models/News.js3
-rw-r--r--src/models/Order.js5
-rw-r--r--src/models/Plan.js1
-rw-r--r--src/models/Recipe.js12
-rw-r--r--src/models/RecipePreview.js6
-rw-r--r--src/models/Service.js51
-rw-r--r--src/models/User.js17
-rw-r--r--src/stores/AppStore.js16
-rw-r--r--src/stores/DictionaryStore.js45
-rw-r--r--src/stores/FeaturesStore.js1
-rw-r--r--src/stores/GlobalErrorStore.js1
-rw-r--r--src/stores/NewsStore.js1
-rw-r--r--src/stores/PaymentStore.js3
-rw-r--r--src/stores/RecipePreviewsStore.js2
-rw-r--r--src/stores/RecipesStore.js2
-rw-r--r--src/stores/RequestStore.js3
-rw-r--r--src/stores/ServicesStore.js23
-rw-r--r--src/stores/SettingsStore.js25
-rw-r--r--src/stores/UserStore.js26
-rw-r--r--src/stores/index.js2
-rw-r--r--src/stores/lib/CachedRequest.js1
-rw-r--r--src/stores/lib/Reaction.js2
-rw-r--r--src/stores/lib/Request.js8
-rw-r--r--src/stores/lib/Store.js4
-rw-r--r--src/styles/auth.scss14
-rw-r--r--src/styles/content-tabs.scss16
-rw-r--r--src/styles/searchInput.scss4
-rw-r--r--src/styles/select.scss4
-rw-r--r--src/styles/settings.scss4
-rw-r--r--src/styles/welcome.scss5
-rw-r--r--src/theme/dark/index.js7
-rw-r--r--src/theme/default/index.js8
-rw-r--r--src/webview/contextMenu.js67
-rw-r--r--src/webview/darkmode.js12
-rw-r--r--src/webview/notifications.js7
-rw-r--r--src/webview/plugin.js90
-rw-r--r--src/webview/recipe.js131
-rw-r--r--src/webview/spellchecker.js34
140 files changed, 2541 insertions, 1764 deletions
diff --git a/.eslintrc b/.eslintrc
index 948550306..1843e560e 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -14,6 +14,8 @@
14 "extensions": [".js", ".jsx"] 14 "extensions": [".js", ".jsx"]
15 }], 15 }],
16 "react/forbid-prop-types": 1, 16 "react/forbid-prop-types": 1,
17 "react/destructuring-assignment": 1,
18 "prefer-destructuring": 1,
17 "no-underscore-dangle": 0, 19 "no-underscore-dangle": 0,
18 "max-len": 0, 20 "max-len": 0,
19 "class-methods-use-this": 0, 21 "class-methods-use-this": 0,
@@ -21,7 +23,23 @@
21 "react/jsx-no-bind": 0, 23 "react/jsx-no-bind": 0,
22 "jsx-a11y/no-static-element-interactions": 0, 24 "jsx-a11y/no-static-element-interactions": 0,
23 "react/jsx-no-target-blank": 0, 25 "react/jsx-no-target-blank": 0,
24 "no-restricted-syntax": [0, "ForInStatement"] 26 "no-restricted-syntax": [0, "ForInStatement"],
27 "jsx-a11y/no-noninteractive-element-interactions": 1,
28 "jsx-a11y/label-has-for": [
29 2,
30 {
31 "components": [
32 "Label"
33 ],
34 "required": {
35 "every": [
36 "id"
37 ]
38 },
39 "allowChildren": false
40 }
41 ],
42 "jsx-a11y/click-events-have-key-events": 1
25 }, 43 },
26 "globals": { 44 "globals": {
27 "window": true, 45 "window": true,
diff --git a/.travis.yml b/.travis.yml
index dfea3a41e..2c2004b3a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -16,11 +16,10 @@ language: node_js
16 16
17before_script: 17before_script:
18- npm install node-sass -g 18- npm install node-sass -g
19- npm ci
20 19
21script: 20script:
22- npm run lint 21- npm run lint
23- travis_wait npm run build 22- travis_wait 30 npm run build
24 23
25cache: npm 24cache: npm
26 25
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c489d4827..6ea5cbed4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,28 @@
1<a name="5.0.0-beta.21"></a>
2# [5.0.0-beta.21](https://github.com/meetfranz/franz/compare/5.0.0-beta.20...5.0.0-beta.21) (2018-12-11)
3
4### General
5
6* **Translations:** Improved translations. **[A million thanks to the amazing community. 🎉](http://i18n.meetfranz.com/)**
7
8### Features
9
10* **Service:** Add option to change spellchecking language by service ([baf7d60](https://github.com/meetfranz/franz/commit/baf7d60))
11* **Context Menu:** Quickly change the spellchecker language for the active service
12* **Service:** Add error screen for services that failed to load ([a5e7171](https://github.com/meetfranz/franz/commit/a5e7171))
13* **Service:** Add port option for proxy configuration ([baf7d60](https://github.com/meetfranz/franz/commit/baf7d60))
14
15
16### Bug Fixes
17
18* **Spellchecker:** Fix issue with dictionary download ([0cdc165](https://github.com/meetfranz/franz/commit/0cdc165))
19
20### Improvements
21
22* **Dark Mode:** Dark Mode polishing
23* **App:** Updated a ton of dependencies
24
25
1<a name="5.0.0-beta.20"></a> 26<a name="5.0.0-beta.20"></a>
2# [5.0.0-beta.20](https://github.com/meetfranz/franz/compare/v5.0.0-beta.19...v5.0.0-beta.20) (2018-12-05) 27# [5.0.0-beta.20](https://github.com/meetfranz/franz/compare/v5.0.0-beta.19...v5.0.0-beta.20) (2018-12-05)
3 28
diff --git a/electron-builder.yml b/electron-builder.yml
index 3e72da4ce..1d62669bf 100644
--- a/electron-builder.yml
+++ b/electron-builder.yml
@@ -42,3 +42,5 @@ nsis:
42protocols: 42protocols:
43 name: Franz 43 name: Franz
44 schemes: [franz] 44 schemes: [franz]
45
46asarUnpack: "./dictionaries"
diff --git a/gulpfile.babel.js b/gulpfile.babel.js
index cea42d6c9..fc2820fed 100644
--- a/gulpfile.babel.js
+++ b/gulpfile.babel.js
@@ -25,6 +25,7 @@ const paths = {
25 src: 'src', 25 src: 'src',
26 dest: 'build', 26 dest: 'build',
27 tmp: '.tmp', 27 tmp: '.tmp',
28 dictionaries: 'dictionaries',
28 package: `out/${config.version}`, 29 package: `out/${config.version}`,
29 html: { 30 html: {
30 src: 'src/**/*.html', 31 src: 'src/**/*.html',
@@ -73,7 +74,8 @@ export function mvSrc() {
73 `${paths.src}/*/**`, 74 `${paths.src}/*/**`,
74 `!${paths.scripts.watch}`, 75 `!${paths.scripts.watch}`,
75 `!${paths.src}/styles/**`, 76 `!${paths.src}/styles/**`,
76 ], { since: gulp.lastRun(mvSrc) }) 77 ], { since: gulp.lastRun(mvSrc) },
78 )
77 .pipe(gulp.dest(paths.dest)); 79 .pipe(gulp.dest(paths.dest));
78} 80}
79 81
@@ -81,7 +83,8 @@ export function mvPackageJson() {
81 return gulp.src( 83 return gulp.src(
82 [ 84 [
83 './package.json', 85 './package.json',
84 ]) 86 ],
87 )
85 .pipe(gulp.dest(paths.dest)); 88 .pipe(gulp.dest(paths.dest));
86} 89}
87 90
@@ -132,6 +135,21 @@ export function webserver() {
132 })); 135 }));
133} 136}
134 137
138export function dictionaries(done) {
139 const { SPELLCHECKER_LOCALES } = require('./build/i18n/languages');
140
141 let packages = '';
142 Object.keys(SPELLCHECKER_LOCALES).forEach((key) => { packages = `${packages} hunspell-dict-${key}`; });
143
144 _shell(`
145 rm -rf ${paths.dictionaries}
146 npm install --prefix ${paths.dictionaries} ${packages}
147 mv ${paths.dictionaries}/node_modules/* ${paths.dictionaries}
148 rm -rf ${paths.dictionaries}/node_modules ${paths.dictionaries}/package-lock.json
149 pwd`,
150 done);
151}
152
135export function sign(done) { 153export function sign(done) {
136 _shell(`codesign --verbose=4 --deep --strict --force --sign "${process.env.SIGNING_IDENTITY}" "${__dirname}/node_modules/electron/dist/Electron.app"`, done); 154 _shell(`codesign --verbose=4 --deep --strict --force --sign "${process.env.SIGNING_IDENTITY}" "${__dirname}/node_modules/electron/dist/Electron.app"`, done);
137} 155}
@@ -140,6 +158,7 @@ const build = gulp.series(
140 clean, 158 clean,
141 gulp.parallel(mvSrc, mvPackageJson), 159 gulp.parallel(mvSrc, mvPackageJson),
142 gulp.parallel(html, scripts, styles), 160 gulp.parallel(html, scripts, styles),
161 dictionaries,
143); 162);
144export { build }; 163export { build };
145 164
diff --git a/package-lock.json b/package-lock.json
index fac5d7a7d..16fe71944 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
1{ 1{
2 "name": "franz", 2 "name": "franz",
3 "version": "5.0.0-beta.18", 3 "version": "5.0.0-beta.21",
4 "lockfileVersion": 1, 4 "lockfileVersion": 1,
5 "requires": true, 5 "requires": true,
6 "dependencies": { 6 "dependencies": {
@@ -56,6 +56,37 @@
56 } 56 }
57 } 57 }
58 }, 58 },
59 "@babel/cli": {
60 "version": "7.0.0",
61 "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.0.0.tgz",
62 "integrity": "sha512-SH/x7W1dz4FSSBeJZXIiYSbHIOU3ZxNgwQPLTG+I8KXyTS81pzmLouPa2st6hji7VbVrEF/D8EQzQbXAYj1TsA==",
63 "dev": true,
64 "requires": {
65 "chokidar": "^2.0.3",
66 "commander": "^2.8.1",
67 "convert-source-map": "^1.1.0",
68 "fs-readdir-recursive": "^1.1.0",
69 "glob": "^7.0.0",
70 "lodash": "^4.17.10",
71 "mkdirp": "^0.5.1",
72 "output-file-sync": "^2.0.0",
73 "slash": "^2.0.0",
74 "source-map": "^0.5.0"
75 },
76 "dependencies": {
77 "output-file-sync": {
78 "version": "2.0.1",
79 "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-2.0.1.tgz",
80 "integrity": "sha512-mDho4qm7WgIXIGf4eYU1RHN2UU5tPfVYVSRwDJw0uTmj35DQUt/eNp19N7v6T3SrR0ESTEf2up2CGO73qI35zQ==",
81 "dev": true,
82 "requires": {
83 "graceful-fs": "^4.1.11",
84 "is-plain-obj": "^1.1.0",
85 "mkdirp": "^0.5.1"
86 }
87 }
88 }
89 },
59 "@babel/code-frame": { 90 "@babel/code-frame": {
60 "version": "7.0.0", 91 "version": "7.0.0",
61 "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", 92 "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz",
@@ -66,18 +97,18 @@
66 } 97 }
67 }, 98 },
68 "@babel/core": { 99 "@babel/core": {
69 "version": "7.1.2", 100 "version": "7.0.0",
70 "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.1.2.tgz", 101 "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.0.0.tgz",
71 "integrity": "sha512-IFeSSnjXdhDaoysIlev//UzHZbdEmm7D0EIH2qtse9xK7mXEZQpYjs2P00XlP1qYsYvid79p+Zgg6tz1mp6iVw==", 102 "integrity": "sha512-nrvxS5u6QUN5gLl1GEakIcmOeoUHT1/gQtdMRq18WFURJ5osn4ppJLVSseMQo4zVWKJfBTF4muIYijXUnKlRLQ==",
72 "dev": true, 103 "dev": true,
73 "requires": { 104 "requires": {
74 "@babel/code-frame": "^7.0.0", 105 "@babel/code-frame": "^7.0.0",
75 "@babel/generator": "^7.1.2", 106 "@babel/generator": "^7.0.0",
76 "@babel/helpers": "^7.1.2", 107 "@babel/helpers": "^7.0.0",
77 "@babel/parser": "^7.1.2", 108 "@babel/parser": "^7.0.0",
78 "@babel/template": "^7.1.2", 109 "@babel/template": "^7.0.0",
79 "@babel/traverse": "^7.1.0", 110 "@babel/traverse": "^7.0.0",
80 "@babel/types": "^7.1.2", 111 "@babel/types": "^7.0.0",
81 "convert-source-map": "^1.1.0", 112 "convert-source-map": "^1.1.0",
82 "debug": "^3.1.0", 113 "debug": "^3.1.0",
83 "json5": "^0.5.0", 114 "json5": "^0.5.0",
@@ -320,14 +351,90 @@
320 } 351 }
321 }, 352 },
322 "@babel/helpers": { 353 "@babel/helpers": {
323 "version": "7.1.2", 354 "version": "7.2.0",
324 "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.1.2.tgz", 355 "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.2.0.tgz",
325 "integrity": "sha512-Myc3pUE8eswD73aWcartxB16K6CGmHDv9KxOmD2CeOs/FaEAQodr3VYGmlvOmog60vNQ2w8QbatuahepZwrHiA==", 356 "integrity": "sha512-Fr07N+ea0dMcMN8nFpuK6dUIT7/ivt9yKQdEEnjVS83tG2pHwPi03gYmk/tyuwONnZ+sY+GFFPlWGgCtW1hF9A==",
326 "dev": true, 357 "dev": true,
327 "requires": { 358 "requires": {
328 "@babel/template": "^7.1.2", 359 "@babel/template": "^7.1.2",
329 "@babel/traverse": "^7.1.0", 360 "@babel/traverse": "^7.1.5",
330 "@babel/types": "^7.1.2" 361 "@babel/types": "^7.2.0"
362 },
363 "dependencies": {
364 "@babel/generator": {
365 "version": "7.2.0",
366 "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.2.0.tgz",
367 "integrity": "sha512-BA75MVfRlFQG2EZgFYIwyT1r6xSkwfP2bdkY/kLZusEYWiJs4xCowab/alaEaT0wSvmVuXGqiefeBlP+7V1yKg==",
368 "dev": true,
369 "requires": {
370 "@babel/types": "^7.2.0",
371 "jsesc": "^2.5.1",
372 "lodash": "^4.17.10",
373 "source-map": "^0.5.0",
374 "trim-right": "^1.0.1"
375 }
376 },
377 "@babel/parser": {
378 "version": "7.2.0",
379 "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.2.0.tgz",
380 "integrity": "sha512-M74+GvK4hn1eejD9lZ7967qAwvqTZayQa3g10ag4s9uewgR7TKjeaT0YMyoq+gVfKYABiWZ4MQD701/t5e1Jhg==",
381 "dev": true
382 },
383 "@babel/traverse": {
384 "version": "7.1.6",
385 "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.1.6.tgz",
386 "integrity": "sha512-CXedit6GpISz3sC2k2FsGCUpOhUqKdyL0lqNrImQojagnUMXf8hex4AxYFRuMkNGcvJX5QAFGzB5WJQmSv8SiQ==",
387 "dev": true,
388 "requires": {
389 "@babel/code-frame": "^7.0.0",
390 "@babel/generator": "^7.1.6",
391 "@babel/helper-function-name": "^7.1.0",
392 "@babel/helper-split-export-declaration": "^7.0.0",
393 "@babel/parser": "^7.1.6",
394 "@babel/types": "^7.1.6",
395 "debug": "^4.1.0",
396 "globals": "^11.1.0",
397 "lodash": "^4.17.10"
398 }
399 },
400 "@babel/types": {
401 "version": "7.2.0",
402 "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.2.0.tgz",
403 "integrity": "sha512-b4v7dyfApuKDvmPb+O488UlGuR1WbwMXFsO/cyqMrnfvRAChZKJAYeeglWTjUO1b9UghKKgepAQM5tsvBJca6A==",
404 "dev": true,
405 "requires": {
406 "esutils": "^2.0.2",
407 "lodash": "^4.17.10",
408 "to-fast-properties": "^2.0.0"
409 }
410 },
411 "debug": {
412 "version": "4.1.0",
413 "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.0.tgz",
414 "integrity": "sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg==",
415 "dev": true,
416 "requires": {
417 "ms": "^2.1.1"
418 }
419 },
420 "globals": {
421 "version": "11.9.0",
422 "resolved": "https://registry.npmjs.org/globals/-/globals-11.9.0.tgz",
423 "integrity": "sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg==",
424 "dev": true
425 },
426 "ms": {
427 "version": "2.1.1",
428 "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
429 "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
430 "dev": true
431 },
432 "to-fast-properties": {
433 "version": "2.0.0",
434 "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
435 "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
436 "dev": true
437 }
331 } 438 }
332 }, 439 },
333 "@babel/highlight": { 440 "@babel/highlight": {
@@ -989,12 +1096,6 @@
989 "locate-path": "^2.0.0" 1096 "locate-path": "^2.0.0"
990 } 1097 }
991 }, 1098 },
992 "home-or-tmp": {
993 "version": "3.0.0",
994 "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-3.0.0.tgz",
995 "integrity": "sha1-V6j+JM8zzdUkhgoVgh3cJchmcfs=",
996 "dev": true
997 },
998 "pkg-dir": { 1099 "pkg-dir": {
999 "version": "2.0.0", 1100 "version": "2.0.0",
1000 "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", 1101 "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz",
@@ -1107,15 +1208,6 @@
1107 "integrity": "sha512-EibsnbJerd0hBFaDjJStFrVbVBAtOy4dgL8zZFw0uOvPqzBAX59Ci8cgjg3+RgJIWhsB5A4c+pi+D4P9tQQh/A==", 1208 "integrity": "sha512-EibsnbJerd0hBFaDjJStFrVbVBAtOy4dgL8zZFw0uOvPqzBAX59Ci8cgjg3+RgJIWhsB5A4c+pi+D4P9tQQh/A==",
1108 "dev": true 1209 "dev": true
1109 }, 1210 },
1110 "JSONStream": {
1111 "version": "1.3.5",
1112 "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz",
1113 "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==",
1114 "requires": {
1115 "jsonparse": "^1.2.0",
1116 "through": ">=2.2.7 <3"
1117 }
1118 },
1119 "abbrev": { 1211 "abbrev": {
1120 "version": "1.1.1", 1212 "version": "1.1.1",
1121 "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", 1213 "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
@@ -1141,27 +1233,16 @@
1141 } 1233 }
1142 }, 1234 },
1143 "acorn": { 1235 "acorn": {
1144 "version": "5.7.3", 1236 "version": "6.0.4",
1145 "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", 1237 "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.4.tgz",
1146 "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", 1238 "integrity": "sha512-VY4i5EKSKkofY2I+6QLTbTTN/UvEQPCo6eiwzzSaSWfpaDhOmStMCMod6wmuPciNq+XS0faCglFu2lHZpdHUtg==",
1147 "dev": true 1239 "dev": true
1148 }, 1240 },
1149 "acorn-jsx": { 1241 "acorn-jsx": {
1150 "version": "3.0.1", 1242 "version": "5.0.1",
1151 "resolved": "http://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", 1243 "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz",
1152 "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", 1244 "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==",
1153 "dev": true, 1245 "dev": true
1154 "requires": {
1155 "acorn": "^3.0.4"
1156 },
1157 "dependencies": {
1158 "acorn": {
1159 "version": "3.3.0",
1160 "resolved": "http://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
1161 "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=",
1162 "dev": true
1163 }
1164 }
1165 }, 1246 },
1166 "address-rfc2822": { 1247 "address-rfc2822": {
1167 "version": "2.0.4", 1248 "version": "2.0.4",
@@ -1177,22 +1258,6 @@
1177 "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", 1258 "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=",
1178 "dev": true 1259 "dev": true
1179 }, 1260 },
1180 "agent-base": {
1181 "version": "4.2.1",
1182 "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz",
1183 "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==",
1184 "requires": {
1185 "es6-promisify": "^5.0.0"
1186 }
1187 },
1188 "agentkeepalive": {
1189 "version": "3.5.2",
1190 "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-3.5.2.tgz",
1191 "integrity": "sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ==",
1192 "requires": {
1193 "humanize-ms": "^1.2.1"
1194 }
1195 },
1196 "ajv": { 1261 "ajv": {
1197 "version": "5.5.2", 1262 "version": "5.5.2",
1198 "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", 1263 "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
@@ -1205,12 +1270,6 @@
1205 "json-schema-traverse": "^0.3.0" 1270 "json-schema-traverse": "^0.3.0"
1206 } 1271 }
1207 }, 1272 },
1208 "ajv-keywords": {
1209 "version": "2.1.1",
1210 "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz",
1211 "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=",
1212 "dev": true
1213 },
1214 "amdefine": { 1273 "amdefine": {
1215 "version": "1.0.1", 1274 "version": "1.0.1",
1216 "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", 1275 "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
@@ -1379,7 +1438,8 @@
1379 "aproba": { 1438 "aproba": {
1380 "version": "1.2.0", 1439 "version": "1.2.0",
1381 "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", 1440 "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
1382 "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" 1441 "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
1442 "dev": true
1383 }, 1443 },
1384 "archy": { 1444 "archy": {
1385 "version": "1.0.0", 1445 "version": "1.0.0",
@@ -1404,6 +1464,16 @@
1404 "sprintf-js": "~1.0.2" 1464 "sprintf-js": "~1.0.2"
1405 } 1465 }
1406 }, 1466 },
1467 "aria-query": {
1468 "version": "3.0.0",
1469 "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz",
1470 "integrity": "sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=",
1471 "dev": true,
1472 "requires": {
1473 "ast-types-flow": "0.0.7",
1474 "commander": "^2.11.0"
1475 }
1476 },
1407 "arr-diff": { 1477 "arr-diff": {
1408 "version": "4.0.0", 1478 "version": "4.0.0",
1409 "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", 1479 "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
@@ -1454,6 +1524,16 @@
1454 "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", 1524 "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
1455 "dev": true 1525 "dev": true
1456 }, 1526 },
1527 "array-includes": {
1528 "version": "3.0.3",
1529 "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz",
1530 "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=",
1531 "dev": true,
1532 "requires": {
1533 "define-properties": "^1.1.2",
1534 "es-abstract": "^1.7.0"
1535 }
1536 },
1457 "array-initial": { 1537 "array-initial": {
1458 "version": "1.1.0", 1538 "version": "1.1.0",
1459 "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz", 1539 "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz",
@@ -1513,15 +1593,6 @@
1513 } 1593 }
1514 } 1594 }
1515 }, 1595 },
1516 "array-union": {
1517 "version": "1.0.2",
1518 "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
1519 "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
1520 "dev": true,
1521 "requires": {
1522 "array-uniq": "^1.0.1"
1523 }
1524 },
1525 "array-uniq": { 1596 "array-uniq": {
1526 "version": "1.0.3", 1597 "version": "1.0.3",
1527 "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", 1598 "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
@@ -1533,28 +1604,12 @@
1533 "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", 1604 "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
1534 "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" 1605 "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg="
1535 }, 1606 },
1536 "array.prototype.find": {
1537 "version": "2.0.4",
1538 "resolved": "https://registry.npmjs.org/array.prototype.find/-/array.prototype.find-2.0.4.tgz",
1539 "integrity": "sha1-VWpcU2LAhkgyPdrrnenRS8GGTJA=",
1540 "dev": true,
1541 "requires": {
1542 "define-properties": "^1.1.2",
1543 "es-abstract": "^1.7.0"
1544 }
1545 },
1546 "arraybuffer.slice": { 1607 "arraybuffer.slice": {
1547 "version": "0.0.6", 1608 "version": "0.0.6",
1548 "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz", 1609 "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz",
1549 "integrity": "sha1-8zshWfBTKj8xB6JywMz70a0peco=", 1610 "integrity": "sha1-8zshWfBTKj8xB6JywMz70a0peco=",
1550 "dev": true 1611 "dev": true
1551 }, 1612 },
1552 "arrify": {
1553 "version": "1.0.1",
1554 "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
1555 "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
1556 "dev": true
1557 },
1558 "asap": { 1613 "asap": {
1559 "version": "2.0.6", 1614 "version": "2.0.6",
1560 "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", 1615 "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
@@ -1580,6 +1635,18 @@
1580 "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", 1635 "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
1581 "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" 1636 "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c="
1582 }, 1637 },
1638 "ast-types-flow": {
1639 "version": "0.0.7",
1640 "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz",
1641 "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=",
1642 "dev": true
1643 },
1644 "astral-regex": {
1645 "version": "1.0.0",
1646 "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
1647 "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
1648 "dev": true
1649 },
1583 "async": { 1650 "async": {
1584 "version": "0.1.22", 1651 "version": "0.1.22",
1585 "resolved": "http://registry.npmjs.org/async/-/async-0.1.22.tgz", 1652 "resolved": "http://registry.npmjs.org/async/-/async-0.1.22.tgz",
@@ -1666,23 +1733,13 @@
1666 "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", 1733 "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==",
1667 "dev": true 1734 "dev": true
1668 }, 1735 },
1669 "babel-code-frame": { 1736 "axobject-query": {
1670 "version": "6.26.0", 1737 "version": "2.0.2",
1671 "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", 1738 "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz",
1672 "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", 1739 "integrity": "sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww==",
1673 "dev": true, 1740 "dev": true,
1674 "requires": { 1741 "requires": {
1675 "chalk": "^1.1.3", 1742 "ast-types-flow": "0.0.7"
1676 "esutils": "^2.0.2",
1677 "js-tokens": "^3.0.2"
1678 },
1679 "dependencies": {
1680 "js-tokens": {
1681 "version": "3.0.2",
1682 "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
1683 "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
1684 "dev": true
1685 }
1686 } 1743 }
1687 }, 1744 },
1688 "babel-eslint": { 1745 "babel-eslint": {
@@ -2179,40 +2236,8 @@
2179 "builtin-modules": { 2236 "builtin-modules": {
2180 "version": "1.1.1", 2237 "version": "1.1.1",
2181 "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", 2238 "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
2182 "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" 2239 "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
2183 }, 2240 "dev": true
2184 "builtins": {
2185 "version": "1.0.3",
2186 "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz",
2187 "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og="
2188 },
2189 "cacache": {
2190 "version": "11.3.1",
2191 "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.1.tgz",
2192 "integrity": "sha512-2PEw4cRRDu+iQvBTTuttQifacYjLPhET+SYO/gEFMy8uhi+jlJREDAjSF5FWSdV/Aw5h18caHA7vMTw2c+wDzA==",
2193 "requires": {
2194 "bluebird": "^3.5.1",
2195 "chownr": "^1.0.1",
2196 "figgy-pudding": "^3.1.0",
2197 "glob": "^7.1.2",
2198 "graceful-fs": "^4.1.11",
2199 "lru-cache": "^4.1.3",
2200 "mississippi": "^3.0.0",
2201 "mkdirp": "^0.5.1",
2202 "move-concurrently": "^1.0.1",
2203 "promise-inflight": "^1.0.1",
2204 "rimraf": "^2.6.2",
2205 "ssri": "^6.0.0",
2206 "unique-filename": "^1.1.0",
2207 "y18n": "^4.0.0"
2208 },
2209 "dependencies": {
2210 "y18n": {
2211 "version": "4.0.0",
2212 "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
2213 "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w=="
2214 }
2215 }
2216 }, 2241 },
2217 "cache-base": { 2242 "cache-base": {
2218 "version": "1.0.1", 2243 "version": "1.0.1",
@@ -2328,9 +2353,9 @@
2328 } 2353 }
2329 }, 2354 },
2330 "chardet": { 2355 "chardet": {
2331 "version": "0.4.2", 2356 "version": "0.7.0",
2332 "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", 2357 "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
2333 "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", 2358 "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
2334 "dev": true 2359 "dev": true
2335 }, 2360 },
2336 "chokidar": { 2361 "chokidar": {
@@ -2587,6 +2612,7 @@
2587 "version": "1.6.2", 2612 "version": "1.6.2",
2588 "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", 2613 "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
2589 "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", 2614 "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
2615 "dev": true,
2590 "requires": { 2616 "requires": {
2591 "buffer-from": "^1.0.0", 2617 "buffer-from": "^1.0.0",
2592 "inherits": "^2.0.3", 2618 "inherits": "^2.0.3",
@@ -2972,19 +2998,6 @@
2972 "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", 2998 "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=",
2973 "dev": true 2999 "dev": true
2974 }, 3000 },
2975 "copy-concurrently": {
2976 "version": "1.0.5",
2977 "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz",
2978 "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==",
2979 "requires": {
2980 "aproba": "^1.1.1",
2981 "fs-write-stream-atomic": "^1.0.8",
2982 "iferr": "^0.1.5",
2983 "mkdirp": "^0.5.1",
2984 "rimraf": "^2.5.4",
2985 "run-queue": "^1.0.0"
2986 }
2987 },
2988 "copy-descriptor": { 3001 "copy-descriptor": {
2989 "version": "0.1.1", 3002 "version": "0.1.1",
2990 "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", 3003 "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
@@ -3008,7 +3021,8 @@
3008 "core-util-is": { 3021 "core-util-is": {
3009 "version": "1.0.2", 3022 "version": "1.0.2",
3010 "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 3023 "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
3011 "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 3024 "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
3025 "dev": true
3012 }, 3026 },
3013 "cosmiconfig": { 3027 "cosmiconfig": {
3014 "version": "5.0.7", 3028 "version": "5.0.7",
@@ -3099,11 +3113,6 @@
3099 "array-find-index": "^1.0.1" 3113 "array-find-index": "^1.0.1"
3100 } 3114 }
3101 }, 3115 },
3102 "cyclist": {
3103 "version": "0.2.2",
3104 "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz",
3105 "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA="
3106 },
3107 "cz-conventional-changelog": { 3116 "cz-conventional-changelog": {
3108 "version": "2.1.0", 3117 "version": "2.1.0",
3109 "resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-2.1.0.tgz", 3118 "resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-2.1.0.tgz",
@@ -3264,21 +3273,6 @@
3264 } 3273 }
3265 } 3274 }
3266 }, 3275 },
3267 "del": {
3268 "version": "2.2.2",
3269 "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz",
3270 "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=",
3271 "dev": true,
3272 "requires": {
3273 "globby": "^5.0.0",
3274 "is-path-cwd": "^1.0.0",
3275 "is-path-in-cwd": "^1.0.0",
3276 "object-assign": "^4.0.1",
3277 "pify": "^2.0.0",
3278 "pinkie-promise": "^2.0.0",
3279 "rimraf": "^2.2.8"
3280 }
3281 },
3282 "delayed-stream": { 3276 "delayed-stream": {
3283 "version": "1.0.0", 3277 "version": "1.0.0",
3284 "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 3278 "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
@@ -3410,9 +3404,9 @@
3410 } 3404 }
3411 }, 3405 },
3412 "domelementtype": { 3406 "domelementtype": {
3413 "version": "1.3.0", 3407 "version": "1.3.1",
3414 "resolved": "http://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", 3408 "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
3415 "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=" 3409 "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w=="
3416 }, 3410 },
3417 "domhandler": { 3411 "domhandler": {
3418 "version": "2.4.2", 3412 "version": "2.4.2",
@@ -3505,6 +3499,7 @@
3505 "version": "3.6.1", 3499 "version": "3.6.1",
3506 "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.1.tgz", 3500 "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.1.tgz",
3507 "integrity": "sha512-vM58DwdnKmty+FSPzT14K9JXb90H+j5emaR4KYbr2KTIz00WHGbWOe5ghQTx233ZCLZtrGDALzKwcjEtSt35mA==", 3501 "integrity": "sha512-vM58DwdnKmty+FSPzT14K9JXb90H+j5emaR4KYbr2KTIz00WHGbWOe5ghQTx233ZCLZtrGDALzKwcjEtSt35mA==",
3502 "dev": true,
3508 "requires": { 3503 "requires": {
3509 "end-of-stream": "^1.0.0", 3504 "end-of-stream": "^1.0.0",
3510 "inherits": "^2.0.1", 3505 "inherits": "^2.0.1",
@@ -4057,6 +4052,12 @@
4057 "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-3.0.2.tgz", 4052 "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-3.0.2.tgz",
4058 "integrity": "sha512-IMn9dnwLMsgZjdUHswB/UZ0S8LQ/u+2/qjnHJ9tCtp3QHZsIYwJCiJOo2FT0i3CwwK/dtSODYtxuvzV4D9MY5g==" 4053 "integrity": "sha512-IMn9dnwLMsgZjdUHswB/UZ0S8LQ/u+2/qjnHJ9tCtp3QHZsIYwJCiJOo2FT0i3CwwK/dtSODYtxuvzV4D9MY5g=="
4059 }, 4054 },
4055 "emoji-regex": {
4056 "version": "6.5.1",
4057 "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.5.1.tgz",
4058 "integrity": "sha512-PAHp6TxrCy7MGMFidro8uikr+zlJJKJ/Q6mm2ExZ7HwkyR9lSVFfE3kt36qcwa24BQL7y0G9axycGjK1A/0uNQ==",
4059 "dev": true
4060 },
4060 "emojis-list": { 4061 "emojis-list": {
4061 "version": "2.1.0", 4062 "version": "2.1.0",
4062 "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", 4063 "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz",
@@ -4084,6 +4085,7 @@
4084 "version": "1.4.1", 4085 "version": "1.4.1",
4085 "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", 4086 "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
4086 "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", 4087 "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
4088 "dev": true,
4087 "requires": { 4089 "requires": {
4088 "once": "^1.4.0" 4090 "once": "^1.4.0"
4089 } 4091 }
@@ -4191,11 +4193,6 @@
4191 "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", 4193 "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
4192 "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" 4194 "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w=="
4193 }, 4195 },
4194 "err-code": {
4195 "version": "1.1.2",
4196 "resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz",
4197 "integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA="
4198 },
4199 "error-ex": { 4196 "error-ex": {
4200 "version": "1.3.2", 4197 "version": "1.3.2",
4201 "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", 4198 "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
@@ -4252,15 +4249,8 @@
4252 "es6-promise": { 4249 "es6-promise": {
4253 "version": "4.2.5", 4250 "version": "4.2.5",
4254 "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.5.tgz", 4251 "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.5.tgz",
4255 "integrity": "sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg==" 4252 "integrity": "sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg==",
4256 }, 4253 "dev": true
4257 "es6-promisify": {
4258 "version": "5.0.0",
4259 "resolved": "http://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
4260 "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
4261 "requires": {
4262 "es6-promise": "^4.0.3"
4263 }
4264 }, 4254 },
4265 "es6-symbol": { 4255 "es6-symbol": {
4266 "version": "3.1.1", 4256 "version": "3.1.1",
@@ -4295,51 +4285,62 @@
4295 "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" 4285 "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
4296 }, 4286 },
4297 "eslint": { 4287 "eslint": {
4298 "version": "4.19.1", 4288 "version": "5.10.0",
4299 "resolved": "http://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", 4289 "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.10.0.tgz",
4300 "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", 4290 "integrity": "sha512-HpqzC+BHULKlnPwWae9MaVZ5AXJKpkxCVXQHrFaRw3hbDj26V/9ArYM4Rr/SQ8pi6qUPLXSSXC4RBJlyq2Z2OQ==",
4301 "dev": true, 4291 "dev": true,
4302 "requires": { 4292 "requires": {
4303 "ajv": "^5.3.0", 4293 "@babel/code-frame": "^7.0.0",
4304 "babel-code-frame": "^6.22.0", 4294 "ajv": "^6.5.3",
4305 "chalk": "^2.1.0", 4295 "chalk": "^2.1.0",
4306 "concat-stream": "^1.6.0", 4296 "cross-spawn": "^6.0.5",
4307 "cross-spawn": "^5.1.0", 4297 "debug": "^4.0.1",
4308 "debug": "^3.1.0",
4309 "doctrine": "^2.1.0", 4298 "doctrine": "^2.1.0",
4310 "eslint-scope": "^3.7.1", 4299 "eslint-scope": "^4.0.0",
4300 "eslint-utils": "^1.3.1",
4311 "eslint-visitor-keys": "^1.0.0", 4301 "eslint-visitor-keys": "^1.0.0",
4312 "espree": "^3.5.4", 4302 "espree": "^5.0.0",
4313 "esquery": "^1.0.0", 4303 "esquery": "^1.0.1",
4314 "esutils": "^2.0.2", 4304 "esutils": "^2.0.2",
4315 "file-entry-cache": "^2.0.0", 4305 "file-entry-cache": "^2.0.0",
4316 "functional-red-black-tree": "^1.0.1", 4306 "functional-red-black-tree": "^1.0.1",
4317 "glob": "^7.1.2", 4307 "glob": "^7.1.2",
4318 "globals": "^11.0.1", 4308 "globals": "^11.7.0",
4319 "ignore": "^3.3.3", 4309 "ignore": "^4.0.6",
4320 "imurmurhash": "^0.1.4", 4310 "imurmurhash": "^0.1.4",
4321 "inquirer": "^3.0.6", 4311 "inquirer": "^6.1.0",
4322 "is-resolvable": "^1.0.0", 4312 "js-yaml": "^3.12.0",
4323 "js-yaml": "^3.9.1",
4324 "json-stable-stringify-without-jsonify": "^1.0.1", 4313 "json-stable-stringify-without-jsonify": "^1.0.1",
4325 "levn": "^0.3.0", 4314 "levn": "^0.3.0",
4326 "lodash": "^4.17.4", 4315 "lodash": "^4.17.5",
4327 "minimatch": "^3.0.2", 4316 "minimatch": "^3.0.4",
4328 "mkdirp": "^0.5.1", 4317 "mkdirp": "^0.5.1",
4329 "natural-compare": "^1.4.0", 4318 "natural-compare": "^1.4.0",
4330 "optionator": "^0.8.2", 4319 "optionator": "^0.8.2",
4331 "path-is-inside": "^1.0.2", 4320 "path-is-inside": "^1.0.2",
4332 "pluralize": "^7.0.0", 4321 "pluralize": "^7.0.0",
4333 "progress": "^2.0.0", 4322 "progress": "^2.0.0",
4334 "regexpp": "^1.0.1", 4323 "regexpp": "^2.0.1",
4335 "require-uncached": "^1.0.3", 4324 "require-uncached": "^1.0.3",
4336 "semver": "^5.3.0", 4325 "semver": "^5.5.1",
4337 "strip-ansi": "^4.0.0", 4326 "strip-ansi": "^4.0.0",
4338 "strip-json-comments": "~2.0.1", 4327 "strip-json-comments": "^2.0.1",
4339 "table": "4.0.2", 4328 "table": "^5.0.2",
4340 "text-table": "~0.2.0" 4329 "text-table": "^0.2.0"
4341 }, 4330 },
4342 "dependencies": { 4331 "dependencies": {
4332 "ajv": {
4333 "version": "6.6.1",
4334 "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.1.tgz",
4335 "integrity": "sha512-ZoJjft5B+EJBjUyu9C9Hc0OZyPZSSlOF+plzouTrg6UlA8f+e/n8NIgBFG/9tppJtpPWfthHakK7juJdNDODww==",
4336 "dev": true,
4337 "requires": {
4338 "fast-deep-equal": "^2.0.1",
4339 "fast-json-stable-stringify": "^2.0.0",
4340 "json-schema-traverse": "^0.4.1",
4341 "uri-js": "^4.2.2"
4342 }
4343 },
4343 "ansi-regex": { 4344 "ansi-regex": {
4344 "version": "3.0.0", 4345 "version": "3.0.0",
4345 "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 4346 "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
@@ -4366,30 +4367,25 @@
4366 "supports-color": "^5.3.0" 4367 "supports-color": "^5.3.0"
4367 } 4368 }
4368 }, 4369 },
4369 "cross-spawn": {
4370 "version": "5.1.0",
4371 "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
4372 "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
4373 "dev": true,
4374 "requires": {
4375 "lru-cache": "^4.0.1",
4376 "shebang-command": "^1.2.0",
4377 "which": "^1.2.9"
4378 }
4379 },
4380 "debug": { 4370 "debug": {
4381 "version": "3.2.6", 4371 "version": "4.1.0",
4382 "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", 4372 "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.0.tgz",
4383 "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", 4373 "integrity": "sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg==",
4384 "dev": true, 4374 "dev": true,
4385 "requires": { 4375 "requires": {
4386 "ms": "^2.1.1" 4376 "ms": "^2.1.1"
4387 } 4377 }
4388 }, 4378 },
4389 "globals": { 4379 "fast-deep-equal": {
4390 "version": "11.8.0", 4380 "version": "2.0.1",
4391 "resolved": "https://registry.npmjs.org/globals/-/globals-11.8.0.tgz", 4381 "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
4392 "integrity": "sha512-io6LkyPVuzCHBSQV9fmOwxZkUk6nIaGmxheLDgmuFv89j0fm2aqDbIXKAGfzCMHqz3HLF2Zf8WSG6VqMh2qFmA==", 4382 "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
4383 "dev": true
4384 },
4385 "json-schema-traverse": {
4386 "version": "0.4.1",
4387 "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
4388 "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
4393 "dev": true 4389 "dev": true
4394 }, 4390 },
4395 "ms": { 4391 "ms": {
@@ -4419,21 +4415,25 @@
4419 } 4415 }
4420 }, 4416 },
4421 "eslint-config-airbnb": { 4417 "eslint-config-airbnb": {
4422 "version": "14.1.0", 4418 "version": "17.1.0",
4423 "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-14.1.0.tgz", 4419 "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-17.1.0.tgz",
4424 "integrity": "sha1-NV0pAEC7+OAL+LSxn0twy+fCMX8=", 4420 "integrity": "sha512-R9jw28hFfEQnpPau01NO5K/JWMGLi6aymiF6RsnMURjTk+MqZKllCqGK/0tOvHkPi/NWSSOU2Ced/GX++YxLnw==",
4425 "dev": true, 4421 "dev": true,
4426 "requires": { 4422 "requires": {
4427 "eslint-config-airbnb-base": "^11.1.0" 4423 "eslint-config-airbnb-base": "^13.1.0",
4424 "object.assign": "^4.1.0",
4425 "object.entries": "^1.0.4"
4428 } 4426 }
4429 }, 4427 },
4430 "eslint-config-airbnb-base": { 4428 "eslint-config-airbnb-base": {
4431 "version": "11.3.2", 4429 "version": "13.1.0",
4432 "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-11.3.2.tgz", 4430 "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-13.1.0.tgz",
4433 "integrity": "sha512-/fhjt/VqzBA2SRsx7ErDtv6Ayf+XLw9LIOqmpBuHFCVwyJo2EtzGWMB9fYRFBoWWQLxmNmCpenNiH0RxyeS41w==", 4431 "integrity": "sha512-XWwQtf3U3zIoKO1BbHh6aUhJZQweOwSt4c2JrPDg9FP3Ltv3+YfEv7jIDB8275tVnO/qOHbfuYg3kzw6Je7uWw==",
4434 "dev": true, 4432 "dev": true,
4435 "requires": { 4433 "requires": {
4436 "eslint-restricted-globals": "^0.1.1" 4434 "eslint-restricted-globals": "^0.1.1",
4435 "object.assign": "^4.1.0",
4436 "object.entries": "^1.0.4"
4437 } 4437 }
4438 }, 4438 },
4439 "eslint-import-resolver-node": { 4439 "eslint-import-resolver-node": {
@@ -4557,39 +4557,32 @@
4557 } 4557 }
4558 }, 4558 },
4559 "eslint-plugin-jsx-a11y": { 4559 "eslint-plugin-jsx-a11y": {
4560 "version": "3.0.2", 4560 "version": "6.1.2",
4561 "resolved": "http://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-3.0.2.tgz", 4561 "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.1.2.tgz",
4562 "integrity": "sha1-nw6ryv3j0qJgDZamatuQ0JnoQf4=", 4562 "integrity": "sha512-7gSSmwb3A+fQwtw0arguwMdOdzmKUgnUcbSNlo+GjKLAQFuC2EZxWqG9XHRI8VscBJD5a8raz3RuxQNFW+XJbw==",
4563 "dev": true, 4563 "dev": true,
4564 "requires": { 4564 "requires": {
4565 "damerau-levenshtein": "^1.0.0", 4565 "aria-query": "^3.0.0",
4566 "jsx-ast-utils": "^1.0.0", 4566 "array-includes": "^3.0.3",
4567 "object-assign": "^4.0.1" 4567 "ast-types-flow": "^0.0.7",
4568 "axobject-query": "^2.0.1",
4569 "damerau-levenshtein": "^1.0.4",
4570 "emoji-regex": "^6.5.1",
4571 "has": "^1.0.3",
4572 "jsx-ast-utils": "^2.0.1"
4568 } 4573 }
4569 }, 4574 },
4570 "eslint-plugin-react": { 4575 "eslint-plugin-react": {
4571 "version": "6.10.3", 4576 "version": "7.11.1",
4572 "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-6.10.3.tgz", 4577 "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.11.1.tgz",
4573 "integrity": "sha1-xUNb6wZ3ThLH2y9qut3L+QDNP3g=", 4578 "integrity": "sha512-cVVyMadRyW7qsIUh3FHp3u6QHNhOgVrLQYdQEB1bPWBsgbNCHdFAeNMquBMCcZJu59eNthX053L70l7gRt4SCw==",
4574 "dev": true, 4579 "dev": true,
4575 "requires": { 4580 "requires": {
4576 "array.prototype.find": "^2.0.1", 4581 "array-includes": "^3.0.3",
4577 "doctrine": "^1.2.2", 4582 "doctrine": "^2.1.0",
4578 "has": "^1.0.1", 4583 "has": "^1.0.3",
4579 "jsx-ast-utils": "^1.3.4", 4584 "jsx-ast-utils": "^2.0.1",
4580 "object.assign": "^4.0.4" 4585 "prop-types": "^15.6.2"
4581 },
4582 "dependencies": {
4583 "doctrine": {
4584 "version": "1.5.0",
4585 "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
4586 "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=",
4587 "dev": true,
4588 "requires": {
4589 "esutils": "^2.0.2",
4590 "isarray": "^1.0.0"
4591 }
4592 }
4593 } 4586 }
4594 }, 4587 },
4595 "eslint-restricted-globals": { 4588 "eslint-restricted-globals": {
@@ -4599,15 +4592,21 @@
4599 "dev": true 4592 "dev": true
4600 }, 4593 },
4601 "eslint-scope": { 4594 "eslint-scope": {
4602 "version": "3.7.3", 4595 "version": "4.0.0",
4603 "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", 4596 "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz",
4604 "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", 4597 "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==",
4605 "dev": true, 4598 "dev": true,
4606 "requires": { 4599 "requires": {
4607 "esrecurse": "^4.1.0", 4600 "esrecurse": "^4.1.0",
4608 "estraverse": "^4.1.1" 4601 "estraverse": "^4.1.1"
4609 } 4602 }
4610 }, 4603 },
4604 "eslint-utils": {
4605 "version": "1.3.1",
4606 "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz",
4607 "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==",
4608 "dev": true
4609 },
4611 "eslint-visitor-keys": { 4610 "eslint-visitor-keys": {
4612 "version": "1.0.0", 4611 "version": "1.0.0",
4613 "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", 4612 "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
@@ -4615,13 +4614,14 @@
4615 "dev": true 4614 "dev": true
4616 }, 4615 },
4617 "espree": { 4616 "espree": {
4618 "version": "3.5.4", 4617 "version": "5.0.0",
4619 "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", 4618 "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.0.tgz",
4620 "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", 4619 "integrity": "sha512-1MpUfwsdS9MMoN7ZXqAr9e9UKdVHDcvrJpyx7mm1WuQlx/ygErEQBzgi5Nh5qBHIoYweprhtMkTCb9GhcAIcsA==",
4621 "dev": true, 4620 "dev": true,
4622 "requires": { 4621 "requires": {
4623 "acorn": "^5.5.0", 4622 "acorn": "^6.0.2",
4624 "acorn-jsx": "^3.0.0" 4623 "acorn-jsx": "^5.0.0",
4624 "eslint-visitor-keys": "^1.0.0"
4625 } 4625 }
4626 }, 4626 },
4627 "esprima": { 4627 "esprima": {
@@ -4815,25 +4815,14 @@
4815 } 4815 }
4816 }, 4816 },
4817 "external-editor": { 4817 "external-editor": {
4818 "version": "2.2.0", 4818 "version": "3.0.3",
4819 "resolved": "http://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", 4819 "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz",
4820 "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", 4820 "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==",
4821 "dev": true, 4821 "dev": true,
4822 "requires": { 4822 "requires": {
4823 "chardet": "^0.4.0", 4823 "chardet": "^0.7.0",
4824 "iconv-lite": "^0.4.17", 4824 "iconv-lite": "^0.4.24",
4825 "tmp": "^0.0.33" 4825 "tmp": "^0.0.33"
4826 },
4827 "dependencies": {
4828 "tmp": {
4829 "version": "0.0.33",
4830 "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
4831 "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
4832 "dev": true,
4833 "requires": {
4834 "os-tmpdir": "~1.0.2"
4835 }
4836 }
4837 } 4826 }
4838 }, 4827 },
4839 "extglob": { 4828 "extglob": {
@@ -4971,11 +4960,6 @@
4971 "pend": "~1.2.0" 4960 "pend": "~1.2.0"
4972 } 4961 }
4973 }, 4962 },
4974 "figgy-pudding": {
4975 "version": "3.5.1",
4976 "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz",
4977 "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w=="
4978 },
4979 "figures": { 4963 "figures": {
4980 "version": "2.0.0", 4964 "version": "2.0.0",
4981 "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", 4965 "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
@@ -5120,14 +5104,14 @@
5120 "integrity": "sha1-Tnmumy6zi/hrO7Vr8+ClaqX8q9c=" 5104 "integrity": "sha1-Tnmumy6zi/hrO7Vr8+ClaqX8q9c="
5121 }, 5105 },
5122 "flat-cache": { 5106 "flat-cache": {
5123 "version": "1.3.0", 5107 "version": "1.3.4",
5124 "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", 5108 "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz",
5125 "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", 5109 "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==",
5126 "dev": true, 5110 "dev": true,
5127 "requires": { 5111 "requires": {
5128 "circular-json": "^0.3.1", 5112 "circular-json": "^0.3.1",
5129 "del": "^2.0.2",
5130 "graceful-fs": "^4.1.2", 5113 "graceful-fs": "^4.1.2",
5114 "rimraf": "~2.6.2",
5131 "write": "^0.2.1" 5115 "write": "^0.2.1"
5132 } 5116 }
5133 }, 5117 },
@@ -5135,6 +5119,7 @@
5135 "version": "1.0.3", 5119 "version": "1.0.3",
5136 "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz", 5120 "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz",
5137 "integrity": "sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw==", 5121 "integrity": "sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw==",
5122 "dev": true,
5138 "requires": { 5123 "requires": {
5139 "inherits": "^2.0.1", 5124 "inherits": "^2.0.1",
5140 "readable-stream": "^2.0.4" 5125 "readable-stream": "^2.0.4"
@@ -5184,15 +5169,6 @@
5184 "integrity": "sha1-lzHc9WeMf660T7kDxPct9VGH+nc=", 5169 "integrity": "sha1-lzHc9WeMf660T7kDxPct9VGH+nc=",
5185 "dev": true 5170 "dev": true
5186 }, 5171 },
5187 "from2": {
5188 "version": "2.3.0",
5189 "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
5190 "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
5191 "requires": {
5192 "inherits": "^2.0.1",
5193 "readable-stream": "^2.0.0"
5194 }
5195 },
5196 "fs-extra": { 5172 "fs-extra": {
5197 "version": "7.0.1", 5173 "version": "7.0.1",
5198 "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", 5174 "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
@@ -5230,21 +5206,17 @@
5230 "through2": "^2.0.3" 5206 "through2": "^2.0.3"
5231 } 5207 }
5232 }, 5208 },
5233 "fs-write-stream-atomic": { 5209 "fs-readdir-recursive": {
5234 "version": "1.0.10", 5210 "version": "1.1.0",
5235 "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", 5211 "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz",
5236 "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", 5212 "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==",
5237 "requires": { 5213 "dev": true
5238 "graceful-fs": "^4.1.2",
5239 "iferr": "^0.1.5",
5240 "imurmurhash": "^0.1.4",
5241 "readable-stream": "1 || 2"
5242 }
5243 }, 5214 },
5244 "fs.realpath": { 5215 "fs.realpath": {
5245 "version": "1.0.0", 5216 "version": "1.0.0",
5246 "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 5217 "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
5247 "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 5218 "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
5219 "dev": true
5248 }, 5220 },
5249 "fsevents": { 5221 "fsevents": {
5250 "version": "1.2.4", 5222 "version": "1.2.4",
@@ -5890,11 +5862,6 @@
5890 "globule": "^1.0.0" 5862 "globule": "^1.0.0"
5891 } 5863 }
5892 }, 5864 },
5893 "genfun": {
5894 "version": "5.0.0",
5895 "resolved": "https://registry.npmjs.org/genfun/-/genfun-5.0.0.tgz",
5896 "integrity": "sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA=="
5897 },
5898 "get-caller-file": { 5865 "get-caller-file": {
5899 "version": "1.0.3", 5866 "version": "1.0.3",
5900 "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", 5867 "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
@@ -5939,6 +5906,7 @@
5939 "version": "7.1.3", 5906 "version": "7.1.3",
5940 "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", 5907 "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
5941 "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", 5908 "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
5909 "dev": true,
5942 "requires": { 5910 "requires": {
5943 "fs.realpath": "^1.0.0", 5911 "fs.realpath": "^1.0.0",
5944 "inflight": "^1.0.4", 5912 "inflight": "^1.0.4",
@@ -6020,13 +5988,15 @@
6020 } 5988 }
6021 }, 5989 },
6022 "glob-watcher": { 5990 "glob-watcher": {
6023 "version": "5.0.1", 5991 "version": "5.0.3",
6024 "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.1.tgz", 5992 "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.3.tgz",
6025 "integrity": "sha512-fK92r2COMC199WCyGUblrZKhjra3cyVMDiypDdqg1vsSDmexnbYivK1kNR4QItiNXLKmGlqan469ks67RtNa2g==", 5993 "integrity": "sha512-8tWsULNEPHKQ2MR4zXuzSmqbdyV5PtwwCaWSGQ1WwHsJ07ilNeN1JB8ntxhckbnpSHaf9dXFUHzIWvm1I13dsg==",
6026 "dev": true, 5994 "dev": true,
6027 "requires": { 5995 "requires": {
5996 "anymatch": "^2.0.0",
6028 "async-done": "^1.2.0", 5997 "async-done": "^1.2.0",
6029 "chokidar": "^2.0.0", 5998 "chokidar": "^2.0.0",
5999 "is-negated-glob": "^1.0.0",
6030 "just-debounce": "^1.0.0", 6000 "just-debounce": "^1.0.0",
6031 "object.defaults": "^1.1.0" 6001 "object.defaults": "^1.1.0"
6032 } 6002 }
@@ -6078,19 +6048,11 @@
6078 } 6048 }
6079 } 6049 }
6080 }, 6050 },
6081 "globby": { 6051 "globals": {
6082 "version": "5.0.0", 6052 "version": "11.9.0",
6083 "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", 6053 "resolved": "https://registry.npmjs.org/globals/-/globals-11.9.0.tgz",
6084 "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", 6054 "integrity": "sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg==",
6085 "dev": true, 6055 "dev": true
6086 "requires": {
6087 "array-union": "^1.0.1",
6088 "arrify": "^1.0.0",
6089 "glob": "^7.0.3",
6090 "object-assign": "^4.0.1",
6091 "pify": "^2.0.0",
6092 "pinkie-promise": "^2.0.0"
6093 }
6094 }, 6056 },
6095 "globule": { 6057 "globule": {
6096 "version": "1.2.1", 6058 "version": "1.2.1",
@@ -6907,6 +6869,11 @@
6907 "integrity": "sha512-iWOUTZu7KQGhErV8JfTQDH5F/M2D0HVd0sexS4Grg4e4RYAiN3c4jfpPqKgfedqeebKcNZBl2z3zlgCtFjpFJQ==", 6869 "integrity": "sha512-iWOUTZu7KQGhErV8JfTQDH5F/M2D0HVd0sexS4Grg4e4RYAiN3c4jfpPqKgfedqeebKcNZBl2z3zlgCtFjpFJQ==",
6908 "dev": true 6870 "dev": true
6909 }, 6871 },
6872 "hex-to-rgba": {
6873 "version": "1.0.2",
6874 "resolved": "https://registry.npmjs.org/hex-to-rgba/-/hex-to-rgba-1.0.2.tgz",
6875 "integrity": "sha512-fL+4NFccs86iOuDnFl1Mhyn471qTPAkpE7k39+JYGPMB3+S9LoUnauQI2nz6BUb3DpYQCx8RqENbaf8IFdKYOg=="
6876 },
6910 "history": { 6877 "history": {
6911 "version": "3.3.0", 6878 "version": "3.3.0",
6912 "resolved": "https://registry.npmjs.org/history/-/history-3.3.0.tgz", 6879 "resolved": "https://registry.npmjs.org/history/-/history-3.3.0.tgz",
@@ -6928,6 +6895,12 @@
6928 "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz", 6895 "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz",
6929 "integrity": "sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw==" 6896 "integrity": "sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw=="
6930 }, 6897 },
6898 "home-or-tmp": {
6899 "version": "3.0.0",
6900 "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-3.0.0.tgz",
6901 "integrity": "sha1-V6j+JM8zzdUkhgoVgh3cJchmcfs=",
6902 "dev": true
6903 },
6931 "home-path": { 6904 "home-path": {
6932 "version": "1.0.6", 6905 "version": "1.0.6",
6933 "resolved": "https://registry.npmjs.org/home-path/-/home-path-1.0.6.tgz", 6906 "resolved": "https://registry.npmjs.org/home-path/-/home-path-1.0.6.tgz",
@@ -6945,7 +6918,8 @@
6945 "hosted-git-info": { 6918 "hosted-git-info": {
6946 "version": "2.7.1", 6919 "version": "2.7.1",
6947 "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", 6920 "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz",
6948 "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==" 6921 "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==",
6922 "dev": true
6949 }, 6923 },
6950 "htmlparser2": { 6924 "htmlparser2": {
6951 "version": "3.10.0", 6925 "version": "3.10.0",
@@ -6972,30 +6946,6 @@
6972 } 6946 }
6973 } 6947 }
6974 }, 6948 },
6975 "http-cache-semantics": {
6976 "version": "3.8.1",
6977 "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz",
6978 "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w=="
6979 },
6980 "http-proxy-agent": {
6981 "version": "2.1.0",
6982 "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz",
6983 "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==",
6984 "requires": {
6985 "agent-base": "4",
6986 "debug": "3.1.0"
6987 },
6988 "dependencies": {
6989 "debug": {
6990 "version": "3.1.0",
6991 "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
6992 "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
6993 "requires": {
6994 "ms": "2.0.0"
6995 }
6996 }
6997 }
6998 },
6999 "http-signature": { 6949 "http-signature": {
7000 "version": "1.2.0", 6950 "version": "1.2.0",
7001 "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", 6951 "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
@@ -7007,38 +6957,6 @@
7007 "sshpk": "^1.7.0" 6957 "sshpk": "^1.7.0"
7008 } 6958 }
7009 }, 6959 },
7010 "https-proxy-agent": {
7011 "version": "2.2.1",
7012 "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz",
7013 "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==",
7014 "requires": {
7015 "agent-base": "^4.1.0",
7016 "debug": "^3.1.0"
7017 },
7018 "dependencies": {
7019 "debug": {
7020 "version": "3.2.6",
7021 "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
7022 "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
7023 "requires": {
7024 "ms": "^2.1.1"
7025 }
7026 },
7027 "ms": {
7028 "version": "2.1.1",
7029 "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
7030 "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
7031 }
7032 }
7033 },
7034 "humanize-ms": {
7035 "version": "1.2.1",
7036 "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
7037 "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=",
7038 "requires": {
7039 "ms": "^2.0.0"
7040 }
7041 },
7042 "hunspell-asm": { 6960 "hunspell-asm": {
7043 "version": "1.0.2", 6961 "version": "1.0.2",
7044 "resolved": "http://registry.npmjs.org/hunspell-asm/-/hunspell-asm-1.0.2.tgz", 6962 "resolved": "http://registry.npmjs.org/hunspell-asm/-/hunspell-asm-1.0.2.tgz",
@@ -7050,26 +6968,6 @@
7050 "unixify": "^1.0.0" 6968 "unixify": "^1.0.0"
7051 } 6969 }
7052 }, 6970 },
7053 "hunspell-dict-downloader": {
7054 "version": "1.0.0",
7055 "resolved": "https://registry.npmjs.org/hunspell-dict-downloader/-/hunspell-dict-downloader-1.0.0.tgz",
7056 "integrity": "sha512-HKVIcQPG8/S3lv+zAsD0dDqDCPM+ICFBUIUqcCTgE6WNDqMYc34pi1XuVjQGhMD901UxcTA+cns/PMoNLGPBJA==",
7057 "requires": {
7058 "fs-extra": "^7.0.0",
7059 "lodash.includes": "^4.3.0",
7060 "md5-file": "^4.0.0",
7061 "pacote": "^9.1.0",
7062 "pify": "^4.0.1",
7063 "tslib": "^1.9.3"
7064 },
7065 "dependencies": {
7066 "pify": {
7067 "version": "4.0.1",
7068 "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
7069 "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g=="
7070 }
7071 }
7072 },
7073 "husky": { 6971 "husky": {
7074 "version": "1.1.4", 6972 "version": "1.1.4",
7075 "resolved": "https://registry.npmjs.org/husky/-/husky-1.1.4.tgz", 6973 "resolved": "https://registry.npmjs.org/husky/-/husky-1.1.4.tgz",
@@ -7228,25 +7126,12 @@
7228 "safer-buffer": ">= 2.1.2 < 3" 7126 "safer-buffer": ">= 2.1.2 < 3"
7229 } 7127 }
7230 }, 7128 },
7231 "iferr": {
7232 "version": "0.1.5",
7233 "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz",
7234 "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE="
7235 },
7236 "ignore": { 7129 "ignore": {
7237 "version": "3.3.10", 7130 "version": "4.0.6",
7238 "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", 7131 "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
7239 "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", 7132 "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
7240 "dev": true 7133 "dev": true
7241 }, 7134 },
7242 "ignore-walk": {
7243 "version": "3.0.1",
7244 "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz",
7245 "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==",
7246 "requires": {
7247 "minimatch": "^3.0.4"
7248 }
7249 },
7250 "import-fresh": { 7135 "import-fresh": {
7251 "version": "2.0.0", 7136 "version": "2.0.0",
7252 "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", 7137 "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz",
@@ -7283,7 +7168,8 @@
7283 "imurmurhash": { 7168 "imurmurhash": {
7284 "version": "0.1.4", 7169 "version": "0.1.4",
7285 "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 7170 "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
7286 "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" 7171 "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
7172 "dev": true
7287 }, 7173 },
7288 "in-publish": { 7174 "in-publish": {
7289 "version": "2.0.0", 7175 "version": "2.0.0",
@@ -7326,24 +7212,23 @@
7326 "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" 7212 "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
7327 }, 7213 },
7328 "inquirer": { 7214 "inquirer": {
7329 "version": "3.3.0", 7215 "version": "6.2.1",
7330 "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", 7216 "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.1.tgz",
7331 "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", 7217 "integrity": "sha512-088kl3DRT2dLU5riVMKKr1DlImd6X7smDhpXUCkJDCKvTEJeRiXh0G132HG9u5a+6Ylw9plFRY7RuTnwohYSpg==",
7332 "dev": true, 7218 "dev": true,
7333 "requires": { 7219 "requires": {
7334 "ansi-escapes": "^3.0.0", 7220 "ansi-escapes": "^3.0.0",
7335 "chalk": "^2.0.0", 7221 "chalk": "^2.0.0",
7336 "cli-cursor": "^2.1.0", 7222 "cli-cursor": "^2.1.0",
7337 "cli-width": "^2.0.0", 7223 "cli-width": "^2.0.0",
7338 "external-editor": "^2.0.4", 7224 "external-editor": "^3.0.0",
7339 "figures": "^2.0.0", 7225 "figures": "^2.0.0",
7340 "lodash": "^4.3.0", 7226 "lodash": "^4.17.10",
7341 "mute-stream": "0.0.7", 7227 "mute-stream": "0.0.7",
7342 "run-async": "^2.2.0", 7228 "run-async": "^2.2.0",
7343 "rx-lite": "^4.0.8", 7229 "rxjs": "^6.1.0",
7344 "rx-lite-aggregates": "^4.0.8",
7345 "string-width": "^2.1.0", 7230 "string-width": "^2.1.0",
7346 "strip-ansi": "^4.0.0", 7231 "strip-ansi": "^5.0.0",
7347 "through": "^2.3.6" 7232 "through": "^2.3.6"
7348 }, 7233 },
7349 "dependencies": { 7234 "dependencies": {
@@ -7379,6 +7264,15 @@
7379 "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 7264 "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
7380 "dev": true 7265 "dev": true
7381 }, 7266 },
7267 "rxjs": {
7268 "version": "6.3.3",
7269 "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz",
7270 "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==",
7271 "dev": true,
7272 "requires": {
7273 "tslib": "^1.9.0"
7274 }
7275 },
7382 "string-width": { 7276 "string-width": {
7383 "version": "2.1.1", 7277 "version": "2.1.1",
7384 "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 7278 "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
@@ -7387,15 +7281,34 @@
7387 "requires": { 7281 "requires": {
7388 "is-fullwidth-code-point": "^2.0.0", 7282 "is-fullwidth-code-point": "^2.0.0",
7389 "strip-ansi": "^4.0.0" 7283 "strip-ansi": "^4.0.0"
7284 },
7285 "dependencies": {
7286 "strip-ansi": {
7287 "version": "4.0.0",
7288 "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
7289 "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
7290 "dev": true,
7291 "requires": {
7292 "ansi-regex": "^3.0.0"
7293 }
7294 }
7390 } 7295 }
7391 }, 7296 },
7392 "strip-ansi": { 7297 "strip-ansi": {
7393 "version": "4.0.0", 7298 "version": "5.0.0",
7394 "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 7299 "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.0.0.tgz",
7395 "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 7300 "integrity": "sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow==",
7396 "dev": true, 7301 "dev": true,
7397 "requires": { 7302 "requires": {
7398 "ansi-regex": "^3.0.0" 7303 "ansi-regex": "^4.0.0"
7304 },
7305 "dependencies": {
7306 "ansi-regex": {
7307 "version": "4.0.0",
7308 "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.0.0.tgz",
7309 "integrity": "sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w==",
7310 "dev": true
7311 }
7399 } 7312 }
7400 }, 7313 },
7401 "supports-color": { 7314 "supports-color": {
@@ -7453,11 +7366,6 @@
7453 "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", 7366 "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
7454 "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" 7367 "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY="
7455 }, 7368 },
7456 "ip": {
7457 "version": "1.1.5",
7458 "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
7459 "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo="
7460 },
7461 "is": { 7369 "is": {
7462 "version": "0.3.0", 7370 "version": "0.3.0",
7463 "resolved": "http://registry.npmjs.org/is/-/is-0.3.0.tgz", 7371 "resolved": "http://registry.npmjs.org/is/-/is-0.3.0.tgz",
@@ -7515,6 +7423,7 @@
7515 "version": "1.0.0", 7423 "version": "1.0.0",
7516 "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", 7424 "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
7517 "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", 7425 "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
7426 "dev": true,
7518 "requires": { 7427 "requires": {
7519 "builtin-modules": "^1.0.0" 7428 "builtin-modules": "^1.0.0"
7520 } 7429 }
@@ -7686,21 +7595,6 @@
7686 "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", 7595 "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
7687 "dev": true 7596 "dev": true
7688 }, 7597 },
7689 "is-path-cwd": {
7690 "version": "1.0.0",
7691 "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz",
7692 "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=",
7693 "dev": true
7694 },
7695 "is-path-in-cwd": {
7696 "version": "1.0.1",
7697 "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz",
7698 "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==",
7699 "dev": true,
7700 "requires": {
7701 "is-path-inside": "^1.0.0"
7702 }
7703 },
7704 "is-path-inside": { 7598 "is-path-inside": {
7705 "version": "1.0.1", 7599 "version": "1.0.1",
7706 "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", 7600 "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz",
@@ -7762,12 +7656,6 @@
7762 "is-unc-path": "^1.0.0" 7656 "is-unc-path": "^1.0.0"
7763 } 7657 }
7764 }, 7658 },
7765 "is-resolvable": {
7766 "version": "1.1.0",
7767 "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz",
7768 "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==",
7769 "dev": true
7770 },
7771 "is-retry-allowed": { 7659 "is-retry-allowed": {
7772 "version": "1.1.0", 7660 "version": "1.1.0",
7773 "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", 7661 "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz",
@@ -7920,7 +7808,8 @@
7920 "json-parse-better-errors": { 7808 "json-parse-better-errors": {
7921 "version": "1.0.2", 7809 "version": "1.0.2",
7922 "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", 7810 "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
7923 "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" 7811 "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
7812 "dev": true
7924 }, 7813 },
7925 "json-schema": { 7814 "json-schema": {
7926 "version": "0.2.3", 7815 "version": "0.2.3",
@@ -7981,11 +7870,6 @@
7981 "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", 7870 "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
7982 "dev": true 7871 "dev": true
7983 }, 7872 },
7984 "jsonparse": {
7985 "version": "1.3.1",
7986 "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
7987 "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA="
7988 },
7989 "jsonwebtoken": { 7873 "jsonwebtoken": {
7990 "version": "7.4.3", 7874 "version": "7.4.3",
7991 "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-7.4.3.tgz", 7875 "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-7.4.3.tgz",
@@ -8113,10 +7997,13 @@
8113 } 7997 }
8114 }, 7998 },
8115 "jsx-ast-utils": { 7999 "jsx-ast-utils": {
8116 "version": "1.4.1", 8000 "version": "2.0.1",
8117 "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz", 8001 "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz",
8118 "integrity": "sha1-OGchPo3Xm/Ho8jAMDPwe+xgsDfE=", 8002 "integrity": "sha1-6AGxs5mF4g//yHtA43SAgOLcrH8=",
8119 "dev": true 8003 "dev": true,
8004 "requires": {
8005 "array-includes": "^3.0.3"
8006 }
8120 }, 8007 },
8121 "just-debounce": { 8008 "just-debounce": {
8122 "version": "1.0.0", 8009 "version": "1.0.0",
@@ -8386,11 +8273,6 @@
8386 "lodash._root": "^3.0.0" 8273 "lodash._root": "^3.0.0"
8387 } 8274 }
8388 }, 8275 },
8389 "lodash.includes": {
8390 "version": "4.3.0",
8391 "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
8392 "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8="
8393 },
8394 "lodash.isarguments": { 8276 "lodash.isarguments": {
8395 "version": "3.1.0", 8277 "version": "3.1.0",
8396 "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", 8278 "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
@@ -8563,6 +8445,7 @@
8563 "version": "4.1.3", 8445 "version": "4.1.3",
8564 "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", 8446 "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz",
8565 "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", 8447 "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==",
8448 "dev": true,
8566 "requires": { 8449 "requires": {
8567 "pseudomap": "^1.0.2", 8450 "pseudomap": "^1.0.2",
8568 "yallist": "^2.1.2" 8451 "yallist": "^2.1.2"
@@ -8594,24 +8477,6 @@
8594 } 8477 }
8595 } 8478 }
8596 }, 8479 },
8597 "make-fetch-happen": {
8598 "version": "4.0.1",
8599 "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-4.0.1.tgz",
8600 "integrity": "sha512-7R5ivfy9ilRJ1EMKIOziwrns9fGeAD4bAha8EB7BIiBBLHm2KeTUGCrICFt2rbHfzheTLynv50GnNTK1zDTrcQ==",
8601 "requires": {
8602 "agentkeepalive": "^3.4.1",
8603 "cacache": "^11.0.1",
8604 "http-cache-semantics": "^3.8.1",
8605 "http-proxy-agent": "^2.1.0",
8606 "https-proxy-agent": "^2.2.1",
8607 "lru-cache": "^4.1.2",
8608 "mississippi": "^3.0.0",
8609 "node-fetch-npm": "^2.0.2",
8610 "promise-retry": "^1.1.1",
8611 "socks-proxy-agent": "^4.0.0",
8612 "ssri": "^6.0.0"
8613 }
8614 },
8615 "make-iterator": { 8480 "make-iterator": {
8616 "version": "1.0.1", 8481 "version": "1.0.1",
8617 "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", 8482 "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz",
@@ -8665,11 +8530,6 @@
8665 "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", 8530 "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz",
8666 "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=" 8531 "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w="
8667 }, 8532 },
8668 "md5-file": {
8669 "version": "4.0.0",
8670 "resolved": "https://registry.npmjs.org/md5-file/-/md5-file-4.0.0.tgz",
8671 "integrity": "sha512-UC0qFwyAjn4YdPpKaDNw6gNxRf7Mcx7jC1UGCY4boCzgvU2Aoc1mOGzTtrjjLKhM5ivsnhoKpQVxKPp+1j1qwg=="
8672 },
8673 "mdi": { 8533 "mdi": {
8674 "version": "1.9.33", 8534 "version": "1.9.33",
8675 "resolved": "https://registry.npmjs.org/mdi/-/mdi-1.9.33.tgz", 8535 "resolved": "https://registry.npmjs.org/mdi/-/mdi-1.9.33.tgz",
@@ -8831,34 +8691,6 @@
8831 "minipass": "^2.2.1" 8691 "minipass": "^2.2.1"
8832 } 8692 }
8833 }, 8693 },
8834 "mississippi": {
8835 "version": "3.0.0",
8836 "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz",
8837 "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==",
8838 "requires": {
8839 "concat-stream": "^1.5.0",
8840 "duplexify": "^3.4.2",
8841 "end-of-stream": "^1.1.0",
8842 "flush-write-stream": "^1.0.0",
8843 "from2": "^2.1.0",
8844 "parallel-transform": "^1.1.0",
8845 "pump": "^3.0.0",
8846 "pumpify": "^1.3.3",
8847 "stream-each": "^1.1.0",
8848 "through2": "^2.0.0"
8849 },
8850 "dependencies": {
8851 "pump": {
8852 "version": "3.0.0",
8853 "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
8854 "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
8855 "requires": {
8856 "end-of-stream": "^1.1.0",
8857 "once": "^1.3.1"
8858 }
8859 }
8860 }
8861 },
8862 "mixin-deep": { 8694 "mixin-deep": {
8863 "version": "1.3.1", 8695 "version": "1.3.1",
8864 "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", 8696 "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
@@ -8894,21 +8726,35 @@
8894 } 8726 }
8895 }, 8727 },
8896 "mobx": { 8728 "mobx": {
8897 "version": "3.6.2", 8729 "version": "5.7.0",
8898 "resolved": "http://registry.npmjs.org/mobx/-/mobx-3.6.2.tgz", 8730 "resolved": "https://registry.npmjs.org/mobx/-/mobx-5.7.0.tgz",
8899 "integrity": "sha512-Dq3boJFLpZEvuh5a/MbHLUIyN9XobKWIb0dBfkNOJffNkE3vtuY0C9kSDVpfH8BB0BPkVw8g22qCv7d05LEhKg==" 8731 "integrity": "sha512-i+EwjPLq/QSvOFtAuhcd5FFWDxWK3gCJCFbW5dhgc4wsaHB/cL6DEVms3vZDgc2txWcfzjYWfknjggE/c0c4fw=="
8900 }, 8732 },
8901 "mobx-localstorage": { 8733 "mobx-localstorage": {
8902 "version": "0.1.7", 8734 "version": "1.1.0",
8903 "resolved": "https://registry.npmjs.org/mobx-localstorage/-/mobx-localstorage-0.1.7.tgz", 8735 "resolved": "https://registry.npmjs.org/mobx-localstorage/-/mobx-localstorage-1.1.0.tgz",
8904 "integrity": "sha1-wMZDZnafOQykozP0GRLq4AzUqd4=" 8736 "integrity": "sha512-R/7hN34XC6kCzXFIYM3E+GKJT+2lUIrqK+7tdqjUFoh5asOFd0trJt4TYxdLy+7UG2UlFzTKpYCyUgZNrsTl2g==",
8737 "requires": {
8738 "reactive-localstorage": "^0.0.2"
8739 }
8905 }, 8740 },
8906 "mobx-react": { 8741 "mobx-react": {
8907 "version": "4.4.3", 8742 "version": "5.4.2",
8908 "resolved": "http://registry.npmjs.org/mobx-react/-/mobx-react-4.4.3.tgz", 8743 "resolved": "https://registry.npmjs.org/mobx-react/-/mobx-react-5.4.2.tgz",
8909 "integrity": "sha1-uqnsQRZe41rnud8ZvKEBkPNvEX4=", 8744 "integrity": "sha512-alSN0KDAAOb1OkYujfoJjjk0JWxWRKO4sLGB4hN2CuvaJMrlj7bhGQe7CBMJvEFNjtJRbhJcquYVjQ3rrH2zQQ==",
8910 "requires": { 8745 "requires": {
8911 "hoist-non-react-statics": "^2.3.1" 8746 "hoist-non-react-statics": "^3.0.0",
8747 "react-lifecycles-compat": "^3.0.2"
8748 },
8749 "dependencies": {
8750 "hoist-non-react-statics": {
8751 "version": "3.2.1",
8752 "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.2.1.tgz",
8753 "integrity": "sha512-TFsu3TV3YLY+zFTZDrN8L2DTFanObwmBLpWvJs1qfUuEQ5bTAdFcwfx2T/bsCXfM9QHSLvjfP+nihEl0yvozxw==",
8754 "requires": {
8755 "react-is": "^16.3.2"
8756 }
8757 }
8912 } 8758 }
8913 }, 8759 },
8914 "mobx-react-form": { 8760 "mobx-react-form": {
@@ -8934,19 +8780,6 @@
8934 "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", 8780 "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz",
8935 "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=" 8781 "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y="
8936 }, 8782 },
8937 "move-concurrently": {
8938 "version": "1.0.1",
8939 "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
8940 "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=",
8941 "requires": {
8942 "aproba": "^1.1.1",
8943 "copy-concurrently": "^1.0.0",
8944 "fs-write-stream-atomic": "^1.0.8",
8945 "mkdirp": "^0.5.1",
8946 "rimraf": "^2.5.4",
8947 "run-queue": "^1.0.3"
8948 }
8949 },
8950 "ms": { 8783 "ms": {
8951 "version": "2.0.0", 8784 "version": "2.0.0",
8952 "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 8785 "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
@@ -9047,16 +8880,6 @@
9047 "is-stream": "^1.0.1" 8880 "is-stream": "^1.0.1"
9048 } 8881 }
9049 }, 8882 },
9050 "node-fetch-npm": {
9051 "version": "2.0.2",
9052 "resolved": "https://registry.npmjs.org/node-fetch-npm/-/node-fetch-npm-2.0.2.tgz",
9053 "integrity": "sha512-nJIxm1QmAj4v3nfCvEeCrYSoVwXyxLnaPBK5W1W5DGEJwjlKuC2VEUycGw5oxk+4zZahRrB84PUJJgEmhFTDFw==",
9054 "requires": {
9055 "encoding": "^0.1.11",
9056 "json-parse-better-errors": "^1.0.0",
9057 "safe-buffer": "^5.1.1"
9058 }
9059 },
9060 "node-gyp": { 8883 "node-gyp": {
9061 "version": "3.8.0", 8884 "version": "3.8.0",
9062 "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz", 8885 "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz",
@@ -9178,6 +9001,7 @@
9178 "version": "2.4.0", 9001 "version": "2.4.0",
9179 "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", 9002 "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
9180 "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", 9003 "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==",
9004 "dev": true,
9181 "requires": { 9005 "requires": {
9182 "hosted-git-info": "^2.1.4", 9006 "hosted-git-info": "^2.1.4",
9183 "is-builtin-module": "^1.0.0", 9007 "is-builtin-module": "^1.0.0",
@@ -9188,7 +9012,8 @@
9188 "semver": { 9012 "semver": {
9189 "version": "5.6.0", 9013 "version": "5.6.0",
9190 "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", 9014 "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
9191 "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" 9015 "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==",
9016 "dev": true
9192 } 9017 }
9193 } 9018 }
9194 }, 9019 },
@@ -9220,54 +9045,6 @@
9220 "once": "^1.3.2" 9045 "once": "^1.3.2"
9221 } 9046 }
9222 }, 9047 },
9223 "npm-bundled": {
9224 "version": "1.0.5",
9225 "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.5.tgz",
9226 "integrity": "sha512-m/e6jgWu8/v5niCUKQi9qQl8QdeEduFA96xHDDzFGqly0OOjI7c+60KM/2sppfnUU9JJagf+zs+yGhqSOFj71g=="
9227 },
9228 "npm-package-arg": {
9229 "version": "6.1.0",
9230 "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.0.tgz",
9231 "integrity": "sha512-zYbhP2k9DbJhA0Z3HKUePUgdB1x7MfIfKssC+WLPFMKTBZKpZh5m13PgexJjCq6KW7j17r0jHWcCpxEqnnncSA==",
9232 "requires": {
9233 "hosted-git-info": "^2.6.0",
9234 "osenv": "^0.1.5",
9235 "semver": "^5.5.0",
9236 "validate-npm-package-name": "^3.0.0"
9237 }
9238 },
9239 "npm-packlist": {
9240 "version": "1.1.12",
9241 "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.1.12.tgz",
9242 "integrity": "sha512-WJKFOVMeAlsU/pjXuqVdzU0WfgtIBCupkEVwn+1Y0ERAbUfWw8R4GjgVbaKnUjRoD2FoQbHOCbOyT5Mbs9Lw4g==",
9243 "requires": {
9244 "ignore-walk": "^3.0.1",
9245 "npm-bundled": "^1.0.1"
9246 }
9247 },
9248 "npm-pick-manifest": {
9249 "version": "2.2.3",
9250 "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-2.2.3.tgz",
9251 "integrity": "sha512-+IluBC5K201+gRU85vFlUwX3PFShZAbAgDNp2ewJdWMVSppdo/Zih0ul2Ecky/X7b51J7LrrUAP+XOmOCvYZqA==",
9252 "requires": {
9253 "figgy-pudding": "^3.5.1",
9254 "npm-package-arg": "^6.0.0",
9255 "semver": "^5.4.1"
9256 }
9257 },
9258 "npm-registry-fetch": {
9259 "version": "3.8.0",
9260 "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-3.8.0.tgz",
9261 "integrity": "sha512-hrw8UMD+Nob3Kl3h8Z/YjmKamb1gf7D1ZZch2otrIXM3uFLB5vjEY6DhMlq80z/zZet6eETLbOXcuQudCB3Zpw==",
9262 "requires": {
9263 "JSONStream": "^1.3.4",
9264 "bluebird": "^3.5.1",
9265 "figgy-pudding": "^3.4.1",
9266 "lru-cache": "^4.1.3",
9267 "make-fetch-happen": "^4.0.1",
9268 "npm-package-arg": "^6.1.0"
9269 }
9270 },
9271 "npm-run-path": { 9048 "npm-run-path": {
9272 "version": "2.0.2", 9049 "version": "2.0.2",
9273 "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", 9050 "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
@@ -9409,6 +9186,18 @@
9409 "isobject": "^3.0.0" 9186 "isobject": "^3.0.0"
9410 } 9187 }
9411 }, 9188 },
9189 "object.entries": {
9190 "version": "1.0.4",
9191 "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.0.4.tgz",
9192 "integrity": "sha1-G/mk3SKI9bM/Opk9JXZh8F0WGl8=",
9193 "dev": true,
9194 "requires": {
9195 "define-properties": "^1.1.2",
9196 "es-abstract": "^1.6.1",
9197 "function-bind": "^1.1.0",
9198 "has": "^1.0.1"
9199 }
9200 },
9412 "object.map": { 9201 "object.map": {
9413 "version": "1.0.1", 9202 "version": "1.0.1",
9414 "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", 9203 "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz",
@@ -9575,12 +9364,14 @@
9575 "os-tmpdir": { 9364 "os-tmpdir": {
9576 "version": "1.0.2", 9365 "version": "1.0.2",
9577 "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", 9366 "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
9578 "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" 9367 "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
9368 "dev": true
9579 }, 9369 },
9580 "osenv": { 9370 "osenv": {
9581 "version": "0.1.5", 9371 "version": "0.1.5",
9582 "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", 9372 "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
9583 "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", 9373 "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
9374 "dev": true,
9584 "requires": { 9375 "requires": {
9585 "os-homedir": "^1.0.0", 9376 "os-homedir": "^1.0.0",
9586 "os-tmpdir": "^1.0.0" 9377 "os-tmpdir": "^1.0.0"
@@ -9640,88 +9431,11 @@
9640 "semver": "^5.1.0" 9431 "semver": "^5.1.0"
9641 } 9432 }
9642 }, 9433 },
9643 "pacote": {
9644 "version": "9.2.3",
9645 "resolved": "https://registry.npmjs.org/pacote/-/pacote-9.2.3.tgz",
9646 "integrity": "sha512-Y3+yY3nBRAxMlZWvr62XLJxOwCmG9UmkGZkFurWHoCjqF0cZL72cTOCRJTvWw8T4OhJS2RTg13x4oYYriauvEw==",
9647 "requires": {
9648 "bluebird": "^3.5.2",
9649 "cacache": "^11.2.0",
9650 "figgy-pudding": "^3.5.1",
9651 "get-stream": "^4.1.0",
9652 "glob": "^7.1.3",
9653 "lru-cache": "^4.1.3",
9654 "make-fetch-happen": "^4.0.1",
9655 "minimatch": "^3.0.4",
9656 "minipass": "^2.3.5",
9657 "mississippi": "^3.0.0",
9658 "mkdirp": "^0.5.1",
9659 "normalize-package-data": "^2.4.0",
9660 "npm-package-arg": "^6.1.0",
9661 "npm-packlist": "^1.1.12",
9662 "npm-pick-manifest": "^2.2.3",
9663 "npm-registry-fetch": "^3.8.0",
9664 "osenv": "^0.1.5",
9665 "promise-inflight": "^1.0.1",
9666 "promise-retry": "^1.1.1",
9667 "protoduck": "^5.0.1",
9668 "rimraf": "^2.6.2",
9669 "safe-buffer": "^5.1.2",
9670 "semver": "^5.6.0",
9671 "ssri": "^6.0.1",
9672 "tar": "^4.4.6",
9673 "unique-filename": "^1.1.1",
9674 "which": "^1.3.1"
9675 },
9676 "dependencies": {
9677 "get-stream": {
9678 "version": "4.1.0",
9679 "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
9680 "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
9681 "requires": {
9682 "pump": "^3.0.0"
9683 }
9684 },
9685 "minipass": {
9686 "version": "2.3.5",
9687 "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz",
9688 "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==",
9689 "requires": {
9690 "safe-buffer": "^5.1.2",
9691 "yallist": "^3.0.0"
9692 }
9693 },
9694 "pump": {
9695 "version": "3.0.0",
9696 "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
9697 "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
9698 "requires": {
9699 "end-of-stream": "^1.1.0",
9700 "once": "^1.3.1"
9701 }
9702 },
9703 "yallist": {
9704 "version": "3.0.3",
9705 "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
9706 "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A=="
9707 }
9708 }
9709 },
9710 "pako": { 9434 "pako": {
9711 "version": "1.0.7", 9435 "version": "1.0.7",
9712 "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.7.tgz", 9436 "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.7.tgz",
9713 "integrity": "sha512-3HNK5tW4x8o5mO8RuHZp3Ydw9icZXx0RANAOMzlMzx7LVXhMJ4mo3MOBpzyd7r/+RUu8BmndP47LXT+vzjtWcQ==" 9437 "integrity": "sha512-3HNK5tW4x8o5mO8RuHZp3Ydw9icZXx0RANAOMzlMzx7LVXhMJ4mo3MOBpzyd7r/+RUu8BmndP47LXT+vzjtWcQ=="
9714 }, 9438 },
9715 "parallel-transform": {
9716 "version": "1.1.0",
9717 "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz",
9718 "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=",
9719 "requires": {
9720 "cyclist": "~0.2.2",
9721 "inherits": "^2.0.3",
9722 "readable-stream": "^2.1.5"
9723 }
9724 },
9725 "parse-color": { 9439 "parse-color": {
9726 "version": "1.0.0", 9440 "version": "1.0.0",
9727 "resolved": "https://registry.npmjs.org/parse-color/-/parse-color-1.0.0.tgz", 9441 "resolved": "https://registry.npmjs.org/parse-color/-/parse-color-1.0.0.tgz",
@@ -9733,7 +9447,7 @@
9733 "dependencies": { 9447 "dependencies": {
9734 "color-convert": { 9448 "color-convert": {
9735 "version": "0.5.3", 9449 "version": "0.5.3",
9736 "resolved": "http://registry.npmjs.org/color-convert/-/color-convert-0.5.3.tgz", 9450 "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-0.5.3.tgz",
9737 "integrity": "sha1-vbbGnOZg+t/+CwAHzER+G59ygr0=", 9451 "integrity": "sha1-vbbGnOZg+t/+CwAHzER+G59ygr0=",
9738 "dev": true 9452 "dev": true
9739 } 9453 }
@@ -9894,11 +9608,6 @@
9894 "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", 9608 "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
9895 "dev": true 9609 "dev": true
9896 }, 9610 },
9897 "performance-now": {
9898 "version": "0.2.0",
9899 "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz",
9900 "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU="
9901 },
9902 "pify": { 9611 "pify": {
9903 "version": "2.3.0", 9612 "version": "2.3.0",
9904 "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", 9613 "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
@@ -10026,9 +9735,9 @@
10026 "dev": true 9735 "dev": true
10027 }, 9736 },
10028 "progress": { 9737 "progress": {
10029 "version": "2.0.1", 9738 "version": "2.0.3",
10030 "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.1.tgz", 9739 "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
10031 "integrity": "sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg==", 9740 "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
10032 "dev": true 9741 "dev": true
10033 }, 9742 },
10034 "progress-stream": { 9743 "progress-stream": {
@@ -10100,20 +9809,6 @@
10100 "asap": "~2.0.3" 9809 "asap": "~2.0.3"
10101 } 9810 }
10102 }, 9811 },
10103 "promise-inflight": {
10104 "version": "1.0.1",
10105 "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
10106 "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM="
10107 },
10108 "promise-retry": {
10109 "version": "1.1.1",
10110 "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-1.1.1.tgz",
10111 "integrity": "sha1-ZznpaOMFHaIM5kl/srUPaRHfPW0=",
10112 "requires": {
10113 "err-code": "^1.0.0",
10114 "retry": "^0.10.0"
10115 }
10116 },
10117 "prop-types": { 9812 "prop-types": {
10118 "version": "15.6.2", 9813 "version": "15.6.2",
10119 "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.2.tgz", 9814 "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.2.tgz",
@@ -10131,14 +9826,6 @@
10131 "invariant": "^2.2.0" 9826 "invariant": "^2.2.0"
10132 } 9827 }
10133 }, 9828 },
10134 "protoduck": {
10135 "version": "5.0.1",
10136 "resolved": "https://registry.npmjs.org/protoduck/-/protoduck-5.0.1.tgz",
10137 "integrity": "sha512-WxoCeDCoCBY55BMvj4cAEjdVUFGRWed9ZxPlqTKYyw1nDDTQ4pqmnIMAGfJlg7Dx35uB/M+PHJPTmGOvaCaPTg==",
10138 "requires": {
10139 "genfun": "^5.0.0"
10140 }
10141 },
10142 "proxy-middleware": { 9829 "proxy-middleware": {
10143 "version": "0.15.0", 9830 "version": "0.15.0",
10144 "resolved": "https://registry.npmjs.org/proxy-middleware/-/proxy-middleware-0.15.0.tgz", 9831 "resolved": "https://registry.npmjs.org/proxy-middleware/-/proxy-middleware-0.15.0.tgz",
@@ -10148,7 +9835,8 @@
10148 "pseudomap": { 9835 "pseudomap": {
10149 "version": "1.0.2", 9836 "version": "1.0.2",
10150 "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", 9837 "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
10151 "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" 9838 "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
9839 "dev": true
10152 }, 9840 },
10153 "psl": { 9841 "psl": {
10154 "version": "1.1.29", 9842 "version": "1.1.29",
@@ -10160,6 +9848,7 @@
10160 "version": "2.0.1", 9848 "version": "2.0.1",
10161 "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", 9849 "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
10162 "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", 9850 "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
9851 "dev": true,
10163 "requires": { 9852 "requires": {
10164 "end-of-stream": "^1.1.0", 9853 "end-of-stream": "^1.1.0",
10165 "once": "^1.3.1" 9854 "once": "^1.3.1"
@@ -10169,6 +9858,7 @@
10169 "version": "1.5.1", 9858 "version": "1.5.1",
10170 "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", 9859 "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz",
10171 "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", 9860 "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
9861 "dev": true,
10172 "requires": { 9862 "requires": {
10173 "duplexify": "^3.6.0", 9863 "duplexify": "^3.6.0",
10174 "inherits": "^2.0.3", 9864 "inherits": "^2.0.3",
@@ -10201,21 +9891,6 @@
10201 "strict-uri-encode": "^1.0.0" 9891 "strict-uri-encode": "^1.0.0"
10202 } 9892 }
10203 }, 9893 },
10204 "raf": {
10205 "version": "3.4.0",
10206 "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.0.tgz",
10207 "integrity": "sha512-pDP/NMRAXoTfrhCfyfSEwJAKLaxBU9eApMeBPB1TkDouZmvPerIClV8lTAd+uF8ZiTaVl69e1FCxQrAd/VTjGw==",
10208 "requires": {
10209 "performance-now": "^2.1.0"
10210 },
10211 "dependencies": {
10212 "performance-now": {
10213 "version": "2.1.0",
10214 "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
10215 "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
10216 }
10217 }
10218 },
10219 "randomatic": { 9894 "randomatic": {
10220 "version": "3.1.0", 9895 "version": "3.1.0",
10221 "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.0.tgz", 9896 "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.0.tgz",
@@ -10252,15 +9927,14 @@
10252 } 9927 }
10253 }, 9928 },
10254 "react": { 9929 "react": {
10255 "version": "15.6.2", 9930 "version": "16.6.3",
10256 "resolved": "https://registry.npmjs.org/react/-/react-15.6.2.tgz", 9931 "resolved": "https://registry.npmjs.org/react/-/react-16.6.3.tgz",
10257 "integrity": "sha1-26BDSrQ5z+gvEI8PURZjkIF5qnI=", 9932 "integrity": "sha512-zCvmH2vbEolgKxtqXL2wmGCUxUyNheYn/C+PD1YAjfxHC54+MhdruyhO7QieQrYsYeTxrn93PM2y0jRH1zEExw==",
10258 "requires": { 9933 "requires": {
10259 "create-react-class": "^15.6.0",
10260 "fbjs": "^0.8.9",
10261 "loose-envify": "^1.1.0", 9934 "loose-envify": "^1.1.0",
10262 "object-assign": "^4.1.0", 9935 "object-assign": "^4.1.1",
10263 "prop-types": "^15.5.10" 9936 "prop-types": "^15.6.2",
9937 "scheduler": "^0.11.2"
10264 } 9938 }
10265 }, 9939 },
10266 "react-addons-css-transition-group": { 9940 "react-addons-css-transition-group": {
@@ -10272,23 +9946,23 @@
10272 } 9946 }
10273 }, 9947 },
10274 "react-dom": { 9948 "react-dom": {
10275 "version": "15.6.2", 9949 "version": "16.6.3",
10276 "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-15.6.2.tgz", 9950 "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.6.3.tgz",
10277 "integrity": "sha1-Qc+t9pO3V/rycIRDodH9WgK+9zA=", 9951 "integrity": "sha512-8ugJWRCWLGXy+7PmNh8WJz3g1TaTUt1XyoIcFN+x0Zbkoz+KKdUyx1AQLYJdbFXjuF41Nmjn5+j//rxvhFjgSQ==",
10278 "requires": { 9952 "requires": {
10279 "fbjs": "^0.8.9",
10280 "loose-envify": "^1.1.0", 9953 "loose-envify": "^1.1.0",
10281 "object-assign": "^4.1.0", 9954 "object-assign": "^4.1.1",
10282 "prop-types": "^15.5.10" 9955 "prop-types": "^15.6.2",
9956 "scheduler": "^0.11.2"
10283 } 9957 }
10284 }, 9958 },
10285 "react-dropzone": { 9959 "react-dropzone": {
10286 "version": "4.3.0", 9960 "version": "7.0.1",
10287 "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-4.3.0.tgz", 9961 "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-7.0.1.tgz",
10288 "integrity": "sha512-ULfrLaTSsd8BDa9KVAGCueuq1AN3L14dtMsGGqtP0UwYyjG4Vhf158f/ITSHuSPYkZXbvfcIiOlZsH+e3QWm+Q==", 9962 "integrity": "sha512-J4rbzhFZPVW7k7K9CVb0OcwSOJGLWa0y+0rvtB4rBLVkvq0agH/o3kPJ0DCkd6ZVzL2K1NFqIOvtQkwQKpmJBA==",
10289 "requires": { 9963 "requires": {
10290 "attr-accept": "^1.1.3", 9964 "attr-accept": "^1.1.3",
10291 "prop-types": "^15.5.7" 9965 "prop-types": "^15.6.2"
10292 } 9966 }
10293 }, 9967 },
10294 "react-electron-web-view": { 9968 "react-electron-web-view": {
@@ -10300,9 +9974,9 @@
10300 } 9974 }
10301 }, 9975 },
10302 "react-intl": { 9976 "react-intl": {
10303 "version": "2.7.1", 9977 "version": "2.7.2",
10304 "resolved": "https://registry.npmjs.org/react-intl/-/react-intl-2.7.1.tgz", 9978 "resolved": "https://registry.npmjs.org/react-intl/-/react-intl-2.7.2.tgz",
10305 "integrity": "sha512-Ndk0i04dSplBivA0/fELd8lMvIPuRizKC+F6s1EZ6jELvRKNcx9shWa8A1UIlTQfYSbys5huWCRgmylbW0e57A==", 9979 "integrity": "sha512-3dcNGLqEw2FKkX+1L2WYLgjP0MVJkvWuVd1uLcnwifIQe8JQvnd9Bss4hb4Gvg/YhBIRcs4LM6C2bAgyklucjw==",
10306 "requires": { 9980 "requires": {
10307 "hoist-non-react-statics": "^2.5.5", 9981 "hoist-non-react-statics": "^2.5.5",
10308 "intl-format-cache": "^2.0.5", 9982 "intl-format-cache": "^2.0.5",
@@ -10311,6 +9985,11 @@
10311 "invariant": "^2.1.1" 9985 "invariant": "^2.1.1"
10312 } 9986 }
10313 }, 9987 },
9988 "react-is": {
9989 "version": "16.6.3",
9990 "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.6.3.tgz",
9991 "integrity": "sha512-u7FDWtthB4rWibG/+mFbVd5FvdI20yde86qKGx4lVUTWmPlSWQ4QxbBIrrs+HnXGbxOUlUzTAP/VDmvCwaP2yA=="
9992 },
10314 "react-jss": { 9993 "react-jss": {
10315 "version": "8.6.1", 9994 "version": "8.6.1",
10316 "resolved": "https://registry.npmjs.org/react-jss/-/react-jss-8.6.1.tgz", 9995 "resolved": "https://registry.npmjs.org/react-jss/-/react-jss-8.6.1.tgz",
@@ -10338,17 +10017,6 @@
10338 "spin.js": "2.x" 10017 "spin.js": "2.x"
10339 } 10018 }
10340 }, 10019 },
10341 "react-motion": {
10342 "version": "0.4.8",
10343 "resolved": "https://registry.npmjs.org/react-motion/-/react-motion-0.4.8.tgz",
10344 "integrity": "sha1-I7st0nwtjgDSKeRVctEF789Ao14=",
10345 "requires": {
10346 "create-react-class": "^15.5.2",
10347 "performance-now": "^0.2.0",
10348 "prop-types": "^15.5.8",
10349 "raf": "^3.1.0"
10350 }
10351 },
10352 "react-router": { 10020 "react-router": {
10353 "version": "3.2.1", 10021 "version": "3.2.1",
10354 "resolved": "http://registry.npmjs.org/react-router/-/react-router-3.2.1.tgz", 10022 "resolved": "http://registry.npmjs.org/react-router/-/react-router-3.2.1.tgz",
@@ -10363,23 +10031,13 @@
10363 "warning": "^3.0.0" 10031 "warning": "^3.0.0"
10364 } 10032 }
10365 }, 10033 },
10366 "react-router-transition": {
10367 "version": "0.1.1",
10368 "resolved": "https://registry.npmjs.org/react-router-transition/-/react-router-transition-0.1.1.tgz",
10369 "integrity": "sha1-bMLLdHyyfk1WMsgsp1C0MSzNO9Y=",
10370 "requires": {
10371 "prop-types": "^15.5.8",
10372 "react-motion": "^0.4.8"
10373 }
10374 },
10375 "react-sortable-hoc": { 10034 "react-sortable-hoc": {
10376 "version": "0.6.8", 10035 "version": "0.8.4",
10377 "resolved": "https://registry.npmjs.org/react-sortable-hoc/-/react-sortable-hoc-0.6.8.tgz", 10036 "resolved": "https://registry.npmjs.org/react-sortable-hoc/-/react-sortable-hoc-0.8.4.tgz",
10378 "integrity": "sha512-sUUAtNdV84AKZ2o+F5lVOOFWcyWG6aGDkNFgHoieB1zFLeWLWENkix06asPS4/GhigfuRh06aZix1j3Qx8+NSQ==", 10037 "integrity": "sha512-J9AFEQAJ7u2YWdVzkU5E3ewrG82xQ4xF1ZPrZYKliDwlVBDkmjri+iKFAEt6NCDIRiBZ4hiN5vzI8pwy/dGPHw==",
10379 "requires": { 10038 "requires": {
10380 "babel-runtime": "^6.11.6", 10039 "babel-runtime": "^6.11.6",
10381 "invariant": "^2.2.1", 10040 "invariant": "^2.2.1",
10382 "lodash": "^4.12.0",
10383 "prop-types": "^15.5.7" 10041 "prop-types": "^15.5.7"
10384 } 10042 }
10385 }, 10043 },
@@ -10418,6 +10076,11 @@
10418 "react-lifecycles-compat": "^3.0.4" 10076 "react-lifecycles-compat": "^3.0.4"
10419 } 10077 }
10420 }, 10078 },
10079 "reactive-localstorage": {
10080 "version": "0.0.2",
10081 "resolved": "https://registry.npmjs.org/reactive-localstorage/-/reactive-localstorage-0.0.2.tgz",
10082 "integrity": "sha512-+3oKBiiNxBbLH9mWw6eiBOAbwQSg3xpRIg7ys+E5Zc98DKQ1zyoUcQygWDDwZAn6mka2kWTaZD+ZUSgmV2VzLA=="
10083 },
10421 "read-config-file": { 10084 "read-config-file": {
10422 "version": "3.2.0", 10085 "version": "3.2.0",
10423 "resolved": "https://registry.npmjs.org/read-config-file/-/read-config-file-3.2.0.tgz", 10086 "resolved": "https://registry.npmjs.org/read-config-file/-/read-config-file-3.2.0.tgz",
@@ -10507,6 +10170,7 @@
10507 "version": "2.3.6", 10170 "version": "2.3.6",
10508 "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", 10171 "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
10509 "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", 10172 "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
10173 "dev": true,
10510 "requires": { 10174 "requires": {
10511 "core-util-is": "~1.0.0", 10175 "core-util-is": "~1.0.0",
10512 "inherits": "~2.0.3", 10176 "inherits": "~2.0.3",
@@ -10520,7 +10184,8 @@
10520 "process-nextick-args": { 10184 "process-nextick-args": {
10521 "version": "2.0.0", 10185 "version": "2.0.0",
10522 "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", 10186 "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
10523 "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" 10187 "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
10188 "dev": true
10524 } 10189 }
10525 } 10190 }
10526 }, 10191 },
@@ -10605,9 +10270,9 @@
10605 "integrity": "sha1-Hg9GUMhi3L/tVP1CsUjpuxch/PI=" 10270 "integrity": "sha1-Hg9GUMhi3L/tVP1CsUjpuxch/PI="
10606 }, 10271 },
10607 "regexpp": { 10272 "regexpp": {
10608 "version": "1.1.0", 10273 "version": "2.0.1",
10609 "resolved": "http://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", 10274 "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz",
10610 "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==", 10275 "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==",
10611 "dev": true 10276 "dev": true
10612 }, 10277 },
10613 "regexpu-core": { 10278 "regexpu-core": {
@@ -10838,11 +10503,6 @@
10838 "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", 10503 "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
10839 "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" 10504 "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg=="
10840 }, 10505 },
10841 "retry": {
10842 "version": "0.10.1",
10843 "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz",
10844 "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q="
10845 },
10846 "right-pad": { 10506 "right-pad": {
10847 "version": "1.0.1", 10507 "version": "1.0.1",
10848 "resolved": "https://registry.npmjs.org/right-pad/-/right-pad-1.0.1.tgz", 10508 "resolved": "https://registry.npmjs.org/right-pad/-/right-pad-1.0.1.tgz",
@@ -10853,6 +10513,7 @@
10853 "version": "2.6.2", 10513 "version": "2.6.2",
10854 "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", 10514 "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
10855 "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", 10515 "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
10516 "dev": true,
10856 "requires": { 10517 "requires": {
10857 "glob": "^7.0.5" 10518 "glob": "^7.0.5"
10858 } 10519 }
@@ -10877,29 +10538,6 @@
10877 "integrity": "sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A==", 10538 "integrity": "sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A==",
10878 "dev": true 10539 "dev": true
10879 }, 10540 },
10880 "run-queue": {
10881 "version": "1.0.3",
10882 "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz",
10883 "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=",
10884 "requires": {
10885 "aproba": "^1.1.1"
10886 }
10887 },
10888 "rx-lite": {
10889 "version": "4.0.8",
10890 "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
10891 "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=",
10892 "dev": true
10893 },
10894 "rx-lite-aggregates": {
10895 "version": "4.0.8",
10896 "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz",
10897 "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=",
10898 "dev": true,
10899 "requires": {
10900 "rx-lite": "*"
10901 }
10902 },
10903 "rxjs": { 10541 "rxjs": {
10904 "version": "5.5.12", 10542 "version": "5.5.12",
10905 "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz", 10543 "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz",
@@ -10963,6 +10601,15 @@
10963 "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", 10601 "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
10964 "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" 10602 "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
10965 }, 10603 },
10604 "scheduler": {
10605 "version": "0.11.3",
10606 "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.11.3.tgz",
10607 "integrity": "sha512-i9X9VRRVZDd3xZw10NY5Z2cVMbdYg6gqFecfj79USv1CFN+YrJ3gIPRKf1qlY+Sxly4djoKdfx1T+m9dnRB8kQ==",
10608 "requires": {
10609 "loose-envify": "^1.1.0",
10610 "object-assign": "^4.1.1"
10611 }
10612 },
10966 "scss-tokenizer": { 10613 "scss-tokenizer": {
10967 "version": "0.2.3", 10614 "version": "0.2.3",
10968 "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", 10615 "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz",
@@ -11150,14 +10797,25 @@
11150 "dev": true 10797 "dev": true
11151 }, 10798 },
11152 "slice-ansi": { 10799 "slice-ansi": {
11153 "version": "1.0.0", 10800 "version": "2.0.0",
11154 "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", 10801 "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.0.0.tgz",
11155 "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", 10802 "integrity": "sha512-4j2WTWjp3GsZ+AOagyzVbzp4vWGtZ0hEZ/gDY/uTvm6MTxUfTUIsnMIFb1bn8o0RuXiqUw15H1bue8f22Vw2oQ==",
11156 "dev": true, 10803 "dev": true,
11157 "requires": { 10804 "requires": {
10805 "ansi-styles": "^3.2.0",
10806 "astral-regex": "^1.0.0",
11158 "is-fullwidth-code-point": "^2.0.0" 10807 "is-fullwidth-code-point": "^2.0.0"
11159 }, 10808 },
11160 "dependencies": { 10809 "dependencies": {
10810 "ansi-styles": {
10811 "version": "3.2.1",
10812 "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
10813 "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
10814 "dev": true,
10815 "requires": {
10816 "color-convert": "^1.9.0"
10817 }
10818 },
11161 "is-fullwidth-code-point": { 10819 "is-fullwidth-code-point": {
11162 "version": "2.0.0", 10820 "version": "2.0.0",
11163 "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 10821 "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
@@ -11166,11 +10824,6 @@
11166 } 10824 }
11167 } 10825 }
11168 }, 10826 },
11169 "smart-buffer": {
11170 "version": "4.0.1",
11171 "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.0.1.tgz",
11172 "integrity": "sha512-RFqinRVJVcCAL9Uh1oVqE6FZkqsyLiVOYEZ20TqIOjuX7iFVJ+zsbs4RIghnw/pTs7mZvt8ZHhvm1ZUrR4fykg=="
11173 },
11174 "smoothscroll-polyfill": { 10827 "smoothscroll-polyfill": {
11175 "version": "0.3.6", 10828 "version": "0.3.6",
11176 "resolved": "https://registry.npmjs.org/smoothscroll-polyfill/-/smoothscroll-polyfill-0.3.6.tgz", 10829 "resolved": "https://registry.npmjs.org/smoothscroll-polyfill/-/smoothscroll-polyfill-0.3.6.tgz",
@@ -11415,24 +11068,6 @@
11415 } 11068 }
11416 } 11069 }
11417 }, 11070 },
11418 "socks": {
11419 "version": "2.2.2",
11420 "resolved": "https://registry.npmjs.org/socks/-/socks-2.2.2.tgz",
11421 "integrity": "sha512-g6wjBnnMOZpE0ym6e0uHSddz9p3a+WsBaaYQaBaSCJYvrC4IXykQR9MNGjLQf38e9iIIhp3b1/Zk8YZI3KGJ0Q==",
11422 "requires": {
11423 "ip": "^1.1.5",
11424 "smart-buffer": "^4.0.1"
11425 }
11426 },
11427 "socks-proxy-agent": {
11428 "version": "4.0.1",
11429 "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-4.0.1.tgz",
11430 "integrity": "sha512-Kezx6/VBguXOsEe5oU3lXYyKMi4+gva72TwJ7pQY5JfqUx2nMk7NXA6z/mpNqIlfQjWYVfeuNvQjexiTaTn6Nw==",
11431 "requires": {
11432 "agent-base": "~4.2.0",
11433 "socks": "~2.2.0"
11434 }
11435 },
11436 "sort-keys": { 11071 "sort-keys": {
11437 "version": "1.1.2", 11072 "version": "1.1.2",
11438 "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", 11073 "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
@@ -11513,6 +11148,7 @@
11513 "version": "3.0.2", 11148 "version": "3.0.2",
11514 "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.2.tgz", 11149 "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.2.tgz",
11515 "integrity": "sha512-q9hedtzyXHr5S0A1vEPoK/7l8NpfkFYTq6iCY+Pno2ZbdZR6WexZFtqeVGkGxW3TEJMN914Z55EnAGMmenlIQQ==", 11150 "integrity": "sha512-q9hedtzyXHr5S0A1vEPoK/7l8NpfkFYTq6iCY+Pno2ZbdZR6WexZFtqeVGkGxW3TEJMN914Z55EnAGMmenlIQQ==",
11151 "dev": true,
11516 "requires": { 11152 "requires": {
11517 "spdx-expression-parse": "^3.0.0", 11153 "spdx-expression-parse": "^3.0.0",
11518 "spdx-license-ids": "^3.0.0" 11154 "spdx-license-ids": "^3.0.0"
@@ -11521,12 +11157,14 @@
11521 "spdx-exceptions": { 11157 "spdx-exceptions": {
11522 "version": "2.2.0", 11158 "version": "2.2.0",
11523 "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", 11159 "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz",
11524 "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==" 11160 "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==",
11161 "dev": true
11525 }, 11162 },
11526 "spdx-expression-parse": { 11163 "spdx-expression-parse": {
11527 "version": "3.0.0", 11164 "version": "3.0.0",
11528 "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", 11165 "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
11529 "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", 11166 "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
11167 "dev": true,
11530 "requires": { 11168 "requires": {
11531 "spdx-exceptions": "^2.1.0", 11169 "spdx-exceptions": "^2.1.0",
11532 "spdx-license-ids": "^3.0.0" 11170 "spdx-license-ids": "^3.0.0"
@@ -11535,7 +11173,8 @@
11535 "spdx-license-ids": { 11173 "spdx-license-ids": {
11536 "version": "3.0.1", 11174 "version": "3.0.1",
11537 "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.1.tgz", 11175 "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.1.tgz",
11538 "integrity": "sha512-TfOfPcYGBB5sDuPn3deByxPhmfegAhpDYKSOXZQN81Oyrrif8ZCodOLzK3AesELnCx03kikhyDwh0pfvvQvF8w==" 11176 "integrity": "sha512-TfOfPcYGBB5sDuPn3deByxPhmfegAhpDYKSOXZQN81Oyrrif8ZCodOLzK3AesELnCx03kikhyDwh0pfvvQvF8w==",
11177 "dev": true
11539 }, 11178 },
11540 "speedometer": { 11179 "speedometer": {
11541 "version": "0.1.4", 11180 "version": "0.1.4",
@@ -11578,14 +11217,6 @@
11578 "tweetnacl": "~0.14.0" 11217 "tweetnacl": "~0.14.0"
11579 } 11218 }
11580 }, 11219 },
11581 "ssri": {
11582 "version": "6.0.1",
11583 "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz",
11584 "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==",
11585 "requires": {
11586 "figgy-pudding": "^3.5.1"
11587 }
11588 },
11589 "stack-trace": { 11220 "stack-trace": {
11590 "version": "0.0.10", 11221 "version": "0.0.10",
11591 "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", 11222 "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
@@ -11626,15 +11257,6 @@
11626 "readable-stream": "^2.0.1" 11257 "readable-stream": "^2.0.1"
11627 } 11258 }
11628 }, 11259 },
11629 "stream-each": {
11630 "version": "1.2.3",
11631 "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz",
11632 "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==",
11633 "requires": {
11634 "end-of-stream": "^1.1.0",
11635 "stream-shift": "^1.0.0"
11636 }
11637 },
11638 "stream-exhaust": { 11260 "stream-exhaust": {
11639 "version": "1.0.2", 11261 "version": "1.0.2",
11640 "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", 11262 "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz",
@@ -11644,7 +11266,8 @@
11644 "stream-shift": { 11266 "stream-shift": {
11645 "version": "1.0.0", 11267 "version": "1.0.0",
11646 "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", 11268 "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz",
11647 "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=" 11269 "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=",
11270 "dev": true
11648 }, 11271 },
11649 "strict-uri-encode": { 11272 "strict-uri-encode": {
11650 "version": "1.1.0", 11273 "version": "1.1.0",
@@ -11728,44 +11351,40 @@
11728 "dev": true 11351 "dev": true
11729 }, 11352 },
11730 "table": { 11353 "table": {
11731 "version": "4.0.2", 11354 "version": "5.1.1",
11732 "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", 11355 "resolved": "https://registry.npmjs.org/table/-/table-5.1.1.tgz",
11733 "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", 11356 "integrity": "sha512-NUjapYb/qd4PeFW03HnAuOJ7OMcBkJlqeClWxeNlQ0lXGSb52oZXGzkO0/I0ARegQ2eUT1g2VDJH0eUxDRcHmw==",
11734 "dev": true, 11357 "dev": true,
11735 "requires": { 11358 "requires": {
11736 "ajv": "^5.2.3", 11359 "ajv": "^6.6.1",
11737 "ajv-keywords": "^2.1.0", 11360 "lodash": "^4.17.11",
11738 "chalk": "^2.1.0", 11361 "slice-ansi": "2.0.0",
11739 "lodash": "^4.17.4",
11740 "slice-ansi": "1.0.0",
11741 "string-width": "^2.1.1" 11362 "string-width": "^2.1.1"
11742 }, 11363 },
11743 "dependencies": { 11364 "dependencies": {
11365 "ajv": {
11366 "version": "6.6.1",
11367 "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.1.tgz",
11368 "integrity": "sha512-ZoJjft5B+EJBjUyu9C9Hc0OZyPZSSlOF+plzouTrg6UlA8f+e/n8NIgBFG/9tppJtpPWfthHakK7juJdNDODww==",
11369 "dev": true,
11370 "requires": {
11371 "fast-deep-equal": "^2.0.1",
11372 "fast-json-stable-stringify": "^2.0.0",
11373 "json-schema-traverse": "^0.4.1",
11374 "uri-js": "^4.2.2"
11375 }
11376 },
11744 "ansi-regex": { 11377 "ansi-regex": {
11745 "version": "3.0.0", 11378 "version": "3.0.0",
11746 "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 11379 "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
11747 "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", 11380 "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
11748 "dev": true 11381 "dev": true
11749 }, 11382 },
11750 "ansi-styles": { 11383 "fast-deep-equal": {
11751 "version": "3.2.1", 11384 "version": "2.0.1",
11752 "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 11385 "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
11753 "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 11386 "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
11754 "dev": true, 11387 "dev": true
11755 "requires": {
11756 "color-convert": "^1.9.0"
11757 }
11758 },
11759 "chalk": {
11760 "version": "2.4.1",
11761 "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
11762 "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
11763 "dev": true,
11764 "requires": {
11765 "ansi-styles": "^3.2.1",
11766 "escape-string-regexp": "^1.0.5",
11767 "supports-color": "^5.3.0"
11768 }
11769 }, 11388 },
11770 "is-fullwidth-code-point": { 11389 "is-fullwidth-code-point": {
11771 "version": "2.0.0", 11390 "version": "2.0.0",
@@ -11773,6 +11392,12 @@
11773 "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 11392 "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
11774 "dev": true 11393 "dev": true
11775 }, 11394 },
11395 "json-schema-traverse": {
11396 "version": "0.4.1",
11397 "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
11398 "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
11399 "dev": true
11400 },
11776 "string-width": { 11401 "string-width": {
11777 "version": "2.1.1", 11402 "version": "2.1.1",
11778 "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 11403 "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
@@ -11791,15 +11416,6 @@
11791 "requires": { 11416 "requires": {
11792 "ansi-regex": "^3.0.0" 11417 "ansi-regex": "^3.0.0"
11793 } 11418 }
11794 },
11795 "supports-color": {
11796 "version": "5.5.0",
11797 "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
11798 "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
11799 "dev": true,
11800 "requires": {
11801 "has-flag": "^3.0.0"
11802 }
11803 } 11419 }
11804 } 11420 }
11805 }, 11421 },
@@ -11870,12 +11486,14 @@
11870 "through": { 11486 "through": {
11871 "version": "2.3.8", 11487 "version": "2.3.8",
11872 "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", 11488 "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz",
11873 "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" 11489 "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
11490 "dev": true
11874 }, 11491 },
11875 "through2": { 11492 "through2": {
11876 "version": "2.0.3", 11493 "version": "2.0.3",
11877 "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", 11494 "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
11878 "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", 11495 "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
11496 "dev": true,
11879 "requires": { 11497 "requires": {
11880 "readable-stream": "^2.1.5", 11498 "readable-stream": "^2.1.5",
11881 "xtend": "~4.0.1" 11499 "xtend": "~4.0.1"
@@ -11910,6 +11528,15 @@
11910 "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", 11528 "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=",
11911 "dev": true 11529 "dev": true
11912 }, 11530 },
11531 "tmp": {
11532 "version": "0.0.33",
11533 "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
11534 "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
11535 "dev": true,
11536 "requires": {
11537 "os-tmpdir": "~1.0.2"
11538 }
11539 },
11913 "to-absolute-glob": { 11540 "to-absolute-glob": {
11914 "version": "2.0.2", 11541 "version": "2.0.2",
11915 "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", 11542 "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz",
@@ -12059,7 +11686,8 @@
12059 "typedarray": { 11686 "typedarray": {
12060 "version": "0.0.6", 11687 "version": "0.0.6",
12061 "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", 11688 "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
12062 "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" 11689 "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
11690 "dev": true
12063 }, 11691 },
12064 "ua-parser-js": { 11692 "ua-parser-js": {
12065 "version": "0.7.18", 11693 "version": "0.7.18",
@@ -12160,22 +11788,6 @@
12160 } 11788 }
12161 } 11789 }
12162 }, 11790 },
12163 "unique-filename": {
12164 "version": "1.1.1",
12165 "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
12166 "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
12167 "requires": {
12168 "unique-slug": "^2.0.0"
12169 }
12170 },
12171 "unique-slug": {
12172 "version": "2.0.1",
12173 "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.1.tgz",
12174 "integrity": "sha512-n9cU6+gITaVu7VGj1Z8feKMmfAjEAQGhwD9fE3zvpRRa0wEIx8ODYkVGfSc94M2OX00tUFV8wH3zYbm1I8mxFg==",
12175 "requires": {
12176 "imurmurhash": "^0.1.4"
12177 }
12178 },
12179 "unique-stream": { 11791 "unique-stream": {
12180 "version": "2.2.1", 11792 "version": "2.2.1",
12181 "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.2.1.tgz", 11793 "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.2.1.tgz",
@@ -12402,19 +12014,12 @@
12402 "version": "3.0.4", 12014 "version": "3.0.4",
12403 "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", 12015 "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
12404 "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", 12016 "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
12017 "dev": true,
12405 "requires": { 12018 "requires": {
12406 "spdx-correct": "^3.0.0", 12019 "spdx-correct": "^3.0.0",
12407 "spdx-expression-parse": "^3.0.0" 12020 "spdx-expression-parse": "^3.0.0"
12408 } 12021 }
12409 }, 12022 },
12410 "validate-npm-package-name": {
12411 "version": "3.0.0",
12412 "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz",
12413 "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=",
12414 "requires": {
12415 "builtins": "^1.0.3"
12416 }
12417 },
12418 "value-or-function": { 12023 "value-or-function": {
12419 "version": "3.0.0", 12024 "version": "3.0.0",
12420 "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", 12025 "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz",
@@ -12777,7 +12382,8 @@
12777 "yallist": { 12382 "yallist": {
12778 "version": "2.1.2", 12383 "version": "2.1.2",
12779 "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", 12384 "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
12780 "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" 12385 "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
12386 "dev": true
12781 }, 12387 },
12782 "yargs": { 12388 "yargs": {
12783 "version": "7.1.0", 12389 "version": "7.1.0",
diff --git a/package.json b/package.json
index 6c6adee5d..551727ca9 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
2 "name": "franz", 2 "name": "franz",
3 "productName": "Franz", 3 "productName": "Franz",
4 "appId": "com.meetfranz.franz", 4 "appId": "com.meetfranz.franz",
5 "version": "5.0.0-beta.20", 5 "version": "5.0.0-beta.21",
6 "description": "Messaging app for WhatsApp, Slack, Telegram, HipChat, Hangouts and many many more.", 6 "description": "Messaging app for WhatsApp, Slack, Telegram, HipChat, Hangouts and many many more.",
7 "copyright": "adlk x franz - Stefan Malzner", 7 "copyright": "adlk x franz - Stefan Malzner",
8 "main": "index.js", 8 "main": "index.js",
@@ -33,7 +33,7 @@
33 "@meetfranz/electron-notification-state": "^1.0.0", 33 "@meetfranz/electron-notification-state": "^1.0.0",
34 "address-rfc2822": "^2.0.1", 34 "address-rfc2822": "^2.0.1",
35 "auto-launch": "https://github.com/meetfranz/node-auto-launch.git", 35 "auto-launch": "https://github.com/meetfranz/node-auto-launch.git",
36 "classnames": "^2.2.5", 36 "classnames": "2.2.6",
37 "debug-electron": "^0.0.4", 37 "debug-electron": "^0.0.4",
38 "du": "^0.1.0", 38 "du": "^0.1.0",
39 "electron-dl": "1.12.0", 39 "electron-dl": "1.12.0",
@@ -44,7 +44,7 @@
44 "electron-window-state": "^4.1.0", 44 "electron-window-state": "^4.1.0",
45 "fs-extra": "7.0.1", 45 "fs-extra": "7.0.1",
46 "gulp-cli": "1.2.2", 46 "gulp-cli": "1.2.2",
47 "hunspell-dict-downloader": "1.0.0", 47 "hex-to-rgba": "1.0.2",
48 "ini": "^1.3.4", 48 "ini": "^1.3.4",
49 "jshashes": "^1.0.6", 49 "jshashes": "^1.0.6",
50 "jsonwebtoken": "^7.4.1", 50 "jsonwebtoken": "^7.4.1",
@@ -54,28 +54,27 @@
54 "mime-types": "2.1.21", 54 "mime-types": "2.1.21",
55 "minimist": "^1.2.0", 55 "minimist": "^1.2.0",
56 "mkdirp": "^0.5.1", 56 "mkdirp": "^0.5.1",
57 "mobx": "^3.1.0", 57 "mobx": "5.7.0",
58 "mobx-localstorage": "^0.1.7", 58 "mobx-localstorage": "1.1.0",
59 "mobx-react": "^4.1.0", 59 "mobx-react": "5.4.2",
60 "mobx-react-form": "^1.32.2", 60 "mobx-react-form": "1.35.1",
61 "mobx-react-router": "^3.1.2", 61 "mobx-react-router": "3.1.2",
62 "moment": "^2.17.1", 62 "moment": "^2.17.1",
63 "normalize-url": "^1.9.1", 63 "normalize-url": "^1.9.1",
64 "pretty-bytes": "^4.0.2", 64 "pretty-bytes": "^4.0.2",
65 "prop-types": "^15.5.10", 65 "prop-types": "^15.5.10",
66 "prop-types-extended": "^0.2.1", 66 "prop-types-extended": "^0.2.1",
67 "react": "^15.4.1", 67 "react": "16.6.3",
68 "react-addons-css-transition-group": "^15.4.2", 68 "react-addons-css-transition-group": "15.6.2",
69 "react-dom": "^15.4.1", 69 "react-dom": "16.6.3",
70 "react-dropzone": "^4.2.1", 70 "react-dropzone": "7.0.1",
71 "react-electron-web-view": "^2.0.1", 71 "react-electron-web-view": "^2.0.1",
72 "react-intl": "^2.3.0", 72 "react-intl": "2.7.2",
73 "react-jss": "8.6.1", 73 "react-jss": "8.6.1",
74 "react-loader": "^2.4.0", 74 "react-loader": "2.4.5",
75 "react-router": "^3.0.2", 75 "react-router": "^3.0.2",
76 "react-router-transition": "^0.1.1", 76 "react-sortable-hoc": "0.8.4",
77 "react-sortable-hoc": "^0.6.7", 77 "react-tooltip": "3.9.0",
78 "react-tooltip": "^3.2.7",
79 "route-parser": "^0.0.5", 78 "route-parser": "^0.0.5",
80 "semver": "^5.4.1", 79 "semver": "^5.4.1",
81 "smoothscroll-polyfill": "^0.3.4", 80 "smoothscroll-polyfill": "^0.3.4",
@@ -84,7 +83,8 @@
84 }, 83 },
85 "devDependencies": { 84 "devDependencies": {
86 "@adlk/misty": "^0.1.1", 85 "@adlk/misty": "^0.1.1",
87 "@babel/core": "^7.0.0", 86 "@babel/cli": "7.0.0",
87 "@babel/core": "7.0.0",
88 "@babel/plugin-proposal-class-properties": "^7.0.0", 88 "@babel/plugin-proposal-class-properties": "^7.0.0",
89 "@babel/plugin-proposal-decorators": "^7.0.0", 89 "@babel/plugin-proposal-decorators": "^7.0.0",
90 "@babel/plugin-proposal-export-default-from": "^7.0.0", 90 "@babel/plugin-proposal-export-default-from": "^7.0.0",
@@ -93,20 +93,20 @@
93 "@babel/plugin-transform-regenerator": "^7.0.0", 93 "@babel/plugin-transform-regenerator": "^7.0.0",
94 "@babel/preset-env": "^7.0.0", 94 "@babel/preset-env": "^7.0.0",
95 "@babel/preset-react": "^7.0.0", 95 "@babel/preset-react": "^7.0.0",
96 "@babel/register": "^7.0.0", 96 "@babel/register": "7.0.0",
97 "babel-eslint": "^10.0.1", 97 "babel-eslint": "10.0.1",
98 "cross-env": "^5.0.5", 98 "cross-env": "^5.0.5",
99 "cz-conventional-changelog": "^2.0.0", 99 "cz-conventional-changelog": "2.1.0",
100 "dotenv": "^4.0.0", 100 "dotenv": "^4.0.0",
101 "electron": "^2.0.13", 101 "electron": "^2.0.13",
102 "electron-builder": "20.34.0", 102 "electron-builder": "20.34.0",
103 "electron-rebuild": "^1.6.0", 103 "electron-rebuild": "^1.6.0",
104 "eslint": "^4.7.1", 104 "eslint": "5.10.0",
105 "eslint-config-airbnb": "^14.1.0", 105 "eslint-config-airbnb": "17.1.0",
106 "eslint-loader": "^1.9.0", 106 "eslint-loader": "^1.9.0",
107 "eslint-plugin-import": "^2.2.0", 107 "eslint-plugin-import": "2.14.0",
108 "eslint-plugin-jsx-a11y": "^3.0.0", 108 "eslint-plugin-jsx-a11y": "6.1.2",
109 "eslint-plugin-react": "^6.10.0", 109 "eslint-plugin-react": "7.11.1",
110 "gulp": "^4.0.0", 110 "gulp": "^4.0.0",
111 "gulp-babel": "^8.0.0", 111 "gulp-babel": "^8.0.0",
112 "gulp-sass": "^4.0.2", 112 "gulp-sass": "^4.0.2",
diff --git a/src/api/server/ServerApi.js b/src/api/server/ServerApi.js
index 164419951..2871769a9 100644
--- a/src/api/server/ServerApi.js
+++ b/src/api/server/ServerApi.js
@@ -42,6 +42,7 @@ const API_VERSION = 'v1';
42 42
43export default class ServerApi { 43export default class ServerApi {
44 recipePreviews = []; 44 recipePreviews = [];
45
45 recipes = []; 46 recipes = [];
46 47
47 // User 48 // User
@@ -522,8 +523,7 @@ export default class ServerApi {
522 const request = await window.fetch(`${SERVER_URL}/${API_VERSION}/recipes/${s.service}`, 523 const request = await window.fetch(`${SERVER_URL}/${API_VERSION}/recipes/${s.service}`,
523 this._prepareAuthRequest({ 524 this._prepareAuthRequest({
524 method: 'GET', 525 method: 'GET',
525 }), 526 }));
526 );
527 527
528 if (request.status === 200) { 528 if (request.status === 200) {
529 const data = await request.json(); 529 const data = await request.json();
@@ -549,9 +549,9 @@ export default class ServerApi {
549 549
550 await this._bulkRecipeCheck(recipes); 550 await this._bulkRecipeCheck(recipes);
551 551
552 return Promise.all(services 552 /* eslint-disable no-return-await */
553 .map(async service => await this._prepareServiceModel(service)) // eslint-disable-line 553 return Promise.all(services.map(async service => await this._prepareServiceModel(service)));
554 ); 554 /* eslint-enable no-return-await */
555 } 555 }
556 556
557 async _prepareServiceModel(service) { 557 async _prepareServiceModel(service) {
@@ -596,8 +596,7 @@ export default class ServerApi {
596 } 596 }
597 597
598 return recipe; 598 return recipe;
599 }), 599 })).catch(err => console.error('Can\'t load recipe', err));
600 ).catch(err => console.error('Can\'t load recipe', err));
601 } 600 }
602 601
603 _mapRecipePreviewModel(recipes) { 602 _mapRecipePreviewModel(recipes) {
diff --git a/src/app.js b/src/app.js
index 43d0cf018..831dd93ce 100644
--- a/src/app.js
+++ b/src/app.js
@@ -4,7 +4,9 @@ import React from 'react';
4import { render } from 'react-dom'; 4import { render } from 'react-dom';
5import { Provider } from 'mobx-react'; 5import { Provider } from 'mobx-react';
6import { syncHistoryWithStore, RouterStore } from 'mobx-react-router'; 6import { syncHistoryWithStore, RouterStore } from 'mobx-react-router';
7import { Router, Route, hashHistory, IndexRedirect } from 'react-router'; 7import {
8 Router, Route, hashHistory, IndexRedirect,
9} from 'react-router';
8 10
9import '@babel/polyfill'; 11import '@babel/polyfill';
10import smoothScroll from 'smoothscroll-polyfill'; 12import smoothScroll from 'smoothscroll-polyfill';
diff --git a/src/components/auth/AuthLayout.js b/src/components/auth/AuthLayout.js
index 4fb0e6a59..ac8fdbe5b 100644
--- a/src/components/auth/AuthLayout.js
+++ b/src/components/auth/AuthLayout.js
@@ -1,7 +1,6 @@
1import React, { Component } from 'react'; 1import React, { Component } from 'react';
2import PropTypes from 'prop-types'; 2import PropTypes from 'prop-types';
3import { observer } from 'mobx-react'; 3import { observer } from 'mobx-react';
4import { RouteTransition } from 'react-router-transition';
5import { intlShape } from 'react-intl'; 4import { intlShape } from 'react-intl';
6import { TitleBar } from 'electron-react-titlebar'; 5import { TitleBar } from 'electron-react-titlebar';
7 6
@@ -16,7 +15,6 @@ import { isWindows } from '../../environment';
16export default @observer class AuthLayout extends Component { 15export default @observer class AuthLayout extends Component {
17 static propTypes = { 16 static propTypes = {
18 children: oneOrManyChildElements.isRequired, 17 children: oneOrManyChildElements.isRequired,
19 pathname: PropTypes.string.isRequired,
20 error: globalErrorPropType.isRequired, 18 error: globalErrorPropType.isRequired,
21 isOnline: PropTypes.bool.isRequired, 19 isOnline: PropTypes.bool.isRequired,
22 isAPIHealthy: PropTypes.bool.isRequired, 20 isAPIHealthy: PropTypes.bool.isRequired,
@@ -33,7 +31,6 @@ export default @observer class AuthLayout extends Component {
33 render() { 31 render() {
34 const { 32 const {
35 children, 33 children,
36 pathname,
37 error, 34 error,
38 isOnline, 35 isOnline,
39 isAPIHealthy, 36 isAPIHealthy,
@@ -46,8 +43,8 @@ export default @observer class AuthLayout extends Component {
46 43
47 return ( 44 return (
48 <div className={darkMode ? 'theme__dark' : ''}> 45 <div className={darkMode ? 'theme__dark' : ''}>
49 {isWindows && !isFullScreen && <TitleBar menu={window.franz.menu.template} icon={'assets/images/logo.svg'} />} 46 {isWindows && !isFullScreen && <TitleBar menu={window.franz.menu.template} icon="assets/images/logo.svg" />}
50 <div className={'auth'}> 47 <div className="auth">
51 {!isOnline && ( 48 {!isOnline && (
52 <InfoBar 49 <InfoBar
53 type="warning" 50 type="warning"
@@ -69,22 +66,10 @@ export default @observer class AuthLayout extends Component {
69 </InfoBar> 66 </InfoBar>
70 )} 67 )}
71 <div className="auth__layout"> 68 <div className="auth__layout">
72 <RouteTransition 69 {/* Inject globalError into children */}
73 pathname={pathname} 70 {React.cloneElement(children, {
74 atEnter={{ opacity: 0 }} 71 error,
75 atLeave={{ opacity: 0 }} 72 })}
76 atActive={{ opacity: 1 }}
77 mapStyles={styles => ({
78 transform: `translateX(${styles.translateX}%)`,
79 opacity: styles.opacity,
80 })}
81 component="span"
82 >
83 {/* Inject globalError into children */}
84 {React.cloneElement(children, {
85 error,
86 })}
87 </RouteTransition>
88 </div> 73 </div>
89 {/* </div> */} 74 {/* </div> */}
90 <Link to="https://adlk.io" className="auth__adlk" target="_blank"> 75 <Link to="https://adlk.io" className="auth__adlk" target="_blank">
diff --git a/src/components/auth/Invite.js b/src/components/auth/Invite.js
index 96821a61a..fd957ee73 100644
--- a/src/components/auth/Invite.js
+++ b/src/components/auth/Invite.js
@@ -1,4 +1,4 @@
1import React, { Component } from 'react'; 1import React, { Component, Fragment } from 'react';
2import PropTypes from 'prop-types'; 2import PropTypes from 'prop-types';
3import { observer } from 'mobx-react'; 3import { observer } from 'mobx-react';
4import { defineMessages, intlShape } from 'react-intl'; 4import { defineMessages, intlShape } from 'react-intl';
@@ -127,7 +127,7 @@ export default @observer class Invite extends Component {
127 }); 127 });
128 128
129 const renderForm = ( 129 const renderForm = (
130 <div> 130 <Fragment>
131 {this.state.showSuccessInfo && isInviteSuccessful && ( 131 {this.state.showSuccessInfo && isInviteSuccessful && (
132 <Appear> 132 <Appear>
133 <Infobox 133 <Infobox
@@ -141,11 +141,13 @@ export default @observer class Invite extends Component {
141 )} 141 )}
142 142
143 <form className="franz-form auth__form" onSubmit={e => this.submit(e)}> 143 <form className="franz-form auth__form" onSubmit={e => this.submit(e)}>
144 {!embed && (<img 144 {!embed && (
145 src="./assets/images/logo.svg" 145 <img
146 className="auth__logo" 146 src="./assets/images/logo.svg"
147 alt="" 147 className="auth__logo"
148 />)} 148 alt=""
149 />
150 )}
149 <h1 className={embed && 'invite__embed'}> 151 <h1 className={embed && 'invite__embed'}>
150 {intl.formatMessage(messages.headline)} 152 {intl.formatMessage(messages.headline)}
151 </h1> 153 </h1>
@@ -164,14 +166,16 @@ export default @observer class Invite extends Component {
164 label={intl.formatMessage(messages.submitButtonLabel)} 166 label={intl.formatMessage(messages.submitButtonLabel)}
165 loaded={!isLoadingInvite} 167 loaded={!isLoadingInvite}
166 /> 168 />
167 {!embed && (<Link 169 {!embed && (
168 to="/" 170 <Link
169 className="franz-form__button franz-form__button--secondary auth__button auth__button--skip" 171 to="/"
170 > 172 className="franz-form__button franz-form__button--secondary auth__button auth__button--skip"
171 {intl.formatMessage(messages.skipButtonLabel)} 173 >
172 </Link>)} 174 {intl.formatMessage(messages.skipButtonLabel)}
175 </Link>
176 )}
173 </form> 177 </form>
174 </div> 178 </Fragment>
175 ); 179 );
176 180
177 return ( 181 return (
diff --git a/src/components/auth/Login.js b/src/components/auth/Login.js
index f465b35a5..5d21f8b60 100644
--- a/src/components/auth/Login.js
+++ b/src/components/auth/Login.js
@@ -11,11 +11,8 @@ import Button from '../ui/Button';
11import Link from '../ui/Link'; 11import Link from '../ui/Link';
12import Infobox from '../ui/Infobox'; 12import Infobox from '../ui/Infobox';
13 13
14
15import { globalError as globalErrorPropType } from '../../prop-types'; 14import { globalError as globalErrorPropType } from '../../prop-types';
16 15
17// import Appear from '../ui/effects/Appear';
18
19const messages = defineMessages({ 16const messages = defineMessages({
20 headline: { 17 headline: {
21 id: 'login.headline', 18 id: 'login.headline',
@@ -86,18 +83,18 @@ export default @observer class Login extends Component {
86 }, 83 },
87 }, this.context.intl); 84 }, this.context.intl);
88 85
86 emailField = null;
87
89 submit(e) { 88 submit(e) {
90 e.preventDefault(); 89 e.preventDefault();
91 this.form.submit({ 90 this.form.submit({
92 onSuccess: (form) => { 91 onSuccess: (form) => {
93 this.props.onSubmit(form.values()); 92 this.props.onSubmit(form.values());
94 }, 93 },
95 onError: () => {}, 94 onError: () => { },
96 }); 95 });
97 } 96 }
98 97
99 emailField = null;
100
101 render() { 98 render() {
102 const { form } = this; 99 const { form } = this;
103 const { intl } = this.context; 100 const { intl } = this.context;
diff --git a/src/components/auth/Pricing.js b/src/components/auth/Pricing.js
index f08129568..7ab14f429 100644
--- a/src/components/auth/Pricing.js
+++ b/src/components/auth/Pricing.js
@@ -69,18 +69,29 @@ export default @observer class Signup extends Component {
69 donor.amount ? ( 69 donor.amount ? (
70 <span> 70 <span>
71 <p> 71 <p>
72 Thank you so much for your previous donation of <strong>$ {donor.amount}</strong>. 72 Thank you so much for your previous donation of
73 {' '}
74 <strong>
75 $
76 {donor.amount}
77 </strong>
78 .
73 <br /> 79 <br />
74 Your support allowed us to get where we are today. 80 Your support allowed us to get where we are today.
75 <br /> 81 <br />
76 </p> 82 </p>
77 <p> 83 <p>
78 As an early supporter, you get <strong>a lifetime premium supporter license</strong> without any 84 As an early supporter, you get
85 {' '}
86 <strong>a lifetime premium supporter license</strong>
87 {' '}
88 without any
79 additional charges. 89 additional charges.
80 </p> 90 </p>
81 <p> 91 <p>
82 However, If you want to keep supporting us, you are more than welcome to subscribe to a plan. 92 However, If you want to keep supporting us, you are more than welcome to subscribe to a plan.
83 <br /><br /> 93 <br />
94 <br />
84 </p> 95 </p>
85 </span> 96 </span>
86 ) : ( 97 ) : (
@@ -113,12 +124,6 @@ export default @observer class Signup extends Component {
113 hideInfo={Boolean(donor.amount)} 124 hideInfo={Boolean(donor.amount)}
114 skipButtonLabel={intl.formatMessage(messages.skipPayment)} 125 skipButtonLabel={intl.formatMessage(messages.skipPayment)}
115 /> 126 />
116 {/* <Link
117 to={inviteRoute}
118 className="franz-form__button franz-form__button--secondary auth__button auth__button--skip"
119 >
120 {intl.formatMessage(messages.skipPayment)}
121 </Link> */}
122 </Appear> 127 </Appear>
123 </Loader> 128 </Loader>
124 </form> 129 </form>
diff --git a/src/components/auth/Signup.js b/src/components/auth/Signup.js
index bbcad8b67..d9b83eeb8 100644
--- a/src/components/auth/Signup.js
+++ b/src/components/auth/Signup.js
@@ -199,7 +199,8 @@ export default @observer class Signup extends Component {
199 className="link" 199 className="link"
200 > 200 >
201 {intl.formatMessage(messages.privacy)} 201 {intl.formatMessage(messages.privacy)}
202 </Link>. 202 </Link>
203 .
203 </p> 204 </p>
204 </form> 205 </form>
205 <div className="auth__links"> 206 <div className="auth__links">
diff --git a/src/components/layout/AppLayout.js b/src/components/layout/AppLayout.js
index 3ababe54a..dbe0bb4b6 100644
--- a/src/components/layout/AppLayout.js
+++ b/src/components/layout/AppLayout.js
@@ -6,6 +6,8 @@ import { TitleBar } from 'electron-react-titlebar';
6 6
7import InfoBar from '../ui/InfoBar'; 7import InfoBar from '../ui/InfoBar';
8import { Component as DelayApp } from '../../features/delayApp'; 8import { Component as DelayApp } from '../../features/delayApp';
9import ErrorBoundary from '../util/ErrorBoundary';
10
9import globalMessages from '../../i18n/globalMessages'; 11import globalMessages from '../../i18n/globalMessages';
10 12
11import { isWindows } from '../../environment'; 13import { isWindows } from '../../environment';
@@ -94,74 +96,78 @@ export default @observer class AppLayout extends Component {
94 const { intl } = this.context; 96 const { intl } = this.context;
95 97
96 return ( 98 return (
97 <div className={(darkMode ? 'theme__dark' : '')}> 99 <ErrorBoundary>
98 <div className="app"> 100 <div className={(darkMode ? 'theme__dark' : '')}>
99 {isWindows && !isFullScreen && <TitleBar menu={window.franz.menu.template} icon={'assets/images/logo.svg'} />} 101 <div className="app">
100 <div className="app__content"> 102 {isWindows && !isFullScreen && <TitleBar menu={window.franz.menu.template} icon="assets/images/logo.svg" />}
101 {sidebar} 103 <div className="app__content">
102 <div className="app__service"> 104 {sidebar}
103 {news.length > 0 && news.map(item => ( 105 <div className="app__service">
104 <InfoBar 106 {news.length > 0 && news.map(item => (
105 key={item.id} 107 <InfoBar
106 position="top" 108 key={item.id}
107 type={item.type} 109 position="top"
108 sticky={item.sticky} 110 type={item.type}
109 onHide={() => removeNewsItem({ newsId: item.id })} 111 sticky={item.sticky}
110 > 112 onHide={() => removeNewsItem({ newsId: item.id })}
111 <span dangerouslySetInnerHTML={createMarkup(item.message)} /> 113 >
112 </InfoBar> 114 <span dangerouslySetInnerHTML={createMarkup(item.message)} />
113 ))} 115 </InfoBar>
114 {!isOnline && ( 116 ))}
115 <InfoBar 117 {!isOnline && (
116 type="danger" 118 <InfoBar
117 > 119 type="danger"
118 <span className="mdi mdi-flash" /> 120 >
119 {intl.formatMessage(globalMessages.notConnectedToTheInternet)} 121 <span className="mdi mdi-flash" />
120 </InfoBar> 122 {intl.formatMessage(globalMessages.notConnectedToTheInternet)}
121 )} 123 </InfoBar>
122 {!areRequiredRequestsSuccessful && showRequiredRequestsError && ( 124 )}
123 <InfoBar 125 {!areRequiredRequestsSuccessful && showRequiredRequestsError && (
124 type="danger" 126 <InfoBar
125 ctaLabel="Try again" 127 type="danger"
126 ctaLoading={areRequiredRequestsLoading} 128 ctaLabel="Try again"
127 sticky 129 ctaLoading={areRequiredRequestsLoading}
128 onClick={retryRequiredRequests} 130 sticky
129 > 131 onClick={retryRequiredRequests}
130 <span className="mdi mdi-flash" /> 132 >
131 {intl.formatMessage(messages.requiredRequestsFailed)} 133 <span className="mdi mdi-flash" />
132 </InfoBar> 134 {intl.formatMessage(messages.requiredRequestsFailed)}
133 )} 135 </InfoBar>
134 {showServicesUpdatedInfoBar && ( 136 )}
135 <InfoBar 137 {showServicesUpdatedInfoBar && (
136 type="primary" 138 <InfoBar
137 ctaLabel={intl.formatMessage(messages.buttonReloadServices)} 139 type="primary"
138 onClick={reloadServicesAfterUpdate} 140 ctaLabel={intl.formatMessage(messages.buttonReloadServices)}
139 sticky 141 onClick={reloadServicesAfterUpdate}
140 > 142 sticky
141 <span className="mdi mdi-power-plug" /> 143 >
142 {intl.formatMessage(messages.servicesUpdated)} 144 <span className="mdi mdi-power-plug" />
143 </InfoBar> 145 {intl.formatMessage(messages.servicesUpdated)}
144 )} 146 </InfoBar>
145 {appUpdateIsDownloaded && ( 147 )}
146 <InfoBar 148 {appUpdateIsDownloaded && (
147 type="primary" 149 <InfoBar
148 ctaLabel={intl.formatMessage(messages.buttonInstallUpdate)} 150 type="primary"
149 onClick={installAppUpdate} 151 ctaLabel={intl.formatMessage(messages.buttonInstallUpdate)}
150 sticky 152 onClick={installAppUpdate}
151 > 153 sticky
152 <span className="mdi mdi-information" /> 154 >
153 {intl.formatMessage(messages.updateAvailable)} <a href="https://meetfranz.com/changelog" target="_blank"> 155 <span className="mdi mdi-information" />
154 <u>{intl.formatMessage(messages.changelog)}</u> 156 {intl.formatMessage(messages.updateAvailable)}
155 </a> 157 {' '}
156 </InfoBar> 158 <a href="https://meetfranz.com/changelog" target="_blank">
157 )} 159 <u>{intl.formatMessage(messages.changelog)}</u>
158 {isDelayAppScreenVisible && (<DelayApp />)} 160 </a>
159 {services} 161 </InfoBar>
162 )}
163 {isDelayAppScreenVisible && (<DelayApp />)}
164 {services}
165 </div>
160 </div> 166 </div>
161 </div> 167 </div>
168 {children}
162 </div> 169 </div>
163 {children} 170 </ErrorBoundary>
164 </div>
165 ); 171 );
166 } 172 }
167} 173}
diff --git a/src/components/layout/Sidebar.js b/src/components/layout/Sidebar.js
index 6ea95bf88..609a3b604 100644
--- a/src/components/layout/Sidebar.js
+++ b/src/components/layout/Sidebar.js
@@ -65,6 +65,7 @@ export default @observer class Sidebar extends Component {
65 disableToolTip={() => this.disableToolTip()} 65 disableToolTip={() => this.disableToolTip()}
66 /> 66 />
67 <button 67 <button
68 type="button"
68 onClick={toggleMuteApp} 69 onClick={toggleMuteApp}
69 className={`sidebar__button sidebar__button--audio ${isAppMuted ? 'is-muted' : ''}`} 70 className={`sidebar__button sidebar__button--audio ${isAppMuted ? 'is-muted' : ''}`}
70 data-tip={`${intl.formatMessage(isAppMuted ? messages.unmute : messages.mute)} (${ctrlKey}+Shift+M)`} 71 data-tip={`${intl.formatMessage(isAppMuted ? messages.unmute : messages.mute)} (${ctrlKey}+Shift+M)`}
@@ -72,6 +73,7 @@ export default @observer class Sidebar extends Component {
72 <i className={`mdi mdi-bell${isAppMuted ? '-off' : ''}`} /> 73 <i className={`mdi mdi-bell${isAppMuted ? '-off' : ''}`} />
73 </button> 74 </button>
74 <button 75 <button
76 type="button"
75 onClick={() => openSettings({ path: 'recipes' })} 77 onClick={() => openSettings({ path: 'recipes' })}
76 className="sidebar__button sidebar__button--new-service" 78 className="sidebar__button sidebar__button--new-service"
77 data-tip={`${intl.formatMessage(messages.addNewService)} (${ctrlKey}+N)`} 79 data-tip={`${intl.formatMessage(messages.addNewService)} (${ctrlKey}+N)`}
@@ -79,6 +81,7 @@ export default @observer class Sidebar extends Component {
79 <i className="mdi mdi-plus-box" /> 81 <i className="mdi mdi-plus-box" />
80 </button> 82 </button>
81 <button 83 <button
84 type="button"
82 onClick={() => openSettings({ path: 'app' })} 85 onClick={() => openSettings({ path: 'app' })}
83 className="sidebar__button sidebar__button--settings" 86 className="sidebar__button sidebar__button--settings"
84 data-tip={`${intl.formatMessage(messages.settings)} (${ctrlKey}+,)`} 87 data-tip={`${intl.formatMessage(messages.settings)} (${ctrlKey}+,)`}
diff --git a/src/components/services/content/ErrorHandlers/WebviewErrorHandler.js b/src/components/services/content/ErrorHandlers/WebviewErrorHandler.js
new file mode 100644
index 000000000..415a8d1b5
--- /dev/null
+++ b/src/components/services/content/ErrorHandlers/WebviewErrorHandler.js
@@ -0,0 +1,84 @@
1import React, { Component } from 'react';
2import PropTypes from 'prop-types';
3import { observer } from 'mobx-react';
4import { defineMessages, intlShape } from 'react-intl';
5import injectSheet from 'react-jss';
6
7import Button from '../../../ui/Button';
8
9import styles from './styles';
10
11const messages = defineMessages({
12 headline: {
13 id: 'service.errorHandler.headline',
14 defaultMessage: '!!!Oh no!',
15 },
16 text: {
17 id: 'service.errorHandler.text',
18 defaultMessage: '!!!{name} has failed to load.',
19 },
20 action: {
21 id: 'service.errorHandler.action',
22 defaultMessage: '!!!Reload {name}',
23 },
24 editAction: {
25 id: 'service.errorHandler.editAction',
26 defaultMessage: '!!!Edit {name}',
27 },
28 errorMessage: {
29 id: 'service.errorHandler.message',
30 defaultMessage: '!!!Error:',
31 },
32});
33
34export default @injectSheet(styles) @observer class WebviewCrashHandler extends Component {
35 static propTypes = {
36 name: PropTypes.string.isRequired,
37 reload: PropTypes.func.isRequired,
38 edit: PropTypes.func.isRequired,
39 errorMessage: PropTypes.string.isRequired,
40 classes: PropTypes.object.isRequired,
41 };
42
43 static contextTypes = {
44 intl: intlShape,
45 };
46
47 render() {
48 const {
49 name,
50 reload,
51 edit,
52 errorMessage,
53 classes,
54 } = this.props;
55 const { intl } = this.context;
56
57 return (
58 <div className={classes.component}>
59 <h1>{intl.formatMessage(messages.headline)}</h1>
60 <p>{intl.formatMessage(messages.text, { name })}</p>
61 <p>
62 <strong>
63 {intl.formatMessage(messages.errorMessage)}
64:
65 </strong>
66 {' '}
67 {errorMessage}
68 </p>
69 <div className={classes.buttonContainer}>
70 <Button
71 label={intl.formatMessage(messages.editAction, { name })}
72 buttonType="inverted"
73 onClick={() => edit()}
74 />
75 <Button
76 label={intl.formatMessage(messages.action, { name })}
77 buttonType="inverted"
78 onClick={() => reload()}
79 />
80 </div>
81 </div>
82 );
83 }
84}
diff --git a/src/components/services/content/ErrorHandlers/styles.js b/src/components/services/content/ErrorHandlers/styles.js
new file mode 100644
index 000000000..f11386798
--- /dev/null
+++ b/src/components/services/content/ErrorHandlers/styles.js
@@ -0,0 +1,25 @@
1export default {
2 component: {
3 left: 0,
4 position: 'absolute',
5 top: 0,
6 width: '100%',
7 zIndex: 0,
8 alignItems: 'center',
9 // background: $theme-gray-lighter;
10 display: 'flex',
11 flexDirection: 'column',
12 justifyContent: 'center',
13 textAlign: 'center',
14 },
15 buttonContainer: {
16 display: 'flex',
17 flexDirection: 'row',
18 height: 'auto',
19 margin: [40, 0, 20],
20
21 '& button': {
22 margin: [0, 10, 0, 10],
23 },
24 },
25};
diff --git a/src/components/services/content/ServiceDisabled.js b/src/components/services/content/ServiceDisabled.js
index 58fb38d8c..d0f12256e 100644
--- a/src/components/services/content/ServiceDisabled.js
+++ b/src/components/services/content/ServiceDisabled.js
@@ -27,6 +27,7 @@ export default @observer class ServiceDisabled extends Component {
27 }; 27 };
28 28
29 countdownInterval = null; 29 countdownInterval = null;
30
30 countdownIntervalTimeout = 1000; 31 countdownIntervalTimeout = 1000;
31 32
32 render() { 33 render() {
diff --git a/src/components/services/content/ServiceWebview.js b/src/components/services/content/ServiceWebview.js
index 7163209ee..b1a2c0207 100644
--- a/src/components/services/content/ServiceWebview.js
+++ b/src/components/services/content/ServiceWebview.js
@@ -1,4 +1,4 @@
1import React, { Component } from 'react'; 1import React, { Component, Fragment } from 'react';
2import PropTypes from 'prop-types'; 2import PropTypes from 'prop-types';
3import { autorun } from 'mobx'; 3import { autorun } from 'mobx';
4import { observer } from 'mobx-react'; 4import { observer } from 'mobx-react';
@@ -7,7 +7,9 @@ import classnames from 'classnames';
7 7
8import ServiceModel from '../../../models/Service'; 8import ServiceModel from '../../../models/Service';
9import StatusBarTargetUrl from '../../ui/StatusBarTargetUrl'; 9import StatusBarTargetUrl from '../../ui/StatusBarTargetUrl';
10import WebviewLoader from '../../ui/WebviewLoader';
10import WebviewCrashHandler from './WebviewCrashHandler'; 11import WebviewCrashHandler from './WebviewCrashHandler';
12import WebviewErrorHandler from './ErrorHandlers/WebviewErrorHandler';
11import ServiceDisabled from './ServiceDisabled'; 13import ServiceDisabled from './ServiceDisabled';
12 14
13export default @observer class ServiceWebview extends Component { 15export default @observer class ServiceWebview extends Component {
@@ -15,8 +17,10 @@ export default @observer class ServiceWebview extends Component {
15 service: PropTypes.instanceOf(ServiceModel).isRequired, 17 service: PropTypes.instanceOf(ServiceModel).isRequired,
16 setWebviewReference: PropTypes.func.isRequired, 18 setWebviewReference: PropTypes.func.isRequired,
17 reload: PropTypes.func.isRequired, 19 reload: PropTypes.func.isRequired,
20 edit: PropTypes.func.isRequired,
18 isAppMuted: PropTypes.bool.isRequired, 21 isAppMuted: PropTypes.bool.isRequired,
19 enable: PropTypes.func.isRequired, 22 enable: PropTypes.func.isRequired,
23 isActive: PropTypes.bool,
20 }; 24 };
21 25
22 static defaultProps = { 26 static defaultProps = {
@@ -29,8 +33,12 @@ export default @observer class ServiceWebview extends Component {
29 statusBarVisible: false, 33 statusBarVisible: false,
30 }; 34 };
31 35
36 autorunDisposer = null;
37
38 webview = null;
39
32 componentDidMount() { 40 componentDidMount() {
33 autorun(() => { 41 this.autorunDisposer = autorun(() => {
34 if (this.props.service.isActive) { 42 if (this.props.service.isActive) {
35 this.setState({ forceRepaint: true }); 43 this.setState({ forceRepaint: true });
36 setTimeout(() => { 44 setTimeout(() => {
@@ -40,6 +48,10 @@ export default @observer class ServiceWebview extends Component {
40 }); 48 });
41 } 49 }
42 50
51 componentWillUnmount() {
52 this.autorunDisposer();
53 }
54
43 updateTargetUrl = (event) => { 55 updateTargetUrl = (event) => {
44 let visible = true; 56 let visible = true;
45 if (event.url === '' || event.url === '#') { 57 if (event.url === '' || event.url === '#') {
@@ -51,13 +63,12 @@ export default @observer class ServiceWebview extends Component {
51 }); 63 });
52 } 64 }
53 65
54 webview = null;
55
56 render() { 66 render() {
57 const { 67 const {
58 service, 68 service,
59 setWebviewReference, 69 setWebviewReference,
60 reload, 70 reload,
71 edit,
61 isAppMuted, 72 isAppMuted,
62 enable, 73 enable,
63 } = this.props; 74 } = this.props;
@@ -78,25 +89,47 @@ export default @observer class ServiceWebview extends Component {
78 89
79 return ( 90 return (
80 <div className={webviewClasses}> 91 <div className={webviewClasses}>
81 {service.hasCrashed && ( 92 {service.isActive && service.isEnabled && (
82 <WebviewCrashHandler 93 <Fragment>
83 name={service.recipe.name} 94 {service.hasCrashed && (
84 webview={service.webview} 95 <WebviewCrashHandler
85 reload={reload} 96 name={service.recipe.name}
86 /> 97 webview={service.webview}
98 reload={reload}
99 />
100 )}
101 {service.isEnabled && service.isLoading && service.isFirstLoad && (
102 <WebviewLoader
103 loaded={false}
104 name={service.name}
105 />
106 )}
107 {service.isError && (
108 <WebviewErrorHandler
109 name={service.recipe.name}
110 errorMessage={service.errorMessage}
111 reload={reload}
112 edit={edit}
113 />
114 )}
115 </Fragment>
87 )} 116 )}
88 {!service.isEnabled ? ( 117 {!service.isEnabled ? (
89 <ServiceDisabled 118 <Fragment>
90 name={service.recipe.name} 119 {service.isActive && (
91 webview={service.webview} 120 <ServiceDisabled
92 enable={enable} 121 name={service.recipe.name}
93 /> 122 webview={service.webview}
123 enable={enable}
124 />
125 )}
126 </Fragment>
94 ) : ( 127 ) : (
95 <Webview 128 <Webview
96 ref={(element) => { this.webview = element; }} 129 ref={(element) => { this.webview = element; }}
97 autosize 130 autosize
98 src={service.url} 131 src={service.url}
99 preload="./webview/plugin.js" 132 preload="./webview/recipe.js"
100 partition={`persist:service-${service.id}`} 133 partition={`persist:service-${service.id}`}
101 onDidAttach={() => setWebviewReference({ 134 onDidAttach={() => setWebviewReference({
102 serviceId: service.id, 135 serviceId: service.id,
diff --git a/src/components/services/content/Services.js b/src/components/services/content/Services.js
index 4cbd51043..1aeb17e03 100644
--- a/src/components/services/content/Services.js
+++ b/src/components/services/content/Services.js
@@ -20,18 +20,18 @@ const messages = defineMessages({
20 20
21export default @observer class Services extends Component { 21export default @observer class Services extends Component {
22 static propTypes = { 22 static propTypes = {
23 services: MobxPropTypes.arrayOrObservableArray.isRequired, 23 services: MobxPropTypes.arrayOrObservableArray,
24 setWebviewReference: PropTypes.func.isRequired, 24 setWebviewReference: PropTypes.func.isRequired,
25 handleIPCMessage: PropTypes.func.isRequired, 25 handleIPCMessage: PropTypes.func.isRequired,
26 openWindow: PropTypes.func.isRequired, 26 openWindow: PropTypes.func.isRequired,
27 reload: PropTypes.func.isRequired, 27 reload: PropTypes.func.isRequired,
28 openSettings: PropTypes.func.isRequired,
28 isAppMuted: PropTypes.bool.isRequired, 29 isAppMuted: PropTypes.bool.isRequired,
29 update: PropTypes.func.isRequired, 30 update: PropTypes.func.isRequired,
30 }; 31 };
31 32
32 static defaultProps = { 33 static defaultProps = {
33 services: [], 34 services: [],
34 activeService: '',
35 }; 35 };
36 36
37 static contextTypes = { 37 static contextTypes = {
@@ -45,6 +45,7 @@ export default @observer class Services extends Component {
45 setWebviewReference, 45 setWebviewReference,
46 openWindow, 46 openWindow,
47 reload, 47 reload,
48 openSettings,
48 isAppMuted, 49 isAppMuted,
49 update, 50 update,
50 } = this.props; 51 } = this.props;
@@ -79,6 +80,7 @@ export default @observer class Services extends Component {
79 setWebviewReference={setWebviewReference} 80 setWebviewReference={setWebviewReference}
80 openWindow={openWindow} 81 openWindow={openWindow}
81 reload={() => reload({ serviceId: service.id })} 82 reload={() => reload({ serviceId: service.id })}
83 edit={() => openSettings({ path: `services/edit/${service.id}` })}
82 isAppMuted={isAppMuted} 84 isAppMuted={isAppMuted}
83 enable={() => update({ 85 enable={() => update({
84 serviceId: service.id, 86 serviceId: service.id,
diff --git a/src/components/services/content/WebviewCrashHandler.js b/src/components/services/content/WebviewCrashHandler.js
index 3be1fccf4..42bc3c877 100644
--- a/src/components/services/content/WebviewCrashHandler.js
+++ b/src/components/services/content/WebviewCrashHandler.js
@@ -38,13 +38,18 @@ export default @observer class WebviewCrashHandler extends Component {
38 countdown: 10000, 38 countdown: 10000,
39 } 39 }
40 40
41 countdownInterval = null;
42
43 countdownIntervalTimeout = 1000;
44
45
41 componentDidMount() { 46 componentDidMount() {
42 const { reload } = this.props; 47 const { reload } = this.props;
43 48
44 this.countdownInterval = setInterval(() => { 49 this.countdownInterval = setInterval(() => {
45 this.setState({ 50 this.setState(prevState => ({
46 countdown: this.state.countdown - this.countdownIntervalTimeout, 51 countdown: prevState.countdown - this.countdownIntervalTimeout,
47 }); 52 }));
48 53
49 if (this.state.countdown <= 0) { 54 if (this.state.countdown <= 0) {
50 reload(); 55 reload();
@@ -53,9 +58,6 @@ export default @observer class WebviewCrashHandler extends Component {
53 }, this.countdownIntervalTimeout); 58 }, this.countdownIntervalTimeout);
54 } 59 }
55 60
56 countdownInterval = null;
57 countdownIntervalTimeout = 1000;
58
59 render() { 61 render() {
60 const { name, reload } = this.props; 62 const { name, reload } = this.props;
61 const { intl } = this.context; 63 const { intl } = this.context;
@@ -70,10 +72,12 @@ export default @observer class WebviewCrashHandler extends Component {
70 buttonType="inverted" 72 buttonType="inverted"
71 onClick={() => reload()} 73 onClick={() => reload()}
72 /> 74 />
73 <p className="footnote">{intl.formatMessage(messages.autoReload, { 75 <p className="footnote">
74 name, 76 {intl.formatMessage(messages.autoReload, {
75 seconds: this.state.countdown / 1000, 77 name,
76 })}</p> 78 seconds: this.state.countdown / 1000,
79 })}
80 </p>
77 </div> 81 </div>
78 ); 82 );
79 } 83 }
diff --git a/src/components/settings/SettingsLayout.js b/src/components/settings/SettingsLayout.js
index 3cb08feb1..72ba7b2e3 100644
--- a/src/components/settings/SettingsLayout.js
+++ b/src/components/settings/SettingsLayout.js
@@ -2,6 +2,7 @@ import React, { Component } from 'react';
2import PropTypes from 'prop-types'; 2import PropTypes from 'prop-types';
3import { observer } from 'mobx-react'; 3import { observer } from 'mobx-react';
4 4
5import ErrorBoundary from '../util/ErrorBoundary';
5import { oneOrManyChildElements } from '../../prop-types'; 6import { oneOrManyChildElements } from '../../prop-types';
6import Appear from '../ui/effects/Appear'; 7import Appear from '../ui/effects/Appear';
7 8
@@ -36,18 +37,22 @@ export default @observer class SettingsLayout extends Component {
36 return ( 37 return (
37 <Appear transitionName="fadeIn-fast"> 38 <Appear transitionName="fadeIn-fast">
38 <div className="settings-wrapper"> 39 <div className="settings-wrapper">
39 <button 40 <ErrorBoundary>
40 className="settings-wrapper__action"
41 onClick={closeSettings}
42 />
43 <div className="settings franz-form">
44 {navigation}
45 {children}
46 <button 41 <button
47 className="settings__close mdi mdi-close" 42 type="button"
43 className="settings-wrapper__action"
48 onClick={closeSettings} 44 onClick={closeSettings}
49 /> 45 />
50 </div> 46 <div className="settings franz-form">
47 {navigation}
48 {children}
49 <button
50 type="button"
51 className="settings__close mdi mdi-close"
52 onClick={closeSettings}
53 />
54 </div>
55 </ErrorBoundary>
51 </div> 56 </div>
52 </Appear> 57 </Appear>
53 ); 58 );
diff --git a/src/components/settings/account/AccountDashboard.js b/src/components/settings/account/AccountDashboard.js
index 06c7074dd..9c9543749 100644
--- a/src/components/settings/account/AccountDashboard.js
+++ b/src/components/settings/account/AccountDashboard.js
@@ -1,4 +1,4 @@
1import React, { Component } from 'react'; 1import React, { Component, Fragment } from 'react';
2import PropTypes from 'prop-types'; 2import PropTypes from 'prop-types';
3import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; 3import { observer, PropTypes as MobxPropTypes } from 'mobx-react';
4import { defineMessages, intlShape } from 'react-intl'; 4import { defineMessages, intlShape } from 'react-intl';
@@ -132,21 +132,19 @@ export default @observer class AccountDashboard extends Component {
132 )} 132 )}
133 133
134 {!isLoading && userInfoRequestFailed && ( 134 {!isLoading && userInfoRequestFailed && (
135 <div> 135 <Infobox
136 <Infobox 136 icon="alert"
137 icon="alert" 137 type="danger"
138 type="danger" 138 ctaLabel={intl.formatMessage(messages.tryReloadUserInfoRequest)}
139 ctaLabel={intl.formatMessage(messages.tryReloadUserInfoRequest)} 139 ctaLoading={isLoading}
140 ctaLoading={isLoading} 140 ctaOnClick={retryUserInfoRequest}
141 ctaOnClick={retryUserInfoRequest} 141 >
142 > 142 {intl.formatMessage(messages.userInfoRequestFailed)}
143 {intl.formatMessage(messages.userInfoRequestFailed)} 143 </Infobox>
144 </Infobox>
145 </div>
146 )} 144 )}
147 145
148 {!userInfoRequestFailed && ( 146 {!userInfoRequestFailed && (
149 <div> 147 <Fragment>
150 {!isLoading && ( 148 {!isLoading && (
151 <div className="account"> 149 <div className="account">
152 <div className="account__box account__box--flex"> 150 <div className="account__box account__box--flex">
@@ -169,7 +167,8 @@ export default @observer class AccountDashboard extends Component {
169 {`${user.firstname} ${user.lastname}`} 167 {`${user.firstname} ${user.lastname}`}
170 </h2> 168 </h2>
171 {user.organization && `${user.organization}, `} 169 {user.organization && `${user.organization}, `}
172 {user.email}<br /> 170 {user.email}
171 <br />
173 {!user.isEnterprise && !user.isPremium && ( 172 {!user.isEnterprise && !user.isPremium && (
174 <span className="badge badge">{intl.formatMessage(messages.accountTypeBasic)}</span> 173 <span className="badge badge">{intl.formatMessage(messages.accountTypeBasic)}</span>
175 )} 174 )}
@@ -194,7 +193,7 @@ export default @observer class AccountDashboard extends Component {
194 ) : ( 193 ) : (
195 <div className="account franz-form"> 194 <div className="account franz-form">
196 {orders.length > 0 && ( 195 {orders.length > 0 && (
197 <div> 196 <Fragment>
198 <div className="account__box"> 197 <div className="account__box">
199 <h2>{intl.formatMessage(messages.headlineSubscription)}</h2> 198 <h2>{intl.formatMessage(messages.headlineSubscription)}</h2>
200 <div className="account__subscription"> 199 <div className="account__subscription">
@@ -219,6 +218,7 @@ export default @observer class AccountDashboard extends Component {
219 </td> 218 </td>
220 <td className="invoices__action"> 219 <td className="invoices__action">
221 <button 220 <button
221 type="button"
222 onClick={() => openExternalUrl(order.invoiceUrl)} 222 onClick={() => openExternalUrl(order.invoiceUrl)}
223 > 223 >
224 {intl.formatMessage(messages.invoiceDownload)} 224 {intl.formatMessage(messages.invoiceDownload)}
@@ -229,7 +229,7 @@ export default @observer class AccountDashboard extends Component {
229 </tbody> 229 </tbody>
230 </table> 230 </table>
231 </div> 231 </div>
232 </div> 232 </Fragment>
233 )} 233 )}
234 </div> 234 </div>
235 ) 235 )
@@ -262,20 +262,6 @@ export default @observer class AccountDashboard extends Component {
262 </div> 262 </div>
263 )} 263 )}
264 264
265 {user.isMiner && (
266 <div className="account franz-form">
267 <div className="account__box account__box">
268 <h2>Miner Info</h2>
269 <div className="account__subscription">
270 <div>
271 <p>To maintain a high security level for all our Franz users, we had to remove the miner. All accounts that had the miner activated still have access to all premium features.</p>
272 <p>Every financial support is still much appreciated.</p>
273 </div>
274 </div>
275 </div>
276 </div>
277 )}
278
279 {!user.isEnterprise && !user.isPremium && ( 265 {!user.isEnterprise && !user.isPremium && (
280 isLoadingPlans ? ( 266 isLoadingPlans ? (
281 <Loader /> 267 <Loader />
@@ -312,7 +298,7 @@ export default @observer class AccountDashboard extends Component {
312 </div> 298 </div>
313 </div> 299 </div>
314 )} 300 )}
315 </div> 301 </Fragment>
316 )} 302 )}
317 </div> 303 </div>
318 <ReactTooltip place="right" type="dark" effect="solid" /> 304 <ReactTooltip place="right" type="dark" effect="solid" />
diff --git a/src/components/settings/navigation/SettingsNavigation.js b/src/components/settings/navigation/SettingsNavigation.js
index b86d94ac7..953f702f8 100644
--- a/src/components/settings/navigation/SettingsNavigation.js
+++ b/src/components/settings/navigation/SettingsNavigation.js
@@ -59,7 +59,9 @@ export default @inject('stores') @observer class SettingsNavigation extends Comp
59 className="settings-navigation__link" 59 className="settings-navigation__link"
60 activeClassName="is-active" 60 activeClassName="is-active"
61 > 61 >
62 {intl.formatMessage(messages.yourServices)} <span className="badge">{serviceCount}</span> 62 {intl.formatMessage(messages.yourServices)}
63 {' '}
64 <span className="badge">{serviceCount}</span>
63 </Link> 65 </Link>
64 <Link 66 <Link
65 to="/settings/user" 67 to="/settings/user"
@@ -93,4 +95,3 @@ export default @inject('stores') @observer class SettingsNavigation extends Comp
93 ); 95 );
94 } 96 }
95} 97}
96
diff --git a/src/components/settings/recipes/RecipeItem.js b/src/components/settings/recipes/RecipeItem.js
index dae8891b3..3bb0852b2 100644
--- a/src/components/settings/recipes/RecipeItem.js
+++ b/src/components/settings/recipes/RecipeItem.js
@@ -15,6 +15,7 @@ export default @observer class RecipeItem extends Component {
15 15
16 return ( 16 return (
17 <button 17 <button
18 type="button"
18 className="recipe-teaser" 19 className="recipe-teaser"
19 onClick={onClick} 20 onClick={onClick}
20 > 21 >
diff --git a/src/components/settings/recipes/RecipesDashboard.js b/src/components/settings/recipes/RecipesDashboard.js
index cd783200f..00cd725cf 100644
--- a/src/components/settings/recipes/RecipesDashboard.js
+++ b/src/components/settings/recipes/RecipesDashboard.js
@@ -129,11 +129,17 @@ export default @observer class RecipesDashboard extends Component {
129 activeClassName={`${!searchNeedle ? 'badge--primary' : ''}`} 129 activeClassName={`${!searchNeedle ? 'badge--primary' : ''}`}
130 onClick={() => resetSearch()} 130 onClick={() => resetSearch()}
131 > 131 >
132 {intl.formatMessage(messages.devRecipes)} ({devRecipesCount}) 132 {intl.formatMessage(messages.devRecipes)}
133 {' '}
134(
135 {devRecipesCount}
136)
133 </Link> 137 </Link>
134 )} 138 )}
135 <a href={FRANZ_SERVICE_REQUEST} target="_blank" className="link recipes__service-request"> 139 <a href={FRANZ_SERVICE_REQUEST} target="_blank" className="link recipes__service-request">
136 {intl.formatMessage(messages.missingService)} <i className="mdi mdi-open-in-new" /> 140 {intl.formatMessage(messages.missingService)}
141 {' '}
142 <i className="mdi mdi-open-in-new" />
137 </a> 143 </a>
138 </div> 144 </div>
139 {/* )} */} 145 {/* )} */}
diff --git a/src/components/settings/services/EditServiceForm.js b/src/components/settings/services/EditServiceForm.js
index d16ec35b8..468d85c45 100644
--- a/src/components/settings/services/EditServiceForm.js
+++ b/src/components/settings/services/EditServiceForm.js
@@ -1,4 +1,4 @@
1import React, { Component } from 'react'; 1import React, { Component, Fragment } from 'react';
2import PropTypes from 'prop-types'; 2import PropTypes from 'prop-types';
3import { observer } from 'mobx-react'; 3import { observer } from 'mobx-react';
4import { Link } from 'react-router'; 4import { Link } from 'react-router';
@@ -14,6 +14,7 @@ import Input from '../../ui/Input';
14import Toggle from '../../ui/Toggle'; 14import Toggle from '../../ui/Toggle';
15import Button from '../../ui/Button'; 15import Button from '../../ui/Button';
16import ImageUpload from '../../ui/ImageUpload'; 16import ImageUpload from '../../ui/ImageUpload';
17import Select from '../../ui/Select';
17 18
18import PremiumFeatureContainer from '../../ui/PremiumFeatureContainer'; 19import PremiumFeatureContainer from '../../ui/PremiumFeatureContainer';
19 20
@@ -96,7 +97,11 @@ const messages = defineMessages({
96 }, 97 },
97 headlineProxy: { 98 headlineProxy: {
98 id: 'settings.service.form.proxy.headline', 99 id: 'settings.service.form.proxy.headline',
99 defaultMessage: '!!!Proxy Settings', 100 defaultMessage: '!!!HTTP/HTTPS Proxy Settings',
101 },
102 proxyRestartInfo: {
103 id: 'settings.service.form.proxy.restartInfo',
104 defaultMessage: '!!!Please restart Franz after changing proxy Settings.',
100 }, 105 },
101 proxyInfo: { 106 proxyInfo: {
102 id: 'settings.service.form.proxy.info', 107 id: 'settings.service.form.proxy.info',
@@ -129,6 +134,7 @@ export default @observer class EditServiceForm extends Component {
129 static defaultProps = { 134 static defaultProps = {
130 service: {}, 135 service: {},
131 }; 136 };
137
132 static contextTypes = { 138 static contextTypes = {
133 intl: intlShape, 139 intl: intlShape,
134 }; 140 };
@@ -270,14 +276,14 @@ export default @observer class EditServiceForm extends Component {
270 {recipe.hasCustomUrl && ( 276 {recipe.hasCustomUrl && (
271 <TabItem title={intl.formatMessage(messages.tabOnPremise)}> 277 <TabItem title={intl.formatMessage(messages.tabOnPremise)}>
272 {user.isPremium || recipe.author.find(a => a.email === user.email) ? ( 278 {user.isPremium || recipe.author.find(a => a.email === user.email) ? (
273 <div> 279 <Fragment>
274 <Input field={form.$('customUrl')} /> 280 <Input field={form.$('customUrl')} />
275 {form.error === 'url-validation-error' && ( 281 {form.error === 'url-validation-error' && (
276 <p className="franz-form__error"> 282 <p className="franz-form__error">
277 {intl.formatMessage(messages.customUrlValidationError, { name: recipe.name })} 283 {intl.formatMessage(messages.customUrlValidationError, { name: recipe.name })}
278 </p> 284 </p>
279 )} 285 )}
280 </div> 286 </Fragment>
281 ) : ( 287 ) : (
282 <div className="center premium-info"> 288 <div className="center premium-info">
283 <p>{intl.formatMessage(messages.customUrlPremiumInfo)}</p> 289 <p>{intl.formatMessage(messages.customUrlPremiumInfo)}</p>
@@ -307,12 +313,12 @@ export default @observer class EditServiceForm extends Component {
307 <h3>{intl.formatMessage(messages.headlineBadges)}</h3> 313 <h3>{intl.formatMessage(messages.headlineBadges)}</h3>
308 <Toggle field={form.$('isBadgeEnabled')} /> 314 <Toggle field={form.$('isBadgeEnabled')} />
309 {recipe.hasIndirectMessages && form.$('isBadgeEnabled').value && ( 315 {recipe.hasIndirectMessages && form.$('isBadgeEnabled').value && (
310 <div> 316 <Fragment>
311 <Toggle field={form.$('isIndirectMessageBadgeEnabled')} /> 317 <Toggle field={form.$('isIndirectMessageBadgeEnabled')} />
312 <p className="settings__help"> 318 <p className="settings__help">
313 {intl.formatMessage(messages.indirectMessageInfo)} 319 {intl.formatMessage(messages.indirectMessageInfo)}
314 </p> 320 </p>
315 </div> 321 </Fragment>
316 )} 322 )}
317 </div> 323 </div>
318 324
@@ -333,6 +339,12 @@ export default @observer class EditServiceForm extends Component {
333 </div> 339 </div>
334 </div> 340 </div>
335 341
342 <PremiumFeatureContainer>
343 <div className="settings__settings-group">
344 <Select field={form.$('spellcheckerLanguage')} />
345 </div>
346 </PremiumFeatureContainer>
347
336 {isProxyFeatureEnabled && ( 348 {isProxyFeatureEnabled && (
337 <PremiumFeatureContainer condition={isProxyFeaturePremiumFeature}> 349 <PremiumFeatureContainer condition={isProxyFeaturePremiumFeature}>
338 <div className="settings__settings-group"> 350 <div className="settings__settings-group">
@@ -342,18 +354,31 @@ export default @observer class EditServiceForm extends Component {
342 </h3> 354 </h3>
343 <Toggle field={form.$('proxy.isEnabled')} /> 355 <Toggle field={form.$('proxy.isEnabled')} />
344 {form.$('proxy.isEnabled').value && ( 356 {form.$('proxy.isEnabled').value && (
345 <div> 357 <Fragment>
346 <Input field={form.$('proxy.host')} /> 358 <div className="grid">
347 <Input field={form.$('proxy.user')} /> 359 <div className="grid__row">
348 <Input 360 <Input field={form.$('proxy.host')} className="proxyHost" />
349 field={form.$('proxy.password')} 361 <Input field={form.$('proxy.port')} />
350 showPasswordToggle 362 </div>
351 /> 363 </div>
364 <div className="grid">
365 <div className="grid__row">
366 <Input field={form.$('proxy.user')} />
367 <Input
368 field={form.$('proxy.password')}
369 showPasswordToggle
370 />
371 </div>
372 </div>
373 <p>
374 <span className="mdi mdi-information" />
375 {intl.formatMessage(messages.proxyRestartInfo)}
376 </p>
352 <p> 377 <p>
353 <span className="mdi mdi-information" /> 378 <span className="mdi mdi-information" />
354 {intl.formatMessage(messages.proxyInfo)} 379 {intl.formatMessage(messages.proxyInfo)}
355 </p> 380 </p>
356 </div> 381 </Fragment>
357 )} 382 )}
358 </div> 383 </div>
359 </PremiumFeatureContainer> 384 </PremiumFeatureContainer>
diff --git a/src/components/settings/services/ServiceItem.js b/src/components/settings/services/ServiceItem.js
index 84080519b..ebc618a00 100644
--- a/src/components/settings/services/ServiceItem.js
+++ b/src/components/settings/services/ServiceItem.js
@@ -27,6 +27,7 @@ export default @observer class ServiceItem extends Component {
27 service: PropTypes.instanceOf(ServiceModel).isRequired, 27 service: PropTypes.instanceOf(ServiceModel).isRequired,
28 goToServiceForm: PropTypes.func.isRequired, 28 goToServiceForm: PropTypes.func.isRequired,
29 }; 29 };
30
30 static contextTypes = { 31 static contextTypes = {
31 intl: intlShape, 32 intl: intlShape,
32 }; 33 };
diff --git a/src/components/settings/services/ServicesDashboard.js b/src/components/settings/services/ServicesDashboard.js
index e7dfaf106..a12df7372 100644
--- a/src/components/settings/services/ServicesDashboard.js
+++ b/src/components/settings/services/ServicesDashboard.js
@@ -101,17 +101,15 @@ export default @observer class ServicesDashboard extends Component {
101 /> 101 />
102 )} 102 )}
103 {!isLoading && servicesRequestFailed && ( 103 {!isLoading && servicesRequestFailed && (
104 <div> 104 <Infobox
105 <Infobox 105 icon="alert"
106 icon="alert" 106 type="danger"
107 type="danger" 107 ctaLabel={intl.formatMessage(messages.tryReloadServices)}
108 ctaLabel={intl.formatMessage(messages.tryReloadServices)} 108 ctaLoading={isLoading}
109 ctaLoading={isLoading} 109 ctaOnClick={retryServicesRequest}
110 ctaOnClick={retryServicesRequest} 110 >
111 > 111 {intl.formatMessage(messages.servicesRequestFailed)}
112 {intl.formatMessage(messages.servicesRequestFailed)} 112 </Infobox>
113 </Infobox>
114 </div>
115 )} 113 )}
116 114
117 {status.length > 0 && status.includes('updated') && ( 115 {status.length > 0 && status.includes('updated') && (
diff --git a/src/components/settings/settings/EditSettingsForm.js b/src/components/settings/settings/EditSettingsForm.js
index 1ec2ab614..a92e559f3 100644
--- a/src/components/settings/settings/EditSettingsForm.js
+++ b/src/components/settings/settings/EditSettingsForm.js
@@ -1,5 +1,5 @@
1import { remote } from 'electron'; 1import { remote } from 'electron';
2import React, { Component } from 'react'; 2import React, { Component, Fragment } from 'react';
3import PropTypes from 'prop-types'; 3import PropTypes from 'prop-types';
4import { observer } from 'mobx-react'; 4import { observer } from 'mobx-react';
5import { defineMessages, intlShape } from 'react-intl'; 5import { defineMessages, intlShape } from 'react-intl';
@@ -171,21 +171,23 @@ export default @observer class EditSettingsForm extends Component {
171 <PremiumFeatureContainer 171 <PremiumFeatureContainer
172 condition={isSpellcheckerPremiumFeature} 172 condition={isSpellcheckerPremiumFeature}
173 > 173 >
174 <div> 174 <Fragment>
175 <Toggle 175 <Toggle
176 field={form.$('enableSpellchecking')} 176 field={form.$('enableSpellchecking')}
177 /> 177 />
178 {form.$('enableSpellchecking').value && ( 178 {form.$('enableSpellchecking').value && (
179 <Select field={form.$('spellcheckerLanguage')} /> 179 <Select field={form.$('spellcheckerLanguage')} />
180 )} 180 )}
181 </div> 181 </Fragment>
182 </PremiumFeatureContainer> 182 </PremiumFeatureContainer>
183 <a 183 <a
184 href={FRANZ_TRANSLATION} 184 href={FRANZ_TRANSLATION}
185 target="_blank" 185 target="_blank"
186 className="link" 186 className="link"
187 > 187 >
188 {intl.formatMessage(messages.translationHelp)} <i className="mdi mdi-open-in-new" /> 188 {intl.formatMessage(messages.translationHelp)}
189 {' '}
190 <i className="mdi mdi-open-in-new" />
189 </a> 191 </a>
190 192
191 {/* Advanced */} 193 {/* Advanced */}
@@ -233,7 +235,9 @@ export default @observer class EditSettingsForm extends Component {
233 )} 235 )}
234 <br /> 236 <br />
235 <Toggle field={form.$('beta')} /> 237 <Toggle field={form.$('beta')} />
236 {intl.formatMessage(messages.currentVersion)} {remote.app.getVersion()} 238 {intl.formatMessage(messages.currentVersion)}
239 {' '}
240 {remote.app.getVersion()}
237 </form> 241 </form>
238 </div> 242 </div>
239 </div> 243 </div>
diff --git a/src/components/settings/user/EditUserForm.js b/src/components/settings/user/EditUserForm.js
index b825f844a..0e3ac6b10 100644
--- a/src/components/settings/user/EditUserForm.js
+++ b/src/components/settings/user/EditUserForm.js
@@ -48,10 +48,6 @@ export default @observer class EditServiceForm extends Component {
48 isEnterprise: PropTypes.bool.isRequired, 48 isEnterprise: PropTypes.bool.isRequired,
49 }; 49 };
50 50
51 static defaultProps = {
52 service: {},
53 };
54
55 static contextTypes = { 51 static contextTypes = {
56 intl: intlShape, 52 intl: intlShape,
57 }; 53 };
diff --git a/src/components/subscription/SubscriptionForm.js b/src/components/subscription/SubscriptionForm.js
index 12e8471ff..90da8ddc3 100644
--- a/src/components/subscription/SubscriptionForm.js
+++ b/src/components/subscription/SubscriptionForm.js
@@ -1,4 +1,4 @@
1import React, { Component } from 'react'; 1import React, { Component, Fragment } from 'react';
2import PropTypes from 'prop-types'; 2import PropTypes from 'prop-types';
3import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; 3import { observer, PropTypes as MobxPropTypes } from 'mobx-react';
4import { defineMessages, intlShape } from 'react-intl'; 4import { defineMessages, intlShape } from 'react-intl';
@@ -81,8 +81,7 @@ export default @observer class SubscriptionForm extends Component {
81 hideInfo: PropTypes.bool.isRequired, 81 hideInfo: PropTypes.bool.isRequired,
82 }; 82 };
83 83
84 static defaultProps ={ 84 static defaultProps = {
85 content: '',
86 showSkipOption: false, 85 showSkipOption: false,
87 skipAction: () => null, 86 skipAction: () => null,
88 skipButtonLabel: '', 87 skipButtonLabel: '',
@@ -158,35 +157,33 @@ export default @observer class SubscriptionForm extends Component {
158 <Radio field={this.form.$('paymentTier')} showLabel={false} className="paymentTiers" /> 157 <Radio field={this.form.$('paymentTier')} showLabel={false} className="paymentTiers" />
159 {!hideInfo && ( 158 {!hideInfo && (
160 <div className="subscription__premium-info"> 159 <div className="subscription__premium-info">
161 <div> 160 <p>
162 <p> 161 <strong>{intl.formatMessage(messages.includedFeatures)}</strong>
163 <strong>{intl.formatMessage(messages.includedFeatures)}</strong> 162 </p>
164 </p> 163 <div className="subscription">
165 <div className="subscription"> 164 <ul className="subscription__premium-features">
166 <ul className="subscription__premium-features"> 165 <li>{intl.formatMessage(messages.features.onpremise)}</li>
167 <li>{intl.formatMessage(messages.features.onpremise)}</li> 166 <li>
168 <li> 167 {intl.formatMessage(messages.features.noInterruptions)}
169 {intl.formatMessage(messages.features.noInterruptions)} 168 </li>
170 </li> 169 <li>
171 <li> 170 {intl.formatMessage(messages.features.spellchecker)}
172 {intl.formatMessage(messages.features.spellchecker)} 171 </li>
173 </li> 172 <li>
174 <li> 173 {intl.formatMessage(messages.features.proxy)}
175 {intl.formatMessage(messages.features.proxy)} 174 </li>
176 </li> 175 <li>
177 <li> 176 {intl.formatMessage(messages.features.ads)}
178 {intl.formatMessage(messages.features.ads)} 177 </li>
179 </li> 178 </ul>
180 </ul>
181 </div>
182 </div> 179 </div>
183 </div> 180 </div>
184 )} 181 )}
185 <div> 182 <Fragment>
186 {error.code === 'no-payment-session' && ( 183 {error.code === 'no-payment-session' && (
187 <p className="error-message center">{intl.formatMessage(messages.paymentSessionError)}</p> 184 <p className="error-message center">{intl.formatMessage(messages.paymentSessionError)}</p>
188 )} 185 )}
189 </div> 186 </Fragment>
190 {showSkipOption && this.form.$('paymentTier').value === 'skip' ? ( 187 {showSkipOption && this.form.$('paymentTier').value === 'skip' ? (
191 <Button 188 <Button
192 label={skipButtonLabel} 189 label={skipButtonLabel}
diff --git a/src/components/subscription/SubscriptionPopup.js b/src/components/subscription/SubscriptionPopup.js
index f3c63e7ee..b5d7c4b2d 100644
--- a/src/components/subscription/SubscriptionPopup.js
+++ b/src/components/subscription/SubscriptionPopup.js
@@ -46,7 +46,9 @@ export default @observer class SubscriptionPopup extends Component {
46 } 46 }
47 47
48 render() { 48 render() {
49 const { url, closeWindow, completeCheck, isCompleted } = this.props; 49 const {
50 url, closeWindow, completeCheck, isCompleted,
51 } = this.props;
50 const { intl } = this.context; 52 const { intl } = this.context;
51 53
52 return ( 54 return (
diff --git a/src/components/ui/AppLoader.js b/src/components/ui/AppLoader.js
deleted file mode 100644
index ac3cdcb05..000000000
--- a/src/components/ui/AppLoader.js
+++ /dev/null
@@ -1,15 +0,0 @@
1import React from 'react';
2
3import Appear from '../../components/ui/effects/Appear';
4import Loader from '../../components/ui/Loader';
5
6export default function () {
7 return (
8 <div className="app-loader">
9 <Appear>
10 <h1 className="app-loader__title">Franz</h1>
11 <Loader color="#FFF" />
12 </Appear>
13 </div>
14 );
15}
diff --git a/src/components/ui/AppLoader/index.js b/src/components/ui/AppLoader/index.js
new file mode 100644
index 000000000..61053f6d1
--- /dev/null
+++ b/src/components/ui/AppLoader/index.js
@@ -0,0 +1,70 @@
1import React, { Component } from 'react';
2import PropTypes from 'prop-types';
3import injectSheet, { withTheme } from 'react-jss';
4import classnames from 'classnames';
5
6import FullscreenLoader from '../FullscreenLoader';
7import { shuffleArray } from '../../../helpers/array-helpers';
8
9import styles from './styles';
10
11const textList = shuffleArray([
12 'Looking for Sisi',
13 'Contacting the herald',
14 'Saddling the unicorn',
15 'Learning the Waltz',
16 'Visiting Horst & Grete',
17 'Twisting my moustache',
18 'Playing the trumpet',
19 'Traveling through space & time',
20]);
21
22export default @injectSheet(styles) @withTheme class AppLoader extends Component {
23 static propTypes = {
24 classes: PropTypes.object.isRequired,
25 theme: PropTypes.object.isRequired,
26 }
27
28 state = {
29 step: 0,
30 }
31
32 interval = null;
33
34 componentDidMount() {
35 this.interval = setInterval(() => {
36 this.setState(prevState => ({
37 step: prevState.step === textList.length - 1 ? 0 : prevState.step + 1,
38 }));
39 }, 2500);
40 }
41
42 componentWillUnmount() {
43 clearInterval(this.interval);
44 }
45
46 render() {
47 const { classes, theme } = this.props;
48 const { step } = this.state;
49
50 return (
51 <FullscreenLoader
52 title="Franz"
53 className={classes.component}
54 spinnerColor={theme.colorAppLoaderSpinner}
55 >
56 {textList.map((text, i) => (
57 <span
58 key={text}
59 className={classnames({
60 [`${classes.slogan}`]: true,
61 [`${classes.visible}`]: step === i,
62 })}
63 >
64 {text}
65 </span>
66 ))}
67 </FullscreenLoader>
68 );
69 }
70}
diff --git a/src/components/ui/AppLoader/styles.js b/src/components/ui/AppLoader/styles.js
new file mode 100644
index 000000000..755a56b40
--- /dev/null
+++ b/src/components/ui/AppLoader/styles.js
@@ -0,0 +1,16 @@
1export default {
2 component: {
3 color: '#FFF',
4 },
5 slogan: {
6 display: 'block',
7 opacity: 0,
8 transition: 'opacity 1s ease',
9 position: 'absolute',
10 textAlign: 'center',
11 width: '100%',
12 },
13 visible: {
14 opacity: 1,
15 },
16};
diff --git a/src/components/ui/Button.js b/src/components/ui/Button.js
index 309e05bb4..ffc7f7051 100644
--- a/src/components/ui/Button.js
+++ b/src/components/ui/Button.js
@@ -62,6 +62,8 @@ export default @observer class Button extends Component {
62 } 62 }
63 63
64 return ( 64 return (
65 // disabling rule as button has type defined in `buttonProps`
66 /* eslint-disable react/button-has-type */
65 <button {...buttonProps}> 67 <button {...buttonProps}>
66 <Loader 68 <Loader
67 loaded={loaded} 69 loaded={loaded}
@@ -72,6 +74,7 @@ export default @observer class Button extends Component {
72 /> 74 />
73 {label} 75 {label}
74 </button> 76 </button>
77 /* eslint-enable react/button-has-type */
75 ); 78 );
76 } 79 }
77} 80}
diff --git a/src/components/ui/FullscreenLoader/index.js b/src/components/ui/FullscreenLoader/index.js
new file mode 100644
index 000000000..6ecf4d395
--- /dev/null
+++ b/src/components/ui/FullscreenLoader/index.js
@@ -0,0 +1,56 @@
1import React, { Component } from 'react';
2import PropTypes from 'prop-types';
3import { observer } from 'mobx-react';
4import injectSheet, { withTheme } from 'react-jss';
5import classnames from 'classnames';
6
7import Loader from '../Loader';
8
9import styles from './styles';
10
11export default @observer @withTheme @injectSheet(styles) class FullscreenLoader extends Component {
12 static propTypes = {
13 className: PropTypes.string,
14 title: PropTypes.string.isRequired,
15 classes: PropTypes.object.isRequired,
16 theme: PropTypes.object.isRequired,
17 spinnerColor: PropTypes.string,
18 children: PropTypes.node,
19 }
20
21 static defaultProps = {
22 className: null,
23 spinnerColor: null,
24 children: null,
25 }
26
27 render() {
28 const {
29 classes,
30 title,
31 children,
32 spinnerColor,
33 className,
34 theme,
35 } = this.props;
36
37 return (
38 <div className={classes.wrapper}>
39 <div
40 className={classnames({
41 [`${classes.component}`]: true,
42 [`${className}`]: className,
43 })}
44 >
45 <h1 className={classes.title}>{title}</h1>
46 <Loader color={spinnerColor || theme.colorFullscreenLoaderSpinner} />
47 {children && (
48 <div className={classes.content}>
49 {children}
50 </div>
51 )}
52 </div>
53 </div>
54 );
55 }
56}
diff --git a/src/components/ui/FullscreenLoader/styles.js b/src/components/ui/FullscreenLoader/styles.js
new file mode 100644
index 000000000..64d24e4ce
--- /dev/null
+++ b/src/components/ui/FullscreenLoader/styles.js
@@ -0,0 +1,23 @@
1export default {
2 wrapper: {
3 display: 'flex',
4 alignItems: 'center',
5 position: 'absolute',
6 width: '100%',
7 },
8 component: {
9 width: '100%',
10 display: 'flex',
11 flexDirection: 'column',
12 alignItems: 'center',
13 textAlign: 'center',
14 height: 'auto',
15 },
16 title: {
17 fontSize: 35,
18 },
19 content: {
20 marginTop: 20,
21 width: '100%',
22 },
23};
diff --git a/src/components/ui/ImageUpload.js b/src/components/ui/ImageUpload.js
index 76f77d631..83a05554b 100644
--- a/src/components/ui/ImageUpload.js
+++ b/src/components/ui/ImageUpload.js
@@ -1,4 +1,4 @@
1import React, { Component } from 'react'; 1import React, { Component, Fragment } from 'react';
2import PropTypes from 'prop-types'; 2import PropTypes from 'prop-types';
3import { observer } from 'mobx-react'; 3import { observer } from 'mobx-react';
4import { Field } from 'mobx-react-form'; 4import { Field } from 'mobx-react-form';
@@ -23,6 +23,8 @@ export default @observer class ImageUpload extends Component {
23 path: null, 23 path: null,
24 } 24 }
25 25
26 dropzoneRef = null;
27
26 onDrop(acceptedFiles) { 28 onDrop(acceptedFiles) {
27 const { field } = this.props; 29 const { field } = this.props;
28 30
@@ -36,8 +38,6 @@ export default @observer class ImageUpload extends Component {
36 field.set(''); 38 field.set('');
37 } 39 }
38 40
39 dropzoneRef = null;
40
41 render() { 41 render() {
42 const { 42 const {
43 field, 43 field,
@@ -57,7 +57,7 @@ export default @observer class ImageUpload extends Component {
57 <label className="franz-form__label" htmlFor="iconUpload">{field.label}</label> 57 <label className="franz-form__label" htmlFor="iconUpload">{field.label}</label>
58 <div className="image-upload"> 58 <div className="image-upload">
59 {(field.value && field.value !== 'delete') || this.state.path ? ( 59 {(field.value && field.value !== 'delete') || this.state.path ? (
60 <div> 60 <Fragment>
61 <div 61 <div
62 className="image-upload__preview" 62 className="image-upload__preview"
63 style={({ 63 style={({
@@ -84,7 +84,7 @@ export default @observer class ImageUpload extends Component {
84 </button> 84 </button>
85 <div className="image-upload__action-background" /> 85 <div className="image-upload__action-background" />
86 </div> 86 </div>
87 </div> 87 </Fragment>
88 ) : ( 88 ) : (
89 <Dropzone 89 <Dropzone
90 ref={(node) => { this.dropzoneRef = node; }} 90 ref={(node) => { this.dropzoneRef = node; }}
diff --git a/src/components/ui/InfoBar.js b/src/components/ui/InfoBar.js
index 94a1ddf76..612399e9f 100644
--- a/src/components/ui/InfoBar.js
+++ b/src/components/ui/InfoBar.js
@@ -5,7 +5,7 @@ import classnames from 'classnames';
5import Loader from 'react-loader'; 5import Loader from 'react-loader';
6 6
7// import { oneOrManyChildElements } from '../../prop-types'; 7// import { oneOrManyChildElements } from '../../prop-types';
8import Appear from '../ui/effects/Appear'; 8import Appear from './effects/Appear';
9 9
10export default @observer class InfoBar extends Component { 10export default @observer class InfoBar extends Component {
11 static propTypes = { 11 static propTypes = {
@@ -64,6 +64,7 @@ export default @observer class InfoBar extends Component {
64 {children} 64 {children}
65 {ctaLabel && ( 65 {ctaLabel && (
66 <button 66 <button
67 type="button"
67 className="info-bar__cta" 68 className="info-bar__cta"
68 onClick={onClick} 69 onClick={onClick}
69 > 70 >
@@ -80,6 +81,7 @@ export default @observer class InfoBar extends Component {
80 </div> 81 </div>
81 {!sticky && ( 82 {!sticky && (
82 <button 83 <button
84 type="button"
83 className="info-bar__close mdi mdi-close" 85 className="info-bar__close mdi mdi-close"
84 onClick={onHide} 86 onClick={onHide}
85 /> 87 />
diff --git a/src/components/ui/Infobox.js b/src/components/ui/Infobox.js
index 77051f567..a33c6474a 100644
--- a/src/components/ui/Infobox.js
+++ b/src/components/ui/Infobox.js
@@ -61,6 +61,7 @@ export default @observer class Infobox extends Component {
61 <button 61 <button
62 className="infobox__cta" 62 className="infobox__cta"
63 onClick={ctaOnClick} 63 onClick={ctaOnClick}
64 type="button"
64 > 65 >
65 <Loader 66 <Loader
66 loaded={!ctaLoading} 67 loaded={!ctaLoading}
@@ -74,6 +75,7 @@ export default @observer class Infobox extends Component {
74 )} 75 )}
75 {dismissable && ( 76 {dismissable && (
76 <button 77 <button
78 type="button"
77 onClick={() => this.setState({ 79 onClick={() => this.setState({
78 dismissed: true, 80 dismissed: true,
79 })} 81 })}
diff --git a/src/components/ui/Input.js b/src/components/ui/Input.js
index 7bf6e1b00..9b070c4df 100644
--- a/src/components/ui/Input.js
+++ b/src/components/ui/Input.js
@@ -33,6 +33,8 @@ export default @observer class Input extends Component {
33 passwordScore: 0, 33 passwordScore: 0,
34 } 34 }
35 35
36 inputElement = null;
37
36 componentDidMount() { 38 componentDidMount() {
37 if (this.props.focus) { 39 if (this.props.focus) {
38 this.focus(); 40 this.focus();
@@ -53,8 +55,6 @@ export default @observer class Input extends Component {
53 this.inputElement.focus(); 55 this.inputElement.focus();
54 } 56 }
55 57
56 inputElement = null;
57
58 render() { 58 render() {
59 const { 59 const {
60 field, 60 field,
@@ -110,7 +110,7 @@ export default @observer class Input extends Component {
110 'mdi-eye': !this.state.showPassword, 110 'mdi-eye': !this.state.showPassword,
111 'mdi-eye-off': this.state.showPassword, 111 'mdi-eye-off': this.state.showPassword,
112 })} 112 })}
113 onClick={() => this.setState({ showPassword: !this.state.showPassword })} 113 onClick={() => this.setState(prevState => ({ showPassword: !prevState.showPassword }))}
114 tabIndex="-1" 114 tabIndex="-1"
115 /> 115 />
116 )} 116 )}
diff --git a/src/components/ui/Link.js b/src/components/ui/Link.js
index 0602290f1..b88686d5e 100644
--- a/src/components/ui/Link.js
+++ b/src/components/ui/Link.js
@@ -72,5 +72,4 @@ Link.wrappedComponent.defaultProps = {
72 activeClassName: '', 72 activeClassName: '',
73 strictFilter: false, 73 strictFilter: false,
74 target: '', 74 target: '',
75 openInBrowser: false,
76}; 75};
diff --git a/src/components/ui/PremiumFeatureContainer/index.js b/src/components/ui/PremiumFeatureContainer/index.js
index 73984be94..67cd6af0b 100644
--- a/src/components/ui/PremiumFeatureContainer/index.js
+++ b/src/components/ui/PremiumFeatureContainer/index.js
@@ -73,4 +73,3 @@ PremiumFeatureContainer.wrappedComponent.propTypes = {
73 }).isRequired, 73 }).isRequired,
74 }).isRequired, 74 }).isRequired,
75}; 75};
76
diff --git a/src/components/ui/PremiumFeatureContainer/styles.js b/src/components/ui/PremiumFeatureContainer/styles.js
index 16c40d0ec..81d6666c6 100644
--- a/src/components/ui/PremiumFeatureContainer/styles.js
+++ b/src/components/ui/PremiumFeatureContainer/styles.js
@@ -5,6 +5,7 @@ export default theme => ({
5 margin: [0, 0, 20, -20], 5 margin: [0, 0, 20, -20],
6 padding: 20, 6 padding: 20,
7 'border-radius': theme.borderRadius, 7 'border-radius': theme.borderRadius,
8 pointerEvents: 'none',
8 }, 9 },
9 titleContainer: { 10 titleContainer: {
10 display: 'flex', 11 display: 'flex',
@@ -20,6 +21,7 @@ export default theme => ({
20 'border-radius': theme.borderRadiusSmall, 21 'border-radius': theme.borderRadiusSmall,
21 padding: [2, 4], 22 padding: [2, 4],
22 'font-size': 12, 23 'font-size': 12,
24 pointerEvents: 'initial',
23 }, 25 },
24 content: { 26 content: {
25 opacity: 0.5, 27 opacity: 0.5,
diff --git a/src/components/ui/Radio.js b/src/components/ui/Radio.js
index 63ca6f9b8..ba13aca63 100644
--- a/src/components/ui/Radio.js
+++ b/src/components/ui/Radio.js
@@ -18,6 +18,8 @@ export default @observer class Radio extends Component {
18 showLabel: true, 18 showLabel: true,
19 }; 19 };
20 20
21 inputElement = null;
22
21 componentDidMount() { 23 componentDidMount() {
22 if (this.props.focus) { 24 if (this.props.focus) {
23 this.focus(); 25 this.focus();
@@ -28,8 +30,6 @@ export default @observer class Radio extends Component {
28 this.inputElement.focus(); 30 this.inputElement.focus();
29 } 31 }
30 32
31 inputElement = null;
32
33 render() { 33 render() {
34 const { 34 const {
35 field, 35 field,
diff --git a/src/components/ui/SearchInput.js b/src/components/ui/SearchInput.js
index 5a9571d27..78d6aae8b 100644
--- a/src/components/ui/SearchInput.js
+++ b/src/components/ui/SearchInput.js
@@ -2,7 +2,6 @@ import React, { Component } from 'react';
2import PropTypes from 'prop-types'; 2import PropTypes from 'prop-types';
3import { observer } from 'mobx-react'; 3import { observer } from 'mobx-react';
4import classnames from 'classnames'; 4import classnames from 'classnames';
5import uuidv1 from 'uuid/v1';
6import { debounce } from 'lodash'; 5import { debounce } from 'lodash';
7 6
8export default @observer class SearchInput extends Component { 7export default @observer class SearchInput extends Component {
@@ -22,7 +21,7 @@ export default @observer class SearchInput extends Component {
22 value: '', 21 value: '',
23 placeholder: '', 22 placeholder: '',
24 className: '', 23 className: '',
25 name: uuidv1(), 24 name: 'searchInput',
26 throttle: false, 25 throttle: false,
27 throttleDelay: 250, 26 throttleDelay: 250,
28 onChange: () => null, 27 onChange: () => null,
@@ -30,6 +29,8 @@ export default @observer class SearchInput extends Component {
30 autoFocus: false, 29 autoFocus: false,
31 } 30 }
32 31
32 input = null;
33
33 constructor(props) { 34 constructor(props) {
34 super(props); 35 super(props);
35 36
@@ -74,8 +75,6 @@ export default @observer class SearchInput extends Component {
74 onReset(); 75 onReset();
75 } 76 }
76 77
77 input = null;
78
79 render() { 78 render() {
80 const { className, name, placeholder } = this.props; 79 const { className, name, placeholder } = this.props;
81 const { value } = this.state; 80 const { value } = this.state;
@@ -90,15 +89,17 @@ export default @observer class SearchInput extends Component {
90 <label 89 <label
91 htmlFor={name} 90 htmlFor={name}
92 className="mdi mdi-magnify" 91 className="mdi mdi-magnify"
93 /> 92 >
94 <input 93 <input
95 name={name} 94 name={name}
96 type="text" 95 id={name}
97 placeholder={placeholder} 96 type="text"
98 value={value} 97 placeholder={placeholder}
99 onChange={e => this.onChange(e)} 98 value={value}
100 ref={(ref) => { this.input = ref; }} 99 onChange={e => this.onChange(e)}
101 /> 100 ref={(ref) => { this.input = ref; }}
101 />
102 </label>
102 {value.length > 0 && ( 103 {value.length > 0 && (
103 <span 104 <span
104 className="mdi mdi-close-circle-outline" 105 className="mdi mdi-close-circle-outline"
diff --git a/src/components/ui/Select.js b/src/components/ui/Select.js
index abcad417e..da52243ca 100644
--- a/src/components/ui/Select.js
+++ b/src/components/ui/Select.js
@@ -9,12 +9,13 @@ export default @observer class Select extends Component {
9 field: PropTypes.instanceOf(Field).isRequired, 9 field: PropTypes.instanceOf(Field).isRequired,
10 className: PropTypes.string, 10 className: PropTypes.string,
11 showLabel: PropTypes.bool, 11 showLabel: PropTypes.bool,
12 disabled: PropTypes.bool,
12 }; 13 };
13 14
14 static defaultProps = { 15 static defaultProps = {
15 className: null, 16 className: null,
16 focus: false,
17 showLabel: true, 17 showLabel: true,
18 disabled: false,
18 }; 19 };
19 20
20 render() { 21 render() {
@@ -22,6 +23,7 @@ export default @observer class Select extends Component {
22 field, 23 field,
23 className, 24 className,
24 showLabel, 25 showLabel,
26 disabled,
25 } = this.props; 27 } = this.props;
26 28
27 return ( 29 return (
@@ -29,6 +31,7 @@ export default @observer class Select extends Component {
29 className={classnames({ 31 className={classnames({
30 'franz-form__field': true, 32 'franz-form__field': true,
31 'has-error': field.error, 33 'has-error': field.error,
34 'is-disabled': disabled,
32 [`${className}`]: className, 35 [`${className}`]: className,
33 })} 36 })}
34 > 37 >
@@ -45,12 +48,13 @@ export default @observer class Select extends Component {
45 id={field.id} 48 id={field.id}
46 defaultValue={field.value} 49 defaultValue={field.value}
47 className="franz-form__select" 50 className="franz-form__select"
51 disabled={field.disabled || disabled}
48 > 52 >
49 {field.options.map(type => ( 53 {field.options.map(type => (
50 <option 54 <option
51 key={type.value} 55 key={type.value}
52 value={type.value} 56 value={type.value}
53 // selected={field.value === } 57 disabled={type.disabled}
54 > 58 >
55 {type.label} 59 {type.label}
56 </option> 60 </option>
diff --git a/src/components/ui/StatusBarTargetUrl.js b/src/components/ui/StatusBarTargetUrl.js
index 4285a343c..6fc50fe5c 100644
--- a/src/components/ui/StatusBarTargetUrl.js
+++ b/src/components/ui/StatusBarTargetUrl.js
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
3import { observer } from 'mobx-react'; 3import { observer } from 'mobx-react';
4import classnames from 'classnames'; 4import classnames from 'classnames';
5 5
6import Appear from '../ui/effects/Appear'; 6import Appear from './effects/Appear';
7 7
8export default @observer class StatusBarTargetUrl extends Component { 8export default @observer class StatusBarTargetUrl extends Component {
9 static propTypes = { 9 static propTypes = {
@@ -13,7 +13,6 @@ export default @observer class StatusBarTargetUrl extends Component {
13 13
14 static defaultProps = { 14 static defaultProps = {
15 className: '', 15 className: '',
16 position: 'bottom',
17 text: '', 16 text: '',
18 }; 17 };
19 18
diff --git a/src/components/ui/Tabs/TabItem.js b/src/components/ui/Tabs/TabItem.js
index 9ff9f009e..16881a7f7 100644
--- a/src/components/ui/Tabs/TabItem.js
+++ b/src/components/ui/Tabs/TabItem.js
@@ -1,4 +1,4 @@
1import React, { Component } from 'react'; 1import React, { Component, Fragment } from 'react';
2 2
3import { oneOrManyChildElements } from '../../../prop-types'; 3import { oneOrManyChildElements } from '../../../prop-types';
4 4
@@ -11,7 +11,7 @@ export default class TabItem extends Component {
11 const { children } = this.props; 11 const { children } = this.props;
12 12
13 return ( 13 return (
14 <div>{children}</div> 14 <Fragment>{children}</Fragment>
15 ); 15 );
16 } 16 }
17} 17}
diff --git a/src/components/ui/WebviewLoader/index.js b/src/components/ui/WebviewLoader/index.js
new file mode 100644
index 000000000..3a3dbbe49
--- /dev/null
+++ b/src/components/ui/WebviewLoader/index.js
@@ -0,0 +1,25 @@
1import React, { Component } from 'react';
2import PropTypes from 'prop-types';
3import { observer } from 'mobx-react';
4import injectSheet from 'react-jss';
5
6import FullscreenLoader from '../FullscreenLoader';
7
8import styles from './styles';
9
10export default @observer @injectSheet(styles) class WebviewLoader extends Component {
11 static propTypes = {
12 name: PropTypes.string.isRequired,
13 classes: PropTypes.object.isRequired,
14 }
15
16 render() {
17 const { classes, name } = this.props;
18 return (
19 <FullscreenLoader
20 className={classes.component}
21 title={`Loading ${name}`}
22 />
23 );
24 }
25}
diff --git a/src/components/ui/WebviewLoader/styles.js b/src/components/ui/WebviewLoader/styles.js
new file mode 100644
index 000000000..dbd75db8a
--- /dev/null
+++ b/src/components/ui/WebviewLoader/styles.js
@@ -0,0 +1,9 @@
1export default theme => ({
2 component: {
3 background: theme.colorWebviewLoaderBackground,
4 padding: 20,
5 width: 'auto',
6 margin: [0, 'auto'],
7 borderRadius: 6,
8 },
9});
diff --git a/src/components/util/ErrorBoundary/index.js b/src/components/util/ErrorBoundary/index.js
new file mode 100644
index 000000000..5db0db226
--- /dev/null
+++ b/src/components/util/ErrorBoundary/index.js
@@ -0,0 +1,60 @@
1import React, { Component } from 'react';
2import PropTypes from 'prop-types';
3import injectSheet from 'react-jss';
4import { defineMessages, intlShape } from 'react-intl';
5
6import Button from '../../ui/Button';
7
8import styles from './styles';
9
10const messages = defineMessages({
11 headline: {
12 id: 'app.errorHandler.headline',
13 defaultMessage: '!!!Something went wrong.',
14 },
15 action: {
16 id: 'app.errorHandler.action',
17 defaultMessage: '!!!Reload',
18 },
19});
20
21export default @injectSheet(styles) class ErrorBoundary extends Component {
22 state = {
23 hasError: false,
24 }
25
26 static propTypes = {
27 classes: PropTypes.object.isRequired,
28 children: PropTypes.node.isRequired,
29 }
30
31 static contextTypes = {
32 intl: intlShape,
33 };
34
35 componentDidCatch() {
36 this.setState({ hasError: true });
37 }
38
39 render() {
40 const { classes } = this.props;
41 const { intl } = this.context;
42
43 if (this.state.hasError) {
44 return (
45 <div className={classes.component}>
46 <h1 className={classes.title}>
47 {intl.formatMessage(messages.headline)}
48 </h1>
49 <Button
50 label={intl.formatMessage(messages.action)}
51 buttonType="inverted"
52 onClick={() => window.location.reload()}
53 />
54 </div>
55 );
56 }
57
58 return this.props.children;
59 }
60}
diff --git a/src/components/util/ErrorBoundary/styles.js b/src/components/util/ErrorBoundary/styles.js
new file mode 100644
index 000000000..0960546ff
--- /dev/null
+++ b/src/components/util/ErrorBoundary/styles.js
@@ -0,0 +1,13 @@
1export default theme => ({
2 component: {
3 display: 'flex',
4 width: '100%',
5 alignItems: 'center',
6 justifyContent: 'center',
7 flexDirection: 'column',
8 },
9 title: {
10 fontSize: 20,
11 color: theme.colorText,
12 },
13});
diff --git a/src/config.js b/src/config.js
index d981f9c6a..789ddd1a0 100644
--- a/src/config.js
+++ b/src/config.js
@@ -56,4 +56,5 @@ export const FILE_SYSTEM_SETTINGS_TYPES = [
56 56
57export const SETTINGS_PATH = path.join(app.getPath('userData'), 'config'); 57export const SETTINGS_PATH = path.join(app.getPath('userData'), 'config');
58 58
59export const DICTIONARY_PATH = path.join(app.getPath('userData'), 'dicts'); 59// Replacing app.asar is not beautiful but unforunately necessary
60export const DICTIONARY_PATH = path.join(__dirname, 'dictionaries').replace('app.asar', 'app.asar.unpacked');
diff --git a/src/containers/auth/AuthLayoutContainer.js b/src/containers/auth/AuthLayoutContainer.js
index b73598f3d..762929dc6 100644
--- a/src/containers/auth/AuthLayoutContainer.js
+++ b/src/containers/auth/AuthLayoutContainer.js
@@ -18,7 +18,9 @@ export default @inject('stores', 'actions') @observer class AuthLayoutContainer
18 }; 18 };
19 19
20 render() { 20 render() {
21 const { stores, actions, children, location } = this.props; 21 const {
22 stores, actions, children, location,
23 } = this.props;
22 const { app, features, globalError } = stores; 24 const { app, features, globalError } = stores;
23 25
24 const isLoadingBaseFeatures = features.defaultFeaturesRequest.isExecuting 26 const isLoadingBaseFeatures = features.defaultFeaturesRequest.isExecuting
diff --git a/src/containers/layout/AppLayoutContainer.js b/src/containers/layout/AppLayoutContainer.js
index e1423bdaa..430b49b55 100644
--- a/src/containers/layout/AppLayoutContainer.js
+++ b/src/containers/layout/AppLayoutContainer.js
@@ -75,7 +75,9 @@ export default @inject('stores', 'actions') @observer class AppLayoutContainer e
75 75
76 if (isLoadingFeatures || isLoadingServices) { 76 if (isLoadingFeatures || isLoadingServices) {
77 return ( 77 return (
78 <AppLoader /> 78 <ThemeProvider theme={ui.theme}>
79 <AppLoader />
80 </ThemeProvider>
79 ); 81 );
80 } 82 }
81 83
@@ -105,6 +107,7 @@ export default @inject('stores', 'actions') @observer class AppLayoutContainer e
105 setWebviewReference={setWebviewReference} 107 setWebviewReference={setWebviewReference}
106 openWindow={openWindow} 108 openWindow={openWindow}
107 reload={reload} 109 reload={reload}
110 openSettings={openSettings}
108 isAppMuted={settings.all.app.isAppMuted} 111 isAppMuted={settings.all.app.isAppMuted}
109 update={updateService} 112 update={updateService}
110 /> 113 />
diff --git a/src/containers/settings/AccountScreen.js b/src/containers/settings/AccountScreen.js
index 5818af0b1..019b3d7d6 100644
--- a/src/containers/settings/AccountScreen.js
+++ b/src/containers/settings/AccountScreen.js
@@ -9,6 +9,7 @@ import AppStore from '../../stores/AppStore';
9import { gaPage } from '../../lib/analytics'; 9import { gaPage } from '../../lib/analytics';
10 10
11import AccountDashboard from '../../components/settings/account/AccountDashboard'; 11import AccountDashboard from '../../components/settings/account/AccountDashboard';
12import ErrorBoundary from '../../components/util/ErrorBoundary';
12 13
13const { BrowserWindow } = remote; 14const { BrowserWindow } = remote;
14 15
@@ -67,22 +68,24 @@ export default @inject('stores', 'actions') @observer class AccountScreen extend
67 const isLoadingPlans = payment.plansRequest.isExecuting; 68 const isLoadingPlans = payment.plansRequest.isExecuting;
68 69
69 return ( 70 return (
70 <AccountDashboard 71 <ErrorBoundary>
71 user={user.data} 72 <AccountDashboard
72 orders={payment.orders} 73 user={user.data}
73 isLoading={isLoadingUserInfo} 74 orders={payment.orders}
74 isLoadingOrdersInfo={isLoadingOrdersInfo} 75 isLoading={isLoadingUserInfo}
75 isLoadingPlans={isLoadingPlans} 76 isLoadingOrdersInfo={isLoadingOrdersInfo}
76 userInfoRequestFailed={user.getUserInfoRequest.wasExecuted && user.getUserInfoRequest.isError} 77 isLoadingPlans={isLoadingPlans}
77 retryUserInfoRequest={() => this.reloadData()} 78 userInfoRequestFailed={user.getUserInfoRequest.wasExecuted && user.getUserInfoRequest.isError}
78 isCreatingPaymentDashboardUrl={payment.createDashboardUrlRequest.isExecuting} 79 retryUserInfoRequest={() => this.reloadData()}
79 openDashboard={price => this.handlePaymentDashboard(price)} 80 isCreatingPaymentDashboardUrl={payment.createDashboardUrlRequest.isExecuting}
80 openExternalUrl={url => openExternalUrl({ url })} 81 openDashboard={price => this.handlePaymentDashboard(price)}
81 onCloseSubscriptionWindow={() => this.onCloseWindow()} 82 openExternalUrl={url => openExternalUrl({ url })}
82 deleteAccount={userActions.delete} 83 onCloseSubscriptionWindow={() => this.onCloseWindow()}
83 isLoadingDeleteAccount={user.deleteAccountRequest.isExecuting} 84 deleteAccount={userActions.delete}
84 isDeleteAccountSuccessful={user.deleteAccountRequest.wasExecuted && !user.deleteAccountRequest.isError} 85 isLoadingDeleteAccount={user.deleteAccountRequest.isExecuting}
85 /> 86 isDeleteAccountSuccessful={user.deleteAccountRequest.wasExecuted && !user.deleteAccountRequest.isError}
87 />
88 </ErrorBoundary>
86 ); 89 );
87 } 90 }
88} 91}
diff --git a/src/containers/settings/EditServiceScreen.js b/src/containers/settings/EditServiceScreen.js
index 639e8b070..b46908344 100644
--- a/src/containers/settings/EditServiceScreen.js
+++ b/src/containers/settings/EditServiceScreen.js
@@ -13,10 +13,15 @@ import { gaPage } from '../../lib/analytics';
13 13
14import ServiceError from '../../components/settings/services/ServiceError'; 14import ServiceError from '../../components/settings/services/ServiceError';
15import EditServiceForm from '../../components/settings/services/EditServiceForm'; 15import EditServiceForm from '../../components/settings/services/EditServiceForm';
16import ErrorBoundary from '../../components/util/ErrorBoundary';
17
16import { required, url, oneRequired } from '../../helpers/validation-helpers'; 18import { required, url, oneRequired } from '../../helpers/validation-helpers';
19import { getSelectOptions } from '../../helpers/i18n-helpers';
17 20
18import { config as proxyFeature } from '../../features/serviceProxy'; 21import { config as proxyFeature } from '../../features/serviceProxy';
19 22
23import { SPELLCHECKER_LOCALES } from '../../i18n/languages';
24
20const messages = defineMessages({ 25const messages = defineMessages({
21 name: { 26 name: {
22 id: 'settings.service.form.name', 27 id: 'settings.service.form.name',
@@ -66,6 +71,10 @@ const messages = defineMessages({
66 id: 'settings.service.form.proxy.host', 71 id: 'settings.service.form.proxy.host',
67 defaultMessage: '!!!Proxy Host/IP', 72 defaultMessage: '!!!Proxy Host/IP',
68 }, 73 },
74 proxyPort: {
75 id: 'settings.service.form.proxy.port',
76 defaultMessage: '!!!Port',
77 },
69 proxyUser: { 78 proxyUser: {
70 id: 'settings.service.form.proxy.user', 79 id: 'settings.service.form.proxy.user',
71 defaultMessage: '!!!User', 80 defaultMessage: '!!!User',
@@ -74,6 +83,14 @@ const messages = defineMessages({
74 id: 'settings.service.form.proxy.password', 83 id: 'settings.service.form.proxy.password',
75 defaultMessage: '!!!Password', 84 defaultMessage: '!!!Password',
76 }, 85 },
86 spellcheckerLanguage: {
87 id: 'settings.service.form.spellcheckerLanguage',
88 defaultMessage: '!!!Spell checking Language',
89 },
90 spellcheckerSystemDefault: {
91 id: 'settings.service.form.spellcheckerLanguage.default',
92 defaultMessage: '!!!Use System Default ({default})',
93 },
77}); 94});
78 95
79export default @inject('stores', 'actions') @observer class EditServiceScreen extends Component { 96export default @inject('stores', 'actions') @observer class EditServiceScreen extends Component {
@@ -101,6 +118,11 @@ export default @inject('stores', 'actions') @observer class EditServiceScreen ex
101 } 118 }
102 119
103 prepareForm(recipe, service, proxy) { 120 prepareForm(recipe, service, proxy) {
121 const spellcheckerLanguage = getSelectOptions({
122 locales: SPELLCHECKER_LOCALES,
123 resetToDefaultText: this.context.intl.formatMessage(messages.spellcheckerSystemDefault, { default: SPELLCHECKER_LOCALES[this.props.stores.settings.app.spellcheckerLanguage] }),
124 });
125
104 const { intl } = this.context; 126 const { intl } = this.context;
105 const config = { 127 const config = {
106 fields: { 128 fields: {
@@ -138,7 +160,13 @@ export default @inject('stores', 'actions') @observer class EditServiceScreen ex
138 isDarkModeEnabled: { 160 isDarkModeEnabled: {
139 label: intl.formatMessage(messages.enableDarkMode), 161 label: intl.formatMessage(messages.enableDarkMode),
140 value: service.isDarkModeEnabled, 162 value: service.isDarkModeEnabled,
141 default: this.props.stores.settings.all.app.darkMode, 163 default: this.props.stores.settings.app.darkMode,
164 },
165 spellcheckerLanguage: {
166 label: intl.formatMessage(messages.spellcheckerLanguage),
167 value: service.spellcheckerLanguage,
168 options: spellcheckerLanguage,
169 disabled: !this.props.stores.settings.app.enableSpellchecking,
142 }, 170 },
143 }, 171 },
144 }; 172 };
@@ -209,6 +237,11 @@ export default @inject('stores', 'actions') @observer class EditServiceScreen ex
209 value: serviceProxyConfig.host, 237 value: serviceProxyConfig.host,
210 default: '', 238 default: '',
211 }, 239 },
240 port: {
241 label: intl.formatMessage(messages.proxyPort),
242 value: serviceProxyConfig.port,
243 default: '',
244 },
212 user: { 245 user: {
213 label: intl.formatMessage(messages.proxyUser), 246 label: intl.formatMessage(messages.proxyUser),
214 value: serviceProxyConfig.user, 247 value: serviceProxyConfig.user,
@@ -280,20 +313,22 @@ export default @inject('stores', 'actions') @observer class EditServiceScreen ex
280 const form = this.prepareForm(recipe, service, proxyFeature); 313 const form = this.prepareForm(recipe, service, proxyFeature);
281 314
282 return ( 315 return (
283 <EditServiceForm 316 <ErrorBoundary>
284 action={action} 317 <EditServiceForm
285 recipe={recipe} 318 action={action}
286 service={service} 319 recipe={recipe}
287 user={user.data} 320 service={service}
288 form={form} 321 user={user.data}
289 status={services.actionStatus} 322 form={form}
290 isSaving={services.updateServiceRequest.isExecuting || services.createServiceRequest.isExecuting} 323 status={services.actionStatus}
291 isDeleting={services.deleteServiceRequest.isExecuting} 324 isSaving={services.updateServiceRequest.isExecuting || services.createServiceRequest.isExecuting}
292 onSubmit={d => this.onSubmit(d)} 325 isDeleting={services.deleteServiceRequest.isExecuting}
293 onDelete={() => this.deleteService()} 326 onSubmit={d => this.onSubmit(d)}
294 isProxyFeatureEnabled={proxyFeature.isEnabled} 327 onDelete={() => this.deleteService()}
295 isProxyFeaturePremiumFeature={proxyFeature.isPremium} 328 isProxyFeatureEnabled={proxyFeature.isEnabled}
296 /> 329 isProxyFeaturePremiumFeature={proxyFeature.isPremium}
330 />
331 </ErrorBoundary>
297 ); 332 );
298 } 333 }
299} 334}
diff --git a/src/containers/settings/EditSettingsScreen.js b/src/containers/settings/EditSettingsScreen.js
index ea1d319d9..f1706a721 100644
--- a/src/containers/settings/EditSettingsScreen.js
+++ b/src/containers/settings/EditSettingsScreen.js
@@ -12,8 +12,11 @@ import { gaPage } from '../../lib/analytics';
12import { DEFAULT_APP_SETTINGS } from '../../config'; 12import { DEFAULT_APP_SETTINGS } from '../../config';
13import { config as spellcheckerConfig } from '../../features/spellchecker'; 13import { config as spellcheckerConfig } from '../../features/spellchecker';
14 14
15import { getSelectOptions } from '../../helpers/i18n-helpers';
16
15 17
16import EditSettingsForm from '../../components/settings/settings/EditSettingsForm'; 18import EditSettingsForm from '../../components/settings/settings/EditSettingsForm';
19import ErrorBoundary from '../../components/util/ErrorBoundary';
17 20
18const messages = defineMessages({ 21const messages = defineMessages({
19 autoLaunchOnStart: { 22 autoLaunchOnStart: {
@@ -116,20 +119,12 @@ export default @inject('stores', 'actions') @observer class EditSettingsScreen e
116 const { app, settings, user } = this.props.stores; 119 const { app, settings, user } = this.props.stores;
117 const { intl } = this.context; 120 const { intl } = this.context;
118 121
119 const locales = []; 122 const locales = getSelectOptions({
120 Object.keys(APP_LOCALES).sort(Intl.Collator().compare).forEach((key) => { 123 locales: APP_LOCALES,
121 locales.push({
122 value: key,
123 label: APP_LOCALES[key],
124 });
125 }); 124 });
126 125
127 const spellcheckingLanguages = []; 126 const spellcheckingLanguages = getSelectOptions({
128 Object.keys(SPELLCHECKER_LOCALES).sort(Intl.Collator().compare).forEach((key) => { 127 locales: SPELLCHECKER_LOCALES,
129 spellcheckingLanguages.push({
130 value: key,
131 label: SPELLCHECKER_LOCALES[key],
132 });
133 }); 128 });
134 129
135 const config = { 130 const config = {
@@ -222,20 +217,22 @@ export default @inject('stores', 'actions') @observer class EditSettingsScreen e
222 const form = this.prepareForm(); 217 const form = this.prepareForm();
223 218
224 return ( 219 return (
225 <EditSettingsForm 220 <ErrorBoundary>
226 form={form} 221 <EditSettingsForm
227 checkForUpdates={checkForUpdates} 222 form={form}
228 installUpdate={installUpdate} 223 checkForUpdates={checkForUpdates}
229 isCheckingForUpdates={updateStatus === updateStatusTypes.CHECKING} 224 installUpdate={installUpdate}
230 isUpdateAvailable={updateStatus === updateStatusTypes.AVAILABLE} 225 isCheckingForUpdates={updateStatus === updateStatusTypes.CHECKING}
231 noUpdateAvailable={updateStatus === updateStatusTypes.NOT_AVAILABLE} 226 isUpdateAvailable={updateStatus === updateStatusTypes.AVAILABLE}
232 updateIsReadyToInstall={updateStatus === updateStatusTypes.DOWNLOADED} 227 noUpdateAvailable={updateStatus === updateStatusTypes.NOT_AVAILABLE}
233 onSubmit={d => this.onSubmit(d)} 228 updateIsReadyToInstall={updateStatus === updateStatusTypes.DOWNLOADED}
234 cacheSize={cacheSize} 229 onSubmit={d => this.onSubmit(d)}
235 isClearingAllCache={isClearingAllCache} 230 cacheSize={cacheSize}
236 onClearAllCache={clearAllCache} 231 isClearingAllCache={isClearingAllCache}
237 isSpellcheckerPremiumFeature={spellcheckerConfig.isPremiumFeature} 232 onClearAllCache={clearAllCache}
238 /> 233 isSpellcheckerPremiumFeature={spellcheckerConfig.isPremiumFeature}
234 />
235 </ErrorBoundary>
239 ); 236 );
240 } 237 }
241} 238}
diff --git a/src/containers/settings/EditUserScreen.js b/src/containers/settings/EditUserScreen.js
index 3da3e8d2c..3d35effc5 100644
--- a/src/containers/settings/EditUserScreen.js
+++ b/src/containers/settings/EditUserScreen.js
@@ -6,6 +6,8 @@ import { defineMessages, intlShape } from 'react-intl';
6import UserStore from '../../stores/UserStore'; 6import UserStore from '../../stores/UserStore';
7import Form from '../../lib/Form'; 7import Form from '../../lib/Form';
8import EditUserForm from '../../components/settings/user/EditUserForm'; 8import EditUserForm from '../../components/settings/user/EditUserForm';
9import ErrorBoundary from '../../components/util/ErrorBoundary';
10
9import { required, email, minLength } from '../../helpers/validation-helpers'; 11import { required, email, minLength } from '../../helpers/validation-helpers';
10import { gaPage } from '../../lib/analytics'; 12import { gaPage } from '../../lib/analytics';
11 13
@@ -140,14 +142,15 @@ export default @inject('stores', 'actions') @observer class EditUserScreen exten
140 const form = this.prepareForm(user.data); 142 const form = this.prepareForm(user.data);
141 143
142 return ( 144 return (
143 <EditUserForm 145 <ErrorBoundary>
144 // user={user.data} 146 <EditUserForm
145 status={user.actionStatus} 147 // user={user.data}
146 form={form} 148 status={user.actionStatus}
147 isEnterprise={user.data.isEnterprise} 149 form={form}
148 isSaving={user.updateUserInfoRequest.isExecuting} 150 isSaving={user.updateUserInfoRequest.isExecuting}
149 onSubmit={d => this.onSubmit(d)} 151 onSubmit={d => this.onSubmit(d)}
150 /> 152 />
153 </ErrorBoundary>
151 ); 154 );
152 } 155 }
153} 156}
diff --git a/src/containers/settings/InviteScreen.js b/src/containers/settings/InviteScreen.js
index 38ca6ec74..cd36610e4 100644
--- a/src/containers/settings/InviteScreen.js
+++ b/src/containers/settings/InviteScreen.js
@@ -3,6 +3,8 @@ import PropTypes from 'prop-types';
3import { inject, observer } from 'mobx-react'; 3import { inject, observer } from 'mobx-react';
4 4
5import Invite from '../../components/auth/Invite'; 5import Invite from '../../components/auth/Invite';
6import ErrorBoundary from '../../components/util/ErrorBoundary';
7
6import { gaPage } from '../../lib/analytics'; 8import { gaPage } from '../../lib/analytics';
7 9
8export default @inject('stores', 'actions') @observer class InviteScreen extends Component { 10export default @inject('stores', 'actions') @observer class InviteScreen extends Component {
@@ -19,12 +21,14 @@ export default @inject('stores', 'actions') @observer class InviteScreen extends
19 const { user } = this.props.stores; 21 const { user } = this.props.stores;
20 22
21 return ( 23 return (
22 <Invite 24 <ErrorBoundary>
23 onSubmit={actions.user.invite} 25 <Invite
24 isLoadingInvite={user.inviteRequest.isExecuting} 26 onSubmit={actions.user.invite}
25 isInviteSuccessful={user.inviteRequest.wasExecuted && !user.inviteRequest.isError} 27 isLoadingInvite={user.inviteRequest.isExecuting}
26 embed 28 isInviteSuccessful={user.inviteRequest.wasExecuted && !user.inviteRequest.isError}
27 /> 29 embed
30 />
31 </ErrorBoundary>
28 ); 32 );
29 } 33 }
30} 34}
diff --git a/src/containers/settings/RecipesScreen.js b/src/containers/settings/RecipesScreen.js
index 4efe81505..b3d758c87 100644
--- a/src/containers/settings/RecipesScreen.js
+++ b/src/containers/settings/RecipesScreen.js
@@ -10,12 +10,13 @@ import UserStore from '../../stores/UserStore';
10import { gaPage } from '../../lib/analytics'; 10import { gaPage } from '../../lib/analytics';
11 11
12import RecipesDashboard from '../../components/settings/recipes/RecipesDashboard'; 12import RecipesDashboard from '../../components/settings/recipes/RecipesDashboard';
13import ErrorBoundary from '../../components/util/ErrorBoundary';
13 14
14export default @inject('stores', 'actions') @observer class RecipesScreen extends Component { 15export default @inject('stores', 'actions') @observer class RecipesScreen extends Component {
15 static propTypes = { 16 static propTypes = {
16 params: PropTypes.shape({ 17 params: PropTypes.shape({
17 filter: PropTypes.string, 18 filter: PropTypes.string,
18 }).isRequired, 19 }),
19 }; 20 };
20 21
21 static defaultProps = { 22 static defaultProps = {
@@ -29,10 +30,12 @@ export default @inject('stores', 'actions') @observer class RecipesScreen extend
29 currentFilter: 'featured', 30 currentFilter: 'featured',
30 }; 31 };
31 32
33 autorunDisposer = null;
34
32 componentDidMount() { 35 componentDidMount() {
33 gaPage('Settings/Recipe Dashboard/Featured'); 36 gaPage('Settings/Recipe Dashboard/Featured');
34 37
35 autorun(() => { 38 this.autorunDisposer = autorun(() => {
36 const { filter } = this.props.params; 39 const { filter } = this.props.params;
37 const { currentFilter } = this.state; 40 const { currentFilter } = this.state;
38 41
@@ -51,6 +54,7 @@ export default @inject('stores', 'actions') @observer class RecipesScreen extend
51 54
52 componentWillUnmount() { 55 componentWillUnmount() {
53 this.props.stores.services.resetStatus(); 56 this.props.stores.services.resetStatus();
57 this.autorunDisposer();
54 } 58 }
55 59
56 searchRecipes(needle) { 60 searchRecipes(needle) {
@@ -68,7 +72,9 @@ export default @inject('stores', 'actions') @observer class RecipesScreen extend
68 } 72 }
69 73
70 render() { 74 render() {
71 const { recipePreviews, recipes, services, user } = this.props.stores; 75 const {
76 recipePreviews, recipes, services, user,
77 } = this.props.stores;
72 const { showAddServiceInterface } = this.props.actions.service; 78 const { showAddServiceInterface } = this.props.actions.service;
73 79
74 const { filter } = this.props.params; 80 const { filter } = this.props.params;
@@ -90,19 +96,21 @@ export default @inject('stores', 'actions') @observer class RecipesScreen extend
90 || recipePreviews.searchRecipePreviewsRequest.isExecuting; 96 || recipePreviews.searchRecipePreviewsRequest.isExecuting;
91 97
92 return ( 98 return (
93 <RecipesDashboard 99 <ErrorBoundary>
94 recipes={allRecipes} 100 <RecipesDashboard
95 isLoading={isLoading} 101 recipes={allRecipes}
96 addedServiceCount={services.all.length} 102 isLoading={isLoading}
97 isPremium={user.data.isPremium} 103 addedServiceCount={services.all.length}
98 hasLoadedRecipes={recipePreviews.featuredRecipePreviewsRequest.wasExecuted} 104 isPremium={user.data.isPremium}
99 showAddServiceInterface={showAddServiceInterface} 105 hasLoadedRecipes={recipePreviews.featuredRecipePreviewsRequest.wasExecuted}
100 searchRecipes={e => this.searchRecipes(e)} 106 showAddServiceInterface={showAddServiceInterface}
101 resetSearch={() => this.resetSearch()} 107 searchRecipes={e => this.searchRecipes(e)}
102 searchNeedle={this.state.needle} 108 resetSearch={() => this.resetSearch()}
103 serviceStatus={services.actionStatus} 109 searchNeedle={this.state.needle}
104 devRecipesCount={recipePreviews.dev.length} 110 serviceStatus={services.actionStatus}
105 /> 111 devRecipesCount={recipePreviews.dev.length}
112 />
113 </ErrorBoundary>
106 ); 114 );
107 } 115 }
108} 116}
diff --git a/src/containers/settings/ServicesScreen.js b/src/containers/settings/ServicesScreen.js
index c1a133ef7..b70a5506e 100644
--- a/src/containers/settings/ServicesScreen.js
+++ b/src/containers/settings/ServicesScreen.js
@@ -9,6 +9,7 @@ import ServiceStore from '../../stores/ServicesStore';
9import { gaPage } from '../../lib/analytics'; 9import { gaPage } from '../../lib/analytics';
10 10
11import ServicesDashboard from '../../components/settings/services/ServicesDashboard'; 11import ServicesDashboard from '../../components/settings/services/ServicesDashboard';
12import ErrorBoundary from '../../components/util/ErrorBoundary';
12 13
13export default @inject('stores', 'actions') @observer class ServicesScreen extends Component { 14export default @inject('stores', 'actions') @observer class ServicesScreen extends Component {
14 componentDidMount() { 15 componentDidMount() {
@@ -40,20 +41,22 @@ export default @inject('stores', 'actions') @observer class ServicesScreen exten
40 } 41 }
41 42
42 return ( 43 return (
43 <ServicesDashboard 44 <ErrorBoundary>
44 user={user.data} 45 <ServicesDashboard
45 services={allServices} 46 user={user.data}
46 status={services.actionStatus} 47 services={allServices}
47 deleteService={() => this.deleteService()} 48 status={services.actionStatus}
48 toggleService={toggleService} 49 deleteService={() => this.deleteService()}
49 isLoading={isLoading} 50 toggleService={toggleService}
50 filterServices={filter} 51 isLoading={isLoading}
51 resetFilter={resetFilter} 52 filterServices={filter}
52 goTo={router.push} 53 resetFilter={resetFilter}
53 servicesRequestFailed={services.allServicesRequest.wasExecuted && services.allServicesRequest.isError} 54 goTo={router.push}
54 retryServicesRequest={() => services.allServicesRequest.reload()} 55 servicesRequestFailed={services.allServicesRequest.wasExecuted && services.allServicesRequest.isError}
55 searchNeedle={services.filterNeedle} 56 retryServicesRequest={() => services.allServicesRequest.reload()}
56 /> 57 searchNeedle={services.filterNeedle}
58 />
59 </ErrorBoundary>
57 ); 60 );
58 } 61 }
59} 62}
diff --git a/src/containers/settings/SettingsWindow.js b/src/containers/settings/SettingsWindow.js
index 55589d0be..6d9e0ee77 100644
--- a/src/containers/settings/SettingsWindow.js
+++ b/src/containers/settings/SettingsWindow.js
@@ -6,6 +6,7 @@ import ServicesStore from '../../stores/ServicesStore';
6 6
7import Layout from '../../components/settings/SettingsLayout'; 7import Layout from '../../components/settings/SettingsLayout';
8import Navigation from '../../components/settings/navigation/SettingsNavigation'; 8import Navigation from '../../components/settings/navigation/SettingsNavigation';
9import ErrorBoundary from '../../components/util/ErrorBoundary';
9 10
10export default @inject('stores', 'actions') @observer class SettingsContainer extends Component { 11export default @inject('stores', 'actions') @observer class SettingsContainer extends Component {
11 render() { 12 render() {
@@ -19,12 +20,14 @@ export default @inject('stores', 'actions') @observer class SettingsContainer ex
19 ); 20 );
20 21
21 return ( 22 return (
22 <Layout 23 <ErrorBoundary>
23 navigation={navigation} 24 <Layout
24 closeSettings={closeSettings} 25 navigation={navigation}
25 > 26 closeSettings={closeSettings}
26 {children} 27 >
27 </Layout> 28 {children}
29 </Layout>
30 </ErrorBoundary>
28 ); 31 );
29 } 32 }
30} 33}
diff --git a/src/containers/subscription/SubscriptionFormScreen.js b/src/containers/subscription/SubscriptionFormScreen.js
index 50ed19bef..3eb7b6255 100644
--- a/src/containers/subscription/SubscriptionFormScreen.js
+++ b/src/containers/subscription/SubscriptionFormScreen.js
@@ -12,7 +12,7 @@ const { BrowserWindow } = remote;
12export default @inject('stores', 'actions') @observer class SubscriptionFormScreen extends Component { 12export default @inject('stores', 'actions') @observer class SubscriptionFormScreen extends Component {
13 static propTypes = { 13 static propTypes = {
14 onCloseWindow: PropTypes.func, 14 onCloseWindow: PropTypes.func,
15 content: PropTypes.oneOrManyChildElements, 15 content: PropTypes.node,
16 showSkipOption: PropTypes.bool, 16 showSkipOption: PropTypes.bool,
17 skipAction: PropTypes.func, 17 skipAction: PropTypes.func,
18 skipButtonLabel: PropTypes.string, 18 skipButtonLabel: PropTypes.string,
diff --git a/src/electron/Settings.js b/src/electron/Settings.js
index ed9733bfe..63f43b6b7 100644
--- a/src/electron/Settings.js
+++ b/src/electron/Settings.js
@@ -8,6 +8,7 @@ const debug = require('debug')('Franz:Settings');
8 8
9export default class Settings { 9export default class Settings {
10 type = ''; 10 type = '';
11
11 @observable store = {}; 12 @observable store = {};
12 13
13 constructor(type, defaultState = {}) { 14 constructor(type, defaultState = {}) {
diff --git a/src/electron/ipc-api/download.js b/src/electron/ipc-api/download.js
index 9e504834d..e6703af2d 100644
--- a/src/electron/ipc-api/download.js
+++ b/src/electron/ipc-api/download.js
@@ -12,7 +12,7 @@ function decodeBase64Image(dataString) {
12 return new Error('Invalid input string'); 12 return new Error('Invalid input string');
13 } 13 }
14 14
15 return new Buffer(matches[2], 'base64'); 15 return Buffer.from(matches[2], 'base64');
16} 16}
17 17
18export default (params) => { 18export default (params) => {
diff --git a/src/features/delayApp/Component.js b/src/features/delayApp/Component.js
index 403340c7b..6e0532c9a 100644
--- a/src/features/delayApp/Component.js
+++ b/src/features/delayApp/Component.js
@@ -6,7 +6,7 @@ import injectSheet from 'react-jss';
6 6
7import Button from '../../components/ui/Button'; 7import Button from '../../components/ui/Button';
8 8
9import { config } from './'; 9import { config } from '.';
10import styles from './styles'; 10import styles from './styles';
11 11
12const messages = defineMessages({ 12const messages = defineMessages({
@@ -38,11 +38,15 @@ export default @inject('actions') @injectSheet(styles) @observer class DelayApp
38 countdown: config.delayDuration, 38 countdown: config.delayDuration,
39 } 39 }
40 40
41 countdownInterval = null;
42
43 countdownIntervalTimeout = 1000;
44
41 componentDidMount() { 45 componentDidMount() {
42 this.countdownInterval = setInterval(() => { 46 this.countdownInterval = setInterval(() => {
43 this.setState({ 47 this.setState(prevState => ({
44 countdown: this.state.countdown - this.countdownIntervalTimeout, 48 countdown: prevState.countdown - this.countdownIntervalTimeout,
45 }); 49 }));
46 50
47 if (this.state.countdown <= 0) { 51 if (this.state.countdown <= 0) {
48 // reload(); 52 // reload();
@@ -55,9 +59,6 @@ export default @inject('actions') @injectSheet(styles) @observer class DelayApp
55 clearInterval(this.countdownInterval); 59 clearInterval(this.countdownInterval);
56 } 60 }
57 61
58 countdownInterval = null;
59 countdownIntervalTimeout = 1000;
60
61 render() { 62 render() {
62 const { classes, actions } = this.props; 63 const { classes, actions } = this.props;
63 const { intl } = this.context; 64 const { intl } = this.context;
@@ -71,9 +72,11 @@ export default @inject('actions') @injectSheet(styles) @observer class DelayApp
71 buttonType="inverted" 72 buttonType="inverted"
72 onClick={() => actions.ui.openSettings({ path: 'user' })} 73 onClick={() => actions.ui.openSettings({ path: 'user' })}
73 /> 74 />
74 <p className="footnote">{intl.formatMessage(messages.text, { 75 <p className="footnote">
75 seconds: this.state.countdown / 1000, 76 {intl.formatMessage(messages.text, {
76 })}</p> 77 seconds: this.state.countdown / 1000,
78 })}
79 </p>
77 </div> 80 </div>
78 ); 81 );
79 } 82 }
diff --git a/src/features/delayApp/index.js b/src/features/delayApp/index.js
index 9ffa1d2fd..d5c544b78 100644
--- a/src/features/delayApp/index.js
+++ b/src/features/delayApp/index.js
@@ -67,4 +67,3 @@ export default function init(stores) {
67} 67}
68 68
69export const Component = DelayAppComponent; 69export const Component = DelayAppComponent;
70
diff --git a/src/features/serviceProxy/index.js b/src/features/serviceProxy/index.js
index ee0b4e79c..4bea327ad 100644
--- a/src/features/serviceProxy/index.js
+++ b/src/features/serviceProxy/index.js
@@ -23,15 +23,18 @@ export default function init(stores) {
23 23
24 const services = stores.services.enabled; 24 const services = stores.services.enabled;
25 const isPremiumUser = stores.user.data.isPremium; 25 const isPremiumUser = stores.user.data.isPremium;
26 const proxySettings = stores.settings.proxy;
27
28 debug('Service Proxy autorun');
26 29
27 services.forEach((service) => { 30 services.forEach((service) => {
28 const s = session.fromPartition(`persist:service-${service.id}`); 31 const s = session.fromPartition(`persist:service-${service.id}`);
29 32
30 if (config.isEnabled && (isPremiumUser || !config.isPremium)) { 33 if (config.isEnabled && (isPremiumUser || !config.isPremium)) {
31 const serviceProxyConfig = stores.settings.proxy[service.id]; 34 const serviceProxyConfig = proxySettings[service.id];
32 35
33 if (serviceProxyConfig && serviceProxyConfig.isEnabled && serviceProxyConfig.host) { 36 if (serviceProxyConfig && serviceProxyConfig.isEnabled && serviceProxyConfig.host) {
34 const proxyHost = serviceProxyConfig.host; 37 const proxyHost = `${serviceProxyConfig.host}${serviceProxyConfig.port ? `:${serviceProxyConfig.port}` : ''}`;
35 debug(`Setting proxy config from service settings for "${service.name}" (${service.id}) to`, proxyHost); 38 debug(`Setting proxy config from service settings for "${service.name}" (${service.id}) to`, proxyHost);
36 39
37 s.setProxy({ proxyRules: proxyHost }, () => { 40 s.setProxy({ proxyRules: proxyHost }, () => {
@@ -42,4 +45,3 @@ export default function init(stores) {
42 }); 45 });
43 }); 46 });
44} 47}
45
diff --git a/src/helpers/array-helpers.js b/src/helpers/array-helpers.js
new file mode 100644
index 000000000..ffb3b63dc
--- /dev/null
+++ b/src/helpers/array-helpers.js
@@ -0,0 +1,4 @@
1export const shuffleArray = arr => arr
2 .map(a => [Math.random(), a])
3 .sort((a, b) => a[0] - b[0])
4 .map(a => a[1]);
diff --git a/src/helpers/i18n-helpers.js b/src/helpers/i18n-helpers.js
index 00a2061c1..091b86b06 100644
--- a/src/helpers/i18n-helpers.js
+++ b/src/helpers/i18n-helpers.js
@@ -1,4 +1,6 @@
1export function getLocale({ locale, locales, defaultLocale, fallbackLocale }) { 1export function getLocale({
2 locale, locales, defaultLocale, fallbackLocale,
3}) {
2 let localeStr = locale; 4 let localeStr = locale;
3 if (locales[locale] === undefined) { 5 if (locales[locale] === undefined) {
4 let localeFuzzy; 6 let localeFuzzy;
@@ -25,3 +27,29 @@ export function getLocale({ locale, locales, defaultLocale, fallbackLocale }) {
25 27
26 return localeStr; 28 return localeStr;
27} 29}
30
31export function getSelectOptions({ locales, resetToDefaultText = '' }) {
32 let options = [];
33
34 if (resetToDefaultText) {
35 options = [
36 {
37 value: '',
38 label: resetToDefaultText,
39 }, {
40 value: '───',
41 label: '───',
42 disabled: true,
43 },
44 ];
45 }
46
47 Object.keys(locales).sort(Intl.Collator().compare).forEach((key) => {
48 options.push({
49 value: key,
50 label: locales[key],
51 });
52 });
53
54 return options;
55}
diff --git a/src/i18n/locales/ca.json b/src/i18n/locales/ca.json
index 117e66d76..ed6f7bacd 100644
--- a/src/i18n/locales/ca.json
+++ b/src/i18n/locales/ca.json
@@ -1,7 +1,9 @@
1{ 1{
2 "feature.delayApp.action" : "Get a Franz Supporter License", 2 "app.errorHandler.action" : "Recarrega",
3 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting", 3 "app.errorHandler.headline" : "Something went wrong",
4 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.", 4 "feature.delayApp.action" : "Aconsegueix una llicència de suport per a Franz",
5 "feature.delayApp.headline" : "Si us plau, compra una llicència de suport per a Franz per saltar l'espera",
6 "feature.delayApp.text" : "Franz continuarà en {seconds} segons",
5 "global.api.unhealthy" : "No es pot connectar amb els serveis en línia de Franz", 7 "global.api.unhealthy" : "No es pot connectar amb els serveis en línia de Franz",
6 "global.notConnectedToTheInternet" : "No esteu connectat a Internet.", 8 "global.notConnectedToTheInternet" : "No esteu connectat a Internet.",
7 "import.headline" : "Importa els teus serveis Franz 4", 9 "import.headline" : "Importa els teus serveis Franz 4",
@@ -79,7 +81,7 @@
79 "password.noUser" : "No s'ha trobat cap usuari amb aquesta adreça de correu electrònic", 81 "password.noUser" : "No s'ha trobat cap usuari amb aquesta adreça de correu electrònic",
80 "password.submit.label" : "Enviar", 82 "password.submit.label" : "Enviar",
81 "password.successInfo" : "Comproveu el vostre correu electrònic", 83 "password.successInfo" : "Comproveu el vostre correu electrònic",
82 "premiumFeature.button.upgradeAccount" : "Upgrade account", 84 "premiumFeature.button.upgradeAccount" : "Millorar el teu compte",
83 "pricing.headline" : "Donar suport a Franz", 85 "pricing.headline" : "Donar suport a Franz",
84 "pricing.link.skipPayment" : "No vull donar suport al desenvolupament de Franz.", 86 "pricing.link.skipPayment" : "No vull donar suport al desenvolupament de Franz.",
85 "pricing.submit.label" : "Vull donar suport al desenvolupament de Franz", 87 "pricing.submit.label" : "Vull donar suport al desenvolupament de Franz",
@@ -90,6 +92,11 @@
90 "service.crashHandler.text" : "{name} ha causat un error.", 92 "service.crashHandler.text" : "{name} ha causat un error.",
91 "service.disabledHandler.action" : "Activar {name}", 93 "service.disabledHandler.action" : "Activar {name}",
92 "service.disabledHandler.headline" : "{name} està desactivat", 94 "service.disabledHandler.headline" : "{name} està desactivat",
95 "service.errorHandler.action" : "Recarrega {name}",
96 "service.errorHandler.editAction" : "Edita {name}",
97 "service.errorHandler.headline" : "Oh no!",
98 "service.errorHandler.message" : "Error",
99 "service.errorHandler.text" : "{name} has failed to load.",
93 "services.getStarted" : "Introducció", 100 "services.getStarted" : "Introducció",
94 "services.welcome" : "Benvingut a Franz", 101 "services.welcome" : "Benvingut a Franz",
95 "settings.account.account.editButton" : "Editar Compte", 102 "settings.account.account.editButton" : "Editar Compte",
@@ -120,7 +127,7 @@
120 "settings.app.form.autoLaunchInBackground" : "Obrir en segon plà", 127 "settings.app.form.autoLaunchInBackground" : "Obrir en segon plà",
121 "settings.app.form.autoLaunchOnStart" : "Iniciar Franz a l'inici", 128 "settings.app.form.autoLaunchOnStart" : "Iniciar Franz a l'inici",
122 "settings.app.form.beta" : "Inclou versions beta", 129 "settings.app.form.beta" : "Inclou versions beta",
123 "settings.app.form.darkMode" : "Join the Dark Side", 130 "settings.app.form.darkMode" : "Uneix-te al Cantó Fosc",
124 "settings.app.form.enableGPUAcceleration" : "Activar acceleració GPU", 131 "settings.app.form.enableGPUAcceleration" : "Activar acceleració GPU",
125 "settings.app.form.enableMenuBar" : "Mostra Franz a la barra de menú", 132 "settings.app.form.enableMenuBar" : "Mostra Franz a la barra de menú",
126 "settings.app.form.enableSpellchecking" : "Habilita la comprobació ortogràfica", 133 "settings.app.form.enableSpellchecking" : "Habilita la comprobació ortogràfica",
@@ -131,7 +138,7 @@
131 "settings.app.form.runInBackground" : "Mantén a Franz en segon pla en tancar la finestra", 138 "settings.app.form.runInBackground" : "Mantén a Franz en segon pla en tancar la finestra",
132 "settings.app.form.showDisabledServices" : "Mostra les pestanyes dels serveis desactivats", 139 "settings.app.form.showDisabledServices" : "Mostra les pestanyes dels serveis desactivats",
133 "settings.app.form.showMessagesBadgesWhenMuted" : "Mostra la insígnia de missatges no llegits quan les notificacions estiguin desactivades", 140 "settings.app.form.showMessagesBadgesWhenMuted" : "Mostra la insígnia de missatges no llegits quan les notificacions estiguin desactivades",
134 "settings.app.form.spellcheckerLanguage" : "Spell checking language", 141 "settings.app.form.spellcheckerLanguage" : "Corrector ortogràfic",
135 "settings.app.headline" : "Configuració", 142 "settings.app.headline" : "Configuració",
136 "settings.app.headlineAdvanced" : "Avançat", 143 "settings.app.headlineAdvanced" : "Avançat",
137 "settings.app.headlineAppearance" : "Aparença", 144 "settings.app.headlineAppearance" : "Aparença",
@@ -172,7 +179,7 @@
172 "settings.service.form.editServiceHeadline" : "Edita {name}", 179 "settings.service.form.editServiceHeadline" : "Edita {name}",
173 "settings.service.form.enableAudio" : "Activa l'àudio", 180 "settings.service.form.enableAudio" : "Activa l'àudio",
174 "settings.service.form.enableBadge" : "Mostra les insígnies als missatges no llegits.", 181 "settings.service.form.enableBadge" : "Mostra les insígnies als missatges no llegits.",
175 "settings.service.form.enableDarkMode" : "Enable Dark Mode", 182 "settings.service.form.enableDarkMode" : "Activar el Mode Fosc",
176 "settings.service.form.enableNotification" : "Activa les notificacions", 183 "settings.service.form.enableNotification" : "Activa les notificacions",
177 "settings.service.form.enableService" : "Activa el servei", 184 "settings.service.form.enableService" : "Activa el servei",
178 "settings.service.form.headlineBadges" : "Insígnies de missatges no llegits", 185 "settings.service.form.headlineBadges" : "Insígnies de missatges no llegits",
@@ -185,13 +192,17 @@
185 "settings.service.form.indirectMessages" : "Mostra la insígnia de missatge per a tots els missatges nous", 192 "settings.service.form.indirectMessages" : "Mostra la insígnia de missatge per a tots els missatges nous",
186 "settings.service.form.isMutedInfo" : "Quan es desactiva, tots els sons de notificació i reproducció d'àudio es silenciaran", 193 "settings.service.form.isMutedInfo" : "Quan es desactiva, tots els sons de notificació i reproducció d'àudio es silenciaran",
187 "settings.service.form.name" : "Nom", 194 "settings.service.form.name" : "Nom",
188 "settings.service.form.proxy.headline" : "Proxy Settings", 195 "settings.service.form.proxy.headline" : "HTTP\/HTTPS Proxy Settings",
189 "settings.service.form.proxy.host" : "Proxy Host\/IP", 196 "settings.service.form.proxy.host" : "Host Proxy \/ IP",
190 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.", 197 "settings.service.form.proxy.info" : "Els ajustaments del Proxy no es sincronitzaran amb els servidors de Franz",
191 "settings.service.form.proxy.isEnabled" : "Use Proxy", 198 "settings.service.form.proxy.isEnabled" : "Utilitzar Proxy",
192 "settings.service.form.proxy.password" : "Password (optional)", 199 "settings.service.form.proxy.password" : "Contrasenya (opcional)",
193 "settings.service.form.proxy.user" : "User (optional)", 200 "settings.service.form.proxy.port" : "Port",
201 "settings.service.form.proxy.restartInfo" : "Please restart Franz after changing proxy Settings.",
202 "settings.service.form.proxy.user" : "Usuari (opcional)",
194 "settings.service.form.saveButton" : "Desa el servei", 203 "settings.service.form.saveButton" : "Desa el servei",
204 "settings.service.form.spellcheckerLanguage" : "Spell checking Language",
205 "settings.service.form.spellcheckerLanguage.default" : "Use System Default ({default})",
195 "settings.service.form.tabHosted" : "Allotjat", 206 "settings.service.form.tabHosted" : "Allotjat",
196 "settings.service.form.tabOnPremise" : "Allotjat per si mateix ⭐️", 207 "settings.service.form.tabOnPremise" : "Allotjat per si mateix ⭐️",
197 "settings.service.form.team" : "Equip", 208 "settings.service.form.team" : "Equip",
@@ -234,11 +245,11 @@
234 "subscription.features.ads" : "Sense anuncis, mai!", 245 "subscription.features.ads" : "Sense anuncis, mai!",
235 "subscription.features.comingSoon" : "properament", 246 "subscription.features.comingSoon" : "properament",
236 "subscription.features.encryptedSync" : "Sincronització de sessió xifrada", 247 "subscription.features.encryptedSync" : "Sincronització de sessió xifrada",
237 "subscription.features.noInterruptions" : "No app delays & nagging to upgrade license", 248 "subscription.features.noInterruptions" : "Sense retards ni molestes actualitzacions de llicències ",
238 "subscription.features.onpremise" : "Afegiu serveis en premissa\/allotjats com HipChat", 249 "subscription.features.onpremise" : "Afegiu serveis en premissa\/allotjats com HipChat",
239 "subscription.features.onpremise.mattermost" : "Add on-premise\/hosted services like Mattermost", 250 "subscription.features.onpremise.mattermost" : "Afegir serveis allotjats com Mattermost",
240 "subscription.features.proxy" : "Proxy support for services", 251 "subscription.features.proxy" : "Suport de Proxy per a serveis",
241 "subscription.features.spellchecker" : "Support for spellchecker", 252 "subscription.features.spellchecker" : "Suport per corrector ortogràfic",
242 "subscription.includedFeatures" : "El compte de pagament Franz Premium Supporter inclou", 253 "subscription.includedFeatures" : "El compte de pagament Franz Premium Supporter inclou",
243 "subscription.paymentSessionError" : "No s'ha pogut inicialitzar el formulari de pagament", 254 "subscription.paymentSessionError" : "No s'ha pogut inicialitzar el formulari de pagament",
244 "subscription.submit.label" : "Vull donar suport al desenvolupament de Franz", 255 "subscription.submit.label" : "Vull donar suport al desenvolupament de Franz",
diff --git a/src/i18n/locales/cs.json b/src/i18n/locales/cs.json
index eb8088e28..b8bfd2526 100644
--- a/src/i18n/locales/cs.json
+++ b/src/i18n/locales/cs.json
@@ -1,4 +1,6 @@
1{ 1{
2 "app.errorHandler.action" : "Obnovit",
3 "app.errorHandler.headline" : "Something went wrong",
2 "feature.delayApp.action" : "Get a Franz Supporter License", 4 "feature.delayApp.action" : "Get a Franz Supporter License",
3 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting", 5 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting",
4 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.", 6 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.",
@@ -90,6 +92,11 @@
90 "service.crashHandler.text" : "{name} způsobil chybu.", 92 "service.crashHandler.text" : "{name} způsobil chybu.",
91 "service.disabledHandler.action" : "Zapnout {name}", 93 "service.disabledHandler.action" : "Zapnout {name}",
92 "service.disabledHandler.headline" : "{name} je vypnutý", 94 "service.disabledHandler.headline" : "{name} je vypnutý",
95 "service.errorHandler.action" : "Načíst znovu {name}",
96 "service.errorHandler.editAction" : "Upravit {name}",
97 "service.errorHandler.headline" : "Ale ne!",
98 "service.errorHandler.message" : "Chyba",
99 "service.errorHandler.text" : "{name} has failed to load.",
93 "services.getStarted" : "Začněme", 100 "services.getStarted" : "Začněme",
94 "services.welcome" : "Vítejte v programu Franz", 101 "services.welcome" : "Vítejte v programu Franz",
95 "settings.account.account.editButton" : "Upravit účet", 102 "settings.account.account.editButton" : "Upravit účet",
@@ -185,13 +192,17 @@
185 "settings.service.form.indirectMessages" : "Zobrazovat znak zprávy pro všechny nové zprávy", 192 "settings.service.form.indirectMessages" : "Zobrazovat znak zprávy pro všechny nové zprávy",
186 "settings.service.form.isMutedInfo" : "Pokud je vypnuto, všechny zvuky notifikací a jiného audia budou ztišeny", 193 "settings.service.form.isMutedInfo" : "Pokud je vypnuto, všechny zvuky notifikací a jiného audia budou ztišeny",
187 "settings.service.form.name" : "Jméno", 194 "settings.service.form.name" : "Jméno",
188 "settings.service.form.proxy.headline" : "Proxy Settings", 195 "settings.service.form.proxy.headline" : "HTTP\/HTTPS Proxy Settings",
189 "settings.service.form.proxy.host" : "Proxy Host\/IP", 196 "settings.service.form.proxy.host" : "Proxy Host\/IP",
190 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.", 197 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.",
191 "settings.service.form.proxy.isEnabled" : "Use Proxy", 198 "settings.service.form.proxy.isEnabled" : "Use Proxy",
192 "settings.service.form.proxy.password" : "Password (optional)", 199 "settings.service.form.proxy.password" : "Password (optional)",
200 "settings.service.form.proxy.port" : "Port",
201 "settings.service.form.proxy.restartInfo" : "Please restart Franz after changing proxy Settings.",
193 "settings.service.form.proxy.user" : "User (optional)", 202 "settings.service.form.proxy.user" : "User (optional)",
194 "settings.service.form.saveButton" : "Uložit službu", 203 "settings.service.form.saveButton" : "Uložit službu",
204 "settings.service.form.spellcheckerLanguage" : "Spell checking Language",
205 "settings.service.form.spellcheckerLanguage.default" : "Use System Default ({default})",
195 "settings.service.form.tabHosted" : "Hostováno", 206 "settings.service.form.tabHosted" : "Hostováno",
196 "settings.service.form.tabOnPremise" : "Samostatně hostované ⭐️", 207 "settings.service.form.tabOnPremise" : "Samostatně hostované ⭐️",
197 "settings.service.form.team" : "Tým", 208 "settings.service.form.team" : "Tým",
diff --git a/src/i18n/locales/de.json b/src/i18n/locales/de.json
index 6aa909519..b5abb56d4 100644
--- a/src/i18n/locales/de.json
+++ b/src/i18n/locales/de.json
@@ -1,4 +1,6 @@
1{ 1{
2 "app.errorHandler.action" : "Neuladen",
3 "app.errorHandler.headline" : "Es trat ein Fehler auf",
2 "feature.delayApp.action" : "Upgrade deinen Account", 4 "feature.delayApp.action" : "Upgrade deinen Account",
3 "feature.delayApp.headline" : "Erspare dir das Warten mit einer Franz Supporter Lizenz", 5 "feature.delayApp.headline" : "Erspare dir das Warten mit einer Franz Supporter Lizenz",
4 "feature.delayApp.text" : "Es geht in {seconds} Sekunden weiter.", 6 "feature.delayApp.text" : "Es geht in {seconds} Sekunden weiter.",
@@ -48,7 +50,7 @@
48 "menu.edit.startDictation" : "Diktat starten", 50 "menu.edit.startDictation" : "Diktat starten",
49 "menu.edit.startSpeaking" : "Sprachausgabe starten", 51 "menu.edit.startSpeaking" : "Sprachausgabe starten",
50 "menu.edit.stopSpeaking" : "Sprachausgabe stoppen", 52 "menu.edit.stopSpeaking" : "Sprachausgabe stoppen",
51 "menu.edit.undo" : "Widerrufen", 53 "menu.edit.undo" : "Rückgängig",
52 "menu.file" : "Datei", 54 "menu.file" : "Datei",
53 "menu.help" : "Hilfe", 55 "menu.help" : "Hilfe",
54 "menu.help.changelog" : "Changelog", 56 "menu.help.changelog" : "Changelog",
@@ -90,6 +92,11 @@
90 "service.crashHandler.text" : "{name} hat einen Fehler verursacht.", 92 "service.crashHandler.text" : "{name} hat einen Fehler verursacht.",
91 "service.disabledHandler.action" : "{name} aktivieren", 93 "service.disabledHandler.action" : "{name} aktivieren",
92 "service.disabledHandler.headline" : "{name} ist deaktiviert", 94 "service.disabledHandler.headline" : "{name} ist deaktiviert",
95 "service.errorHandler.action" : "{name} neuladen",
96 "service.errorHandler.editAction" : "{name} bearbeiten",
97 "service.errorHandler.headline" : "Oh nein!",
98 "service.errorHandler.message" : "Fehler",
99 "service.errorHandler.text" : "{name} konnte nicht geladen werden.",
93 "services.getStarted" : "Loslegen", 100 "services.getStarted" : "Loslegen",
94 "services.welcome" : "Willkommen bei Franz.", 101 "services.welcome" : "Willkommen bei Franz.",
95 "settings.account.account.editButton" : "Konto bearbeiten", 102 "settings.account.account.editButton" : "Konto bearbeiten",
@@ -124,10 +131,10 @@
124 "settings.app.form.enableGPUAcceleration" : "Hardwarebeschleunigung aktivieren", 131 "settings.app.form.enableGPUAcceleration" : "Hardwarebeschleunigung aktivieren",
125 "settings.app.form.enableMenuBar" : "Franz in Menüleiste anzeigen", 132 "settings.app.form.enableMenuBar" : "Franz in Menüleiste anzeigen",
126 "settings.app.form.enableSpellchecking" : "Rechtschreibprüfung aktivieren", 133 "settings.app.form.enableSpellchecking" : "Rechtschreibprüfung aktivieren",
127 "settings.app.form.enableSystemTray" : "Franz in der Taskleiste anzeigen", 134 "settings.app.form.enableSystemTray" : "Franz im Infobereich anzeigen",
128 "settings.app.form.hideDockIcon" : "Franz Icon im Dock ausblenden", 135 "settings.app.form.hideDockIcon" : "Franz Icon im Dock ausblenden",
129 "settings.app.form.language" : "Sprache", 136 "settings.app.form.language" : "Sprache",
130 "settings.app.form.minimizeToSystemTray" : "Franz in die Systemleiste minimieren", 137 "settings.app.form.minimizeToSystemTray" : "Franz in den Infobereich minimieren",
131 "settings.app.form.runInBackground" : "Franz im Hintergrund behalten, wenn das Fenster geschlossen wird", 138 "settings.app.form.runInBackground" : "Franz im Hintergrund behalten, wenn das Fenster geschlossen wird",
132 "settings.app.form.showDisabledServices" : "Deaktivierte Services-Tabs anzeigen", 139 "settings.app.form.showDisabledServices" : "Deaktivierte Services-Tabs anzeigen",
133 "settings.app.form.showMessagesBadgesWhenMuted" : "Ungelesene Nachrichten zeigen, wenn die Benachrichtigungen deaktiviert sind", 140 "settings.app.form.showMessagesBadgesWhenMuted" : "Ungelesene Nachrichten zeigen, wenn die Benachrichtigungen deaktiviert sind",
@@ -154,11 +161,11 @@
154 "settings.recipes.all" : "Alle Dienste", 161 "settings.recipes.all" : "Alle Dienste",
155 "settings.recipes.dev" : "Entwicklung", 162 "settings.recipes.dev" : "Entwicklung",
156 "settings.recipes.headline" : "Verfügbare Dienste", 163 "settings.recipes.headline" : "Verfügbare Dienste",
157 "settings.recipes.missingService" : "Fehlt ein Service?", 164 "settings.recipes.missingService" : "Fehlt ein Dienst?",
158 "settings.recipes.mostPopular" : "Am beliebtesten", 165 "settings.recipes.mostPopular" : "Am beliebtesten",
159 "settings.recipes.nothingFound" : "Entschuldigung, aber der von Dir gesuchte Dienst konnte nicht gefunden werden.", 166 "settings.recipes.nothingFound" : "Entschuldigung, aber der von Dir gesuchte Dienst konnte nicht gefunden werden.",
160 "settings.recipes.servicesSuccessfulAddedInfo" : "Dienst erfolgreich hinzugefügt", 167 "settings.recipes.servicesSuccessfulAddedInfo" : "Dienst erfolgreich hinzugefügt",
161 "settings.searchService" : "Service suchen", 168 "settings.searchService" : "Dienst suchen",
162 "settings.service.error.goBack" : "Zurück zu den Diensten", 169 "settings.service.error.goBack" : "Zurück zu den Diensten",
163 "settings.service.error.headline" : "Fehler", 170 "settings.service.error.headline" : "Fehler",
164 "settings.service.error.message" : "Das Dienst-Rezept konnte nicht geladen werden.", 171 "settings.service.error.message" : "Das Dienst-Rezept konnte nicht geladen werden.",
@@ -185,13 +192,17 @@
185 "settings.service.form.indirectMessages" : "Nachrichten-Badge für alle neuen Nachrichten anzeigen", 192 "settings.service.form.indirectMessages" : "Nachrichten-Badge für alle neuen Nachrichten anzeigen",
186 "settings.service.form.isMutedInfo" : "Sämtliche Wiedergabe von Tönen wird deaktiviert", 193 "settings.service.form.isMutedInfo" : "Sämtliche Wiedergabe von Tönen wird deaktiviert",
187 "settings.service.form.name" : "Name", 194 "settings.service.form.name" : "Name",
188 "settings.service.form.proxy.headline" : "Proxy Einstellungen", 195 "settings.service.form.proxy.headline" : "HTTP\/HTTPS Proxy Einstellungen",
189 "settings.service.form.proxy.host" : "Proxy Host\/IP", 196 "settings.service.form.proxy.host" : "Proxy Host\/IP",
190 "settings.service.form.proxy.info" : "Proxy Einstellungen werden nicht mit den Franz Servern synchronisiert.", 197 "settings.service.form.proxy.info" : "Proxy Einstellungen werden nicht mit den Franz Servern synchronisiert.",
191 "settings.service.form.proxy.isEnabled" : "Proxy Server verwenden", 198 "settings.service.form.proxy.isEnabled" : "Proxy Server verwenden",
192 "settings.service.form.proxy.password" : "Passwort (optional)", 199 "settings.service.form.proxy.password" : "Passwort (optional)",
200 "settings.service.form.proxy.port" : "Port",
201 "settings.service.form.proxy.restartInfo" : "Bitte starte Franz nach dem Ändern der Proxy Einstellungen neu.",
193 "settings.service.form.proxy.user" : "Benutzer (optional)", 202 "settings.service.form.proxy.user" : "Benutzer (optional)",
194 "settings.service.form.saveButton" : "Dienst speichern", 203 "settings.service.form.saveButton" : "Dienst speichern",
204 "settings.service.form.spellcheckerLanguage" : "Sprache für Rechtschreibprüfung",
205 "settings.service.form.spellcheckerLanguage.default" : "Standard benutzen ({default})",
195 "settings.service.form.tabHosted" : "Gehostet", 206 "settings.service.form.tabHosted" : "Gehostet",
196 "settings.service.form.tabOnPremise" : "Selbst gehostet ⭐️", 207 "settings.service.form.tabOnPremise" : "Selbst gehostet ⭐️",
197 "settings.service.form.team" : "Team", 208 "settings.service.form.team" : "Team",
@@ -238,7 +249,7 @@
238 "subscription.features.onpremise" : "Integration von gehosteten Diensten, wie HipChat", 249 "subscription.features.onpremise" : "Integration von gehosteten Diensten, wie HipChat",
239 "subscription.features.onpremise.mattermost" : "Integration von gehosteten Diensten, wie Mattermost", 250 "subscription.features.onpremise.mattermost" : "Integration von gehosteten Diensten, wie Mattermost",
240 "subscription.features.proxy" : "Proxy Support für Dienste", 251 "subscription.features.proxy" : "Proxy Support für Dienste",
241 "subscription.features.spellchecker" : "Support for spellchecker", 252 "subscription.features.spellchecker" : "Unterstützung für Rechtschreibprüfung",
242 "subscription.includedFeatures" : "Bezahlte Franz Premium Support Konten beinhalten", 253 "subscription.includedFeatures" : "Bezahlte Franz Premium Support Konten beinhalten",
243 "subscription.paymentSessionError" : "Das Zahlungs-Formular konnte nicht geladen werden.", 254 "subscription.paymentSessionError" : "Das Zahlungs-Formular konnte nicht geladen werden.",
244 "subscription.submit.label" : "Ich möchte die Entwicklung von Franz unterstützen", 255 "subscription.submit.label" : "Ich möchte die Entwicklung von Franz unterstützen",
diff --git a/src/i18n/locales/el.json b/src/i18n/locales/el.json
index 31852d20c..671eecd41 100644
--- a/src/i18n/locales/el.json
+++ b/src/i18n/locales/el.json
@@ -1,4 +1,6 @@
1{ 1{
2 "app.errorHandler.action" : "Επαναφόρτωση",
3 "app.errorHandler.headline" : "Something went wrong",
2 "feature.delayApp.action" : "Get a Franz Supporter License", 4 "feature.delayApp.action" : "Get a Franz Supporter License",
3 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting", 5 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting",
4 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.", 6 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.",
@@ -90,6 +92,11 @@
90 "service.crashHandler.text" : "Το {name} προκάλεσε ένα σφάλμα.", 92 "service.crashHandler.text" : "Το {name} προκάλεσε ένα σφάλμα.",
91 "service.disabledHandler.action" : "Ενεργοποίηση {name}", 93 "service.disabledHandler.action" : "Ενεργοποίηση {name}",
92 "service.disabledHandler.headline" : "{name} είναι απενεργοποιημένο", 94 "service.disabledHandler.headline" : "{name} είναι απενεργοποιημένο",
95 "service.errorHandler.action" : "Επαναφόρτωση {name}",
96 "service.errorHandler.editAction" : "Επεξεργασία {name}",
97 "service.errorHandler.headline" : "Ω, όχι!",
98 "service.errorHandler.message" : "Σφάλμα",
99 "service.errorHandler.text" : "{name} has failed to load.",
93 "services.getStarted" : "Ξεκινήστε", 100 "services.getStarted" : "Ξεκινήστε",
94 "services.welcome" : "Καλώς ορίσατε στον Franz", 101 "services.welcome" : "Καλώς ορίσατε στον Franz",
95 "settings.account.account.editButton" : "Επεξεργασία λογαριασμού", 102 "settings.account.account.editButton" : "Επεξεργασία λογαριασμού",
@@ -185,13 +192,17 @@
185 "settings.service.form.indirectMessages" : "Εμφάνιση ειδοποίησης μηνύματος για όλα τα νέα μηνύματα", 192 "settings.service.form.indirectMessages" : "Εμφάνιση ειδοποίησης μηνύματος για όλα τα νέα μηνύματα",
186 "settings.service.form.isMutedInfo" : "Όλοι οι ήχοι καθώς και η αναπαραγωγή ήχου θα απενεργοποιηθούν", 193 "settings.service.form.isMutedInfo" : "Όλοι οι ήχοι καθώς και η αναπαραγωγή ήχου θα απενεργοποιηθούν",
187 "settings.service.form.name" : "Όνομα", 194 "settings.service.form.name" : "Όνομα",
188 "settings.service.form.proxy.headline" : "Proxy Settings", 195 "settings.service.form.proxy.headline" : "HTTP\/HTTPS Proxy Settings",
189 "settings.service.form.proxy.host" : "Proxy Host\/IP", 196 "settings.service.form.proxy.host" : "Proxy Host\/IP",
190 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.", 197 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.",
191 "settings.service.form.proxy.isEnabled" : "Use Proxy", 198 "settings.service.form.proxy.isEnabled" : "Use Proxy",
192 "settings.service.form.proxy.password" : "Password (optional)", 199 "settings.service.form.proxy.password" : "Password (optional)",
200 "settings.service.form.proxy.port" : "Port",
201 "settings.service.form.proxy.restartInfo" : "Please restart Franz after changing proxy Settings.",
193 "settings.service.form.proxy.user" : "User (optional)", 202 "settings.service.form.proxy.user" : "User (optional)",
194 "settings.service.form.saveButton" : "Αποθήκευση υπηρεσίας", 203 "settings.service.form.saveButton" : "Αποθήκευση υπηρεσίας",
204 "settings.service.form.spellcheckerLanguage" : "Spell checking Language",
205 "settings.service.form.spellcheckerLanguage.default" : "Use System Default ({default})",
195 "settings.service.form.tabHosted" : "Φιλοξενείται", 206 "settings.service.form.tabHosted" : "Φιλοξενείται",
196 "settings.service.form.tabOnPremise" : "Αυτο-φιλοξενείται ⭐️", 207 "settings.service.form.tabOnPremise" : "Αυτο-φιλοξενείται ⭐️",
197 "settings.service.form.team" : "Ομάδα", 208 "settings.service.form.team" : "Ομάδα",
diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json
index aa55f5dfe..99df6a0ca 100644
--- a/src/i18n/locales/en-US.json
+++ b/src/i18n/locales/en-US.json
@@ -133,12 +133,16 @@
133 "settings.service.form.iconDelete": "Delete", 133 "settings.service.form.iconDelete": "Delete",
134 "settings.service.form.iconUpload": "Drop your image, or click here", 134 "settings.service.form.iconUpload": "Drop your image, or click here",
135 "settings.service.form.enableDarkMode": "Enable Dark Mode", 135 "settings.service.form.enableDarkMode": "Enable Dark Mode",
136 "settings.service.form.proxy.headline": "Proxy Settings", 136 "settings.service.form.proxy.headline": "HTTP/HTTPS Proxy Settings",
137 "settings.service.form.proxy.isEnabled": "Use Proxy", 137 "settings.service.form.proxy.isEnabled": "Use Proxy",
138 "settings.service.form.proxy.host": "Proxy Host/IP", 138 "settings.service.form.proxy.host": "Proxy Host/IP",
139 "settings.service.form.proxy.port": "Port",
139 "settings.service.form.proxy.user": "User (optional)", 140 "settings.service.form.proxy.user": "User (optional)",
140 "settings.service.form.proxy.password": "Password (optional)", 141 "settings.service.form.proxy.password": "Password (optional)",
141 "settings.service.form.proxy.info": "Proxy settings will not synced with the Franz servers.", 142 "settings.service.form.proxy.info": "Proxy settings will not synced with the Franz servers.",
143 "settings.service.form.proxy.restartInfo": "Please restart Franz after changing proxy Settings.",
144 "settings.service.form.spellcheckerLanguage": "Spell checking Language",
145 "settings.service.form.spellcheckerLanguage.default": "Use System Default ({default})",
142 "settings.service.error.headline": "Error", 146 "settings.service.error.headline": "Error",
143 "settings.service.error.goBack": "Back to services", 147 "settings.service.error.goBack": "Back to services",
144 "settings.service.error.message": "Could not load service recipe.", 148 "settings.service.error.message": "Could not load service recipe.",
@@ -210,6 +214,11 @@
210 "service.crashHandler.text": "{name} has caused an error.", 214 "service.crashHandler.text": "{name} has caused an error.",
211 "service.crashHandler.action": "Reload {name}", 215 "service.crashHandler.action": "Reload {name}",
212 "service.crashHandler.autoReload": "Trying to automatically restore {name} in {seconds} seconds", 216 "service.crashHandler.autoReload": "Trying to automatically restore {name} in {seconds} seconds",
217 "service.errorHandler.headline": "Oh no!",
218 "service.errorHandler.text": "{name} has failed to load.",
219 "service.errorHandler.message": "Error",
220 "service.errorHandler.action": "Reload {name}",
221 "service.errorHandler.editAction": "Edit {name}",
213 "service.disabledHandler.headline": "{name} is disabled", 222 "service.disabledHandler.headline": "{name} is disabled",
214 "service.disabledHandler.action": "Enable {name}", 223 "service.disabledHandler.action": "Enable {name}",
215 "menu.edit": "Edit", 224 "menu.edit": "Edit",
@@ -262,5 +271,7 @@
262 "feature.delayApp.headline": "Please purchase a Franz Supporter License to skip waiting", 271 "feature.delayApp.headline": "Please purchase a Franz Supporter License to skip waiting",
263 "feature.delayApp.action": "Get a Franz Supporter License", 272 "feature.delayApp.action": "Get a Franz Supporter License",
264 "feature.delayApp.text": "Franz will continue in {seconds} seconds.", 273 "feature.delayApp.text": "Franz will continue in {seconds} seconds.",
265 "premiumFeature.button.upgradeAccount": "Upgrade account" 274 "premiumFeature.button.upgradeAccount": "Upgrade account",
275 "app.errorHandler.headline": "Something went wrong",
276 "app.errorHandler.action": "Reload"
266} 277}
diff --git a/src/i18n/locales/es.json b/src/i18n/locales/es.json
index a5984dd1c..669b4d2dd 100644
--- a/src/i18n/locales/es.json
+++ b/src/i18n/locales/es.json
@@ -1,7 +1,9 @@
1{ 1{
2 "feature.delayApp.action" : "Get a Franz Supporter License", 2 "app.errorHandler.action" : "Recargar",
3 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting", 3 "app.errorHandler.headline" : "Something went wrong",
4 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.", 4 "feature.delayApp.action" : "Consigue una Licencia de Soporte de Franz",
5 "feature.delayApp.headline" : "Por favor, compra una Licencia de Soporte de Franz para saltar la espera",
6 "feature.delayApp.text" : "Franz continuará en {seconds} segundos.",
5 "global.api.unhealthy" : "No es posible conectarse a los servicios en línea de Franz.", 7 "global.api.unhealthy" : "No es posible conectarse a los servicios en línea de Franz.",
6 "global.notConnectedToTheInternet" : "No estás conectado a Internet", 8 "global.notConnectedToTheInternet" : "No estás conectado a Internet",
7 "import.headline" : "Importa tus servicios de Franz 4", 9 "import.headline" : "Importa tus servicios de Franz 4",
@@ -79,7 +81,7 @@
79 "password.noUser" : "No se encontró un usuario con esa dirección de correo electrónico", 81 "password.noUser" : "No se encontró un usuario con esa dirección de correo electrónico",
80 "password.submit.label" : "Enviar", 82 "password.submit.label" : "Enviar",
81 "password.successInfo" : "Por favor revisa tu correo electrónico", 83 "password.successInfo" : "Por favor revisa tu correo electrónico",
82 "premiumFeature.button.upgradeAccount" : "Upgrade account", 84 "premiumFeature.button.upgradeAccount" : "Mejora tu cuenta",
83 "pricing.headline" : "Apoya a Franz", 85 "pricing.headline" : "Apoya a Franz",
84 "pricing.link.skipPayment" : "No quiero apoyar el desarrollo de Franz.", 86 "pricing.link.skipPayment" : "No quiero apoyar el desarrollo de Franz.",
85 "pricing.submit.label" : "Quiero apoyar el desarrollo de Franz", 87 "pricing.submit.label" : "Quiero apoyar el desarrollo de Franz",
@@ -90,6 +92,11 @@
90 "service.crashHandler.text" : "{name} ha causado un error.", 92 "service.crashHandler.text" : "{name} ha causado un error.",
91 "service.disabledHandler.action" : "Activar {name}", 93 "service.disabledHandler.action" : "Activar {name}",
92 "service.disabledHandler.headline" : "{name} está desactivado", 94 "service.disabledHandler.headline" : "{name} está desactivado",
95 "service.errorHandler.action" : "Recargar {name}",
96 "service.errorHandler.editAction" : "Editar {name}",
97 "service.errorHandler.headline" : "¡Oh, no!",
98 "service.errorHandler.message" : "Error",
99 "service.errorHandler.text" : "{name} has failed to load.",
93 "services.getStarted" : "Primeros pasos", 100 "services.getStarted" : "Primeros pasos",
94 "services.welcome" : "Bienvenido a Franz", 101 "services.welcome" : "Bienvenido a Franz",
95 "settings.account.account.editButton" : "Editar cuenta", 102 "settings.account.account.editButton" : "Editar cuenta",
@@ -120,7 +127,7 @@
120 "settings.app.form.autoLaunchInBackground" : "Abrir en segundo plano", 127 "settings.app.form.autoLaunchInBackground" : "Abrir en segundo plano",
121 "settings.app.form.autoLaunchOnStart" : "Iniciar Franz al iniciar", 128 "settings.app.form.autoLaunchOnStart" : "Iniciar Franz al iniciar",
122 "settings.app.form.beta" : "Incluir versiones beta", 129 "settings.app.form.beta" : "Incluir versiones beta",
123 "settings.app.form.darkMode" : "Join the Dark Side", 130 "settings.app.form.darkMode" : "Únete al Lado Oscuro",
124 "settings.app.form.enableGPUAcceleration" : "Habilitar aceleración de GPU", 131 "settings.app.form.enableGPUAcceleration" : "Habilitar aceleración de GPU",
125 "settings.app.form.enableMenuBar" : "Mostrar a Franz en la barra de menús", 132 "settings.app.form.enableMenuBar" : "Mostrar a Franz en la barra de menús",
126 "settings.app.form.enableSpellchecking" : "Activar corrección ortográfica", 133 "settings.app.form.enableSpellchecking" : "Activar corrección ortográfica",
@@ -131,7 +138,7 @@
131 "settings.app.form.runInBackground" : "Mantener Franz en segundo plano al cerrar la ventana", 138 "settings.app.form.runInBackground" : "Mantener Franz en segundo plano al cerrar la ventana",
132 "settings.app.form.showDisabledServices" : "Mostrar pestañas de servicios desactivados", 139 "settings.app.form.showDisabledServices" : "Mostrar pestañas de servicios desactivados",
133 "settings.app.form.showMessagesBadgesWhenMuted" : "Mostrar la insignia de mensajes sin leer cuando las notificaciones están desactivadas", 140 "settings.app.form.showMessagesBadgesWhenMuted" : "Mostrar la insignia de mensajes sin leer cuando las notificaciones están desactivadas",
134 "settings.app.form.spellcheckerLanguage" : "Spell checking language", 141 "settings.app.form.spellcheckerLanguage" : "Corrector de ortografía",
135 "settings.app.headline" : "Configuración", 142 "settings.app.headline" : "Configuración",
136 "settings.app.headlineAdvanced" : "Avanzado", 143 "settings.app.headlineAdvanced" : "Avanzado",
137 "settings.app.headlineAppearance" : "Apariencia", 144 "settings.app.headlineAppearance" : "Apariencia",
@@ -172,7 +179,7 @@
172 "settings.service.form.editServiceHeadline" : "Editar {name}", 179 "settings.service.form.editServiceHeadline" : "Editar {name}",
173 "settings.service.form.enableAudio" : "Habilitar audio", 180 "settings.service.form.enableAudio" : "Habilitar audio",
174 "settings.service.form.enableBadge" : "Mostrar señal de mensajes no leídos", 181 "settings.service.form.enableBadge" : "Mostrar señal de mensajes no leídos",
175 "settings.service.form.enableDarkMode" : "Enable Dark Mode", 182 "settings.service.form.enableDarkMode" : "Habilitar modo oscuro",
176 "settings.service.form.enableNotification" : "Activar notificaciones", 183 "settings.service.form.enableNotification" : "Activar notificaciones",
177 "settings.service.form.enableService" : "Activar servicio", 184 "settings.service.form.enableService" : "Activar servicio",
178 "settings.service.form.headlineBadges" : "Insignias de mensaje no leídos", 185 "settings.service.form.headlineBadges" : "Insignias de mensaje no leídos",
@@ -185,13 +192,17 @@
185 "settings.service.form.indirectMessages" : "Mostrar señal de notificación para todos los mensajes nuevos", 192 "settings.service.form.indirectMessages" : "Mostrar señal de notificación para todos los mensajes nuevos",
186 "settings.service.form.isMutedInfo" : "Cuando estén desactivados, todos los sonidos de notificación y la reproducción de audio serán silenciados", 193 "settings.service.form.isMutedInfo" : "Cuando estén desactivados, todos los sonidos de notificación y la reproducción de audio serán silenciados",
187 "settings.service.form.name" : "Nombre", 194 "settings.service.form.name" : "Nombre",
188 "settings.service.form.proxy.headline" : "Proxy Settings", 195 "settings.service.form.proxy.headline" : "HTTP\/HTTPS Proxy Settings",
189 "settings.service.form.proxy.host" : "Proxy Host\/IP", 196 "settings.service.form.proxy.host" : "Proxy Host\/IP",
190 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.", 197 "settings.service.form.proxy.info" : "Las configuraciones de Proxy no se sincronizarán con los servidores de Franz.",
191 "settings.service.form.proxy.isEnabled" : "Use Proxy", 198 "settings.service.form.proxy.isEnabled" : "Use Proxy",
192 "settings.service.form.proxy.password" : "Password (optional)", 199 "settings.service.form.proxy.password" : "Contraseña (opcional)",
193 "settings.service.form.proxy.user" : "User (optional)", 200 "settings.service.form.proxy.port" : "Port",
201 "settings.service.form.proxy.restartInfo" : "Please restart Franz after changing proxy Settings.",
202 "settings.service.form.proxy.user" : "Usuario (opcional)",
194 "settings.service.form.saveButton" : "Guardar servicio", 203 "settings.service.form.saveButton" : "Guardar servicio",
204 "settings.service.form.spellcheckerLanguage" : "Spell checking Language",
205 "settings.service.form.spellcheckerLanguage.default" : "Use System Default ({default})",
195 "settings.service.form.tabHosted" : "Alojado", 206 "settings.service.form.tabHosted" : "Alojado",
196 "settings.service.form.tabOnPremise" : "Auto alojado ⭐️", 207 "settings.service.form.tabOnPremise" : "Auto alojado ⭐️",
197 "settings.service.form.team" : "Equipo", 208 "settings.service.form.team" : "Equipo",
@@ -234,11 +245,11 @@
234 "subscription.features.ads" : "¡Sin publicidad, para siempre!", 245 "subscription.features.ads" : "¡Sin publicidad, para siempre!",
235 "subscription.features.comingSoon" : "próximamente", 246 "subscription.features.comingSoon" : "próximamente",
236 "subscription.features.encryptedSync" : "Sincronización de sesión encriptada", 247 "subscription.features.encryptedSync" : "Sincronización de sesión encriptada",
237 "subscription.features.noInterruptions" : "No app delays & nagging to upgrade license", 248 "subscription.features.noInterruptions" : "Sin retrasos en la app ni molestas actualizaciones de licencias",
238 "subscription.features.onpremise" : "Añade servicios locales\/autoalojados como HipChat", 249 "subscription.features.onpremise" : "Añade servicios locales\/autoalojados como HipChat",
239 "subscription.features.onpremise.mattermost" : "Add on-premise\/hosted services like Mattermost", 250 "subscription.features.onpremise.mattermost" : "Agregar servicios de almacenamiento como Mattermost",
240 "subscription.features.proxy" : "Proxy support for services", 251 "subscription.features.proxy" : "Soporte Proxy para servicios",
241 "subscription.features.spellchecker" : "Support for spellchecker", 252 "subscription.features.spellchecker" : "Soporte para corrector de ortografía",
242 "subscription.includedFeatures" : "La Cuenta pagada de Colaborador Premium de Franz incluye", 253 "subscription.includedFeatures" : "La Cuenta pagada de Colaborador Premium de Franz incluye",
243 "subscription.paymentSessionError" : "No se pudo inicializar el formulario de pago", 254 "subscription.paymentSessionError" : "No se pudo inicializar el formulario de pago",
244 "subscription.submit.label" : "Quiero apoyar el desarrollo de Franz", 255 "subscription.submit.label" : "Quiero apoyar el desarrollo de Franz",
diff --git a/src/i18n/locales/fr.json b/src/i18n/locales/fr.json
index 6964d27d2..a83767f1e 100644
--- a/src/i18n/locales/fr.json
+++ b/src/i18n/locales/fr.json
@@ -1,7 +1,9 @@
1{ 1{
2 "feature.delayApp.action" : "Get a Franz Supporter License", 2 "app.errorHandler.action" : "Recharger",
3 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting", 3 "app.errorHandler.headline" : "Une erreur s'est produite.",
4 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.", 4 "feature.delayApp.action" : "Obtenez une licence de Supporter Franz",
5 "feature.delayApp.headline" : "Veuillez acheter une licence de Supporter Franz pour sauter le temps d'attente",
6 "feature.delayApp.text" : "Franz continuera dans {seconds} secondes.",
5 "global.api.unhealthy" : "Impossible de se connecter aux services en ligne de Franz", 7 "global.api.unhealthy" : "Impossible de se connecter aux services en ligne de Franz",
6 "global.notConnectedToTheInternet" : "Vous n'êtes pas connecté à Internet.", 8 "global.notConnectedToTheInternet" : "Vous n'êtes pas connecté à Internet.",
7 "import.headline" : "Importez vos services depuis la version 4 de Franz.", 9 "import.headline" : "Importez vos services depuis la version 4 de Franz.",
@@ -79,7 +81,7 @@
79 "password.noUser" : "Aucun utilisateur n'a été trouvé avec cette adresse e-mail", 81 "password.noUser" : "Aucun utilisateur n'a été trouvé avec cette adresse e-mail",
80 "password.submit.label" : "Soumettre", 82 "password.submit.label" : "Soumettre",
81 "password.successInfo" : "Merci de consulter vos e-mails", 83 "password.successInfo" : "Merci de consulter vos e-mails",
82 "premiumFeature.button.upgradeAccount" : "Upgrade account", 84 "premiumFeature.button.upgradeAccount" : "Mettre à niveau mon compte",
83 "pricing.headline" : "Soutenez Franz", 85 "pricing.headline" : "Soutenez Franz",
84 "pricing.link.skipPayment" : "Je ne veux pas soutenir le développement de Franz.", 86 "pricing.link.skipPayment" : "Je ne veux pas soutenir le développement de Franz.",
85 "pricing.submit.label" : "Je veux soutenir le développement de Franz", 87 "pricing.submit.label" : "Je veux soutenir le développement de Franz",
@@ -90,6 +92,11 @@
90 "service.crashHandler.text" : "{name} a causé une erreur.", 92 "service.crashHandler.text" : "{name} a causé une erreur.",
91 "service.disabledHandler.action" : "Activer {name}", 93 "service.disabledHandler.action" : "Activer {name}",
92 "service.disabledHandler.headline" : "{name} est désactivé", 94 "service.disabledHandler.headline" : "{name} est désactivé",
95 "service.errorHandler.action" : "Recharger {name}",
96 "service.errorHandler.editAction" : "Modifier {name}",
97 "service.errorHandler.headline" : "Oh non !",
98 "service.errorHandler.message" : "Erreur",
99 "service.errorHandler.text" : "Le chargement de {name} a échoué.",
93 "services.getStarted" : "Commencer", 100 "services.getStarted" : "Commencer",
94 "services.welcome" : "Bienvenue dans Franz", 101 "services.welcome" : "Bienvenue dans Franz",
95 "settings.account.account.editButton" : "Modifier le compte", 102 "settings.account.account.editButton" : "Modifier le compte",
@@ -120,7 +127,7 @@
120 "settings.app.form.autoLaunchInBackground" : "Ouvrir en arrière-plan", 127 "settings.app.form.autoLaunchInBackground" : "Ouvrir en arrière-plan",
121 "settings.app.form.autoLaunchOnStart" : "Lancer Franz au démarrage", 128 "settings.app.form.autoLaunchOnStart" : "Lancer Franz au démarrage",
122 "settings.app.form.beta" : "Accepter les versions bêta", 129 "settings.app.form.beta" : "Accepter les versions bêta",
123 "settings.app.form.darkMode" : "Join the Dark Side", 130 "settings.app.form.darkMode" : "Rejoins le côté obscur",
124 "settings.app.form.enableGPUAcceleration" : "Activer l'accélération GPU", 131 "settings.app.form.enableGPUAcceleration" : "Activer l'accélération GPU",
125 "settings.app.form.enableMenuBar" : "Afficher Franz dans la barre des menus", 132 "settings.app.form.enableMenuBar" : "Afficher Franz dans la barre des menus",
126 "settings.app.form.enableSpellchecking" : "Activer la vérification orthographique", 133 "settings.app.form.enableSpellchecking" : "Activer la vérification orthographique",
@@ -131,7 +138,7 @@
131 "settings.app.form.runInBackground" : "Garder Franz ouvert en arrière-plan à la fermeture de la fenêtre", 138 "settings.app.form.runInBackground" : "Garder Franz ouvert en arrière-plan à la fermeture de la fenêtre",
132 "settings.app.form.showDisabledServices" : "Afficher les onglets des services désactivés", 139 "settings.app.form.showDisabledServices" : "Afficher les onglets des services désactivés",
133 "settings.app.form.showMessagesBadgesWhenMuted" : "Afficher les badges de messages non lus quand les notifications sont désactivées.", 140 "settings.app.form.showMessagesBadgesWhenMuted" : "Afficher les badges de messages non lus quand les notifications sont désactivées.",
134 "settings.app.form.spellcheckerLanguage" : "Spell checking language", 141 "settings.app.form.spellcheckerLanguage" : "Langue de la vérification orthographique",
135 "settings.app.headline" : "Paramètres", 142 "settings.app.headline" : "Paramètres",
136 "settings.app.headlineAdvanced" : "Paramètres avancés", 143 "settings.app.headlineAdvanced" : "Paramètres avancés",
137 "settings.app.headlineAppearance" : "Apparence", 144 "settings.app.headlineAppearance" : "Apparence",
@@ -172,7 +179,7 @@
172 "settings.service.form.editServiceHeadline" : "Modifier {name}", 179 "settings.service.form.editServiceHeadline" : "Modifier {name}",
173 "settings.service.form.enableAudio" : "Activer l'audio", 180 "settings.service.form.enableAudio" : "Activer l'audio",
174 "settings.service.form.enableBadge" : "Afficher le badge des messages non lus", 181 "settings.service.form.enableBadge" : "Afficher le badge des messages non lus",
175 "settings.service.form.enableDarkMode" : "Enable Dark Mode", 182 "settings.service.form.enableDarkMode" : "Activer le mode sombre",
176 "settings.service.form.enableNotification" : "Activer les notifications", 183 "settings.service.form.enableNotification" : "Activer les notifications",
177 "settings.service.form.enableService" : "Activer le service", 184 "settings.service.form.enableService" : "Activer le service",
178 "settings.service.form.headlineBadges" : "Badge des messages non lus", 185 "settings.service.form.headlineBadges" : "Badge des messages non lus",
@@ -185,13 +192,17 @@
185 "settings.service.form.indirectMessages" : "Afficher le badge des messages pour tous les nouveaux messages", 192 "settings.service.form.indirectMessages" : "Afficher le badge des messages pour tous les nouveaux messages",
186 "settings.service.form.isMutedInfo" : "Lorsque désactivé, tous les sons de notifications ainsi que l'audio sont coupés", 193 "settings.service.form.isMutedInfo" : "Lorsque désactivé, tous les sons de notifications ainsi que l'audio sont coupés",
187 "settings.service.form.name" : "Nom", 194 "settings.service.form.name" : "Nom",
188 "settings.service.form.proxy.headline" : "Proxy Settings", 195 "settings.service.form.proxy.headline" : "Paramètres Proxy HTTP\/HTTPS",
189 "settings.service.form.proxy.host" : "Proxy Host\/IP", 196 "settings.service.form.proxy.host" : "Hôte\/IP du proxy",
190 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.", 197 "settings.service.form.proxy.info" : "Les paramètres de proxy ne seront pas synchronisés avec les serveurs de Franz.",
191 "settings.service.form.proxy.isEnabled" : "Use Proxy", 198 "settings.service.form.proxy.isEnabled" : "Utiliser un proxy",
192 "settings.service.form.proxy.password" : "Password (optional)", 199 "settings.service.form.proxy.password" : "Mot de passe (facultatif)",
193 "settings.service.form.proxy.user" : "User (optional)", 200 "settings.service.form.proxy.port" : "Port",
201 "settings.service.form.proxy.restartInfo" : "Veuillez redémarrer Franz après avoir modifier les paramètres proxy.",
202 "settings.service.form.proxy.user" : "Utilisateur (facultatif)",
194 "settings.service.form.saveButton" : "Enregistrer le service", 203 "settings.service.form.saveButton" : "Enregistrer le service",
204 "settings.service.form.spellcheckerLanguage" : "Veuillez vérifier l'épellation Langage",
205 "settings.service.form.spellcheckerLanguage.default" : "Par défaut ({default})",
195 "settings.service.form.tabHosted" : "Hébergé", 206 "settings.service.form.tabHosted" : "Hébergé",
196 "settings.service.form.tabOnPremise" : "Auto-hébergé ⭐️", 207 "settings.service.form.tabOnPremise" : "Auto-hébergé ⭐️",
197 "settings.service.form.team" : "Équipe", 208 "settings.service.form.team" : "Équipe",
@@ -234,11 +245,11 @@
234 "subscription.features.ads" : "Plus de pubs !", 245 "subscription.features.ads" : "Plus de pubs !",
235 "subscription.features.comingSoon" : "Bientôt disponible", 246 "subscription.features.comingSoon" : "Bientôt disponible",
236 "subscription.features.encryptedSync" : "Synchronisation de session cryptée", 247 "subscription.features.encryptedSync" : "Synchronisation de session cryptée",
237 "subscription.features.noInterruptions" : "No app delays & nagging to upgrade license", 248 "subscription.features.noInterruptions" : "Aucun délai dans l'application ni de harcèlement pour mettre à niveau la licence",
238 "subscription.features.onpremise" : "Ajouter des services locaux\/hébergés comme HipChat", 249 "subscription.features.onpremise" : "Ajouter des services locaux\/hébergés comme HipChat",
239 "subscription.features.onpremise.mattermost" : "Add on-premise\/hosted services like Mattermost", 250 "subscription.features.onpremise.mattermost" : "Ajouter des services auto-hébergés comme Mattermost",
240 "subscription.features.proxy" : "Proxy support for services", 251 "subscription.features.proxy" : "Support proxy pour les services",
241 "subscription.features.spellchecker" : "Support for spellchecker", 252 "subscription.features.spellchecker" : "Prise en charge du correcteur orthographique",
242 "subscription.includedFeatures" : "Le compte payant Supporter Premium Franz inclut", 253 "subscription.includedFeatures" : "Le compte payant Supporter Premium Franz inclut",
243 "subscription.paymentSessionError" : "Initialisation du paiement impossible", 254 "subscription.paymentSessionError" : "Initialisation du paiement impossible",
244 "subscription.submit.label" : "Je souhaite aider au développement de Franz", 255 "subscription.submit.label" : "Je souhaite aider au développement de Franz",
diff --git a/src/i18n/locales/ga.json b/src/i18n/locales/ga.json
index 3bb838ba3..0d3d8623e 100644
--- a/src/i18n/locales/ga.json
+++ b/src/i18n/locales/ga.json
@@ -1,4 +1,6 @@
1{ 1{
2 "app.errorHandler.action" : "Athlódáil",
3 "app.errorHandler.headline" : "Something went wrong",
2 "feature.delayApp.action" : "Get a Franz Supporter License", 4 "feature.delayApp.action" : "Get a Franz Supporter License",
3 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting", 5 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting",
4 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.", 6 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.",
@@ -90,6 +92,11 @@
90 "service.crashHandler.text" : "Tá {name} tar éis earráid a dhéanamh.", 92 "service.crashHandler.text" : "Tá {name} tar éis earráid a dhéanamh.",
91 "service.disabledHandler.action" : "Cumasaigh {name}", 93 "service.disabledHandler.action" : "Cumasaigh {name}",
92 "service.disabledHandler.headline" : "Tá {name} díchumasaithe", 94 "service.disabledHandler.headline" : "Tá {name} díchumasaithe",
95 "service.errorHandler.action" : "Athlódáil {name}",
96 "service.errorHandler.editAction" : "Cuir {name} in eagar",
97 "service.errorHandler.headline" : "Oró, ní hea!",
98 "service.errorHandler.message" : "Earráid",
99 "service.errorHandler.text" : "{name} has failed to load.",
93 "services.getStarted" : "Cuir tús", 100 "services.getStarted" : "Cuir tús",
94 "services.welcome" : "Fáilte go Franz", 101 "services.welcome" : "Fáilte go Franz",
95 "settings.account.account.editButton" : "Cuir cuntas in eagar", 102 "settings.account.account.editButton" : "Cuir cuntas in eagar",
@@ -185,13 +192,17 @@
185 "settings.service.form.indirectMessages" : "Taispeáin comhartha theachtaireachta do gach teachtaireacht nua", 192 "settings.service.form.indirectMessages" : "Taispeáin comhartha theachtaireachta do gach teachtaireacht nua",
186 "settings.service.form.isMutedInfo" : "Tachtar gach fuaim fógraí agus athchasadh fuaime", 193 "settings.service.form.isMutedInfo" : "Tachtar gach fuaim fógraí agus athchasadh fuaime",
187 "settings.service.form.name" : "Ainm", 194 "settings.service.form.name" : "Ainm",
188 "settings.service.form.proxy.headline" : "Proxy Settings", 195 "settings.service.form.proxy.headline" : "HTTP\/HTTPS Proxy Settings",
189 "settings.service.form.proxy.host" : "Proxy Host\/IP", 196 "settings.service.form.proxy.host" : "Proxy Host\/IP",
190 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.", 197 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.",
191 "settings.service.form.proxy.isEnabled" : "Use Proxy", 198 "settings.service.form.proxy.isEnabled" : "Use Proxy",
192 "settings.service.form.proxy.password" : "Password (optional)", 199 "settings.service.form.proxy.password" : "Password (optional)",
200 "settings.service.form.proxy.port" : "Port",
201 "settings.service.form.proxy.restartInfo" : "Please restart Franz after changing proxy Settings.",
193 "settings.service.form.proxy.user" : "User (optional)", 202 "settings.service.form.proxy.user" : "User (optional)",
194 "settings.service.form.saveButton" : "Sábháil seirbhís", 203 "settings.service.form.saveButton" : "Sábháil seirbhís",
204 "settings.service.form.spellcheckerLanguage" : "Spell checking Language",
205 "settings.service.form.spellcheckerLanguage.default" : "Use System Default ({default})",
195 "settings.service.form.tabHosted" : "Óstáilte", 206 "settings.service.form.tabHosted" : "Óstáilte",
196 "settings.service.form.tabOnPremise" : "Féinóstáilte ⭐️", 207 "settings.service.form.tabOnPremise" : "Féinóstáilte ⭐️",
197 "settings.service.form.team" : "Foireann", 208 "settings.service.form.team" : "Foireann",
diff --git a/src/i18n/locales/hr.json b/src/i18n/locales/hr.json
index ae9f25695..2ff69755d 100644
--- a/src/i18n/locales/hr.json
+++ b/src/i18n/locales/hr.json
@@ -1,4 +1,6 @@
1{ 1{
2 "app.errorHandler.action" : "Ponovno učitavanje",
3 "app.errorHandler.headline" : "Something went wrong",
2 "feature.delayApp.action" : "Get a Franz Supporter License", 4 "feature.delayApp.action" : "Get a Franz Supporter License",
3 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting", 5 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting",
4 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.", 6 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.",
@@ -90,6 +92,11 @@
90 "service.crashHandler.text" : "{name} je izazvalo grešku. ", 92 "service.crashHandler.text" : "{name} je izazvalo grešku. ",
91 "service.disabledHandler.action" : "Omogući {name}", 93 "service.disabledHandler.action" : "Omogući {name}",
92 "service.disabledHandler.headline" : "{name} je onemogućen\/o", 94 "service.disabledHandler.headline" : "{name} je onemogućen\/o",
95 "service.errorHandler.action" : "Osvježi okvir",
96 "service.errorHandler.editAction" : "Uredite {ime}",
97 "service.errorHandler.headline" : "O, ne! ",
98 "service.errorHandler.message" : "Greška",
99 "service.errorHandler.text" : "{name} has failed to load.",
93 "services.getStarted" : "Započnimo!", 100 "services.getStarted" : "Započnimo!",
94 "services.welcome" : "Dobrodošli u Franz", 101 "services.welcome" : "Dobrodošli u Franz",
95 "settings.account.account.editButton" : "Uredi račun", 102 "settings.account.account.editButton" : "Uredi račun",
@@ -185,13 +192,17 @@
185 "settings.service.form.indirectMessages" : "Prikaži značku na svim novim porukuama", 192 "settings.service.form.indirectMessages" : "Prikaži značku na svim novim porukuama",
186 "settings.service.form.isMutedInfo" : "Kada je onemogućeno, sve obavijesti, svi zvukovi i sva pozadinska podrška će biti nečujna. ", 193 "settings.service.form.isMutedInfo" : "Kada je onemogućeno, sve obavijesti, svi zvukovi i sva pozadinska podrška će biti nečujna. ",
187 "settings.service.form.name" : "Ime", 194 "settings.service.form.name" : "Ime",
188 "settings.service.form.proxy.headline" : "Proxy Settings", 195 "settings.service.form.proxy.headline" : "HTTP\/HTTPS Proxy Settings",
189 "settings.service.form.proxy.host" : "Proxy Host\/IP", 196 "settings.service.form.proxy.host" : "Proxy Host\/IP",
190 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.", 197 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.",
191 "settings.service.form.proxy.isEnabled" : "Use Proxy", 198 "settings.service.form.proxy.isEnabled" : "Use Proxy",
192 "settings.service.form.proxy.password" : "Password (optional)", 199 "settings.service.form.proxy.password" : "Password (optional)",
200 "settings.service.form.proxy.port" : "Port",
201 "settings.service.form.proxy.restartInfo" : "Please restart Franz after changing proxy Settings.",
193 "settings.service.form.proxy.user" : "User (optional)", 202 "settings.service.form.proxy.user" : "User (optional)",
194 "settings.service.form.saveButton" : "Sačuvaj uslugu\/e", 203 "settings.service.form.saveButton" : "Sačuvaj uslugu\/e",
204 "settings.service.form.spellcheckerLanguage" : "Spell checking Language",
205 "settings.service.form.spellcheckerLanguage.default" : "Use System Default ({default})",
195 "settings.service.form.tabHosted" : "Hostovano", 206 "settings.service.form.tabHosted" : "Hostovano",
196 "settings.service.form.tabOnPremise" : "Samo-hostovano ⭐️", 207 "settings.service.form.tabOnPremise" : "Samo-hostovano ⭐️",
197 "settings.service.form.team" : "Tim", 208 "settings.service.form.team" : "Tim",
diff --git a/src/i18n/locales/hu.json b/src/i18n/locales/hu.json
index 365dec9c6..0b396cf3b 100644
--- a/src/i18n/locales/hu.json
+++ b/src/i18n/locales/hu.json
@@ -1,4 +1,6 @@
1{ 1{
2 "app.errorHandler.action" : "Újratöltés",
3 "app.errorHandler.headline" : "Something went wrong",
2 "feature.delayApp.action" : "Get a Franz Supporter License", 4 "feature.delayApp.action" : "Get a Franz Supporter License",
3 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting", 5 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting",
4 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.", 6 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.",
@@ -90,6 +92,11 @@
90 "service.crashHandler.text" : "{name} hibát okozott.", 92 "service.crashHandler.text" : "{name} hibát okozott.",
91 "service.disabledHandler.action" : "{name} engedélyezése", 93 "service.disabledHandler.action" : "{name} engedélyezése",
92 "service.disabledHandler.headline" : "{name} letiltva", 94 "service.disabledHandler.headline" : "{name} letiltva",
95 "service.errorHandler.action" : "{name} újratöltése",
96 "service.errorHandler.editAction" : "{name} szerkesztése",
97 "service.errorHandler.headline" : "Jajj ne!",
98 "service.errorHandler.message" : "Hiba",
99 "service.errorHandler.text" : "{name} has failed to load.",
93 "services.getStarted" : "Kezdj hozzá", 100 "services.getStarted" : "Kezdj hozzá",
94 "services.welcome" : "Üdvözöl a Franz", 101 "services.welcome" : "Üdvözöl a Franz",
95 "settings.account.account.editButton" : "Fiók szerkesztése", 102 "settings.account.account.editButton" : "Fiók szerkesztése",
@@ -185,13 +192,17 @@
185 "settings.service.form.indirectMessages" : "Üzenet kitűző megjelenítése minden üzenethez", 192 "settings.service.form.indirectMessages" : "Üzenet kitűző megjelenítése minden üzenethez",
186 "settings.service.form.isMutedInfo" : "Ha kikapcsolod, minden értesítési és lejátszott hang némításra kerül.", 193 "settings.service.form.isMutedInfo" : "Ha kikapcsolod, minden értesítési és lejátszott hang némításra kerül.",
187 "settings.service.form.name" : "Név", 194 "settings.service.form.name" : "Név",
188 "settings.service.form.proxy.headline" : "Proxy Settings", 195 "settings.service.form.proxy.headline" : "HTTP\/HTTPS Proxy Settings",
189 "settings.service.form.proxy.host" : "Proxy Host\/IP", 196 "settings.service.form.proxy.host" : "Proxy Host\/IP",
190 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.", 197 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.",
191 "settings.service.form.proxy.isEnabled" : "Use Proxy", 198 "settings.service.form.proxy.isEnabled" : "Use Proxy",
192 "settings.service.form.proxy.password" : "Password (optional)", 199 "settings.service.form.proxy.password" : "Password (optional)",
200 "settings.service.form.proxy.port" : "Port",
201 "settings.service.form.proxy.restartInfo" : "Please restart Franz after changing proxy Settings.",
193 "settings.service.form.proxy.user" : "User (optional)", 202 "settings.service.form.proxy.user" : "User (optional)",
194 "settings.service.form.saveButton" : "Szolgáltatás mentése", 203 "settings.service.form.saveButton" : "Szolgáltatás mentése",
204 "settings.service.form.spellcheckerLanguage" : "Spell checking Language",
205 "settings.service.form.spellcheckerLanguage.default" : "Use System Default ({default})",
195 "settings.service.form.tabHosted" : "Üzemeltetett", 206 "settings.service.form.tabHosted" : "Üzemeltetett",
196 "settings.service.form.tabOnPremise" : "Egyénileg üzemeltetett", 207 "settings.service.form.tabOnPremise" : "Egyénileg üzemeltetett",
197 "settings.service.form.team" : "Csapat", 208 "settings.service.form.team" : "Csapat",
diff --git a/src/i18n/locales/id.json b/src/i18n/locales/id.json
index 437c1304f..11596d142 100644
--- a/src/i18n/locales/id.json
+++ b/src/i18n/locales/id.json
@@ -1,9 +1,11 @@
1{ 1{
2 "feature.delayApp.action" : "Get a Franz Supporter License", 2 "app.errorHandler.action" : "Muat Ulang",
3 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting", 3 "app.errorHandler.headline" : "Something went wrong",
4 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.", 4 "feature.delayApp.action" : "Dapatkan Franz Supporter License",
5 "feature.delayApp.headline" : "Beli Franz Supporter License agar tidak perlu menunggu",
6 "feature.delayApp.text" : "Franz akan melanjutkan dalam {seconds} detik.",
5 "global.api.unhealthy" : "Tidak dapat tersambung ke layanan Franz", 7 "global.api.unhealthy" : "Tidak dapat tersambung ke layanan Franz",
6 "global.notConnectedToTheInternet" : "Anda tidak mempunyai koneksi internet", 8 "global.notConnectedToTheInternet" : "Anda tidak tersambung ke internet.",
7 "import.headline" : "Impor layanan Franz 4 Anda", 9 "import.headline" : "Impor layanan Franz 4 Anda",
8 "import.notSupportedHeadline" : "Layanan belum didukung di Franz 5", 10 "import.notSupportedHeadline" : "Layanan belum didukung di Franz 5",
9 "import.skip.label" : "Saya ingin menambahkan layanan secara manual", 11 "import.skip.label" : "Saya ingin menambahkan layanan secara manual",
@@ -79,7 +81,7 @@
79 "password.noUser" : "Tidak ditemukan pengguna dengan email tersebut", 81 "password.noUser" : "Tidak ditemukan pengguna dengan email tersebut",
80 "password.submit.label" : "Kirim", 82 "password.submit.label" : "Kirim",
81 "password.successInfo" : "Periksa email Anda", 83 "password.successInfo" : "Periksa email Anda",
82 "premiumFeature.button.upgradeAccount" : "Upgrade account", 84 "premiumFeature.button.upgradeAccount" : "Tingkatkan akun",
83 "pricing.headline" : "Dukung Franz", 85 "pricing.headline" : "Dukung Franz",
84 "pricing.link.skipPayment" : "Saya tidak ingin mendukung pengembangan Franz.", 86 "pricing.link.skipPayment" : "Saya tidak ingin mendukung pengembangan Franz.",
85 "pricing.submit.label" : "Saya ingin mendukung pengembangan Franz", 87 "pricing.submit.label" : "Saya ingin mendukung pengembangan Franz",
@@ -90,6 +92,11 @@
90 "service.crashHandler.text" : "{name} menyebabkan kesalahan.", 92 "service.crashHandler.text" : "{name} menyebabkan kesalahan.",
91 "service.disabledHandler.action" : "Aktifkan {name}", 93 "service.disabledHandler.action" : "Aktifkan {name}",
92 "service.disabledHandler.headline" : "{name} dinonaktifkan", 94 "service.disabledHandler.headline" : "{name} dinonaktifkan",
95 "service.errorHandler.action" : "Muat Ulang {name}",
96 "service.errorHandler.editAction" : "Edit {nama}",
97 "service.errorHandler.headline" : "Ya Ampun!",
98 "service.errorHandler.message" : "Kesalahan",
99 "service.errorHandler.text" : "{name} has failed to load.",
93 "services.getStarted" : "Ayo mulai!", 100 "services.getStarted" : "Ayo mulai!",
94 "services.welcome" : "Selamat datang di Franz", 101 "services.welcome" : "Selamat datang di Franz",
95 "settings.account.account.editButton" : "Edit akun", 102 "settings.account.account.editButton" : "Edit akun",
@@ -120,7 +127,7 @@
120 "settings.app.form.autoLaunchInBackground" : "Buka di latar belakang", 127 "settings.app.form.autoLaunchInBackground" : "Buka di latar belakang",
121 "settings.app.form.autoLaunchOnStart" : "Jalankan Franz saat komputer dimulai", 128 "settings.app.form.autoLaunchOnStart" : "Jalankan Franz saat komputer dimulai",
122 "settings.app.form.beta" : "Sertakan versi beta", 129 "settings.app.form.beta" : "Sertakan versi beta",
123 "settings.app.form.darkMode" : "Join the Dark Side", 130 "settings.app.form.darkMode" : "Sisi Kelam menunggu Anda (Mode Gelap)",
124 "settings.app.form.enableGPUAcceleration" : "Aktifkan Akselerasi GPU", 131 "settings.app.form.enableGPUAcceleration" : "Aktifkan Akselerasi GPU",
125 "settings.app.form.enableMenuBar" : "Tampilkan Franz di Bilah Menu", 132 "settings.app.form.enableMenuBar" : "Tampilkan Franz di Bilah Menu",
126 "settings.app.form.enableSpellchecking" : "Aktifkan pemeriksaan ejaan", 133 "settings.app.form.enableSpellchecking" : "Aktifkan pemeriksaan ejaan",
@@ -131,7 +138,7 @@
131 "settings.app.form.runInBackground" : "Tetap jalankan Franz di latar belakang saat menutup jendela", 138 "settings.app.form.runInBackground" : "Tetap jalankan Franz di latar belakang saat menutup jendela",
132 "settings.app.form.showDisabledServices" : "Tampilkan tab layanan yang dinonaktifkan", 139 "settings.app.form.showDisabledServices" : "Tampilkan tab layanan yang dinonaktifkan",
133 "settings.app.form.showMessagesBadgesWhenMuted" : "Tampilkan lencana pesan belum dibaca saat pemberitahuan dinonaktifkan", 140 "settings.app.form.showMessagesBadgesWhenMuted" : "Tampilkan lencana pesan belum dibaca saat pemberitahuan dinonaktifkan",
134 "settings.app.form.spellcheckerLanguage" : "Spell checking language", 141 "settings.app.form.spellcheckerLanguage" : "Periksa ejaan",
135 "settings.app.headline" : "Pengaturan", 142 "settings.app.headline" : "Pengaturan",
136 "settings.app.headlineAdvanced" : "Tingkat Lanjut", 143 "settings.app.headlineAdvanced" : "Tingkat Lanjut",
137 "settings.app.headlineAppearance" : "Tampilan", 144 "settings.app.headlineAppearance" : "Tampilan",
@@ -172,7 +179,7 @@
172 "settings.service.form.editServiceHeadline" : "Edit {nama}", 179 "settings.service.form.editServiceHeadline" : "Edit {nama}",
173 "settings.service.form.enableAudio" : "Aktifkan audio", 180 "settings.service.form.enableAudio" : "Aktifkan audio",
174 "settings.service.form.enableBadge" : "Tampilkan lencana pesan belum dibaca", 181 "settings.service.form.enableBadge" : "Tampilkan lencana pesan belum dibaca",
175 "settings.service.form.enableDarkMode" : "Enable Dark Mode", 182 "settings.service.form.enableDarkMode" : "Aktifkan Mode Gelap",
176 "settings.service.form.enableNotification" : "Aktifkan pemberitahuan", 183 "settings.service.form.enableNotification" : "Aktifkan pemberitahuan",
177 "settings.service.form.enableService" : "Aktifkan layanan", 184 "settings.service.form.enableService" : "Aktifkan layanan",
178 "settings.service.form.headlineBadges" : "Lencana pesan belum dibaca", 185 "settings.service.form.headlineBadges" : "Lencana pesan belum dibaca",
@@ -185,13 +192,17 @@
185 "settings.service.form.indirectMessages" : "Tampilkan lencana pesan untuk semua pesan baru", 192 "settings.service.form.indirectMessages" : "Tampilkan lencana pesan untuk semua pesan baru",
186 "settings.service.form.isMutedInfo" : "Saat dinonaktifkan, semua suara pemberitahuan dan pemutaran audio akan dibisukan", 193 "settings.service.form.isMutedInfo" : "Saat dinonaktifkan, semua suara pemberitahuan dan pemutaran audio akan dibisukan",
187 "settings.service.form.name" : "Nama", 194 "settings.service.form.name" : "Nama",
188 "settings.service.form.proxy.headline" : "Proxy Settings", 195 "settings.service.form.proxy.headline" : "HTTP\/HTTPS Proxy Settings",
189 "settings.service.form.proxy.host" : "Proxy Host\/IP", 196 "settings.service.form.proxy.host" : "Host\/IP Proksi",
190 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.", 197 "settings.service.form.proxy.info" : "Pengaturan proksi tidak akan disinkronkan dengan server Franz.",
191 "settings.service.form.proxy.isEnabled" : "Use Proxy", 198 "settings.service.form.proxy.isEnabled" : "Gunakan Proksi",
192 "settings.service.form.proxy.password" : "Password (optional)", 199 "settings.service.form.proxy.password" : "Sandi (opsional)",
193 "settings.service.form.proxy.user" : "User (optional)", 200 "settings.service.form.proxy.port" : "Port",
201 "settings.service.form.proxy.restartInfo" : "Please restart Franz after changing proxy Settings.",
202 "settings.service.form.proxy.user" : "Pengguna (opsional)",
194 "settings.service.form.saveButton" : "Simpan layanan", 203 "settings.service.form.saveButton" : "Simpan layanan",
204 "settings.service.form.spellcheckerLanguage" : "Spell checking Language",
205 "settings.service.form.spellcheckerLanguage.default" : "Use System Default ({default})",
195 "settings.service.form.tabHosted" : "Hosted", 206 "settings.service.form.tabHosted" : "Hosted",
196 "settings.service.form.tabOnPremise" : "Hosted mandiri", 207 "settings.service.form.tabOnPremise" : "Hosted mandiri",
197 "settings.service.form.team" : "Tim", 208 "settings.service.form.team" : "Tim",
@@ -234,11 +245,11 @@
234 "subscription.features.ads" : "Tanpa iklan, selamanya!", 245 "subscription.features.ads" : "Tanpa iklan, selamanya!",
235 "subscription.features.comingSoon" : "segera hadir", 246 "subscription.features.comingSoon" : "segera hadir",
236 "subscription.features.encryptedSync" : "Sinkronisasi sesi terenkripsi", 247 "subscription.features.encryptedSync" : "Sinkronisasi sesi terenkripsi",
237 "subscription.features.noInterruptions" : "No app delays & nagging to upgrade license", 248 "subscription.features.noInterruptions" : "Tanpa menunggu dan ditanya untuk meningkatkan lisensi",
238 "subscription.features.onpremise" : "Layanan add-on premise\/hosted seperti HipChat", 249 "subscription.features.onpremise" : "Integrasi layanan hosted, misalnya HipChat",
239 "subscription.features.onpremise.mattermost" : "Add on-premise\/hosted services like Mattermost", 250 "subscription.features.onpremise.mattermost" : "Integrasi layanan hosted, misalnya Mattermost",
240 "subscription.features.proxy" : "Proxy support for services", 251 "subscription.features.proxy" : "Dukungan proksi untuk layanan",
241 "subscription.features.spellchecker" : "Support for spellchecker", 252 "subscription.features.spellchecker" : "Dukungan pengecek ejaan",
242 "subscription.includedFeatures" : "Franz Premium Supporter Account berbayar menyertakan", 253 "subscription.includedFeatures" : "Franz Premium Supporter Account berbayar menyertakan",
243 "subscription.paymentSessionError" : "Tidak bisa menginisialisasi formulir pembayaran", 254 "subscription.paymentSessionError" : "Tidak bisa menginisialisasi formulir pembayaran",
244 "subscription.submit.label" : "Saya ingin mendukung pengembangan Franz", 255 "subscription.submit.label" : "Saya ingin mendukung pengembangan Franz",
diff --git a/src/i18n/locales/it.json b/src/i18n/locales/it.json
index 958d1470d..47cbd8f1e 100644
--- a/src/i18n/locales/it.json
+++ b/src/i18n/locales/it.json
@@ -1,7 +1,9 @@
1{ 1{
2 "feature.delayApp.action" : "Get a Franz Supporter License", 2 "app.errorHandler.action" : "Ricarica",
3 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting", 3 "app.errorHandler.headline" : "Something went wrong",
4 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.", 4 "feature.delayApp.action" : "Ricevi una Licenza Supporter di Franz",
5 "feature.delayApp.headline" : "Per favore, compra una Licenza Supporter di Franz per saltare l'attesa",
6 "feature.delayApp.text" : "Franz continuerà a funzionare tra {seconds} secondi.",
5 "global.api.unhealthy" : "Impossibile connettersi ai servizi online di Franz", 7 "global.api.unhealthy" : "Impossibile connettersi ai servizi online di Franz",
6 "global.notConnectedToTheInternet" : "Non sei connesso a Internet.", 8 "global.notConnectedToTheInternet" : "Non sei connesso a Internet.",
7 "import.headline" : "Importa i servizi di Franz 4", 9 "import.headline" : "Importa i servizi di Franz 4",
@@ -90,6 +92,11 @@
90 "service.crashHandler.text" : "{name} ha causato un errore.", 92 "service.crashHandler.text" : "{name} ha causato un errore.",
91 "service.disabledHandler.action" : "Attiva {name}", 93 "service.disabledHandler.action" : "Attiva {name}",
92 "service.disabledHandler.headline" : "{name} è disattivato", 94 "service.disabledHandler.headline" : "{name} è disattivato",
95 "service.errorHandler.action" : "Ricarica {name}",
96 "service.errorHandler.editAction" : "Modifica {name}",
97 "service.errorHandler.headline" : "Oh no!",
98 "service.errorHandler.message" : "Errore",
99 "service.errorHandler.text" : "{name} has failed to load.",
93 "services.getStarted" : "Iniziamo", 100 "services.getStarted" : "Iniziamo",
94 "services.welcome" : "Benvenuto su Franz", 101 "services.welcome" : "Benvenuto su Franz",
95 "settings.account.account.editButton" : "Modifica account", 102 "settings.account.account.editButton" : "Modifica account",
@@ -120,7 +127,7 @@
120 "settings.app.form.autoLaunchInBackground" : "Apri in background", 127 "settings.app.form.autoLaunchInBackground" : "Apri in background",
121 "settings.app.form.autoLaunchOnStart" : "Esegui Franz all'avvio", 128 "settings.app.form.autoLaunchOnStart" : "Esegui Franz all'avvio",
122 "settings.app.form.beta" : "Includi versioni beta", 129 "settings.app.form.beta" : "Includi versioni beta",
123 "settings.app.form.darkMode" : "Join the Dark Side", 130 "settings.app.form.darkMode" : "Unisciti al Lato Oscuro.",
124 "settings.app.form.enableGPUAcceleration" : "Attiva Accelerazione GPU", 131 "settings.app.form.enableGPUAcceleration" : "Attiva Accelerazione GPU",
125 "settings.app.form.enableMenuBar" : "Mostra Franz nella Barra del Menu", 132 "settings.app.form.enableMenuBar" : "Mostra Franz nella Barra del Menu",
126 "settings.app.form.enableSpellchecking" : "Attiva controllo ortografico", 133 "settings.app.form.enableSpellchecking" : "Attiva controllo ortografico",
@@ -172,7 +179,7 @@
172 "settings.service.form.editServiceHeadline" : "Modifica {name}", 179 "settings.service.form.editServiceHeadline" : "Modifica {name}",
173 "settings.service.form.enableAudio" : "Attiva audio", 180 "settings.service.form.enableAudio" : "Attiva audio",
174 "settings.service.form.enableBadge" : "Mostra l'etichetta dei messaggi non letti", 181 "settings.service.form.enableBadge" : "Mostra l'etichetta dei messaggi non letti",
175 "settings.service.form.enableDarkMode" : "Enable Dark Mode", 182 "settings.service.form.enableDarkMode" : "Attiva la modalità scura.",
176 "settings.service.form.enableNotification" : "Attiva le notifiche", 183 "settings.service.form.enableNotification" : "Attiva le notifiche",
177 "settings.service.form.enableService" : "Attiva il servizio", 184 "settings.service.form.enableService" : "Attiva il servizio",
178 "settings.service.form.headlineBadges" : "Etichetta dei messaggi non letti", 185 "settings.service.form.headlineBadges" : "Etichetta dei messaggi non letti",
@@ -185,13 +192,17 @@
185 "settings.service.form.indirectMessages" : "Mostra l'etichetta per tutti i nuovi messaggi", 192 "settings.service.form.indirectMessages" : "Mostra l'etichetta per tutti i nuovi messaggi",
186 "settings.service.form.isMutedInfo" : "Se disattivato, tutte le notifiche sonore e le riproduzioni audio saranno mutate", 193 "settings.service.form.isMutedInfo" : "Se disattivato, tutte le notifiche sonore e le riproduzioni audio saranno mutate",
187 "settings.service.form.name" : "Nome", 194 "settings.service.form.name" : "Nome",
188 "settings.service.form.proxy.headline" : "Proxy Settings", 195 "settings.service.form.proxy.headline" : "HTTP\/HTTPS Proxy Settings",
189 "settings.service.form.proxy.host" : "Proxy Host\/IP", 196 "settings.service.form.proxy.host" : "Proxy Host\/IP",
190 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.", 197 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.",
191 "settings.service.form.proxy.isEnabled" : "Use Proxy", 198 "settings.service.form.proxy.isEnabled" : "Use Proxy",
192 "settings.service.form.proxy.password" : "Password (optional)", 199 "settings.service.form.proxy.password" : "Password (optional)",
200 "settings.service.form.proxy.port" : "Port",
201 "settings.service.form.proxy.restartInfo" : "Please restart Franz after changing proxy Settings.",
193 "settings.service.form.proxy.user" : "User (optional)", 202 "settings.service.form.proxy.user" : "User (optional)",
194 "settings.service.form.saveButton" : "Salva servizio", 203 "settings.service.form.saveButton" : "Salva servizio",
204 "settings.service.form.spellcheckerLanguage" : "Spell checking Language",
205 "settings.service.form.spellcheckerLanguage.default" : "Use System Default ({default})",
195 "settings.service.form.tabHosted" : "Hosted", 206 "settings.service.form.tabHosted" : "Hosted",
196 "settings.service.form.tabOnPremise" : "Self hosted ⭐️", 207 "settings.service.form.tabOnPremise" : "Self hosted ⭐️",
197 "settings.service.form.team" : "Gruppo", 208 "settings.service.form.team" : "Gruppo",
diff --git a/src/i18n/locales/ja.json b/src/i18n/locales/ja.json
index 57b767ef1..6eea64c3a 100644
--- a/src/i18n/locales/ja.json
+++ b/src/i18n/locales/ja.json
@@ -1,7 +1,9 @@
1{ 1{
2 "feature.delayApp.action" : "Get a Franz Supporter License", 2 "app.errorHandler.action" : "再読み込み",
3 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting", 3 "app.errorHandler.headline" : "Something went wrong",
4 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.", 4 "feature.delayApp.action" : "Franz サポーターライセンスを購入する",
5 "feature.delayApp.headline" : "Franz をすぐに起動するには、Franz サポーターライセンスを購入してください。",
6 "feature.delayApp.text" : "Franz はあと{seconds}秒後に起動します。",
5 "global.api.unhealthy" : "Franzのオンラインサービスに接続できません。", 7 "global.api.unhealthy" : "Franzのオンラインサービスに接続できません。",
6 "global.notConnectedToTheInternet" : "インターネットに接続されていません。", 8 "global.notConnectedToTheInternet" : "インターネットに接続されていません。",
7 "import.headline" : "Franz 4のサービスをインポートして下さい", 9 "import.headline" : "Franz 4のサービスをインポートして下さい",
@@ -79,7 +81,7 @@
79 "password.noUser" : "このメールアドレスはまだ登録されていません", 81 "password.noUser" : "このメールアドレスはまだ登録されていません",
80 "password.submit.label" : "送信", 82 "password.submit.label" : "送信",
81 "password.successInfo" : "メールを確認して下さい", 83 "password.successInfo" : "メールを確認して下さい",
82 "premiumFeature.button.upgradeAccount" : "Upgrade account", 84 "premiumFeature.button.upgradeAccount" : "アカウントをアップグレード",
83 "pricing.headline" : "Franzを支援する", 85 "pricing.headline" : "Franzを支援する",
84 "pricing.link.skipPayment" : "Franzの開発を支援したくない。", 86 "pricing.link.skipPayment" : "Franzの開発を支援したくない。",
85 "pricing.submit.label" : "Franzの開発を支援したい。", 87 "pricing.submit.label" : "Franzの開発を支援したい。",
@@ -90,6 +92,11 @@
90 "service.crashHandler.text" : "{name}はエラーを起こしました。", 92 "service.crashHandler.text" : "{name}はエラーを起こしました。",
91 "service.disabledHandler.action" : "{name}を有効にする", 93 "service.disabledHandler.action" : "{name}を有効にする",
92 "service.disabledHandler.headline" : "{name}は無効です", 94 "service.disabledHandler.headline" : "{name}は無効です",
95 "service.errorHandler.action" : "{name}を再読み込み",
96 "service.errorHandler.editAction" : "{name}を編集",
97 "service.errorHandler.headline" : "しまった!",
98 "service.errorHandler.message" : "エラー",
99 "service.errorHandler.text" : "{name} has failed to load.",
93 "services.getStarted" : "はじめる", 100 "services.getStarted" : "はじめる",
94 "services.welcome" : "Franzにようこそ", 101 "services.welcome" : "Franzにようこそ",
95 "settings.account.account.editButton" : "アカウントの編集", 102 "settings.account.account.editButton" : "アカウントの編集",
@@ -120,7 +127,7 @@
120 "settings.app.form.autoLaunchInBackground" : "バックグラウンドで開く", 127 "settings.app.form.autoLaunchInBackground" : "バックグラウンドで開く",
121 "settings.app.form.autoLaunchOnStart" : "システム起動時にFranzを開く", 128 "settings.app.form.autoLaunchOnStart" : "システム起動時にFranzを開く",
122 "settings.app.form.beta" : "Betaバージョンを含める", 129 "settings.app.form.beta" : "Betaバージョンを含める",
123 "settings.app.form.darkMode" : "Join the Dark Side", 130 "settings.app.form.darkMode" : "ダークモードを有効にする",
124 "settings.app.form.enableGPUAcceleration" : "GPUアクセラレーションを有効にする", 131 "settings.app.form.enableGPUAcceleration" : "GPUアクセラレーションを有効にする",
125 "settings.app.form.enableMenuBar" : "メニューバーにFranzを表示する", 132 "settings.app.form.enableMenuBar" : "メニューバーにFranzを表示する",
126 "settings.app.form.enableSpellchecking" : "スペルチェックを有効にする", 133 "settings.app.form.enableSpellchecking" : "スペルチェックを有効にする",
@@ -131,7 +138,7 @@
131 "settings.app.form.runInBackground" : "ウインドウを閉じた際にFranzをバックグラウンドで実行させておく", 138 "settings.app.form.runInBackground" : "ウインドウを閉じた際にFranzをバックグラウンドで実行させておく",
132 "settings.app.form.showDisabledServices" : "無効化されたサービスのタブを表示する", 139 "settings.app.form.showDisabledServices" : "無効化されたサービスのタブを表示する",
133 "settings.app.form.showMessagesBadgesWhenMuted" : "通知の無効時に未読メッセージ件数を表示する", 140 "settings.app.form.showMessagesBadgesWhenMuted" : "通知の無効時に未読メッセージ件数を表示する",
134 "settings.app.form.spellcheckerLanguage" : "Spell checking language", 141 "settings.app.form.spellcheckerLanguage" : "スペルチェックする言語",
135 "settings.app.headline" : "設定", 142 "settings.app.headline" : "設定",
136 "settings.app.headlineAdvanced" : "詳細", 143 "settings.app.headlineAdvanced" : "詳細",
137 "settings.app.headlineAppearance" : "表示スタイル", 144 "settings.app.headlineAppearance" : "表示スタイル",
@@ -172,7 +179,7 @@
172 "settings.service.form.editServiceHeadline" : "{name}を編集", 179 "settings.service.form.editServiceHeadline" : "{name}を編集",
173 "settings.service.form.enableAudio" : "オーディオを有効にする", 180 "settings.service.form.enableAudio" : "オーディオを有効にする",
174 "settings.service.form.enableBadge" : "未読件数の通知バッジを表示する", 181 "settings.service.form.enableBadge" : "未読件数の通知バッジを表示する",
175 "settings.service.form.enableDarkMode" : "Enable Dark Mode", 182 "settings.service.form.enableDarkMode" : "ダークモードを有効にする",
176 "settings.service.form.enableNotification" : "通知を有効にする", 183 "settings.service.form.enableNotification" : "通知を有効にする",
177 "settings.service.form.enableService" : "サービスを有効にする", 184 "settings.service.form.enableService" : "サービスを有効にする",
178 "settings.service.form.headlineBadges" : "未読件数の通知バッジ", 185 "settings.service.form.headlineBadges" : "未読件数の通知バッジ",
@@ -185,13 +192,17 @@
185 "settings.service.form.indirectMessages" : "すべての新規メッセージについてバッジを表示する", 192 "settings.service.form.indirectMessages" : "すべての新規メッセージについてバッジを表示する",
186 "settings.service.form.isMutedInfo" : "無効化されている場合、全ての通知音やオーディオ再生は無音になります", 193 "settings.service.form.isMutedInfo" : "無効化されている場合、全ての通知音やオーディオ再生は無音になります",
187 "settings.service.form.name" : "サービス名", 194 "settings.service.form.name" : "サービス名",
188 "settings.service.form.proxy.headline" : "Proxy Settings", 195 "settings.service.form.proxy.headline" : "HTTP\/HTTPS Proxy Settings",
189 "settings.service.form.proxy.host" : "Proxy Host\/IP", 196 "settings.service.form.proxy.host" : "プロキシサーバー\/IP",
190 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.", 197 "settings.service.form.proxy.info" : "プロキシ設定はFranz アカウントで同期されません。",
191 "settings.service.form.proxy.isEnabled" : "Use Proxy", 198 "settings.service.form.proxy.isEnabled" : "プロキシ設定を有効にする",
192 "settings.service.form.proxy.password" : "Password (optional)", 199 "settings.service.form.proxy.password" : "パスワード(任意)",
193 "settings.service.form.proxy.user" : "User (optional)", 200 "settings.service.form.proxy.port" : "Port",
201 "settings.service.form.proxy.restartInfo" : "Please restart Franz after changing proxy Settings.",
202 "settings.service.form.proxy.user" : "ユーザー名(任意)",
194 "settings.service.form.saveButton" : "サービスの保存", 203 "settings.service.form.saveButton" : "サービスの保存",
204 "settings.service.form.spellcheckerLanguage" : "Spell checking Language",
205 "settings.service.form.spellcheckerLanguage.default" : "Use System Default ({default})",
195 "settings.service.form.tabHosted" : "ホスト", 206 "settings.service.form.tabHosted" : "ホスト",
196 "settings.service.form.tabOnPremise" : "セルフホスト ⭐️", 207 "settings.service.form.tabOnPremise" : "セルフホスト ⭐️",
197 "settings.service.form.team" : "チーム", 208 "settings.service.form.team" : "チーム",
@@ -234,11 +245,11 @@
234 "subscription.features.ads" : "広告は一切ありません!", 245 "subscription.features.ads" : "広告は一切ありません!",
235 "subscription.features.comingSoon" : "まもなく登場", 246 "subscription.features.comingSoon" : "まもなく登場",
236 "subscription.features.encryptedSync" : "暗号化されたセッションの同期", 247 "subscription.features.encryptedSync" : "暗号化されたセッションの同期",
237 "subscription.features.noInterruptions" : "No app delays & nagging to upgrade license", 248 "subscription.features.noInterruptions" : "待ち時間なしでFranz をお使いいただけます",
238 "subscription.features.onpremise" : "HipChatのようなオンプレミス\/ホスト型サービスの追加", 249 "subscription.features.onpremise" : "HipChatのようなオンプレミス\/ホスト型サービスの追加",
239 "subscription.features.onpremise.mattermost" : "Add on-premise\/hosted services like Mattermost", 250 "subscription.features.onpremise.mattermost" : "Mattermost のようなオンプレミス(自社運用)型のサービスを追加できるようになります",
240 "subscription.features.proxy" : "Proxy support for services", 251 "subscription.features.proxy" : "プロキシ設定が利用可能",
241 "subscription.features.spellchecker" : "Support for spellchecker", 252 "subscription.features.spellchecker" : "スペルチェック機能をお使いいただけます",
242 "subscription.includedFeatures" : "Franz Premium Supporter有料アカウントには以下が含まれます", 253 "subscription.includedFeatures" : "Franz Premium Supporter有料アカウントには以下が含まれます",
243 "subscription.paymentSessionError" : "支払いフォームを初期化出来ません", 254 "subscription.paymentSessionError" : "支払いフォームを初期化出来ません",
244 "subscription.submit.label" : "Franzの開発を支援したい", 255 "subscription.submit.label" : "Franzの開発を支援したい",
diff --git a/src/i18n/locales/ka.json b/src/i18n/locales/ka.json
index d521c838a..632ca618e 100644
--- a/src/i18n/locales/ka.json
+++ b/src/i18n/locales/ka.json
@@ -1,4 +1,6 @@
1{ 1{
2 "app.errorHandler.action" : "ჩატვირთვა",
3 "app.errorHandler.headline" : "Something went wrong",
2 "feature.delayApp.action" : "Get a Franz Supporter License", 4 "feature.delayApp.action" : "Get a Franz Supporter License",
3 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting", 5 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting",
4 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.", 6 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.",
@@ -90,6 +92,11 @@
90 "service.crashHandler.text" : "{name} has caused an error.", 92 "service.crashHandler.text" : "{name} has caused an error.",
91 "service.disabledHandler.action" : "Enable {name}", 93 "service.disabledHandler.action" : "Enable {name}",
92 "service.disabledHandler.headline" : "{name} is disabled", 94 "service.disabledHandler.headline" : "{name} is disabled",
95 "service.errorHandler.action" : "Reload {name}",
96 "service.errorHandler.editAction" : "შეასწორე {name}",
97 "service.errorHandler.headline" : "Oh no!",
98 "service.errorHandler.message" : "შეცდომა",
99 "service.errorHandler.text" : "{name} has failed to load.",
93 "services.getStarted" : "დაწყება", 100 "services.getStarted" : "დაწყება",
94 "services.welcome" : "მოგესალმებით Franz-ზე", 101 "services.welcome" : "მოგესალმებით Franz-ზე",
95 "settings.account.account.editButton" : "ანგარიშის მართვა", 102 "settings.account.account.editButton" : "ანგარიშის მართვა",
@@ -185,13 +192,17 @@
185 "settings.service.form.indirectMessages" : "აჩვენე შეტყობინებების ნიშანი ყოველი ახალი შეტყობინებისთვის", 192 "settings.service.form.indirectMessages" : "აჩვენე შეტყობინებების ნიშანი ყოველი ახალი შეტყობინებისთვის",
186 "settings.service.form.isMutedInfo" : "When disabled, all notification sounds and audio playback are muted", 193 "settings.service.form.isMutedInfo" : "When disabled, all notification sounds and audio playback are muted",
187 "settings.service.form.name" : "სახელი", 194 "settings.service.form.name" : "სახელი",
188 "settings.service.form.proxy.headline" : "Proxy Settings", 195 "settings.service.form.proxy.headline" : "HTTP\/HTTPS Proxy Settings",
189 "settings.service.form.proxy.host" : "Proxy Host\/IP", 196 "settings.service.form.proxy.host" : "Proxy Host\/IP",
190 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.", 197 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.",
191 "settings.service.form.proxy.isEnabled" : "Use Proxy", 198 "settings.service.form.proxy.isEnabled" : "Use Proxy",
192 "settings.service.form.proxy.password" : "Password (optional)", 199 "settings.service.form.proxy.password" : "Password (optional)",
200 "settings.service.form.proxy.port" : "Port",
201 "settings.service.form.proxy.restartInfo" : "Please restart Franz after changing proxy Settings.",
193 "settings.service.form.proxy.user" : "User (optional)", 202 "settings.service.form.proxy.user" : "User (optional)",
194 "settings.service.form.saveButton" : "სერვისის შენახვა", 203 "settings.service.form.saveButton" : "სერვისის შენახვა",
204 "settings.service.form.spellcheckerLanguage" : "Spell checking Language",
205 "settings.service.form.spellcheckerLanguage.default" : "Use System Default ({default})",
195 "settings.service.form.tabHosted" : "დაჰოსტილი", 206 "settings.service.form.tabHosted" : "დაჰოსტილი",
196 "settings.service.form.tabOnPremise" : "თვით დაჰოსტილი ⭐️", 207 "settings.service.form.tabOnPremise" : "თვით დაჰოსტილი ⭐️",
197 "settings.service.form.team" : "გუნდი", 208 "settings.service.form.team" : "გუნდი",
diff --git a/src/i18n/locales/nl-BE.json b/src/i18n/locales/nl-BE.json
index 5807f11f6..c38a7f024 100644
--- a/src/i18n/locales/nl-BE.json
+++ b/src/i18n/locales/nl-BE.json
@@ -1,4 +1,6 @@
1{ 1{
2 "app.errorHandler.action" : "Herladen",
3 "app.errorHandler.headline" : "Something went wrong",
2 "feature.delayApp.action" : "Get a Franz Supporter License", 4 "feature.delayApp.action" : "Get a Franz Supporter License",
3 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting", 5 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting",
4 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.", 6 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.",
@@ -90,6 +92,11 @@
90 "service.crashHandler.text" : "{name} heeft een probleem veroorzaakt.", 92 "service.crashHandler.text" : "{name} heeft een probleem veroorzaakt.",
91 "service.disabledHandler.action" : "Activeer {name}", 93 "service.disabledHandler.action" : "Activeer {name}",
92 "service.disabledHandler.headline" : "{name} is uitgeschakeld", 94 "service.disabledHandler.headline" : "{name} is uitgeschakeld",
95 "service.errorHandler.action" : "{naam} herladen",
96 "service.errorHandler.editAction" : "{name} aanpassen",
97 "service.errorHandler.headline" : "Oh nee!",
98 "service.errorHandler.message" : "Fout",
99 "service.errorHandler.text" : "{name} has failed to load.",
93 "services.getStarted" : "Beginnen", 100 "services.getStarted" : "Beginnen",
94 "services.welcome" : "Welkom bij Franz", 101 "services.welcome" : "Welkom bij Franz",
95 "settings.account.account.editButton" : "Bewerk account", 102 "settings.account.account.editButton" : "Bewerk account",
@@ -185,13 +192,17 @@
185 "settings.service.form.indirectMessages" : "Toon berichten-badge voor alle nieuwe berichten", 192 "settings.service.form.indirectMessages" : "Toon berichten-badge voor alle nieuwe berichten",
186 "settings.service.form.isMutedInfo" : "When disabled, all notification sounds and audio playback are muted", 193 "settings.service.form.isMutedInfo" : "When disabled, all notification sounds and audio playback are muted",
187 "settings.service.form.name" : "Naam", 194 "settings.service.form.name" : "Naam",
188 "settings.service.form.proxy.headline" : "Proxy Settings", 195 "settings.service.form.proxy.headline" : "HTTP\/HTTPS Proxy Settings",
189 "settings.service.form.proxy.host" : "Proxy Host\/IP", 196 "settings.service.form.proxy.host" : "Proxy Host\/IP",
190 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.", 197 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.",
191 "settings.service.form.proxy.isEnabled" : "Use Proxy", 198 "settings.service.form.proxy.isEnabled" : "Use Proxy",
192 "settings.service.form.proxy.password" : "Password (optional)", 199 "settings.service.form.proxy.password" : "Password (optional)",
200 "settings.service.form.proxy.port" : "Port",
201 "settings.service.form.proxy.restartInfo" : "Please restart Franz after changing proxy Settings.",
193 "settings.service.form.proxy.user" : "User (optional)", 202 "settings.service.form.proxy.user" : "User (optional)",
194 "settings.service.form.saveButton" : "Service bewaren", 203 "settings.service.form.saveButton" : "Service bewaren",
204 "settings.service.form.spellcheckerLanguage" : "Spell checking Language",
205 "settings.service.form.spellcheckerLanguage.default" : "Use System Default ({default})",
195 "settings.service.form.tabHosted" : "Gehost", 206 "settings.service.form.tabHosted" : "Gehost",
196 "settings.service.form.tabOnPremise" : "Intern gehost ⭐️", 207 "settings.service.form.tabOnPremise" : "Intern gehost ⭐️",
197 "settings.service.form.team" : "Team", 208 "settings.service.form.team" : "Team",
diff --git a/src/i18n/locales/nl.json b/src/i18n/locales/nl.json
index a6db3d773..940f24b0b 100644
--- a/src/i18n/locales/nl.json
+++ b/src/i18n/locales/nl.json
@@ -1,7 +1,9 @@
1{ 1{
2 "feature.delayApp.action" : "Get a Franz Supporter License", 2 "app.errorHandler.action" : "Laad opnieuw",
3 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting", 3 "app.errorHandler.headline" : "Something went wrong",
4 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.", 4 "feature.delayApp.action" : "Sponsor Franz",
5 "feature.delayApp.headline" : "Sponsor Franz om wachten over te slaan",
6 "feature.delayApp.text" : "Franz gaat over {seconds} seconden verder.",
5 "global.api.unhealthy" : "Kan geen verbinding maken met de Franz-services", 7 "global.api.unhealthy" : "Kan geen verbinding maken met de Franz-services",
6 "global.notConnectedToTheInternet" : "U bent niet verbonden met het internet.", 8 "global.notConnectedToTheInternet" : "U bent niet verbonden met het internet.",
7 "import.headline" : "Importeer uw Franz 4-services", 9 "import.headline" : "Importeer uw Franz 4-services",
@@ -79,7 +81,7 @@
79 "password.noUser" : "Geen gebruiker bekend met dat e-mailadres", 81 "password.noUser" : "Geen gebruiker bekend met dat e-mailadres",
80 "password.submit.label" : "Verzenden", 82 "password.submit.label" : "Verzenden",
81 "password.successInfo" : "Controleer alsjeblieft je e-mail", 83 "password.successInfo" : "Controleer alsjeblieft je e-mail",
82 "premiumFeature.button.upgradeAccount" : "Upgrade account", 84 "premiumFeature.button.upgradeAccount" : "Upgrade Account",
83 "pricing.headline" : "Steun Franz", 85 "pricing.headline" : "Steun Franz",
84 "pricing.link.skipPayment" : "Ik wil de ontwikkeling van Franz niet ondersteunen.", 86 "pricing.link.skipPayment" : "Ik wil de ontwikkeling van Franz niet ondersteunen.",
85 "pricing.submit.label" : "Ik wil de ontwikkeling van Franz steunen", 87 "pricing.submit.label" : "Ik wil de ontwikkeling van Franz steunen",
@@ -90,6 +92,11 @@
90 "service.crashHandler.text" : "{name} heeft een fout veroorzaakt.", 92 "service.crashHandler.text" : "{name} heeft een fout veroorzaakt.",
91 "service.disabledHandler.action" : "Activeer {name}", 93 "service.disabledHandler.action" : "Activeer {name}",
92 "service.disabledHandler.headline" : "{name} is uitgeschakeld", 94 "service.disabledHandler.headline" : "{name} is uitgeschakeld",
95 "service.errorHandler.action" : "Laad {name} opnieuw",
96 "service.errorHandler.editAction" : "Bewerk {name}",
97 "service.errorHandler.headline" : "Oh nee!",
98 "service.errorHandler.message" : "Fout",
99 "service.errorHandler.text" : "{name} has failed to load.",
93 "services.getStarted" : "Begin", 100 "services.getStarted" : "Begin",
94 "services.welcome" : "Welkom bij Franz", 101 "services.welcome" : "Welkom bij Franz",
95 "settings.account.account.editButton" : "Bewerk account", 102 "settings.account.account.editButton" : "Bewerk account",
@@ -120,7 +127,7 @@
120 "settings.app.form.autoLaunchInBackground" : "Open op de achtergrond", 127 "settings.app.form.autoLaunchInBackground" : "Open op de achtergrond",
121 "settings.app.form.autoLaunchOnStart" : "Open Franz bij opstarten", 128 "settings.app.form.autoLaunchOnStart" : "Open Franz bij opstarten",
122 "settings.app.form.beta" : "Inclusief bètaversies", 129 "settings.app.form.beta" : "Inclusief bètaversies",
123 "settings.app.form.darkMode" : "Join the Dark Side", 130 "settings.app.form.darkMode" : "Stap over naar de donkere kant",
124 "settings.app.form.enableGPUAcceleration" : "Schakel videokaart acceleratie in ", 131 "settings.app.form.enableGPUAcceleration" : "Schakel videokaart acceleratie in ",
125 "settings.app.form.enableMenuBar" : "Toon Franz in menubalk", 132 "settings.app.form.enableMenuBar" : "Toon Franz in menubalk",
126 "settings.app.form.enableSpellchecking" : "Zet spellingcontrole aan", 133 "settings.app.form.enableSpellchecking" : "Zet spellingcontrole aan",
@@ -131,7 +138,7 @@
131 "settings.app.form.runInBackground" : "Houd Franz op de achtergrond wanneer het venster gesloten wordt", 138 "settings.app.form.runInBackground" : "Houd Franz op de achtergrond wanneer het venster gesloten wordt",
132 "settings.app.form.showDisabledServices" : "Toon uitgeschakelde services", 139 "settings.app.form.showDisabledServices" : "Toon uitgeschakelde services",
133 "settings.app.form.showMessagesBadgesWhenMuted" : "Toon badge met ongelezen berichten wanneer meldingen zijn uitgeschakeld", 140 "settings.app.form.showMessagesBadgesWhenMuted" : "Toon badge met ongelezen berichten wanneer meldingen zijn uitgeschakeld",
134 "settings.app.form.spellcheckerLanguage" : "Spell checking language", 141 "settings.app.form.spellcheckerLanguage" : "Spelling checken",
135 "settings.app.headline" : "Instellingen", 142 "settings.app.headline" : "Instellingen",
136 "settings.app.headlineAdvanced" : "Geavanceerd", 143 "settings.app.headlineAdvanced" : "Geavanceerd",
137 "settings.app.headlineAppearance" : "Weergave", 144 "settings.app.headlineAppearance" : "Weergave",
@@ -172,7 +179,7 @@
172 "settings.service.form.editServiceHeadline" : "Bewerk {name}", 179 "settings.service.form.editServiceHeadline" : "Bewerk {name}",
173 "settings.service.form.enableAudio" : "Audio inschakelen", 180 "settings.service.form.enableAudio" : "Audio inschakelen",
174 "settings.service.form.enableBadge" : "Toon badges met ongelezen berichten", 181 "settings.service.form.enableBadge" : "Toon badges met ongelezen berichten",
175 "settings.service.form.enableDarkMode" : "Enable Dark Mode", 182 "settings.service.form.enableDarkMode" : "Dark mode aanzetten",
176 "settings.service.form.enableNotification" : "Meldingen inschakelen", 183 "settings.service.form.enableNotification" : "Meldingen inschakelen",
177 "settings.service.form.enableService" : "Service inschakelen", 184 "settings.service.form.enableService" : "Service inschakelen",
178 "settings.service.form.headlineBadges" : "Ongelezen berichten badges", 185 "settings.service.form.headlineBadges" : "Ongelezen berichten badges",
@@ -185,13 +192,17 @@
185 "settings.service.form.indirectMessages" : "Toon berichtenbadge voor alle nieuwe berichten", 192 "settings.service.form.indirectMessages" : "Toon berichtenbadge voor alle nieuwe berichten",
186 "settings.service.form.isMutedInfo" : "Indien uitgeschakeld zullen alle meldinggeluiden en afgespeelde audio uitgeschakeld zijn", 193 "settings.service.form.isMutedInfo" : "Indien uitgeschakeld zullen alle meldinggeluiden en afgespeelde audio uitgeschakeld zijn",
187 "settings.service.form.name" : "Naam", 194 "settings.service.form.name" : "Naam",
188 "settings.service.form.proxy.headline" : "Proxy Settings", 195 "settings.service.form.proxy.headline" : "HTTP\/HTTPS Proxy Settings",
189 "settings.service.form.proxy.host" : "Proxy Host\/IP", 196 "settings.service.form.proxy.host" : "Proxy Host\/IP",
190 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.", 197 "settings.service.form.proxy.info" : "Proxy instellingen worden niet gesynchroniseerd met de Franz servers",
191 "settings.service.form.proxy.isEnabled" : "Use Proxy", 198 "settings.service.form.proxy.isEnabled" : "Proxy gebruiken",
192 "settings.service.form.proxy.password" : "Password (optional)", 199 "settings.service.form.proxy.password" : "Wachtwoord (optioneel)",
193 "settings.service.form.proxy.user" : "User (optional)", 200 "settings.service.form.proxy.port" : "Port",
201 "settings.service.form.proxy.restartInfo" : "Please restart Franz after changing proxy Settings.",
202 "settings.service.form.proxy.user" : "Gebruiker (optioneel)",
194 "settings.service.form.saveButton" : "Service opslaan", 203 "settings.service.form.saveButton" : "Service opslaan",
204 "settings.service.form.spellcheckerLanguage" : "Spell checking Language",
205 "settings.service.form.spellcheckerLanguage.default" : "Use System Default ({default})",
195 "settings.service.form.tabHosted" : "Gehost", 206 "settings.service.form.tabHosted" : "Gehost",
196 "settings.service.form.tabOnPremise" : "Zelf-gehost ⭐️", 207 "settings.service.form.tabOnPremise" : "Zelf-gehost ⭐️",
197 "settings.service.form.team" : "Team", 208 "settings.service.form.team" : "Team",
@@ -234,11 +245,11 @@
234 "subscription.features.ads" : "Geen advertenties, nooit!", 245 "subscription.features.ads" : "Geen advertenties, nooit!",
235 "subscription.features.comingSoon" : "komt binnenkort", 246 "subscription.features.comingSoon" : "komt binnenkort",
236 "subscription.features.encryptedSync" : "Beveiligde sessie synchronisatie", 247 "subscription.features.encryptedSync" : "Beveiligde sessie synchronisatie",
237 "subscription.features.noInterruptions" : "No app delays & nagging to upgrade license", 248 "subscription.features.noInterruptions" : "Geen haperingen & pop ups over upgrades",
238 "subscription.features.onpremise" : "Add on-geschikt\/gehoste services zoals HipChat", 249 "subscription.features.onpremise" : "Add on-geschikt\/gehoste services zoals HipChat",
239 "subscription.features.onpremise.mattermost" : "Add on-premise\/hosted services like Mattermost", 250 "subscription.features.onpremise.mattermost" : "Add on-premise\/hosted services like Mattermost",
240 "subscription.features.proxy" : "Proxy support for services", 251 "subscription.features.proxy" : "Proxy understeuning voor diensten",
241 "subscription.features.spellchecker" : "Support for spellchecker", 252 "subscription.features.spellchecker" : "Ondersteuning voor spellingscheck",
242 "subscription.includedFeatures" : "Betaald Franz Premium Supporter Account bevat", 253 "subscription.includedFeatures" : "Betaald Franz Premium Supporter Account bevat",
243 "subscription.paymentSessionError" : "Kan betaalformulier niet initialiseren", 254 "subscription.paymentSessionError" : "Kan betaalformulier niet initialiseren",
244 "subscription.submit.label" : "Ik wil de ontwikkeling van Franz ondersteunen", 255 "subscription.submit.label" : "Ik wil de ontwikkeling van Franz ondersteunen",
diff --git a/src/i18n/locales/pl.json b/src/i18n/locales/pl.json
index 60ced5933..d45e5ce24 100644
--- a/src/i18n/locales/pl.json
+++ b/src/i18n/locales/pl.json
@@ -1,7 +1,9 @@
1{ 1{
2 "feature.delayApp.action" : "Get a Franz Supporter License", 2 "app.errorHandler.action" : "Przeładuj",
3 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting", 3 "app.errorHandler.headline" : "Something went wrong",
4 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.", 4 "feature.delayApp.action" : "Uzyskaj licencję Franz Supporter",
5 "feature.delayApp.headline" : "Kup licencję Franz Supporter , aby nie czekać",
6 "feature.delayApp.text" : "Franz będzie kontynuował za {seconds} sekund.",
5 "global.api.unhealthy" : "Nie można połączyć się z usługami Franz online", 7 "global.api.unhealthy" : "Nie można połączyć się z usługami Franz online",
6 "global.notConnectedToTheInternet" : "Nie masz połączenia z Internetem.", 8 "global.notConnectedToTheInternet" : "Nie masz połączenia z Internetem.",
7 "import.headline" : "Importuj usługi Franz 4", 9 "import.headline" : "Importuj usługi Franz 4",
@@ -90,6 +92,11 @@
90 "service.crashHandler.text" : "{name} spowodował problem.", 92 "service.crashHandler.text" : "{name} spowodował problem.",
91 "service.disabledHandler.action" : "Włącz {name}", 93 "service.disabledHandler.action" : "Włącz {name}",
92 "service.disabledHandler.headline" : "{name} jest wyłączony", 94 "service.disabledHandler.headline" : "{name} jest wyłączony",
95 "service.errorHandler.action" : "Przeładuj {name}",
96 "service.errorHandler.editAction" : "Edytuj {name}",
97 "service.errorHandler.headline" : "O nie!",
98 "service.errorHandler.message" : "Błąd",
99 "service.errorHandler.text" : "{name} has failed to load.",
93 "services.getStarted" : "Zacznij", 100 "services.getStarted" : "Zacznij",
94 "services.welcome" : "Witaj w programie Franz", 101 "services.welcome" : "Witaj w programie Franz",
95 "settings.account.account.editButton" : "Modyfikuj konta", 102 "settings.account.account.editButton" : "Modyfikuj konta",
@@ -120,7 +127,7 @@
120 "settings.app.form.autoLaunchInBackground" : "Otwórz w tle", 127 "settings.app.form.autoLaunchInBackground" : "Otwórz w tle",
121 "settings.app.form.autoLaunchOnStart" : "Uruchom Franz na początku", 128 "settings.app.form.autoLaunchOnStart" : "Uruchom Franz na początku",
122 "settings.app.form.beta" : "Uwzględnij wersje beta", 129 "settings.app.form.beta" : "Uwzględnij wersje beta",
123 "settings.app.form.darkMode" : "Join the Dark Side", 130 "settings.app.form.darkMode" : "Przejdź na Ciemną Stronę",
124 "settings.app.form.enableGPUAcceleration" : "Włącz akcelerację GPU", 131 "settings.app.form.enableGPUAcceleration" : "Włącz akcelerację GPU",
125 "settings.app.form.enableMenuBar" : "Pokaż Franz na pasku menu", 132 "settings.app.form.enableMenuBar" : "Pokaż Franz na pasku menu",
126 "settings.app.form.enableSpellchecking" : "Włącz sprawdzanie pisowni", 133 "settings.app.form.enableSpellchecking" : "Włącz sprawdzanie pisowni",
@@ -131,7 +138,7 @@
131 "settings.app.form.runInBackground" : "Zachowaj aplikację Franz w tle po zamknięciu okna", 138 "settings.app.form.runInBackground" : "Zachowaj aplikację Franz w tle po zamknięciu okna",
132 "settings.app.form.showDisabledServices" : "Wyłącz wyświetlanie zakładek z usługami", 139 "settings.app.form.showDisabledServices" : "Wyłącz wyświetlanie zakładek z usługami",
133 "settings.app.form.showMessagesBadgesWhenMuted" : "Pokaż licznik nieprzeczytanych wiadomości gdy powiadomienia są wyłączone", 140 "settings.app.form.showMessagesBadgesWhenMuted" : "Pokaż licznik nieprzeczytanych wiadomości gdy powiadomienia są wyłączone",
134 "settings.app.form.spellcheckerLanguage" : "Spell checking language", 141 "settings.app.form.spellcheckerLanguage" : "Język słownika",
135 "settings.app.headline" : "Ustawienia", 142 "settings.app.headline" : "Ustawienia",
136 "settings.app.headlineAdvanced" : "Zaawansowane", 143 "settings.app.headlineAdvanced" : "Zaawansowane",
137 "settings.app.headlineAppearance" : "Wygląd", 144 "settings.app.headlineAppearance" : "Wygląd",
@@ -172,7 +179,7 @@
172 "settings.service.form.editServiceHeadline" : "Edytuj {name}", 179 "settings.service.form.editServiceHeadline" : "Edytuj {name}",
173 "settings.service.form.enableAudio" : "Włącz dźwięk", 180 "settings.service.form.enableAudio" : "Włącz dźwięk",
174 "settings.service.form.enableBadge" : "Pokaż znacznik nieprzeczytanych wiadomości", 181 "settings.service.form.enableBadge" : "Pokaż znacznik nieprzeczytanych wiadomości",
175 "settings.service.form.enableDarkMode" : "Enable Dark Mode", 182 "settings.service.form.enableDarkMode" : "Włącz Ciemny motyw",
176 "settings.service.form.enableNotification" : "Aktywuj powiadomienia", 183 "settings.service.form.enableNotification" : "Aktywuj powiadomienia",
177 "settings.service.form.enableService" : "Aktywuj usługę", 184 "settings.service.form.enableService" : "Aktywuj usługę",
178 "settings.service.form.headlineBadges" : "Znaczniki nieprzeczytanych wiadomości", 185 "settings.service.form.headlineBadges" : "Znaczniki nieprzeczytanych wiadomości",
@@ -185,13 +192,17 @@
185 "settings.service.form.indirectMessages" : "Pokaż ikonę wiadomości dla wszystkich nowych wiadomości", 192 "settings.service.form.indirectMessages" : "Pokaż ikonę wiadomości dla wszystkich nowych wiadomości",
186 "settings.service.form.isMutedInfo" : "Kiedy nieaktywne, wszystkie dźwięki powiadomień są wyciszone", 193 "settings.service.form.isMutedInfo" : "Kiedy nieaktywne, wszystkie dźwięki powiadomień są wyciszone",
187 "settings.service.form.name" : "Nazwa", 194 "settings.service.form.name" : "Nazwa",
188 "settings.service.form.proxy.headline" : "Proxy Settings", 195 "settings.service.form.proxy.headline" : "HTTP\/HTTPS Proxy Settings",
189 "settings.service.form.proxy.host" : "Proxy Host\/IP", 196 "settings.service.form.proxy.host" : "Host Proxy\/IP",
190 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.", 197 "settings.service.form.proxy.info" : "Ustawienia proxy nie będą zsynchronizowane z serwerami Franza.",
191 "settings.service.form.proxy.isEnabled" : "Use Proxy", 198 "settings.service.form.proxy.isEnabled" : "Użyj Proxy",
192 "settings.service.form.proxy.password" : "Password (optional)", 199 "settings.service.form.proxy.password" : "Hasło (opcjonalnie)",
193 "settings.service.form.proxy.user" : "User (optional)", 200 "settings.service.form.proxy.port" : "Port",
201 "settings.service.form.proxy.restartInfo" : "Please restart Franz after changing proxy Settings.",
202 "settings.service.form.proxy.user" : "Użytkownik (opcjonalnie)",
194 "settings.service.form.saveButton" : "Zapisz usługę", 203 "settings.service.form.saveButton" : "Zapisz usługę",
204 "settings.service.form.spellcheckerLanguage" : "Spell checking Language",
205 "settings.service.form.spellcheckerLanguage.default" : "Use System Default ({default})",
195 "settings.service.form.tabHosted" : "Hostowane", 206 "settings.service.form.tabHosted" : "Hostowane",
196 "settings.service.form.tabOnPremise" : "Hostowane lokalnie ⭐️", 207 "settings.service.form.tabOnPremise" : "Hostowane lokalnie ⭐️",
197 "settings.service.form.team" : "Zespół", 208 "settings.service.form.team" : "Zespół",
@@ -237,7 +248,7 @@
237 "subscription.features.noInterruptions" : "No app delays & nagging to upgrade license", 248 "subscription.features.noInterruptions" : "No app delays & nagging to upgrade license",
238 "subscription.features.onpremise" : "Dodawanie lokalnych\/hostowanych usług takich jak HipChat", 249 "subscription.features.onpremise" : "Dodawanie lokalnych\/hostowanych usług takich jak HipChat",
239 "subscription.features.onpremise.mattermost" : "Add on-premise\/hosted services like Mattermost", 250 "subscription.features.onpremise.mattermost" : "Add on-premise\/hosted services like Mattermost",
240 "subscription.features.proxy" : "Proxy support for services", 251 "subscription.features.proxy" : "Obsługa proxy dla usług",
241 "subscription.features.spellchecker" : "Support for spellchecker", 252 "subscription.features.spellchecker" : "Support for spellchecker",
242 "subscription.includedFeatures" : "Płatne konto Franz Premium obejmuje", 253 "subscription.includedFeatures" : "Płatne konto Franz Premium obejmuje",
243 "subscription.paymentSessionError" : "Nie można wczytać formularza płatności\"", 254 "subscription.paymentSessionError" : "Nie można wczytać formularza płatności\"",
diff --git a/src/i18n/locales/pt-BR.json b/src/i18n/locales/pt-BR.json
index 70f6431df..c0cf0039f 100644
--- a/src/i18n/locales/pt-BR.json
+++ b/src/i18n/locales/pt-BR.json
@@ -1,7 +1,9 @@
1{ 1{
2 "feature.delayApp.action" : "Get a Franz Supporter License", 2 "app.errorHandler.action" : "Recarregar",
3 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting", 3 "app.errorHandler.headline" : "Something went wrong",
4 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.", 4 "feature.delayApp.action" : "Adquira uma licença Franz Supporter",
5 "feature.delayApp.headline" : "Por favor, adquira uma licença Franz Supporter para pular o tempo de espera",
6 "feature.delayApp.text" : "Franz continuará em {seconds} segundos.",
5 "global.api.unhealthy" : "Não foi possível conectar-se aos serviços on-line do Franz.", 7 "global.api.unhealthy" : "Não foi possível conectar-se aos serviços on-line do Franz.",
6 "global.notConnectedToTheInternet" : "Você não está conectado à internet", 8 "global.notConnectedToTheInternet" : "Você não está conectado à internet",
7 "import.headline" : "Importe seus serviços do Franz 4 ", 9 "import.headline" : "Importe seus serviços do Franz 4 ",
@@ -79,7 +81,7 @@
79 "password.noUser" : "Nenhum usuário com este e-mail foi encontrado", 81 "password.noUser" : "Nenhum usuário com este e-mail foi encontrado",
80 "password.submit.label" : "Enviar", 82 "password.submit.label" : "Enviar",
81 "password.successInfo" : "Por favor, verifique o seu e-mail", 83 "password.successInfo" : "Por favor, verifique o seu e-mail",
82 "premiumFeature.button.upgradeAccount" : "Upgrade account", 84 "premiumFeature.button.upgradeAccount" : "Atualizar conta",
83 "pricing.headline" : "Apoie o Franz", 85 "pricing.headline" : "Apoie o Franz",
84 "pricing.link.skipPayment" : "Eu não quero apoiar o desenvolvimento do Franz.", 86 "pricing.link.skipPayment" : "Eu não quero apoiar o desenvolvimento do Franz.",
85 "pricing.submit.label" : "Eu quero apoiar o desenvolvimento do Franz", 87 "pricing.submit.label" : "Eu quero apoiar o desenvolvimento do Franz",
@@ -90,6 +92,11 @@
90 "service.crashHandler.text" : "{name} causou um erro.", 92 "service.crashHandler.text" : "{name} causou um erro.",
91 "service.disabledHandler.action" : "Ativar {name}", 93 "service.disabledHandler.action" : "Ativar {name}",
92 "service.disabledHandler.headline" : "{name} está desativado", 94 "service.disabledHandler.headline" : "{name} está desativado",
95 "service.errorHandler.action" : "Recarregar {name}",
96 "service.errorHandler.editAction" : "Editar {name}",
97 "service.errorHandler.headline" : "Ah, não!",
98 "service.errorHandler.message" : "Erro",
99 "service.errorHandler.text" : "{name} has failed to load.",
93 "services.getStarted" : "Iniciar", 100 "services.getStarted" : "Iniciar",
94 "services.welcome" : "Bem-vindo ao Franz!", 101 "services.welcome" : "Bem-vindo ao Franz!",
95 "settings.account.account.editButton" : "Editar conta", 102 "settings.account.account.editButton" : "Editar conta",
@@ -120,7 +127,7 @@
120 "settings.app.form.autoLaunchInBackground" : "Abrir em segundo plano", 127 "settings.app.form.autoLaunchInBackground" : "Abrir em segundo plano",
121 "settings.app.form.autoLaunchOnStart" : "Abrir o Franz ao iniciar o sistema", 128 "settings.app.form.autoLaunchOnStart" : "Abrir o Franz ao iniciar o sistema",
122 "settings.app.form.beta" : "Incluir versões beta", 129 "settings.app.form.beta" : "Incluir versões beta",
123 "settings.app.form.darkMode" : "Join the Dark Side", 130 "settings.app.form.darkMode" : "Venha para o Lado Negro da força",
124 "settings.app.form.enableGPUAcceleration" : "Ativar Aceleração de GPU", 131 "settings.app.form.enableGPUAcceleration" : "Ativar Aceleração de GPU",
125 "settings.app.form.enableMenuBar" : "Mostrar Franz na Barra de Menu", 132 "settings.app.form.enableMenuBar" : "Mostrar Franz na Barra de Menu",
126 "settings.app.form.enableSpellchecking" : "Ativar correção ortográfica", 133 "settings.app.form.enableSpellchecking" : "Ativar correção ortográfica",
@@ -131,7 +138,7 @@
131 "settings.app.form.runInBackground" : "Manter o Franz no fundo quando fechar a janela", 138 "settings.app.form.runInBackground" : "Manter o Franz no fundo quando fechar a janela",
132 "settings.app.form.showDisabledServices" : "Mostrar abas de serviços desativados", 139 "settings.app.form.showDisabledServices" : "Mostrar abas de serviços desativados",
133 "settings.app.form.showMessagesBadgesWhenMuted" : "Mostrar ícone de mensagem não lida quando as notificações estiverem desativadas", 140 "settings.app.form.showMessagesBadgesWhenMuted" : "Mostrar ícone de mensagem não lida quando as notificações estiverem desativadas",
134 "settings.app.form.spellcheckerLanguage" : "Spell checking language", 141 "settings.app.form.spellcheckerLanguage" : "Idioma de verificação ortográfica",
135 "settings.app.headline" : "Configurações", 142 "settings.app.headline" : "Configurações",
136 "settings.app.headlineAdvanced" : "Avançado", 143 "settings.app.headlineAdvanced" : "Avançado",
137 "settings.app.headlineAppearance" : "Aparência", 144 "settings.app.headlineAppearance" : "Aparência",
@@ -172,7 +179,7 @@
172 "settings.service.form.editServiceHeadline" : "Editar {name}", 179 "settings.service.form.editServiceHeadline" : "Editar {name}",
173 "settings.service.form.enableAudio" : "Ativar áudio", 180 "settings.service.form.enableAudio" : "Ativar áudio",
174 "settings.service.form.enableBadge" : "Mostrar aviso de mensagens não lidas", 181 "settings.service.form.enableBadge" : "Mostrar aviso de mensagens não lidas",
175 "settings.service.form.enableDarkMode" : "Enable Dark Mode", 182 "settings.service.form.enableDarkMode" : "Ativar modo noturno",
176 "settings.service.form.enableNotification" : "Ativar notificações", 183 "settings.service.form.enableNotification" : "Ativar notificações",
177 "settings.service.form.enableService" : "Ativar serviço", 184 "settings.service.form.enableService" : "Ativar serviço",
178 "settings.service.form.headlineBadges" : "Mensagens não lidas", 185 "settings.service.form.headlineBadges" : "Mensagens não lidas",
@@ -185,13 +192,17 @@
185 "settings.service.form.indirectMessages" : "Mostrar avisos para todas as mensagens", 192 "settings.service.form.indirectMessages" : "Mostrar avisos para todas as mensagens",
186 "settings.service.form.isMutedInfo" : "Quando desativado, as notificações sonoras e áudios ficarão em silêncio", 193 "settings.service.form.isMutedInfo" : "Quando desativado, as notificações sonoras e áudios ficarão em silêncio",
187 "settings.service.form.name" : "Nome", 194 "settings.service.form.name" : "Nome",
188 "settings.service.form.proxy.headline" : "Proxy Settings", 195 "settings.service.form.proxy.headline" : "HTTP\/HTTPS Proxy Settings",
189 "settings.service.form.proxy.host" : "Proxy Host\/IP", 196 "settings.service.form.proxy.host" : "Proxy Host\/IP",
190 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.", 197 "settings.service.form.proxy.info" : "As configurações de proxy não serão sincronizadas com os servidores do Franz.",
191 "settings.service.form.proxy.isEnabled" : "Use Proxy", 198 "settings.service.form.proxy.isEnabled" : "Usar o Proxy",
192 "settings.service.form.proxy.password" : "Password (optional)", 199 "settings.service.form.proxy.password" : "Senha (opcional)",
193 "settings.service.form.proxy.user" : "User (optional)", 200 "settings.service.form.proxy.port" : "Port",
201 "settings.service.form.proxy.restartInfo" : "Please restart Franz after changing proxy Settings.",
202 "settings.service.form.proxy.user" : "Usuário (opcional)",
194 "settings.service.form.saveButton" : "Salvar serviço", 203 "settings.service.form.saveButton" : "Salvar serviço",
204 "settings.service.form.spellcheckerLanguage" : "Spell checking Language",
205 "settings.service.form.spellcheckerLanguage.default" : "Use System Default ({default})",
195 "settings.service.form.tabHosted" : "Hospedado", 206 "settings.service.form.tabHosted" : "Hospedado",
196 "settings.service.form.tabOnPremise" : "Auto-hospedado ⭐️", 207 "settings.service.form.tabOnPremise" : "Auto-hospedado ⭐️",
197 "settings.service.form.team" : "Equipe", 208 "settings.service.form.team" : "Equipe",
@@ -237,8 +248,8 @@
237 "subscription.features.noInterruptions" : "No app delays & nagging to upgrade license", 248 "subscription.features.noInterruptions" : "No app delays & nagging to upgrade license",
238 "subscription.features.onpremise" : "Adicionar serviços locais\/hospedados como o HipChat", 249 "subscription.features.onpremise" : "Adicionar serviços locais\/hospedados como o HipChat",
239 "subscription.features.onpremise.mattermost" : "Add on-premise\/hosted services like Mattermost", 250 "subscription.features.onpremise.mattermost" : "Add on-premise\/hosted services like Mattermost",
240 "subscription.features.proxy" : "Proxy support for services", 251 "subscription.features.proxy" : "Suporte de proxy para serviços",
241 "subscription.features.spellchecker" : "Support for spellchecker", 252 "subscription.features.spellchecker" : "Suporte para corretor ortográfico",
242 "subscription.includedFeatures" : "A conta Apoiador Franz Premium inclui", 253 "subscription.includedFeatures" : "A conta Apoiador Franz Premium inclui",
243 "subscription.paymentSessionError" : "Não foi possível abrir o formulário de pagamento", 254 "subscription.paymentSessionError" : "Não foi possível abrir o formulário de pagamento",
244 "subscription.submit.label" : "Eu quero apoiar o desenvolvimento do Franz", 255 "subscription.submit.label" : "Eu quero apoiar o desenvolvimento do Franz",
diff --git a/src/i18n/locales/pt.json b/src/i18n/locales/pt.json
index 71978ed6b..80e8094f5 100644
--- a/src/i18n/locales/pt.json
+++ b/src/i18n/locales/pt.json
@@ -1,4 +1,6 @@
1{ 1{
2 "app.errorHandler.action" : "Recarregar",
3 "app.errorHandler.headline" : "Something went wrong",
2 "feature.delayApp.action" : "Get a Franz Supporter License", 4 "feature.delayApp.action" : "Get a Franz Supporter License",
3 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting", 5 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting",
4 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.", 6 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.",
@@ -90,6 +92,11 @@
90 "service.crashHandler.text" : "{name} causou um erro.", 92 "service.crashHandler.text" : "{name} causou um erro.",
91 "service.disabledHandler.action" : "Ativar {name}", 93 "service.disabledHandler.action" : "Ativar {name}",
92 "service.disabledHandler.headline" : "{name} está desativado", 94 "service.disabledHandler.headline" : "{name} está desativado",
95 "service.errorHandler.action" : "Recarregar {name}",
96 "service.errorHandler.editAction" : "Editar {name}",
97 "service.errorHandler.headline" : "Oh não!",
98 "service.errorHandler.message" : "Erro",
99 "service.errorHandler.text" : "{name} has failed to load.",
93 "services.getStarted" : "Vamos começar", 100 "services.getStarted" : "Vamos começar",
94 "services.welcome" : "Bem-vindo ao Franz", 101 "services.welcome" : "Bem-vindo ao Franz",
95 "settings.account.account.editButton" : "Editar conta", 102 "settings.account.account.editButton" : "Editar conta",
@@ -185,13 +192,17 @@
185 "settings.service.form.indirectMessages" : "Mostrar o emblema da mensagem para todas as novas mensagens", 192 "settings.service.form.indirectMessages" : "Mostrar o emblema da mensagem para todas as novas mensagens",
186 "settings.service.form.isMutedInfo" : "Quando desativado, todos sons e reproduções de áudio serão silenciados", 193 "settings.service.form.isMutedInfo" : "Quando desativado, todos sons e reproduções de áudio serão silenciados",
187 "settings.service.form.name" : "Nome", 194 "settings.service.form.name" : "Nome",
188 "settings.service.form.proxy.headline" : "Proxy Settings", 195 "settings.service.form.proxy.headline" : "HTTP\/HTTPS Proxy Settings",
189 "settings.service.form.proxy.host" : "Proxy Host\/IP", 196 "settings.service.form.proxy.host" : "Proxy Host\/IP",
190 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.", 197 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.",
191 "settings.service.form.proxy.isEnabled" : "Use Proxy", 198 "settings.service.form.proxy.isEnabled" : "Use Proxy",
192 "settings.service.form.proxy.password" : "Password (optional)", 199 "settings.service.form.proxy.password" : "Password (optional)",
200 "settings.service.form.proxy.port" : "Port",
201 "settings.service.form.proxy.restartInfo" : "Please restart Franz after changing proxy Settings.",
193 "settings.service.form.proxy.user" : "User (optional)", 202 "settings.service.form.proxy.user" : "User (optional)",
194 "settings.service.form.saveButton" : "Guardar serviço", 203 "settings.service.form.saveButton" : "Guardar serviço",
204 "settings.service.form.spellcheckerLanguage" : "Spell checking Language",
205 "settings.service.form.spellcheckerLanguage.default" : "Use System Default ({default})",
195 "settings.service.form.tabHosted" : "Com domínio", 206 "settings.service.form.tabHosted" : "Com domínio",
196 "settings.service.form.tabOnPremise" : "Com domínio próprio ⭐️", 207 "settings.service.form.tabOnPremise" : "Com domínio próprio ⭐️",
197 "settings.service.form.team" : "Equipa", 208 "settings.service.form.team" : "Equipa",
diff --git a/src/i18n/locales/ru.json b/src/i18n/locales/ru.json
index 78030dc15..b605afc4d 100644
--- a/src/i18n/locales/ru.json
+++ b/src/i18n/locales/ru.json
@@ -1,4 +1,6 @@
1{ 1{
2 "app.errorHandler.action" : "Перезагрузить",
3 "app.errorHandler.headline" : "Something went wrong",
2 "feature.delayApp.action" : "Get a Franz Supporter License", 4 "feature.delayApp.action" : "Get a Franz Supporter License",
3 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting", 5 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting",
4 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.", 6 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.",
@@ -90,6 +92,11 @@
90 "service.crashHandler.text" : "{name} вызвало ошибку.", 92 "service.crashHandler.text" : "{name} вызвало ошибку.",
91 "service.disabledHandler.action" : "Включить {name}", 93 "service.disabledHandler.action" : "Включить {name}",
92 "service.disabledHandler.headline" : "{name} выключено", 94 "service.disabledHandler.headline" : "{name} выключено",
95 "service.errorHandler.action" : "Перезагрузить {name}",
96 "service.errorHandler.editAction" : "Редактирование {name}",
97 "service.errorHandler.headline" : "О, нет!",
98 "service.errorHandler.message" : "Ошибка",
99 "service.errorHandler.text" : "{name} has failed to load.",
93 "services.getStarted" : "Начать работу", 100 "services.getStarted" : "Начать работу",
94 "services.welcome" : "Добро пожаловать во Franz", 101 "services.welcome" : "Добро пожаловать во Franz",
95 "settings.account.account.editButton" : "Редактировать аккаунт", 102 "settings.account.account.editButton" : "Редактировать аккаунт",
@@ -185,13 +192,17 @@
185 "settings.service.form.indirectMessages" : "Показывать значок уведомлений для всех новых сообщений", 192 "settings.service.form.indirectMessages" : "Показывать значок уведомлений для всех новых сообщений",
186 "settings.service.form.isMutedInfo" : "Когда выключено, все звуковые уведомления будут отключены", 193 "settings.service.form.isMutedInfo" : "Когда выключено, все звуковые уведомления будут отключены",
187 "settings.service.form.name" : "Название", 194 "settings.service.form.name" : "Название",
188 "settings.service.form.proxy.headline" : "Proxy Settings", 195 "settings.service.form.proxy.headline" : "HTTP\/HTTPS Proxy Settings",
189 "settings.service.form.proxy.host" : "Proxy Host\/IP", 196 "settings.service.form.proxy.host" : "Proxy Host\/IP",
190 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.", 197 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.",
191 "settings.service.form.proxy.isEnabled" : "Use Proxy", 198 "settings.service.form.proxy.isEnabled" : "Use Proxy",
192 "settings.service.form.proxy.password" : "Password (optional)", 199 "settings.service.form.proxy.password" : "Password (optional)",
200 "settings.service.form.proxy.port" : "Port",
201 "settings.service.form.proxy.restartInfo" : "Please restart Franz after changing proxy Settings.",
193 "settings.service.form.proxy.user" : "User (optional)", 202 "settings.service.form.proxy.user" : "User (optional)",
194 "settings.service.form.saveButton" : "Сохранить сервис", 203 "settings.service.form.saveButton" : "Сохранить сервис",
204 "settings.service.form.spellcheckerLanguage" : "Spell checking Language",
205 "settings.service.form.spellcheckerLanguage.default" : "Use System Default ({default})",
195 "settings.service.form.tabHosted" : "Размещено", 206 "settings.service.form.tabHosted" : "Размещено",
196 "settings.service.form.tabOnPremise" : "Свой хостинг ⭐️", 207 "settings.service.form.tabOnPremise" : "Свой хостинг ⭐️",
197 "settings.service.form.team" : "Команда", 208 "settings.service.form.team" : "Команда",
diff --git a/src/i18n/locales/sk.json b/src/i18n/locales/sk.json
index 70e3e7f2d..ca7335fe9 100644
--- a/src/i18n/locales/sk.json
+++ b/src/i18n/locales/sk.json
@@ -1,4 +1,6 @@
1{ 1{
2 "app.errorHandler.action" : "Obnoviť",
3 "app.errorHandler.headline" : "Something went wrong",
2 "feature.delayApp.action" : "Get a Franz Supporter License", 4 "feature.delayApp.action" : "Get a Franz Supporter License",
3 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting", 5 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting",
4 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.", 6 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.",
@@ -90,6 +92,11 @@
90 "service.crashHandler.text" : "{name} spôsobil chybu.", 92 "service.crashHandler.text" : "{name} spôsobil chybu.",
91 "service.disabledHandler.action" : "Zapnúť {name}", 93 "service.disabledHandler.action" : "Zapnúť {name}",
92 "service.disabledHandler.headline" : "{name} je vypnuté", 94 "service.disabledHandler.headline" : "{name} je vypnuté",
95 "service.errorHandler.action" : "Znovu načítať {name}",
96 "service.errorHandler.editAction" : "Upraviť {name}",
97 "service.errorHandler.headline" : "Ale nie!",
98 "service.errorHandler.message" : "Chyba",
99 "service.errorHandler.text" : "{name} has failed to load.",
93 "services.getStarted" : "Začíname", 100 "services.getStarted" : "Začíname",
94 "services.welcome" : "Vítajte v aplikácii Franz", 101 "services.welcome" : "Vítajte v aplikácii Franz",
95 "settings.account.account.editButton" : "Upraviť účet", 102 "settings.account.account.editButton" : "Upraviť účet",
@@ -185,13 +192,17 @@
185 "settings.service.form.indirectMessages" : "Zobraziť symbol správy pre všetky nové správy", 192 "settings.service.form.indirectMessages" : "Zobraziť symbol správy pre všetky nové správy",
186 "settings.service.form.isMutedInfo" : "Ak je vypnuté, všetky zvuky oznámení a iné prehrávania budú stíšené", 193 "settings.service.form.isMutedInfo" : "Ak je vypnuté, všetky zvuky oznámení a iné prehrávania budú stíšené",
187 "settings.service.form.name" : "Meno", 194 "settings.service.form.name" : "Meno",
188 "settings.service.form.proxy.headline" : "Proxy Settings", 195 "settings.service.form.proxy.headline" : "HTTP\/HTTPS Proxy Settings",
189 "settings.service.form.proxy.host" : "Proxy Host\/IP", 196 "settings.service.form.proxy.host" : "Proxy Host\/IP",
190 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.", 197 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.",
191 "settings.service.form.proxy.isEnabled" : "Use Proxy", 198 "settings.service.form.proxy.isEnabled" : "Use Proxy",
192 "settings.service.form.proxy.password" : "Password (optional)", 199 "settings.service.form.proxy.password" : "Password (optional)",
200 "settings.service.form.proxy.port" : "Port",
201 "settings.service.form.proxy.restartInfo" : "Please restart Franz after changing proxy Settings.",
193 "settings.service.form.proxy.user" : "User (optional)", 202 "settings.service.form.proxy.user" : "User (optional)",
194 "settings.service.form.saveButton" : "Uložiť službu", 203 "settings.service.form.saveButton" : "Uložiť službu",
204 "settings.service.form.spellcheckerLanguage" : "Spell checking Language",
205 "settings.service.form.spellcheckerLanguage.default" : "Use System Default ({default})",
195 "settings.service.form.tabHosted" : "Hostované", 206 "settings.service.form.tabHosted" : "Hostované",
196 "settings.service.form.tabOnPremise" : "Vlastné hostovanie ⭐️", 207 "settings.service.form.tabOnPremise" : "Vlastné hostovanie ⭐️",
197 "settings.service.form.team" : "Tím", 208 "settings.service.form.team" : "Tím",
diff --git a/src/i18n/locales/sr.json b/src/i18n/locales/sr.json
index dd4c74277..df0b849c4 100644
--- a/src/i18n/locales/sr.json
+++ b/src/i18n/locales/sr.json
@@ -1,4 +1,6 @@
1{ 1{
2 "app.errorHandler.action" : "Ponovno učitavanje",
3 "app.errorHandler.headline" : "Something went wrong",
2 "feature.delayApp.action" : "Get a Franz Supporter License", 4 "feature.delayApp.action" : "Get a Franz Supporter License",
3 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting", 5 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting",
4 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.", 6 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.",
@@ -90,6 +92,11 @@
90 "service.crashHandler.text" : "{ime} je izazvalo grešku. ", 92 "service.crashHandler.text" : "{ime} je izazvalo grešku. ",
91 "service.disabledHandler.action" : "Omogući {ime} ", 93 "service.disabledHandler.action" : "Omogući {ime} ",
92 "service.disabledHandler.headline" : "{ime} je onemogućen\/o", 94 "service.disabledHandler.headline" : "{ime} je onemogućen\/o",
95 "service.errorHandler.action" : "Osvježi {ime}",
96 "service.errorHandler.editAction" : "Uredite {ime}",
97 "service.errorHandler.headline" : "O, ne! ",
98 "service.errorHandler.message" : "Greška ",
99 "service.errorHandler.text" : "{name} has failed to load.",
93 "services.getStarted" : "Započnimo! ", 100 "services.getStarted" : "Započnimo! ",
94 "services.welcome" : "Dobrodošli u Franz", 101 "services.welcome" : "Dobrodošli u Franz",
95 "settings.account.account.editButton" : "Uredi račun", 102 "settings.account.account.editButton" : "Uredi račun",
@@ -185,13 +192,17 @@
185 "settings.service.form.indirectMessages" : "Prikaži značku na svim novim porukuama", 192 "settings.service.form.indirectMessages" : "Prikaži značku na svim novim porukuama",
186 "settings.service.form.isMutedInfo" : "Kada je onemogućeno, sve obavijesti, svi zvukovi i sva pozadinska podrška će biti nečujna.", 193 "settings.service.form.isMutedInfo" : "Kada je onemogućeno, sve obavijesti, svi zvukovi i sva pozadinska podrška će biti nečujna.",
187 "settings.service.form.name" : "Ime", 194 "settings.service.form.name" : "Ime",
188 "settings.service.form.proxy.headline" : "Proxy Settings", 195 "settings.service.form.proxy.headline" : "HTTP\/HTTPS Proxy Settings",
189 "settings.service.form.proxy.host" : "Proxy Host\/IP", 196 "settings.service.form.proxy.host" : "Proxy Host\/IP",
190 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.", 197 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.",
191 "settings.service.form.proxy.isEnabled" : "Use Proxy", 198 "settings.service.form.proxy.isEnabled" : "Use Proxy",
192 "settings.service.form.proxy.password" : "Password (optional)", 199 "settings.service.form.proxy.password" : "Password (optional)",
200 "settings.service.form.proxy.port" : "Port",
201 "settings.service.form.proxy.restartInfo" : "Please restart Franz after changing proxy Settings.",
193 "settings.service.form.proxy.user" : "User (optional)", 202 "settings.service.form.proxy.user" : "User (optional)",
194 "settings.service.form.saveButton" : "Sačuvaj uslugu\/e", 203 "settings.service.form.saveButton" : "Sačuvaj uslugu\/e",
204 "settings.service.form.spellcheckerLanguage" : "Spell checking Language",
205 "settings.service.form.spellcheckerLanguage.default" : "Use System Default ({default})",
195 "settings.service.form.tabHosted" : "Hostovano", 206 "settings.service.form.tabHosted" : "Hostovano",
196 "settings.service.form.tabOnPremise" : "Samo-hostovano ⭐️", 207 "settings.service.form.tabOnPremise" : "Samo-hostovano ⭐️",
197 "settings.service.form.team" : "Tim", 208 "settings.service.form.team" : "Tim",
diff --git a/src/i18n/locales/tr.json b/src/i18n/locales/tr.json
index 130b51ddf..9e7619454 100644
--- a/src/i18n/locales/tr.json
+++ b/src/i18n/locales/tr.json
@@ -1,11 +1,13 @@
1{ 1{
2 "feature.delayApp.action" : "Get a Franz Supporter License", 2 "app.errorHandler.action" : "Yeniden Yükle",
3 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting", 3 "app.errorHandler.headline" : "Something went wrong",
4 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.", 4 "feature.delayApp.action" : "Franz Destek Lisansı'nı alın.",
5 "feature.delayApp.headline" : "Beklememek için Franz Destek Lisansı'nı satın alın.",
6 "feature.delayApp.text" : "Franz {seconds} saniye sonra devam edecek.",
5 "global.api.unhealthy" : "Franz hizmetlerine şu anda erişilemiyor.", 7 "global.api.unhealthy" : "Franz hizmetlerine şu anda erişilemiyor.",
6 "global.notConnectedToTheInternet" : "İnternete bağlı değilsiniz.", 8 "global.notConnectedToTheInternet" : "İnternete bağlı değilsiniz.",
7 "import.headline" : "Franz 4 servislerinizi ekleyin.", 9 "import.headline" : "Franz 4 servislerinizi ekleyin.",
8 "import.notSupportedHeadline" : "Servisler henüz Franz 5'de desteklenmiyor.", 10 "import.notSupportedHeadline" : "Servisler henüz Franz 5'te desteklenmiyor.",
9 "import.skip.label" : "Servisleri kendim eklemek istiyorum", 11 "import.skip.label" : "Servisleri kendim eklemek istiyorum",
10 "import.submit.label" : "Servisleri içe aktar", 12 "import.submit.label" : "Servisleri içe aktar",
11 "infobar.buttonChangelog" : "Yeni ne var?", 13 "infobar.buttonChangelog" : "Yeni ne var?",
@@ -90,6 +92,11 @@
90 "service.crashHandler.text" : "{name} bir hataya neden oldu.", 92 "service.crashHandler.text" : "{name} bir hataya neden oldu.",
91 "service.disabledHandler.action" : "{name} aktif", 93 "service.disabledHandler.action" : "{name} aktif",
92 "service.disabledHandler.headline" : "{name} devredışı", 94 "service.disabledHandler.headline" : "{name} devredışı",
95 "service.errorHandler.action" : "{name} yeniden yükle",
96 "service.errorHandler.editAction" : "{name} düzenle",
97 "service.errorHandler.headline" : "Aman Tanrım hayır!",
98 "service.errorHandler.message" : "Hata",
99 "service.errorHandler.text" : "{name} has failed to load.",
93 "services.getStarted" : "Haydi başlayalım", 100 "services.getStarted" : "Haydi başlayalım",
94 "services.welcome" : "Franz'a Hoşgeldiniz", 101 "services.welcome" : "Franz'a Hoşgeldiniz",
95 "settings.account.account.editButton" : "Hesabı düzenle", 102 "settings.account.account.editButton" : "Hesabı düzenle",
@@ -185,13 +192,17 @@
185 "settings.service.form.indirectMessages" : "Mesaj rozetini tüm yeni mesajlar için göster", 192 "settings.service.form.indirectMessages" : "Mesaj rozetini tüm yeni mesajlar için göster",
186 "settings.service.form.isMutedInfo" : "Devre dışı bırakıldığında, tüm bildirim sesleri sessize alınır", 193 "settings.service.form.isMutedInfo" : "Devre dışı bırakıldığında, tüm bildirim sesleri sessize alınır",
187 "settings.service.form.name" : "İsim", 194 "settings.service.form.name" : "İsim",
188 "settings.service.form.proxy.headline" : "Proxy Settings", 195 "settings.service.form.proxy.headline" : "HTTP\/HTTPS Proxy Settings",
189 "settings.service.form.proxy.host" : "Proxy Host\/IP", 196 "settings.service.form.proxy.host" : "Proxy Host\/IP",
190 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.", 197 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.",
191 "settings.service.form.proxy.isEnabled" : "Use Proxy", 198 "settings.service.form.proxy.isEnabled" : "Use Proxy",
192 "settings.service.form.proxy.password" : "Password (optional)", 199 "settings.service.form.proxy.password" : "Password (optional)",
200 "settings.service.form.proxy.port" : "Port",
201 "settings.service.form.proxy.restartInfo" : "Please restart Franz after changing proxy Settings.",
193 "settings.service.form.proxy.user" : "User (optional)", 202 "settings.service.form.proxy.user" : "User (optional)",
194 "settings.service.form.saveButton" : "Servisi kaydet", 203 "settings.service.form.saveButton" : "Servisi kaydet",
204 "settings.service.form.spellcheckerLanguage" : "Spell checking Language",
205 "settings.service.form.spellcheckerLanguage.default" : "Use System Default ({default})",
195 "settings.service.form.tabHosted" : "Barındırılan", 206 "settings.service.form.tabHosted" : "Barındırılan",
196 "settings.service.form.tabOnPremise" : "Kendi barındırılan", 207 "settings.service.form.tabOnPremise" : "Kendi barındırılan",
197 "settings.service.form.team" : "Takım", 208 "settings.service.form.team" : "Takım",
diff --git a/src/i18n/locales/uk.json b/src/i18n/locales/uk.json
index 94c6f7e54..7d51b380e 100644
--- a/src/i18n/locales/uk.json
+++ b/src/i18n/locales/uk.json
@@ -1,4 +1,6 @@
1{ 1{
2 "app.errorHandler.action" : "Перезавантажити",
3 "app.errorHandler.headline" : "Something went wrong",
2 "feature.delayApp.action" : "Get a Franz Supporter License", 4 "feature.delayApp.action" : "Get a Franz Supporter License",
3 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting", 5 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting",
4 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.", 6 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.",
@@ -90,6 +92,11 @@
90 "service.crashHandler.text" : "{name} призвів до помилки.", 92 "service.crashHandler.text" : "{name} призвів до помилки.",
91 "service.disabledHandler.action" : "Увімкнути {name} ", 93 "service.disabledHandler.action" : "Увімкнути {name} ",
92 "service.disabledHandler.headline" : "{name} вимкнено", 94 "service.disabledHandler.headline" : "{name} вимкнено",
95 "service.errorHandler.action" : "Перезавантажити {name}",
96 "service.errorHandler.editAction" : "Редагувати {name}",
97 "service.errorHandler.headline" : "О, ні!",
98 "service.errorHandler.message" : "Помилка",
99 "service.errorHandler.text" : "{name} has failed to load.",
93 "services.getStarted" : "Почати", 100 "services.getStarted" : "Почати",
94 "services.welcome" : "Ласкаво просимо в Franz", 101 "services.welcome" : "Ласкаво просимо в Franz",
95 "settings.account.account.editButton" : "Редагувати акаунт", 102 "settings.account.account.editButton" : "Редагувати акаунт",
@@ -185,13 +192,17 @@
185 "settings.service.form.indirectMessages" : "Показувати значок повідомлення для всіх нових повідомлень", 192 "settings.service.form.indirectMessages" : "Показувати значок повідомлення для всіх нових повідомлень",
186 "settings.service.form.isMutedInfo" : "Коли вимкнено, всі сповищення та відтворення ігноруються", 193 "settings.service.form.isMutedInfo" : "Коли вимкнено, всі сповищення та відтворення ігноруються",
187 "settings.service.form.name" : "Ім'я", 194 "settings.service.form.name" : "Ім'я",
188 "settings.service.form.proxy.headline" : "Proxy Settings", 195 "settings.service.form.proxy.headline" : "HTTP\/HTTPS Proxy Settings",
189 "settings.service.form.proxy.host" : "Proxy Host\/IP", 196 "settings.service.form.proxy.host" : "Proxy Host\/IP",
190 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.", 197 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.",
191 "settings.service.form.proxy.isEnabled" : "Use Proxy", 198 "settings.service.form.proxy.isEnabled" : "Use Proxy",
192 "settings.service.form.proxy.password" : "Password (optional)", 199 "settings.service.form.proxy.password" : "Password (optional)",
200 "settings.service.form.proxy.port" : "Port",
201 "settings.service.form.proxy.restartInfo" : "Please restart Franz after changing proxy Settings.",
193 "settings.service.form.proxy.user" : "User (optional)", 202 "settings.service.form.proxy.user" : "User (optional)",
194 "settings.service.form.saveButton" : "Зберегти сервіс", 203 "settings.service.form.saveButton" : "Зберегти сервіс",
204 "settings.service.form.spellcheckerLanguage" : "Spell checking Language",
205 "settings.service.form.spellcheckerLanguage.default" : "Use System Default ({default})",
195 "settings.service.form.tabHosted" : "Розміщений", 206 "settings.service.form.tabHosted" : "Розміщений",
196 "settings.service.form.tabOnPremise" : "Самостійно розміщений ⭐️", 207 "settings.service.form.tabOnPremise" : "Самостійно розміщений ⭐️",
197 "settings.service.form.team" : "Команда", 208 "settings.service.form.team" : "Команда",
diff --git a/src/i18n/locales/zh-TW.json b/src/i18n/locales/zh-TW.json
index 23bff247d..cfb1d3dce 100644
--- a/src/i18n/locales/zh-TW.json
+++ b/src/i18n/locales/zh-TW.json
@@ -1,11 +1,13 @@
1{ 1{
2 "app.errorHandler.action" : "重新載入",
3 "app.errorHandler.headline" : "有些東西出錯了",
2 "feature.delayApp.action" : "Get a Franz Supporter License", 4 "feature.delayApp.action" : "Get a Franz Supporter License",
3 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting", 5 "feature.delayApp.headline" : "Please purchase a Franz Supporter License to skip waiting",
4 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.", 6 "feature.delayApp.text" : "Franz will continue in {seconds} seconds.",
5 "global.api.unhealthy" : "無法連線至Franz的伺服器。", 7 "global.api.unhealthy" : "無法連線至Franz的伺服器。",
6 "global.notConnectedToTheInternet" : "你沒有連上網路。", 8 "global.notConnectedToTheInternet" : "你沒有連上網路。",
7 "import.headline" : "匯入Franz 4的服務", 9 "import.headline" : "匯入 Franz 4 的服務",
8 "import.notSupportedHeadline" : "Franz 5尚未支援此服務", 10 "import.notSupportedHeadline" : "Franz 5 尚未支援此服務",
9 "import.skip.label" : "手動添加服務", 11 "import.skip.label" : "手動添加服務",
10 "import.submit.label" : "匯入服務", 12 "import.submit.label" : "匯入服務",
11 "infobar.buttonChangelog" : "有什麼新功能呢?", 13 "infobar.buttonChangelog" : "有什麼新功能呢?",
@@ -79,7 +81,7 @@
79 "password.noUser" : "找不到該電子郵件地址的用戶", 81 "password.noUser" : "找不到該電子郵件地址的用戶",
80 "password.submit.label" : "送出", 82 "password.submit.label" : "送出",
81 "password.successInfo" : "請檢查您的電子郵件", 83 "password.successInfo" : "請檢查您的電子郵件",
82 "premiumFeature.button.upgradeAccount" : "Upgrade account", 84 "premiumFeature.button.upgradeAccount" : "升級帳號",
83 "pricing.headline" : "支持Franz", 85 "pricing.headline" : "支持Franz",
84 "pricing.link.skipPayment" : "我不想支持Franz的開發。", 86 "pricing.link.skipPayment" : "我不想支持Franz的開發。",
85 "pricing.submit.label" : "我想支持Franz的開發。", 87 "pricing.submit.label" : "我想支持Franz的開發。",
@@ -90,6 +92,11 @@
90 "service.crashHandler.text" : "{name}導致了一個錯誤。", 92 "service.crashHandler.text" : "{name}導致了一個錯誤。",
91 "service.disabledHandler.action" : "啟用{name}", 93 "service.disabledHandler.action" : "啟用{name}",
92 "service.disabledHandler.headline" : "{name}已停用", 94 "service.disabledHandler.headline" : "{name}已停用",
95 "service.errorHandler.action" : "重新載入{name}",
96 "service.errorHandler.editAction" : "編輯{名稱}",
97 "service.errorHandler.headline" : "噢不!",
98 "service.errorHandler.message" : "錯誤",
99 "service.errorHandler.text" : "{name} has failed to load.",
93 "services.getStarted" : "開始", 100 "services.getStarted" : "開始",
94 "services.welcome" : "歡迎使用Franz", 101 "services.welcome" : "歡迎使用Franz",
95 "settings.account.account.editButton" : "編輯帳號", 102 "settings.account.account.editButton" : "編輯帳號",
@@ -131,7 +138,7 @@
131 "settings.app.form.runInBackground" : "當關閉視窗時保持Franz在背景運作", 138 "settings.app.form.runInBackground" : "當關閉視窗時保持Franz在背景運作",
132 "settings.app.form.showDisabledServices" : "顯示停用的服務標籤", 139 "settings.app.form.showDisabledServices" : "顯示停用的服務標籤",
133 "settings.app.form.showMessagesBadgesWhenMuted" : "當通知關閉時,標記未讀的訊息", 140 "settings.app.form.showMessagesBadgesWhenMuted" : "當通知關閉時,標記未讀的訊息",
134 "settings.app.form.spellcheckerLanguage" : "Spell checking language", 141 "settings.app.form.spellcheckerLanguage" : "拼字檢查語言",
135 "settings.app.headline" : "設定", 142 "settings.app.headline" : "設定",
136 "settings.app.headlineAdvanced" : "進階", 143 "settings.app.headlineAdvanced" : "進階",
137 "settings.app.headlineAppearance" : "外觀", 144 "settings.app.headlineAppearance" : "外觀",
@@ -172,7 +179,7 @@
172 "settings.service.form.editServiceHeadline" : "編輯{名稱}", 179 "settings.service.form.editServiceHeadline" : "編輯{名稱}",
173 "settings.service.form.enableAudio" : "啟用音訊", 180 "settings.service.form.enableAudio" : "啟用音訊",
174 "settings.service.form.enableBadge" : "顯示未讀訊息圖示", 181 "settings.service.form.enableBadge" : "顯示未讀訊息圖示",
175 "settings.service.form.enableDarkMode" : "Enable Dark Mode", 182 "settings.service.form.enableDarkMode" : "開啟深色模式",
176 "settings.service.form.enableNotification" : "啟用通知", 183 "settings.service.form.enableNotification" : "啟用通知",
177 "settings.service.form.enableService" : "啟用服務", 184 "settings.service.form.enableService" : "啟用服務",
178 "settings.service.form.headlineBadges" : "未讀訊息圖示", 185 "settings.service.form.headlineBadges" : "未讀訊息圖示",
@@ -185,13 +192,17 @@
185 "settings.service.form.indirectMessages" : "顯示所有新消息的消息標誌", 192 "settings.service.form.indirectMessages" : "顯示所有新消息的消息標誌",
186 "settings.service.form.isMutedInfo" : "停用時,所有通知聲和聲音播放都將靜音", 193 "settings.service.form.isMutedInfo" : "停用時,所有通知聲和聲音播放都將靜音",
187 "settings.service.form.name" : "名稱", 194 "settings.service.form.name" : "名稱",
188 "settings.service.form.proxy.headline" : "Proxy Settings", 195 "settings.service.form.proxy.headline" : "HTTP\/HTTPS Proxy Settings",
189 "settings.service.form.proxy.host" : "Proxy Host\/IP", 196 "settings.service.form.proxy.host" : "Proxy Host\/IP",
190 "settings.service.form.proxy.info" : "Proxy settings will not synced with the Franz servers.", 197 "settings.service.form.proxy.info" : "Proxy 設定不會與 Franz 伺服器同步",
191 "settings.service.form.proxy.isEnabled" : "Use Proxy", 198 "settings.service.form.proxy.isEnabled" : "使用 Proxy",
192 "settings.service.form.proxy.password" : "Password (optional)", 199 "settings.service.form.proxy.password" : "密碼 (選填)",
193 "settings.service.form.proxy.user" : "User (optional)", 200 "settings.service.form.proxy.port" : "Port",
201 "settings.service.form.proxy.restartInfo" : "Please restart Franz after changing proxy Settings.",
202 "settings.service.form.proxy.user" : "使用者 (選填)",
194 "settings.service.form.saveButton" : "保存服務", 203 "settings.service.form.saveButton" : "保存服務",
204 "settings.service.form.spellcheckerLanguage" : "Spell checking Language",
205 "settings.service.form.spellcheckerLanguage.default" : "Use System Default ({default})",
195 "settings.service.form.tabHosted" : "託管", 206 "settings.service.form.tabHosted" : "託管",
196 "settings.service.form.tabOnPremise" : "自我託管⭐️", 207 "settings.service.form.tabOnPremise" : "自我託管⭐️",
197 "settings.service.form.team" : "團隊", 208 "settings.service.form.team" : "團隊",
@@ -238,7 +249,7 @@
238 "subscription.features.onpremise" : "添加本地\/託管服務如HipChat", 249 "subscription.features.onpremise" : "添加本地\/託管服務如HipChat",
239 "subscription.features.onpremise.mattermost" : "Add on-premise\/hosted services like Mattermost", 250 "subscription.features.onpremise.mattermost" : "Add on-premise\/hosted services like Mattermost",
240 "subscription.features.proxy" : "Proxy support for services", 251 "subscription.features.proxy" : "Proxy support for services",
241 "subscription.features.spellchecker" : "Support for spellchecker", 252 "subscription.features.spellchecker" : "支援拼字檢查",
242 "subscription.includedFeatures" : "包含高級Franz付費帳戶", 253 "subscription.includedFeatures" : "包含高級Franz付費帳戶",
243 "subscription.paymentSessionError" : "無法初始化付款表單", 254 "subscription.paymentSessionError" : "無法初始化付款表單",
244 "subscription.submit.label" : "我想支持Franz的開發", 255 "subscription.submit.label" : "我想支持Franz的開發",
diff --git a/src/index.js b/src/index.js
index 7f3fe5b44..830166dcf 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,10 +1,14 @@
1import { app, BrowserWindow, shell, ipcMain } from 'electron'; 1import {
2 app, BrowserWindow, shell, ipcMain,
3} from 'electron';
2 4
3import fs from 'fs-extra'; 5import fs from 'fs-extra';
4import path from 'path'; 6import path from 'path';
5import windowStateKeeper from 'electron-window-state'; 7import windowStateKeeper from 'electron-window-state';
6 8
7import { isDevMode, isMac, isWindows, isLinux } from './environment'; 9import {
10 isDevMode, isMac, isWindows, isLinux,
11} from './environment';
8 12
9// DEV MODE: Save user data into FranzDev 13// DEV MODE: Save user data into FranzDev
10if (isDevMode) { 14if (isDevMode) {
diff --git a/src/lib/Tray.js b/src/lib/Tray.js
index 588fa75bf..669b02709 100644
--- a/src/lib/Tray.js
+++ b/src/lib/Tray.js
@@ -1,4 +1,6 @@
1import { app, Tray, Menu, systemPreferences, nativeImage } from 'electron'; 1import {
2 app, Tray, Menu, systemPreferences, nativeImage,
3} from 'electron';
2import path from 'path'; 4import path from 'path';
3 5
4const FILE_EXTENSION = process.platform === 'win32' ? 'ico' : 'png'; 6const FILE_EXTENSION = process.platform === 'win32' ? 'ico' : 'png';
@@ -7,7 +9,9 @@ const INDICATOR_TRAY_UNREAD = 'tray-unread';
7 9
8export default class TrayIcon { 10export default class TrayIcon {
9 trayIcon = null; 11 trayIcon = null;
12
10 indicator = 0; 13 indicator = 0;
14
11 themeChangeSubscriberId = null; 15 themeChangeSubscriberId = null;
12 16
13 show() { 17 show() {
@@ -79,7 +83,7 @@ export default class TrayIcon {
79 } 83 }
80 84
81 return nativeImage.createFromPath(path.join( 85 return nativeImage.createFromPath(path.join(
82 __dirname, '..', 'assets', 'images', type, platform, `${asset}.${FILE_EXTENSION}`), 86 __dirname, '..', 'assets', 'images', type, platform, `${asset}.${FILE_EXTENSION}`,
83 ); 87 ));
84 } 88 }
85} 89}
diff --git a/src/models/News.js b/src/models/News.js
index caf1d70e5..acacb97dd 100644
--- a/src/models/News.js
+++ b/src/models/News.js
@@ -2,8 +2,11 @@
2 2
3export default class News { 3export default class News {
4 id = ''; 4 id = '';
5
5 message = ''; 6 message = '';
7
6 type = 'primary'; 8 type = 'primary';
9
7 sticky = false; 10 sticky = false;
8 11
9 constructor(data) { 12 constructor(data) {
diff --git a/src/models/Order.js b/src/models/Order.js
index 0e10b01d6..f7624c627 100644
--- a/src/models/Order.js
+++ b/src/models/Order.js
@@ -1,9 +1,14 @@
1export default class Order { 1export default class Order {
2 id = ''; 2 id = '';
3
3 subscriptionId = ''; 4 subscriptionId = '';
5
4 name = ''; 6 name = '';
7
5 invoiceUrl = ''; 8 invoiceUrl = '';
9
6 price = ''; 10 price = '';
11
7 date = ''; 12 date = '';
8 13
9 constructor(data) { 14 constructor(data) {
diff --git a/src/models/Plan.js b/src/models/Plan.js
index c7b4a0962..3dedf0d5e 100644
--- a/src/models/Plan.js
+++ b/src/models/Plan.js
@@ -5,6 +5,7 @@ export default class Plan {
5 id: '', 5 id: '',
6 price: 0, 6 price: 0,
7 } 7 }
8
8 year = { 9 year = {
9 id: '', 10 id: '',
10 price: 0, 11 price: 0,
diff --git a/src/models/Recipe.js b/src/models/Recipe.js
index 43c44514c..b0d60e75e 100644
--- a/src/models/Recipe.js
+++ b/src/models/Recipe.js
@@ -5,21 +5,33 @@ import path from 'path';
5 5
6export default class Recipe { 6export default class Recipe {
7 id = ''; 7 id = '';
8
8 name = ''; 9 name = '';
10
9 description = ''; 11 description = '';
12
10 version = ''; 13 version = '';
14
11 path = ''; 15 path = '';
12 16
13 serviceURL = ''; 17 serviceURL = '';
14 18
15 hasDirectMessages = true; 19 hasDirectMessages = true;
20
16 hasIndirectMessages = false; 21 hasIndirectMessages = false;
22
17 hasNotificationSound = false; 23 hasNotificationSound = false;
24
18 hasTeamId = false; 25 hasTeamId = false;
26
19 hasPredefinedUrl = false; 27 hasPredefinedUrl = false;
28
20 hasCustomUrl = false; 29 hasCustomUrl = false;
30
21 hasHostedOption = false; 31 hasHostedOption = false;
32
22 urlInputPrefix = ''; 33 urlInputPrefix = '';
34
23 urlInputSuffix = ''; 35 urlInputSuffix = '';
24 36
25 message = ''; 37 message = '';
diff --git a/src/models/RecipePreview.js b/src/models/RecipePreview.js
index 7470d757a..cfb22f860 100644
--- a/src/models/RecipePreview.js
+++ b/src/models/RecipePreview.js
@@ -2,8 +2,12 @@
2 2
3export default class RecipePreview { 3export default class RecipePreview {
4 id = ''; 4 id = '';
5
5 name = ''; 6 name = '';
6 icon = ''; // TODO: check if this isn't replaced by `icons` 7
8 icon = '';
9
10 // TODO: check if this isn't replaced by `icons`
7 featured = false; 11 featured = false;
8 12
9 constructor(data) { 13 constructor(data) {
diff --git a/src/models/Service.js b/src/models/Service.js
index 41180dd76..4cc6102ff 100644
--- a/src/models/Service.js
+++ b/src/models/Service.js
@@ -2,11 +2,17 @@ import { computed, observable, autorun } from 'mobx';
2import path from 'path'; 2import path from 'path';
3import normalizeUrl from 'normalize-url'; 3import normalizeUrl from 'normalize-url';
4 4
5const debug = require('debug')('Franz:Service');
6
5export default class Service { 7export default class Service {
6 id = ''; 8 id = '';
9
7 recipe = ''; 10 recipe = '';
11
8 webview = null; 12 webview = null;
13
9 timer = null; 14 timer = null;
15
10 events = {}; 16 events = {};
11 17
12 isAttached = false; 18 isAttached = false;
@@ -14,22 +20,45 @@ export default class Service {
14 @observable isActive = false; // Is current webview active 20 @observable isActive = false; // Is current webview active
15 21
16 @observable name = ''; 22 @observable name = '';
23
17 @observable unreadDirectMessageCount = 0; 24 @observable unreadDirectMessageCount = 0;
25
18 @observable unreadIndirectMessageCount = 0; 26 @observable unreadIndirectMessageCount = 0;
19 27
20 @observable order = 99; 28 @observable order = 99;
29
21 @observable isEnabled = true; 30 @observable isEnabled = true;
31
22 @observable isMuted = false; 32 @observable isMuted = false;
33
23 @observable team = ''; 34 @observable team = '';
35
24 @observable customUrl = ''; 36 @observable customUrl = '';
37
25 @observable isNotificationEnabled = true; 38 @observable isNotificationEnabled = true;
39
26 @observable isBadgeEnabled = true; 40 @observable isBadgeEnabled = true;
41
27 @observable isIndirectMessageBadgeEnabled = true; 42 @observable isIndirectMessageBadgeEnabled = true;
43
28 @observable iconUrl = ''; 44 @observable iconUrl = '';
45
29 @observable hasCustomUploadedIcon = false; 46 @observable hasCustomUploadedIcon = false;
47
30 @observable hasCrashed = false; 48 @observable hasCrashed = false;
49
31 @observable isDarkModeEnabled = false; 50 @observable isDarkModeEnabled = false;
32 51
52 @observable spellcheckerLanguage = null;
53
54 @observable isFirstLoad = true;
55
56 @observable isLoading = true;
57
58 @observable isError = false;
59
60 @observable errorMessage = '';
61
33 constructor(data, recipe) { 62 constructor(data, recipe) {
34 if (!data) { 63 if (!data) {
35 console.error('Service config not valid'); 64 console.error('Service config not valid');
@@ -71,6 +100,8 @@ export default class Service {
71 100
72 this.proxy = data.proxy !== undefined ? data.proxy : this.proxy; 101 this.proxy = data.proxy !== undefined ? data.proxy : this.proxy;
73 102
103 this.spellcheckerLanguage = data.spellcheckerLanguage !== undefined ? data.spellcheckerLanguage : this.spellcheckerLanguage;
104
74 this.recipe = recipe; 105 this.recipe = recipe;
75 106
76 autorun(() => { 107 autorun(() => {
@@ -147,9 +178,29 @@ export default class Service {
147 178
148 this.webview.addEventListener('did-start-loading', () => { 179 this.webview.addEventListener('did-start-loading', () => {
149 this.hasCrashed = false; 180 this.hasCrashed = false;
181 this.isLoading = true;
182 this.isError = false;
183 });
184
185 this.webview.addEventListener('did-frame-finish-load', () => {
186 this.isLoading = false;
187
188 if (!this.isError) {
189 this.isFirstLoad = false;
190 }
191 });
192
193 this.webview.addEventListener('did-fail-load', (event) => {
194 debug('Service failed to load', this.name, event);
195 if (event.isMainFrame) {
196 this.isError = true;
197 this.errorMessage = event.errorDescription;
198 this.isLoading = false;
199 }
150 }); 200 });
151 201
152 this.webview.addEventListener('crashed', () => { 202 this.webview.addEventListener('crashed', () => {
203 debug('Service crashed', this.name);
153 this.hasCrashed = true; 204 this.hasCrashed = true;
154 }); 205 });
155 } 206 }
diff --git a/src/models/User.js b/src/models/User.js
index 3e4aa187d..bec78fc16 100644
--- a/src/models/User.js
+++ b/src/models/User.js
@@ -2,19 +2,34 @@ import { observable } from 'mobx';
2 2
3export default class User { 3export default class User {
4 id = null; 4 id = null;
5
5 @observable email = null; 6 @observable email = null;
7
6 @observable firstname = null; 8 @observable firstname = null;
9
7 @observable lastname = null; 10 @observable lastname = null;
11
8 @observable organization = null; 12 @observable organization = null;
13
9 @observable accountType = null; 14 @observable accountType = null;
10 @observable emailIsConfirmed = true; // better assume it's confirmed to avoid noise 15
16 @observable emailIsConfirmed = true;
17
18 // better assume it's confirmed to avoid noise
11 @observable subscription = {}; 19 @observable subscription = {};
20
12 @observable isSubscriptionOwner = false; 21 @observable isSubscriptionOwner = false;
22
13 @observable isPremium = false; 23 @observable isPremium = false;
24
14 @observable beta = false; 25 @observable beta = false;
26
15 @observable donor = {}; 27 @observable donor = {};
28
16 @observable isDonor = false; 29 @observable isDonor = false;
30
17 @observable isMiner = false; 31 @observable isMiner = false;
32
18 @observable locale = false; 33 @observable locale = false;
19 34
20 constructor(data) { 35 constructor(data) {
diff --git a/src/stores/AppStore.js b/src/stores/AppStore.js
index 6f156a96d..dd4642d70 100644
--- a/src/stores/AppStore.js
+++ b/src/stores/AppStore.js
@@ -38,12 +38,15 @@ export default class AppStore extends Store {
38 }; 38 };
39 39
40 @observable healthCheckRequest = new Request(this.api.app, 'health'); 40 @observable healthCheckRequest = new Request(this.api.app, 'health');
41
41 @observable getAppCacheSizeRequest = new Request(this.api.local, 'getAppCacheSize'); 42 @observable getAppCacheSizeRequest = new Request(this.api.local, 'getAppCacheSize');
43
42 @observable clearAppCacheRequest = new Request(this.api.local, 'clearAppCache'); 44 @observable clearAppCacheRequest = new Request(this.api.local, 'clearAppCache');
43 45
44 @observable autoLaunchOnStart = true; 46 @observable autoLaunchOnStart = true;
45 47
46 @observable isOnline = navigator.onLine; 48 @observable isOnline = navigator.onLine;
49
47 @observable timeOfflineStart; 50 @observable timeOfflineStart;
48 51
49 @observable updateStatus = null; 52 @observable updateStatus = null;
@@ -150,19 +153,22 @@ export default class AppStore extends Store {
150 key( 153 key(
151 '⌘+pagedown, ctrl+pagedown, ⌘+alt+right, ctrl+tab', () => { 154 '⌘+pagedown, ctrl+pagedown, ⌘+alt+right, ctrl+tab', () => {
152 this.actions.service.setActiveNext(); 155 this.actions.service.setActiveNext();
153 }); 156 },
157 );
154 158
155 // Set active the prev service 159 // Set active the prev service
156 key( 160 key(
157 '⌘+pageup, ctrl+pageup, ⌘+alt+left, ctrl+shift+tab', () => { 161 '⌘+pageup, ctrl+pageup, ⌘+alt+left, ctrl+shift+tab', () => {
158 this.actions.service.setActivePrev(); 162 this.actions.service.setActivePrev();
159 }); 163 },
164 );
160 165
161 // Global Mute 166 // Global Mute
162 key( 167 key(
163 '⌘+shift+m ctrl+shift+m', () => { 168 '⌘+shift+m ctrl+shift+m', () => {
164 this.actions.app.toggleMuteApp(); 169 this.actions.app.toggleMuteApp();
165 }); 170 },
171 );
166 172
167 this.locale = this._getDefaultLocale(); 173 this.locale = this._getDefaultLocale();
168 174
@@ -182,7 +188,9 @@ export default class AppStore extends Store {
182 } 188 }
183 189
184 // Actions 190 // Actions
185 @action _notify({ title, options, notificationId, serviceId = null }) { 191 @action _notify({
192 title, options, notificationId, serviceId = null,
193 }) {
186 if (this.stores.settings.all.app.isAppMuted) return; 194 if (this.stores.settings.all.app.isAppMuted) return;
187 195
188 const notification = new window.Notification(title, options); 196 const notification = new window.Notification(title, options);
diff --git a/src/stores/DictionaryStore.js b/src/stores/DictionaryStore.js
deleted file mode 100644
index b9c5f2abf..000000000
--- a/src/stores/DictionaryStore.js
+++ /dev/null
@@ -1,45 +0,0 @@
1import { observable } from 'mobx';
2import { createDownloader } from 'hunspell-dict-downloader';
3
4import Store from './lib/Store';
5
6import { DICTIONARY_PATH } from '../config';
7
8const debug = require('debug')('Franz:DictionaryStore');
9
10export default class DictionaryStore extends Store {
11 @observable available = []
12 @observable installed = []
13
14 _dictDownloader = null
15
16 constructor(...args) {
17 super(...args);
18
19 this.registerReactions([
20 this._downloadDictForUserLocale.bind(this),
21 ]);
22 }
23
24 async setup() {
25 this._dictDownloader = await createDownloader(DICTIONARY_PATH);
26 debug('dicts', this._dictDownloader);
27
28 this.available = this._dictDownloader.availableDictionaries;
29 this.installed = this._dictDownloader.installedDictionaries;
30
31 if (!this.installed.includes('en-us')) {
32 this._dictDownloader.installDictionary('en-us');
33 }
34 }
35
36 _downloadDictForUserLocale() {
37 const spellcheckerLanguage = this.stores.settings.app.spellcheckerLanguage;
38
39 debug('trying to Downloading dict for', spellcheckerLanguage);
40 if (!this.installed.includes(spellcheckerLanguage) && this.available.includes(spellcheckerLanguage) && spellcheckerLanguage !== 'en-us') {
41 debug('Downloading dict for', spellcheckerLanguage);
42 this._dictDownloader.installDictionary(spellcheckerLanguage);
43 }
44 }
45}
diff --git a/src/stores/FeaturesStore.js b/src/stores/FeaturesStore.js
index 10c893d3f..2a0713b6f 100644
--- a/src/stores/FeaturesStore.js
+++ b/src/stores/FeaturesStore.js
@@ -11,6 +11,7 @@ import { DEFAULT_FEATURES_CONFIG } from '../config';
11 11
12export default class FeaturesStore extends Store { 12export default class FeaturesStore extends Store {
13 @observable defaultFeaturesRequest = new CachedRequest(this.api.features, 'default'); 13 @observable defaultFeaturesRequest = new CachedRequest(this.api.features, 'default');
14
14 @observable featuresRequest = new CachedRequest(this.api.features, 'features'); 15 @observable featuresRequest = new CachedRequest(this.api.features, 'features');
15 16
16 async setup() { 17 async setup() {
diff --git a/src/stores/GlobalErrorStore.js b/src/stores/GlobalErrorStore.js
index f4b9d7838..90bf751c3 100644
--- a/src/stores/GlobalErrorStore.js
+++ b/src/stores/GlobalErrorStore.js
@@ -4,6 +4,7 @@ import Request from './lib/Request';
4 4
5export default class GlobalErrorStore extends Store { 5export default class GlobalErrorStore extends Store {
6 @observable error = null; 6 @observable error = null;
7
7 @observable response = {}; 8 @observable response = {};
8 9
9 constructor(...args) { 10 constructor(...args) {
diff --git a/src/stores/NewsStore.js b/src/stores/NewsStore.js
index e5091834f..6984425df 100644
--- a/src/stores/NewsStore.js
+++ b/src/stores/NewsStore.js
@@ -8,6 +8,7 @@ import { CHECK_INTERVAL } from '../config';
8 8
9export default class NewsStore extends Store { 9export default class NewsStore extends Store {
10 @observable latestNewsRequest = new CachedRequest(this.api.news, 'latest'); 10 @observable latestNewsRequest = new CachedRequest(this.api.news, 'latest');
11
11 @observable hideNewsRequest = new Request(this.api.news, 'hide'); 12 @observable hideNewsRequest = new Request(this.api.news, 'hide');
12 13
13 constructor(...args) { 14 constructor(...args) {
diff --git a/src/stores/PaymentStore.js b/src/stores/PaymentStore.js
index 9e348d14e..4cabee194 100644
--- a/src/stores/PaymentStore.js
+++ b/src/stores/PaymentStore.js
@@ -7,8 +7,11 @@ import { gaEvent } from '../lib/analytics';
7 7
8export default class PaymentStore extends Store { 8export default class PaymentStore extends Store {
9 @observable plansRequest = new CachedRequest(this.api.payment, 'plans'); 9 @observable plansRequest = new CachedRequest(this.api.payment, 'plans');
10
10 @observable createHostedPageRequest = new Request(this.api.payment, 'getHostedPage'); 11 @observable createHostedPageRequest = new Request(this.api.payment, 'getHostedPage');
12
11 @observable createDashboardUrlRequest = new Request(this.api.payment, 'getDashboardUrl'); 13 @observable createDashboardUrlRequest = new Request(this.api.payment, 'getDashboardUrl');
14
12 @observable ordersDataRequest = new CachedRequest(this.api.payment, 'getOrders'); 15 @observable ordersDataRequest = new CachedRequest(this.api.payment, 'getOrders');
13 16
14 constructor(...args) { 17 constructor(...args) {
diff --git a/src/stores/RecipePreviewsStore.js b/src/stores/RecipePreviewsStore.js
index e25936f15..10b2928e3 100644
--- a/src/stores/RecipePreviewsStore.js
+++ b/src/stores/RecipePreviewsStore.js
@@ -8,7 +8,9 @@ import { gaEvent } from '../lib/analytics';
8 8
9export default class RecipePreviewsStore extends Store { 9export default class RecipePreviewsStore extends Store {
10 @observable allRecipePreviewsRequest = new CachedRequest(this.api.recipePreviews, 'all'); 10 @observable allRecipePreviewsRequest = new CachedRequest(this.api.recipePreviews, 'all');
11
11 @observable featuredRecipePreviewsRequest = new CachedRequest(this.api.recipePreviews, 'featured'); 12 @observable featuredRecipePreviewsRequest = new CachedRequest(this.api.recipePreviews, 'featured');
13
12 @observable searchRecipePreviewsRequest = new Request(this.api.recipePreviews, 'search'); 14 @observable searchRecipePreviewsRequest = new Request(this.api.recipePreviews, 'search');
13 15
14 constructor(...args) { 16 constructor(...args) {
diff --git a/src/stores/RecipesStore.js b/src/stores/RecipesStore.js
index f2480bc8e..ab64bf79c 100644
--- a/src/stores/RecipesStore.js
+++ b/src/stores/RecipesStore.js
@@ -9,7 +9,9 @@ const debug = require('debug')('Franz:RecipeStore');
9 9
10export default class RecipesStore extends Store { 10export default class RecipesStore extends Store {
11 @observable allRecipesRequest = new CachedRequest(this.api.recipes, 'all'); 11 @observable allRecipesRequest = new CachedRequest(this.api.recipes, 'all');
12
12 @observable installRecipeRequest = new Request(this.api.recipes, 'install'); 13 @observable installRecipeRequest = new Request(this.api.recipes, 'install');
14
13 @observable getRecipeUpdatesRequest = new Request(this.api.recipes, 'update'); 15 @observable getRecipeUpdatesRequest = new Request(this.api.recipes, 'update');
14 16
15 constructor(...args) { 17 constructor(...args) {
diff --git a/src/stores/RequestStore.js b/src/stores/RequestStore.js
index bbfe6f6df..2629e0a38 100644
--- a/src/stores/RequestStore.js
+++ b/src/stores/RequestStore.js
@@ -6,10 +6,13 @@ const debug = require('debug')('Franz:RequestsStore');
6 6
7export default class RequestStore extends Store { 7export default class RequestStore extends Store {
8 @observable userInfoRequest; 8 @observable userInfoRequest;
9
9 @observable servicesRequest; 10 @observable servicesRequest;
11
10 @observable showRequiredRequestsError = false; 12 @observable showRequiredRequestsError = false;
11 13
12 retries = 0; 14 retries = 0;
15
13 retryDelay = 2000; 16 retryDelay = 2000;
14 17
15 constructor(...args) { 18 constructor(...args) {
diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js
index 99b091589..5b70ca271 100644
--- a/src/stores/ServicesStore.js
+++ b/src/stores/ServicesStore.js
@@ -1,4 +1,6 @@
1import { action, reaction, computed, observable } from 'mobx'; 1import {
2 action, reaction, computed, observable,
3} from 'mobx';
2import { debounce, remove } from 'lodash'; 4import { debounce, remove } from 'lodash';
3 5
4import Store from './lib/Store'; 6import Store from './lib/Store';
@@ -11,10 +13,15 @@ const debug = require('debug')('Franz:ServiceStore');
11 13
12export default class ServicesStore extends Store { 14export default class ServicesStore extends Store {
13 @observable allServicesRequest = new CachedRequest(this.api.services, 'all'); 15 @observable allServicesRequest = new CachedRequest(this.api.services, 'all');
16
14 @observable createServiceRequest = new Request(this.api.services, 'create'); 17 @observable createServiceRequest = new Request(this.api.services, 'create');
18
15 @observable updateServiceRequest = new Request(this.api.services, 'update'); 19 @observable updateServiceRequest = new Request(this.api.services, 'update');
20
16 @observable reorderServicesRequest = new Request(this.api.services, 'reorder'); 21 @observable reorderServicesRequest = new Request(this.api.services, 'reorder');
22
17 @observable deleteServiceRequest = new Request(this.api.services, 'delete'); 23 @observable deleteServiceRequest = new Request(this.api.services, 'delete');
24
18 @observable clearCacheRequest = new Request(this.api.services, 'clearCache'); 25 @observable clearCacheRequest = new Request(this.api.services, 'clearCache');
19 26
20 @observable filterNeedle = null; 27 @observable filterNeedle = null;
@@ -400,6 +407,18 @@ export default class ServicesStore extends Store {
400 const url = args[0]; 407 const url = args[0];
401 408
402 this.actions.app.openExternalUrl({ url }); 409 this.actions.app.openExternalUrl({ url });
410 } else if (channel === 'set-service-spellchecker-language') {
411 if (!args) {
412 console.warn('Did not receive locale');
413 } else {
414 this.actions.service.updateService({
415 serviceId,
416 serviceData: {
417 spellcheckerLanguage: args[0] === 'reset' ? '' : args[0],
418 },
419 redirect: false,
420 });
421 }
403 } 422 }
404 } 423 }
405 424
@@ -625,7 +644,7 @@ export default class ServicesStore extends Store {
625 const service = this.one(serviceId); 644 const service = this.one(serviceId);
626 645
627 if (service.webview) { 646 if (service.webview) {
628 service.webview.send('initializeRecipe', service); 647 service.webview.send('initialize-recipe', service);
629 } 648 }
630 } 649 }
631 650
diff --git a/src/stores/SettingsStore.js b/src/stores/SettingsStore.js
index 4c01e9910..a456195bf 100644
--- a/src/stores/SettingsStore.js
+++ b/src/stores/SettingsStore.js
@@ -1,5 +1,7 @@
1import { ipcRenderer } from 'electron'; 1import { ipcRenderer } from 'electron';
2import { action, computed, observable } from 'mobx'; 2import {
3 action, computed, observable, set,
4} from 'mobx';
3import localStorage from 'mobx-localstorage'; 5import localStorage from 'mobx-localstorage';
4 6
5import Store from './lib/Store'; 7import Store from './lib/Store';
@@ -14,11 +16,13 @@ const debug = require('debug')('Franz:SettingsStore');
14 16
15export default class SettingsStore extends Store { 17export default class SettingsStore extends Store {
16 @observable appSettingsRequest = new CachedRequest(this.api.local, 'getAppSettings'); 18 @observable appSettingsRequest = new CachedRequest(this.api.local, 'getAppSettings');
19
17 @observable updateAppSettingsRequest = new Request(this.api.local, 'updateAppSettings'); 20 @observable updateAppSettingsRequest = new Request(this.api.local, 'updateAppSettings');
18 21
19 @observable fileSystemSettingsRequests = []; 22 fileSystemSettingsRequests = [];
20 23
21 fileSystemSettingsTypes = FILE_SYSTEM_SETTINGS_TYPES; 24 fileSystemSettingsTypes = FILE_SYSTEM_SETTINGS_TYPES;
25
22 @observable _fileSystemSettingsCache = { 26 @observable _fileSystemSettingsCache = {
23 app: DEFAULT_APP_SETTINGS, 27 app: DEFAULT_APP_SETTINGS,
24 proxy: {}, 28 proxy: {},
@@ -57,6 +61,21 @@ export default class SettingsStore extends Store {
57 } 61 }
58 62
59 @computed get proxy() { 63 @computed get proxy() {
64 // // We need to provide the final data structure as mobx autoruns won't work
65 // const proxySettings = observable({});
66 // this.stores.services.all.forEach((service) => {
67 // proxySettings[service.id] = {
68 // isEnabled: false,
69 // host: null,
70 // user: null,
71 // password: null,
72 // };
73 // });
74
75 // debug('this._fileSystemSettingsCache.proxy', this._fileSystemSettingsCache.proxy, proxySettings);
76
77 // return Object.assign(proxySettings, this._fileSystemSettingsCache.proxy);
78
60 return this._fileSystemSettingsCache.proxy || {}; 79 return this._fileSystemSettingsCache.proxy || {};
61 } 80 }
62 81
@@ -98,7 +117,7 @@ export default class SettingsStore extends Store {
98 data, 117 data,
99 }); 118 });
100 119
101 Object.assign(this._fileSystemSettingsCache[type], data); 120 set(this._fileSystemSettingsCache[type], data);
102 } 121 }
103 } 122 }
104 123
diff --git a/src/stores/UserStore.js b/src/stores/UserStore.js
index 26ac2c60e..7addb5760 100644
--- a/src/stores/UserStore.js
+++ b/src/stores/UserStore.js
@@ -14,29 +14,47 @@ const debug = require('debug')('Franz:UserStore');
14// TODO: split stores into UserStore and AuthStore 14// TODO: split stores into UserStore and AuthStore
15export default class UserStore extends Store { 15export default class UserStore extends Store {
16 BASE_ROUTE = '/auth'; 16 BASE_ROUTE = '/auth';
17
17 WELCOME_ROUTE = `${this.BASE_ROUTE}/welcome`; 18 WELCOME_ROUTE = `${this.BASE_ROUTE}/welcome`;
19
18 LOGIN_ROUTE = `${this.BASE_ROUTE}/login`; 20 LOGIN_ROUTE = `${this.BASE_ROUTE}/login`;
21
19 LOGOUT_ROUTE = `${this.BASE_ROUTE}/logout`; 22 LOGOUT_ROUTE = `${this.BASE_ROUTE}/logout`;
23
20 SIGNUP_ROUTE = `${this.BASE_ROUTE}/signup`; 24 SIGNUP_ROUTE = `${this.BASE_ROUTE}/signup`;
25
21 PRICING_ROUTE = `${this.BASE_ROUTE}/signup/pricing`; 26 PRICING_ROUTE = `${this.BASE_ROUTE}/signup/pricing`;
27
22 IMPORT_ROUTE = `${this.BASE_ROUTE}/signup/import`; 28 IMPORT_ROUTE = `${this.BASE_ROUTE}/signup/import`;
29
23 INVITE_ROUTE = `${this.BASE_ROUTE}/signup/invite`; 30 INVITE_ROUTE = `${this.BASE_ROUTE}/signup/invite`;
31
24 PASSWORD_ROUTE = `${this.BASE_ROUTE}/password`; 32 PASSWORD_ROUTE = `${this.BASE_ROUTE}/password`;
25 33
26 @observable loginRequest = new Request(this.api.user, 'login'); 34 @observable loginRequest = new Request(this.api.user, 'login');
35
27 @observable signupRequest = new Request(this.api.user, 'signup'); 36 @observable signupRequest = new Request(this.api.user, 'signup');
37
28 @observable passwordRequest = new Request(this.api.user, 'password'); 38 @observable passwordRequest = new Request(this.api.user, 'password');
39
29 @observable inviteRequest = new Request(this.api.user, 'invite'); 40 @observable inviteRequest = new Request(this.api.user, 'invite');
41
30 @observable getUserInfoRequest = new CachedRequest(this.api.user, 'getInfo'); 42 @observable getUserInfoRequest = new CachedRequest(this.api.user, 'getInfo');
43
31 @observable updateUserInfoRequest = new Request(this.api.user, 'updateInfo'); 44 @observable updateUserInfoRequest = new Request(this.api.user, 'updateInfo');
45
32 @observable getLegacyServicesRequest = new CachedRequest(this.api.user, 'getLegacyServices'); 46 @observable getLegacyServicesRequest = new CachedRequest(this.api.user, 'getLegacyServices');
47
33 @observable deleteAccountRequest = new CachedRequest(this.api.user, 'delete'); 48 @observable deleteAccountRequest = new CachedRequest(this.api.user, 'delete');
34 49
35 @observable isImportLegacyServicesExecuting = false; 50 @observable isImportLegacyServicesExecuting = false;
51
36 @observable isImportLegacyServicesCompleted = false; 52 @observable isImportLegacyServicesCompleted = false;
37 53
38 @observable id; 54 @observable id;
55
39 @observable authToken = localStorage.getItem('authToken') || null; 56 @observable authToken = localStorage.getItem('authToken') || null;
57
40 @observable accountType; 58 @observable accountType;
41 59
42 @observable hasCompletedSignup = null; 60 @observable hasCompletedSignup = null;
@@ -48,6 +66,7 @@ export default class UserStore extends Store {
48 logoutReasonTypes = { 66 logoutReasonTypes = {
49 SERVER: 'SERVER', 67 SERVER: 'SERVER',
50 }; 68 };
69
51 @observable logoutReason = null; 70 @observable logoutReason = null;
52 71
53 constructor(...args) { 72 constructor(...args) {
@@ -141,7 +160,9 @@ export default class UserStore extends Store {
141 gaEvent('User', 'login'); 160 gaEvent('User', 'login');
142 } 161 }
143 162
144 @action async _signup({ firstname, lastname, email, password, accountType, company }) { 163 @action async _signup({
164 firstname, lastname, email, password, accountType, company,
165 }) {
145 const authToken = await this.signupRequest.execute({ 166 const authToken = await this.signupRequest.execute({
146 firstname, 167 firstname,
147 lastname, 168 lastname,
@@ -198,10 +219,11 @@ export default class UserStore extends Store {
198 } 219 }
199 220
200 @action _logout() { 221 @action _logout() {
222 // workaround mobx issue
201 localStorage.removeItem('authToken'); 223 localStorage.removeItem('authToken');
224 window.localStorage.removeItem('authToken');
202 this.getUserInfoRequest.invalidate().reset(); 225 this.getUserInfoRequest.invalidate().reset();
203 this.authToken = null; 226 this.authToken = null;
204 // this.data = {};
205 } 227 }
206 228
207 @action async _importLegacyServices({ services }) { 229 @action async _importLegacyServices({ services }) {
diff --git a/src/stores/index.js b/src/stores/index.js
index f547d0a7a..96b844c95 100644
--- a/src/stores/index.js
+++ b/src/stores/index.js
@@ -9,7 +9,6 @@ import UIStore from './UIStore';
9import PaymentStore from './PaymentStore'; 9import PaymentStore from './PaymentStore';
10import NewsStore from './NewsStore'; 10import NewsStore from './NewsStore';
11import RequestStore from './RequestStore'; 11import RequestStore from './RequestStore';
12import DictionaryStore from './DictionaryStore';
13import GlobalErrorStore from './GlobalErrorStore'; 12import GlobalErrorStore from './GlobalErrorStore';
14 13
15export default (api, actions, router) => { 14export default (api, actions, router) => {
@@ -27,7 +26,6 @@ export default (api, actions, router) => {
27 payment: new PaymentStore(stores, api, actions), 26 payment: new PaymentStore(stores, api, actions),
28 news: new NewsStore(stores, api, actions), 27 news: new NewsStore(stores, api, actions),
29 requests: new RequestStore(stores, api, actions), 28 requests: new RequestStore(stores, api, actions),
30 dictionary: new DictionaryStore(stores, api, actions),
31 globalError: new GlobalErrorStore(stores, api, actions), 29 globalError: new GlobalErrorStore(stores, api, actions),
32 }); 30 });
33 // Initialize all stores 31 // Initialize all stores
diff --git a/src/stores/lib/CachedRequest.js b/src/stores/lib/CachedRequest.js
index c0c3d40a1..ac8b2bd81 100644
--- a/src/stores/lib/CachedRequest.js
+++ b/src/stores/lib/CachedRequest.js
@@ -5,6 +5,7 @@ import Request from './Request';
5 5
6export default class CachedRequest extends Request { 6export default class CachedRequest extends Request {
7 _apiCalls = []; 7 _apiCalls = [];
8
8 _isInvalidated = true; 9 _isInvalidated = true;
9 10
10 execute(...callArgs) { 11 execute(...callArgs) {
diff --git a/src/stores/lib/Reaction.js b/src/stores/lib/Reaction.js
index e9bc26d81..46aa4dae6 100644
--- a/src/stores/lib/Reaction.js
+++ b/src/stores/lib/Reaction.js
@@ -3,7 +3,9 @@ import { autorun } from 'mobx';
3 3
4export default class Reaction { 4export default class Reaction {
5 reaction; 5 reaction;
6
6 hasBeenStarted; 7 hasBeenStarted;
8
7 dispose; 9 dispose;
8 10
9 constructor(reaction) { 11 constructor(reaction) {
diff --git a/src/stores/lib/Request.js b/src/stores/lib/Request.js
index 4a6925cc5..04f528156 100644
--- a/src/stores/lib/Request.js
+++ b/src/stores/lib/Request.js
@@ -9,15 +9,23 @@ export default class Request {
9 } 9 }
10 10
11 @observable result = null; 11 @observable result = null;
12
12 @observable error = null; 13 @observable error = null;
14
13 @observable isExecuting = false; 15 @observable isExecuting = false;
16
14 @observable isError = false; 17 @observable isError = false;
18
15 @observable wasExecuted = false; 19 @observable wasExecuted = false;
16 20
17 _promise = Promise; 21 _promise = Promise;
22
18 _api = {}; 23 _api = {};
24
19 _method = ''; 25 _method = '';
26
20 _isWaitingForResponse = false; 27 _isWaitingForResponse = false;
28
21 _currentApiCall = null; 29 _currentApiCall = null;
22 30
23 constructor(api, method) { 31 constructor(api, method) {
diff --git a/src/stores/lib/Store.js b/src/stores/lib/Store.js
index 873da7b37..8d2fb4066 100644
--- a/src/stores/lib/Store.js
+++ b/src/stores/lib/Store.js
@@ -3,16 +3,20 @@ import Reaction from './Reaction';
3 3
4export default class Store { 4export default class Store {
5 stores = {}; 5 stores = {};
6
6 api = {}; 7 api = {};
8
7 actions = {}; 9 actions = {};
8 10
9 _reactions = []; 11 _reactions = [];
10 12
11 // status implementation 13 // status implementation
12 @observable _status = null; 14 @observable _status = null;
15
13 @computed get actionStatus() { 16 @computed get actionStatus() {
14 return this._status || []; 17 return this._status || [];
15 } 18 }
19
16 set actionStatus(status) { 20 set actionStatus(status) {
17 this._status = status; 21 this._status = status;
18 } 22 }
diff --git a/src/styles/auth.scss b/src/styles/auth.scss
index 54e264dc6..817801982 100644
--- a/src/styles/auth.scss
+++ b/src/styles/auth.scss
@@ -33,17 +33,9 @@
33 33
34 .auth__layout { 34 .auth__layout {
35 width: 100%; 35 width: 100%;
36 36 display: flex;
37 & > div { 37 align-items: center;
38 align-items: center; 38 justify-content: center;
39 display: flex;
40 justify-content: center;
41
42 & > span {
43 position: absolute;
44 width: 100%;
45 }
46 }
47 } 39 }
48 40
49 .auth__container { 41 .auth__container {
diff --git a/src/styles/content-tabs.scss b/src/styles/content-tabs.scss
index ca3820fb4..03befedcb 100644
--- a/src/styles/content-tabs.scss
+++ b/src/styles/content-tabs.scss
@@ -1,5 +1,21 @@
1@import './config.scss'; 1@import './config.scss';
2 2
3.theme__dark {
4 .content-tabs {
5 .content-tabs__content {
6 background: $dark-theme-gray-darker;
7 }
8
9 .content-tabs__tabs {
10 .content-tabs__item {
11 background: $dark-theme-gray;
12 color: #FFF;
13 border: 0;
14 }
15 }
16 }
17}
18
3.content-tabs { 19.content-tabs {
4 .content-tabs__tabs { 20 .content-tabs__tabs {
5 border-top-left-radius: $theme-border-radius-small; 21 border-top-left-radius: $theme-border-radius-small;
diff --git a/src/styles/searchInput.scss b/src/styles/searchInput.scss
index 32b9da065..91453c600 100644
--- a/src/styles/searchInput.scss
+++ b/src/styles/searchInput.scss
@@ -22,6 +22,10 @@
22 padding: 5px 10px; 22 padding: 5px 10px;
23 width: 100%; 23 width: 100%;
24 24
25 label {
26 width: 100%;
27 }
28
25 input { 29 input {
26 background: none; 30 background: none;
27 border: 0; 31 border: 0;
diff --git a/src/styles/select.scss b/src/styles/select.scss
index ed0fc0fc2..513975f9c 100644
--- a/src/styles/select.scss
+++ b/src/styles/select.scss
@@ -20,4 +20,8 @@ $toggle: "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj
20 min-width: 200px; 20 min-width: 200px;
21 padding: 10px; 21 padding: 10px;
22 -webkit-appearance: none; 22 -webkit-appearance: none;
23
24 &[disabled] {
25 opacity: 0.5;
26 }
23} 27}
diff --git a/src/styles/settings.scss b/src/styles/settings.scss
index f94ca114d..750b6bedd 100644
--- a/src/styles/settings.scss
+++ b/src/styles/settings.scss
@@ -216,6 +216,10 @@
216 letter-spacing: -0.1px; 216 letter-spacing: -0.1px;
217 } 217 }
218 } 218 }
219
220 .proxyHost {
221 flex-basis: 70%;
222 }
219 } 223 }
220 224
221 .settings__close { 225 .settings__close {
diff --git a/src/styles/welcome.scss b/src/styles/welcome.scss
index b3d6515b1..b517431f0 100644
--- a/src/styles/welcome.scss
+++ b/src/styles/welcome.scss
@@ -1,9 +1,12 @@
1.auth .welcome { 1.auth .welcome {
2 height: auto;
3
2 &__content { 4 &__content {
3 align-items: center; 5 align-items: center;
4 color: #FFF; 6 color: #FFF;
5 display: flex; 7 display: flex;
6 justify-content: center; 8 justify-content: center;
9 height: auto;
7 } 10 }
8 11
9 &__logo { width: 100px; } 12 &__logo { width: 100px; }
@@ -37,6 +40,7 @@
37 display: block; 40 display: block;
38 margin-top: 100px; 41 margin-top: 100px;
39 text-align: center; 42 text-align: center;
43 height: auto;
40 44
41 .button:first-of-type { margin-right: 25px; } 45 .button:first-of-type { margin-right: 25px; }
42 } 46 }
@@ -71,6 +75,7 @@
71 padding: 20px 20px 5px; 75 padding: 20px 20px 5px;
72 text-align: center; 76 text-align: center;
73 width: 480px; 77 width: 480px;
78 height: auto;
74 } 79 }
75 80
76 &__featured-service { 81 &__featured-service {
diff --git a/src/theme/dark/index.js b/src/theme/dark/index.js
index 496a51119..fb1713184 100644
--- a/src/theme/dark/index.js
+++ b/src/theme/dark/index.js
@@ -1,6 +1,13 @@
1import hexToRgba from 'hex-to-rgba';
2
1import * as legacyStyles from '../default/legacy'; 3import * as legacyStyles from '../default/legacy';
2 4
3export const colorBackground = legacyStyles.darkThemeGrayDarkest; 5export const colorBackground = legacyStyles.darkThemeGrayDarkest;
4export const colorBackgroundSubscriptionContainer = legacyStyles.themeBrandInfo; 6export const colorBackgroundSubscriptionContainer = legacyStyles.themeBrandInfo;
5 7
6export const colorHeadline = legacyStyles.darkThemeTextColor; 8export const colorHeadline = legacyStyles.darkThemeTextColor;
9export const colorText = legacyStyles.darkThemeTextColor;
10
11// Loader
12export const colorFullscreenLoaderSpinner = '#FFF';
13export const colorWebviewLoaderBackground = hexToRgba(legacyStyles.darkThemeGrayDarkest, 0.5);
diff --git a/src/theme/default/index.js b/src/theme/default/index.js
index 8766fb609..37827621c 100644
--- a/src/theme/default/index.js
+++ b/src/theme/default/index.js
@@ -1,3 +1,5 @@
1import hexToRgba from 'hex-to-rgba';
2
1import * as legacyStyles from './legacy'; 3import * as legacyStyles from './legacy';
2 4
3export const brandPrimary = '#3498db'; 5export const brandPrimary = '#3498db';
@@ -12,6 +14,8 @@ export const borderRadiusSmall = legacyStyles.themeBorderRadiusSmall;
12export const colorBackground = legacyStyles.themeGrayLighter; 14export const colorBackground = legacyStyles.themeGrayLighter;
13export const colorHeadline = legacyStyles.themeGrayDark; 15export const colorHeadline = legacyStyles.themeGrayDark;
14 16
17export const colorText = legacyStyles.themeTextColor;
18
15// Subscription Container Component 19// Subscription Container Component
16export const colorSubscriptionContainerBackground = 'none'; 20export const colorSubscriptionContainerBackground = 'none';
17export const colorSubscriptionContainerBorder = [1, 'solid', brandPrimary]; 21export const colorSubscriptionContainerBorder = [1, 'solid', brandPrimary];
@@ -19,3 +23,7 @@ export const colorSubscriptionContainerTitle = brandPrimary;
19export const colorSubscriptionContainerActionButtonBackground = brandPrimary; 23export const colorSubscriptionContainerActionButtonBackground = brandPrimary;
20export const colorSubscriptionContainerActionButtonColor = '#FFF'; 24export const colorSubscriptionContainerActionButtonColor = '#FFF';
21 25
26// Loader
27export const colorAppLoaderSpinner = '#FFF';
28export const colorFullscreenLoaderSpinner = legacyStyles.themeGrayDark;
29export const colorWebviewLoaderBackground = hexToRgba(legacyStyles.themeGrayLighter, 0.8);
diff --git a/src/webview/contextMenu.js b/src/webview/contextMenu.js
index ad156128c..bd099987d 100644
--- a/src/webview/contextMenu.js
+++ b/src/webview/contextMenu.js
@@ -1,9 +1,12 @@
1// This is heavily based on https://github.com/sindresorhus/electron-context-menu 1// This is heavily based on https://github.com/sindresorhus/electron-context-menu
2// ❤ @sindresorhus 2// ❤ @sindresorhus
3 3
4import { clipboard, remote, ipcRenderer, shell } from 'electron'; 4import {
5 clipboard, remote, ipcRenderer, shell,
6} from 'electron';
5 7
6import { isDevMode, isMac } from '../environment'; 8import { isDevMode, isMac } from '../environment';
9import { SPELLCHECKER_LOCALES } from '../i18n/languages';
7 10
8const debug = require('debug')('Franz:contextMenu'); 11const debug = require('debug')('Franz:contextMenu');
9 12
@@ -21,7 +24,7 @@ function delUnusedElements(menuTpl) {
21 }); 24 });
22} 25}
23 26
24const buildMenuTpl = (props, suggestions) => { 27const buildMenuTpl = (props, suggestions, isSpellcheckEnabled, defaultSpellcheckerLanguage, spellcheckerLanguage) => {
25 const { editFlags } = props; 28 const { editFlags } = props;
26 const textSelection = props.selectionText.trim(); 29 const textSelection = props.selectionText.trim();
27 const hasText = textSelection.length > 0; 30 const hasText = textSelection.length > 0;
@@ -190,6 +193,54 @@ const buildMenuTpl = (props, suggestions) => {
190 }); 193 });
191 } 194 }
192 195
196 const spellcheckingLanguages = [];
197 Object.keys(SPELLCHECKER_LOCALES).sort(Intl.Collator().compare).forEach((key) => {
198 spellcheckingLanguages.push({
199 id: `lang-${key}`,
200 label: SPELLCHECKER_LOCALES[key],
201 type: 'radio',
202 checked: spellcheckerLanguage === key,
203 click() {
204 debug('Setting service spellchecker to', key);
205 ipcRenderer.sendToHost('set-service-spellchecker-language', key);
206 },
207 });
208 });
209
210 console.log('isSpellcheckEnabled', isSpellcheckEnabled);
211
212 menuTpl.push({
213 type: 'separator',
214 }, {
215 id: 'spellchecker',
216 label: 'Spell Checking',
217 visible: isSpellcheckEnabled,
218 submenu: [
219 {
220 id: 'spellchecker',
221 label: 'Available Languages',
222 enabled: false,
223 }, {
224 type: 'separator',
225 },
226 {
227 id: 'resetToDefault',
228 label: `Reset to system default (${SPELLCHECKER_LOCALES[defaultSpellcheckerLanguage]})`,
229 type: 'radio',
230 visible: defaultSpellcheckerLanguage !== spellcheckerLanguage,
231 click() {
232 debug('Resetting service spellchecker to system default');
233 ipcRenderer.sendToHost('set-service-spellchecker-language', 'reset');
234 },
235 },
236 {
237 type: 'separator',
238 visible: defaultSpellcheckerLanguage !== spellcheckerLanguage,
239 },
240 ...spellcheckingLanguages],
241 });
242
243
193 if (isDevMode) { 244 if (isDevMode) {
194 menuTpl.push({ 245 menuTpl.push({
195 type: 'separator', 246 type: 'separator',
@@ -205,7 +256,7 @@ const buildMenuTpl = (props, suggestions) => {
205 return delUnusedElements(menuTpl); 256 return delUnusedElements(menuTpl);
206}; 257};
207 258
208export default function contextMenu(spellcheckProvider) { 259export default function contextMenu(spellcheckProvider, isSpellcheckEnabled, getDefaultSpellcheckerLanguage, getSpellcheckerLanguage) {
209 webContents.on('context-menu', (e, props) => { 260 webContents.on('context-menu', (e, props) => {
210 e.preventDefault(); 261 e.preventDefault();
211 262
@@ -216,7 +267,15 @@ export default function contextMenu(spellcheckProvider) {
216 debug('Suggestions', suggestions); 267 debug('Suggestions', suggestions);
217 } 268 }
218 269
219 const menu = Menu.buildFromTemplate(buildMenuTpl(props, suggestions.slice(0, 5))); 270 const menu = Menu.buildFromTemplate(
271 buildMenuTpl(
272 props,
273 suggestions.slice(0, 5),
274 isSpellcheckEnabled(),
275 getDefaultSpellcheckerLanguage(),
276 getSpellcheckerLanguage(),
277 ),
278 );
220 279
221 menu.popup(remote.getCurrentWindow()); 280 menu.popup(remote.getCurrentWindow());
222 }); 281 });
diff --git a/src/webview/darkmode.js b/src/webview/darkmode.js
index 9830ef33c..73c7007c6 100644
--- a/src/webview/darkmode.js
+++ b/src/webview/darkmode.js
@@ -1,7 +1,13 @@
1/* eslint no-bitwise: ["error", { "int32Hint": true }] */
2
1import path from 'path'; 3import path from 'path';
2import fs from 'fs-extra'; 4import fs from 'fs-extra';
3 5
4const ID = 'franz-theme-dark-mode'; 6const debug = require('debug')('Franz:DarkMode');
7
8const chars = [...'abcdefghijklmnopqrstuvwxyz'];
9
10const ID = [...Array(20)].map(() => chars[Math.random() * chars.length | 0]).join``;
5 11
6export function injectDarkModeStyle(recipePath) { 12export function injectDarkModeStyle(recipePath) {
7 const darkModeStyle = path.join(recipePath, 'darkmode.css'); 13 const darkModeStyle = path.join(recipePath, 'darkmode.css');
@@ -12,6 +18,8 @@ export function injectDarkModeStyle(recipePath) {
12 styles.innerHTML = data.toString(); 18 styles.innerHTML = data.toString();
13 19
14 document.querySelector('head').appendChild(styles); 20 document.querySelector('head').appendChild(styles);
21
22 debug('Injected Dark Mode style with ID', ID);
15 } 23 }
16} 24}
17 25
@@ -20,6 +28,8 @@ export function removeDarkModeStyle() {
20 28
21 if (style) { 29 if (style) {
22 style.remove(); 30 style.remove();
31
32 debug('Removed Dark Mode Style with ID', ID);
23 } 33 }
24} 34}
25 35
diff --git a/src/webview/notifications.js b/src/webview/notifications.js
index 2020bbdc6..f8fe53e1b 100644
--- a/src/webview/notifications.js
+++ b/src/webview/notifications.js
@@ -1,10 +1,13 @@
1const { ipcRenderer } = require('electron'); 1import { ipcRenderer } from 'electron';
2const uuidV1 = require('uuid/v1'); 2import uuidV1 from 'uuid/v1';
3
4const debug = require('debug')('Franz:Notifications');
3 5
4class Notification { 6class Notification {
5 static permission = 'granted'; 7 static permission = 'granted';
6 8
7 constructor(title = '', options = {}) { 9 constructor(title = '', options = {}) {
10 debug('New notification', title, options);
8 this.title = title; 11 this.title = title;
9 this.options = options; 12 this.options = options;
10 this.notificationId = uuidV1(); 13 this.notificationId = uuidV1();
diff --git a/src/webview/plugin.js b/src/webview/plugin.js
deleted file mode 100644
index 72530733d..000000000
--- a/src/webview/plugin.js
+++ /dev/null
@@ -1,90 +0,0 @@
1import { ipcRenderer } from 'electron';
2import path from 'path';
3
4import RecipeWebview from './lib/RecipeWebview';
5
6import spellchecker, { switchDict, disable as disableSpellchecker } from './spellchecker';
7import { injectDarkModeStyle, isDarkModeStyleInjected, removeDarkModeStyle } from './darkmode';
8import contextMenu from './contextMenu';
9import './notifications';
10
11const debug = require('debug')('Franz:Plugin');
12
13window.franzSettings = {};
14let serviceData;
15
16ipcRenderer.on('initializeRecipe', (e, data) => {
17 const modulePath = path.join(data.recipe.path, 'webview.js');
18 // Delete module from cache
19 delete require.cache[require.resolve(modulePath)];
20 try {
21 // eslint-disable-next-line
22 require(modulePath)(new RecipeWebview(), data);
23 debug('Initialize Recipe', data);
24
25 serviceData = data;
26
27 if (data.isDarkModeEnabled) {
28 injectDarkModeStyle(data.recipe.path);
29 debug('Add dark theme styles');
30 }
31 } catch (err) {
32 debug('Recipe initialization failed', err);
33 }
34});
35
36// Needs to run asap to intialize dictionaries
37(async () => {
38 const spellcheckingProvider = await spellchecker();
39 contextMenu(spellcheckingProvider);
40})();
41
42ipcRenderer.on('settings-update', async (e, data) => {
43 debug('Settings update received', data);
44
45 if (data.enableSpellchecking) {
46 switchDict(data.spellcheckerLanguage);
47 } else {
48 disableSpellchecker();
49 }
50
51 window.franzSettings = data;
52});
53
54ipcRenderer.on('service-settings-update', (e, data) => {
55 debug('Service settings update received', data);
56
57 if (data.isDarkModeEnabled && !isDarkModeStyleInjected()) {
58 injectDarkModeStyle(serviceData.recipe.path);
59
60 debug('Enable service dark mode');
61 } else if (!data.isDarkModeEnabled && isDarkModeStyleInjected()) {
62 removeDarkModeStyle();
63
64 debug('Disable service dark mode');
65 }
66});
67
68// Needed for current implementation of electrons 'login' event 🤦‍
69ipcRenderer.on('get-service-id', (event) => {
70 debug('Asking for service id', event);
71
72 event.sender.send('service-id', serviceData.id);
73});
74
75
76document.addEventListener('DOMContentLoaded', () => {
77 ipcRenderer.sendToHost('hello');
78}, false);
79
80// Patching window.open
81const originalWindowOpen = window.open;
82
83window.open = (url, frameName, features) => {
84 // We need to differentiate if the link should be opened in a popup or in the systems default browser
85 if (!frameName && !features) {
86 return ipcRenderer.sendToHost('new-window', url);
87 }
88
89 return originalWindowOpen(url, frameName, features);
90};
diff --git a/src/webview/recipe.js b/src/webview/recipe.js
new file mode 100644
index 000000000..944883899
--- /dev/null
+++ b/src/webview/recipe.js
@@ -0,0 +1,131 @@
1import { ipcRenderer } from 'electron';
2import path from 'path';
3import { autorun, computed, observable } from 'mobx';
4
5import RecipeWebview from './lib/RecipeWebview';
6
7import spellchecker, { switchDict, disable as disableSpellchecker } from './spellchecker';
8import { injectDarkModeStyle, isDarkModeStyleInjected, removeDarkModeStyle } from './darkmode';
9import contextMenu from './contextMenu';
10import './notifications';
11
12import { DEFAULT_APP_SETTINGS } from '../config';
13
14const debug = require('debug')('Franz:Plugin');
15
16class RecipeController {
17 @observable settings = {
18 overrideSpellcheckerLanguage: false,
19 app: DEFAULT_APP_SETTINGS,
20 service: {
21 isDarkModeEnabled: false,
22 spellcheckerLanguage: '',
23 },
24 };
25
26 spellcheckProvider = null;
27
28 ipcEvents = {
29 'initialize-recipe': 'loadRecipeModule',
30 'settings-update': 'updateAppSettings',
31 'service-settings-update': 'updateServiceSettings',
32 'get-service-id': 'serviceIdEcho',
33 }
34
35 constructor() {
36 this.initialize();
37 }
38
39 @computed get spellcheckerLanguage() {
40 return this.settings.service.spellcheckerLanguage || this.settings.app.spellcheckerLanguage;
41 }
42
43 async initialize() {
44 Object.keys(this.ipcEvents).forEach((channel) => {
45 ipcRenderer.on(channel, (event, data) => {
46 debug('Received IPC event for channel', channel, 'with', data);
47 this[this.ipcEvents[channel]](event, data);
48 });
49 });
50
51 debug('Send "hello" to host');
52 setTimeout(() => ipcRenderer.sendToHost('hello'), 100);
53
54 this.spellcheckingProvider = await spellchecker();
55 contextMenu(
56 this.spellcheckingProvider,
57 () => this.settings.app.enableSpellchecking,
58 () => this.settings.app.spellcheckerLanguage,
59 () => this.spellcheckerLanguage,
60 );
61
62 autorun(() => this.update());
63 }
64
65 loadRecipeModule(event, data) {
66 debug('loadRecipeModule');
67 const modulePath = path.join(data.recipe.path, 'webview.js');
68 // Delete module from cache
69 delete require.cache[require.resolve(modulePath)];
70 try {
71 // eslint-disable-next-line
72 require(modulePath)(new RecipeWebview(), data);
73 debug('Initialize Recipe', data);
74
75 this.settings.service = data;
76 } catch (err) {
77 console.error('Recipe initialization failed', err);
78 }
79 }
80
81 update() {
82 debug('enableSpellchecking', this.settings.app.enableSpellchecking);
83 debug('isDarkModeEnabled', this.settings.service.isDarkModeEnabled);
84 debug('System spellcheckerLanguage', this.settings.app.spellcheckerLanguage);
85 debug('Service spellcheckerLanguage', this.settings.service.spellcheckerLanguage);
86
87 if (this.settings.app.enableSpellchecking) {
88 debug('Setting spellchecker language to', this.spellcheckerLanguage);
89 switchDict(this.spellcheckerLanguage);
90 } else {
91 debug('Disable spellchecker');
92 disableSpellchecker();
93 }
94
95 if (this.settings.service.isDarkModeEnabled) {
96 debug('Enable dark mode');
97 injectDarkModeStyle(this.settings.service.recipe.path);
98 } else if (isDarkModeStyleInjected()) {
99 debug('Remove dark mode');
100 removeDarkModeStyle();
101 }
102 }
103
104 updateAppSettings(event, data) {
105 this.settings.app = Object.assign(this.settings.app, data);
106 }
107
108 updateServiceSettings(event, data) {
109 this.settings.service = Object.assign(this.settings.service, data);
110 }
111
112 serviceIdEcho(event) {
113 event.sender.send('service-id', this.settings.service.id);
114 }
115}
116
117/* eslint-disable no-new */
118new RecipeController();
119/* eslint-enable no-new */
120
121// Patching window.open
122const originalWindowOpen = window.open;
123
124window.open = (url, frameName, features) => {
125 // We need to differentiate if the link should be opened in a popup or in the systems default browser
126 if (!frameName && !features) {
127 return ipcRenderer.sendToHost('new-window', url);
128 }
129
130 return originalWindowOpen(url, frameName, features);
131};
diff --git a/src/webview/spellchecker.js b/src/webview/spellchecker.js
index b0192b7ef..becaed449 100644
--- a/src/webview/spellchecker.js
+++ b/src/webview/spellchecker.js
@@ -1,7 +1,6 @@
1import { webFrame } from 'electron'; 1import { webFrame } from 'electron';
2import fs from 'fs';
3import path from 'path';
4import { SpellCheckerProvider } from 'electron-hunspell'; 2import { SpellCheckerProvider } from 'electron-hunspell';
3import path from 'path';
5 4
6import { DICTIONARY_PATH } from '../config'; 5import { DICTIONARY_PATH } from '../config';
7 6
@@ -11,18 +10,13 @@ let provider;
11let currentDict; 10let currentDict;
12let _isEnabled = false; 11let _isEnabled = false;
13 12
14async function loadDictionaries() { 13async function loadDictionary(locale) {
15 const rawList = fs.readdirSync(DICTIONARY_PATH); 14 try {
16 15 const fileLocation = path.join(DICTIONARY_PATH, `hunspell-dict-${locale}/${locale}`);
17 const dicts = rawList.filter(item => !item.startsWith('.') && fs.lstatSync(path.join(DICTIONARY_PATH, item)).isDirectory()); 16 await provider.loadDictionary(locale, `${fileLocation}.dic`, `${fileLocation}.aff`);
18 17 debug('Loaded dictionary', locale, 'from', fileLocation);
19 debug('Found dictionaries', dicts); 18 } catch (err) {
20 19 console.error('Could not load dictionary', err);
21 for (let i = 0; i < dicts.length; i += 1) {
22 const fileLocation = `${DICTIONARY_PATH}/${dicts[i]}/${dicts[i]}`;
23 debug('Trying to load', fileLocation);
24 // eslint-disable-next-line
25 await provider.loadDictionary(dicts[i], `${fileLocation}.dic`, `${fileLocation}.aff`);
26 } 20 }
27} 21}
28 22
@@ -30,12 +24,6 @@ export async function switchDict(locale) {
30 try { 24 try {
31 debug('Trying to load dictionary', locale); 25 debug('Trying to load dictionary', locale);
32 26
33 if (!provider.availableDictionaries.includes(locale)) {
34 console.warn('Dict not available', locale);
35
36 return;
37 }
38
39 if (!provider) { 27 if (!provider) {
40 console.warn('SpellcheckProvider not initialized'); 28 console.warn('SpellcheckProvider not initialized');
41 29
@@ -48,6 +36,10 @@ export async function switchDict(locale) {
48 return; 36 return;
49 } 37 }
50 38
39 if (currentDict) {
40 provider.unloadDictionary(locale);
41 }
42 loadDictionary(locale);
51 provider.switchDictionary(locale); 43 provider.switchDictionary(locale);
52 44
53 debug('Switched dictionary to', locale); 45 debug('Switched dictionary to', locale);
@@ -66,7 +58,7 @@ export default async function initialize(languageCode = 'en-us') {
66 58
67 debug('Init spellchecker'); 59 debug('Init spellchecker');
68 await provider.initialize(); 60 await provider.initialize();
69 await loadDictionaries(); 61 // await loadDictionaries();
70 62
71 debug('Available spellchecker dictionaries', provider.availableDictionaries); 63 debug('Available spellchecker dictionaries', provider.availableDictionaries);
72 64