aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Stefan Malzner <stefan@adlk.io>2019-04-12 19:05:59 +0200
committerLibravatar Stefan Malzner <stefan@adlk.io>2019-04-12 19:05:59 +0200
commit821a3192801eb86a06373054e90150f73473d30c (patch)
treef7f3417d05108787636fbe8371f3babb40fe47f3
parentadd locale on signup (diff)
parentlink to in-app changelog on new update notification (diff)
downloadferdium-app-821a3192801eb86a06373054e90150f73473d30c.tar.gz
ferdium-app-821a3192801eb86a06373054e90150f73473d30c.tar.zst
ferdium-app-821a3192801eb86a06373054e90150f73473d30c.zip
Merge branch 'feature/announcements' into develop
-rw-r--r--package-lock.json5
-rw-r--r--package.json1
-rw-r--r--packages/theme/src/themes/dark/index.ts26
-rw-r--r--packages/theme/src/themes/default/index.ts25
-rw-r--r--src/actions/index.js2
-rw-r--r--src/actions/lib/actions.js2
-rw-r--r--src/actions/service.js1
-rw-r--r--src/api/server/ServerApi.js4
-rw-r--r--src/components/layout/AppLayout.js16
-rw-r--r--src/config.js1
-rw-r--r--src/containers/layout/AppLayoutContainer.js3
-rw-r--r--src/electron/ipc-api/autoUpdate.js7
-rw-r--r--src/features/announcements/actions.js10
-rw-r--r--src/features/announcements/api.js33
-rw-r--r--src/features/announcements/components/AnnouncementScreen.js286
-rw-r--r--src/features/announcements/index.js30
-rw-r--r--src/features/announcements/store.js128
-rw-r--r--src/features/utils/ActionBinding.js29
-rw-r--r--src/features/utils/FeatureStore.js43
-rw-r--r--src/features/workspaces/components/CreateWorkspaceForm.js4
-rw-r--r--src/features/workspaces/store.js69
-rw-r--r--src/i18n/locales/defaultMessages.json4437
-rw-r--r--src/i18n/locales/en-US.json2
-rw-r--r--src/i18n/messages/src/components/layout/AppLayout.json24
-rw-r--r--src/i18n/messages/src/features/announcements/components/AnnouncementScreen.json15
-rw-r--r--src/i18n/messages/src/lib/Menu.json221
-rw-r--r--src/lib/Menu.js11
-rw-r--r--src/stores/AppStore.js5
-rw-r--r--src/stores/FeaturesStore.js2
-rw-r--r--src/stores/ServicesStore.js6
-rw-r--r--src/stores/index.js4
-rw-r--r--src/stores/lib/Reaction.js19
-rw-r--r--src/styles/info-bar.scss4
33 files changed, 843 insertions, 4632 deletions
diff --git a/package-lock.json b/package-lock.json
index fcf3e7463..70f3b2484 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12147,6 +12147,11 @@
12147 "object-visit": "^1.0.0" 12147 "object-visit": "^1.0.0"
12148 } 12148 }
12149 }, 12149 },
12150 "marked": {
12151 "version": "0.6.1",
12152 "resolved": "https://registry.npmjs.org/marked/-/marked-0.6.1.tgz",
12153 "integrity": "sha512-+H0L3ibcWhAZE02SKMqmvYsErLo4EAVJxu5h3bHBBDvvjeWXtl92rGUSBYHL2++5Y+RSNgl8dYOAXcYe7lp1fA=="
12154 },
12150 "matchdep": { 12155 "matchdep": {
12151 "version": "2.0.0", 12156 "version": "2.0.0",
12152 "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", 12157 "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz",
diff --git a/package.json b/package.json
index 8dcf1cb37..c43e0b3a9 100644
--- a/package.json
+++ b/package.json
@@ -54,6 +54,7 @@
54 "hex-to-rgba": "1.0.2", 54 "hex-to-rgba": "1.0.2",
55 "jsonwebtoken": "8.5.1", 55 "jsonwebtoken": "8.5.1",
56 "lodash": "^4.17.4", 56 "lodash": "^4.17.4",
57 "marked": "0.6.1",
57 "mdi": "^1.9.33", 58 "mdi": "^1.9.33",
58 "mime-types": "2.1.21", 59 "mime-types": "2.1.21",
59 "mobx": "5.7.0", 60 "mobx": "5.7.0",
diff --git a/packages/theme/src/themes/dark/index.ts b/packages/theme/src/themes/dark/index.ts
index fd04b106c..d48dbf916 100644
--- a/packages/theme/src/themes/dark/index.ts
+++ b/packages/theme/src/themes/dark/index.ts
@@ -1,5 +1,5 @@
1import color from 'color'; 1import color from 'color';
2import { merge, cloneDeep } from 'lodash'; 2import { cloneDeep, merge } from 'lodash';
3 3
4import * as defaultStyles from '../default'; 4import * as defaultStyles from '../default';
5import * as legacyStyles from '../legacy'; 5import * as legacyStyles from '../legacy';
@@ -112,21 +112,9 @@ export const workspaces = merge({}, defaultStyles.workspaces, {
112 }, 112 },
113}); 113});
114 114
115// // Workspace settings 115// Announcements
116// export const workspaceSettings = merge({}, defaultStyles.workspaceSettings, { 116export const announcements = merge({}, defaultStyles.workspaces, {
117// listItemBorderColor: legacyStyles.darkThemeGrayDarker, 117 spotlight: {
118// listItemHoverBgColor: legacyStyles.darkThemeGrayDarker, 118 background: legacyStyles.darkThemeGrayDark,
119// }); 119 },
120// 120});
121// // Workspace Drawer
122// export const workspaceDrawerBackground = color(colorBackground).lighten(0.3).hex();
123// export const workspaceDrawerAddButtonColor = legacyStyles.darkThemeGrayLighter;
124// export const workspaceDrawerAddButtonHoverColor = legacyStyles.darkThemeGraySmoke;
125// export const workspaceDrawerItemBorder = color(workspaceDrawerBackground).lighten(0.2).hex();
126// export const workspaceDrawerItemHoverBackground = color(workspaceDrawerBackground).lighten(0.2).hex();
127// export const workspaceDrawerItemActiveBackground = defaultStyles.brandPrimary;
128// export const workspaceDrawerItemNameColor = colorText;
129// export const workspaceDrawerItemNameActiveColor = 'white';
130// export const workspaceDrawerServicesColor = color(colorText).darken(0.5).hex();
131// export const workspaceDrawerServicesActiveColor = color(defaultStyles.brandPrimary).lighten(0.5).hex();
132//
diff --git a/packages/theme/src/themes/default/index.ts b/packages/theme/src/themes/default/index.ts
index d0493b82f..0f02fa3c8 100644
--- a/packages/theme/src/themes/default/index.ts
+++ b/packages/theme/src/themes/default/index.ts
@@ -201,22 +201,9 @@ export const workspaces = {
201 }, 201 },
202}; 202};
203 203
204// export const workspaceSettings = { 204// Announcements
205// listItemHeight: 57, 205export const announcements = {
206// listItemBorderColor: legacyStyles.themeGrayLightest, 206 spotlight: {
207// listItemHoverBgColor: legacyStyles.themeGrayLightest, 207 background: legacyStyles.themeGrayLightest,
208// }; 208 },
209// 209};
210// // Workspace Drawer
211// export const workspaceDrawerWidth = 300;
212// export const workspaceDrawerPadding = 20;
213// export const workspaceDrawerBackground = color(colorBackground).lighten(0.1).hex();
214// export const workspaceDrawerAddButtonColor = legacyStyles.themeGrayLight;
215// export const workspaceDrawerAddButtonHoverColor = color(legacyStyles.themeGrayLight).lighten(0.1).hex();
216// export const workspaceDrawerItemHoverBackground = color(workspaceDrawerBackground).darken(0.01).hex();
217// export const workspaceDrawerItemActiveBackground = legacyStyles.themeGrayLightest;
218// export const workspaceDrawerItemBorder = color(workspaceDrawerBackground).darken(0.05).hex();
219// export const workspaceDrawerItemNameColor = colorText;
220// export const workspaceDrawerItemNameActiveColor = colorText;
221// export const workspaceDrawerServicesColor = color(colorText).lighten(1.5).hex();
222// export const workspaceDrawerServicesActiveColor = workspaceDrawerServicesColor;
diff --git a/src/actions/index.js b/src/actions/index.js
index 00f843cd6..fc525afeb 100644
--- a/src/actions/index.js
+++ b/src/actions/index.js
@@ -11,6 +11,7 @@ import payment from './payment';
11import news from './news'; 11import news from './news';
12import settings from './settings'; 12import settings from './settings';
13import requests from './requests'; 13import requests from './requests';
14import announcements from '../features/announcements/actions';
14import workspaces from '../features/workspaces/actions'; 15import workspaces from '../features/workspaces/actions';
15 16
16const actions = Object.assign({}, { 17const actions = Object.assign({}, {
@@ -28,5 +29,6 @@ const actions = Object.assign({}, {
28 29
29export default Object.assign( 30export default Object.assign(
30 defineActions(actions, PropTypes.checkPropTypes), 31 defineActions(actions, PropTypes.checkPropTypes),
32 { announcements },
31 { workspaces }, 33 { workspaces },
32); 34);
diff --git a/src/actions/lib/actions.js b/src/actions/lib/actions.js
index 2bc7d2711..b38db9946 100644
--- a/src/actions/lib/actions.js
+++ b/src/actions/lib/actions.js
@@ -1,7 +1,7 @@
1export const createActionsFromDefinitions = (actionDefinitions, validate) => { 1export const createActionsFromDefinitions = (actionDefinitions, validate) => {
2 const actions = {}; 2 const actions = {};
3 Object.keys(actionDefinitions).forEach((actionName) => { 3 Object.keys(actionDefinitions).forEach((actionName) => {
4 const action = (params) => { 4 const action = (params = {}) => {
5 const schema = actionDefinitions[actionName]; 5 const schema = actionDefinitions[actionName];
6 validate(schema, params, actionName); 6 validate(schema, params, actionName);
7 action.notify(params); 7 action.notify(params);
diff --git a/src/actions/service.js b/src/actions/service.js
index ceaabc31e..ce62560a9 100644
--- a/src/actions/service.js
+++ b/src/actions/service.js
@@ -5,6 +5,7 @@ export default {
5 setActive: { 5 setActive: {
6 serviceId: PropTypes.string.isRequired, 6 serviceId: PropTypes.string.isRequired,
7 }, 7 },
8 blurActive: {},
8 setActiveNext: {}, 9 setActiveNext: {},
9 setActivePrev: {}, 10 setActivePrev: {},
10 showAddServiceInterface: { 11 showAddServiceInterface: {
diff --git a/src/api/server/ServerApi.js b/src/api/server/ServerApi.js
index bafeef005..ab27e92bf 100644
--- a/src/api/server/ServerApi.js
+++ b/src/api/server/ServerApi.js
@@ -268,7 +268,7 @@ export default class ServerApi {
268 const data = await request.json(); 268 const data = await request.json();
269 269
270 const features = data; 270 const features = data;
271 console.debug('ServerApi::getDefaultFeatures resolves', features); 271 debug('ServerApi::getDefaultFeatures resolves', features);
272 return features; 272 return features;
273 } 273 }
274 274
@@ -280,7 +280,7 @@ export default class ServerApi {
280 const data = await request.json(); 280 const data = await request.json();
281 281
282 const features = data; 282 const features = data;
283 console.debug('ServerApi::getFeatures resolves', features); 283 debug('ServerApi::getFeatures resolves', features);
284 return features; 284 return features;
285 } 285 }
286 286
diff --git a/src/components/layout/AppLayout.js b/src/components/layout/AppLayout.js
index b7f7722dd..d5febfaf4 100644
--- a/src/components/layout/AppLayout.js
+++ b/src/components/layout/AppLayout.js
@@ -14,8 +14,10 @@ import ErrorBoundary from '../util/ErrorBoundary';
14// import globalMessages from '../../i18n/globalMessages'; 14// import globalMessages from '../../i18n/globalMessages';
15 15
16import { isWindows } from '../../environment'; 16import { isWindows } from '../../environment';
17import AnnouncementScreen from '../../features/announcements/components/AnnouncementScreen';
17import WorkspaceSwitchingIndicator from '../../features/workspaces/components/WorkspaceSwitchingIndicator'; 18import WorkspaceSwitchingIndicator from '../../features/workspaces/components/WorkspaceSwitchingIndicator';
18import { workspaceStore } from '../../features/workspaces'; 19import { workspaceStore } from '../../features/workspaces';
20import { announcementActions } from '../../features/announcements/actions';
19 21
20function createMarkup(HTMLString) { 22function createMarkup(HTMLString) {
21 return { __html: HTMLString }; 23 return { __html: HTMLString };
@@ -71,6 +73,7 @@ class AppLayout extends Component {
71 // isOnline: PropTypes.bool.isRequired, 73 // isOnline: PropTypes.bool.isRequired,
72 showServicesUpdatedInfoBar: PropTypes.bool.isRequired, 74 showServicesUpdatedInfoBar: PropTypes.bool.isRequired,
73 appUpdateIsDownloaded: PropTypes.bool.isRequired, 75 appUpdateIsDownloaded: PropTypes.bool.isRequired,
76 nextAppReleaseVersion: PropTypes.string,
74 removeNewsItem: PropTypes.func.isRequired, 77 removeNewsItem: PropTypes.func.isRequired,
75 reloadServicesAfterUpdate: PropTypes.func.isRequired, 78 reloadServicesAfterUpdate: PropTypes.func.isRequired,
76 installAppUpdate: PropTypes.func.isRequired, 79 installAppUpdate: PropTypes.func.isRequired,
@@ -80,10 +83,12 @@ class AppLayout extends Component {
80 areRequiredRequestsLoading: PropTypes.bool.isRequired, 83 areRequiredRequestsLoading: PropTypes.bool.isRequired,
81 darkMode: PropTypes.bool.isRequired, 84 darkMode: PropTypes.bool.isRequired,
82 isDelayAppScreenVisible: PropTypes.bool.isRequired, 85 isDelayAppScreenVisible: PropTypes.bool.isRequired,
86 isAnnouncementVisible: PropTypes.bool.isRequired,
83 }; 87 };
84 88
85 static defaultProps = { 89 static defaultProps = {
86 children: [], 90 children: [],
91 nextAppReleaseVersion: null,
87 }; 92 };
88 93
89 static contextTypes = { 94 static contextTypes = {
@@ -102,6 +107,7 @@ class AppLayout extends Component {
102 news, 107 news,
103 showServicesUpdatedInfoBar, 108 showServicesUpdatedInfoBar,
104 appUpdateIsDownloaded, 109 appUpdateIsDownloaded,
110 nextAppReleaseVersion,
105 removeNewsItem, 111 removeNewsItem,
106 reloadServicesAfterUpdate, 112 reloadServicesAfterUpdate,
107 installAppUpdate, 113 installAppUpdate,
@@ -111,6 +117,7 @@ class AppLayout extends Component {
111 areRequiredRequestsLoading, 117 areRequiredRequestsLoading,
112 darkMode, 118 darkMode,
113 isDelayAppScreenVisible, 119 isDelayAppScreenVisible,
120 isAnnouncementVisible,
114 } = this.props; 121 } = this.props;
115 122
116 const { intl } = this.context; 123 const { intl } = this.context;
@@ -178,14 +185,19 @@ class AppLayout extends Component {
178 <span className="mdi mdi-information" /> 185 <span className="mdi mdi-information" />
179 {intl.formatMessage(messages.updateAvailable)} 186 {intl.formatMessage(messages.updateAvailable)}
180 {' '} 187 {' '}
181 <a href="https://meetfranz.com/changelog" target="_blank"> 188 <button
189 className="info-bar__inline-button"
190 type="button"
191 onClick={() => announcementActions.show({ targetVersion: nextAppReleaseVersion })}
192 >
182 <u>{intl.formatMessage(messages.changelog)}</u> 193 <u>{intl.formatMessage(messages.changelog)}</u>
183 </a> 194 </button>
184 </InfoBar> 195 </InfoBar>
185 )} 196 )}
186 {isDelayAppScreenVisible && (<DelayApp />)} 197 {isDelayAppScreenVisible && (<DelayApp />)}
187 <BasicAuth /> 198 <BasicAuth />
188 <ShareFranz /> 199 <ShareFranz />
200 {isAnnouncementVisible && (<AnnouncementScreen />)}
189 {services} 201 {services}
190 </div> 202 </div>
191 </div> 203 </div>
diff --git a/src/config.js b/src/config.js
index 242675762..e7745b61d 100644
--- a/src/config.js
+++ b/src/config.js
@@ -41,6 +41,7 @@ export const DEFAULT_FEATURES_CONFIG = {
41 }, 41 },
42 isServiceProxyEnabled: false, 42 isServiceProxyEnabled: false,
43 isServiceProxyPremiumFeature: true, 43 isServiceProxyPremiumFeature: true,
44 isAnnouncementsEnabled: true,
44 isWorkspacePremiumFeature: true, 45 isWorkspacePremiumFeature: true,
45 isWorkspaceEnabled: false, 46 isWorkspaceEnabled: false,
46}; 47};
diff --git a/src/containers/layout/AppLayoutContainer.js b/src/containers/layout/AppLayoutContainer.js
index 2d855c78f..d2891a6a4 100644
--- a/src/containers/layout/AppLayoutContainer.js
+++ b/src/containers/layout/AppLayoutContainer.js
@@ -23,6 +23,7 @@ import { state as delayAppState } from '../../features/delayApp';
23import { workspaceActions } from '../../features/workspaces/actions'; 23import { workspaceActions } from '../../features/workspaces/actions';
24import WorkspaceDrawer from '../../features/workspaces/components/WorkspaceDrawer'; 24import WorkspaceDrawer from '../../features/workspaces/components/WorkspaceDrawer';
25import { workspaceStore } from '../../features/workspaces'; 25import { workspaceStore } from '../../features/workspaces';
26import { announcementsStore } from '../../features/announcements';
26 27
27export default @inject('stores', 'actions') @observer class AppLayoutContainer extends Component { 28export default @inject('stores', 'actions') @observer class AppLayoutContainer extends Component {
28 static defaultProps = { 29 static defaultProps = {
@@ -135,6 +136,7 @@ export default @inject('stores', 'actions') @observer class AppLayoutContainer e
135 isOnline={app.isOnline} 136 isOnline={app.isOnline}
136 showServicesUpdatedInfoBar={ui.showServicesUpdatedInfoBar} 137 showServicesUpdatedInfoBar={ui.showServicesUpdatedInfoBar}
137 appUpdateIsDownloaded={app.updateStatus === app.updateStatusTypes.DOWNLOADED} 138 appUpdateIsDownloaded={app.updateStatus === app.updateStatusTypes.DOWNLOADED}
139 nextAppReleaseVersion={app.nextAppReleaseVersion}
138 sidebar={sidebar} 140 sidebar={sidebar}
139 workspacesDrawer={workspacesDrawer} 141 workspacesDrawer={workspacesDrawer}
140 services={servicesContainer} 142 services={servicesContainer}
@@ -149,6 +151,7 @@ export default @inject('stores', 'actions') @observer class AppLayoutContainer e
149 areRequiredRequestsLoading={requests.areRequiredRequestsLoading} 151 areRequiredRequestsLoading={requests.areRequiredRequestsLoading}
150 darkMode={settings.all.app.darkMode} 152 darkMode={settings.all.app.darkMode}
151 isDelayAppScreenVisible={delayAppState.isDelayAppScreenVisible} 153 isDelayAppScreenVisible={delayAppState.isDelayAppScreenVisible}
154 isAnnouncementVisible={announcementsStore.isAnnouncementVisible}
152 > 155 >
153 {React.Children.count(children) > 0 ? children : null} 156 {React.Children.count(children) > 0 ? children : null}
154 </AppLayout> 157 </AppLayout>
diff --git a/src/electron/ipc-api/autoUpdate.js b/src/electron/ipc-api/autoUpdate.js
index 74b718734..9a04c1958 100644
--- a/src/electron/ipc-api/autoUpdate.js
+++ b/src/electron/ipc-api/autoUpdate.js
@@ -30,9 +30,12 @@ export default (params) => {
30 params.mainWindow.webContents.send('autoUpdate', { available: false }); 30 params.mainWindow.webContents.send('autoUpdate', { available: false });
31 }); 31 });
32 32
33 autoUpdater.on('update-available', () => { 33 autoUpdater.on('update-available', (event) => {
34 debug('update-available'); 34 debug('update-available');
35 params.mainWindow.webContents.send('autoUpdate', { available: true }); 35 params.mainWindow.webContents.send('autoUpdate', {
36 version: event.version,
37 available: true,
38 });
36 }); 39 });
37 40
38 autoUpdater.on('download-progress', (progressObj) => { 41 autoUpdater.on('download-progress', (progressObj) => {
diff --git a/src/features/announcements/actions.js b/src/features/announcements/actions.js
new file mode 100644
index 000000000..bab496314
--- /dev/null
+++ b/src/features/announcements/actions.js
@@ -0,0 +1,10 @@
1import PropTypes from 'prop-types';
2import { createActionsFromDefinitions } from '../../actions/lib/actions';
3
4export const announcementActions = createActionsFromDefinitions({
5 show: {
6 targetVersion: PropTypes.string,
7 },
8}, PropTypes.checkPropTypes);
9
10export default announcementActions;
diff --git a/src/features/announcements/api.js b/src/features/announcements/api.js
new file mode 100644
index 000000000..a581bd8de
--- /dev/null
+++ b/src/features/announcements/api.js
@@ -0,0 +1,33 @@
1import { remote } from 'electron';
2import Request from '../../stores/lib/Request';
3import { API, API_VERSION } from '../../environment';
4
5const debug = require('debug')('Franz:feature:announcements:api');
6
7export const announcementsApi = {
8 async getCurrentVersion() {
9 debug('getting current version of electron app');
10 return Promise.resolve(remote.app.getVersion());
11 },
12
13 async getChangelog(version) {
14 debug('fetching release changelog from Github');
15 const url = `https://api.github.com/repos/meetfranz/franz/releases/tags/v${version}`;
16 const request = await window.fetch(url, { method: 'GET' });
17 if (!request.ok) return null;
18 const data = await request.json();
19 return data.body;
20 },
21
22 async getAnnouncement(version) {
23 debug('fetching release announcement from api');
24 const url = `${API}/${API_VERSION}/announcements/${version}`;
25 const response = await window.fetch(url, { method: 'GET' });
26 if (!response.ok) return null;
27 return response.json();
28 },
29};
30
31export const getCurrentVersionRequest = new Request(announcementsApi, 'getCurrentVersion');
32export const getChangelogRequest = new Request(announcementsApi, 'getChangelog');
33export const getAnnouncementRequest = new Request(announcementsApi, 'getAnnouncement');
diff --git a/src/features/announcements/components/AnnouncementScreen.js b/src/features/announcements/components/AnnouncementScreen.js
new file mode 100644
index 000000000..dfce6cdd5
--- /dev/null
+++ b/src/features/announcements/components/AnnouncementScreen.js
@@ -0,0 +1,286 @@
1import React, { Component } from 'react';
2import marked from 'marked';
3import PropTypes from 'prop-types';
4import { inject, observer } from 'mobx-react';
5import { defineMessages, intlShape } from 'react-intl';
6import injectSheet from 'react-jss';
7import { Button } from '@meetfranz/forms';
8
9import { announcementsStore } from '../index';
10import UIStore from '../../../stores/UIStore';
11import { gaEvent } from '../../../lib/analytics';
12
13const renderer = new marked.Renderer();
14
15renderer.link = (href, title, text) => `<a target="_blank" href="${href}" title="${title}">${text}</a>`;
16
17const markedOptions = { sanitize: true, renderer };
18
19const messages = defineMessages({
20 headline: {
21 id: 'feature.announcements.changelog.headline',
22 defaultMessage: '!!!Changes in Franz {version}',
23 },
24});
25
26const smallScreen = '1000px';
27
28const styles = theme => ({
29 container: {
30 background: theme.colorBackground,
31 position: 'absolute',
32 top: 0,
33 zIndex: 140,
34 width: '100%',
35 height: '100%',
36 overflowY: 'auto',
37 },
38 headline: {
39 color: theme.colorHeadline,
40 margin: [25, 0, 40],
41 // 'max-width': 500,
42 'text-align': 'center',
43 'line-height': '1.3em',
44 },
45 announcement: {
46 height: 'auto',
47
48 [`@media(min-width: ${smallScreen})`]: {
49 display: 'flex',
50 flexDirection: 'column',
51 justifyContent: 'center',
52 height: '100vh',
53 },
54 },
55 main: {
56 display: 'flex',
57 flexDirection: 'column',
58 flexGrow: 1,
59 justifyContent: 'center',
60
61 '& h1': {
62 margin: [40, 0, 15],
63 fontSize: 70,
64 color: theme.styleTypes.primary.accent,
65 textAlign: 'center',
66
67 [`@media(min-width: ${smallScreen})`]: {
68 marginTop: 0,
69 },
70 },
71 '& h2': {
72 fontSize: 30,
73 fontWeight: 300,
74 color: theme.colorText,
75 textAlign: 'center',
76 marginBottom: 60,
77 },
78 },
79 mainBody: {
80 display: 'flex',
81 flexDirection: 'column',
82 alignItems: 'center',
83 width: 'calc(100% - 80px)',
84 height: 'auto',
85 margin: '0 auto',
86 [`@media(min-width: ${smallScreen})`]: {
87 flexDirection: 'row',
88 justifyContent: 'center',
89 },
90 },
91 mainImage: {
92 minWidth: 250,
93 maxWidth: 400,
94 margin: '0 auto',
95 marginBottom: 40,
96 '& img': {
97 width: '100%',
98 },
99 [`@media(min-width: ${smallScreen})`]: {
100 margin: 0,
101 },
102 },
103 mainText: {
104 height: 'auto',
105 maxWidth: 600,
106 textAlign: 'center',
107 '& p': {
108 lineHeight: '1.5em',
109 },
110 [`@media(min-width: ${smallScreen})`]: {
111 textAlign: 'left',
112 },
113 },
114 mainCtaButton: {
115 textAlign: 'center',
116 marginTop: 40,
117 [`@media(min-width: ${smallScreen})`]: {
118 textAlign: 'left',
119 },
120 },
121 spotlight: {
122 height: 'auto',
123 background: theme.announcements.spotlight.background,
124 padding: [40, 0],
125 marginTop: 80,
126 [`@media(min-width: ${smallScreen})`]: {
127 marginTop: 0,
128 justifyContent: 'center',
129 alignItems: 'flex-start',
130 display: 'flex',
131 flexDirection: 'row',
132 },
133 },
134 spotlightTopicContainer: {
135 textAlign: 'center',
136 marginBottom: 20,
137
138 [`@media(min-width: ${smallScreen})`]: {
139 marginBottom: 0,
140 minWidth: 250,
141 maxWidth: 330,
142 width: '100%',
143 textAlign: 'right',
144 marginRight: 60,
145 },
146 },
147 spotlightContentContainer: {
148 textAlign: 'center',
149 [`@media(min-width: ${smallScreen})`]: {
150 height: 'auto',
151 maxWidth: 600,
152 paddingRight: 40,
153 textAlign: 'left',
154 },
155 '& p': {
156 lineHeight: '1.5em',
157 },
158 },
159 spotlightTopic: {
160 fontSize: 20,
161 marginBottom: 5,
162 letterSpacing: 0,
163 fontWeight: 100,
164 },
165 spotlightSubject: {
166 fontSize: 20,
167 },
168 changelog: {
169 padding: [0, 60],
170 maxWidth: 700,
171 margin: [100, 'auto'],
172 height: 'auto',
173
174 '& h3': {
175 fontSize: '24px',
176 margin: '1.5em 0 1em 0',
177 },
178 '& li': {
179 marginBottom: '1em',
180 lineHeight: '1.4em',
181 },
182 '& div': {
183 height: 'auto',
184 },
185 },
186});
187
188
189@inject('stores', 'actions') @injectSheet(styles) @observer
190class AnnouncementScreen extends Component {
191 static propTypes = {
192 classes: PropTypes.object.isRequired,
193 stores: PropTypes.shape({
194 ui: PropTypes.instanceOf(UIStore).isRequired,
195 }).isRequired,
196 };
197
198 static contextTypes = {
199 intl: intlShape,
200 };
201
202 render() {
203 const { classes, stores } = this.props;
204 const { intl } = this.context;
205 const { changelog, announcement } = announcementsStore;
206 const themeImage = stores.ui.isDarkThemeActive ? 'dark' : 'light';
207 return (
208 <div className={classes.container}>
209 {announcement && (
210 <div className={classes.announcement}>
211 <div className={classes.main}>
212 <h1>{announcement.main.headline}</h1>
213 <h2>{announcement.main.subHeadline}</h2>
214 <div className={classes.mainBody}>
215 <div className={classes.mainImage}>
216 <img
217 src={announcement.main.image[themeImage]}
218 alt=""
219 />
220 </div>
221 <div className={classes.mainText}>
222 <div
223 dangerouslySetInnerHTML={{
224 __html: marked(announcement.main.text, markedOptions),
225 }}
226 />
227 <div className={classes.mainCtaButton}>
228 <Button
229 label={announcement.main.cta.label}
230 onClick={() => {
231 const { analytics } = announcement.main.cta;
232 window.location.href = `#${announcement.main.cta.href}`;
233 gaEvent(analytics.category, analytics.action, announcement.main.cta.label);
234 }}
235 />
236 </div>
237 </div>
238 </div>
239 </div>
240 {announcement.spotlight && (
241 <div className={classes.spotlight}>
242 <div className={classes.spotlightTopicContainer}>
243 <h2 className={classes.spotlightTopic}>{announcement.spotlight.title}</h2>
244 <h3 className={classes.spotlightSubject}>{announcement.spotlight.subject}</h3>
245 </div>
246 <div className={classes.spotlightContentContainer}>
247 <div
248 dangerouslySetInnerHTML={{
249 __html: marked(announcement.spotlight.text, markedOptions),
250 }}
251 />
252 <div className={classes.mainCtaButton}>
253 <Button
254 label={announcement.spotlight.cta.label}
255 onClick={() => {
256 const { analytics } = announcement.spotlight.cta;
257 window.location.href = `#${announcement.spotlight.cta.href}`;
258 gaEvent(analytics.category, analytics.action, announcement.spotlight.cta.label);
259 }}
260 />
261 </div>
262 </div>
263 </div>
264 )}
265 </div>
266 )}
267 {changelog && (
268 <div className={classes.changelog}>
269 <h1 className={classes.headline}>
270 {intl.formatMessage(messages.headline, {
271 version: announcementsStore.currentVersion,
272 })}
273 </h1>
274 <div
275 dangerouslySetInnerHTML={{
276 __html: marked(changelog, markedOptions),
277 }}
278 />
279 </div>
280 )}
281 </div>
282 );
283 }
284}
285
286export default AnnouncementScreen;
diff --git a/src/features/announcements/index.js b/src/features/announcements/index.js
new file mode 100644
index 000000000..c087689a7
--- /dev/null
+++ b/src/features/announcements/index.js
@@ -0,0 +1,30 @@
1import { reaction } from 'mobx';
2import { AnnouncementsStore } from './store';
3
4const debug = require('debug')('Franz:feature:announcements');
5
6export const announcementsStore = new AnnouncementsStore();
7
8export default function initAnnouncements(stores, actions) {
9 // const { features } = stores;
10
11 // Toggle workspace feature
12 reaction(
13 () => (
14 true
15 // features.features.isAnnouncementsEnabled
16 ),
17 (isEnabled) => {
18 if (isEnabled) {
19 debug('Initializing `announcements` feature');
20 announcementsStore.start(stores, actions);
21 } else if (announcementsStore.isFeatureActive) {
22 debug('Disabling `announcements` feature');
23 announcementsStore.stop();
24 }
25 },
26 {
27 fireImmediately: true,
28 },
29 );
30}
diff --git a/src/features/announcements/store.js b/src/features/announcements/store.js
new file mode 100644
index 000000000..0bebf29fd
--- /dev/null
+++ b/src/features/announcements/store.js
@@ -0,0 +1,128 @@
1import {
2 action,
3 computed,
4 observable,
5 reaction,
6} from 'mobx';
7import semver from 'semver';
8import localStorage from 'mobx-localstorage';
9
10import { FeatureStore } from '../utils/FeatureStore';
11import { getAnnouncementRequest, getChangelogRequest, getCurrentVersionRequest } from './api';
12import { announcementActions } from './actions';
13import { createActionBindings } from '../utils/ActionBinding';
14import { createReactions } from '../../stores/lib/Reaction';
15
16const LOCAL_STORAGE_KEY = 'announcements';
17
18const debug = require('debug')('Franz:feature:announcements:store');
19
20export class AnnouncementsStore extends FeatureStore {
21 @observable targetVersion = null;
22
23 @observable isAnnouncementVisible = false;
24
25 @observable isFeatureActive = false;
26
27 @computed get changelog() {
28 return getChangelogRequest.result;
29 }
30
31 @computed get announcement() {
32 return getAnnouncementRequest.result;
33 }
34
35 @computed get settings() {
36 return localStorage.getItem(LOCAL_STORAGE_KEY) || {};
37 }
38
39 @computed get lastSeenAnnouncementVersion() {
40 return this.settings.lastSeenAnnouncementVersion || null;
41 }
42
43 @computed get currentVersion() {
44 return getCurrentVersionRequest.result;
45 }
46
47 @computed get isNewUser() {
48 return this.stores.settings.stats.appStarts <= 1;
49 }
50
51 async start(stores, actions) {
52 debug('AnnouncementsStore::start');
53 this.stores = stores;
54 this.actions = actions;
55 getCurrentVersionRequest.execute();
56
57 this._registerActions(createActionBindings([
58 [announcementActions.show, this._showAnnouncement],
59 ]));
60
61 this._reactions = createReactions([
62 this._fetchAnnouncements,
63 this._showAnnouncementToUsersWhoUpdatedApp,
64 ]);
65 this._registerReactions(this._reactions);
66 this.isFeatureActive = true;
67 }
68
69 stop() {
70 super.stop();
71 debug('AnnouncementsStore::stop');
72 this.isFeatureActive = false;
73 this.isAnnouncementVisible = false;
74 }
75
76 // ======= HELPERS ======= //
77
78 _updateSettings = (changes) => {
79 localStorage.setItem(LOCAL_STORAGE_KEY, {
80 ...this.settings,
81 ...changes,
82 });
83 };
84
85 // ======= ACTIONS ======= //
86
87 @action _showAnnouncement = ({ targetVersion } = {}) => {
88 this.targetVersion = targetVersion || this.currentVersion;
89 this.isAnnouncementVisible = true;
90 this.actions.service.blurActive();
91 this._updateSettings({
92 lastSeenAnnouncementVersion: this.currentVersion,
93 });
94 const dispose = reaction(
95 () => this.stores.services.active,
96 () => {
97 this._hideAnnouncement();
98 dispose();
99 },
100 );
101 };
102
103 @action _hideAnnouncement() {
104 this.isAnnouncementVisible = false;
105 }
106
107 // ======= REACTIONS ========
108
109 _showAnnouncementToUsersWhoUpdatedApp = () => {
110 const { announcement, isNewUser } = this;
111 // Check if there is an announcement and on't show announcements to new users
112 if (!announcement || isNewUser) return;
113
114 // Check if the user has already used current version (= has seen the announcement)
115 const { currentVersion, lastSeenAnnouncementVersion } = this;
116 if (semver.gt(currentVersion, lastSeenAnnouncementVersion)) {
117 debug(`${currentVersion} < ${lastSeenAnnouncementVersion}: announcement is shown`);
118 this._showAnnouncement();
119 }
120 };
121
122 _fetchAnnouncements = () => {
123 const targetVersion = this.targetVersion || this.currentVersion;
124 if (!targetVersion) return;
125 getChangelogRequest.execute(targetVersion);
126 getAnnouncementRequest.execute(targetVersion);
127 }
128}
diff --git a/src/features/utils/ActionBinding.js b/src/features/utils/ActionBinding.js
new file mode 100644
index 000000000..497aa071b
--- /dev/null
+++ b/src/features/utils/ActionBinding.js
@@ -0,0 +1,29 @@
1export default class ActionBinding {
2 action;
3
4 isActive = false;
5
6 constructor(action) {
7 this.action = action;
8 }
9
10 start() {
11 if (!this.isActive) {
12 const { action } = this;
13 action[0].listen(action[1]);
14 this.isActive = true;
15 }
16 }
17
18 stop() {
19 if (this.isActive) {
20 const { action } = this;
21 action[0].off(action[1]);
22 this.isActive = false;
23 }
24 }
25}
26
27export const createActionBindings = actions => (
28 actions.map(a => new ActionBinding(a))
29);
diff --git a/src/features/utils/FeatureStore.js b/src/features/utils/FeatureStore.js
index 66b66a104..b6e0fbce3 100644
--- a/src/features/utils/FeatureStore.js
+++ b/src/features/utils/FeatureStore.js
@@ -1,21 +1,42 @@
1import Reaction from '../../stores/lib/Reaction'; 1import { union } from 'lodash';
2 2
3export class FeatureStore { 3export class FeatureStore {
4 _actions = null; 4 _actions = null;
5 5
6 _reactions = null; 6 _reactions = null;
7 7
8 _listenToActions(actions) { 8 stop() {
9 if (this._actions) this._actions.forEach(a => a[0].off(a[1])); 9 this._stopActions();
10 this._actions = []; 10 this._stopReactions();
11 actions.forEach(a => this._actions.push(a));
12 this._actions.forEach(a => a[0].listen(a[1]));
13 } 11 }
14 12
15 _startReactions(reactions) { 13 // ACTIONS
16 if (this._reactions) this._reactions.forEach(r => r.stop()); 14
17 this._reactions = []; 15 _registerActions(actions) {
18 reactions.forEach(r => this._reactions.push(new Reaction(r))); 16 this._actions = union(this._actions, actions);
19 this._reactions.forEach(r => r.start()); 17 this._startActions();
18 }
19
20 _startActions(actions = this._actions) {
21 actions.forEach(a => a.start());
22 }
23
24 _stopActions(actions = this._actions) {
25 actions.forEach(a => a.stop());
26 }
27
28 // REACTIONS
29
30 _registerReactions(reactions) {
31 this._reactions = union(this._reactions, reactions);
32 this._startReactions();
33 }
34
35 _startReactions(reactions = this._reactions) {
36 reactions.forEach(r => r.start());
37 }
38
39 _stopReactions(reactions = this._reactions) {
40 reactions.forEach(r => r.stop());
20 } 41 }
21} 42}
diff --git a/src/features/workspaces/components/CreateWorkspaceForm.js b/src/features/workspaces/components/CreateWorkspaceForm.js
index 2c00ea63c..cddbb2b04 100644
--- a/src/features/workspaces/components/CreateWorkspaceForm.js
+++ b/src/features/workspaces/components/CreateWorkspaceForm.js
@@ -7,7 +7,7 @@ import injectSheet from 'react-jss';
7import Form from '../../../lib/Form'; 7import Form from '../../../lib/Form';
8import { required } from '../../../helpers/validation-helpers'; 8import { required } from '../../../helpers/validation-helpers';
9import { gaEvent } from '../../../lib/analytics'; 9import { gaEvent } from '../../../lib/analytics';
10import { GA_CATEGORY_WORKSPACES } from '../index'; 10import { GA_CATEGORY_WORKSPACES, workspaceStore } from '../index';
11 11
12const messages = defineMessages({ 12const messages = defineMessages({
13 submitButton: { 13 submitButton: {
@@ -82,7 +82,7 @@ class CreateWorkspaceForm extends Component {
82 {...form.$('name').bind()} 82 {...form.$('name').bind()}
83 showLabel={false} 83 showLabel={false}
84 onEnterKey={this.submitForm.bind(this, form)} 84 onEnterKey={this.submitForm.bind(this, form)}
85 focus 85 focus={workspaceStore.isUserAllowedToUseFeature}
86 /> 86 />
87 <Button 87 <Button
88 className={classes.submitButton} 88 className={classes.submitButton}
diff --git a/src/features/workspaces/store.js b/src/features/workspaces/store.js
index ea601700e..e11513d1f 100644
--- a/src/features/workspaces/store.js
+++ b/src/features/workspaces/store.js
@@ -14,6 +14,8 @@ import {
14 updateWorkspaceRequest, 14 updateWorkspaceRequest,
15} from './api'; 15} from './api';
16import { WORKSPACES_ROUTES } from './index'; 16import { WORKSPACES_ROUTES } from './index';
17import { createReactions } from '../../stores/lib/Reaction';
18import { createActionBindings } from '../utils/ActionBinding';
17 19
18const debug = require('debug')('Franz:feature:workspaces:store'); 20const debug = require('debug')('Franz:feature:workspaces:store');
19 21
@@ -51,37 +53,74 @@ export default class WorkspacesStore extends FeatureStore {
51 return getUserWorkspacesRequest.wasExecuted && this.workspaces.length > 0; 53 return getUserWorkspacesRequest.wasExecuted && this.workspaces.length > 0;
52 } 54 }
53 55
56 @computed get isUserAllowedToUseFeature() {
57 return !this.isPremiumUpgradeRequired;
58 }
59
60 // ========== PRIVATE PROPERTIES ========= //
61
62 _wasDrawerOpenBeforeSettingsRoute = null;
63
64 _freeUserActions = [];
65
66 _premiumUserActions = [];
67
68 _allActions = [];
69
70 _freeUserReactions = [];
71
72 _premiumUserReactions = [];
73
74 _allReactions = [];
75
76 // ========== PUBLIC API ========= //
77
54 start(stores, actions) { 78 start(stores, actions) {
55 debug('WorkspacesStore::start'); 79 debug('WorkspacesStore::start');
56 this.stores = stores; 80 this.stores = stores;
57 this.actions = actions; 81 this.actions = actions;
58 82
59 this._listenToActions([ 83 // ACTIONS
84
85 this._freeUserActions = createActionBindings([
86 [workspaceActions.toggleWorkspaceDrawer, this._toggleWorkspaceDrawer],
87 [workspaceActions.openWorkspaceSettings, this._openWorkspaceSettings],
88 ]);
89 this._premiumUserActions = createActionBindings([
60 [workspaceActions.edit, this._edit], 90 [workspaceActions.edit, this._edit],
61 [workspaceActions.create, this._create], 91 [workspaceActions.create, this._create],
62 [workspaceActions.delete, this._delete], 92 [workspaceActions.delete, this._delete],
63 [workspaceActions.update, this._update], 93 [workspaceActions.update, this._update],
64 [workspaceActions.activate, this._setActiveWorkspace], 94 [workspaceActions.activate, this._setActiveWorkspace],
65 [workspaceActions.deactivate, this._deactivateActiveWorkspace], 95 [workspaceActions.deactivate, this._deactivateActiveWorkspace],
66 [workspaceActions.toggleWorkspaceDrawer, this._toggleWorkspaceDrawer],
67 [workspaceActions.openWorkspaceSettings, this._openWorkspaceSettings],
68 ]); 96 ]);
97 this._allActions = this._freeUserActions.concat(this._premiumUserActions);
98 this._registerActions(this._allActions);
69 99
70 this._startReactions([ 100 // REACTIONS
71 this._setWorkspaceBeingEditedReaction, 101
72 this._setActiveServiceOnWorkspaceSwitchReaction, 102 this._freeUserReactions = createReactions([
103 this._stopPremiumActionsAndReactions,
104 this._openDrawerWithSettingsReaction,
73 this._setFeatureEnabledReaction, 105 this._setFeatureEnabledReaction,
74 this._setIsPremiumFeatureReaction, 106 this._setIsPremiumFeatureReaction,
75 this._activateLastUsedWorkspaceReaction,
76 this._openDrawerWithSettingsReaction,
77 this._cleanupInvalidServiceReferences, 107 this._cleanupInvalidServiceReferences,
78 ]); 108 ]);
109 this._premiumUserReactions = createReactions([
110 this._setActiveServiceOnWorkspaceSwitchReaction,
111 this._activateLastUsedWorkspaceReaction,
112 this._setWorkspaceBeingEditedReaction,
113 ]);
114 this._allReactions = this._freeUserReactions.concat(this._premiumUserReactions);
115
116 this._registerReactions(this._allReactions);
79 117
80 getUserWorkspacesRequest.execute(); 118 getUserWorkspacesRequest.execute();
81 this.isFeatureActive = true; 119 this.isFeatureActive = true;
82 } 120 }
83 121
84 stop() { 122 stop() {
123 super.stop();
85 debug('WorkspacesStore::stop'); 124 debug('WorkspacesStore::stop');
86 this.isFeatureActive = false; 125 this.isFeatureActive = false;
87 this.activeWorkspace = null; 126 this.activeWorkspace = null;
@@ -104,9 +143,7 @@ export default class WorkspacesStore extends FeatureStore {
104 return workspace.services.map(id => services.one(id)).filter(s => !!s); 143 return workspace.services.map(id => services.one(id)).filter(s => !!s);
105 } 144 }
106 145
107 // ========== PRIVATE ========= // 146 // ========== PRIVATE METHODS ========= //
108
109 _wasDrawerOpenBeforeSettingsRoute = null;
110 147
111 _getWorkspaceById = id => this.workspaces.find(w => w.id === id); 148 _getWorkspaceById = id => this.workspaces.find(w => w.id === id);
112 149
@@ -273,4 +310,14 @@ export default class WorkspacesStore extends FeatureStore {
273 getUserWorkspacesRequest.execute(); 310 getUserWorkspacesRequest.execute();
274 } 311 }
275 }; 312 };
313
314 _stopPremiumActionsAndReactions = () => {
315 if (!this.isUserAllowedToUseFeature) {
316 this._stopActions(this._premiumUserActions);
317 this._stopReactions(this._premiumUserReactions);
318 } else {
319 this._startActions(this._premiumUserActions);
320 this._startReactions(this._premiumUserReactions);
321 }
322 }
276} 323}
diff --git a/src/i18n/locales/defaultMessages.json b/src/i18n/locales/defaultMessages.json
deleted file mode 100644
index bb7784257..000000000
--- a/src/i18n/locales/defaultMessages.json
+++ /dev/null
@@ -1,4437 +0,0 @@
1[
2 {
3 "descriptors": [
4 {
5 "defaultMessage": "!!!Import your Franz 4 services",
6 "end": {
7 "column": 3,
8 "line": 16
9 },
10 "file": "src/components/auth/Import.js",
11 "id": "import.headline",
12 "start": {
13 "column": 12,
14 "line": 13
15 }
16 },
17 {
18 "defaultMessage": "!!!Services not yet supported in Franz 5",
19 "end": {
20 "column": 3,
21 "line": 20
22 },
23 "file": "src/components/auth/Import.js",
24 "id": "import.notSupportedHeadline",
25 "start": {
26 "column": 24,
27 "line": 17
28 }
29 },
30 {
31 "defaultMessage": "!!!Import {count} services",
32 "end": {
33 "column": 3,
34 "line": 24
35 },
36 "file": "src/components/auth/Import.js",
37 "id": "import.submit.label",
38 "start": {
39 "column": 21,
40 "line": 21
41 }
42 },
43 {
44 "defaultMessage": "!!!I want to add services manually",
45 "end": {
46 "column": 3,
47 "line": 28
48 },
49 "file": "src/components/auth/Import.js",
50 "id": "import.skip.label",
51 "start": {
52 "column": 19,
53 "line": 25
54 }
55 }
56 ],
57 "path": "src/components/auth/Import.json"
58 },
59 {
60 "descriptors": [
61 {
62 "defaultMessage": "!!!Invite Friends",
63 "end": {
64 "column": 3,
65 "line": 19
66 },
67 "file": "src/components/auth/Invite.js",
68 "id": "settings.invite.headline",
69 "start": {
70 "column": 20,
71 "line": 16
72 }
73 },
74 {
75 "defaultMessage": "!!!Invite 3 of your friends or colleagues",
76 "end": {
77 "column": 3,
78 "line": 23
79 },
80 "file": "src/components/auth/Invite.js",
81 "id": "invite.headline.friends",
82 "start": {
83 "column": 12,
84 "line": 20
85 }
86 },
87 {
88 "defaultMessage": "!!!Name",
89 "end": {
90 "column": 3,
91 "line": 27
92 },
93 "file": "src/components/auth/Invite.js",
94 "id": "invite.name.label",
95 "start": {
96 "column": 13,
97 "line": 24
98 }
99 },
100 {
101 "defaultMessage": "!!!Email address",
102 "end": {
103 "column": 3,
104 "line": 31
105 },
106 "file": "src/components/auth/Invite.js",
107 "id": "invite.email.label",
108 "start": {
109 "column": 14,
110 "line": 28
111 }
112 },
113 {
114 "defaultMessage": "!!!Send invites",
115 "end": {
116 "column": 3,
117 "line": 35
118 },
119 "file": "src/components/auth/Invite.js",
120 "id": "invite.submit.label",
121 "start": {
122 "column": 21,
123 "line": 32
124 }
125 },
126 {
127 "defaultMessage": "!!!I want to do this later",
128 "end": {
129 "column": 3,
130 "line": 39
131 },
132 "file": "src/components/auth/Invite.js",
133 "id": "invite.skip.label",
134 "start": {
135 "column": 19,
136 "line": 36
137 }
138 },
139 {
140 "defaultMessage": "!!!Invitations sent successfully",
141 "end": {
142 "column": 3,
143 "line": 43
144 },
145 "file": "src/components/auth/Invite.js",
146 "id": "invite.successInfo",
147 "start": {
148 "column": 21,
149 "line": 40
150 }
151 }
152 ],
153 "path": "src/components/auth/Invite.json"
154 },
155 {
156 "descriptors": [
157 {
158 "defaultMessage": "!!!Sign in",
159 "end": {
160 "column": 3,
161 "line": 20
162 },
163 "file": "src/components/auth/Login.js",
164 "id": "login.headline",
165 "start": {
166 "column": 12,
167 "line": 17
168 }
169 },
170 {
171 "defaultMessage": "!!!Email address",
172 "end": {
173 "column": 3,
174 "line": 24
175 },
176 "file": "src/components/auth/Login.js",
177 "id": "login.email.label",
178 "start": {
179 "column": 14,
180 "line": 21
181 }
182 },
183 {
184 "defaultMessage": "!!!Password",
185 "end": {
186 "column": 3,
187 "line": 28
188 },
189 "file": "src/components/auth/Login.js",
190 "id": "login.password.label",
191 "start": {
192 "column": 17,
193 "line": 25
194 }
195 },
196 {
197 "defaultMessage": "!!!Sign in",
198 "end": {
199 "column": 3,
200 "line": 32
201 },
202 "file": "src/components/auth/Login.js",
203 "id": "login.submit.label",
204 "start": {
205 "column": 21,
206 "line": 29
207 }
208 },
209 {
210 "defaultMessage": "!!!Email or password not valid",
211 "end": {
212 "column": 3,
213 "line": 36
214 },
215 "file": "src/components/auth/Login.js",
216 "id": "login.invalidCredentials",
217 "start": {
218 "column": 22,
219 "line": 33
220 }
221 },
222 {
223 "defaultMessage": "!!!Your session expired, please login again.",
224 "end": {
225 "column": 3,
226 "line": 40
227 },
228 "file": "src/components/auth/Login.js",
229 "id": "login.tokenExpired",
230 "start": {
231 "column": 16,
232 "line": 37
233 }
234 },
235 {
236 "defaultMessage": "!!!Your session expired, please login again.",
237 "end": {
238 "column": 3,
239 "line": 44
240 },
241 "file": "src/components/auth/Login.js",
242 "id": "login.serverLogout",
243 "start": {
244 "column": 16,
245 "line": 41
246 }
247 },
248 {
249 "defaultMessage": "!!!Create a free account",
250 "end": {
251 "column": 3,
252 "line": 48
253 },
254 "file": "src/components/auth/Login.js",
255 "id": "login.link.signup",
256 "start": {
257 "column": 14,
258 "line": 45
259 }
260 },
261 {
262 "defaultMessage": "!!!Forgot password",
263 "end": {
264 "column": 3,
265 "line": 52
266 },
267 "file": "src/components/auth/Login.js",
268 "id": "login.link.password",
269 "start": {
270 "column": 16,
271 "line": 49
272 }
273 }
274 ],
275 "path": "src/components/auth/Login.json"
276 },
277 {
278 "descriptors": [
279 {
280 "defaultMessage": "!!!Forgot password",
281 "end": {
282 "column": 3,
283 "line": 17
284 },
285 "file": "src/components/auth/Password.js",
286 "id": "password.headline",
287 "start": {
288 "column": 12,
289 "line": 14
290 }
291 },
292 {
293 "defaultMessage": "!!!Email address",
294 "end": {
295 "column": 3,
296 "line": 21
297 },
298 "file": "src/components/auth/Password.js",
299 "id": "password.email.label",
300 "start": {
301 "column": 14,
302 "line": 18
303 }
304 },
305 {
306 "defaultMessage": "!!!Submit",
307 "end": {
308 "column": 3,
309 "line": 25
310 },
311 "file": "src/components/auth/Password.js",
312 "id": "password.submit.label",
313 "start": {
314 "column": 21,
315 "line": 22
316 }
317 },
318 {
319 "defaultMessage": "!!!Your new password was sent to your email address",
320 "end": {
321 "column": 3,
322 "line": 29
323 },
324 "file": "src/components/auth/Password.js",
325 "id": "password.successInfo",
326 "start": {
327 "column": 15,
328 "line": 26
329 }
330 },
331 {
332 "defaultMessage": "!!!No user affiliated with that email address",
333 "end": {
334 "column": 3,
335 "line": 33
336 },
337 "file": "src/components/auth/Password.js",
338 "id": "password.noUser",
339 "start": {
340 "column": 10,
341 "line": 30
342 }
343 },
344 {
345 "defaultMessage": "!!!Create a free account",
346 "end": {
347 "column": 3,
348 "line": 37
349 },
350 "file": "src/components/auth/Password.js",
351 "id": "password.link.signup",
352 "start": {
353 "column": 14,
354 "line": 34
355 }
356 },
357 {
358 "defaultMessage": "!!!Sign in to your account",
359 "end": {
360 "column": 3,
361 "line": 41
362 },
363 "file": "src/components/auth/Password.js",
364 "id": "password.link.login",
365 "start": {
366 "column": 13,
367 "line": 38
368 }
369 }
370 ],
371 "path": "src/components/auth/Password.json"
372 },
373 {
374 "descriptors": [
375 {
376 "defaultMessage": "!!!Support Franz",
377 "end": {
378 "column": 3,
379 "line": 16
380 },
381 "file": "src/components/auth/Pricing.js",
382 "id": "pricing.headline",
383 "start": {
384 "column": 12,
385 "line": 13
386 }
387 },
388 {
389 "defaultMessage": "!!!Select your support plan",
390 "end": {
391 "column": 3,
392 "line": 20
393 },
394 "file": "src/components/auth/Pricing.js",
395 "id": "pricing.support.label",
396 "start": {
397 "column": 23,
398 "line": 17
399 }
400 },
401 {
402 "defaultMessage": "!!!Support the development of Franz",
403 "end": {
404 "column": 3,
405 "line": 24
406 },
407 "file": "src/components/auth/Pricing.js",
408 "id": "pricing.submit.label",
409 "start": {
410 "column": 21,
411 "line": 21
412 }
413 },
414 {
415 "defaultMessage": "!!!I don't want to support the development of Franz.",
416 "end": {
417 "column": 3,
418 "line": 28
419 },
420 "file": "src/components/auth/Pricing.js",
421 "id": "pricing.link.skipPayment",
422 "start": {
423 "column": 15,
424 "line": 25
425 }
426 }
427 ],
428 "path": "src/components/auth/Pricing.json"
429 },
430 {
431 "descriptors": [
432 {
433 "defaultMessage": "!!!Sign up",
434 "end": {
435 "column": 3,
436 "line": 21
437 },
438 "file": "src/components/auth/Signup.js",
439 "id": "signup.headline",
440 "start": {
441 "column": 12,
442 "line": 18
443 }
444 },
445 {
446 "defaultMessage": "!!!Firstname",
447 "end": {
448 "column": 3,
449 "line": 25
450 },
451 "file": "src/components/auth/Signup.js",
452 "id": "signup.firstname.label",
453 "start": {
454 "column": 18,
455 "line": 22
456 }
457 },
458 {
459 "defaultMessage": "!!!Lastname",
460 "end": {
461 "column": 3,
462 "line": 29
463 },
464 "file": "src/components/auth/Signup.js",
465 "id": "signup.lastname.label",
466 "start": {
467 "column": 17,
468 "line": 26
469 }
470 },
471 {
472 "defaultMessage": "!!!Email address",
473 "end": {
474 "column": 3,
475 "line": 33
476 },
477 "file": "src/components/auth/Signup.js",
478 "id": "signup.email.label",
479 "start": {
480 "column": 14,
481 "line": 30
482 }
483 },
484 {
485 "defaultMessage": "!!!Company",
486 "end": {
487 "column": 3,
488 "line": 37
489 },
490 "file": "src/components/auth/Signup.js",
491 "id": "signup.company.label",
492 "start": {
493 "column": 16,
494 "line": 34
495 }
496 },
497 {
498 "defaultMessage": "!!!Password",
499 "end": {
500 "column": 3,
501 "line": 41
502 },
503 "file": "src/components/auth/Signup.js",
504 "id": "signup.password.label",
505 "start": {
506 "column": 17,
507 "line": 38
508 }
509 },
510 {
511 "defaultMessage": "!!!By creating a Franz account you accept the",
512 "end": {
513 "column": 3,
514 "line": 45
515 },
516 "file": "src/components/auth/Signup.js",
517 "id": "signup.legal.info",
518 "start": {
519 "column": 13,
520 "line": 42
521 }
522 },
523 {
524 "defaultMessage": "!!!Terms of service",
525 "end": {
526 "column": 3,
527 "line": 49
528 },
529 "file": "src/components/auth/Signup.js",
530 "id": "signup.legal.terms",
531 "start": {
532 "column": 9,
533 "line": 46
534 }
535 },
536 {
537 "defaultMessage": "!!!Privacy Statement",
538 "end": {
539 "column": 3,
540 "line": 53
541 },
542 "file": "src/components/auth/Signup.js",
543 "id": "signup.legal.privacy",
544 "start": {
545 "column": 11,
546 "line": 50
547 }
548 },
549 {
550 "defaultMessage": "!!!Create account",
551 "end": {
552 "column": 3,
553 "line": 57
554 },
555 "file": "src/components/auth/Signup.js",
556 "id": "signup.submit.label",
557 "start": {
558 "column": 21,
559 "line": 54
560 }
561 },
562 {
563 "defaultMessage": "!!!Already have an account, sign in?",
564 "end": {
565 "column": 3,
566 "line": 61
567 },
568 "file": "src/components/auth/Signup.js",
569 "id": "signup.link.login",
570 "start": {
571 "column": 13,
572 "line": 58
573 }
574 },
575 {
576 "defaultMessage": "!!!A user with that email address already exists",
577 "end": {
578 "column": 3,
579 "line": 65
580 },
581 "file": "src/components/auth/Signup.js",
582 "id": "signup.emailDuplicate",
583 "start": {
584 "column": 18,
585 "line": 62
586 }
587 }
588 ],
589 "path": "src/components/auth/Signup.json"
590 },
591 {
592 "descriptors": [
593 {
594 "defaultMessage": "!!!Create a free account",
595 "end": {
596 "column": 3,
597 "line": 12
598 },
599 "file": "src/components/auth/Welcome.js",
600 "id": "welcome.signupButton",
601 "start": {
602 "column": 16,
603 "line": 9
604 }
605 },
606 {
607 "defaultMessage": "!!!Login to your account",
608 "end": {
609 "column": 3,
610 "line": 16
611 },
612 "file": "src/components/auth/Welcome.js",
613 "id": "welcome.loginButton",
614 "start": {
615 "column": 15,
616 "line": 13
617 }
618 }
619 ],
620 "path": "src/components/auth/Welcome.json"
621 },
622 {
623 "descriptors": [
624 {
625 "defaultMessage": "!!!Your services have been updated.",
626 "end": {
627 "column": 3,
628 "line": 28
629 },
630 "file": "src/components/layout/AppLayout.js",
631 "id": "infobar.servicesUpdated",
632 "start": {
633 "column": 19,
634 "line": 25
635 }
636 },
637 {
638 "defaultMessage": "!!!A new update for Franz is available.",
639 "end": {
640 "column": 3,
641 "line": 32
642 },
643 "file": "src/components/layout/AppLayout.js",
644 "id": "infobar.updateAvailable",
645 "start": {
646 "column": 19,
647 "line": 29
648 }
649 },
650 {
651 "defaultMessage": "!!!Reload services",
652 "end": {
653 "column": 3,
654 "line": 36
655 },
656 "file": "src/components/layout/AppLayout.js",
657 "id": "infobar.buttonReloadServices",
658 "start": {
659 "column": 24,
660 "line": 33
661 }
662 },
663 {
664 "defaultMessage": "!!!Changelog",
665 "end": {
666 "column": 3,
667 "line": 40
668 },
669 "file": "src/components/layout/AppLayout.js",
670 "id": "infobar.buttonChangelog",
671 "start": {
672 "column": 13,
673 "line": 37
674 }
675 },
676 {
677 "defaultMessage": "!!!Restart & install update",
678 "end": {
679 "column": 3,
680 "line": 44
681 },
682 "file": "src/components/layout/AppLayout.js",
683 "id": "infobar.buttonInstallUpdate",
684 "start": {
685 "column": 23,
686 "line": 41
687 }
688 },
689 {
690 "defaultMessage": "!!!Could not load services and user information",
691 "end": {
692 "column": 3,
693 "line": 48
694 },
695 "file": "src/components/layout/AppLayout.js",
696 "id": "infobar.requiredRequestsFailed",
697 "start": {
698 "column": 26,
699 "line": 45
700 }
701 }
702 ],
703 "path": "src/components/layout/AppLayout.json"
704 },
705 {
706 "descriptors": [
707 {
708 "defaultMessage": "!!!Settings",
709 "end": {
710 "column": 3,
711 "line": 16
712 },
713 "file": "src/components/layout/Sidebar.js",
714 "id": "sidebar.settings",
715 "start": {
716 "column": 12,
717 "line": 13
718 }
719 },
720 {
721 "defaultMessage": "!!!Add new service",
722 "end": {
723 "column": 3,
724 "line": 20
725 },
726 "file": "src/components/layout/Sidebar.js",
727 "id": "sidebar.addNewService",
728 "start": {
729 "column": 17,
730 "line": 17
731 }
732 },
733 {
734 "defaultMessage": "!!!Disable notifications & audio",
735 "end": {
736 "column": 3,
737 "line": 24
738 },
739 "file": "src/components/layout/Sidebar.js",
740 "id": "sidebar.muteApp",
741 "start": {
742 "column": 8,
743 "line": 21
744 }
745 },
746 {
747 "defaultMessage": "!!!Enable notifications & audio",
748 "end": {
749 "column": 3,
750 "line": 28
751 },
752 "file": "src/components/layout/Sidebar.js",
753 "id": "sidebar.unmuteApp",
754 "start": {
755 "column": 10,
756 "line": 25
757 }
758 },
759 {
760 "defaultMessage": "!!!Open workspace drawer",
761 "end": {
762 "column": 3,
763 "line": 32
764 },
765 "file": "src/components/layout/Sidebar.js",
766 "id": "sidebar.openWorkspaceDrawer",
767 "start": {
768 "column": 23,
769 "line": 29
770 }
771 },
772 {
773 "defaultMessage": "!!!Close workspace drawer",
774 "end": {
775 "column": 3,
776 "line": 36
777 },
778 "file": "src/components/layout/Sidebar.js",
779 "id": "sidebar.closeWorkspaceDrawer",
780 "start": {
781 "column": 24,
782 "line": 33
783 }
784 }
785 ],
786 "path": "src/components/layout/Sidebar.json"
787 },
788 {
789 "descriptors": [
790 {
791 "defaultMessage": "!!!Oh no!",
792 "end": {
793 "column": 3,
794 "line": 15
795 },
796 "file": "src/components/services/content/ErrorHandlers/WebviewErrorHandler.js",
797 "id": "service.errorHandler.headline",
798 "start": {
799 "column": 12,
800 "line": 12
801 }
802 },
803 {
804 "defaultMessage": "!!!{name} has failed to load.",
805 "end": {
806 "column": 3,
807 "line": 19
808 },
809 "file": "src/components/services/content/ErrorHandlers/WebviewErrorHandler.js",
810 "id": "service.errorHandler.text",
811 "start": {
812 "column": 8,
813 "line": 16
814 }
815 },
816 {
817 "defaultMessage": "!!!Reload {name}",
818 "end": {
819 "column": 3,
820 "line": 23
821 },
822 "file": "src/components/services/content/ErrorHandlers/WebviewErrorHandler.js",
823 "id": "service.errorHandler.action",
824 "start": {
825 "column": 10,
826 "line": 20
827 }
828 },
829 {
830 "defaultMessage": "!!!Edit {name}",
831 "end": {
832 "column": 3,
833 "line": 27
834 },
835 "file": "src/components/services/content/ErrorHandlers/WebviewErrorHandler.js",
836 "id": "service.errorHandler.editAction",
837 "start": {
838 "column": 14,
839 "line": 24
840 }
841 },
842 {
843 "defaultMessage": "!!!Error:",
844 "end": {
845 "column": 3,
846 "line": 31
847 },
848 "file": "src/components/services/content/ErrorHandlers/WebviewErrorHandler.js",
849 "id": "service.errorHandler.message",
850 "start": {
851 "column": 16,
852 "line": 28
853 }
854 }
855 ],
856 "path": "src/components/services/content/ErrorHandlers/WebviewErrorHandler.json"
857 },
858 {
859 "descriptors": [
860 {
861 "defaultMessage": "!!!{name} is disabled",
862 "end": {
863 "column": 3,
864 "line": 12
865 },
866 "file": "src/components/services/content/ServiceDisabled.js",
867 "id": "service.disabledHandler.headline",
868 "start": {
869 "column": 12,
870 "line": 9
871 }
872 },
873 {
874 "defaultMessage": "!!!Enable {name}",
875 "end": {
876 "column": 3,
877 "line": 16
878 },
879 "file": "src/components/services/content/ServiceDisabled.js",
880 "id": "service.disabledHandler.action",
881 "start": {
882 "column": 10,
883 "line": 13
884 }
885 }
886 ],
887 "path": "src/components/services/content/ServiceDisabled.json"
888 },
889 {
890 "descriptors": [
891 {
892 "defaultMessage": "!!!Welcome to Franz",
893 "end": {
894 "column": 3,
895 "line": 14
896 },
897 "file": "src/components/services/content/Services.js",
898 "id": "services.welcome",
899 "start": {
900 "column": 11,
901 "line": 11
902 }
903 },
904 {
905 "defaultMessage": "!!!Get started",
906 "end": {
907 "column": 3,
908 "line": 18
909 },
910 "file": "src/components/services/content/Services.js",
911 "id": "services.getStarted",
912 "start": {
913 "column": 14,
914 "line": 15
915 }
916 }
917 ],
918 "path": "src/components/services/content/Services.json"
919 },
920 {
921 "descriptors": [
922 {
923 "defaultMessage": "!!!Oh no!",
924 "end": {
925 "column": 3,
926 "line": 13
927 },
928 "file": "src/components/services/content/WebviewCrashHandler.js",
929 "id": "service.crashHandler.headline",
930 "start": {
931 "column": 12,
932 "line": 10
933 }
934 },
935 {
936 "defaultMessage": "!!!{name} has caused an error.",
937 "end": {
938 "column": 3,
939 "line": 17
940 },
941 "file": "src/components/services/content/WebviewCrashHandler.js",
942 "id": "service.crashHandler.text",
943 "start": {
944 "column": 8,
945 "line": 14
946 }
947 },
948 {
949 "defaultMessage": "!!!Reload {name}",
950 "end": {
951 "column": 3,
952 "line": 21
953 },
954 "file": "src/components/services/content/WebviewCrashHandler.js",
955 "id": "service.crashHandler.action",
956 "start": {
957 "column": 10,
958 "line": 18
959 }
960 },
961 {
962 "defaultMessage": "!!!Trying to automatically restore {name} in {seconds} seconds",
963 "end": {
964 "column": 3,
965 "line": 25
966 },
967 "file": "src/components/services/content/WebviewCrashHandler.js",
968 "id": "service.crashHandler.autoReload",
969 "start": {
970 "column": 14,
971 "line": 22
972 }
973 }
974 ],
975 "path": "src/components/services/content/WebviewCrashHandler.json"
976 },
977 {
978 "descriptors": [
979 {
980 "defaultMessage": "!!!Reload",
981 "end": {
982 "column": 3,
983 "line": 18
984 },
985 "file": "src/components/services/tabs/TabItem.js",
986 "id": "tabs.item.reload",
987 "start": {
988 "column": 10,
989 "line": 15
990 }
991 },
992 {
993 "defaultMessage": "!!!Edit",
994 "end": {
995 "column": 3,
996 "line": 22
997 },
998 "file": "src/components/services/tabs/TabItem.js",
999 "id": "tabs.item.edit",
1000 "start": {
1001 "column": 8,
1002 "line": 19
1003 }
1004 },
1005 {
1006 "defaultMessage": "!!!Disable notifications",
1007 "end": {
1008 "column": 3,
1009 "line": 26
1010 },
1011 "file": "src/components/services/tabs/TabItem.js",
1012 "id": "tabs.item.disableNotifications",
1013 "start": {
1014 "column": 24,
1015 "line": 23
1016 }
1017 },
1018 {
1019 "defaultMessage": "!!!Enable notifications",
1020 "end": {
1021 "column": 3,
1022 "line": 30
1023 },
1024 "file": "src/components/services/tabs/TabItem.js",
1025 "id": "tabs.item.enableNotification",
1026 "start": {
1027 "column": 23,
1028 "line": 27
1029 }
1030 },
1031 {
1032 "defaultMessage": "!!!Disable audio",
1033 "end": {
1034 "column": 3,
1035 "line": 34
1036 },
1037 "file": "src/components/services/tabs/TabItem.js",
1038 "id": "tabs.item.disableAudio",
1039 "start": {
1040 "column": 16,
1041 "line": 31
1042 }
1043 },
1044 {
1045 "defaultMessage": "!!!Enable audio",
1046 "end": {
1047 "column": 3,
1048 "line": 38
1049 },
1050 "file": "src/components/services/tabs/TabItem.js",
1051 "id": "tabs.item.enableAudio",
1052 "start": {
1053 "column": 15,
1054 "line": 35
1055 }
1056 },
1057 {
1058 "defaultMessage": "!!!Disable Service",
1059 "end": {
1060 "column": 3,
1061 "line": 42
1062 },
1063 "file": "src/components/services/tabs/TabItem.js",
1064 "id": "tabs.item.disableService",
1065 "start": {
1066 "column": 18,
1067 "line": 39
1068 }
1069 },
1070 {
1071 "defaultMessage": "!!!Enable Service",
1072 "end": {
1073 "column": 3,
1074 "line": 46
1075 },
1076 "file": "src/components/services/tabs/TabItem.js",
1077 "id": "tabs.item.enableService",
1078 "start": {
1079 "column": 17,
1080 "line": 43
1081 }
1082 },
1083 {
1084 "defaultMessage": "!!!Delete Service",
1085 "end": {
1086 "column": 3,
1087 "line": 50
1088 },
1089 "file": "src/components/services/tabs/TabItem.js",
1090 "id": "tabs.item.deleteService",
1091 "start": {
1092 "column": 17,
1093 "line": 47
1094 }
1095 }
1096 ],
1097 "path": "src/components/services/tabs/TabItem.json"
1098 },
1099 {
1100 "descriptors": [
1101 {
1102 "defaultMessage": "!!!Account",
1103 "end": {
1104 "column": 3,
1105 "line": 18
1106 },
1107 "file": "src/components/settings/account/AccountDashboard.js",
1108 "id": "settings.account.headline",
1109 "start": {
1110 "column": 12,
1111 "line": 15
1112 }
1113 },
1114 {
1115 "defaultMessage": "!!!Your Subscription",
1116 "end": {
1117 "column": 3,
1118 "line": 22
1119 },
1120 "file": "src/components/settings/account/AccountDashboard.js",
1121 "id": "settings.account.headlineSubscription",
1122 "start": {
1123 "column": 24,
1124 "line": 19
1125 }
1126 },
1127 {
1128 "defaultMessage": "!!!Upgrade your Account",
1129 "end": {
1130 "column": 3,
1131 "line": 26
1132 },
1133 "file": "src/components/settings/account/AccountDashboard.js",
1134 "id": "settings.account.headlineUpgrade",
1135 "start": {
1136 "column": 19,
1137 "line": 23
1138 }
1139 },
1140 {
1141 "defaultMessage": "!!Invoices",
1142 "end": {
1143 "column": 3,
1144 "line": 30
1145 },
1146 "file": "src/components/settings/account/AccountDashboard.js",
1147 "id": "settings.account.headlineInvoices",
1148 "start": {
1149 "column": 20,
1150 "line": 27
1151 }
1152 },
1153 {
1154 "defaultMessage": "!!Danger Zone",
1155 "end": {
1156 "column": 3,
1157 "line": 34
1158 },
1159 "file": "src/components/settings/account/AccountDashboard.js",
1160 "id": "settings.account.headlineDangerZone",
1161 "start": {
1162 "column": 22,
1163 "line": 31
1164 }
1165 },
1166 {
1167 "defaultMessage": "!!!Manage your subscription",
1168 "end": {
1169 "column": 3,
1170 "line": 38
1171 },
1172 "file": "src/components/settings/account/AccountDashboard.js",
1173 "id": "settings.account.manageSubscription.label",
1174 "start": {
1175 "column": 33,
1176 "line": 35
1177 }
1178 },
1179 {
1180 "defaultMessage": "!!!Basic Account",
1181 "end": {
1182 "column": 3,
1183 "line": 42
1184 },
1185 "file": "src/components/settings/account/AccountDashboard.js",
1186 "id": "settings.account.accountType.basic",
1187 "start": {
1188 "column": 20,
1189 "line": 39
1190 }
1191 },
1192 {
1193 "defaultMessage": "!!!Premium Supporter Account",
1194 "end": {
1195 "column": 3,
1196 "line": 46
1197 },
1198 "file": "src/components/settings/account/AccountDashboard.js",
1199 "id": "settings.account.accountType.premium",
1200 "start": {
1201 "column": 22,
1202 "line": 43
1203 }
1204 },
1205 {
1206 "defaultMessage": "!!!Edit Account",
1207 "end": {
1208 "column": 3,
1209 "line": 50
1210 },
1211 "file": "src/components/settings/account/AccountDashboard.js",
1212 "id": "settings.account.account.editButton",
1213 "start": {
1214 "column": 21,
1215 "line": 47
1216 }
1217 },
1218 {
1219 "defaultMessage": "!!!Download",
1220 "end": {
1221 "column": 3,
1222 "line": 54
1223 },
1224 "file": "src/components/settings/account/AccountDashboard.js",
1225 "id": "settings.account.invoiceDownload",
1226 "start": {
1227 "column": 19,
1228 "line": 51
1229 }
1230 },
1231 {
1232 "defaultMessage": "!!!Could not load user information",
1233 "end": {
1234 "column": 3,
1235 "line": 58
1236 },
1237 "file": "src/components/settings/account/AccountDashboard.js",
1238 "id": "settings.account.userInfoRequestFailed",
1239 "start": {
1240 "column": 25,
1241 "line": 55
1242 }
1243 },
1244 {
1245 "defaultMessage": "!!!Try again",
1246 "end": {
1247 "column": 3,
1248 "line": 62
1249 },
1250 "file": "src/components/settings/account/AccountDashboard.js",
1251 "id": "settings.account.tryReloadUserInfoRequest",
1252 "start": {
1253 "column": 28,
1254 "line": 59
1255 }
1256 },
1257 {
1258 "defaultMessage": "!!!Delete account",
1259 "end": {
1260 "column": 3,
1261 "line": 66
1262 },
1263 "file": "src/components/settings/account/AccountDashboard.js",
1264 "id": "settings.account.deleteAccount",
1265 "start": {
1266 "column": 17,
1267 "line": 63
1268 }
1269 },
1270 {
1271 "defaultMessage": "!!!If you don't need your Franz account any longer, you can delete your account and all related data here.",
1272 "end": {
1273 "column": 3,
1274 "line": 70
1275 },
1276 "file": "src/components/settings/account/AccountDashboard.js",
1277 "id": "settings.account.deleteInfo",
1278 "start": {
1279 "column": 14,
1280 "line": 67
1281 }
1282 },
1283 {
1284 "defaultMessage": "!!!You have received an email with a link to confirm your account deletion. Your account and data cannot be restored!",
1285 "end": {
1286 "column": 3,
1287 "line": 74
1288 },
1289 "file": "src/components/settings/account/AccountDashboard.js",
1290 "id": "settings.account.deleteEmailSent",
1291 "start": {
1292 "column": 19,
1293 "line": 71
1294 }
1295 }
1296 ],
1297 "path": "src/components/settings/account/AccountDashboard.json"
1298 },
1299 {
1300 "descriptors": [
1301 {
1302 "defaultMessage": "!!!Available services",
1303 "end": {
1304 "column": 3,
1305 "line": 15
1306 },
1307 "file": "src/components/settings/navigation/SettingsNavigation.js",
1308 "id": "settings.navigation.availableServices",
1309 "start": {
1310 "column": 21,
1311 "line": 12
1312 }
1313 },
1314 {
1315 "defaultMessage": "!!!Your services",
1316 "end": {
1317 "column": 3,
1318 "line": 19
1319 },
1320 "file": "src/components/settings/navigation/SettingsNavigation.js",
1321 "id": "settings.navigation.yourServices",
1322 "start": {
1323 "column": 16,
1324 "line": 16
1325 }
1326 },
1327 {
1328 "defaultMessage": "!!!Your workspaces",
1329 "end": {
1330 "column": 3,
1331 "line": 23
1332 },
1333 "file": "src/components/settings/navigation/SettingsNavigation.js",
1334 "id": "settings.navigation.yourWorkspaces",
1335 "start": {
1336 "column": 18,
1337 "line": 20
1338 }
1339 },
1340 {
1341 "defaultMessage": "!!!Account",
1342 "end": {
1343 "column": 3,
1344 "line": 27
1345 },
1346 "file": "src/components/settings/navigation/SettingsNavigation.js",
1347 "id": "settings.navigation.account",
1348 "start": {
1349 "column": 11,
1350 "line": 24
1351 }
1352 },
1353 {
1354 "defaultMessage": "!!!Settings",
1355 "end": {
1356 "column": 3,
1357 "line": 31
1358 },
1359 "file": "src/components/settings/navigation/SettingsNavigation.js",
1360 "id": "settings.navigation.settings",
1361 "start": {
1362 "column": 12,
1363 "line": 28
1364 }
1365 },
1366 {
1367 "defaultMessage": "!!!Invite Friends",
1368 "end": {
1369 "column": 3,
1370 "line": 35
1371 },
1372 "file": "src/components/settings/navigation/SettingsNavigation.js",
1373 "id": "settings.navigation.inviteFriends",
1374 "start": {
1375 "column": 17,
1376 "line": 32
1377 }
1378 },
1379 {
1380 "defaultMessage": "!!!Logout",
1381 "end": {
1382 "column": 3,
1383 "line": 39
1384 },
1385 "file": "src/components/settings/navigation/SettingsNavigation.js",
1386 "id": "settings.navigation.logout",
1387 "start": {
1388 "column": 10,
1389 "line": 36
1390 }
1391 }
1392 ],
1393 "path": "src/components/settings/navigation/SettingsNavigation.json"
1394 },
1395 {
1396 "descriptors": [
1397 {
1398 "defaultMessage": "!!!Available Services",
1399 "end": {
1400 "column": 3,
1401 "line": 18
1402 },
1403 "file": "src/components/settings/recipes/RecipesDashboard.js",
1404 "id": "settings.recipes.headline",
1405 "start": {
1406 "column": 12,
1407 "line": 15
1408 }
1409 },
1410 {
1411 "defaultMessage": "!!!Search service",
1412 "end": {
1413 "column": 3,
1414 "line": 22
1415 },
1416 "file": "src/components/settings/recipes/RecipesDashboard.js",
1417 "id": "settings.searchService",
1418 "start": {
1419 "column": 17,
1420 "line": 19
1421 }
1422 },
1423 {
1424 "defaultMessage": "!!!Most popular",
1425 "end": {
1426 "column": 3,
1427 "line": 26
1428 },
1429 "file": "src/components/settings/recipes/RecipesDashboard.js",
1430 "id": "settings.recipes.mostPopular",
1431 "start": {
1432 "column": 22,
1433 "line": 23
1434 }
1435 },
1436 {
1437 "defaultMessage": "!!!All services",
1438 "end": {
1439 "column": 3,
1440 "line": 30
1441 },
1442 "file": "src/components/settings/recipes/RecipesDashboard.js",
1443 "id": "settings.recipes.all",
1444 "start": {
1445 "column": 14,
1446 "line": 27
1447 }
1448 },
1449 {
1450 "defaultMessage": "!!!Development",
1451 "end": {
1452 "column": 3,
1453 "line": 34
1454 },
1455 "file": "src/components/settings/recipes/RecipesDashboard.js",
1456 "id": "settings.recipes.dev",
1457 "start": {
1458 "column": 14,
1459 "line": 31
1460 }
1461 },
1462 {
1463 "defaultMessage": "!!!Sorry, but no service matched your search term.",
1464 "end": {
1465 "column": 3,
1466 "line": 38
1467 },
1468 "file": "src/components/settings/recipes/RecipesDashboard.js",
1469 "id": "settings.recipes.nothingFound",
1470 "start": {
1471 "column": 16,
1472 "line": 35
1473 }
1474 },
1475 {
1476 "defaultMessage": "!!!Service successfully added",
1477 "end": {
1478 "column": 3,
1479 "line": 42
1480 },
1481 "file": "src/components/settings/recipes/RecipesDashboard.js",
1482 "id": "settings.recipes.servicesSuccessfulAddedInfo",
1483 "start": {
1484 "column": 31,
1485 "line": 39
1486 }
1487 },
1488 {
1489 "defaultMessage": "!!!Missing a service?",
1490 "end": {
1491 "column": 3,
1492 "line": 46
1493 },
1494 "file": "src/components/settings/recipes/RecipesDashboard.js",
1495 "id": "settings.recipes.missingService",
1496 "start": {
1497 "column": 18,
1498 "line": 43
1499 }
1500 }
1501 ],
1502 "path": "src/components/settings/recipes/RecipesDashboard.json"
1503 },
1504 {
1505 "descriptors": [
1506 {
1507 "defaultMessage": "!!!Save service",
1508 "end": {
1509 "column": 3,
1510 "line": 25
1511 },
1512 "file": "src/components/settings/services/EditServiceForm.js",
1513 "id": "settings.service.form.saveButton",
1514 "start": {
1515 "column": 15,
1516 "line": 22
1517 }
1518 },
1519 {
1520 "defaultMessage": "!!!Delete Service",
1521 "end": {
1522 "column": 3,
1523 "line": 29
1524 },
1525 "file": "src/components/settings/services/EditServiceForm.js",
1526 "id": "settings.service.form.deleteButton",
1527 "start": {
1528 "column": 17,
1529 "line": 26
1530 }
1531 },
1532 {
1533 "defaultMessage": "!!!Available services",
1534 "end": {
1535 "column": 3,
1536 "line": 33
1537 },
1538 "file": "src/components/settings/services/EditServiceForm.js",
1539 "id": "settings.service.form.availableServices",
1540 "start": {
1541 "column": 21,
1542 "line": 30
1543 }
1544 },
1545 {
1546 "defaultMessage": "!!!Your services",
1547 "end": {
1548 "column": 3,
1549 "line": 37
1550 },
1551 "file": "src/components/settings/services/EditServiceForm.js",
1552 "id": "settings.service.form.yourServices",
1553 "start": {
1554 "column": 16,
1555 "line": 34
1556 }
1557 },
1558 {
1559 "defaultMessage": "!!!Add {name}",
1560 "end": {
1561 "column": 3,
1562 "line": 41
1563 },
1564 "file": "src/components/settings/services/EditServiceForm.js",
1565 "id": "settings.service.form.addServiceHeadline",
1566 "start": {
1567 "column": 22,
1568 "line": 38
1569 }
1570 },
1571 {
1572 "defaultMessage": "!!!Edit {name}",
1573 "end": {
1574 "column": 3,
1575 "line": 45
1576 },
1577 "file": "src/components/settings/services/EditServiceForm.js",
1578 "id": "settings.service.form.editServiceHeadline",
1579 "start": {
1580 "column": 23,
1581 "line": 42
1582 }
1583 },
1584 {
1585 "defaultMessage": "!!!Hosted",
1586 "end": {
1587 "column": 3,
1588 "line": 49
1589 },
1590 "file": "src/components/settings/services/EditServiceForm.js",
1591 "id": "settings.service.form.tabHosted",
1592 "start": {
1593 "column": 13,
1594 "line": 46
1595 }
1596 },
1597 {
1598 "defaultMessage": "!!!Self hosted ⭐️",
1599 "end": {
1600 "column": 3,
1601 "line": 53
1602 },
1603 "file": "src/components/settings/services/EditServiceForm.js",
1604 "id": "settings.service.form.tabOnPremise",
1605 "start": {
1606 "column": 16,
1607 "line": 50
1608 }
1609 },
1610 {
1611 "defaultMessage": "!!!Use the hosted {name} service.",
1612 "end": {
1613 "column": 3,
1614 "line": 57
1615 },
1616 "file": "src/components/settings/services/EditServiceForm.js",
1617 "id": "settings.service.form.useHostedService",
1618 "start": {
1619 "column": 20,
1620 "line": 54
1621 }
1622 },
1623 {
1624 "defaultMessage": "!!!Could not validate custom {name} server.",
1625 "end": {
1626 "column": 3,
1627 "line": 61
1628 },
1629 "file": "src/components/settings/services/EditServiceForm.js",
1630 "id": "settings.service.form.customUrlValidationError",
1631 "start": {
1632 "column": 28,
1633 "line": 58
1634 }
1635 },
1636 {
1637 "defaultMessage": "!!!To add self hosted services, you need a Franz Premium Supporter Account.",
1638 "end": {
1639 "column": 3,
1640 "line": 65
1641 },
1642 "file": "src/components/settings/services/EditServiceForm.js",
1643 "id": "settings.service.form.customUrlPremiumInfo",
1644 "start": {
1645 "column": 24,
1646 "line": 62
1647 }
1648 },
1649 {
1650 "defaultMessage": "!!!Upgrade your account",
1651 "end": {
1652 "column": 3,
1653 "line": 69
1654 },
1655 "file": "src/components/settings/services/EditServiceForm.js",
1656 "id": "settings.service.form.customUrlUpgradeAccount",
1657 "start": {
1658 "column": 27,
1659 "line": 66
1660 }
1661 },
1662 {
1663 "defaultMessage": "!!!You will be notified about all new messages in a channel, not just @username, @channel, @here, ...",
1664 "end": {
1665 "column": 3,
1666 "line": 73
1667 },
1668 "file": "src/components/settings/services/EditServiceForm.js",
1669 "id": "settings.service.form.indirectMessageInfo",
1670 "start": {
1671 "column": 23,
1672 "line": 70
1673 }
1674 },
1675 {
1676 "defaultMessage": "!!!When disabled, all notification sounds and audio playback are muted",
1677 "end": {
1678 "column": 3,
1679 "line": 77
1680 },
1681 "file": "src/components/settings/services/EditServiceForm.js",
1682 "id": "settings.service.form.isMutedInfo",
1683 "start": {
1684 "column": 15,
1685 "line": 74
1686 }
1687 },
1688 {
1689 "defaultMessage": "!!!Notifications",
1690 "end": {
1691 "column": 3,
1692 "line": 81
1693 },
1694 "file": "src/components/settings/services/EditServiceForm.js",
1695 "id": "settings.service.form.headlineNotifications",
1696 "start": {
1697 "column": 25,
1698 "line": 78
1699 }
1700 },
1701 {
1702 "defaultMessage": "!!!Unread message badges",
1703 "end": {
1704 "column": 3,
1705 "line": 85
1706 },
1707 "file": "src/components/settings/services/EditServiceForm.js",
1708 "id": "settings.service.form.headlineBadges",
1709 "start": {
1710 "column": 18,
1711 "line": 82
1712 }
1713 },
1714 {
1715 "defaultMessage": "!!!General",
1716 "end": {
1717 "column": 3,
1718 "line": 89
1719 },
1720 "file": "src/components/settings/services/EditServiceForm.js",
1721 "id": "settings.service.form.headlineGeneral",
1722 "start": {
1723 "column": 19,
1724 "line": 86
1725 }
1726 },
1727 {
1728 "defaultMessage": "!!!Delete",
1729 "end": {
1730 "column": 3,
1731 "line": 93
1732 },
1733 "file": "src/components/settings/services/EditServiceForm.js",
1734 "id": "settings.service.form.iconDelete",
1735 "start": {
1736 "column": 14,
1737 "line": 90
1738 }
1739 },
1740 {
1741 "defaultMessage": "!!!Drop your image, or click here",
1742 "end": {
1743 "column": 3,
1744 "line": 97
1745 },
1746 "file": "src/components/settings/services/EditServiceForm.js",
1747 "id": "settings.service.form.iconUpload",
1748 "start": {
1749 "column": 14,
1750 "line": 94
1751 }
1752 },
1753 {
1754 "defaultMessage": "!!!HTTP/HTTPS Proxy Settings",
1755 "end": {
1756 "column": 3,
1757 "line": 101
1758 },
1759 "file": "src/components/settings/services/EditServiceForm.js",
1760 "id": "settings.service.form.proxy.headline",
1761 "start": {
1762 "column": 17,
1763 "line": 98
1764 }
1765 },
1766 {
1767 "defaultMessage": "!!!Please restart Franz after changing proxy Settings.",
1768 "end": {
1769 "column": 3,
1770 "line": 105
1771 },
1772 "file": "src/components/settings/services/EditServiceForm.js",
1773 "id": "settings.service.form.proxy.restartInfo",
1774 "start": {
1775 "column": 20,
1776 "line": 102
1777 }
1778 },
1779 {
1780 "defaultMessage": "!!!Proxy settings will not be synchronized with the Franz servers.",
1781 "end": {
1782 "column": 3,
1783 "line": 109
1784 },
1785 "file": "src/components/settings/services/EditServiceForm.js",
1786 "id": "settings.service.form.proxy.info",
1787 "start": {
1788 "column": 13,
1789 "line": 106
1790 }
1791 }
1792 ],
1793 "path": "src/components/settings/services/EditServiceForm.json"
1794 },
1795 {
1796 "descriptors": [
1797 {
1798 "defaultMessage": "!!!Error",
1799 "end": {
1800 "column": 3,
1801 "line": 13
1802 },
1803 "file": "src/components/settings/services/ServiceError.js",
1804 "id": "settings.service.error.headline",
1805 "start": {
1806 "column": 12,
1807 "line": 10
1808 }
1809 },
1810 {
1811 "defaultMessage": "!!!Back to services",
1812 "end": {
1813 "column": 3,
1814 "line": 17
1815 },
1816 "file": "src/components/settings/services/ServiceError.js",
1817 "id": "settings.service.error.goBack",
1818 "start": {
1819 "column": 10,
1820 "line": 14
1821 }
1822 },
1823 {
1824 "defaultMessage": "!!!Available services",
1825 "end": {
1826 "column": 3,
1827 "line": 21
1828 },
1829 "file": "src/components/settings/services/ServiceError.js",
1830 "id": "settings.service.form.availableServices",
1831 "start": {
1832 "column": 21,
1833 "line": 18
1834 }
1835 },
1836 {
1837 "defaultMessage": "!!!Could not load service recipe.",
1838 "end": {
1839 "column": 3,
1840 "line": 25
1841 },
1842 "file": "src/components/settings/services/ServiceError.js",
1843 "id": "settings.service.error.message",
1844 "start": {
1845 "column": 16,
1846 "line": 22
1847 }
1848 }
1849 ],
1850 "path": "src/components/settings/services/ServiceError.json"
1851 },
1852 {
1853 "descriptors": [
1854 {
1855 "defaultMessage": "!!!Service is disabled",
1856 "end": {
1857 "column": 3,
1858 "line": 14
1859 },
1860 "file": "src/components/settings/services/ServiceItem.js",
1861 "id": "settings.services.tooltip.isDisabled",
1862 "start": {
1863 "column": 21,
1864 "line": 11
1865 }
1866 },
1867 {
1868 "defaultMessage": "!!!Notifications are disabled",
1869 "end": {
1870 "column": 3,
1871 "line": 18
1872 },
1873 "file": "src/components/settings/services/ServiceItem.js",
1874 "id": "settings.services.tooltip.notificationsDisabled",
1875 "start": {
1876 "column": 32,
1877 "line": 15
1878 }
1879 },
1880 {
1881 "defaultMessage": "!!!All sounds are muted",
1882 "end": {
1883 "column": 3,
1884 "line": 22
1885 },
1886 "file": "src/components/settings/services/ServiceItem.js",
1887 "id": "settings.services.tooltip.isMuted",
1888 "start": {
1889 "column": 18,
1890 "line": 19
1891 }
1892 }
1893 ],
1894 "path": "src/components/settings/services/ServiceItem.json"
1895 },
1896 {
1897 "descriptors": [
1898 {
1899 "defaultMessage": "!!!Your services",
1900 "end": {
1901 "column": 3,
1902 "line": 17
1903 },
1904 "file": "src/components/settings/services/ServicesDashboard.js",
1905 "id": "settings.services.headline",
1906 "start": {
1907 "column": 12,
1908 "line": 14
1909 }
1910 },
1911 {
1912 "defaultMessage": "!!!Search service",
1913 "end": {
1914 "column": 3,
1915 "line": 21
1916 },
1917 "file": "src/components/settings/services/ServicesDashboard.js",
1918 "id": "settings.searchService",
1919 "start": {
1920 "column": 17,
1921 "line": 18
1922 }
1923 },
1924 {
1925 "defaultMessage": "!!!You haven't added any services yet.",
1926 "end": {
1927 "column": 3,
1928 "line": 25
1929 },
1930 "file": "src/components/settings/services/ServicesDashboard.js",
1931 "id": "settings.services.noServicesAdded",
1932 "start": {
1933 "column": 19,
1934 "line": 22
1935 }
1936 },
1937 {
1938 "defaultMessage": "!!!Sorry, but no service matched your search term.",
1939 "end": {
1940 "column": 3,
1941 "line": 29
1942 },
1943 "file": "src/components/settings/services/ServicesDashboard.js",
1944 "id": "settings.recipes.nothingFound",
1945 "start": {
1946 "column": 18,
1947 "line": 26
1948 }
1949 },
1950 {
1951 "defaultMessage": "!!!Discover services",
1952 "end": {
1953 "column": 3,
1954 "line": 33
1955 },
1956 "file": "src/components/settings/services/ServicesDashboard.js",
1957 "id": "settings.services.discoverServices",
1958 "start": {
1959 "column": 20,
1960 "line": 30
1961 }
1962 },
1963 {
1964 "defaultMessage": "!!!Could not load your services",
1965 "end": {
1966 "column": 3,
1967 "line": 37
1968 },
1969 "file": "src/components/settings/services/ServicesDashboard.js",
1970 "id": "settings.services.servicesRequestFailed",
1971 "start": {
1972 "column": 25,
1973 "line": 34
1974 }
1975 },
1976 {
1977 "defaultMessage": "!!!Try again",
1978 "end": {
1979 "column": 3,
1980 "line": 41
1981 },
1982 "file": "src/components/settings/services/ServicesDashboard.js",
1983 "id": "settings.account.tryReloadServices",
1984 "start": {
1985 "column": 21,
1986 "line": 38
1987 }
1988 },
1989 {
1990 "defaultMessage": "!!!Your changes have been saved",
1991 "end": {
1992 "column": 3,
1993 "line": 45
1994 },
1995 "file": "src/components/settings/services/ServicesDashboard.js",
1996 "id": "settings.services.updatedInfo",
1997 "start": {
1998 "column": 15,
1999 "line": 42
2000 }
2001 },
2002 {
2003 "defaultMessage": "!!!Service has been deleted",
2004 "end": {
2005 "column": 3,
2006 "line": 49
2007 },
2008 "file": "src/components/settings/services/ServicesDashboard.js",
2009 "id": "settings.services.deletedInfo",
2010 "start": {
2011 "column": 15,
2012 "line": 46
2013 }
2014 }
2015 ],
2016 "path": "src/components/settings/services/ServicesDashboard.json"
2017 },
2018 {
2019 "descriptors": [
2020 {
2021 "defaultMessage": "!!!Settings",
2022 "end": {
2023 "column": 3,
2024 "line": 19
2025 },
2026 "file": "src/components/settings/settings/EditSettingsForm.js",
2027 "id": "settings.app.headline",
2028 "start": {
2029 "column": 12,
2030 "line": 16
2031 }
2032 },
2033 {
2034 "defaultMessage": "!!!General",
2035 "end": {
2036 "column": 3,
2037 "line": 23
2038 },
2039 "file": "src/components/settings/settings/EditSettingsForm.js",
2040 "id": "settings.app.headlineGeneral",
2041 "start": {
2042 "column": 19,
2043 "line": 20
2044 }
2045 },
2046 {
2047 "defaultMessage": "!!!Language",
2048 "end": {
2049 "column": 3,
2050 "line": 27
2051 },
2052 "file": "src/components/settings/settings/EditSettingsForm.js",
2053 "id": "settings.app.headlineLanguage",
2054 "start": {
2055 "column": 20,
2056 "line": 24
2057 }
2058 },
2059 {
2060 "defaultMessage": "!!!Updates",
2061 "end": {
2062 "column": 3,
2063 "line": 31
2064 },
2065 "file": "src/components/settings/settings/EditSettingsForm.js",
2066 "id": "settings.app.headlineUpdates",
2067 "start": {
2068 "column": 19,
2069 "line": 28
2070 }
2071 },
2072 {
2073 "defaultMessage": "!!!Appearance",
2074 "end": {
2075 "column": 3,
2076 "line": 35
2077 },
2078 "file": "src/components/settings/settings/EditSettingsForm.js",
2079 "id": "settings.app.headlineAppearance",
2080 "start": {
2081 "column": 22,
2082 "line": 32
2083 }
2084 },
2085 {
2086 "defaultMessage": "!!!Advanced",
2087 "end": {
2088 "column": 3,
2089 "line": 39
2090 },
2091 "file": "src/components/settings/settings/EditSettingsForm.js",
2092 "id": "settings.app.headlineAdvanced",
2093 "start": {
2094 "column": 20,
2095 "line": 36
2096 }
2097 },
2098 {
2099 "defaultMessage": "!!!Help us to translate Franz into your language.",
2100 "end": {
2101 "column": 3,
2102 "line": 43
2103 },
2104 "file": "src/components/settings/settings/EditSettingsForm.js",
2105 "id": "settings.app.translationHelp",
2106 "start": {
2107 "column": 19,
2108 "line": 40
2109 }
2110 },
2111 {
2112 "defaultMessage": "!!!Cache",
2113 "end": {
2114 "column": 3,
2115 "line": 47
2116 },
2117 "file": "src/components/settings/settings/EditSettingsForm.js",
2118 "id": "settings.app.subheadlineCache",
2119 "start": {
2120 "column": 20,
2121 "line": 44
2122 }
2123 },
2124 {
2125 "defaultMessage": "!!!Franz cache is currently using {size} of disk space.",
2126 "end": {
2127 "column": 3,
2128 "line": 51
2129 },
2130 "file": "src/components/settings/settings/EditSettingsForm.js",
2131 "id": "settings.app.cacheInfo",
2132 "start": {
2133 "column": 13,
2134 "line": 48
2135 }
2136 },
2137 {
2138 "defaultMessage": "!!!Clear cache",
2139 "end": {
2140 "column": 3,
2141 "line": 55
2142 },
2143 "file": "src/components/settings/settings/EditSettingsForm.js",
2144 "id": "settings.app.buttonClearAllCache",
2145 "start": {
2146 "column": 23,
2147 "line": 52
2148 }
2149 },
2150 {
2151 "defaultMessage": "!!!Check for updates",
2152 "end": {
2153 "column": 3,
2154 "line": 59
2155 },
2156 "file": "src/components/settings/settings/EditSettingsForm.js",
2157 "id": "settings.app.buttonSearchForUpdate",
2158 "start": {
2159 "column": 25,
2160 "line": 56
2161 }
2162 },
2163 {
2164 "defaultMessage": "!!!Restart & install update",
2165 "end": {
2166 "column": 3,
2167 "line": 63
2168 },
2169 "file": "src/components/settings/settings/EditSettingsForm.js",
2170 "id": "settings.app.buttonInstallUpdate",
2171 "start": {
2172 "column": 23,
2173 "line": 60
2174 }
2175 },
2176 {
2177 "defaultMessage": "!!!Is searching for update",
2178 "end": {
2179 "column": 3,
2180 "line": 67
2181 },
2182 "file": "src/components/settings/settings/EditSettingsForm.js",
2183 "id": "settings.app.updateStatusSearching",
2184 "start": {
2185 "column": 25,
2186 "line": 64
2187 }
2188 },
2189 {
2190 "defaultMessage": "!!!Update available, downloading...",
2191 "end": {
2192 "column": 3,
2193 "line": 71
2194 },
2195 "file": "src/components/settings/settings/EditSettingsForm.js",
2196 "id": "settings.app.updateStatusAvailable",
2197 "start": {
2198 "column": 25,
2199 "line": 68
2200 }
2201 },
2202 {
2203 "defaultMessage": "!!!You are using the latest version of Franz",
2204 "end": {
2205 "column": 3,
2206 "line": 75
2207 },
2208 "file": "src/components/settings/settings/EditSettingsForm.js",
2209 "id": "settings.app.updateStatusUpToDate",
2210 "start": {
2211 "column": 24,
2212 "line": 72
2213 }
2214 },
2215 {
2216 "defaultMessage": "!!!Current version:",
2217 "end": {
2218 "column": 3,
2219 "line": 79
2220 },
2221 "file": "src/components/settings/settings/EditSettingsForm.js",
2222 "id": "settings.app.currentVersion",
2223 "start": {
2224 "column": 18,
2225 "line": 76
2226 }
2227 },
2228 {
2229 "defaultMessage": "!!!Changes require restart",
2230 "end": {
2231 "column": 3,
2232 "line": 83
2233 },
2234 "file": "src/components/settings/settings/EditSettingsForm.js",
2235 "id": "settings.app.restartRequired",
2236 "start": {
2237 "column": 29,
2238 "line": 80
2239 }
2240 },
2241 {
2242 "defaultMessage": "!!!Official translations are English & German. All other languages are community based translations.",
2243 "end": {
2244 "column": 3,
2245 "line": 87
2246 },
2247 "file": "src/components/settings/settings/EditSettingsForm.js",
2248 "id": "settings.app.languageDisclaimer",
2249 "start": {
2250 "column": 22,
2251 "line": 84
2252 }
2253 }
2254 ],
2255 "path": "src/components/settings/settings/EditSettingsForm.json"
2256 },
2257 {
2258 "descriptors": [
2259 {
2260 "defaultMessage": "!!!Account",
2261 "end": {
2262 "column": 3,
2263 "line": 18
2264 },
2265 "file": "src/components/settings/user/EditUserForm.js",
2266 "id": "settings.account.headline",
2267 "start": {
2268 "column": 12,
2269 "line": 15
2270 }
2271 },
2272 {
2273 "defaultMessage": "!!!Update Profile",
2274 "end": {
2275 "column": 3,
2276 "line": 22
2277 },
2278 "file": "src/components/settings/user/EditUserForm.js",
2279 "id": "settings.account.headlineProfile",
2280 "start": {
2281 "column": 19,
2282 "line": 19
2283 }
2284 },
2285 {
2286 "defaultMessage": "!!!Account Information",
2287 "end": {
2288 "column": 3,
2289 "line": 26
2290 },
2291 "file": "src/components/settings/user/EditUserForm.js",
2292 "id": "settings.account.headlineAccount",
2293 "start": {
2294 "column": 19,
2295 "line": 23
2296 }
2297 },
2298 {
2299 "defaultMessage": "!!!Change Password",
2300 "end": {
2301 "column": 3,
2302 "line": 30
2303 },
2304 "file": "src/components/settings/user/EditUserForm.js",
2305 "id": "settings.account.headlinePassword",
2306 "start": {
2307 "column": 20,
2308 "line": 27
2309 }
2310 },
2311 {
2312 "defaultMessage": "!!!Your changes have been saved",
2313 "end": {
2314 "column": 3,
2315 "line": 34
2316 },
2317 "file": "src/components/settings/user/EditUserForm.js",
2318 "id": "settings.account.successInfo",
2319 "start": {
2320 "column": 15,
2321 "line": 31
2322 }
2323 },
2324 {
2325 "defaultMessage": "!!!Update profile",
2326 "end": {
2327 "column": 3,
2328 "line": 38
2329 },
2330 "file": "src/components/settings/user/EditUserForm.js",
2331 "id": "settings.account.buttonSave",
2332 "start": {
2333 "column": 14,
2334 "line": 35
2335 }
2336 }
2337 ],
2338 "path": "src/components/settings/user/EditUserForm.json"
2339 },
2340 {
2341 "descriptors": [
2342 {
2343 "defaultMessage": "!!!Support the development of Franz",
2344 "end": {
2345 "column": 3,
2346 "line": 17
2347 },
2348 "file": "src/components/subscription/SubscriptionForm.js",
2349 "id": "subscription.submit.label",
2350 "start": {
2351 "column": 21,
2352 "line": 14
2353 }
2354 },
2355 {
2356 "defaultMessage": "!!!Could not initialize payment form",
2357 "end": {
2358 "column": 3,
2359 "line": 21
2360 },
2361 "file": "src/components/subscription/SubscriptionForm.js",
2362 "id": "subscription.paymentSessionError",
2363 "start": {
2364 "column": 23,
2365 "line": 18
2366 }
2367 },
2368 {
2369 "defaultMessage": "!!!free",
2370 "end": {
2371 "column": 3,
2372 "line": 25
2373 },
2374 "file": "src/components/subscription/SubscriptionForm.js",
2375 "id": "subscription.type.free",
2376 "start": {
2377 "column": 12,
2378 "line": 22
2379 }
2380 },
2381 {
2382 "defaultMessage": "!!!month",
2383 "end": {
2384 "column": 3,
2385 "line": 29
2386 },
2387 "file": "src/components/subscription/SubscriptionForm.js",
2388 "id": "subscription.type.month",
2389 "start": {
2390 "column": 15,
2391 "line": 26
2392 }
2393 },
2394 {
2395 "defaultMessage": "!!!year",
2396 "end": {
2397 "column": 3,
2398 "line": 33
2399 },
2400 "file": "src/components/subscription/SubscriptionForm.js",
2401 "id": "subscription.type.year",
2402 "start": {
2403 "column": 14,
2404 "line": 30
2405 }
2406 },
2407 {
2408 "defaultMessage": "!!!The Franz Premium Supporter Account includes",
2409 "end": {
2410 "column": 3,
2411 "line": 37
2412 },
2413 "file": "src/components/subscription/SubscriptionForm.js",
2414 "id": "subscription.includedFeatures",
2415 "start": {
2416 "column": 20,
2417 "line": 34
2418 }
2419 },
2420 {
2421 "defaultMessage": "!!!Add on-premise/hosted services like Mattermost",
2422 "end": {
2423 "column": 3,
2424 "line": 41
2425 },
2426 "file": "src/components/subscription/SubscriptionForm.js",
2427 "id": "subscription.features.onpremise.mattermost",
2428 "start": {
2429 "column": 13,
2430 "line": 38
2431 }
2432 },
2433 {
2434 "defaultMessage": "!!!No app delays & nagging to upgrade license",
2435 "end": {
2436 "column": 3,
2437 "line": 45
2438 },
2439 "file": "src/components/subscription/SubscriptionForm.js",
2440 "id": "subscription.features.noInterruptions",
2441 "start": {
2442 "column": 19,
2443 "line": 42
2444 }
2445 },
2446 {
2447 "defaultMessage": "!!!Proxy support for services",
2448 "end": {
2449 "column": 3,
2450 "line": 49
2451 },
2452 "file": "src/components/subscription/SubscriptionForm.js",
2453 "id": "subscription.features.proxy",
2454 "start": {
2455 "column": 9,
2456 "line": 46
2457 }
2458 },
2459 {
2460 "defaultMessage": "!!!Support for Spellchecker",
2461 "end": {
2462 "column": 3,
2463 "line": 53
2464 },
2465 "file": "src/components/subscription/SubscriptionForm.js",
2466 "id": "subscription.features.spellchecker",
2467 "start": {
2468 "column": 16,
2469 "line": 50
2470 }
2471 },
2472 {
2473 "defaultMessage": "!!!No ads, ever!",
2474 "end": {
2475 "column": 3,
2476 "line": 57
2477 },
2478 "file": "src/components/subscription/SubscriptionForm.js",
2479 "id": "subscription.features.ads",
2480 "start": {
2481 "column": 7,
2482 "line": 54
2483 }
2484 },
2485 {
2486 "defaultMessage": "!!!coming soon",
2487 "end": {
2488 "column": 3,
2489 "line": 61
2490 },
2491 "file": "src/components/subscription/SubscriptionForm.js",
2492 "id": "subscription.features.comingSoon",
2493 "start": {
2494 "column": 14,
2495 "line": 58
2496 }
2497 },
2498 {
2499 "defaultMessage": "!!!EU residents: local sales tax may apply",
2500 "end": {
2501 "column": 3,
2502 "line": 65
2503 },
2504 "file": "src/components/subscription/SubscriptionForm.js",
2505 "id": "subscription.euTaxInfo",
2506 "start": {
2507 "column": 13,
2508 "line": 62
2509 }
2510 }
2511 ],
2512 "path": "src/components/subscription/SubscriptionForm.json"
2513 },
2514 {
2515 "descriptors": [
2516 {
2517 "defaultMessage": "!!!Cancel",
2518 "end": {
2519 "column": 3,
2520 "line": 14
2521 },
2522 "file": "src/components/subscription/SubscriptionPopup.js",
2523 "id": "subscriptionPopup.buttonCancel",
2524 "start": {
2525 "column": 16,
2526 "line": 11
2527 }
2528 },
2529 {
2530 "defaultMessage": "!!!Done",
2531 "end": {
2532 "column": 3,
2533 "line": 18
2534 },
2535 "file": "src/components/subscription/SubscriptionPopup.js",
2536 "id": "subscriptionPopup.buttonDone",
2537 "start": {
2538 "column": 14,
2539 "line": 15
2540 }
2541 }
2542 ],
2543 "path": "src/components/subscription/SubscriptionPopup.json"
2544 },
2545 {
2546 "descriptors": [
2547 {
2548 "defaultMessage": "!!!Upgrade account",
2549 "end": {
2550 "column": 3,
2551 "line": 18
2552 },
2553 "file": "src/components/ui/PremiumFeatureContainer/index.js",
2554 "id": "premiumFeature.button.upgradeAccount",
2555 "start": {
2556 "column": 10,
2557 "line": 15
2558 }
2559 }
2560 ],
2561 "path": "src/components/ui/PremiumFeatureContainer/index.json"
2562 },
2563 {
2564 "descriptors": [
2565 {
2566 "defaultMessage": "!!!Loading",
2567 "end": {
2568 "column": 3,
2569 "line": 14
2570 },
2571 "file": "src/components/ui/WebviewLoader/index.js",
2572 "id": "service.webviewLoader.loading",
2573 "start": {
2574 "column": 11,
2575 "line": 11
2576 }
2577 }
2578 ],
2579 "path": "src/components/ui/WebviewLoader/index.json"
2580 },
2581 {
2582 "descriptors": [
2583 {
2584 "defaultMessage": "!!!Something went wrong.",
2585 "end": {
2586 "column": 3,
2587 "line": 14
2588 },
2589 "file": "src/components/util/ErrorBoundary/index.js",
2590 "id": "app.errorHandler.headline",
2591 "start": {
2592 "column": 12,
2593 "line": 11
2594 }
2595 },
2596 {
2597 "defaultMessage": "!!!Reload",
2598 "end": {
2599 "column": 3,
2600 "line": 18
2601 },
2602 "file": "src/components/util/ErrorBoundary/index.js",
2603 "id": "app.errorHandler.action",
2604 "start": {
2605 "column": 10,
2606 "line": 15
2607 }
2608 }
2609 ],
2610 "path": "src/components/util/ErrorBoundary/index.json"
2611 },
2612 {
2613 "descriptors": [
2614 {
2615 "defaultMessage": "!!!Name",
2616 "end": {
2617 "column": 3,
2618 "line": 31
2619 },
2620 "file": "src/containers/settings/EditServiceScreen.js",
2621 "id": "settings.service.form.name",
2622 "start": {
2623 "column": 8,
2624 "line": 28
2625 }
2626 },
2627 {
2628 "defaultMessage": "!!!Enable service",
2629 "end": {
2630 "column": 3,
2631 "line": 35
2632 },
2633 "file": "src/containers/settings/EditServiceScreen.js",
2634 "id": "settings.service.form.enableService",
2635 "start": {
2636 "column": 17,
2637 "line": 32
2638 }
2639 },
2640 {
2641 "defaultMessage": "!!!Enable Notifications",
2642 "end": {
2643 "column": 3,
2644 "line": 39
2645 },
2646 "file": "src/containers/settings/EditServiceScreen.js",
2647 "id": "settings.service.form.enableNotification",
2648 "start": {
2649 "column": 22,
2650 "line": 36
2651 }
2652 },
2653 {
2654 "defaultMessage": "!!!Show unread message badges",
2655 "end": {
2656 "column": 3,
2657 "line": 43
2658 },
2659 "file": "src/containers/settings/EditServiceScreen.js",
2660 "id": "settings.service.form.enableBadge",
2661 "start": {
2662 "column": 15,
2663 "line": 40
2664 }
2665 },
2666 {
2667 "defaultMessage": "!!!Enable audio",
2668 "end": {
2669 "column": 3,
2670 "line": 47
2671 },
2672 "file": "src/containers/settings/EditServiceScreen.js",
2673 "id": "settings.service.form.enableAudio",
2674 "start": {
2675 "column": 15,
2676 "line": 44
2677 }
2678 },
2679 {
2680 "defaultMessage": "!!!Team",
2681 "end": {
2682 "column": 3,
2683 "line": 51
2684 },
2685 "file": "src/containers/settings/EditServiceScreen.js",
2686 "id": "settings.service.form.team",
2687 "start": {
2688 "column": 8,
2689 "line": 48
2690 }
2691 },
2692 {
2693 "defaultMessage": "!!!Custom server",
2694 "end": {
2695 "column": 3,
2696 "line": 55
2697 },
2698 "file": "src/containers/settings/EditServiceScreen.js",
2699 "id": "settings.service.form.customUrl",
2700 "start": {
2701 "column": 13,
2702 "line": 52
2703 }
2704 },
2705 {
2706 "defaultMessage": "!!!Show message badge for all new messages",
2707 "end": {
2708 "column": 3,
2709 "line": 59
2710 },
2711 "file": "src/containers/settings/EditServiceScreen.js",
2712 "id": "settings.service.form.indirectMessages",
2713 "start": {
2714 "column": 20,
2715 "line": 56
2716 }
2717 },
2718 {
2719 "defaultMessage": "!!!Custom icon",
2720 "end": {
2721 "column": 3,
2722 "line": 63
2723 },
2724 "file": "src/containers/settings/EditServiceScreen.js",
2725 "id": "settings.service.form.icon",
2726 "start": {
2727 "column": 8,
2728 "line": 60
2729 }
2730 },
2731 {
2732 "defaultMessage": "!!!Enable Dark Mode",
2733 "end": {
2734 "column": 3,
2735 "line": 67
2736 },
2737 "file": "src/containers/settings/EditServiceScreen.js",
2738 "id": "settings.service.form.enableDarkMode",
2739 "start": {
2740 "column": 18,
2741 "line": 64
2742 }
2743 },
2744 {
2745 "defaultMessage": "!!!Use Proxy",
2746 "end": {
2747 "column": 3,
2748 "line": 71
2749 },
2750 "file": "src/containers/settings/EditServiceScreen.js",
2751 "id": "settings.service.form.proxy.isEnabled",
2752 "start": {
2753 "column": 15,
2754 "line": 68
2755 }
2756 },
2757 {
2758 "defaultMessage": "!!!Proxy Host/IP",
2759 "end": {
2760 "column": 3,
2761 "line": 75
2762 },
2763 "file": "src/containers/settings/EditServiceScreen.js",
2764 "id": "settings.service.form.proxy.host",
2765 "start": {
2766 "column": 13,
2767 "line": 72
2768 }
2769 },
2770 {
2771 "defaultMessage": "!!!Port",
2772 "end": {
2773 "column": 3,
2774 "line": 79
2775 },
2776 "file": "src/containers/settings/EditServiceScreen.js",
2777 "id": "settings.service.form.proxy.port",
2778 "start": {
2779 "column": 13,
2780 "line": 76
2781 }
2782 },
2783 {
2784 "defaultMessage": "!!!User",
2785 "end": {
2786 "column": 3,
2787 "line": 83
2788 },
2789 "file": "src/containers/settings/EditServiceScreen.js",
2790 "id": "settings.service.form.proxy.user",
2791 "start": {
2792 "column": 13,
2793 "line": 80
2794 }
2795 },
2796 {
2797 "defaultMessage": "!!!Password",
2798 "end": {
2799 "column": 3,
2800 "line": 87
2801 },
2802 "file": "src/containers/settings/EditServiceScreen.js",
2803 "id": "settings.service.form.proxy.password",
2804 "start": {
2805 "column": 17,
2806 "line": 84
2807 }
2808 }
2809 ],
2810 "path": "src/containers/settings/EditServiceScreen.json"
2811 },
2812 {
2813 "descriptors": [
2814 {
2815 "defaultMessage": "!!!Launch Franz on start",
2816 "end": {
2817 "column": 3,
2818 "line": 25
2819 },
2820 "file": "src/containers/settings/EditSettingsScreen.js",
2821 "id": "settings.app.form.autoLaunchOnStart",
2822 "start": {
2823 "column": 21,
2824 "line": 22
2825 }
2826 },
2827 {
2828 "defaultMessage": "!!!Open in background",
2829 "end": {
2830 "column": 3,
2831 "line": 29
2832 },
2833 "file": "src/containers/settings/EditSettingsScreen.js",
2834 "id": "settings.app.form.autoLaunchInBackground",
2835 "start": {
2836 "column": 26,
2837 "line": 26
2838 }
2839 },
2840 {
2841 "defaultMessage": "!!!Keep Franz in background when closing the window",
2842 "end": {
2843 "column": 3,
2844 "line": 33
2845 },
2846 "file": "src/containers/settings/EditSettingsScreen.js",
2847 "id": "settings.app.form.runInBackground",
2848 "start": {
2849 "column": 19,
2850 "line": 30
2851 }
2852 },
2853 {
2854 "defaultMessage": "!!!Show Franz in system tray",
2855 "end": {
2856 "column": 3,
2857 "line": 37
2858 },
2859 "file": "src/containers/settings/EditSettingsScreen.js",
2860 "id": "settings.app.form.enableSystemTray",
2861 "start": {
2862 "column": 20,
2863 "line": 34
2864 }
2865 },
2866 {
2867 "defaultMessage": "!!!Minimize Franz to system tray",
2868 "end": {
2869 "column": 3,
2870 "line": 41
2871 },
2872 "file": "src/containers/settings/EditSettingsScreen.js",
2873 "id": "settings.app.form.minimizeToSystemTray",
2874 "start": {
2875 "column": 24,
2876 "line": 38
2877 }
2878 },
2879 {
2880 "defaultMessage": "!!!Language",
2881 "end": {
2882 "column": 3,
2883 "line": 45
2884 },
2885 "file": "src/containers/settings/EditSettingsScreen.js",
2886 "id": "settings.app.form.language",
2887 "start": {
2888 "column": 12,
2889 "line": 42
2890 }
2891 },
2892 {
2893 "defaultMessage": "!!!Dark Mode",
2894 "end": {
2895 "column": 3,
2896 "line": 49
2897 },
2898 "file": "src/containers/settings/EditSettingsScreen.js",
2899 "id": "settings.app.form.darkMode",
2900 "start": {
2901 "column": 12,
2902 "line": 46
2903 }
2904 },
2905 {
2906 "defaultMessage": "!!!Display disabled services tabs",
2907 "end": {
2908 "column": 3,
2909 "line": 53
2910 },
2911 "file": "src/containers/settings/EditSettingsScreen.js",
2912 "id": "settings.app.form.showDisabledServices",
2913 "start": {
2914 "column": 24,
2915 "line": 50
2916 }
2917 },
2918 {
2919 "defaultMessage": "!!!Show unread message badge when notifications are disabled",
2920 "end": {
2921 "column": 3,
2922 "line": 57
2923 },
2924 "file": "src/containers/settings/EditSettingsScreen.js",
2925 "id": "settings.app.form.showMessagesBadgesWhenMuted",
2926 "start": {
2927 "column": 29,
2928 "line": 54
2929 }
2930 },
2931 {
2932 "defaultMessage": "!!!Enable spell checking",
2933 "end": {
2934 "column": 3,
2935 "line": 61
2936 },
2937 "file": "src/containers/settings/EditSettingsScreen.js",
2938 "id": "settings.app.form.enableSpellchecking",
2939 "start": {
2940 "column": 23,
2941 "line": 58
2942 }
2943 },
2944 {
2945 "defaultMessage": "!!!Enable GPU Acceleration",
2946 "end": {
2947 "column": 3,
2948 "line": 65
2949 },
2950 "file": "src/containers/settings/EditSettingsScreen.js",
2951 "id": "settings.app.form.enableGPUAcceleration",
2952 "start": {
2953 "column": 25,
2954 "line": 62
2955 }
2956 },
2957 {
2958 "defaultMessage": "!!!Include beta versions",
2959 "end": {
2960 "column": 3,
2961 "line": 69
2962 },
2963 "file": "src/containers/settings/EditSettingsScreen.js",
2964 "id": "settings.app.form.beta",
2965 "start": {
2966 "column": 8,
2967 "line": 66
2968 }
2969 }
2970 ],
2971 "path": "src/containers/settings/EditSettingsScreen.json"
2972 },
2973 {
2974 "descriptors": [
2975 {
2976 "defaultMessage": "!!!Firstname",
2977 "end": {
2978 "column": 3,
2979 "line": 17
2980 },
2981 "file": "src/containers/settings/EditUserScreen.js",
2982 "id": "settings.user.form.firstname",
2983 "start": {
2984 "column": 13,
2985 "line": 14
2986 }
2987 },
2988 {
2989 "defaultMessage": "!!!Lastname",
2990 "end": {
2991 "column": 3,
2992 "line": 21
2993 },
2994 "file": "src/containers/settings/EditUserScreen.js",
2995 "id": "settings.user.form.lastname",
2996 "start": {
2997 "column": 12,
2998 "line": 18
2999 }
3000 },
3001 {
3002 "defaultMessage": "!!!Email",
3003 "end": {
3004 "column": 3,
3005 "line": 25
3006 },
3007 "file": "src/containers/settings/EditUserScreen.js",
3008 "id": "settings.user.form.email",
3009 "start": {
3010 "column": 9,
3011 "line": 22
3012 }
3013 },
3014 {
3015 "defaultMessage": "!!!Account type",
3016 "end": {
3017 "column": 3,
3018 "line": 29
3019 },
3020 "file": "src/containers/settings/EditUserScreen.js",
3021 "id": "settings.user.form.accountType.label",
3022 "start": {
3023 "column": 20,
3024 "line": 26
3025 }
3026 },
3027 {
3028 "defaultMessage": "!!!Individual",
3029 "end": {
3030 "column": 3,
3031 "line": 33
3032 },
3033 "file": "src/containers/settings/EditUserScreen.js",
3034 "id": "settings.user.form.accountType.individual",
3035 "start": {
3036 "column": 25,
3037 "line": 30
3038 }
3039 },
3040 {
3041 "defaultMessage": "!!!Non-Profit",
3042 "end": {
3043 "column": 3,
3044 "line": 37
3045 },
3046 "file": "src/containers/settings/EditUserScreen.js",
3047 "id": "settings.user.form.accountType.non-profit",
3048 "start": {
3049 "column": 24,
3050 "line": 34
3051 }
3052 },
3053 {
3054 "defaultMessage": "!!!Company",
3055 "end": {
3056 "column": 3,
3057 "line": 41
3058 },
3059 "file": "src/containers/settings/EditUserScreen.js",
3060 "id": "settings.user.form.accountType.company",
3061 "start": {
3062 "column": 22,
3063 "line": 38
3064 }
3065 },
3066 {
3067 "defaultMessage": "!!!Current password",
3068 "end": {
3069 "column": 3,
3070 "line": 45
3071 },
3072 "file": "src/containers/settings/EditUserScreen.js",
3073 "id": "settings.user.form.currentPassword",
3074 "start": {
3075 "column": 19,
3076 "line": 42
3077 }
3078 },
3079 {
3080 "defaultMessage": "!!!New password",
3081 "end": {
3082 "column": 3,
3083 "line": 49
3084 },
3085 "file": "src/containers/settings/EditUserScreen.js",
3086 "id": "settings.user.form.newPassword",
3087 "start": {
3088 "column": 15,
3089 "line": 46
3090 }
3091 }
3092 ],
3093 "path": "src/containers/settings/EditUserScreen.json"
3094 },
3095 {
3096 "descriptors": [
3097 {
3098 "defaultMessage": "!!!Please purchase license to skip waiting",
3099 "end": {
3100 "column": 3,
3101 "line": 18
3102 },
3103 "file": "src/features/delayApp/Component.js",
3104 "id": "feature.delayApp.headline",
3105 "start": {
3106 "column": 12,
3107 "line": 15
3108 }
3109 },
3110 {
3111 "defaultMessage": "!!!Get a Franz Supporter License",
3112 "end": {
3113 "column": 3,
3114 "line": 22
3115 },
3116 "file": "src/features/delayApp/Component.js",
3117 "id": "feature.delayApp.action",
3118 "start": {
3119 "column": 10,
3120 "line": 19
3121 }
3122 },
3123 {
3124 "defaultMessage": "!!!Franz will continue in {seconds} seconds.",
3125 "end": {
3126 "column": 3,
3127 "line": 26
3128 },
3129 "file": "src/features/delayApp/Component.js",
3130 "id": "feature.delayApp.text",
3131 "start": {
3132 "column": 8,
3133 "line": 23
3134 }
3135 }
3136 ],
3137 "path": "src/features/delayApp/Component.json"
3138 },
3139 {
3140 "descriptors": [
3141 {
3142 "defaultMessage": "!!!Franz is better together!",
3143 "end": {
3144 "column": 3,
3145 "line": 18
3146 },
3147 "file": "src/features/shareFranz/Component.js",
3148 "id": "feature.shareFranz.headline",
3149 "start": {
3150 "column": 12,
3151 "line": 15
3152 }
3153 },
3154 {
3155 "defaultMessage": "!!!Tell your friends and colleagues how awesome Franz is and help us to spread the word.",
3156 "end": {
3157 "column": 3,
3158 "line": 22
3159 },
3160 "file": "src/features/shareFranz/Component.js",
3161 "id": "feature.shareFranz.text",
3162 "start": {
3163 "column": 8,
3164 "line": 19
3165 }
3166 },
3167 {
3168 "defaultMessage": "!!!Share as email",
3169 "end": {
3170 "column": 3,
3171 "line": 26
3172 },
3173 "file": "src/features/shareFranz/Component.js",
3174 "id": "feature.shareFranz.action.email",
3175 "start": {
3176 "column": 16,
3177 "line": 23
3178 }
3179 },
3180 {
3181 "defaultMessage": "!!!Share on Facebook",
3182 "end": {
3183 "column": 3,
3184 "line": 30
3185 },
3186 "file": "src/features/shareFranz/Component.js",
3187 "id": "feature.shareFranz.action.facebook",
3188 "start": {
3189 "column": 19,
3190 "line": 27
3191 }
3192 },
3193 {
3194 "defaultMessage": "!!!Share on Twitter",
3195 "end": {
3196 "column": 3,
3197 "line": 34
3198 },
3199 "file": "src/features/shareFranz/Component.js",
3200 "id": "feature.shareFranz.action.twitter",
3201 "start": {
3202 "column": 18,
3203 "line": 31
3204 }
3205 },
3206 {
3207 "defaultMessage": "!!! I've added {count} services to Franz! Get the free app for WhatsApp, Messenger, Slack, Skype and co at www.meetfranz.com",
3208 "end": {
3209 "column": 3,
3210 "line": 38
3211 },
3212 "file": "src/features/shareFranz/Component.js",
3213 "id": "feature.shareFranz.shareText.email",
3214 "start": {
3215 "column": 18,
3216 "line": 35
3217 }
3218 },
3219 {
3220 "defaultMessage": "!!! I've added {count} services to Franz! Get the free app for WhatsApp, Messenger, Slack, Skype and co at www.meetfranz.com /cc @FranzMessenger",
3221 "end": {
3222 "column": 3,
3223 "line": 42
3224 },
3225 "file": "src/features/shareFranz/Component.js",
3226 "id": "feature.shareFranz.shareText.twitter",
3227 "start": {
3228 "column": 20,
3229 "line": 39
3230 }
3231 }
3232 ],
3233 "path": "src/features/shareFranz/Component.json"
3234 },
3235 {
3236 "descriptors": [
3237 {
3238 "defaultMessage": "!!!Create workspace",
3239 "end": {
3240 "column": 3,
3241 "line": 16
3242 },
3243 "file": "src/features/workspaces/components/CreateWorkspaceForm.js",
3244 "id": "settings.workspace.add.form.submitButton",
3245 "start": {
3246 "column": 16,
3247 "line": 13
3248 }
3249 },
3250 {
3251 "defaultMessage": "!!!Name",
3252 "end": {
3253 "column": 3,
3254 "line": 20
3255 },
3256 "file": "src/features/workspaces/components/CreateWorkspaceForm.js",
3257 "id": "settings.workspace.add.form.name",
3258 "start": {
3259 "column": 8,
3260 "line": 17
3261 }
3262 }
3263 ],
3264 "path": "src/features/workspaces/components/CreateWorkspaceForm.json"
3265 },
3266 {
3267 "descriptors": [
3268 {
3269 "defaultMessage": "!!!Delete workspace",
3270 "end": {
3271 "column": 3,
3272 "line": 22
3273 },
3274 "file": "src/features/workspaces/components/EditWorkspaceForm.js",
3275 "id": "settings.workspace.form.buttonDelete",
3276 "start": {
3277 "column": 16,
3278 "line": 19
3279 }
3280 },
3281 {
3282 "defaultMessage": "!!!Save workspace",
3283 "end": {
3284 "column": 3,
3285 "line": 26
3286 },
3287 "file": "src/features/workspaces/components/EditWorkspaceForm.js",
3288 "id": "settings.workspace.form.buttonSave",
3289 "start": {
3290 "column": 14,
3291 "line": 23
3292 }
3293 },
3294 {
3295 "defaultMessage": "!!!Name",
3296 "end": {
3297 "column": 3,
3298 "line": 30
3299 },
3300 "file": "src/features/workspaces/components/EditWorkspaceForm.js",
3301 "id": "settings.workspace.form.name",
3302 "start": {
3303 "column": 8,
3304 "line": 27
3305 }
3306 },
3307 {
3308 "defaultMessage": "!!!Your workspaces",
3309 "end": {
3310 "column": 3,
3311 "line": 34
3312 },
3313 "file": "src/features/workspaces/components/EditWorkspaceForm.js",
3314 "id": "settings.workspace.form.yourWorkspaces",
3315 "start": {
3316 "column": 18,
3317 "line": 31
3318 }
3319 },
3320 {
3321 "defaultMessage": "!!!Services in this Workspace",
3322 "end": {
3323 "column": 3,
3324 "line": 38
3325 },
3326 "file": "src/features/workspaces/components/EditWorkspaceForm.js",
3327 "id": "settings.workspace.form.servicesInWorkspaceHeadline",
3328 "start": {
3329 "column": 31,
3330 "line": 35
3331 }
3332 }
3333 ],
3334 "path": "src/features/workspaces/components/EditWorkspaceForm.json"
3335 },
3336 {
3337 "descriptors": [
3338 {
3339 "defaultMessage": "!!!Workspaces",
3340 "end": {
3341 "column": 3,
3342 "line": 19
3343 },
3344 "file": "src/features/workspaces/components/WorkspaceDrawer.js",
3345 "id": "workspaceDrawer.headline",
3346 "start": {
3347 "column": 12,
3348 "line": 16
3349 }
3350 },
3351 {
3352 "defaultMessage": "!!!All services",
3353 "end": {
3354 "column": 3,
3355 "line": 23
3356 },
3357 "file": "src/features/workspaces/components/WorkspaceDrawer.js",
3358 "id": "workspaceDrawer.allServices",
3359 "start": {
3360 "column": 15,
3361 "line": 20
3362 }
3363 },
3364 {
3365 "defaultMessage": "!!!Workspaces settings",
3366 "end": {
3367 "column": 3,
3368 "line": 27
3369 },
3370 "file": "src/features/workspaces/components/WorkspaceDrawer.js",
3371 "id": "workspaceDrawer.workspacesSettingsTooltip",
3372 "start": {
3373 "column": 29,
3374 "line": 24
3375 }
3376 },
3377 {
3378 "defaultMessage": "!!!Info about workspace feature",
3379 "end": {
3380 "column": 3,
3381 "line": 31
3382 },
3383 "file": "src/features/workspaces/components/WorkspaceDrawer.js",
3384 "id": "workspaceDrawer.workspaceFeatureInfo",
3385 "start": {
3386 "column": 24,
3387 "line": 28
3388 }
3389 },
3390 {
3391 "defaultMessage": "!!!Create your first workspace",
3392 "end": {
3393 "column": 3,
3394 "line": 35
3395 },
3396 "file": "src/features/workspaces/components/WorkspaceDrawer.js",
3397 "id": "workspaceDrawer.premiumCtaButtonLabel",
3398 "start": {
3399 "column": 25,
3400 "line": 32
3401 }
3402 },
3403 {
3404 "defaultMessage": "!!!Reactivate premium account",
3405 "end": {
3406 "column": 3,
3407 "line": 39
3408 },
3409 "file": "src/features/workspaces/components/WorkspaceDrawer.js",
3410 "id": "workspaceDrawer.reactivatePremiumAccountLabel",
3411 "start": {
3412 "column": 28,
3413 "line": 36
3414 }
3415 },
3416 {
3417 "defaultMessage": "!!!add new workspace",
3418 "end": {
3419 "column": 3,
3420 "line": 43
3421 },
3422 "file": "src/features/workspaces/components/WorkspaceDrawer.js",
3423 "id": "workspaceDrawer.addNewWorkspaceLabel",
3424 "start": {
3425 "column": 24,
3426 "line": 40
3427 }
3428 },
3429 {
3430 "defaultMessage": "!!!Premium feature",
3431 "end": {
3432 "column": 3,
3433 "line": 47
3434 },
3435 "file": "src/features/workspaces/components/WorkspaceDrawer.js",
3436 "id": "workspaceDrawer.proFeatureBadge",
3437 "start": {
3438 "column": 23,
3439 "line": 44
3440 }
3441 }
3442 ],
3443 "path": "src/features/workspaces/components/WorkspaceDrawer.json"
3444 },
3445 {
3446 "descriptors": [
3447 {
3448 "defaultMessage": "!!!No services added yet",
3449 "end": {
3450 "column": 3,
3451 "line": 15
3452 },
3453 "file": "src/features/workspaces/components/WorkspaceDrawerItem.js",
3454 "id": "workspaceDrawer.item.noServicesAddedYet",
3455 "start": {
3456 "column": 22,
3457 "line": 12
3458 }
3459 },
3460 {
3461 "defaultMessage": "!!!edit",
3462 "end": {
3463 "column": 3,
3464 "line": 19
3465 },
3466 "file": "src/features/workspaces/components/WorkspaceDrawerItem.js",
3467 "id": "workspaceDrawer.item.contextMenuEdit",
3468 "start": {
3469 "column": 19,
3470 "line": 16
3471 }
3472 }
3473 ],
3474 "path": "src/features/workspaces/components/WorkspaceDrawerItem.json"
3475 },
3476 {
3477 "descriptors": [
3478 {
3479 "defaultMessage": "!!!Your workspaces",
3480 "end": {
3481 "column": 3,
3482 "line": 20
3483 },
3484 "file": "src/features/workspaces/components/WorkspacesDashboard.js",
3485 "id": "settings.workspaces.headline",
3486 "start": {
3487 "column": 12,
3488 "line": 17
3489 }
3490 },
3491 {
3492 "defaultMessage": "!!!You haven't added any workspaces yet.",
3493 "end": {
3494 "column": 3,
3495 "line": 24
3496 },
3497 "file": "src/features/workspaces/components/WorkspacesDashboard.js",
3498 "id": "settings.workspaces.noWorkspacesAdded",
3499 "start": {
3500 "column": 19,
3501 "line": 21
3502 }
3503 },
3504 {
3505 "defaultMessage": "!!!Could not load your workspaces",
3506 "end": {
3507 "column": 3,
3508 "line": 28
3509 },
3510 "file": "src/features/workspaces/components/WorkspacesDashboard.js",
3511 "id": "settings.workspaces.workspacesRequestFailed",
3512 "start": {
3513 "column": 27,
3514 "line": 25
3515 }
3516 },
3517 {
3518 "defaultMessage": "!!!Try again",
3519 "end": {
3520 "column": 3,
3521 "line": 32
3522 },
3523 "file": "src/features/workspaces/components/WorkspacesDashboard.js",
3524 "id": "settings.workspaces.tryReloadWorkspaces",
3525 "start": {
3526 "column": 23,
3527 "line": 29
3528 }
3529 },
3530 {
3531 "defaultMessage": "!!!Your changes have been saved",
3532 "end": {
3533 "column": 3,
3534 "line": 36
3535 },
3536 "file": "src/features/workspaces/components/WorkspacesDashboard.js",
3537 "id": "settings.workspaces.updatedInfo",
3538 "start": {
3539 "column": 15,
3540 "line": 33
3541 }
3542 },
3543 {
3544 "defaultMessage": "!!!Workspace has been deleted",
3545 "end": {
3546 "column": 3,
3547 "line": 40
3548 },
3549 "file": "src/features/workspaces/components/WorkspacesDashboard.js",
3550 "id": "settings.workspaces.deletedInfo",
3551 "start": {
3552 "column": 15,
3553 "line": 37
3554 }
3555 },
3556 {
3557 "defaultMessage": "!!!Info about workspace feature",
3558 "end": {
3559 "column": 3,
3560 "line": 44
3561 },
3562 "file": "src/features/workspaces/components/WorkspacesDashboard.js",
3563 "id": "settings.workspaces.workspaceFeatureInfo",
3564 "start": {
3565 "column": 24,
3566 "line": 41
3567 }
3568 },
3569 {
3570 "defaultMessage": "!!!Less is More: Introducing Franz Workspaces",
3571 "end": {
3572 "column": 3,
3573 "line": 48
3574 },
3575 "file": "src/features/workspaces/components/WorkspacesDashboard.js",
3576 "id": "settings.workspaces.workspaceFeatureHeadline",
3577 "start": {
3578 "column": 28,
3579 "line": 45
3580 }
3581 }
3582 ],
3583 "path": "src/features/workspaces/components/WorkspacesDashboard.json"
3584 },
3585 {
3586 "descriptors": [
3587 {
3588 "defaultMessage": "!!!Switching to",
3589 "end": {
3590 "column": 3,
3591 "line": 15
3592 },
3593 "file": "src/features/workspaces/components/WorkspaceSwitchingIndicator.js",
3594 "id": "workspaces.switchingIndicator.switchingTo",
3595 "start": {
3596 "column": 15,
3597 "line": 12
3598 }
3599 }
3600 ],
3601 "path": "src/features/workspaces/components/WorkspaceSwitchingIndicator.json"
3602 },
3603 {
3604 "descriptors": [
3605 {
3606 "defaultMessage": "!!!Field is required",
3607 "end": {
3608 "column": 3,
3609 "line": 7
3610 },
3611 "file": "src/helpers/validation-helpers.js",
3612 "id": "validation.required",
3613 "start": {
3614 "column": 12,
3615 "line": 4
3616 }
3617 },
3618 {
3619 "defaultMessage": "!!!Email not valid",
3620 "end": {
3621 "column": 3,
3622 "line": 11
3623 },
3624 "file": "src/helpers/validation-helpers.js",
3625 "id": "validation.email",
3626 "start": {
3627 "column": 9,
3628 "line": 8
3629 }
3630 },
3631 {
3632 "defaultMessage": "!!!Not a valid URL",
3633 "end": {
3634 "column": 3,
3635 "line": 15
3636 },
3637 "file": "src/helpers/validation-helpers.js",
3638 "id": "validation.url",
3639 "start": {
3640 "column": 7,
3641 "line": 12
3642 }
3643 },
3644 {
3645 "defaultMessage": "!!!Too few characters",
3646 "end": {
3647 "column": 3,
3648 "line": 19
3649 },
3650 "file": "src/helpers/validation-helpers.js",
3651 "id": "validation.minLength",
3652 "start": {
3653 "column": 13,
3654 "line": 16
3655 }
3656 },
3657 {
3658 "defaultMessage": "!!!At least one is required",
3659 "end": {
3660 "column": 3,
3661 "line": 23
3662 },
3663 "file": "src/helpers/validation-helpers.js",
3664 "id": "validation.oneRequired",
3665 "start": {
3666 "column": 15,
3667 "line": 20
3668 }
3669 }
3670 ],
3671 "path": "src/helpers/validation-helpers.json"
3672 },
3673 {
3674 "descriptors": [
3675 {
3676 "defaultMessage": "!!!Can't connect to Franz Online Services",
3677 "end": {
3678 "column": 3,
3679 "line": 7
3680 },
3681 "file": "src/i18n/globalMessages.js",
3682 "id": "global.api.unhealthy",
3683 "start": {
3684 "column": 16,
3685 "line": 4
3686 }
3687 },
3688 {
3689 "defaultMessage": "!!!You are not connected to the internet.",
3690 "end": {
3691 "column": 3,
3692 "line": 11
3693 },
3694 "file": "src/i18n/globalMessages.js",
3695 "id": "global.notConnectedToTheInternet",
3696 "start": {
3697 "column": 29,
3698 "line": 8
3699 }
3700 },
3701 {
3702 "defaultMessage": "!!!Spell checking language",
3703 "end": {
3704 "column": 3,
3705 "line": 15
3706 },
3707 "file": "src/i18n/globalMessages.js",
3708 "id": "global.spellchecking.language",
3709 "start": {
3710 "column": 24,
3711 "line": 12
3712 }
3713 },
3714 {
3715 "defaultMessage": "!!!Use System Default ({default})",
3716 "end": {
3717 "column": 3,
3718 "line": 19
3719 },
3720 "file": "src/i18n/globalMessages.js",
3721 "id": "global.spellchecker.useDefault",
3722 "start": {
3723 "column": 29,
3724 "line": 16
3725 }
3726 },
3727 {
3728 "defaultMessage": "!!!Detect language automatically",
3729 "end": {
3730 "column": 3,
3731 "line": 23
3732 },
3733 "file": "src/i18n/globalMessages.js",
3734 "id": "global.spellchecking.autodetect",
3735 "start": {
3736 "column": 34,
3737 "line": 20
3738 }
3739 },
3740 {
3741 "defaultMessage": "!!!Automatic",
3742 "end": {
3743 "column": 3,
3744 "line": 27
3745 },
3746 "file": "src/i18n/globalMessages.js",
3747 "id": "global.spellchecking.autodetect.short",
3748 "start": {
3749 "column": 39,
3750 "line": 24
3751 }
3752 }
3753 ],
3754 "path": "src/i18n/globalMessages.json"
3755 },
3756 {
3757 "descriptors": [
3758 {
3759 "defaultMessage": "!!!Edit",
3760 "end": {
3761 "column": 3,
3762 "line": 16
3763 },
3764 "file": "src/lib/Menu.js",
3765 "id": "menu.edit",
3766 "start": {
3767 "column": 8,
3768 "line": 13
3769 }
3770 },
3771 {
3772 "defaultMessage": "!!!Undo",
3773 "end": {
3774 "column": 3,
3775 "line": 20
3776 },
3777 "file": "src/lib/Menu.js",
3778 "id": "menu.edit.undo",
3779 "start": {
3780 "column": 8,
3781 "line": 17
3782 }
3783 },
3784 {
3785 "defaultMessage": "!!!Redo",
3786 "end": {
3787 "column": 3,
3788 "line": 24
3789 },
3790 "file": "src/lib/Menu.js",
3791 "id": "menu.edit.redo",
3792 "start": {
3793 "column": 8,
3794 "line": 21
3795 }
3796 },
3797 {
3798 "defaultMessage": "!!!Cut",
3799 "end": {
3800 "column": 3,
3801 "line": 28
3802 },
3803 "file": "src/lib/Menu.js",
3804 "id": "menu.edit.cut",
3805 "start": {
3806 "column": 7,
3807 "line": 25
3808 }
3809 },
3810 {
3811 "defaultMessage": "!!!Copy",
3812 "end": {
3813 "column": 3,
3814 "line": 32
3815 },
3816 "file": "src/lib/Menu.js",
3817 "id": "menu.edit.copy",
3818 "start": {
3819 "column": 8,
3820 "line": 29
3821 }
3822 },
3823 {
3824 "defaultMessage": "!!!Paste",
3825 "end": {
3826 "column": 3,
3827 "line": 36
3828 },
3829 "file": "src/lib/Menu.js",
3830 "id": "menu.edit.paste",
3831 "start": {
3832 "column": 9,
3833 "line": 33
3834 }
3835 },
3836 {
3837 "defaultMessage": "!!!Paste And Match Style",
3838 "end": {
3839 "column": 3,
3840 "line": 40
3841 },
3842 "file": "src/lib/Menu.js",
3843 "id": "menu.edit.pasteAndMatchStyle",
3844 "start": {
3845 "column": 22,
3846 "line": 37
3847 }
3848 },
3849 {
3850 "defaultMessage": "!!!Delete",
3851 "end": {
3852 "column": 3,
3853 "line": 44
3854 },
3855 "file": "src/lib/Menu.js",
3856 "id": "menu.edit.delete",
3857 "start": {
3858 "column": 10,
3859 "line": 41
3860 }
3861 },
3862 {
3863 "defaultMessage": "!!!Select All",
3864 "end": {
3865 "column": 3,
3866 "line": 48
3867 },
3868 "file": "src/lib/Menu.js",
3869 "id": "menu.edit.selectAll",
3870 "start": {
3871 "column": 13,
3872 "line": 45
3873 }
3874 },
3875 {
3876 "defaultMessage": "!!!Speech",
3877 "end": {
3878 "column": 3,
3879 "line": 52
3880 },
3881 "file": "src/lib/Menu.js",
3882 "id": "menu.edit.speech",
3883 "start": {
3884 "column": 10,
3885 "line": 49
3886 }
3887 },
3888 {
3889 "defaultMessage": "!!!Start Speaking",
3890 "end": {
3891 "column": 3,
3892 "line": 56
3893 },
3894 "file": "src/lib/Menu.js",
3895 "id": "menu.edit.startSpeaking",
3896 "start": {
3897 "column": 17,
3898 "line": 53
3899 }
3900 },
3901 {
3902 "defaultMessage": "!!!Stop Speaking",
3903 "end": {
3904 "column": 3,
3905 "line": 60
3906 },
3907 "file": "src/lib/Menu.js",
3908 "id": "menu.edit.stopSpeaking",
3909 "start": {
3910 "column": 16,
3911 "line": 57
3912 }
3913 },
3914 {
3915 "defaultMessage": "!!!Start Dictation",
3916 "end": {
3917 "column": 3,
3918 "line": 64
3919 },
3920 "file": "src/lib/Menu.js",
3921 "id": "menu.edit.startDictation",
3922 "start": {
3923 "column": 18,
3924 "line": 61
3925 }
3926 },
3927 {
3928 "defaultMessage": "!!!Emoji & Symbols",
3929 "end": {
3930 "column": 3,
3931 "line": 68
3932 },
3933 "file": "src/lib/Menu.js",
3934 "id": "menu.edit.emojiSymbols",
3935 "start": {
3936 "column": 16,
3937 "line": 65
3938 }
3939 },
3940 {
3941 "defaultMessage": "!!!Actual Size",
3942 "end": {
3943 "column": 3,
3944 "line": 72
3945 },
3946 "file": "src/lib/Menu.js",
3947 "id": "menu.view.resetZoom",
3948 "start": {
3949 "column": 13,
3950 "line": 69
3951 }
3952 },
3953 {
3954 "defaultMessage": "!!!Zoom In",
3955 "end": {
3956 "column": 3,
3957 "line": 76
3958 },
3959 "file": "src/lib/Menu.js",
3960 "id": "menu.view.zoomIn",
3961 "start": {
3962 "column": 10,
3963 "line": 73
3964 }
3965 },
3966 {
3967 "defaultMessage": "!!!Zoom Out",
3968 "end": {
3969 "column": 3,
3970 "line": 80
3971 },
3972 "file": "src/lib/Menu.js",
3973 "id": "menu.view.zoomOut",
3974 "start": {
3975 "column": 11,
3976 "line": 77
3977 }
3978 },
3979 {
3980 "defaultMessage": "!!!Enter Full Screen",
3981 "end": {
3982 "column": 3,
3983 "line": 84
3984 },
3985 "file": "src/lib/Menu.js",
3986 "id": "menu.view.enterFullScreen",
3987 "start": {
3988 "column": 19,
3989 "line": 81
3990 }
3991 },
3992 {
3993 "defaultMessage": "!!!Exit Full Screen",
3994 "end": {
3995 "column": 3,
3996 "line": 88
3997 },
3998 "file": "src/lib/Menu.js",
3999 "id": "menu.view.exitFullScreen",
4000 "start": {
4001 "column": 18,
4002 "line": 85
4003 }
4004 },
4005 {
4006 "defaultMessage": "!!!Toggle Full Screen",
4007 "end": {
4008 "column": 3,
4009 "line": 92
4010 },
4011 "file": "src/lib/Menu.js",
4012 "id": "menu.view.toggleFullScreen",
4013 "start": {
4014 "column": 20,
4015 "line": 89
4016 }
4017 },
4018 {
4019 "defaultMessage": "!!!Toggle Developer Tools",
4020 "end": {
4021 "column": 3,
4022 "line": 96
4023 },
4024 "file": "src/lib/Menu.js",
4025 "id": "menu.view.toggleDevTools",
4026 "start": {
4027 "column": 18,
4028 "line": 93
4029 }
4030 },
4031 {
4032 "defaultMessage": "!!!Toggle Service Developer Tools",
4033 "end": {
4034 "column": 3,
4035 "line": 100
4036 },
4037 "file": "src/lib/Menu.js",
4038 "id": "menu.view.toggleServiceDevTools",
4039 "start": {
4040 "column": 25,
4041 "line": 97
4042 }
4043 },
4044 {
4045 "defaultMessage": "!!!Reload Service",
4046 "end": {
4047 "column": 3,
4048 "line": 104
4049 },
4050 "file": "src/lib/Menu.js",
4051 "id": "menu.view.reloadService",
4052 "start": {
4053 "column": 17,
4054 "line": 101
4055 }
4056 },
4057 {
4058 "defaultMessage": "!!!Reload Franz",
4059 "end": {
4060 "column": 3,
4061 "line": 108
4062 },
4063 "file": "src/lib/Menu.js",
4064 "id": "menu.view.reloadFranz",
4065 "start": {
4066 "column": 15,
4067 "line": 105
4068 }
4069 },
4070 {
4071 "defaultMessage": "!!!Minimize",
4072 "end": {
4073 "column": 3,
4074 "line": 112
4075 },
4076 "file": "src/lib/Menu.js",
4077 "id": "menu.window.minimize",
4078 "start": {
4079 "column": 12,
4080 "line": 109
4081 }
4082 },
4083 {
4084 "defaultMessage": "!!!Close",
4085 "end": {
4086 "column": 3,
4087 "line": 116
4088 },
4089 "file": "src/lib/Menu.js",
4090 "id": "menu.window.close",
4091 "start": {
4092 "column": 9,
4093 "line": 113
4094 }
4095 },
4096 {
4097 "defaultMessage": "!!!Learn More",
4098 "end": {
4099 "column": 3,
4100 "line": 120
4101 },
4102 "file": "src/lib/Menu.js",
4103 "id": "menu.help.learnMore",
4104 "start": {
4105 "column": 13,
4106 "line": 117
4107 }
4108 },
4109 {
4110 "defaultMessage": "!!!Changelog",
4111 "end": {
4112 "column": 3,
4113 "line": 124
4114 },
4115 "file": "src/lib/Menu.js",
4116 "id": "menu.help.changelog",
4117 "start": {
4118 "column": 13,
4119 "line": 121
4120 }
4121 },
4122 {
4123 "defaultMessage": "!!!Support",
4124 "end": {
4125 "column": 3,
4126 "line": 128
4127 },
4128 "file": "src/lib/Menu.js",
4129 "id": "menu.help.support",
4130 "start": {
4131 "column": 11,
4132 "line": 125
4133 }
4134 },
4135 {
4136 "defaultMessage": "!!!Terms of Service",
4137 "end": {
4138 "column": 3,
4139 "line": 132
4140 },
4141 "file": "src/lib/Menu.js",
4142 "id": "menu.help.tos",
4143 "start": {
4144 "column": 7,
4145 "line": 129
4146 }
4147 },
4148 {
4149 "defaultMessage": "!!!Privacy Statement",
4150 "end": {
4151 "column": 3,
4152 "line": 136
4153 },
4154 "file": "src/lib/Menu.js",
4155 "id": "menu.help.privacy",
4156 "start": {
4157 "column": 11,
4158 "line": 133
4159 }
4160 },
4161 {
4162 "defaultMessage": "!!!File",
4163 "end": {
4164 "column": 3,
4165 "line": 140
4166 },
4167 "file": "src/lib/Menu.js",
4168 "id": "menu.file",
4169 "start": {
4170 "column": 8,
4171 "line": 137
4172 }
4173 },
4174 {
4175 "defaultMessage": "!!!View",
4176 "end": {
4177 "column": 3,
4178 "line": 144
4179 },
4180 "file": "src/lib/Menu.js",
4181 "id": "menu.view",
4182 "start": {
4183 "column": 8,
4184 "line": 141
4185 }
4186 },
4187 {
4188 "defaultMessage": "!!!Services",
4189 "end": {
4190 "column": 3,
4191 "line": 148
4192 },
4193 "file": "src/lib/Menu.js",
4194 "id": "menu.services",
4195 "start": {
4196 "column": 12,
4197 "line": 145
4198 }
4199 },
4200 {
4201 "defaultMessage": "!!!Window",
4202 "end": {
4203 "column": 3,
4204 "line": 152
4205 },
4206 "file": "src/lib/Menu.js",
4207 "id": "menu.window",
4208 "start": {
4209 "column": 10,
4210 "line": 149
4211 }
4212 },
4213 {
4214 "defaultMessage": "!!!Help",
4215 "end": {
4216 "column": 3,
4217 "line": 156
4218 },
4219 "file": "src/lib/Menu.js",
4220 "id": "menu.help",
4221 "start": {
4222 "column": 8,
4223 "line": 153
4224 }
4225 },
4226 {
4227 "defaultMessage": "!!!About Franz",
4228 "end": {
4229 "column": 3,
4230 "line": 160
4231 },
4232 "file": "src/lib/Menu.js",
4233 "id": "menu.app.about",
4234 "start": {
4235 "column": 9,
4236 "line": 157
4237 }
4238 },
4239 {
4240 "defaultMessage": "!!!Settings",
4241 "end": {
4242 "column": 3,
4243 "line": 164
4244 },
4245 "file": "src/lib/Menu.js",
4246 "id": "menu.app.settings",
4247 "start": {
4248 "column": 12,
4249 "line": 161
4250 }
4251 },
4252 {
4253 "defaultMessage": "!!!Hide",
4254 "end": {
4255 "column": 3,
4256 "line": 168
4257 },
4258 "file": "src/lib/Menu.js",
4259 "id": "menu.app.hide",
4260 "start": {
4261 "column": 8,
4262 "line": 165
4263 }
4264 },
4265 {
4266 "defaultMessage": "!!!Hide Others",
4267 "end": {
4268 "column": 3,
4269 "line": 172
4270 },
4271 "file": "src/lib/Menu.js",
4272 "id": "menu.app.hideOthers",
4273 "start": {
4274 "column": 14,
4275 "line": 169
4276 }
4277 },
4278 {
4279 "defaultMessage": "!!!Unhide",
4280 "end": {
4281 "column": 3,
4282 "line": 176
4283 },
4284 "file": "src/lib/Menu.js",
4285 "id": "menu.app.unhide",
4286 "start": {
4287 "column": 10,
4288 "line": 173
4289 }
4290 },
4291 {
4292 "defaultMessage": "!!!Quit",
4293 "end": {
4294 "column": 3,
4295 "line": 180
4296 },
4297 "file": "src/lib/Menu.js",
4298 "id": "menu.app.quit",
4299 "start": {
4300 "column": 8,
4301 "line": 177
4302 }
4303 },
4304 {
4305 "defaultMessage": "!!!Add New Service...",
4306 "end": {
4307 "column": 3,
4308 "line": 184
4309 },
4310 "file": "src/lib/Menu.js",
4311 "id": "menu.services.addNewService",
4312 "start": {
4313 "column": 17,
4314 "line": 181
4315 }
4316 },
4317 {
4318 "defaultMessage": "!!!Add New Workspace...",
4319 "end": {
4320 "column": 3,
4321 "line": 188
4322 },
4323 "file": "src/lib/Menu.js",
4324 "id": "menu.workspaces.addNewWorkspace",
4325 "start": {
4326 "column": 19,
4327 "line": 185
4328 }
4329 },
4330 {
4331 "defaultMessage": "!!!Open workspace drawer",
4332 "end": {
4333 "column": 3,
4334 "line": 192
4335 },
4336 "file": "src/lib/Menu.js",
4337 "id": "menu.workspaces.openWorkspaceDrawer",
4338 "start": {
4339 "column": 23,
4340 "line": 189
4341 }
4342 },
4343 {
4344 "defaultMessage": "!!!Close workspace drawer",
4345 "end": {
4346 "column": 3,
4347 "line": 196
4348 },
4349 "file": "src/lib/Menu.js",
4350 "id": "menu.workspaces.closeWorkspaceDrawer",
4351 "start": {
4352 "column": 24,
4353 "line": 193
4354 }
4355 },
4356 {
4357 "defaultMessage": "!!!Activate next service...",
4358 "end": {
4359 "column": 3,
4360 "line": 200
4361 },
4362 "file": "src/lib/Menu.js",
4363 "id": "menu.services.setNextServiceActive",
4364 "start": {
4365 "column": 23,
4366 "line": 197
4367 }
4368 },
4369 {
4370 "defaultMessage": "!!!Activate previous service...",
4371 "end": {
4372 "column": 3,
4373 "line": 204
4374 },
4375 "file": "src/lib/Menu.js",
4376 "id": "menu.services.activatePreviousService",
4377 "start": {
4378 "column": 27,
4379 "line": 201
4380 }
4381 },
4382 {
4383 "defaultMessage": "!!!Disable notifications & audio",
4384 "end": {
4385 "column": 3,
4386 "line": 208
4387 },
4388 "file": "src/lib/Menu.js",
4389 "id": "sidebar.muteApp",
4390 "start": {
4391 "column": 11,
4392 "line": 205
4393 }
4394 },
4395 {
4396 "defaultMessage": "!!!Enable notifications & audio",
4397 "end": {
4398 "column": 3,
4399 "line": 212
4400 },
4401 "file": "src/lib/Menu.js",
4402 "id": "sidebar.unmuteApp",
4403 "start": {
4404 "column": 13,
4405 "line": 209
4406 }
4407 },
4408 {
4409 "defaultMessage": "!!!Workspaces",
4410 "end": {
4411 "column": 3,
4412 "line": 216
4413 },
4414 "file": "src/lib/Menu.js",
4415 "id": "menu.workspaces",
4416 "start": {
4417 "column": 14,
4418 "line": 213
4419 }
4420 },
4421 {
4422 "defaultMessage": "!!!Default",
4423 "end": {
4424 "column": 3,
4425 "line": 220
4426 },
4427 "file": "src/lib/Menu.js",
4428 "id": "menu.workspaces.defaultWorkspace",
4429 "start": {
4430 "column": 20,
4431 "line": 217
4432 }
4433 }
4434 ],
4435 "path": "src/lib/Menu.json"
4436 }
4437] \ No newline at end of file
diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json
index a9d0f789d..70b869557 100644
--- a/src/i18n/locales/en-US.json
+++ b/src/i18n/locales/en-US.json
@@ -1,6 +1,7 @@
1{ 1{
2 "app.errorHandler.action": "Reload", 2 "app.errorHandler.action": "Reload",
3 "app.errorHandler.headline": "Something went wrong", 3 "app.errorHandler.headline": "Something went wrong",
4 "feature.announcements.changelog.headline": "Changes in Franz {version}",
4 "feature.delayApp.action": "Get a Franz Supporter License", 5 "feature.delayApp.action": "Get a Franz Supporter License",
5 "feature.delayApp.headline": "Please purchase a Franz Supporter License to skip waiting", 6 "feature.delayApp.headline": "Please purchase a Franz Supporter License to skip waiting",
6 "feature.delayApp.text": "Franz will continue in {seconds} seconds.", 7 "feature.delayApp.text": "Franz will continue in {seconds} seconds.",
@@ -43,6 +44,7 @@
43 "login.submit.label": "Sign in", 44 "login.submit.label": "Sign in",
44 "login.tokenExpired": "Your session expired, please login again.", 45 "login.tokenExpired": "Your session expired, please login again.",
45 "menu.app.about": "About Franz", 46 "menu.app.about": "About Franz",
47 "menu.app.announcement": "What's new?",
46 "menu.app.hide": "Hide", 48 "menu.app.hide": "Hide",
47 "menu.app.hideOthers": "Hide Others", 49 "menu.app.hideOthers": "Hide Others",
48 "menu.app.quit": "Quit", 50 "menu.app.quit": "Quit",
diff --git a/src/i18n/messages/src/components/layout/AppLayout.json b/src/i18n/messages/src/components/layout/AppLayout.json
index 92593ed5c..26b8ce040 100644
--- a/src/i18n/messages/src/components/layout/AppLayout.json
+++ b/src/i18n/messages/src/components/layout/AppLayout.json
@@ -4,11 +4,11 @@
4 "defaultMessage": "!!!Your services have been updated.", 4 "defaultMessage": "!!!Your services have been updated.",
5 "file": "src/components/layout/AppLayout.js", 5 "file": "src/components/layout/AppLayout.js",
6 "start": { 6 "start": {
7 "line": 25, 7 "line": 27,
8 "column": 19 8 "column": 19
9 }, 9 },
10 "end": { 10 "end": {
11 "line": 28, 11 "line": 30,
12 "column": 3 12 "column": 3
13 } 13 }
14 }, 14 },
@@ -17,11 +17,11 @@
17 "defaultMessage": "!!!A new update for Franz is available.", 17 "defaultMessage": "!!!A new update for Franz is available.",
18 "file": "src/components/layout/AppLayout.js", 18 "file": "src/components/layout/AppLayout.js",
19 "start": { 19 "start": {
20 "line": 29, 20 "line": 31,
21 "column": 19 21 "column": 19
22 }, 22 },
23 "end": { 23 "end": {
24 "line": 32, 24 "line": 34,
25 "column": 3 25 "column": 3
26 } 26 }
27 }, 27 },
@@ -30,11 +30,11 @@
30 "defaultMessage": "!!!Reload services", 30 "defaultMessage": "!!!Reload services",
31 "file": "src/components/layout/AppLayout.js", 31 "file": "src/components/layout/AppLayout.js",
32 "start": { 32 "start": {
33 "line": 33, 33 "line": 35,
34 "column": 24 34 "column": 24
35 }, 35 },
36 "end": { 36 "end": {
37 "line": 36, 37 "line": 38,
38 "column": 3 38 "column": 3
39 } 39 }
40 }, 40 },
@@ -43,11 +43,11 @@
43 "defaultMessage": "!!!Changelog", 43 "defaultMessage": "!!!Changelog",
44 "file": "src/components/layout/AppLayout.js", 44 "file": "src/components/layout/AppLayout.js",
45 "start": { 45 "start": {
46 "line": 37, 46 "line": 39,
47 "column": 13 47 "column": 13
48 }, 48 },
49 "end": { 49 "end": {
50 "line": 40, 50 "line": 42,
51 "column": 3 51 "column": 3
52 } 52 }
53 }, 53 },
@@ -56,11 +56,11 @@
56 "defaultMessage": "!!!Restart & install update", 56 "defaultMessage": "!!!Restart & install update",
57 "file": "src/components/layout/AppLayout.js", 57 "file": "src/components/layout/AppLayout.js",
58 "start": { 58 "start": {
59 "line": 41, 59 "line": 43,
60 "column": 23 60 "column": 23
61 }, 61 },
62 "end": { 62 "end": {
63 "line": 44, 63 "line": 46,
64 "column": 3 64 "column": 3
65 } 65 }
66 }, 66 },
@@ -69,11 +69,11 @@
69 "defaultMessage": "!!!Could not load services and user information", 69 "defaultMessage": "!!!Could not load services and user information",
70 "file": "src/components/layout/AppLayout.js", 70 "file": "src/components/layout/AppLayout.js",
71 "start": { 71 "start": {
72 "line": 45, 72 "line": 47,
73 "column": 26 73 "column": 26
74 }, 74 },
75 "end": { 75 "end": {
76 "line": 48, 76 "line": 50,
77 "column": 3 77 "column": 3
78 } 78 }
79 } 79 }
diff --git a/src/i18n/messages/src/features/announcements/components/AnnouncementScreen.json b/src/i18n/messages/src/features/announcements/components/AnnouncementScreen.json
new file mode 100644
index 000000000..eb1b66916
--- /dev/null
+++ b/src/i18n/messages/src/features/announcements/components/AnnouncementScreen.json
@@ -0,0 +1,15 @@
1[
2 {
3 "id": "feature.announcements.changelog.headline",
4 "defaultMessage": "!!!Changes in Franz {version}",
5 "file": "src/features/announcements/components/AnnouncementScreen.js",
6 "start": {
7 "line": 20,
8 "column": 12
9 },
10 "end": {
11 "line": 23,
12 "column": 3
13 }
14 }
15] \ No newline at end of file
diff --git a/src/i18n/messages/src/lib/Menu.json b/src/i18n/messages/src/lib/Menu.json
index 3889d39e0..a2ce34cd4 100644
--- a/src/i18n/messages/src/lib/Menu.json
+++ b/src/i18n/messages/src/lib/Menu.json
@@ -4,11 +4,11 @@
4 "defaultMessage": "!!!Edit", 4 "defaultMessage": "!!!Edit",
5 "file": "src/lib/Menu.js", 5 "file": "src/lib/Menu.js",
6 "start": { 6 "start": {
7 "line": 13, 7 "line": 14,
8 "column": 8 8 "column": 8
9 }, 9 },
10 "end": { 10 "end": {
11 "line": 16, 11 "line": 17,
12 "column": 3 12 "column": 3
13 } 13 }
14 }, 14 },
@@ -17,11 +17,11 @@
17 "defaultMessage": "!!!Undo", 17 "defaultMessage": "!!!Undo",
18 "file": "src/lib/Menu.js", 18 "file": "src/lib/Menu.js",
19 "start": { 19 "start": {
20 "line": 17, 20 "line": 18,
21 "column": 8 21 "column": 8
22 }, 22 },
23 "end": { 23 "end": {
24 "line": 20, 24 "line": 21,
25 "column": 3 25 "column": 3
26 } 26 }
27 }, 27 },
@@ -30,11 +30,11 @@
30 "defaultMessage": "!!!Redo", 30 "defaultMessage": "!!!Redo",
31 "file": "src/lib/Menu.js", 31 "file": "src/lib/Menu.js",
32 "start": { 32 "start": {
33 "line": 21, 33 "line": 22,
34 "column": 8 34 "column": 8
35 }, 35 },
36 "end": { 36 "end": {
37 "line": 24, 37 "line": 25,
38 "column": 3 38 "column": 3
39 } 39 }
40 }, 40 },
@@ -43,11 +43,11 @@
43 "defaultMessage": "!!!Cut", 43 "defaultMessage": "!!!Cut",
44 "file": "src/lib/Menu.js", 44 "file": "src/lib/Menu.js",
45 "start": { 45 "start": {
46 "line": 25, 46 "line": 26,
47 "column": 7 47 "column": 7
48 }, 48 },
49 "end": { 49 "end": {
50 "line": 28, 50 "line": 29,
51 "column": 3 51 "column": 3
52 } 52 }
53 }, 53 },
@@ -56,11 +56,11 @@
56 "defaultMessage": "!!!Copy", 56 "defaultMessage": "!!!Copy",
57 "file": "src/lib/Menu.js", 57 "file": "src/lib/Menu.js",
58 "start": { 58 "start": {
59 "line": 29, 59 "line": 30,
60 "column": 8 60 "column": 8
61 }, 61 },
62 "end": { 62 "end": {
63 "line": 32, 63 "line": 33,
64 "column": 3 64 "column": 3
65 } 65 }
66 }, 66 },
@@ -69,11 +69,11 @@
69 "defaultMessage": "!!!Paste", 69 "defaultMessage": "!!!Paste",
70 "file": "src/lib/Menu.js", 70 "file": "src/lib/Menu.js",
71 "start": { 71 "start": {
72 "line": 33, 72 "line": 34,
73 "column": 9 73 "column": 9
74 }, 74 },
75 "end": { 75 "end": {
76 "line": 36, 76 "line": 37,
77 "column": 3 77 "column": 3
78 } 78 }
79 }, 79 },
@@ -82,11 +82,11 @@
82 "defaultMessage": "!!!Paste And Match Style", 82 "defaultMessage": "!!!Paste And Match Style",
83 "file": "src/lib/Menu.js", 83 "file": "src/lib/Menu.js",
84 "start": { 84 "start": {
85 "line": 37, 85 "line": 38,
86 "column": 22 86 "column": 22
87 }, 87 },
88 "end": { 88 "end": {
89 "line": 40, 89 "line": 41,
90 "column": 3 90 "column": 3
91 } 91 }
92 }, 92 },
@@ -95,11 +95,11 @@
95 "defaultMessage": "!!!Delete", 95 "defaultMessage": "!!!Delete",
96 "file": "src/lib/Menu.js", 96 "file": "src/lib/Menu.js",
97 "start": { 97 "start": {
98 "line": 41, 98 "line": 42,
99 "column": 10 99 "column": 10
100 }, 100 },
101 "end": { 101 "end": {
102 "line": 44, 102 "line": 45,
103 "column": 3 103 "column": 3
104 } 104 }
105 }, 105 },
@@ -108,11 +108,11 @@
108 "defaultMessage": "!!!Select All", 108 "defaultMessage": "!!!Select All",
109 "file": "src/lib/Menu.js", 109 "file": "src/lib/Menu.js",
110 "start": { 110 "start": {
111 "line": 45, 111 "line": 46,
112 "column": 13 112 "column": 13
113 }, 113 },
114 "end": { 114 "end": {
115 "line": 48, 115 "line": 49,
116 "column": 3 116 "column": 3
117 } 117 }
118 }, 118 },
@@ -121,11 +121,11 @@
121 "defaultMessage": "!!!Speech", 121 "defaultMessage": "!!!Speech",
122 "file": "src/lib/Menu.js", 122 "file": "src/lib/Menu.js",
123 "start": { 123 "start": {
124 "line": 49, 124 "line": 50,
125 "column": 10 125 "column": 10
126 }, 126 },
127 "end": { 127 "end": {
128 "line": 52, 128 "line": 53,
129 "column": 3 129 "column": 3
130 } 130 }
131 }, 131 },
@@ -134,11 +134,11 @@
134 "defaultMessage": "!!!Start Speaking", 134 "defaultMessage": "!!!Start Speaking",
135 "file": "src/lib/Menu.js", 135 "file": "src/lib/Menu.js",
136 "start": { 136 "start": {
137 "line": 53, 137 "line": 54,
138 "column": 17 138 "column": 17
139 }, 139 },
140 "end": { 140 "end": {
141 "line": 56, 141 "line": 57,
142 "column": 3 142 "column": 3
143 } 143 }
144 }, 144 },
@@ -147,11 +147,11 @@
147 "defaultMessage": "!!!Stop Speaking", 147 "defaultMessage": "!!!Stop Speaking",
148 "file": "src/lib/Menu.js", 148 "file": "src/lib/Menu.js",
149 "start": { 149 "start": {
150 "line": 57, 150 "line": 58,
151 "column": 16 151 "column": 16
152 }, 152 },
153 "end": { 153 "end": {
154 "line": 60, 154 "line": 61,
155 "column": 3 155 "column": 3
156 } 156 }
157 }, 157 },
@@ -160,11 +160,11 @@
160 "defaultMessage": "!!!Start Dictation", 160 "defaultMessage": "!!!Start Dictation",
161 "file": "src/lib/Menu.js", 161 "file": "src/lib/Menu.js",
162 "start": { 162 "start": {
163 "line": 61, 163 "line": 62,
164 "column": 18 164 "column": 18
165 }, 165 },
166 "end": { 166 "end": {
167 "line": 64, 167 "line": 65,
168 "column": 3 168 "column": 3
169 } 169 }
170 }, 170 },
@@ -173,11 +173,11 @@
173 "defaultMessage": "!!!Emoji & Symbols", 173 "defaultMessage": "!!!Emoji & Symbols",
174 "file": "src/lib/Menu.js", 174 "file": "src/lib/Menu.js",
175 "start": { 175 "start": {
176 "line": 65, 176 "line": 66,
177 "column": 16 177 "column": 16
178 }, 178 },
179 "end": { 179 "end": {
180 "line": 68, 180 "line": 69,
181 "column": 3 181 "column": 3
182 } 182 }
183 }, 183 },
@@ -186,11 +186,11 @@
186 "defaultMessage": "!!!Actual Size", 186 "defaultMessage": "!!!Actual Size",
187 "file": "src/lib/Menu.js", 187 "file": "src/lib/Menu.js",
188 "start": { 188 "start": {
189 "line": 69, 189 "line": 70,
190 "column": 13 190 "column": 13
191 }, 191 },
192 "end": { 192 "end": {
193 "line": 72, 193 "line": 73,
194 "column": 3 194 "column": 3
195 } 195 }
196 }, 196 },
@@ -199,11 +199,11 @@
199 "defaultMessage": "!!!Zoom In", 199 "defaultMessage": "!!!Zoom In",
200 "file": "src/lib/Menu.js", 200 "file": "src/lib/Menu.js",
201 "start": { 201 "start": {
202 "line": 73, 202 "line": 74,
203 "column": 10 203 "column": 10
204 }, 204 },
205 "end": { 205 "end": {
206 "line": 76, 206 "line": 77,
207 "column": 3 207 "column": 3
208 } 208 }
209 }, 209 },
@@ -212,11 +212,11 @@
212 "defaultMessage": "!!!Zoom Out", 212 "defaultMessage": "!!!Zoom Out",
213 "file": "src/lib/Menu.js", 213 "file": "src/lib/Menu.js",
214 "start": { 214 "start": {
215 "line": 77, 215 "line": 78,
216 "column": 11 216 "column": 11
217 }, 217 },
218 "end": { 218 "end": {
219 "line": 80, 219 "line": 81,
220 "column": 3 220 "column": 3
221 } 221 }
222 }, 222 },
@@ -225,11 +225,11 @@
225 "defaultMessage": "!!!Enter Full Screen", 225 "defaultMessage": "!!!Enter Full Screen",
226 "file": "src/lib/Menu.js", 226 "file": "src/lib/Menu.js",
227 "start": { 227 "start": {
228 "line": 81, 228 "line": 82,
229 "column": 19 229 "column": 19
230 }, 230 },
231 "end": { 231 "end": {
232 "line": 84, 232 "line": 85,
233 "column": 3 233 "column": 3
234 } 234 }
235 }, 235 },
@@ -238,11 +238,11 @@
238 "defaultMessage": "!!!Exit Full Screen", 238 "defaultMessage": "!!!Exit Full Screen",
239 "file": "src/lib/Menu.js", 239 "file": "src/lib/Menu.js",
240 "start": { 240 "start": {
241 "line": 85, 241 "line": 86,
242 "column": 18 242 "column": 18
243 }, 243 },
244 "end": { 244 "end": {
245 "line": 88, 245 "line": 89,
246 "column": 3 246 "column": 3
247 } 247 }
248 }, 248 },
@@ -251,11 +251,11 @@
251 "defaultMessage": "!!!Toggle Full Screen", 251 "defaultMessage": "!!!Toggle Full Screen",
252 "file": "src/lib/Menu.js", 252 "file": "src/lib/Menu.js",
253 "start": { 253 "start": {
254 "line": 89, 254 "line": 90,
255 "column": 20 255 "column": 20
256 }, 256 },
257 "end": { 257 "end": {
258 "line": 92, 258 "line": 93,
259 "column": 3 259 "column": 3
260 } 260 }
261 }, 261 },
@@ -264,11 +264,11 @@
264 "defaultMessage": "!!!Toggle Developer Tools", 264 "defaultMessage": "!!!Toggle Developer Tools",
265 "file": "src/lib/Menu.js", 265 "file": "src/lib/Menu.js",
266 "start": { 266 "start": {
267 "line": 93, 267 "line": 94,
268 "column": 18 268 "column": 18
269 }, 269 },
270 "end": { 270 "end": {
271 "line": 96, 271 "line": 97,
272 "column": 3 272 "column": 3
273 } 273 }
274 }, 274 },
@@ -277,11 +277,11 @@
277 "defaultMessage": "!!!Toggle Service Developer Tools", 277 "defaultMessage": "!!!Toggle Service Developer Tools",
278 "file": "src/lib/Menu.js", 278 "file": "src/lib/Menu.js",
279 "start": { 279 "start": {
280 "line": 97, 280 "line": 98,
281 "column": 25 281 "column": 25
282 }, 282 },
283 "end": { 283 "end": {
284 "line": 100, 284 "line": 101,
285 "column": 3 285 "column": 3
286 } 286 }
287 }, 287 },
@@ -290,11 +290,11 @@
290 "defaultMessage": "!!!Reload Service", 290 "defaultMessage": "!!!Reload Service",
291 "file": "src/lib/Menu.js", 291 "file": "src/lib/Menu.js",
292 "start": { 292 "start": {
293 "line": 101, 293 "line": 102,
294 "column": 17 294 "column": 17
295 }, 295 },
296 "end": { 296 "end": {
297 "line": 104, 297 "line": 105,
298 "column": 3 298 "column": 3
299 } 299 }
300 }, 300 },
@@ -303,11 +303,11 @@
303 "defaultMessage": "!!!Reload Franz", 303 "defaultMessage": "!!!Reload Franz",
304 "file": "src/lib/Menu.js", 304 "file": "src/lib/Menu.js",
305 "start": { 305 "start": {
306 "line": 105, 306 "line": 106,
307 "column": 15 307 "column": 15
308 }, 308 },
309 "end": { 309 "end": {
310 "line": 108, 310 "line": 109,
311 "column": 3 311 "column": 3
312 } 312 }
313 }, 313 },
@@ -316,11 +316,11 @@
316 "defaultMessage": "!!!Minimize", 316 "defaultMessage": "!!!Minimize",
317 "file": "src/lib/Menu.js", 317 "file": "src/lib/Menu.js",
318 "start": { 318 "start": {
319 "line": 109, 319 "line": 110,
320 "column": 12 320 "column": 12
321 }, 321 },
322 "end": { 322 "end": {
323 "line": 112, 323 "line": 113,
324 "column": 3 324 "column": 3
325 } 325 }
326 }, 326 },
@@ -329,11 +329,11 @@
329 "defaultMessage": "!!!Close", 329 "defaultMessage": "!!!Close",
330 "file": "src/lib/Menu.js", 330 "file": "src/lib/Menu.js",
331 "start": { 331 "start": {
332 "line": 113, 332 "line": 114,
333 "column": 9 333 "column": 9
334 }, 334 },
335 "end": { 335 "end": {
336 "line": 116, 336 "line": 117,
337 "column": 3 337 "column": 3
338 } 338 }
339 }, 339 },
@@ -342,11 +342,11 @@
342 "defaultMessage": "!!!Learn More", 342 "defaultMessage": "!!!Learn More",
343 "file": "src/lib/Menu.js", 343 "file": "src/lib/Menu.js",
344 "start": { 344 "start": {
345 "line": 117, 345 "line": 118,
346 "column": 13 346 "column": 13
347 }, 347 },
348 "end": { 348 "end": {
349 "line": 120, 349 "line": 121,
350 "column": 3 350 "column": 3
351 } 351 }
352 }, 352 },
@@ -355,11 +355,11 @@
355 "defaultMessage": "!!!Changelog", 355 "defaultMessage": "!!!Changelog",
356 "file": "src/lib/Menu.js", 356 "file": "src/lib/Menu.js",
357 "start": { 357 "start": {
358 "line": 121, 358 "line": 122,
359 "column": 13 359 "column": 13
360 }, 360 },
361 "end": { 361 "end": {
362 "line": 124, 362 "line": 125,
363 "column": 3 363 "column": 3
364 } 364 }
365 }, 365 },
@@ -368,11 +368,11 @@
368 "defaultMessage": "!!!Support", 368 "defaultMessage": "!!!Support",
369 "file": "src/lib/Menu.js", 369 "file": "src/lib/Menu.js",
370 "start": { 370 "start": {
371 "line": 125, 371 "line": 126,
372 "column": 11 372 "column": 11
373 }, 373 },
374 "end": { 374 "end": {
375 "line": 128, 375 "line": 129,
376 "column": 3 376 "column": 3
377 } 377 }
378 }, 378 },
@@ -381,11 +381,11 @@
381 "defaultMessage": "!!!Terms of Service", 381 "defaultMessage": "!!!Terms of Service",
382 "file": "src/lib/Menu.js", 382 "file": "src/lib/Menu.js",
383 "start": { 383 "start": {
384 "line": 129, 384 "line": 130,
385 "column": 7 385 "column": 7
386 }, 386 },
387 "end": { 387 "end": {
388 "line": 132, 388 "line": 133,
389 "column": 3 389 "column": 3
390 } 390 }
391 }, 391 },
@@ -394,11 +394,11 @@
394 "defaultMessage": "!!!Privacy Statement", 394 "defaultMessage": "!!!Privacy Statement",
395 "file": "src/lib/Menu.js", 395 "file": "src/lib/Menu.js",
396 "start": { 396 "start": {
397 "line": 133, 397 "line": 134,
398 "column": 11 398 "column": 11
399 }, 399 },
400 "end": { 400 "end": {
401 "line": 136, 401 "line": 137,
402 "column": 3 402 "column": 3
403 } 403 }
404 }, 404 },
@@ -407,11 +407,11 @@
407 "defaultMessage": "!!!File", 407 "defaultMessage": "!!!File",
408 "file": "src/lib/Menu.js", 408 "file": "src/lib/Menu.js",
409 "start": { 409 "start": {
410 "line": 137, 410 "line": 138,
411 "column": 8 411 "column": 8
412 }, 412 },
413 "end": { 413 "end": {
414 "line": 140, 414 "line": 141,
415 "column": 3 415 "column": 3
416 } 416 }
417 }, 417 },
@@ -420,11 +420,11 @@
420 "defaultMessage": "!!!View", 420 "defaultMessage": "!!!View",
421 "file": "src/lib/Menu.js", 421 "file": "src/lib/Menu.js",
422 "start": { 422 "start": {
423 "line": 141, 423 "line": 142,
424 "column": 8 424 "column": 8
425 }, 425 },
426 "end": { 426 "end": {
427 "line": 144, 427 "line": 145,
428 "column": 3 428 "column": 3
429 } 429 }
430 }, 430 },
@@ -433,11 +433,11 @@
433 "defaultMessage": "!!!Services", 433 "defaultMessage": "!!!Services",
434 "file": "src/lib/Menu.js", 434 "file": "src/lib/Menu.js",
435 "start": { 435 "start": {
436 "line": 145, 436 "line": 146,
437 "column": 12 437 "column": 12
438 }, 438 },
439 "end": { 439 "end": {
440 "line": 148, 440 "line": 149,
441 "column": 3 441 "column": 3
442 } 442 }
443 }, 443 },
@@ -446,11 +446,11 @@
446 "defaultMessage": "!!!Window", 446 "defaultMessage": "!!!Window",
447 "file": "src/lib/Menu.js", 447 "file": "src/lib/Menu.js",
448 "start": { 448 "start": {
449 "line": 149, 449 "line": 150,
450 "column": 10 450 "column": 10
451 }, 451 },
452 "end": { 452 "end": {
453 "line": 152, 453 "line": 153,
454 "column": 3 454 "column": 3
455 } 455 }
456 }, 456 },
@@ -459,11 +459,11 @@
459 "defaultMessage": "!!!Help", 459 "defaultMessage": "!!!Help",
460 "file": "src/lib/Menu.js", 460 "file": "src/lib/Menu.js",
461 "start": { 461 "start": {
462 "line": 153, 462 "line": 154,
463 "column": 8 463 "column": 8
464 }, 464 },
465 "end": { 465 "end": {
466 "line": 156, 466 "line": 157,
467 "column": 3 467 "column": 3
468 } 468 }
469 }, 469 },
@@ -472,11 +472,24 @@
472 "defaultMessage": "!!!About Franz", 472 "defaultMessage": "!!!About Franz",
473 "file": "src/lib/Menu.js", 473 "file": "src/lib/Menu.js",
474 "start": { 474 "start": {
475 "line": 157, 475 "line": 158,
476 "column": 9 476 "column": 9
477 }, 477 },
478 "end": { 478 "end": {
479 "line": 160, 479 "line": 161,
480 "column": 3
481 }
482 },
483 {
484 "id": "menu.app.announcement",
485 "defaultMessage": "!!!What's new?",
486 "file": "src/lib/Menu.js",
487 "start": {
488 "line": 162,
489 "column": 16
490 },
491 "end": {
492 "line": 165,
480 "column": 3 493 "column": 3
481 } 494 }
482 }, 495 },
@@ -485,11 +498,11 @@
485 "defaultMessage": "!!!Settings", 498 "defaultMessage": "!!!Settings",
486 "file": "src/lib/Menu.js", 499 "file": "src/lib/Menu.js",
487 "start": { 500 "start": {
488 "line": 161, 501 "line": 166,
489 "column": 12 502 "column": 12
490 }, 503 },
491 "end": { 504 "end": {
492 "line": 164, 505 "line": 169,
493 "column": 3 506 "column": 3
494 } 507 }
495 }, 508 },
@@ -498,11 +511,11 @@
498 "defaultMessage": "!!!Hide", 511 "defaultMessage": "!!!Hide",
499 "file": "src/lib/Menu.js", 512 "file": "src/lib/Menu.js",
500 "start": { 513 "start": {
501 "line": 165, 514 "line": 170,
502 "column": 8 515 "column": 8
503 }, 516 },
504 "end": { 517 "end": {
505 "line": 168, 518 "line": 173,
506 "column": 3 519 "column": 3
507 } 520 }
508 }, 521 },
@@ -511,11 +524,11 @@
511 "defaultMessage": "!!!Hide Others", 524 "defaultMessage": "!!!Hide Others",
512 "file": "src/lib/Menu.js", 525 "file": "src/lib/Menu.js",
513 "start": { 526 "start": {
514 "line": 169, 527 "line": 174,
515 "column": 14 528 "column": 14
516 }, 529 },
517 "end": { 530 "end": {
518 "line": 172, 531 "line": 177,
519 "column": 3 532 "column": 3
520 } 533 }
521 }, 534 },
@@ -524,11 +537,11 @@
524 "defaultMessage": "!!!Unhide", 537 "defaultMessage": "!!!Unhide",
525 "file": "src/lib/Menu.js", 538 "file": "src/lib/Menu.js",
526 "start": { 539 "start": {
527 "line": 173, 540 "line": 178,
528 "column": 10 541 "column": 10
529 }, 542 },
530 "end": { 543 "end": {
531 "line": 176, 544 "line": 181,
532 "column": 3 545 "column": 3
533 } 546 }
534 }, 547 },
@@ -537,11 +550,11 @@
537 "defaultMessage": "!!!Quit", 550 "defaultMessage": "!!!Quit",
538 "file": "src/lib/Menu.js", 551 "file": "src/lib/Menu.js",
539 "start": { 552 "start": {
540 "line": 177, 553 "line": 182,
541 "column": 8 554 "column": 8
542 }, 555 },
543 "end": { 556 "end": {
544 "line": 180, 557 "line": 185,
545 "column": 3 558 "column": 3
546 } 559 }
547 }, 560 },
@@ -550,11 +563,11 @@
550 "defaultMessage": "!!!Add New Service...", 563 "defaultMessage": "!!!Add New Service...",
551 "file": "src/lib/Menu.js", 564 "file": "src/lib/Menu.js",
552 "start": { 565 "start": {
553 "line": 181, 566 "line": 186,
554 "column": 17 567 "column": 17
555 }, 568 },
556 "end": { 569 "end": {
557 "line": 184, 570 "line": 189,
558 "column": 3 571 "column": 3
559 } 572 }
560 }, 573 },
@@ -563,11 +576,11 @@
563 "defaultMessage": "!!!Add New Workspace...", 576 "defaultMessage": "!!!Add New Workspace...",
564 "file": "src/lib/Menu.js", 577 "file": "src/lib/Menu.js",
565 "start": { 578 "start": {
566 "line": 185, 579 "line": 190,
567 "column": 19 580 "column": 19
568 }, 581 },
569 "end": { 582 "end": {
570 "line": 188, 583 "line": 193,
571 "column": 3 584 "column": 3
572 } 585 }
573 }, 586 },
@@ -576,11 +589,11 @@
576 "defaultMessage": "!!!Open workspace drawer", 589 "defaultMessage": "!!!Open workspace drawer",
577 "file": "src/lib/Menu.js", 590 "file": "src/lib/Menu.js",
578 "start": { 591 "start": {
579 "line": 189, 592 "line": 194,
580 "column": 23 593 "column": 23
581 }, 594 },
582 "end": { 595 "end": {
583 "line": 192, 596 "line": 197,
584 "column": 3 597 "column": 3
585 } 598 }
586 }, 599 },
@@ -589,11 +602,11 @@
589 "defaultMessage": "!!!Close workspace drawer", 602 "defaultMessage": "!!!Close workspace drawer",
590 "file": "src/lib/Menu.js", 603 "file": "src/lib/Menu.js",
591 "start": { 604 "start": {
592 "line": 193, 605 "line": 198,
593 "column": 24 606 "column": 24
594 }, 607 },
595 "end": { 608 "end": {
596 "line": 196, 609 "line": 201,
597 "column": 3 610 "column": 3
598 } 611 }
599 }, 612 },
@@ -602,11 +615,11 @@
602 "defaultMessage": "!!!Activate next service...", 615 "defaultMessage": "!!!Activate next service...",
603 "file": "src/lib/Menu.js", 616 "file": "src/lib/Menu.js",
604 "start": { 617 "start": {
605 "line": 197, 618 "line": 202,
606 "column": 23 619 "column": 23
607 }, 620 },
608 "end": { 621 "end": {
609 "line": 200, 622 "line": 205,
610 "column": 3 623 "column": 3
611 } 624 }
612 }, 625 },
@@ -615,11 +628,11 @@
615 "defaultMessage": "!!!Activate previous service...", 628 "defaultMessage": "!!!Activate previous service...",
616 "file": "src/lib/Menu.js", 629 "file": "src/lib/Menu.js",
617 "start": { 630 "start": {
618 "line": 201, 631 "line": 206,
619 "column": 27 632 "column": 27
620 }, 633 },
621 "end": { 634 "end": {
622 "line": 204, 635 "line": 209,
623 "column": 3 636 "column": 3
624 } 637 }
625 }, 638 },
@@ -628,11 +641,11 @@
628 "defaultMessage": "!!!Disable notifications & audio", 641 "defaultMessage": "!!!Disable notifications & audio",
629 "file": "src/lib/Menu.js", 642 "file": "src/lib/Menu.js",
630 "start": { 643 "start": {
631 "line": 205, 644 "line": 210,
632 "column": 11 645 "column": 11
633 }, 646 },
634 "end": { 647 "end": {
635 "line": 208, 648 "line": 213,
636 "column": 3 649 "column": 3
637 } 650 }
638 }, 651 },
@@ -641,11 +654,11 @@
641 "defaultMessage": "!!!Enable notifications & audio", 654 "defaultMessage": "!!!Enable notifications & audio",
642 "file": "src/lib/Menu.js", 655 "file": "src/lib/Menu.js",
643 "start": { 656 "start": {
644 "line": 209, 657 "line": 214,
645 "column": 13 658 "column": 13
646 }, 659 },
647 "end": { 660 "end": {
648 "line": 212, 661 "line": 217,
649 "column": 3 662 "column": 3
650 } 663 }
651 }, 664 },
@@ -654,11 +667,11 @@
654 "defaultMessage": "!!!Workspaces", 667 "defaultMessage": "!!!Workspaces",
655 "file": "src/lib/Menu.js", 668 "file": "src/lib/Menu.js",
656 "start": { 669 "start": {
657 "line": 213, 670 "line": 218,
658 "column": 14 671 "column": 14
659 }, 672 },
660 "end": { 673 "end": {
661 "line": 216, 674 "line": 221,
662 "column": 3 675 "column": 3
663 } 676 }
664 }, 677 },
@@ -667,11 +680,11 @@
667 "defaultMessage": "!!!Default", 680 "defaultMessage": "!!!Default",
668 "file": "src/lib/Menu.js", 681 "file": "src/lib/Menu.js",
669 "start": { 682 "start": {
670 "line": 217, 683 "line": 222,
671 "column": 20 684 "column": 20
672 }, 685 },
673 "end": { 686 "end": {
674 "line": 220, 687 "line": 225,
675 "column": 3 688 "column": 3
676 } 689 }
677 } 690 }
diff --git a/src/lib/Menu.js b/src/lib/Menu.js
index a4e41c17c..6bea67860 100644
--- a/src/lib/Menu.js
+++ b/src/lib/Menu.js
@@ -6,6 +6,7 @@ import { isMac, ctrlKey, cmdKey } from '../environment';
6import { GA_CATEGORY_WORKSPACES, workspaceStore } from '../features/workspaces/index'; 6import { GA_CATEGORY_WORKSPACES, workspaceStore } from '../features/workspaces/index';
7import { workspaceActions } from '../features/workspaces/actions'; 7import { workspaceActions } from '../features/workspaces/actions';
8import { gaEvent } from './analytics'; 8import { gaEvent } from './analytics';
9import { announcementActions } from '../features/announcements/actions';
9 10
10const { app, Menu, dialog } = remote; 11const { app, Menu, dialog } = remote;
11 12
@@ -158,6 +159,10 @@ const menuItems = defineMessages({
158 id: 'menu.app.about', 159 id: 'menu.app.about',
159 defaultMessage: '!!!About Franz', 160 defaultMessage: '!!!About Franz',
160 }, 161 },
162 announcement: {
163 id: 'menu.app.announcement',
164 defaultMessage: '!!!What\'s new?',
165 },
161 settings: { 166 settings: {
162 id: 'menu.app.settings', 167 id: 'menu.app.settings',
163 defaultMessage: '!!!Settings', 168 defaultMessage: '!!!Settings',
@@ -348,8 +353,10 @@ const _templateFactory = intl => [
348 click() { shell.openExternal('https://meetfranz.com'); }, 353 click() { shell.openExternal('https://meetfranz.com'); },
349 }, 354 },
350 { 355 {
351 label: intl.formatMessage(menuItems.changelog), 356 label: intl.formatMessage(menuItems.announcement),
352 click() { shell.openExternal('https://github.com/meetfranz/franz/blob/master/CHANGELOG.md'); }, 357 click: () => {
358 announcementActions.show();
359 },
353 }, 360 },
354 { 361 {
355 type: 'separator', 362 type: 'separator',
diff --git a/src/stores/AppStore.js b/src/stores/AppStore.js
index 351ad6422..e68e797ef 100644
--- a/src/stores/AppStore.js
+++ b/src/stores/AppStore.js
@@ -67,6 +67,8 @@ export default class AppStore extends Store {
67 67
68 @observable isFocused = true; 68 @observable isFocused = true;
69 69
70 @observable nextAppReleaseVersion = null;
71
70 dictionaries = []; 72 dictionaries = [];
71 73
72 constructor(...args) { 74 constructor(...args) {
@@ -123,7 +125,7 @@ export default class AppStore extends Store {
123 ipcRenderer.on('autoUpdate', (event, data) => { 125 ipcRenderer.on('autoUpdate', (event, data) => {
124 if (data.available) { 126 if (data.available) {
125 this.updateStatus = this.updateStatusTypes.AVAILABLE; 127 this.updateStatus = this.updateStatusTypes.AVAILABLE;
126 128 this.nextAppReleaseVersion = data.version;
127 if (isMac) { 129 if (isMac) {
128 app.dock.bounce(); 130 app.dock.bounce();
129 } 131 }
@@ -172,7 +174,6 @@ export default class AppStore extends Store {
172 reaction(() => this.stores.router.location.pathname, (pathname) => { 174 reaction(() => this.stores.router.location.pathname, (pathname) => {
173 gaPage(pathname); 175 gaPage(pathname);
174 }); 176 });
175 console.log('router location', this.stores.router.location);
176 } 177 }
177 178
178 @computed get cacheSize() { 179 @computed get cacheSize() {
diff --git a/src/stores/FeaturesStore.js b/src/stores/FeaturesStore.js
index 8fe576813..dcda021c1 100644
--- a/src/stores/FeaturesStore.js
+++ b/src/stores/FeaturesStore.js
@@ -14,6 +14,7 @@ import serviceProxy from '../features/serviceProxy';
14import basicAuth from '../features/basicAuth'; 14import basicAuth from '../features/basicAuth';
15import workspaces from '../features/workspaces'; 15import workspaces from '../features/workspaces';
16import shareFranz from '../features/shareFranz'; 16import shareFranz from '../features/shareFranz';
17import announcements from '../features/announcements';
17 18
18import { DEFAULT_FEATURES_CONFIG } from '../config'; 19import { DEFAULT_FEATURES_CONFIG } from '../config';
19 20
@@ -71,5 +72,6 @@ export default class FeaturesStore extends Store {
71 basicAuth(this.stores, this.actions); 72 basicAuth(this.stores, this.actions);
72 workspaces(this.stores, this.actions); 73 workspaces(this.stores, this.actions);
73 shareFranz(this.stores, this.actions); 74 shareFranz(this.stores, this.actions);
75 announcements(this.stores, this.actions);
74 } 76 }
75} 77}
diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js
index 0ec6bf550..d04fdd0c5 100644
--- a/src/stores/ServicesStore.js
+++ b/src/stores/ServicesStore.js
@@ -36,6 +36,7 @@ export default class ServicesStore extends Store {
36 36
37 // Register action handlers 37 // Register action handlers
38 this.actions.service.setActive.listen(this._setActive.bind(this)); 38 this.actions.service.setActive.listen(this._setActive.bind(this));
39 this.actions.service.blurActive.listen(this._blurActive.bind(this));
39 this.actions.service.setActiveNext.listen(this._setActiveNext.bind(this)); 40 this.actions.service.setActiveNext.listen(this._setActiveNext.bind(this));
40 this.actions.service.setActivePrev.listen(this._setActivePrev.bind(this)); 41 this.actions.service.setActivePrev.listen(this._setActivePrev.bind(this));
41 this.actions.service.showAddServiceInterface.listen(this._showAddServiceInterface.bind(this)); 42 this.actions.service.showAddServiceInterface.listen(this._showAddServiceInterface.bind(this));
@@ -301,6 +302,11 @@ export default class ServicesStore extends Store {
301 this._focusActiveService(); 302 this._focusActiveService();
302 } 303 }
303 304
305 @action _blurActive() {
306 if (!this.active) return;
307 this.active.isActive = false;
308 }
309
304 @action _setActiveNext() { 310 @action _setActiveNext() {
305 const nextIndex = this._wrapIndex(this.allDisplayed.findIndex(service => service.isActive), 1, this.allDisplayed.length); 311 const nextIndex = this._wrapIndex(this.allDisplayed.findIndex(service => service.isActive), 1, this.allDisplayed.length);
306 312
diff --git a/src/stores/index.js b/src/stores/index.js
index 96b844c95..1912418a2 100644
--- a/src/stores/index.js
+++ b/src/stores/index.js
@@ -10,6 +10,8 @@ import PaymentStore from './PaymentStore';
10import NewsStore from './NewsStore'; 10import NewsStore from './NewsStore';
11import RequestStore from './RequestStore'; 11import RequestStore from './RequestStore';
12import GlobalErrorStore from './GlobalErrorStore'; 12import GlobalErrorStore from './GlobalErrorStore';
13import { workspaceStore } from '../features/workspaces';
14import { announcementsStore } from '../features/announcements';
13 15
14export default (api, actions, router) => { 16export default (api, actions, router) => {
15 const stores = {}; 17 const stores = {};
@@ -27,6 +29,8 @@ export default (api, actions, router) => {
27 news: new NewsStore(stores, api, actions), 29 news: new NewsStore(stores, api, actions),
28 requests: new RequestStore(stores, api, actions), 30 requests: new RequestStore(stores, api, actions),
29 globalError: new GlobalErrorStore(stores, api, actions), 31 globalError: new GlobalErrorStore(stores, api, actions),
32 workspaces: workspaceStore,
33 announcements: announcementsStore,
30 }); 34 });
31 // Initialize all stores 35 // Initialize all stores
32 Object.keys(stores).forEach((name) => { 36 Object.keys(stores).forEach((name) => {
diff --git a/src/stores/lib/Reaction.js b/src/stores/lib/Reaction.js
index 46aa4dae6..f2642908f 100644
--- a/src/stores/lib/Reaction.js
+++ b/src/stores/lib/Reaction.js
@@ -1,24 +1,31 @@
1// @flow
2import { autorun } from 'mobx'; 1import { autorun } from 'mobx';
3 2
4export default class Reaction { 3export default class Reaction {
5 reaction; 4 reaction;
6 5
7 hasBeenStarted; 6 isRunning = false;
8 7
9 dispose; 8 dispose;
10 9
11 constructor(reaction) { 10 constructor(reaction) {
12 this.reaction = reaction; 11 this.reaction = reaction;
13 this.hasBeenStarted = false;
14 } 12 }
15 13
16 start() { 14 start() {
17 this.dispose = autorun(() => this.reaction()); 15 if (!this.isRunning) {
18 this.hasBeenStarted = true; 16 this.dispose = autorun(() => this.reaction());
17 this.isActive = true;
18 }
19 } 19 }
20 20
21 stop() { 21 stop() {
22 if (this.hasBeenStarted) this.dispose(); 22 if (this.isRunning) {
23 this.dispose();
24 this.isActive = false;
25 }
23 } 26 }
24} 27}
28
29export const createReactions = reactions => (
30 reactions.map(r => new Reaction(r))
31);
diff --git a/src/styles/info-bar.scss b/src/styles/info-bar.scss
index fb4917358..d3010942f 100644
--- a/src/styles/info-bar.scss
+++ b/src/styles/info-bar.scss
@@ -43,6 +43,10 @@
43 } 43 }
44 } 44 }
45 45
46 .info-bar__inline-button {
47 color: white;
48 }
49
46 &.info-bar--bottom { order: 10; } 50 &.info-bar--bottom { order: 10; }
47 51
48 &.info-bar--primary { 52 &.info-bar--primary {