diff options
-rw-r--r-- | package.json | 1 | ||||
-rw-r--r-- | src/api/LocalApi.js | 12 | ||||
-rw-r--r-- | src/api/server/LocalApi.js | 32 | ||||
-rw-r--r-- | src/api/server/ServerApi.js | 1 | ||||
-rw-r--r-- | src/assets/images/tray/linux/tray-unread.png | bin | 1264 -> 2786 bytes | |||
-rw-r--r-- | src/assets/images/tray/linux/tray-unread@2x.png | bin | 2026 -> 6062 bytes | |||
-rw-r--r-- | src/assets/images/tray/linux/tray.png | bin | 1230 -> 2847 bytes | |||
-rw-r--r-- | src/assets/images/tray/linux/tray@2x.png | bin | 1545 -> 6318 bytes | |||
-rw-r--r-- | src/components/auth/Welcome.js | 2 | ||||
-rw-r--r-- | src/containers/settings/EditServiceScreen.js | 8 | ||||
-rw-r--r-- | src/i18n/locales/en-US.json | 2 | ||||
-rw-r--r-- | src/lib/Menu.js | 8 | ||||
-rw-r--r-- | src/lib/Tray.js | 6 | ||||
-rw-r--r-- | src/models/Settings.js | 1 | ||||
-rw-r--r-- | src/stores/AppStore.js | 14 | ||||
-rw-r--r-- | src/stores/ServicesStore.js | 1 | ||||
-rw-r--r-- | src/stores/SettingsStore.js | 26 | ||||
-rw-r--r-- | src/stores/UserStore.js | 3 | ||||
-rw-r--r-- | src/styles/welcome.scss | 9 | ||||
-rw-r--r-- | yarn.lock | 4 |
20 files changed, 47 insertions, 83 deletions
diff --git a/package.json b/package.json index d6b11ec96..a14367bf2 100644 --- a/package.json +++ b/package.json | |||
@@ -49,6 +49,7 @@ | |||
49 | "minimist": "^1.2.0", | 49 | "minimist": "^1.2.0", |
50 | "mkdirp": "^0.5.1", | 50 | "mkdirp": "^0.5.1", |
51 | "mobx": "^3.1.0", | 51 | "mobx": "^3.1.0", |
52 | "mobx-localstorage": "^0.1.7", | ||
52 | "mobx-react": "^4.1.0", | 53 | "mobx-react": "^4.1.0", |
53 | "mobx-react-form": "^1.32.2", | 54 | "mobx-react-form": "^1.32.2", |
54 | "mobx-react-router": "^3.1.2", | 55 | "mobx-react-router": "^3.1.2", |
diff --git a/src/api/LocalApi.js b/src/api/LocalApi.js index 3f84f8a0b..59d7d8fa2 100644 --- a/src/api/LocalApi.js +++ b/src/api/LocalApi.js | |||
@@ -4,18 +4,6 @@ export default class LocalApi { | |||
4 | this.local = local; | 4 | this.local = local; |
5 | } | 5 | } |
6 | 6 | ||
7 | getSettings() { | ||
8 | return this.local.getAppSettings(); | ||
9 | } | ||
10 | |||
11 | updateSettings(data) { | ||
12 | return this.local.updateAppSettings(data); | ||
13 | } | ||
14 | |||
15 | removeKey(key) { | ||
16 | return this.local.removeKey(key); | ||
17 | } | ||
18 | |||
19 | getAppCacheSize() { | 7 | getAppCacheSize() { |
20 | return this.local.getAppCacheSize(); | 8 | return this.local.getAppCacheSize(); |
21 | } | 9 | } |
diff --git a/src/api/server/LocalApi.js b/src/api/server/LocalApi.js index e95d750ac..aa3a7d655 100644 --- a/src/api/server/LocalApi.js +++ b/src/api/server/LocalApi.js | |||
@@ -6,38 +6,6 @@ import { getServicePartitionsDirectory } from '../../helpers/service-helpers.js' | |||
6 | const { session } = remote; | 6 | const { session } = remote; |
7 | 7 | ||
8 | export default class LocalApi { | 8 | export default class LocalApi { |
9 | // App | ||
10 | async updateAppSettings(data) { | ||
11 | const currentSettings = await this.getAppSettings(); | ||
12 | const settings = Object.assign(currentSettings, data); | ||
13 | |||
14 | localStorage.setItem('app', JSON.stringify(settings)); | ||
15 | console.debug('LocalApi::updateAppSettings resolves', settings); | ||
16 | |||
17 | return settings; | ||
18 | } | ||
19 | |||
20 | async getAppSettings() { | ||
21 | const settingsString = localStorage.getItem('app'); | ||
22 | try { | ||
23 | const settings = JSON.parse(settingsString) || {}; | ||
24 | console.debug('LocalApi::getAppSettings resolves', settings); | ||
25 | |||
26 | return settings; | ||
27 | } catch (err) { | ||
28 | return {}; | ||
29 | } | ||
30 | } | ||
31 | |||
32 | async removeKey(key) { | ||
33 | const settings = await this.getAppSettings(); | ||
34 | |||
35 | if (Object.hasOwnProperty.call(settings, key)) { | ||
36 | delete settings[key]; | ||
37 | localStorage.setItem('app', JSON.stringify(settings)); | ||
38 | } | ||
39 | } | ||
40 | |||
41 | // Services | 9 | // Services |
42 | async getAppCacheSize() { | 10 | async getAppCacheSize() { |
43 | const partitionsDir = getServicePartitionsDirectory(); | 11 | const partitionsDir = getServicePartitionsDirectory(); |
diff --git a/src/api/server/ServerApi.js b/src/api/server/ServerApi.js index d37ff51f8..8f3297d13 100644 --- a/src/api/server/ServerApi.js +++ b/src/api/server/ServerApi.js | |||
@@ -3,6 +3,7 @@ import path from 'path'; | |||
3 | import tar from 'tar'; | 3 | import tar from 'tar'; |
4 | import fs from 'fs-extra'; | 4 | import fs from 'fs-extra'; |
5 | import { remote } from 'electron'; | 5 | import { remote } from 'electron'; |
6 | import localStorage from 'mobx-localstorage'; | ||
6 | 7 | ||
7 | import ServiceModel from '../../models/Service'; | 8 | import ServiceModel from '../../models/Service'; |
8 | import RecipePreviewModel from '../../models/RecipePreview'; | 9 | import RecipePreviewModel from '../../models/RecipePreview'; |
diff --git a/src/assets/images/tray/linux/tray-unread.png b/src/assets/images/tray/linux/tray-unread.png index a94ad81fb..5697141e0 100644 --- a/src/assets/images/tray/linux/tray-unread.png +++ b/src/assets/images/tray/linux/tray-unread.png | |||
Binary files differ | |||
diff --git a/src/assets/images/tray/linux/tray-unread@2x.png b/src/assets/images/tray/linux/tray-unread@2x.png index 56e74b16a..d31e1401d 100644 --- a/src/assets/images/tray/linux/tray-unread@2x.png +++ b/src/assets/images/tray/linux/tray-unread@2x.png | |||
Binary files differ | |||
diff --git a/src/assets/images/tray/linux/tray.png b/src/assets/images/tray/linux/tray.png index 583f34df8..29a13da12 100644 --- a/src/assets/images/tray/linux/tray.png +++ b/src/assets/images/tray/linux/tray.png | |||
Binary files differ | |||
diff --git a/src/assets/images/tray/linux/tray@2x.png b/src/assets/images/tray/linux/tray@2x.png index 479a2cf95..256c52dcc 100644 --- a/src/assets/images/tray/linux/tray@2x.png +++ b/src/assets/images/tray/linux/tray@2x.png | |||
Binary files differ | |||
diff --git a/src/components/auth/Welcome.js b/src/components/auth/Welcome.js index eb9fbb847..9e1c762a5 100644 --- a/src/components/auth/Welcome.js +++ b/src/components/auth/Welcome.js | |||
@@ -46,7 +46,7 @@ export default class Login extends Component { | |||
46 | </div> | 46 | </div> |
47 | </div> | 47 | </div> |
48 | <div className="welcome__buttons"> | 48 | <div className="welcome__buttons"> |
49 | <Link to={signupRoute} className="button"> | 49 | <Link to={signupRoute} className="button button__inverted"> |
50 | {intl.formatMessage(messages.signupButton)} | 50 | {intl.formatMessage(messages.signupButton)} |
51 | </Link> | 51 | </Link> |
52 | <Link to={loginRoute} className="button"> | 52 | <Link to={loginRoute} className="button"> |
diff --git a/src/containers/settings/EditServiceScreen.js b/src/containers/settings/EditServiceScreen.js index 00e888cc4..67c2731fc 100644 --- a/src/containers/settings/EditServiceScreen.js +++ b/src/containers/settings/EditServiceScreen.js | |||
@@ -139,17 +139,17 @@ export default class EditServiceScreen extends Component { | |||
139 | 139 | ||
140 | // More fine grained and use case specific validation rules | 140 | // More fine grained and use case specific validation rules |
141 | if (recipe.hasTeamId && recipe.hasCustomUrl) { | 141 | if (recipe.hasTeamId && recipe.hasCustomUrl) { |
142 | config.fields.team.validate = [oneRequired(['team', 'customUrl'])]; | 142 | config.fields.team.validators = [oneRequired(['team', 'customUrl'])]; |
143 | config.fields.customUrl.validate = [url, oneRequired(['team', 'customUrl'])]; | 143 | config.fields.customUrl.validators = [url, oneRequired(['team', 'customUrl'])]; |
144 | } | 144 | } |
145 | 145 | ||
146 | // If a service can be hosted and has a teamId or customUrl | 146 | // If a service can be hosted and has a teamId or customUrl |
147 | if (recipe.hasHostedOption && (recipe.hasTeamId || recipe.hasCustomUrl)) { | 147 | if (recipe.hasHostedOption && (recipe.hasTeamId || recipe.hasCustomUrl)) { |
148 | if (config.fields.team) { | 148 | if (config.fields.team) { |
149 | config.fields.team.validate = []; | 149 | config.fields.team.validators = []; |
150 | } | 150 | } |
151 | if (config.fields.customUrl) { | 151 | if (config.fields.customUrl) { |
152 | config.fields.customUrl.validate = [url]; | 152 | config.fields.customUrl.validators = [url]; |
153 | } | 153 | } |
154 | } | 154 | } |
155 | 155 | ||
diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 3c09fca3b..d5c0ea441 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json | |||
@@ -159,6 +159,8 @@ | |||
159 | "settings.app.form.autoLaunchInBackground": "Open in background", | 159 | "settings.app.form.autoLaunchInBackground": "Open in background", |
160 | "settings.app.form.enableSystemTray": "Show Franz in system tray", | 160 | "settings.app.form.enableSystemTray": "Show Franz in system tray", |
161 | "settings.app.form.minimizeToSystemTray": "Minimize Franz to system tray", | 161 | "settings.app.form.minimizeToSystemTray": "Minimize Franz to system tray", |
162 | "settings.app.form.enableMenuBar": "Show Franz in Menu Bar", | ||
163 | "settings.app.form.hideDockIcon": "Hide Franz icon in Dock", | ||
162 | "settings.app.form.runInBackground": "Keep Franz in background when closing the window", | 164 | "settings.app.form.runInBackground": "Keep Franz in background when closing the window", |
163 | "settings.app.form.language": "Language", | 165 | "settings.app.form.language": "Language", |
164 | "settings.app.form.enableSpellchecking": "Enable spell checking", | 166 | "settings.app.form.enableSpellchecking": "Enable spell checking", |
diff --git a/src/lib/Menu.js b/src/lib/Menu.js index d01666d49..703060dc1 100644 --- a/src/lib/Menu.js +++ b/src/lib/Menu.js | |||
@@ -22,10 +22,14 @@ const template = [ | |||
22 | role: 'cut', | 22 | role: 'cut', |
23 | }, | 23 | }, |
24 | { | 24 | { |
25 | role: 'copy', | 25 | label: 'Copy', |
26 | accelerator: 'Cmd+C', | ||
27 | selector: 'copy:', | ||
26 | }, | 28 | }, |
27 | { | 29 | { |
28 | role: 'paste', | 30 | label: 'Paste', |
31 | accelerator: 'Cmd+V', | ||
32 | selector: 'paste:', | ||
29 | }, | 33 | }, |
30 | { | 34 | { |
31 | role: 'pasteandmatchstyle', | 35 | role: 'pasteandmatchstyle', |
diff --git a/src/lib/Tray.js b/src/lib/Tray.js index 2efe71a71..588fa75bf 100644 --- a/src/lib/Tray.js +++ b/src/lib/Tray.js | |||
@@ -1,4 +1,4 @@ | |||
1 | import { app, Tray, Menu, systemPreferences } from 'electron'; | 1 | import { app, Tray, Menu, systemPreferences, nativeImage } from 'electron'; |
2 | import path from 'path'; | 2 | import path from 'path'; |
3 | 3 | ||
4 | const FILE_EXTENSION = process.platform === 'win32' ? 'ico' : 'png'; | 4 | const FILE_EXTENSION = process.platform === 'win32' ? 'ico' : 'png'; |
@@ -78,8 +78,8 @@ export default class TrayIcon { | |||
78 | platform = `${platform}-dark`; | 78 | platform = `${platform}-dark`; |
79 | } | 79 | } |
80 | 80 | ||
81 | return path.join( | 81 | return nativeImage.createFromPath(path.join( |
82 | __dirname, '..', 'assets', 'images', type, platform, `${asset}.${FILE_EXTENSION}`, | 82 | __dirname, '..', 'assets', 'images', type, platform, `${asset}.${FILE_EXTENSION}`), |
83 | ); | 83 | ); |
84 | } | 84 | } |
85 | } | 85 | } |
diff --git a/src/models/Settings.js b/src/models/Settings.js index ca44da258..e39b63087 100644 --- a/src/models/Settings.js +++ b/src/models/Settings.js | |||
@@ -2,7 +2,6 @@ import { observable, extendObservable } from 'mobx'; | |||
2 | import { DEFAULT_APP_SETTINGS } from '../config'; | 2 | import { DEFAULT_APP_SETTINGS } from '../config'; |
3 | 3 | ||
4 | export default class Settings { | 4 | export default class Settings { |
5 | @observable autoLaunchOnStart = DEFAULT_APP_SETTINGS.autoLaunchOnStart; | ||
6 | @observable autoLaunchInBackground = DEFAULT_APP_SETTINGS.autoLaunchInBackground; | 5 | @observable autoLaunchInBackground = DEFAULT_APP_SETTINGS.autoLaunchInBackground; |
7 | @observable runInBackground = DEFAULT_APP_SETTINGS.runInBackground; | 6 | @observable runInBackground = DEFAULT_APP_SETTINGS.runInBackground; |
8 | @observable enableSystemTray = DEFAULT_APP_SETTINGS.enableSystemTray; | 7 | @observable enableSystemTray = DEFAULT_APP_SETTINGS.enableSystemTray; |
diff --git a/src/stores/AppStore.js b/src/stores/AppStore.js index a51a3267f..162422017 100644 --- a/src/stores/AppStore.js +++ b/src/stores/AppStore.js | |||
@@ -334,10 +334,7 @@ export default class AppStore extends Store { | |||
334 | } | 334 | } |
335 | 335 | ||
336 | // Helpers | 336 | // Helpers |
337 | async _appStartsCounter() { | 337 | _appStartsCounter() { |
338 | // we need to wait until the settings request is resolved | ||
339 | await this.stores.settings.allSettingsRequest; | ||
340 | |||
341 | this.actions.settings.update({ | 338 | this.actions.settings.update({ |
342 | settings: { | 339 | settings: { |
343 | appStarts: (this.stores.settings.all.appStarts || 0) + 1, | 340 | appStarts: (this.stores.settings.all.appStarts || 0) + 1, |
@@ -348,10 +345,7 @@ export default class AppStore extends Store { | |||
348 | async _autoStart() { | 345 | async _autoStart() { |
349 | this.autoLaunchOnStart = await this._checkAutoStart(); | 346 | this.autoLaunchOnStart = await this._checkAutoStart(); |
350 | 347 | ||
351 | // we need to wait until the settings request is resolved | 348 | if (this.stores.settings.all.appStarts === 1) { |
352 | await this.stores.settings.allSettingsRequest; | ||
353 | |||
354 | if (!this.stores.settings.all.appStarts) { | ||
355 | this.actions.app.launchOnStartup({ | 349 | this.actions.app.launchOnStartup({ |
356 | enable: true, | 350 | enable: true, |
357 | }); | 351 | }); |
@@ -367,8 +361,8 @@ export default class AppStore extends Store { | |||
367 | console.debug('reactivateServices: computer is offline, trying again in 5s, retries:', retryCount); | 361 | console.debug('reactivateServices: computer is offline, trying again in 5s, retries:', retryCount); |
368 | setTimeout(() => this._reactivateServices(retryCount + 1), 5000); | 362 | setTimeout(() => this._reactivateServices(retryCount + 1), 5000); |
369 | } else { | 363 | } else { |
370 | console.debug('reactivateServices: reload all services'); | 364 | console.debug('reactivateServices: reload Franz'); |
371 | this.actions.service.reloadAll(); | 365 | window.location.reload(); |
372 | } | 366 | } |
373 | } | 367 | } |
374 | 368 | ||
diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js index 99ffe5439..c38d0d9ee 100644 --- a/src/stores/ServicesStore.js +++ b/src/stores/ServicesStore.js | |||
@@ -536,7 +536,6 @@ export default class ServicesStore extends Store { | |||
536 | 536 | ||
537 | // We can't just block this earlier, otherwise the mobx reaction won't be aware of the vars to watch in some cases | 537 | // We can't just block this earlier, otherwise the mobx reaction won't be aware of the vars to watch in some cases |
538 | if (showMessageBadgesEvenWhenMuted) { | 538 | if (showMessageBadgesEvenWhenMuted) { |
539 | console.log('set badge', unreadDirectMessageCount, unreadIndirectMessageCount); | ||
540 | this.actions.app.setBadge({ | 539 | this.actions.app.setBadge({ |
541 | unreadDirectMessageCount, | 540 | unreadDirectMessageCount, |
542 | unreadIndirectMessageCount, | 541 | unreadIndirectMessageCount, |
diff --git a/src/stores/SettingsStore.js b/src/stores/SettingsStore.js index da99a720f..b7d803398 100644 --- a/src/stores/SettingsStore.js +++ b/src/stores/SettingsStore.js | |||
@@ -1,17 +1,12 @@ | |||
1 | import { ipcRenderer } from 'electron'; | 1 | import { ipcRenderer } from 'electron'; |
2 | import { action, computed, observable, extendObservable } from 'mobx'; | 2 | import { action, computed } from 'mobx'; |
3 | import localStorage from 'mobx-localstorage'; | ||
3 | 4 | ||
4 | import Store from './lib/Store'; | 5 | import Store from './lib/Store'; |
5 | import Request from './lib/Request'; | ||
6 | import CachedRequest from './lib/CachedRequest'; | ||
7 | import { gaEvent } from '../lib/analytics'; | 6 | import { gaEvent } from '../lib/analytics'; |
8 | import SettingsModel from '../models/Settings'; | 7 | import SettingsModel from '../models/Settings'; |
9 | 8 | ||
10 | export default class SettingsStore extends Store { | 9 | export default class SettingsStore extends Store { |
11 | @observable allSettingsRequest = new CachedRequest(this.api.local, 'getSettings'); | ||
12 | @observable updateSettingsRequest = new Request(this.api.local, 'updateSettings'); | ||
13 | @observable removeSettingsKeyRequest = new Request(this.api.local, 'removeKey'); | ||
14 | |||
15 | constructor(...args) { | 10 | constructor(...args) { |
16 | super(...args); | 11 | super(...args); |
17 | 12 | ||
@@ -21,20 +16,16 @@ export default class SettingsStore extends Store { | |||
21 | } | 16 | } |
22 | 17 | ||
23 | setup() { | 18 | setup() { |
24 | this.allSettingsRequest.execute(); | ||
25 | this._shareSettingsWithMainProcess(); | 19 | this._shareSettingsWithMainProcess(); |
26 | } | 20 | } |
27 | 21 | ||
28 | @computed get all() { | 22 | @computed get all() { |
29 | return new SettingsModel(this.allSettingsRequest.result); | 23 | return new SettingsModel(localStorage.getItem('app') || {}); |
30 | } | 24 | } |
31 | 25 | ||
32 | @action async _update({ settings }) { | 26 | @action async _update({ settings }) { |
33 | await this.updateSettingsRequest.execute(settings)._promise; | 27 | const appSettings = this.all; |
34 | await this.allSettingsRequest.patch((result) => { | 28 | localStorage.setItem('app', Object.assign(appSettings, settings)); |
35 | if (!result) return; | ||
36 | extendObservable(result, settings); | ||
37 | }); | ||
38 | 29 | ||
39 | // We need a little hack to wait until everything is patched | 30 | // We need a little hack to wait until everything is patched |
40 | setTimeout(() => this._shareSettingsWithMainProcess(), 0); | 31 | setTimeout(() => this._shareSettingsWithMainProcess(), 0); |
@@ -43,8 +34,11 @@ export default class SettingsStore extends Store { | |||
43 | } | 34 | } |
44 | 35 | ||
45 | @action async _remove({ key }) { | 36 | @action async _remove({ key }) { |
46 | await this.removeSettingsKeyRequest.execute(key); | 37 | const appSettings = this.all; |
47 | await this.allSettingsRequest.invalidate({ immediately: true }); | 38 | if (Object.hasOwnProperty.call(appSettings, key)) { |
39 | delete appSettings[key]; | ||
40 | localStorage.setItem('app', appSettings); | ||
41 | } | ||
48 | 42 | ||
49 | this._shareSettingsWithMainProcess(); | 43 | this._shareSettingsWithMainProcess(); |
50 | } | 44 | } |
diff --git a/src/stores/UserStore.js b/src/stores/UserStore.js index abec4df5d..7dbbd955b 100644 --- a/src/stores/UserStore.js +++ b/src/stores/UserStore.js | |||
@@ -1,6 +1,7 @@ | |||
1 | import { observable, computed, action } from 'mobx'; | 1 | import { observable, computed, action } from 'mobx'; |
2 | import moment from 'moment'; | 2 | import moment from 'moment'; |
3 | import jwt from 'jsonwebtoken'; | 3 | import jwt from 'jsonwebtoken'; |
4 | import localStorage from 'mobx-localstorage'; | ||
4 | 5 | ||
5 | import { isDevMode } from '../environment'; | 6 | import { isDevMode } from '../environment'; |
6 | import Store from './lib/Store'; | 7 | import Store from './lib/Store'; |
@@ -99,7 +100,7 @@ export default class UserStore extends Store { | |||
99 | 100 | ||
100 | // Data | 101 | // Data |
101 | @computed get isLoggedIn() { | 102 | @computed get isLoggedIn() { |
102 | return this.authToken !== null && this.authToken !== undefined; | 103 | return Boolean(localStorage.getItem('authToken')); |
103 | } | 104 | } |
104 | 105 | ||
105 | // @computed get isTokenValid() { | 106 | // @computed get isTokenValid() { |
diff --git a/src/styles/welcome.scss b/src/styles/welcome.scss index 46299b966..a12069ba4 100644 --- a/src/styles/welcome.scss +++ b/src/styles/welcome.scss | |||
@@ -55,6 +55,15 @@ | |||
55 | background: #FFF; | 55 | background: #FFF; |
56 | color: $theme-brand-primary; | 56 | color: $theme-brand-primary; |
57 | } | 57 | } |
58 | |||
59 | &__inverted { | ||
60 | background: #FFF; | ||
61 | color: $theme-brand-primary; | ||
62 | } | ||
63 | &__inverted:hover { | ||
64 | background: none; | ||
65 | color: #FFF; | ||
66 | } | ||
58 | } | 67 | } |
59 | 68 | ||
60 | &__featured-services { | 69 | &__featured-services { |
@@ -4270,6 +4270,10 @@ mksnapshot@^0.3.0: | |||
4270 | fs-extra "0.26.7" | 4270 | fs-extra "0.26.7" |
4271 | request "^2.79.0" | 4271 | request "^2.79.0" |
4272 | 4272 | ||
4273 | mobx-localstorage@^0.1.7: | ||
4274 | version "0.1.7" | ||
4275 | resolved "https://registry.yarnpkg.com/mobx-localstorage/-/mobx-localstorage-0.1.7.tgz#c0c64366769f390ca4a333f41912eae00cd4a9de" | ||
4276 | |||
4273 | mobx-react-form@^1.32.2: | 4277 | mobx-react-form@^1.32.2: |
4274 | version "1.32.2" | 4278 | version "1.32.2" |
4275 | resolved "https://registry.yarnpkg.com/mobx-react-form/-/mobx-react-form-1.32.2.tgz#5610dd0e4fab006acf2daf1becbedecad182a5a0" | 4279 | resolved "https://registry.yarnpkg.com/mobx-react-form/-/mobx-react-form-1.32.2.tgz#5610dd0e4fab006acf2daf1becbedecad182a5a0" |