aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--packages/ui/src/infobox/index.tsx2
-rw-r--r--src/components/services/content/ServiceRestricted.js78
-rw-r--r--src/components/services/content/ServiceView.js25
-rw-r--r--src/components/services/content/Services.js1
-rw-r--r--src/components/settings/navigation/SettingsNavigation.js8
-rw-r--r--src/components/settings/recipes/RecipesDashboard.js2
-rw-r--r--src/components/settings/services/EditServiceForm.js5
-rw-r--r--src/components/settings/services/ServicesDashboard.js2
-rw-r--r--src/features/serviceLimit/components/LimitReachedInfobox.js78
-rw-r--r--src/features/serviceLimit/index.js33
-rw-r--r--src/features/serviceLimit/store.js41
-rw-r--r--src/i18n/locales/defaultMessages.json393
-rw-r--r--src/i18n/locales/en-US.json8
-rw-r--r--src/i18n/messages/src/components/services/content/ServiceRestricted.json67
-rw-r--r--src/i18n/messages/src/components/settings/navigation/SettingsNavigation.json32
-rw-r--r--src/i18n/messages/src/components/settings/recipes/RecipesDashboard.json56
-rw-r--r--src/i18n/messages/src/components/settings/services/EditServiceForm.json88
-rw-r--r--src/i18n/messages/src/components/settings/services/ServicesDashboard.json36
-rw-r--r--src/i18n/messages/src/features/serviceLimit/components/AnnouncementScreen.json15
-rw-r--r--src/i18n/messages/src/features/serviceLimit/components/LimitReachedInfobox.json28
-rw-r--r--src/models/Service.js15
-rw-r--r--src/stores/FeaturesStore.js2
-rw-r--r--src/stores/ServicesStore.js37
-rw-r--r--src/stores/index.js2
24 files changed, 769 insertions, 285 deletions
diff --git a/packages/ui/src/infobox/index.tsx b/packages/ui/src/infobox/index.tsx
index 9066a623e..09fc4596a 100644
--- a/packages/ui/src/infobox/index.tsx
+++ b/packages/ui/src/infobox/index.tsx
@@ -48,13 +48,13 @@ const styles = (theme: Theme) => ({
48 position: 'relative', 48 position: 'relative',
49 overflow: 'hidden', 49 overflow: 'hidden',
50 height: 'auto', 50 height: 'auto',
51 marginBottom: 30,
51 }, 52 },
52 infobox: { 53 infobox: {
53 alignItems: 'center', 54 alignItems: 'center',
54 borderRadius: theme.borderRadiusSmall, 55 borderRadius: theme.borderRadiusSmall,
55 display: 'flex', 56 display: 'flex',
56 height: 'auto', 57 height: 'auto',
57 marginBottom: 30,
58 padding: '15px 20px', 58 padding: '15px 20px',
59 top: 0, 59 top: 0,
60 transition: 'all 0.5s', 60 transition: 'all 0.5s',
diff --git a/src/components/services/content/ServiceRestricted.js b/src/components/services/content/ServiceRestricted.js
new file mode 100644
index 000000000..4b8d926aa
--- /dev/null
+++ b/src/components/services/content/ServiceRestricted.js
@@ -0,0 +1,78 @@
1import React, { Component } from 'react';
2import PropTypes from 'prop-types';
3import { observer } from 'mobx-react';
4import { defineMessages, intlShape } from 'react-intl';
5
6import { serviceLimitStore } from '../../../features/serviceLimit';
7import Button from '../../ui/Button';
8import { RESTRICTION_TYPES } from '../../../models/Service';
9
10const messages = defineMessages({
11 headlineServiceLimit: {
12 id: 'service.restrictedHandler.serviceLimit.headline',
13 defaultMessage: '!!!You have reached your service limit.',
14 },
15 textServiceLimit: {
16 id: 'service.restrictedHandler.serviceLimit.text',
17 defaultMessage: '!!!Please upgrade your account to use more than {count} services.',
18 },
19 headlineCustomUrl: {
20 id: 'service.restrictedHandler.customUrl.headline',
21 defaultMessage: '!!!Franz Professional Plan required',
22 },
23 textCustomUrl: {
24 id: 'service.restrictedHandler.customUrl.text',
25 defaultMessage: '!!!Please upgrade to the Franz Professional plan to use custom urls & self hosted services.',
26 },
27 action: {
28 id: 'service.restrictedHandler.action',
29 defaultMessage: '!!!Upgrade Account',
30 },
31});
32
33export default @observer class ServiceRestricted extends Component {
34 static propTypes = {
35 name: PropTypes.string.isRequired,
36 upgrade: PropTypes.func.isRequired,
37 type: PropTypes.number.isRequired,
38 };
39
40 static contextTypes = {
41 intl: intlShape,
42 };
43
44 countdownInterval = null;
45
46 countdownIntervalTimeout = 1000;
47
48 render() {
49 const {
50 name,
51 upgrade,
52 type,
53 } = this.props;
54 const { intl } = this.context;
55
56 return (
57 <div className="services__info-layer">
58 {type === RESTRICTION_TYPES.SERVICE_LIMIT && (
59 <>
60 <h1>{intl.formatMessage(messages.headlineServiceLimit)}</h1>
61 <p>{intl.formatMessage(messages.textServiceLimit, { count: serviceLimitStore.serviceLimit })}</p>
62 </>
63 )}
64 {type === RESTRICTION_TYPES.CUSTOM_URL && (
65 <>
66 <h1>{intl.formatMessage(messages.headlineCustomUrl)}</h1>
67 <p>{intl.formatMessage(messages.textCustomUrl)}</p>
68 </>
69 )}
70 <Button
71 label={intl.formatMessage(messages.action, { name })}
72 buttonType="inverted"
73 onClick={() => upgrade()}
74 />
75 </div>
76 );
77 }
78}
diff --git a/src/components/services/content/ServiceView.js b/src/components/services/content/ServiceView.js
index 13148b9b3..f65f51346 100644
--- a/src/components/services/content/ServiceView.js
+++ b/src/components/services/content/ServiceView.js
@@ -10,6 +10,7 @@ import WebviewLoader from '../../ui/WebviewLoader';
10import WebviewCrashHandler from './WebviewCrashHandler'; 10import WebviewCrashHandler from './WebviewCrashHandler';
11import WebviewErrorHandler from './ErrorHandlers/WebviewErrorHandler'; 11import WebviewErrorHandler from './ErrorHandlers/WebviewErrorHandler';
12import ServiceDisabled from './ServiceDisabled'; 12import ServiceDisabled from './ServiceDisabled';
13import ServiceRestricted from './ServiceRestricted';
13import ServiceWebview from './ServiceWebview'; 14import ServiceWebview from './ServiceWebview';
14 15
15export default @observer class ServiceView extends Component { 16export default @observer class ServiceView extends Component {
@@ -21,6 +22,7 @@ export default @observer class ServiceView extends Component {
21 edit: PropTypes.func.isRequired, 22 edit: PropTypes.func.isRequired,
22 enable: PropTypes.func.isRequired, 23 enable: PropTypes.func.isRequired,
23 isActive: PropTypes.bool, 24 isActive: PropTypes.bool,
25 upgrade: PropTypes.func.isRequired,
24 }; 26 };
25 27
26 static defaultProps = { 28 static defaultProps = {
@@ -72,6 +74,7 @@ export default @observer class ServiceView extends Component {
72 reload, 74 reload,
73 edit, 75 edit,
74 enable, 76 enable,
77 upgrade,
75 } = this.props; 78 } = this.props;
76 79
77 const webviewClasses = classnames({ 80 const webviewClasses = classnames({
@@ -99,7 +102,7 @@ export default @observer class ServiceView extends Component {
99 reload={reload} 102 reload={reload}
100 /> 103 />
101 )} 104 )}
102 {service.isEnabled && service.isLoading && service.isFirstLoad && ( 105 {service.isEnabled && service.isLoading && service.isFirstLoad && !service.isServiceAccessRestricted && (
103 <WebviewLoader 106 <WebviewLoader
104 loaded={false} 107 loaded={false}
105 name={service.name} 108 name={service.name}
@@ -126,11 +129,21 @@ export default @observer class ServiceView extends Component {
126 )} 129 )}
127 </Fragment> 130 </Fragment>
128 ) : ( 131 ) : (
129 <ServiceWebview 132 <>
130 service={service} 133 {service.isServiceAccessRestricted ? (
131 setWebviewReference={setWebviewReference} 134 <ServiceRestricted
132 detachService={detachService} 135 name={service.recipe.name}
133 /> 136 upgrade={upgrade}
137 type={service.restrictionType}
138 />
139 ) : (
140 <ServiceWebview
141 service={service}
142 setWebviewReference={setWebviewReference}
143 detachService={detachService}
144 />
145 )}
146 </>
134 )} 147 )}
135 {statusBar} 148 {statusBar}
136 </div> 149 </div>
diff --git a/src/components/services/content/Services.js b/src/components/services/content/Services.js
index 8f8c38a11..48de0ebaa 100644
--- a/src/components/services/content/Services.js
+++ b/src/components/services/content/Services.js
@@ -89,6 +89,7 @@ export default @observer class Services extends Component {
89 }, 89 },
90 redirect: false, 90 redirect: false,
91 })} 91 })}
92 upgrade={() => openSettings({ path: 'user' })}
92 /> 93 />
93 ))} 94 ))}
94 </div> 95 </div>
diff --git a/src/components/settings/navigation/SettingsNavigation.js b/src/components/settings/navigation/SettingsNavigation.js
index df4b3b3b2..4696b82eb 100644
--- a/src/components/settings/navigation/SettingsNavigation.js
+++ b/src/components/settings/navigation/SettingsNavigation.js
@@ -8,6 +8,7 @@ import Link from '../../ui/Link';
8import { workspaceStore } from '../../../features/workspaces'; 8import { workspaceStore } from '../../../features/workspaces';
9import UIStore from '../../../stores/UIStore'; 9import UIStore from '../../../stores/UIStore';
10import UserStore from '../../../stores/UserStore'; 10import UserStore from '../../../stores/UserStore';
11import { serviceLimitStore } from '../../../features/serviceLimit';
11 12
12const messages = defineMessages({ 13const messages = defineMessages({
13 availableServices: { 14 availableServices: {
@@ -80,7 +81,12 @@ export default @inject('stores') @observer class SettingsNavigation extends Comp
80 > 81 >
81 {intl.formatMessage(messages.yourServices)} 82 {intl.formatMessage(messages.yourServices)}
82 {' '} 83 {' '}
83 <span className="badge">{serviceCount}</span> 84 <span className="badge">
85 {serviceCount}
86 {serviceLimitStore.serviceLimit !== 0 && (
87 `/${serviceLimitStore.serviceLimit}`
88 )}
89 </span>
84 </Link> 90 </Link>
85 {workspaceStore.isFeatureEnabled ? ( 91 {workspaceStore.isFeatureEnabled ? (
86 <Link 92 <Link
diff --git a/src/components/settings/recipes/RecipesDashboard.js b/src/components/settings/recipes/RecipesDashboard.js
index dce4758f0..ed4a429db 100644
--- a/src/components/settings/recipes/RecipesDashboard.js
+++ b/src/components/settings/recipes/RecipesDashboard.js
@@ -13,6 +13,7 @@ import RecipeItem from './RecipeItem';
13import Loader from '../../ui/Loader'; 13import Loader from '../../ui/Loader';
14import Appear from '../../ui/effects/Appear'; 14import Appear from '../../ui/effects/Appear';
15import { FRANZ_SERVICE_REQUEST } from '../../../config'; 15import { FRANZ_SERVICE_REQUEST } from '../../../config';
16import LimitReachedInfobox from '../../../features/serviceLimit/components/LimitReachedInfobox';
16import PremiumFeatureContainer from '../../ui/PremiumFeatureContainer'; 17import PremiumFeatureContainer from '../../ui/PremiumFeatureContainer';
17 18
18const messages = defineMessages({ 19const messages = defineMessages({
@@ -157,6 +158,7 @@ export default @injectSheet(styles) @observer class RecipesDashboard extends Com
157 <div className="settings__header"> 158 <div className="settings__header">
158 <h1>{intl.formatMessage(messages.headline)}</h1> 159 <h1>{intl.formatMessage(messages.headline)}</h1>
159 </div> 160 </div>
161 <LimitReachedInfobox />
160 <div className="settings__body recipes"> 162 <div className="settings__body recipes">
161 {serviceStatus.length > 0 && serviceStatus.includes('created') && ( 163 {serviceStatus.length > 0 && serviceStatus.includes('created') && (
162 <Appear> 164 <Appear>
diff --git a/src/components/settings/services/EditServiceForm.js b/src/components/settings/services/EditServiceForm.js
index 4ba2eb844..c089a1582 100644
--- a/src/components/settings/services/EditServiceForm.js
+++ b/src/components/settings/services/EditServiceForm.js
@@ -17,6 +17,8 @@ import ImageUpload from '../../ui/ImageUpload';
17import Select from '../../ui/Select'; 17import Select from '../../ui/Select';
18 18
19import PremiumFeatureContainer from '../../ui/PremiumFeatureContainer'; 19import PremiumFeatureContainer from '../../ui/PremiumFeatureContainer';
20import LimitReachedInfobox from '../../../features/serviceLimit/components/LimitReachedInfobox';
21import { serviceLimitStore } from '../../../features/serviceLimit';
20 22
21const messages = defineMessages({ 23const messages = defineMessages({
22 saveService: { 24 saveService: {
@@ -252,6 +254,7 @@ export default @observer class EditServiceForm extends Component {
252 )} 254 )}
253 </span> 255 </span>
254 </div> 256 </div>
257 <LimitReachedInfobox />
255 <div className="settings__body"> 258 <div className="settings__body">
256 <form onSubmit={e => this.submit(e)} id="form"> 259 <form onSubmit={e => this.submit(e)} id="form">
257 <div className="service-name"> 260 <div className="service-name">
@@ -418,7 +421,7 @@ export default @observer class EditServiceForm extends Component {
418 type="submit" 421 type="submit"
419 label={intl.formatMessage(messages.saveService)} 422 label={intl.formatMessage(messages.saveService)}
420 htmlForm="form" 423 htmlForm="form"
421 disabled={action !== 'edit' && form.isPristine && requiresUserInput} 424 disabled={action !== 'edit' && ((form.isPristine && requiresUserInput) || serviceLimitStore.userHasReachedServiceLimit)}
422 /> 425 />
423 )} 426 )}
424 </div> 427 </div>
diff --git a/src/components/settings/services/ServicesDashboard.js b/src/components/settings/services/ServicesDashboard.js
index 53bae12df..78038e86a 100644
--- a/src/components/settings/services/ServicesDashboard.js
+++ b/src/components/settings/services/ServicesDashboard.js
@@ -9,6 +9,7 @@ import Infobox from '../../ui/Infobox';
9import Loader from '../../ui/Loader'; 9import Loader from '../../ui/Loader';
10import ServiceItem from './ServiceItem'; 10import ServiceItem from './ServiceItem';
11import Appear from '../../ui/effects/Appear'; 11import Appear from '../../ui/effects/Appear';
12import LimitReachedInfobox from '../../../features/serviceLimit/components/LimitReachedInfobox';
12 13
13const messages = defineMessages({ 14const messages = defineMessages({
14 headline: { 15 headline: {
@@ -91,6 +92,7 @@ export default @observer class ServicesDashboard extends Component {
91 <div className="settings__header"> 92 <div className="settings__header">
92 <h1>{intl.formatMessage(messages.headline)}</h1> 93 <h1>{intl.formatMessage(messages.headline)}</h1>
93 </div> 94 </div>
95 <LimitReachedInfobox />
94 <div className="settings__body"> 96 <div className="settings__body">
95 {!isLoading && ( 97 {!isLoading && (
96 <SearchInput 98 <SearchInput
diff --git a/src/features/serviceLimit/components/LimitReachedInfobox.js b/src/features/serviceLimit/components/LimitReachedInfobox.js
new file mode 100644
index 000000000..fc54dcf85
--- /dev/null
+++ b/src/features/serviceLimit/components/LimitReachedInfobox.js
@@ -0,0 +1,78 @@
1import React, { Component } from 'react';
2import PropTypes from 'prop-types';
3import { inject, observer } from 'mobx-react';
4import { defineMessages, intlShape } from 'react-intl';
5import injectSheet from 'react-jss';
6import { Infobox } from '@meetfranz/ui';
7
8import { gaEvent } from '../../../lib/analytics';
9
10const messages = defineMessages({
11 limitReached: {
12 id: 'feature.serviceLimit.limitReached',
13 defaultMessage: '!!!You have added {amount} of {limit} services. Please upgrade your account to add more services.',
14 },
15 action: {
16 id: 'premiumFeature.button.upgradeAccount',
17 defaultMessage: '!!!Upgrade account',
18 },
19});
20
21const styles = theme => ({
22 container: {
23 height: 'auto',
24 background: theme.styleTypes.primary.accent,
25 color: theme.styleTypes.primary.contrast,
26 borderRadius: 0,
27 marginBottom: 0,
28
29 '& > div': {
30 marginBottom: 0,
31 },
32
33 '& button': {
34 color: theme.styleTypes.primary.contrast,
35 },
36 },
37});
38
39
40@inject('stores', 'actions') @injectSheet(styles) @observer
41class LimitReachedInfobox extends Component {
42 static propTypes = {
43 classes: PropTypes.object.isRequired,
44 stores: PropTypes.object.isRequired,
45 actions: PropTypes.object.isRequired,
46 };
47
48 static contextTypes = {
49 intl: intlShape,
50 };
51
52 render() {
53 const { classes, stores, actions } = this.props;
54 const { intl } = this.context;
55
56 const {
57 serviceLimit,
58 } = stores;
59
60 if (!serviceLimit.userHasReachedServiceLimit) return null;
61
62 return (
63 <Infobox
64 icon="mdiInformation"
65 className={classes.container}
66 ctaLabel={intl.formatMessage(messages.action)}
67 ctaOnClick={() => {
68 actions.ui.openSettings({ path: 'user' });
69 gaEvent('Service Limit', 'upgrade', 'Upgrade account');
70 }}
71 >
72 {intl.formatMessage(messages.limitReached, { amount: serviceLimit.serviceCount, limit: serviceLimit.serviceLimit })}
73 </Infobox>
74 );
75 }
76}
77
78export default LimitReachedInfobox;
diff --git a/src/features/serviceLimit/index.js b/src/features/serviceLimit/index.js
new file mode 100644
index 000000000..92ad8bb98
--- /dev/null
+++ b/src/features/serviceLimit/index.js
@@ -0,0 +1,33 @@
1import { reaction } from 'mobx';
2import { ServiceLimitStore } from './store';
3
4const debug = require('debug')('Franz:feature:serviceLimit');
5
6export const DEFAULT_SERVICE_LIMIT = 3;
7
8let store = null;
9
10export const serviceLimitStore = new ServiceLimitStore();
11
12export default function initServiceLimit(stores, actions) {
13 const { features } = stores;
14
15 // Toggle serviceLimit feature
16 reaction(
17 () => (
18 features.features.isServiceLimitEnabled
19 ),
20 (isEnabled) => {
21 if (isEnabled) {
22 debug('Initializing `serviceLimit` feature');
23 store = serviceLimitStore.start(stores, actions);
24 } else if (store) {
25 debug('Disabling `serviceLimit` feature');
26 serviceLimitStore.stop();
27 }
28 },
29 {
30 fireImmediately: true,
31 },
32 );
33}
diff --git a/src/features/serviceLimit/store.js b/src/features/serviceLimit/store.js
new file mode 100644
index 000000000..9836c5f51
--- /dev/null
+++ b/src/features/serviceLimit/store.js
@@ -0,0 +1,41 @@
1import { computed, observable } from 'mobx';
2import { FeatureStore } from '../utils/FeatureStore';
3import { DEFAULT_SERVICE_LIMIT } from '.';
4
5const debug = require('debug')('Franz:feature:serviceLimit:store');
6
7export class ServiceLimitStore extends FeatureStore {
8 @observable isServiceLimitEnabled = false;
9
10 start(stores, actions) {
11 debug('start');
12 this.stores = stores;
13 this.actions = actions;
14
15 this.isServiceLimitEnabled = true;
16 }
17
18 stop() {
19 super.stop();
20
21 this.isServiceLimitEnabled = false;
22 }
23
24 @computed get userHasReachedServiceLimit() {
25 if (!this.isServiceLimitEnabled) return false;
26
27 return this.serviceLimit !== 0 && this.serviceCount >= this.serviceLimit;
28 }
29
30 @computed get serviceLimit() {
31 if (!this.isServiceLimitEnabled || this.stores.features.features.serviceLimitCount === 0) return 0;
32
33 return this.stores.features.features.serviceLimitCount || DEFAULT_SERVICE_LIMIT;
34 }
35
36 @computed get serviceCount() {
37 return this.stores.services.all.length;
38 }
39}
40
41export default ServiceLimitStore;
diff --git a/src/i18n/locales/defaultMessages.json b/src/i18n/locales/defaultMessages.json
index 5cd01db74..3d11a372d 100644
--- a/src/i18n/locales/defaultMessages.json
+++ b/src/i18n/locales/defaultMessages.json
@@ -894,6 +894,76 @@
894 { 894 {
895 "descriptors": [ 895 "descriptors": [
896 { 896 {
897 "defaultMessage": "!!!You have reached your service limit.",
898 "end": {
899 "column": 3,
900 "line": 14
901 },
902 "file": "src/components/services/content/ServiceRestricted.js",
903 "id": "service.restrictedHandler.serviceLimit.headline",
904 "start": {
905 "column": 24,
906 "line": 11
907 }
908 },
909 {
910 "defaultMessage": "!!!Please upgrade your account to use more than {count} services.",
911 "end": {
912 "column": 3,
913 "line": 18
914 },
915 "file": "src/components/services/content/ServiceRestricted.js",
916 "id": "service.restrictedHandler.serviceLimit.text",
917 "start": {
918 "column": 20,
919 "line": 15
920 }
921 },
922 {
923 "defaultMessage": "!!!Franz Professional Plan required",
924 "end": {
925 "column": 3,
926 "line": 22
927 },
928 "file": "src/components/services/content/ServiceRestricted.js",
929 "id": "service.restrictedHandler.customUrl.headline",
930 "start": {
931 "column": 21,
932 "line": 19
933 }
934 },
935 {
936 "defaultMessage": "!!!Please upgrade to the Franz Professional plan to use custom urls & self hosted services.",
937 "end": {
938 "column": 3,
939 "line": 26
940 },
941 "file": "src/components/services/content/ServiceRestricted.js",
942 "id": "service.restrictedHandler.customUrl.text",
943 "start": {
944 "column": 17,
945 "line": 23
946 }
947 },
948 {
949 "defaultMessage": "!!!Upgrade Account",
950 "end": {
951 "column": 3,
952 "line": 30
953 },
954 "file": "src/components/services/content/ServiceRestricted.js",
955 "id": "service.restrictedHandler.action",
956 "start": {
957 "column": 10,
958 "line": 27
959 }
960 }
961 ],
962 "path": "src/components/services/content/ServiceRestricted.json"
963 },
964 {
965 "descriptors": [
966 {
897 "defaultMessage": "!!!Welcome to Franz", 967 "defaultMessage": "!!!Welcome to Franz",
898 "end": { 968 "end": {
899 "column": 3, 969 "column": 3,
@@ -1307,104 +1377,104 @@
1307 "defaultMessage": "!!!Available services", 1377 "defaultMessage": "!!!Available services",
1308 "end": { 1378 "end": {
1309 "column": 3, 1379 "column": 3,
1310 "line": 16 1380 "line": 17
1311 }, 1381 },
1312 "file": "src/components/settings/navigation/SettingsNavigation.js", 1382 "file": "src/components/settings/navigation/SettingsNavigation.js",
1313 "id": "settings.navigation.availableServices", 1383 "id": "settings.navigation.availableServices",
1314 "start": { 1384 "start": {
1315 "column": 21, 1385 "column": 21,
1316 "line": 13 1386 "line": 14
1317 } 1387 }
1318 }, 1388 },
1319 { 1389 {
1320 "defaultMessage": "!!!Your services", 1390 "defaultMessage": "!!!Your services",
1321 "end": { 1391 "end": {
1322 "column": 3, 1392 "column": 3,
1323 "line": 20 1393 "line": 21
1324 }, 1394 },
1325 "file": "src/components/settings/navigation/SettingsNavigation.js", 1395 "file": "src/components/settings/navigation/SettingsNavigation.js",
1326 "id": "settings.navigation.yourServices", 1396 "id": "settings.navigation.yourServices",
1327 "start": { 1397 "start": {
1328 "column": 16, 1398 "column": 16,
1329 "line": 17 1399 "line": 18
1330 } 1400 }
1331 }, 1401 },
1332 { 1402 {
1333 "defaultMessage": "!!!Your workspaces", 1403 "defaultMessage": "!!!Your workspaces",
1334 "end": { 1404 "end": {
1335 "column": 3, 1405 "column": 3,
1336 "line": 24 1406 "line": 25
1337 }, 1407 },
1338 "file": "src/components/settings/navigation/SettingsNavigation.js", 1408 "file": "src/components/settings/navigation/SettingsNavigation.js",
1339 "id": "settings.navigation.yourWorkspaces", 1409 "id": "settings.navigation.yourWorkspaces",
1340 "start": { 1410 "start": {
1341 "column": 18, 1411 "column": 18,
1342 "line": 21 1412 "line": 22
1343 } 1413 }
1344 }, 1414 },
1345 { 1415 {
1346 "defaultMessage": "!!!Account", 1416 "defaultMessage": "!!!Account",
1347 "end": { 1417 "end": {
1348 "column": 3, 1418 "column": 3,
1349 "line": 28 1419 "line": 29
1350 }, 1420 },
1351 "file": "src/components/settings/navigation/SettingsNavigation.js", 1421 "file": "src/components/settings/navigation/SettingsNavigation.js",
1352 "id": "settings.navigation.account", 1422 "id": "settings.navigation.account",
1353 "start": { 1423 "start": {
1354 "column": 11, 1424 "column": 11,
1355 "line": 25 1425 "line": 26
1356 } 1426 }
1357 }, 1427 },
1358 { 1428 {
1359 "defaultMessage": "!!!Manage Team", 1429 "defaultMessage": "!!!Manage Team",
1360 "end": { 1430 "end": {
1361 "column": 3, 1431 "column": 3,
1362 "line": 32 1432 "line": 33
1363 }, 1433 },
1364 "file": "src/components/settings/navigation/SettingsNavigation.js", 1434 "file": "src/components/settings/navigation/SettingsNavigation.js",
1365 "id": "settings.navigation.team", 1435 "id": "settings.navigation.team",
1366 "start": { 1436 "start": {
1367 "column": 8, 1437 "column": 8,
1368 "line": 29 1438 "line": 30
1369 } 1439 }
1370 }, 1440 },
1371 { 1441 {
1372 "defaultMessage": "!!!Settings", 1442 "defaultMessage": "!!!Settings",
1373 "end": { 1443 "end": {
1374 "column": 3, 1444 "column": 3,
1375 "line": 36 1445 "line": 37
1376 }, 1446 },
1377 "file": "src/components/settings/navigation/SettingsNavigation.js", 1447 "file": "src/components/settings/navigation/SettingsNavigation.js",
1378 "id": "settings.navigation.settings", 1448 "id": "settings.navigation.settings",
1379 "start": { 1449 "start": {
1380 "column": 12, 1450 "column": 12,
1381 "line": 33 1451 "line": 34
1382 } 1452 }
1383 }, 1453 },
1384 { 1454 {
1385 "defaultMessage": "!!!Invite Friends", 1455 "defaultMessage": "!!!Invite Friends",
1386 "end": { 1456 "end": {
1387 "column": 3, 1457 "column": 3,
1388 "line": 40 1458 "line": 41
1389 }, 1459 },
1390 "file": "src/components/settings/navigation/SettingsNavigation.js", 1460 "file": "src/components/settings/navigation/SettingsNavigation.js",
1391 "id": "settings.navigation.inviteFriends", 1461 "id": "settings.navigation.inviteFriends",
1392 "start": { 1462 "start": {
1393 "column": 17, 1463 "column": 17,
1394 "line": 37 1464 "line": 38
1395 } 1465 }
1396 }, 1466 },
1397 { 1467 {
1398 "defaultMessage": "!!!Logout", 1468 "defaultMessage": "!!!Logout",
1399 "end": { 1469 "end": {
1400 "column": 3, 1470 "column": 3,
1401 "line": 44 1471 "line": 45
1402 }, 1472 },
1403 "file": "src/components/settings/navigation/SettingsNavigation.js", 1473 "file": "src/components/settings/navigation/SettingsNavigation.js",
1404 "id": "settings.navigation.logout", 1474 "id": "settings.navigation.logout",
1405 "start": { 1475 "start": {
1406 "column": 10, 1476 "column": 10,
1407 "line": 41 1477 "line": 42
1408 } 1478 }
1409 } 1479 }
1410 ], 1480 ],
@@ -1416,182 +1486,182 @@
1416 "defaultMessage": "!!!Available Services", 1486 "defaultMessage": "!!!Available Services",
1417 "end": { 1487 "end": {
1418 "column": 3, 1488 "column": 3,
1419 "line": 22 1489 "line": 23
1420 }, 1490 },
1421 "file": "src/components/settings/recipes/RecipesDashboard.js", 1491 "file": "src/components/settings/recipes/RecipesDashboard.js",
1422 "id": "settings.recipes.headline", 1492 "id": "settings.recipes.headline",
1423 "start": { 1493 "start": {
1424 "column": 12, 1494 "column": 12,
1425 "line": 19 1495 "line": 20
1426 } 1496 }
1427 }, 1497 },
1428 { 1498 {
1429 "defaultMessage": "!!!Search service", 1499 "defaultMessage": "!!!Search service",
1430 "end": { 1500 "end": {
1431 "column": 3, 1501 "column": 3,
1432 "line": 26 1502 "line": 27
1433 }, 1503 },
1434 "file": "src/components/settings/recipes/RecipesDashboard.js", 1504 "file": "src/components/settings/recipes/RecipesDashboard.js",
1435 "id": "settings.searchService", 1505 "id": "settings.searchService",
1436 "start": { 1506 "start": {
1437 "column": 17, 1507 "column": 17,
1438 "line": 23 1508 "line": 24
1439 } 1509 }
1440 }, 1510 },
1441 { 1511 {
1442 "defaultMessage": "!!!Most popular", 1512 "defaultMessage": "!!!Most popular",
1443 "end": { 1513 "end": {
1444 "column": 3, 1514 "column": 3,
1445 "line": 30 1515 "line": 31
1446 }, 1516 },
1447 "file": "src/components/settings/recipes/RecipesDashboard.js", 1517 "file": "src/components/settings/recipes/RecipesDashboard.js",
1448 "id": "settings.recipes.mostPopular", 1518 "id": "settings.recipes.mostPopular",
1449 "start": { 1519 "start": {
1450 "column": 22, 1520 "column": 22,
1451 "line": 27 1521 "line": 28
1452 } 1522 }
1453 }, 1523 },
1454 { 1524 {
1455 "defaultMessage": "!!!All services", 1525 "defaultMessage": "!!!All services",
1456 "end": { 1526 "end": {
1457 "column": 3, 1527 "column": 3,
1458 "line": 34 1528 "line": 35
1459 }, 1529 },
1460 "file": "src/components/settings/recipes/RecipesDashboard.js", 1530 "file": "src/components/settings/recipes/RecipesDashboard.js",
1461 "id": "settings.recipes.all", 1531 "id": "settings.recipes.all",
1462 "start": { 1532 "start": {
1463 "column": 14, 1533 "column": 14,
1464 "line": 31 1534 "line": 32
1465 } 1535 }
1466 }, 1536 },
1467 { 1537 {
1468 "defaultMessage": "!!!Custom Services", 1538 "defaultMessage": "!!!Custom Services",
1469 "end": { 1539 "end": {
1470 "column": 3, 1540 "column": 3,
1471 "line": 38 1541 "line": 39
1472 }, 1542 },
1473 "file": "src/components/settings/recipes/RecipesDashboard.js", 1543 "file": "src/components/settings/recipes/RecipesDashboard.js",
1474 "id": "settings.recipes.custom", 1544 "id": "settings.recipes.custom",
1475 "start": { 1545 "start": {
1476 "column": 17, 1546 "column": 17,
1477 "line": 35 1547 "line": 36
1478 } 1548 }
1479 }, 1549 },
1480 { 1550 {
1481 "defaultMessage": "!!!Sorry, but no service matched your search term.", 1551 "defaultMessage": "!!!Sorry, but no service matched your search term.",
1482 "end": { 1552 "end": {
1483 "column": 3, 1553 "column": 3,
1484 "line": 42 1554 "line": 43
1485 }, 1555 },
1486 "file": "src/components/settings/recipes/RecipesDashboard.js", 1556 "file": "src/components/settings/recipes/RecipesDashboard.js",
1487 "id": "settings.recipes.nothingFound", 1557 "id": "settings.recipes.nothingFound",
1488 "start": { 1558 "start": {
1489 "column": 16, 1559 "column": 16,
1490 "line": 39 1560 "line": 40
1491 } 1561 }
1492 }, 1562 },
1493 { 1563 {
1494 "defaultMessage": "!!!Service successfully added", 1564 "defaultMessage": "!!!Service successfully added",
1495 "end": { 1565 "end": {
1496 "column": 3, 1566 "column": 3,
1497 "line": 46 1567 "line": 47
1498 }, 1568 },
1499 "file": "src/components/settings/recipes/RecipesDashboard.js", 1569 "file": "src/components/settings/recipes/RecipesDashboard.js",
1500 "id": "settings.recipes.servicesSuccessfulAddedInfo", 1570 "id": "settings.recipes.servicesSuccessfulAddedInfo",
1501 "start": { 1571 "start": {
1502 "column": 31, 1572 "column": 31,
1503 "line": 43 1573 "line": 44
1504 } 1574 }
1505 }, 1575 },
1506 { 1576 {
1507 "defaultMessage": "!!!Missing a service?", 1577 "defaultMessage": "!!!Missing a service?",
1508 "end": { 1578 "end": {
1509 "column": 3, 1579 "column": 3,
1510 "line": 50 1580 "line": 51
1511 }, 1581 },
1512 "file": "src/components/settings/recipes/RecipesDashboard.js", 1582 "file": "src/components/settings/recipes/RecipesDashboard.js",
1513 "id": "settings.recipes.missingService", 1583 "id": "settings.recipes.missingService",
1514 "start": { 1584 "start": {
1515 "column": 18, 1585 "column": 18,
1516 "line": 47 1586 "line": 48
1517 } 1587 }
1518 }, 1588 },
1519 { 1589 {
1520 "defaultMessage": "!!!To add a custom service, copy the recipe folder into:", 1590 "defaultMessage": "!!!To add a custom service, copy the recipe folder into:",
1521 "end": { 1591 "end": {
1522 "column": 3, 1592 "column": 3,
1523 "line": 54 1593 "line": 55
1524 }, 1594 },
1525 "file": "src/components/settings/recipes/RecipesDashboard.js", 1595 "file": "src/components/settings/recipes/RecipesDashboard.js",
1526 "id": "settings.recipes.customService.intro", 1596 "id": "settings.recipes.customService.intro",
1527 "start": { 1597 "start": {
1528 "column": 21, 1598 "column": 21,
1529 "line": 51 1599 "line": 52
1530 } 1600 }
1531 }, 1601 },
1532 { 1602 {
1533 "defaultMessage": "!!!Open directory", 1603 "defaultMessage": "!!!Open directory",
1534 "end": { 1604 "end": {
1535 "column": 3, 1605 "column": 3,
1536 "line": 58 1606 "line": 59
1537 }, 1607 },
1538 "file": "src/components/settings/recipes/RecipesDashboard.js", 1608 "file": "src/components/settings/recipes/RecipesDashboard.js",
1539 "id": "settings.recipes.customService.openFolder", 1609 "id": "settings.recipes.customService.openFolder",
1540 "start": { 1610 "start": {
1541 "column": 14, 1611 "column": 14,
1542 "line": 55 1612 "line": 56
1543 } 1613 }
1544 }, 1614 },
1545 { 1615 {
1546 "defaultMessage": "!!!Developer Documentation", 1616 "defaultMessage": "!!!Developer Documentation",
1547 "end": { 1617 "end": {
1548 "column": 3, 1618 "column": 3,
1549 "line": 62 1619 "line": 63
1550 }, 1620 },
1551 "file": "src/components/settings/recipes/RecipesDashboard.js", 1621 "file": "src/components/settings/recipes/RecipesDashboard.js",
1552 "id": "settings.recipes.customService.openDevDocs", 1622 "id": "settings.recipes.customService.openDevDocs",
1553 "start": { 1623 "start": {
1554 "column": 15, 1624 "column": 15,
1555 "line": 59 1625 "line": 60
1556 } 1626 }
1557 }, 1627 },
1558 { 1628 {
1559 "defaultMessage": "!!!Custom Service Recipes", 1629 "defaultMessage": "!!!Custom Service Recipes",
1560 "end": { 1630 "end": {
1561 "column": 3, 1631 "column": 3,
1562 "line": 66 1632 "line": 67
1563 }, 1633 },
1564 "file": "src/components/settings/recipes/RecipesDashboard.js", 1634 "file": "src/components/settings/recipes/RecipesDashboard.js",
1565 "id": "settings.recipes.customService.headline.customRecipes", 1635 "id": "settings.recipes.customService.headline.customRecipes",
1566 "start": { 1636 "start": {
1567 "column": 25, 1637 "column": 25,
1568 "line": 63 1638 "line": 64
1569 } 1639 }
1570 }, 1640 },
1571 { 1641 {
1572 "defaultMessage": "!!!Community Services", 1642 "defaultMessage": "!!!Community Services",
1573 "end": { 1643 "end": {
1574 "column": 3, 1644 "column": 3,
1575 "line": 70 1645 "line": 71
1576 }, 1646 },
1577 "file": "src/components/settings/recipes/RecipesDashboard.js", 1647 "file": "src/components/settings/recipes/RecipesDashboard.js",
1578 "id": "settings.recipes.customService.headline.communityRecipes", 1648 "id": "settings.recipes.customService.headline.communityRecipes",
1579 "start": { 1649 "start": {
1580 "column": 28, 1650 "column": 28,
1581 "line": 67 1651 "line": 68
1582 } 1652 }
1583 }, 1653 },
1584 { 1654 {
1585 "defaultMessage": "!!!Your Development Service Recipes", 1655 "defaultMessage": "!!!Your Development Service Recipes",
1586 "end": { 1656 "end": {
1587 "column": 3, 1657 "column": 3,
1588 "line": 74 1658 "line": 75
1589 }, 1659 },
1590 "file": "src/components/settings/recipes/RecipesDashboard.js", 1660 "file": "src/components/settings/recipes/RecipesDashboard.js",
1591 "id": "settings.recipes.customService.headline.devRecipes", 1661 "id": "settings.recipes.customService.headline.devRecipes",
1592 "start": { 1662 "start": {
1593 "column": 22, 1663 "column": 22,
1594 "line": 71 1664 "line": 72
1595 } 1665 }
1596 } 1666 }
1597 ], 1667 ],
@@ -1603,286 +1673,286 @@
1603 "defaultMessage": "!!!Save service", 1673 "defaultMessage": "!!!Save service",
1604 "end": { 1674 "end": {
1605 "column": 3, 1675 "column": 3,
1606 "line": 25 1676 "line": 27
1607 }, 1677 },
1608 "file": "src/components/settings/services/EditServiceForm.js", 1678 "file": "src/components/settings/services/EditServiceForm.js",
1609 "id": "settings.service.form.saveButton", 1679 "id": "settings.service.form.saveButton",
1610 "start": { 1680 "start": {
1611 "column": 15, 1681 "column": 15,
1612 "line": 22 1682 "line": 24
1613 } 1683 }
1614 }, 1684 },
1615 { 1685 {
1616 "defaultMessage": "!!!Delete Service", 1686 "defaultMessage": "!!!Delete Service",
1617 "end": { 1687 "end": {
1618 "column": 3, 1688 "column": 3,
1619 "line": 29 1689 "line": 31
1620 }, 1690 },
1621 "file": "src/components/settings/services/EditServiceForm.js", 1691 "file": "src/components/settings/services/EditServiceForm.js",
1622 "id": "settings.service.form.deleteButton", 1692 "id": "settings.service.form.deleteButton",
1623 "start": { 1693 "start": {
1624 "column": 17, 1694 "column": 17,
1625 "line": 26 1695 "line": 28
1626 } 1696 }
1627 }, 1697 },
1628 { 1698 {
1629 "defaultMessage": "!!!Available services", 1699 "defaultMessage": "!!!Available services",
1630 "end": { 1700 "end": {
1631 "column": 3, 1701 "column": 3,
1632 "line": 33 1702 "line": 35
1633 }, 1703 },
1634 "file": "src/components/settings/services/EditServiceForm.js", 1704 "file": "src/components/settings/services/EditServiceForm.js",
1635 "id": "settings.service.form.availableServices", 1705 "id": "settings.service.form.availableServices",
1636 "start": { 1706 "start": {
1637 "column": 21, 1707 "column": 21,
1638 "line": 30 1708 "line": 32
1639 } 1709 }
1640 }, 1710 },
1641 { 1711 {
1642 "defaultMessage": "!!!Your services", 1712 "defaultMessage": "!!!Your services",
1643 "end": { 1713 "end": {
1644 "column": 3, 1714 "column": 3,
1645 "line": 37 1715 "line": 39
1646 }, 1716 },
1647 "file": "src/components/settings/services/EditServiceForm.js", 1717 "file": "src/components/settings/services/EditServiceForm.js",
1648 "id": "settings.service.form.yourServices", 1718 "id": "settings.service.form.yourServices",
1649 "start": { 1719 "start": {
1650 "column": 16, 1720 "column": 16,
1651 "line": 34 1721 "line": 36
1652 } 1722 }
1653 }, 1723 },
1654 { 1724 {
1655 "defaultMessage": "!!!Add {name}", 1725 "defaultMessage": "!!!Add {name}",
1656 "end": { 1726 "end": {
1657 "column": 3, 1727 "column": 3,
1658 "line": 41 1728 "line": 43
1659 }, 1729 },
1660 "file": "src/components/settings/services/EditServiceForm.js", 1730 "file": "src/components/settings/services/EditServiceForm.js",
1661 "id": "settings.service.form.addServiceHeadline", 1731 "id": "settings.service.form.addServiceHeadline",
1662 "start": { 1732 "start": {
1663 "column": 22, 1733 "column": 22,
1664 "line": 38 1734 "line": 40
1665 } 1735 }
1666 }, 1736 },
1667 { 1737 {
1668 "defaultMessage": "!!!Edit {name}", 1738 "defaultMessage": "!!!Edit {name}",
1669 "end": { 1739 "end": {
1670 "column": 3, 1740 "column": 3,
1671 "line": 45 1741 "line": 47
1672 }, 1742 },
1673 "file": "src/components/settings/services/EditServiceForm.js", 1743 "file": "src/components/settings/services/EditServiceForm.js",
1674 "id": "settings.service.form.editServiceHeadline", 1744 "id": "settings.service.form.editServiceHeadline",
1675 "start": { 1745 "start": {
1676 "column": 23, 1746 "column": 23,
1677 "line": 42 1747 "line": 44
1678 } 1748 }
1679 }, 1749 },
1680 { 1750 {
1681 "defaultMessage": "!!!Hosted", 1751 "defaultMessage": "!!!Hosted",
1682 "end": { 1752 "end": {
1683 "column": 3, 1753 "column": 3,
1684 "line": 49 1754 "line": 51
1685 }, 1755 },
1686 "file": "src/components/settings/services/EditServiceForm.js", 1756 "file": "src/components/settings/services/EditServiceForm.js",
1687 "id": "settings.service.form.tabHosted", 1757 "id": "settings.service.form.tabHosted",
1688 "start": { 1758 "start": {
1689 "column": 13, 1759 "column": 13,
1690 "line": 46 1760 "line": 48
1691 } 1761 }
1692 }, 1762 },
1693 { 1763 {
1694 "defaultMessage": "!!!Self hosted ⭐️", 1764 "defaultMessage": "!!!Self hosted ⭐️",
1695 "end": { 1765 "end": {
1696 "column": 3, 1766 "column": 3,
1697 "line": 53 1767 "line": 55
1698 }, 1768 },
1699 "file": "src/components/settings/services/EditServiceForm.js", 1769 "file": "src/components/settings/services/EditServiceForm.js",
1700 "id": "settings.service.form.tabOnPremise", 1770 "id": "settings.service.form.tabOnPremise",
1701 "start": { 1771 "start": {
1702 "column": 16, 1772 "column": 16,
1703 "line": 50 1773 "line": 52
1704 } 1774 }
1705 }, 1775 },
1706 { 1776 {
1707 "defaultMessage": "!!!Use the hosted {name} service.", 1777 "defaultMessage": "!!!Use the hosted {name} service.",
1708 "end": { 1778 "end": {
1709 "column": 3, 1779 "column": 3,
1710 "line": 57 1780 "line": 59
1711 }, 1781 },
1712 "file": "src/components/settings/services/EditServiceForm.js", 1782 "file": "src/components/settings/services/EditServiceForm.js",
1713 "id": "settings.service.form.useHostedService", 1783 "id": "settings.service.form.useHostedService",
1714 "start": { 1784 "start": {
1715 "column": 20, 1785 "column": 20,
1716 "line": 54 1786 "line": 56
1717 } 1787 }
1718 }, 1788 },
1719 { 1789 {
1720 "defaultMessage": "!!!Could not validate custom {name} server.", 1790 "defaultMessage": "!!!Could not validate custom {name} server.",
1721 "end": { 1791 "end": {
1722 "column": 3, 1792 "column": 3,
1723 "line": 61 1793 "line": 63
1724 }, 1794 },
1725 "file": "src/components/settings/services/EditServiceForm.js", 1795 "file": "src/components/settings/services/EditServiceForm.js",
1726 "id": "settings.service.form.customUrlValidationError", 1796 "id": "settings.service.form.customUrlValidationError",
1727 "start": { 1797 "start": {
1728 "column": 28, 1798 "column": 28,
1729 "line": 58 1799 "line": 60
1730 } 1800 }
1731 }, 1801 },
1732 { 1802 {
1733 "defaultMessage": "!!!To add self hosted services, you need a Franz Premium Supporter Account.", 1803 "defaultMessage": "!!!To add self hosted services, you need a Franz Premium Supporter Account.",
1734 "end": { 1804 "end": {
1735 "column": 3, 1805 "column": 3,
1736 "line": 65 1806 "line": 67
1737 }, 1807 },
1738 "file": "src/components/settings/services/EditServiceForm.js", 1808 "file": "src/components/settings/services/EditServiceForm.js",
1739 "id": "settings.service.form.customUrlPremiumInfo", 1809 "id": "settings.service.form.customUrlPremiumInfo",
1740 "start": { 1810 "start": {
1741 "column": 24, 1811 "column": 24,
1742 "line": 62 1812 "line": 64
1743 } 1813 }
1744 }, 1814 },
1745 { 1815 {
1746 "defaultMessage": "!!!Upgrade your account", 1816 "defaultMessage": "!!!Upgrade your account",
1747 "end": { 1817 "end": {
1748 "column": 3, 1818 "column": 3,
1749 "line": 69 1819 "line": 71
1750 }, 1820 },
1751 "file": "src/components/settings/services/EditServiceForm.js", 1821 "file": "src/components/settings/services/EditServiceForm.js",
1752 "id": "settings.service.form.customUrlUpgradeAccount", 1822 "id": "settings.service.form.customUrlUpgradeAccount",
1753 "start": { 1823 "start": {
1754 "column": 27, 1824 "column": 27,
1755 "line": 66 1825 "line": 68
1756 } 1826 }
1757 }, 1827 },
1758 { 1828 {
1759 "defaultMessage": "!!!You will be notified about all new messages in a channel, not just @username, @channel, @here, ...", 1829 "defaultMessage": "!!!You will be notified about all new messages in a channel, not just @username, @channel, @here, ...",
1760 "end": { 1830 "end": {
1761 "column": 3, 1831 "column": 3,
1762 "line": 73 1832 "line": 75
1763 }, 1833 },
1764 "file": "src/components/settings/services/EditServiceForm.js", 1834 "file": "src/components/settings/services/EditServiceForm.js",
1765 "id": "settings.service.form.indirectMessageInfo", 1835 "id": "settings.service.form.indirectMessageInfo",
1766 "start": { 1836 "start": {
1767 "column": 23, 1837 "column": 23,
1768 "line": 70 1838 "line": 72
1769 } 1839 }
1770 }, 1840 },
1771 { 1841 {
1772 "defaultMessage": "!!!When disabled, all notification sounds and audio playback are muted", 1842 "defaultMessage": "!!!When disabled, all notification sounds and audio playback are muted",
1773 "end": { 1843 "end": {
1774 "column": 3, 1844 "column": 3,
1775 "line": 77 1845 "line": 79
1776 }, 1846 },
1777 "file": "src/components/settings/services/EditServiceForm.js", 1847 "file": "src/components/settings/services/EditServiceForm.js",
1778 "id": "settings.service.form.isMutedInfo", 1848 "id": "settings.service.form.isMutedInfo",
1779 "start": { 1849 "start": {
1780 "column": 15, 1850 "column": 15,
1781 "line": 74 1851 "line": 76
1782 } 1852 }
1783 }, 1853 },
1784 { 1854 {
1785 "defaultMessage": "!!!Notifications", 1855 "defaultMessage": "!!!Notifications",
1786 "end": { 1856 "end": {
1787 "column": 3, 1857 "column": 3,
1788 "line": 81 1858 "line": 83
1789 }, 1859 },
1790 "file": "src/components/settings/services/EditServiceForm.js", 1860 "file": "src/components/settings/services/EditServiceForm.js",
1791 "id": "settings.service.form.headlineNotifications", 1861 "id": "settings.service.form.headlineNotifications",
1792 "start": { 1862 "start": {
1793 "column": 25, 1863 "column": 25,
1794 "line": 78 1864 "line": 80
1795 } 1865 }
1796 }, 1866 },
1797 { 1867 {
1798 "defaultMessage": "!!!Unread message badges", 1868 "defaultMessage": "!!!Unread message badges",
1799 "end": { 1869 "end": {
1800 "column": 3, 1870 "column": 3,
1801 "line": 85 1871 "line": 87
1802 }, 1872 },
1803 "file": "src/components/settings/services/EditServiceForm.js", 1873 "file": "src/components/settings/services/EditServiceForm.js",
1804 "id": "settings.service.form.headlineBadges", 1874 "id": "settings.service.form.headlineBadges",
1805 "start": { 1875 "start": {
1806 "column": 18, 1876 "column": 18,
1807 "line": 82 1877 "line": 84
1808 } 1878 }
1809 }, 1879 },
1810 { 1880 {
1811 "defaultMessage": "!!!General", 1881 "defaultMessage": "!!!General",
1812 "end": { 1882 "end": {
1813 "column": 3, 1883 "column": 3,
1814 "line": 89 1884 "line": 91
1815 }, 1885 },
1816 "file": "src/components/settings/services/EditServiceForm.js", 1886 "file": "src/components/settings/services/EditServiceForm.js",
1817 "id": "settings.service.form.headlineGeneral", 1887 "id": "settings.service.form.headlineGeneral",
1818 "start": { 1888 "start": {
1819 "column": 19, 1889 "column": 19,
1820 "line": 86 1890 "line": 88
1821 } 1891 }
1822 }, 1892 },
1823 { 1893 {
1824 "defaultMessage": "!!!Delete", 1894 "defaultMessage": "!!!Delete",
1825 "end": { 1895 "end": {
1826 "column": 3, 1896 "column": 3,
1827 "line": 93 1897 "line": 95
1828 }, 1898 },
1829 "file": "src/components/settings/services/EditServiceForm.js", 1899 "file": "src/components/settings/services/EditServiceForm.js",
1830 "id": "settings.service.form.iconDelete", 1900 "id": "settings.service.form.iconDelete",
1831 "start": { 1901 "start": {
1832 "column": 14, 1902 "column": 14,
1833 "line": 90 1903 "line": 92
1834 } 1904 }
1835 }, 1905 },
1836 { 1906 {
1837 "defaultMessage": "!!!Drop your image, or click here", 1907 "defaultMessage": "!!!Drop your image, or click here",
1838 "end": { 1908 "end": {
1839 "column": 3, 1909 "column": 3,
1840 "line": 97 1910 "line": 99
1841 }, 1911 },
1842 "file": "src/components/settings/services/EditServiceForm.js", 1912 "file": "src/components/settings/services/EditServiceForm.js",
1843 "id": "settings.service.form.iconUpload", 1913 "id": "settings.service.form.iconUpload",
1844 "start": { 1914 "start": {
1845 "column": 14, 1915 "column": 14,
1846 "line": 94 1916 "line": 96
1847 } 1917 }
1848 }, 1918 },
1849 { 1919 {
1850 "defaultMessage": "!!!HTTP/HTTPS Proxy Settings", 1920 "defaultMessage": "!!!HTTP/HTTPS Proxy Settings",
1851 "end": { 1921 "end": {
1852 "column": 3, 1922 "column": 3,
1853 "line": 101 1923 "line": 103
1854 }, 1924 },
1855 "file": "src/components/settings/services/EditServiceForm.js", 1925 "file": "src/components/settings/services/EditServiceForm.js",
1856 "id": "settings.service.form.proxy.headline", 1926 "id": "settings.service.form.proxy.headline",
1857 "start": { 1927 "start": {
1858 "column": 17, 1928 "column": 17,
1859 "line": 98 1929 "line": 100
1860 } 1930 }
1861 }, 1931 },
1862 { 1932 {
1863 "defaultMessage": "!!!Please restart Franz after changing proxy Settings.", 1933 "defaultMessage": "!!!Please restart Franz after changing proxy Settings.",
1864 "end": { 1934 "end": {
1865 "column": 3, 1935 "column": 3,
1866 "line": 105 1936 "line": 107
1867 }, 1937 },
1868 "file": "src/components/settings/services/EditServiceForm.js", 1938 "file": "src/components/settings/services/EditServiceForm.js",
1869 "id": "settings.service.form.proxy.restartInfo", 1939 "id": "settings.service.form.proxy.restartInfo",
1870 "start": { 1940 "start": {
1871 "column": 20, 1941 "column": 20,
1872 "line": 102 1942 "line": 104
1873 } 1943 }
1874 }, 1944 },
1875 { 1945 {
1876 "defaultMessage": "!!!Proxy settings will not be synchronized with the Franz servers.", 1946 "defaultMessage": "!!!Proxy settings will not be synchronized with the Franz servers.",
1877 "end": { 1947 "end": {
1878 "column": 3, 1948 "column": 3,
1879 "line": 109 1949 "line": 111
1880 }, 1950 },
1881 "file": "src/components/settings/services/EditServiceForm.js", 1951 "file": "src/components/settings/services/EditServiceForm.js",
1882 "id": "settings.service.form.proxy.info", 1952 "id": "settings.service.form.proxy.info",
1883 "start": { 1953 "start": {
1884 "column": 13, 1954 "column": 13,
1885 "line": 106 1955 "line": 108
1886 } 1956 }
1887 } 1957 }
1888 ], 1958 ],
@@ -1995,117 +2065,117 @@
1995 "defaultMessage": "!!!Your services", 2065 "defaultMessage": "!!!Your services",
1996 "end": { 2066 "end": {
1997 "column": 3, 2067 "column": 3,
1998 "line": 17 2068 "line": 18
1999 }, 2069 },
2000 "file": "src/components/settings/services/ServicesDashboard.js", 2070 "file": "src/components/settings/services/ServicesDashboard.js",
2001 "id": "settings.services.headline", 2071 "id": "settings.services.headline",
2002 "start": { 2072 "start": {
2003 "column": 12, 2073 "column": 12,
2004 "line": 14 2074 "line": 15
2005 } 2075 }
2006 }, 2076 },
2007 { 2077 {
2008 "defaultMessage": "!!!Search service", 2078 "defaultMessage": "!!!Search service",
2009 "end": { 2079 "end": {
2010 "column": 3, 2080 "column": 3,
2011 "line": 21 2081 "line": 22
2012 }, 2082 },
2013 "file": "src/components/settings/services/ServicesDashboard.js", 2083 "file": "src/components/settings/services/ServicesDashboard.js",
2014 "id": "settings.searchService", 2084 "id": "settings.searchService",
2015 "start": { 2085 "start": {
2016 "column": 17, 2086 "column": 17,
2017 "line": 18 2087 "line": 19
2018 } 2088 }
2019 }, 2089 },
2020 { 2090 {
2021 "defaultMessage": "!!!You haven't added any services yet.", 2091 "defaultMessage": "!!!You haven't added any services yet.",
2022 "end": { 2092 "end": {
2023 "column": 3, 2093 "column": 3,
2024 "line": 25 2094 "line": 26
2025 }, 2095 },
2026 "file": "src/components/settings/services/ServicesDashboard.js", 2096 "file": "src/components/settings/services/ServicesDashboard.js",
2027 "id": "settings.services.noServicesAdded", 2097 "id": "settings.services.noServicesAdded",
2028 "start": { 2098 "start": {
2029 "column": 19, 2099 "column": 19,
2030 "line": 22 2100 "line": 23
2031 } 2101 }
2032 }, 2102 },
2033 { 2103 {
2034 "defaultMessage": "!!!Sorry, but no service matched your search term.", 2104 "defaultMessage": "!!!Sorry, but no service matched your search term.",
2035 "end": { 2105 "end": {
2036 "column": 3, 2106 "column": 3,
2037 "line": 29 2107 "line": 30
2038 }, 2108 },
2039 "file": "src/components/settings/services/ServicesDashboard.js", 2109 "file": "src/components/settings/services/ServicesDashboard.js",
2040 "id": "settings.recipes.nothingFound", 2110 "id": "settings.recipes.nothingFound",
2041 "start": { 2111 "start": {
2042 "column": 18, 2112 "column": 18,
2043 "line": 26 2113 "line": 27
2044 } 2114 }
2045 }, 2115 },
2046 { 2116 {
2047 "defaultMessage": "!!!Discover services", 2117 "defaultMessage": "!!!Discover services",
2048 "end": { 2118 "end": {
2049 "column": 3, 2119 "column": 3,
2050 "line": 33 2120 "line": 34
2051 }, 2121 },
2052 "file": "src/components/settings/services/ServicesDashboard.js", 2122 "file": "src/components/settings/services/ServicesDashboard.js",
2053 "id": "settings.services.discoverServices", 2123 "id": "settings.services.discoverServices",
2054 "start": { 2124 "start": {
2055 "column": 20, 2125 "column": 20,
2056 "line": 30 2126 "line": 31
2057 } 2127 }
2058 }, 2128 },
2059 { 2129 {
2060 "defaultMessage": "!!!Could not load your services", 2130 "defaultMessage": "!!!Could not load your services",
2061 "end": { 2131 "end": {
2062 "column": 3, 2132 "column": 3,
2063 "line": 37 2133 "line": 38
2064 }, 2134 },
2065 "file": "src/components/settings/services/ServicesDashboard.js", 2135 "file": "src/components/settings/services/ServicesDashboard.js",
2066 "id": "settings.services.servicesRequestFailed", 2136 "id": "settings.services.servicesRequestFailed",
2067 "start": { 2137 "start": {
2068 "column": 25, 2138 "column": 25,
2069 "line": 34 2139 "line": 35
2070 } 2140 }
2071 }, 2141 },
2072 { 2142 {
2073 "defaultMessage": "!!!Try again", 2143 "defaultMessage": "!!!Try again",
2074 "end": { 2144 "end": {
2075 "column": 3, 2145 "column": 3,
2076 "line": 41 2146 "line": 42
2077 }, 2147 },
2078 "file": "src/components/settings/services/ServicesDashboard.js", 2148 "file": "src/components/settings/services/ServicesDashboard.js",
2079 "id": "settings.account.tryReloadServices", 2149 "id": "settings.account.tryReloadServices",
2080 "start": { 2150 "start": {
2081 "column": 21, 2151 "column": 21,
2082 "line": 38 2152 "line": 39
2083 } 2153 }
2084 }, 2154 },
2085 { 2155 {
2086 "defaultMessage": "!!!Your changes have been saved", 2156 "defaultMessage": "!!!Your changes have been saved",
2087 "end": { 2157 "end": {
2088 "column": 3, 2158 "column": 3,
2089 "line": 45 2159 "line": 46
2090 }, 2160 },
2091 "file": "src/components/settings/services/ServicesDashboard.js", 2161 "file": "src/components/settings/services/ServicesDashboard.js",
2092 "id": "settings.services.updatedInfo", 2162 "id": "settings.services.updatedInfo",
2093 "start": { 2163 "start": {
2094 "column": 15, 2164 "column": 15,
2095 "line": 42 2165 "line": 43
2096 } 2166 }
2097 }, 2167 },
2098 { 2168 {
2099 "defaultMessage": "!!!Service has been deleted", 2169 "defaultMessage": "!!!Service has been deleted",
2100 "end": { 2170 "end": {
2101 "column": 3, 2171 "column": 3,
2102 "line": 49 2172 "line": 50
2103 }, 2173 },
2104 "file": "src/components/settings/services/ServicesDashboard.js", 2174 "file": "src/components/settings/services/ServicesDashboard.js",
2105 "id": "settings.services.deletedInfo", 2175 "id": "settings.services.deletedInfo",
2106 "start": { 2176 "start": {
2107 "column": 15, 2177 "column": 15,
2108 "line": 46 2178 "line": 47
2109 } 2179 }
2110 } 2180 }
2111 ], 2181 ],
@@ -3305,37 +3375,6 @@
3305 { 3375 {
3306 "descriptors": [ 3376 "descriptors": [
3307 { 3377 {
3308 "defaultMessage": "!!!You have added {amount} of {limit} services. Please upgrade your account to add more services.",
3309 "end": {
3310 "column": 3,
3311 "line": 14
3312 },
3313 "file": "src/features/communityRecipes/components/LimitReachedInfobox.js",
3314 "id": "feature.serviceLimit.limitReached",
3315 "start": {
3316 "column": 16,
3317 "line": 11
3318 }
3319 },
3320 {
3321 "defaultMessage": "!!!Upgrade account",
3322 "end": {
3323 "column": 3,
3324 "line": 18
3325 },
3326 "file": "src/features/communityRecipes/components/LimitReachedInfobox.js",
3327 "id": "premiumFeature.button.upgradeAccount",
3328 "start": {
3329 "column": 10,
3330 "line": 15
3331 }
3332 }
3333 ],
3334 "path": "src/features/communityRecipes/components/LimitReachedInfobox.json"
3335 },
3336 {
3337 "descriptors": [
3338 {
3339 "defaultMessage": "!!!Please purchase license to skip waiting", 3378 "defaultMessage": "!!!Please purchase license to skip waiting",
3340 "end": { 3379 "end": {
3341 "column": 3, 3380 "column": 3,
@@ -3380,6 +3419,55 @@
3380 { 3419 {
3381 "descriptors": [ 3420 "descriptors": [
3382 { 3421 {
3422 "defaultMessage": "!!!Changes in Franz {version}",
3423 "end": {
3424 "column": 3,
3425 "line": 23
3426 },
3427 "file": "src/features/serviceLimit/components/AnnouncementScreen.js",
3428 "id": "feature.announcements.changelog.headline",
3429 "start": {
3430 "column": 12,
3431 "line": 20
3432 }
3433 }
3434 ],
3435 "path": "src/features/serviceLimit/components/AnnouncementScreen.json"
3436 },
3437 {
3438 "descriptors": [
3439 {
3440 "defaultMessage": "!!!You have added {amount} of {limit} services. Please upgrade your account to add more services.",
3441 "end": {
3442 "column": 3,
3443 "line": 14
3444 },
3445 "file": "src/features/serviceLimit/components/LimitReachedInfobox.js",
3446 "id": "feature.serviceLimit.limitReached",
3447 "start": {
3448 "column": 16,
3449 "line": 11
3450 }
3451 },
3452 {
3453 "defaultMessage": "!!!Upgrade account",
3454 "end": {
3455 "column": 3,
3456 "line": 18
3457 },
3458 "file": "src/features/serviceLimit/components/LimitReachedInfobox.js",
3459 "id": "premiumFeature.button.upgradeAccount",
3460 "start": {
3461 "column": 10,
3462 "line": 15
3463 }
3464 }
3465 ],
3466 "path": "src/features/serviceLimit/components/LimitReachedInfobox.json"
3467 },
3468 {
3469 "descriptors": [
3470 {
3383 "defaultMessage": "!!!Franz is better together!", 3471 "defaultMessage": "!!!Franz is better together!",
3384 "end": { 3472 "end": {
3385 "column": 3, 3473 "column": 3,
@@ -3476,37 +3564,6 @@
3476 { 3564 {
3477 "descriptors": [ 3565 "descriptors": [
3478 { 3566 {
3479 "defaultMessage": "!!!You have added {amount} of {limit} services. Please upgrade your account to add more services.",
3480 "end": {
3481 "column": 3,
3482 "line": 14
3483 },
3484 "file": "src/features/unofficialRecipes/components/LimitReachedInfobox.js",
3485 "id": "feature.serviceLimit.limitReached",
3486 "start": {
3487 "column": 16,
3488 "line": 11
3489 }
3490 },
3491 {
3492 "defaultMessage": "!!!Upgrade account",
3493 "end": {
3494 "column": 3,
3495 "line": 18
3496 },
3497 "file": "src/features/unofficialRecipes/components/LimitReachedInfobox.js",
3498 "id": "premiumFeature.button.upgradeAccount",
3499 "start": {
3500 "column": 10,
3501 "line": 15
3502 }
3503 }
3504 ],
3505 "path": "src/features/unofficialRecipes/components/LimitReachedInfobox.json"
3506 },
3507 {
3508 "descriptors": [
3509 {
3510 "defaultMessage": "!!!Create workspace", 3567 "defaultMessage": "!!!Create workspace",
3511 "end": { 3568 "end": {
3512 "column": 3, 3569 "column": 3,
diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json
index f84edda34..0a8e04b21 100644
--- a/src/i18n/locales/en-US.json
+++ b/src/i18n/locales/en-US.json
@@ -5,6 +5,7 @@
5 "feature.delayApp.action": "Get a Franz Supporter License", 5 "feature.delayApp.action": "Get a Franz Supporter License",
6 "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",
7 "feature.delayApp.text": "Franz will continue in {seconds} seconds.", 7 "feature.delayApp.text": "Franz will continue in {seconds} seconds.",
8 "feature.serviceLimit.limitReached": "You have added {amount} out of {limit} services that are included in your plan. Please upgrade your account to add more services.",
8 "feature.shareFranz.action.email": "Send as email", 9 "feature.shareFranz.action.email": "Send as email",
9 "feature.shareFranz.action.facebook": "Share on Facebook", 10 "feature.shareFranz.action.facebook": "Share on Facebook",
10 "feature.shareFranz.action.twitter": "Share on Twitter", 11 "feature.shareFranz.action.twitter": "Share on Twitter",
@@ -118,6 +119,11 @@
118 "service.errorHandler.headline": "Oh no!", 119 "service.errorHandler.headline": "Oh no!",
119 "service.errorHandler.message": "Error", 120 "service.errorHandler.message": "Error",
120 "service.errorHandler.text": "{name} has failed to load.", 121 "service.errorHandler.text": "{name} has failed to load.",
122 "service.restrictedHandler.action": "Upgrade Account",
123 "service.restrictedHandler.customUrl.headline": "Franz Professional Plan required",
124 "service.restrictedHandler.customUrl.text": "Please upgrade to the Franz Professional plan to use custom urls & self hosted services.",
125 "service.restrictedHandler.serviceLimit.headline": "You have reached your service limit.",
126 "service.restrictedHandler.serviceLimit.text": "Please upgrade your account to use more than {count} services.",
121 "service.webviewLoader.loading": "Loading", 127 "service.webviewLoader.loading": "Loading",
122 "services.getStarted": "Get started", 128 "services.getStarted": "Get started",
123 "services.welcome": "Welcome to Franz", 129 "services.welcome": "Welcome to Franz",
@@ -335,4 +341,4 @@
335 "workspaceDrawer.workspaceFeatureInfo": "<p>Franz Workspaces let you focus on what’s important right now. Set up different sets of services and easily switch between them at any time.</p><p>You decide which services you need when and where, so we can help you stay on top of your game - or easily switch off from work whenever you want.</p>", 341 "workspaceDrawer.workspaceFeatureInfo": "<p>Franz Workspaces let you focus on what’s important right now. Set up different sets of services and easily switch between them at any time.</p><p>You decide which services you need when and where, so we can help you stay on top of your game - or easily switch off from work whenever you want.</p>",
336 "workspaceDrawer.workspacesSettingsTooltip": "Edit workspaces settings", 342 "workspaceDrawer.workspacesSettingsTooltip": "Edit workspaces settings",
337 "workspaces.switchingIndicator.switchingTo": "Switching to" 343 "workspaces.switchingIndicator.switchingTo": "Switching to"
338} \ No newline at end of file 344}
diff --git a/src/i18n/messages/src/components/services/content/ServiceRestricted.json b/src/i18n/messages/src/components/services/content/ServiceRestricted.json
new file mode 100644
index 000000000..c1984afe3
--- /dev/null
+++ b/src/i18n/messages/src/components/services/content/ServiceRestricted.json
@@ -0,0 +1,67 @@
1[
2 {
3 "id": "service.restrictedHandler.serviceLimit.headline",
4 "defaultMessage": "!!!You have reached your service limit.",
5 "file": "src/components/services/content/ServiceRestricted.js",
6 "start": {
7 "line": 11,
8 "column": 24
9 },
10 "end": {
11 "line": 14,
12 "column": 3
13 }
14 },
15 {
16 "id": "service.restrictedHandler.serviceLimit.text",
17 "defaultMessage": "!!!Please upgrade your account to use more than {count} services.",
18 "file": "src/components/services/content/ServiceRestricted.js",
19 "start": {
20 "line": 15,
21 "column": 20
22 },
23 "end": {
24 "line": 18,
25 "column": 3
26 }
27 },
28 {
29 "id": "service.restrictedHandler.customUrl.headline",
30 "defaultMessage": "!!!Franz Professional Plan required",
31 "file": "src/components/services/content/ServiceRestricted.js",
32 "start": {
33 "line": 19,
34 "column": 21
35 },
36 "end": {
37 "line": 22,
38 "column": 3
39 }
40 },
41 {
42 "id": "service.restrictedHandler.customUrl.text",
43 "defaultMessage": "!!!Please upgrade to the Franz Professional plan to use custom urls & self hosted services.",
44 "file": "src/components/services/content/ServiceRestricted.js",
45 "start": {
46 "line": 23,
47 "column": 17
48 },
49 "end": {
50 "line": 26,
51 "column": 3
52 }
53 },
54 {
55 "id": "service.restrictedHandler.action",
56 "defaultMessage": "!!!Upgrade Account",
57 "file": "src/components/services/content/ServiceRestricted.js",
58 "start": {
59 "line": 27,
60 "column": 10
61 },
62 "end": {
63 "line": 30,
64 "column": 3
65 }
66 }
67] \ No newline at end of file
diff --git a/src/i18n/messages/src/components/settings/navigation/SettingsNavigation.json b/src/i18n/messages/src/components/settings/navigation/SettingsNavigation.json
index 70a989211..7dfb3ce04 100644
--- a/src/i18n/messages/src/components/settings/navigation/SettingsNavigation.json
+++ b/src/i18n/messages/src/components/settings/navigation/SettingsNavigation.json
@@ -4,11 +4,11 @@
4 "defaultMessage": "!!!Available services", 4 "defaultMessage": "!!!Available services",
5 "file": "src/components/settings/navigation/SettingsNavigation.js", 5 "file": "src/components/settings/navigation/SettingsNavigation.js",
6 "start": { 6 "start": {
7 "line": 13, 7 "line": 14,
8 "column": 21 8 "column": 21
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": "!!!Your services", 17 "defaultMessage": "!!!Your services",
18 "file": "src/components/settings/navigation/SettingsNavigation.js", 18 "file": "src/components/settings/navigation/SettingsNavigation.js",
19 "start": { 19 "start": {
20 "line": 17, 20 "line": 18,
21 "column": 16 21 "column": 16
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": "!!!Your workspaces", 30 "defaultMessage": "!!!Your workspaces",
31 "file": "src/components/settings/navigation/SettingsNavigation.js", 31 "file": "src/components/settings/navigation/SettingsNavigation.js",
32 "start": { 32 "start": {
33 "line": 21, 33 "line": 22,
34 "column": 18 34 "column": 18
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": "!!!Account", 43 "defaultMessage": "!!!Account",
44 "file": "src/components/settings/navigation/SettingsNavigation.js", 44 "file": "src/components/settings/navigation/SettingsNavigation.js",
45 "start": { 45 "start": {
46 "line": 25, 46 "line": 26,
47 "column": 11 47 "column": 11
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": "!!!Manage Team", 56 "defaultMessage": "!!!Manage Team",
57 "file": "src/components/settings/navigation/SettingsNavigation.js", 57 "file": "src/components/settings/navigation/SettingsNavigation.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": "!!!Settings", 69 "defaultMessage": "!!!Settings",
70 "file": "src/components/settings/navigation/SettingsNavigation.js", 70 "file": "src/components/settings/navigation/SettingsNavigation.js",
71 "start": { 71 "start": {
72 "line": 33, 72 "line": 34,
73 "column": 12 73 "column": 12
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": "!!!Invite Friends", 82 "defaultMessage": "!!!Invite Friends",
83 "file": "src/components/settings/navigation/SettingsNavigation.js", 83 "file": "src/components/settings/navigation/SettingsNavigation.js",
84 "start": { 84 "start": {
85 "line": 37, 85 "line": 38,
86 "column": 17 86 "column": 17
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": "!!!Logout", 95 "defaultMessage": "!!!Logout",
96 "file": "src/components/settings/navigation/SettingsNavigation.js", 96 "file": "src/components/settings/navigation/SettingsNavigation.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 }
diff --git a/src/i18n/messages/src/components/settings/recipes/RecipesDashboard.json b/src/i18n/messages/src/components/settings/recipes/RecipesDashboard.json
index 26dcd3da5..8afaaed50 100644
--- a/src/i18n/messages/src/components/settings/recipes/RecipesDashboard.json
+++ b/src/i18n/messages/src/components/settings/recipes/RecipesDashboard.json
@@ -4,11 +4,11 @@
4 "defaultMessage": "!!!Available Services", 4 "defaultMessage": "!!!Available Services",
5 "file": "src/components/settings/recipes/RecipesDashboard.js", 5 "file": "src/components/settings/recipes/RecipesDashboard.js",
6 "start": { 6 "start": {
7 "line": 19, 7 "line": 20,
8 "column": 12 8 "column": 12
9 }, 9 },
10 "end": { 10 "end": {
11 "line": 22, 11 "line": 23,
12 "column": 3 12 "column": 3
13 } 13 }
14 }, 14 },
@@ -17,11 +17,11 @@
17 "defaultMessage": "!!!Search service", 17 "defaultMessage": "!!!Search service",
18 "file": "src/components/settings/recipes/RecipesDashboard.js", 18 "file": "src/components/settings/recipes/RecipesDashboard.js",
19 "start": { 19 "start": {
20 "line": 23, 20 "line": 24,
21 "column": 17 21 "column": 17
22 }, 22 },
23 "end": { 23 "end": {
24 "line": 26, 24 "line": 27,
25 "column": 3 25 "column": 3
26 } 26 }
27 }, 27 },
@@ -30,11 +30,11 @@
30 "defaultMessage": "!!!Most popular", 30 "defaultMessage": "!!!Most popular",
31 "file": "src/components/settings/recipes/RecipesDashboard.js", 31 "file": "src/components/settings/recipes/RecipesDashboard.js",
32 "start": { 32 "start": {
33 "line": 27, 33 "line": 28,
34 "column": 22 34 "column": 22
35 }, 35 },
36 "end": { 36 "end": {
37 "line": 30, 37 "line": 31,
38 "column": 3 38 "column": 3
39 } 39 }
40 }, 40 },
@@ -43,11 +43,11 @@
43 "defaultMessage": "!!!All services", 43 "defaultMessage": "!!!All services",
44 "file": "src/components/settings/recipes/RecipesDashboard.js", 44 "file": "src/components/settings/recipes/RecipesDashboard.js",
45 "start": { 45 "start": {
46 "line": 31, 46 "line": 32,
47 "column": 14 47 "column": 14
48 }, 48 },
49 "end": { 49 "end": {
50 "line": 34, 50 "line": 35,
51 "column": 3 51 "column": 3
52 } 52 }
53 }, 53 },
@@ -56,11 +56,11 @@
56 "defaultMessage": "!!!Custom Services", 56 "defaultMessage": "!!!Custom Services",
57 "file": "src/components/settings/recipes/RecipesDashboard.js", 57 "file": "src/components/settings/recipes/RecipesDashboard.js",
58 "start": { 58 "start": {
59 "line": 35, 59 "line": 36,
60 "column": 17 60 "column": 17
61 }, 61 },
62 "end": { 62 "end": {
63 "line": 38, 63 "line": 39,
64 "column": 3 64 "column": 3
65 } 65 }
66 }, 66 },
@@ -69,11 +69,11 @@
69 "defaultMessage": "!!!Sorry, but no service matched your search term.", 69 "defaultMessage": "!!!Sorry, but no service matched your search term.",
70 "file": "src/components/settings/recipes/RecipesDashboard.js", 70 "file": "src/components/settings/recipes/RecipesDashboard.js",
71 "start": { 71 "start": {
72 "line": 39, 72 "line": 40,
73 "column": 16 73 "column": 16
74 }, 74 },
75 "end": { 75 "end": {
76 "line": 42, 76 "line": 43,
77 "column": 3 77 "column": 3
78 } 78 }
79 }, 79 },
@@ -82,11 +82,11 @@
82 "defaultMessage": "!!!Service successfully added", 82 "defaultMessage": "!!!Service successfully added",
83 "file": "src/components/settings/recipes/RecipesDashboard.js", 83 "file": "src/components/settings/recipes/RecipesDashboard.js",
84 "start": { 84 "start": {
85 "line": 43, 85 "line": 44,
86 "column": 31 86 "column": 31
87 }, 87 },
88 "end": { 88 "end": {
89 "line": 46, 89 "line": 47,
90 "column": 3 90 "column": 3
91 } 91 }
92 }, 92 },
@@ -95,11 +95,11 @@
95 "defaultMessage": "!!!Missing a service?", 95 "defaultMessage": "!!!Missing a service?",
96 "file": "src/components/settings/recipes/RecipesDashboard.js", 96 "file": "src/components/settings/recipes/RecipesDashboard.js",
97 "start": { 97 "start": {
98 "line": 47, 98 "line": 48,
99 "column": 18 99 "column": 18
100 }, 100 },
101 "end": { 101 "end": {
102 "line": 50, 102 "line": 51,
103 "column": 3 103 "column": 3
104 } 104 }
105 }, 105 },
@@ -108,11 +108,11 @@
108 "defaultMessage": "!!!To add a custom service, copy the recipe folder into:", 108 "defaultMessage": "!!!To add a custom service, copy the recipe folder into:",
109 "file": "src/components/settings/recipes/RecipesDashboard.js", 109 "file": "src/components/settings/recipes/RecipesDashboard.js",
110 "start": { 110 "start": {
111 "line": 51, 111 "line": 52,
112 "column": 21 112 "column": 21
113 }, 113 },
114 "end": { 114 "end": {
115 "line": 54, 115 "line": 55,
116 "column": 3 116 "column": 3
117 } 117 }
118 }, 118 },
@@ -121,11 +121,11 @@
121 "defaultMessage": "!!!Open directory", 121 "defaultMessage": "!!!Open directory",
122 "file": "src/components/settings/recipes/RecipesDashboard.js", 122 "file": "src/components/settings/recipes/RecipesDashboard.js",
123 "start": { 123 "start": {
124 "line": 55, 124 "line": 56,
125 "column": 14 125 "column": 14
126 }, 126 },
127 "end": { 127 "end": {
128 "line": 58, 128 "line": 59,
129 "column": 3 129 "column": 3
130 } 130 }
131 }, 131 },
@@ -134,11 +134,11 @@
134 "defaultMessage": "!!!Developer Documentation", 134 "defaultMessage": "!!!Developer Documentation",
135 "file": "src/components/settings/recipes/RecipesDashboard.js", 135 "file": "src/components/settings/recipes/RecipesDashboard.js",
136 "start": { 136 "start": {
137 "line": 59, 137 "line": 60,
138 "column": 15 138 "column": 15
139 }, 139 },
140 "end": { 140 "end": {
141 "line": 62, 141 "line": 63,
142 "column": 3 142 "column": 3
143 } 143 }
144 }, 144 },
@@ -147,11 +147,11 @@
147 "defaultMessage": "!!!Custom Service Recipes", 147 "defaultMessage": "!!!Custom Service Recipes",
148 "file": "src/components/settings/recipes/RecipesDashboard.js", 148 "file": "src/components/settings/recipes/RecipesDashboard.js",
149 "start": { 149 "start": {
150 "line": 63, 150 "line": 64,
151 "column": 25 151 "column": 25
152 }, 152 },
153 "end": { 153 "end": {
154 "line": 66, 154 "line": 67,
155 "column": 3 155 "column": 3
156 } 156 }
157 }, 157 },
@@ -160,11 +160,11 @@
160 "defaultMessage": "!!!Community Services", 160 "defaultMessage": "!!!Community Services",
161 "file": "src/components/settings/recipes/RecipesDashboard.js", 161 "file": "src/components/settings/recipes/RecipesDashboard.js",
162 "start": { 162 "start": {
163 "line": 67, 163 "line": 68,
164 "column": 28 164 "column": 28
165 }, 165 },
166 "end": { 166 "end": {
167 "line": 70, 167 "line": 71,
168 "column": 3 168 "column": 3
169 } 169 }
170 }, 170 },
@@ -173,11 +173,11 @@
173 "defaultMessage": "!!!Your Development Service Recipes", 173 "defaultMessage": "!!!Your Development Service Recipes",
174 "file": "src/components/settings/recipes/RecipesDashboard.js", 174 "file": "src/components/settings/recipes/RecipesDashboard.js",
175 "start": { 175 "start": {
176 "line": 71, 176 "line": 72,
177 "column": 22 177 "column": 22
178 }, 178 },
179 "end": { 179 "end": {
180 "line": 74, 180 "line": 75,
181 "column": 3 181 "column": 3
182 } 182 }
183 } 183 }
diff --git a/src/i18n/messages/src/components/settings/services/EditServiceForm.json b/src/i18n/messages/src/components/settings/services/EditServiceForm.json
index 42b741b7a..e66db807d 100644
--- a/src/i18n/messages/src/components/settings/services/EditServiceForm.json
+++ b/src/i18n/messages/src/components/settings/services/EditServiceForm.json
@@ -4,11 +4,11 @@
4 "defaultMessage": "!!!Save service", 4 "defaultMessage": "!!!Save service",
5 "file": "src/components/settings/services/EditServiceForm.js", 5 "file": "src/components/settings/services/EditServiceForm.js",
6 "start": { 6 "start": {
7 "line": 22, 7 "line": 24,
8 "column": 15 8 "column": 15
9 }, 9 },
10 "end": { 10 "end": {
11 "line": 25, 11 "line": 27,
12 "column": 3 12 "column": 3
13 } 13 }
14 }, 14 },
@@ -17,11 +17,11 @@
17 "defaultMessage": "!!!Delete Service", 17 "defaultMessage": "!!!Delete Service",
18 "file": "src/components/settings/services/EditServiceForm.js", 18 "file": "src/components/settings/services/EditServiceForm.js",
19 "start": { 19 "start": {
20 "line": 26, 20 "line": 28,
21 "column": 17 21 "column": 17
22 }, 22 },
23 "end": { 23 "end": {
24 "line": 29, 24 "line": 31,
25 "column": 3 25 "column": 3
26 } 26 }
27 }, 27 },
@@ -30,11 +30,11 @@
30 "defaultMessage": "!!!Available services", 30 "defaultMessage": "!!!Available services",
31 "file": "src/components/settings/services/EditServiceForm.js", 31 "file": "src/components/settings/services/EditServiceForm.js",
32 "start": { 32 "start": {
33 "line": 30, 33 "line": 32,
34 "column": 21 34 "column": 21
35 }, 35 },
36 "end": { 36 "end": {
37 "line": 33, 37 "line": 35,
38 "column": 3 38 "column": 3
39 } 39 }
40 }, 40 },
@@ -43,11 +43,11 @@
43 "defaultMessage": "!!!Your services", 43 "defaultMessage": "!!!Your services",
44 "file": "src/components/settings/services/EditServiceForm.js", 44 "file": "src/components/settings/services/EditServiceForm.js",
45 "start": { 45 "start": {
46 "line": 34, 46 "line": 36,
47 "column": 16 47 "column": 16
48 }, 48 },
49 "end": { 49 "end": {
50 "line": 37, 50 "line": 39,
51 "column": 3 51 "column": 3
52 } 52 }
53 }, 53 },
@@ -56,11 +56,11 @@
56 "defaultMessage": "!!!Add {name}", 56 "defaultMessage": "!!!Add {name}",
57 "file": "src/components/settings/services/EditServiceForm.js", 57 "file": "src/components/settings/services/EditServiceForm.js",
58 "start": { 58 "start": {
59 "line": 38, 59 "line": 40,
60 "column": 22 60 "column": 22
61 }, 61 },
62 "end": { 62 "end": {
63 "line": 41, 63 "line": 43,
64 "column": 3 64 "column": 3
65 } 65 }
66 }, 66 },
@@ -69,11 +69,11 @@
69 "defaultMessage": "!!!Edit {name}", 69 "defaultMessage": "!!!Edit {name}",
70 "file": "src/components/settings/services/EditServiceForm.js", 70 "file": "src/components/settings/services/EditServiceForm.js",
71 "start": { 71 "start": {
72 "line": 42, 72 "line": 44,
73 "column": 23 73 "column": 23
74 }, 74 },
75 "end": { 75 "end": {
76 "line": 45, 76 "line": 47,
77 "column": 3 77 "column": 3
78 } 78 }
79 }, 79 },
@@ -82,11 +82,11 @@
82 "defaultMessage": "!!!Hosted", 82 "defaultMessage": "!!!Hosted",
83 "file": "src/components/settings/services/EditServiceForm.js", 83 "file": "src/components/settings/services/EditServiceForm.js",
84 "start": { 84 "start": {
85 "line": 46, 85 "line": 48,
86 "column": 13 86 "column": 13
87 }, 87 },
88 "end": { 88 "end": {
89 "line": 49, 89 "line": 51,
90 "column": 3 90 "column": 3
91 } 91 }
92 }, 92 },
@@ -95,11 +95,11 @@
95 "defaultMessage": "!!!Self hosted ⭐️", 95 "defaultMessage": "!!!Self hosted ⭐️",
96 "file": "src/components/settings/services/EditServiceForm.js", 96 "file": "src/components/settings/services/EditServiceForm.js",
97 "start": { 97 "start": {
98 "line": 50, 98 "line": 52,
99 "column": 16 99 "column": 16
100 }, 100 },
101 "end": { 101 "end": {
102 "line": 53, 102 "line": 55,
103 "column": 3 103 "column": 3
104 } 104 }
105 }, 105 },
@@ -108,11 +108,11 @@
108 "defaultMessage": "!!!Use the hosted {name} service.", 108 "defaultMessage": "!!!Use the hosted {name} service.",
109 "file": "src/components/settings/services/EditServiceForm.js", 109 "file": "src/components/settings/services/EditServiceForm.js",
110 "start": { 110 "start": {
111 "line": 54, 111 "line": 56,
112 "column": 20 112 "column": 20
113 }, 113 },
114 "end": { 114 "end": {
115 "line": 57, 115 "line": 59,
116 "column": 3 116 "column": 3
117 } 117 }
118 }, 118 },
@@ -121,11 +121,11 @@
121 "defaultMessage": "!!!Could not validate custom {name} server.", 121 "defaultMessage": "!!!Could not validate custom {name} server.",
122 "file": "src/components/settings/services/EditServiceForm.js", 122 "file": "src/components/settings/services/EditServiceForm.js",
123 "start": { 123 "start": {
124 "line": 58, 124 "line": 60,
125 "column": 28 125 "column": 28
126 }, 126 },
127 "end": { 127 "end": {
128 "line": 61, 128 "line": 63,
129 "column": 3 129 "column": 3
130 } 130 }
131 }, 131 },
@@ -134,11 +134,11 @@
134 "defaultMessage": "!!!To add self hosted services, you need a Franz Premium Supporter Account.", 134 "defaultMessage": "!!!To add self hosted services, you need a Franz Premium Supporter Account.",
135 "file": "src/components/settings/services/EditServiceForm.js", 135 "file": "src/components/settings/services/EditServiceForm.js",
136 "start": { 136 "start": {
137 "line": 62, 137 "line": 64,
138 "column": 24 138 "column": 24
139 }, 139 },
140 "end": { 140 "end": {
141 "line": 65, 141 "line": 67,
142 "column": 3 142 "column": 3
143 } 143 }
144 }, 144 },
@@ -147,11 +147,11 @@
147 "defaultMessage": "!!!Upgrade your account", 147 "defaultMessage": "!!!Upgrade your account",
148 "file": "src/components/settings/services/EditServiceForm.js", 148 "file": "src/components/settings/services/EditServiceForm.js",
149 "start": { 149 "start": {
150 "line": 66, 150 "line": 68,
151 "column": 27 151 "column": 27
152 }, 152 },
153 "end": { 153 "end": {
154 "line": 69, 154 "line": 71,
155 "column": 3 155 "column": 3
156 } 156 }
157 }, 157 },
@@ -160,11 +160,11 @@
160 "defaultMessage": "!!!You will be notified about all new messages in a channel, not just @username, @channel, @here, ...", 160 "defaultMessage": "!!!You will be notified about all new messages in a channel, not just @username, @channel, @here, ...",
161 "file": "src/components/settings/services/EditServiceForm.js", 161 "file": "src/components/settings/services/EditServiceForm.js",
162 "start": { 162 "start": {
163 "line": 70, 163 "line": 72,
164 "column": 23 164 "column": 23
165 }, 165 },
166 "end": { 166 "end": {
167 "line": 73, 167 "line": 75,
168 "column": 3 168 "column": 3
169 } 169 }
170 }, 170 },
@@ -173,11 +173,11 @@
173 "defaultMessage": "!!!When disabled, all notification sounds and audio playback are muted", 173 "defaultMessage": "!!!When disabled, all notification sounds and audio playback are muted",
174 "file": "src/components/settings/services/EditServiceForm.js", 174 "file": "src/components/settings/services/EditServiceForm.js",
175 "start": { 175 "start": {
176 "line": 74, 176 "line": 76,
177 "column": 15 177 "column": 15
178 }, 178 },
179 "end": { 179 "end": {
180 "line": 77, 180 "line": 79,
181 "column": 3 181 "column": 3
182 } 182 }
183 }, 183 },
@@ -186,11 +186,11 @@
186 "defaultMessage": "!!!Notifications", 186 "defaultMessage": "!!!Notifications",
187 "file": "src/components/settings/services/EditServiceForm.js", 187 "file": "src/components/settings/services/EditServiceForm.js",
188 "start": { 188 "start": {
189 "line": 78, 189 "line": 80,
190 "column": 25 190 "column": 25
191 }, 191 },
192 "end": { 192 "end": {
193 "line": 81, 193 "line": 83,
194 "column": 3 194 "column": 3
195 } 195 }
196 }, 196 },
@@ -199,11 +199,11 @@
199 "defaultMessage": "!!!Unread message badges", 199 "defaultMessage": "!!!Unread message badges",
200 "file": "src/components/settings/services/EditServiceForm.js", 200 "file": "src/components/settings/services/EditServiceForm.js",
201 "start": { 201 "start": {
202 "line": 82, 202 "line": 84,
203 "column": 18 203 "column": 18
204 }, 204 },
205 "end": { 205 "end": {
206 "line": 85, 206 "line": 87,
207 "column": 3 207 "column": 3
208 } 208 }
209 }, 209 },
@@ -212,11 +212,11 @@
212 "defaultMessage": "!!!General", 212 "defaultMessage": "!!!General",
213 "file": "src/components/settings/services/EditServiceForm.js", 213 "file": "src/components/settings/services/EditServiceForm.js",
214 "start": { 214 "start": {
215 "line": 86, 215 "line": 88,
216 "column": 19 216 "column": 19
217 }, 217 },
218 "end": { 218 "end": {
219 "line": 89, 219 "line": 91,
220 "column": 3 220 "column": 3
221 } 221 }
222 }, 222 },
@@ -225,11 +225,11 @@
225 "defaultMessage": "!!!Delete", 225 "defaultMessage": "!!!Delete",
226 "file": "src/components/settings/services/EditServiceForm.js", 226 "file": "src/components/settings/services/EditServiceForm.js",
227 "start": { 227 "start": {
228 "line": 90, 228 "line": 92,
229 "column": 14 229 "column": 14
230 }, 230 },
231 "end": { 231 "end": {
232 "line": 93, 232 "line": 95,
233 "column": 3 233 "column": 3
234 } 234 }
235 }, 235 },
@@ -238,11 +238,11 @@
238 "defaultMessage": "!!!Drop your image, or click here", 238 "defaultMessage": "!!!Drop your image, or click here",
239 "file": "src/components/settings/services/EditServiceForm.js", 239 "file": "src/components/settings/services/EditServiceForm.js",
240 "start": { 240 "start": {
241 "line": 94, 241 "line": 96,
242 "column": 14 242 "column": 14
243 }, 243 },
244 "end": { 244 "end": {
245 "line": 97, 245 "line": 99,
246 "column": 3 246 "column": 3
247 } 247 }
248 }, 248 },
@@ -251,11 +251,11 @@
251 "defaultMessage": "!!!HTTP/HTTPS Proxy Settings", 251 "defaultMessage": "!!!HTTP/HTTPS Proxy Settings",
252 "file": "src/components/settings/services/EditServiceForm.js", 252 "file": "src/components/settings/services/EditServiceForm.js",
253 "start": { 253 "start": {
254 "line": 98, 254 "line": 100,
255 "column": 17 255 "column": 17
256 }, 256 },
257 "end": { 257 "end": {
258 "line": 101, 258 "line": 103,
259 "column": 3 259 "column": 3
260 } 260 }
261 }, 261 },
@@ -264,11 +264,11 @@
264 "defaultMessage": "!!!Please restart Franz after changing proxy Settings.", 264 "defaultMessage": "!!!Please restart Franz after changing proxy Settings.",
265 "file": "src/components/settings/services/EditServiceForm.js", 265 "file": "src/components/settings/services/EditServiceForm.js",
266 "start": { 266 "start": {
267 "line": 102, 267 "line": 104,
268 "column": 20 268 "column": 20
269 }, 269 },
270 "end": { 270 "end": {
271 "line": 105, 271 "line": 107,
272 "column": 3 272 "column": 3
273 } 273 }
274 }, 274 },
@@ -277,11 +277,11 @@
277 "defaultMessage": "!!!Proxy settings will not be synchronized with the Franz servers.", 277 "defaultMessage": "!!!Proxy settings will not be synchronized with the Franz servers.",
278 "file": "src/components/settings/services/EditServiceForm.js", 278 "file": "src/components/settings/services/EditServiceForm.js",
279 "start": { 279 "start": {
280 "line": 106, 280 "line": 108,
281 "column": 13 281 "column": 13
282 }, 282 },
283 "end": { 283 "end": {
284 "line": 109, 284 "line": 111,
285 "column": 3 285 "column": 3
286 } 286 }
287 } 287 }
diff --git a/src/i18n/messages/src/components/settings/services/ServicesDashboard.json b/src/i18n/messages/src/components/settings/services/ServicesDashboard.json
index 3803c6512..fa661ea2f 100644
--- a/src/i18n/messages/src/components/settings/services/ServicesDashboard.json
+++ b/src/i18n/messages/src/components/settings/services/ServicesDashboard.json
@@ -4,11 +4,11 @@
4 "defaultMessage": "!!!Your services", 4 "defaultMessage": "!!!Your services",
5 "file": "src/components/settings/services/ServicesDashboard.js", 5 "file": "src/components/settings/services/ServicesDashboard.js",
6 "start": { 6 "start": {
7 "line": 14, 7 "line": 15,
8 "column": 12 8 "column": 12
9 }, 9 },
10 "end": { 10 "end": {
11 "line": 17, 11 "line": 18,
12 "column": 3 12 "column": 3
13 } 13 }
14 }, 14 },
@@ -17,11 +17,11 @@
17 "defaultMessage": "!!!Search service", 17 "defaultMessage": "!!!Search service",
18 "file": "src/components/settings/services/ServicesDashboard.js", 18 "file": "src/components/settings/services/ServicesDashboard.js",
19 "start": { 19 "start": {
20 "line": 18, 20 "line": 19,
21 "column": 17 21 "column": 17
22 }, 22 },
23 "end": { 23 "end": {
24 "line": 21, 24 "line": 22,
25 "column": 3 25 "column": 3
26 } 26 }
27 }, 27 },
@@ -30,11 +30,11 @@
30 "defaultMessage": "!!!You haven't added any services yet.", 30 "defaultMessage": "!!!You haven't added any services yet.",
31 "file": "src/components/settings/services/ServicesDashboard.js", 31 "file": "src/components/settings/services/ServicesDashboard.js",
32 "start": { 32 "start": {
33 "line": 22, 33 "line": 23,
34 "column": 19 34 "column": 19
35 }, 35 },
36 "end": { 36 "end": {
37 "line": 25, 37 "line": 26,
38 "column": 3 38 "column": 3
39 } 39 }
40 }, 40 },
@@ -43,11 +43,11 @@
43 "defaultMessage": "!!!Sorry, but no service matched your search term.", 43 "defaultMessage": "!!!Sorry, but no service matched your search term.",
44 "file": "src/components/settings/services/ServicesDashboard.js", 44 "file": "src/components/settings/services/ServicesDashboard.js",
45 "start": { 45 "start": {
46 "line": 26, 46 "line": 27,
47 "column": 18 47 "column": 18
48 }, 48 },
49 "end": { 49 "end": {
50 "line": 29, 50 "line": 30,
51 "column": 3 51 "column": 3
52 } 52 }
53 }, 53 },
@@ -56,11 +56,11 @@
56 "defaultMessage": "!!!Discover services", 56 "defaultMessage": "!!!Discover services",
57 "file": "src/components/settings/services/ServicesDashboard.js", 57 "file": "src/components/settings/services/ServicesDashboard.js",
58 "start": { 58 "start": {
59 "line": 30, 59 "line": 31,
60 "column": 20 60 "column": 20
61 }, 61 },
62 "end": { 62 "end": {
63 "line": 33, 63 "line": 34,
64 "column": 3 64 "column": 3
65 } 65 }
66 }, 66 },
@@ -69,11 +69,11 @@
69 "defaultMessage": "!!!Could not load your services", 69 "defaultMessage": "!!!Could not load your services",
70 "file": "src/components/settings/services/ServicesDashboard.js", 70 "file": "src/components/settings/services/ServicesDashboard.js",
71 "start": { 71 "start": {
72 "line": 34, 72 "line": 35,
73 "column": 25 73 "column": 25
74 }, 74 },
75 "end": { 75 "end": {
76 "line": 37, 76 "line": 38,
77 "column": 3 77 "column": 3
78 } 78 }
79 }, 79 },
@@ -82,11 +82,11 @@
82 "defaultMessage": "!!!Try again", 82 "defaultMessage": "!!!Try again",
83 "file": "src/components/settings/services/ServicesDashboard.js", 83 "file": "src/components/settings/services/ServicesDashboard.js",
84 "start": { 84 "start": {
85 "line": 38, 85 "line": 39,
86 "column": 21 86 "column": 21
87 }, 87 },
88 "end": { 88 "end": {
89 "line": 41, 89 "line": 42,
90 "column": 3 90 "column": 3
91 } 91 }
92 }, 92 },
@@ -95,11 +95,11 @@
95 "defaultMessage": "!!!Your changes have been saved", 95 "defaultMessage": "!!!Your changes have been saved",
96 "file": "src/components/settings/services/ServicesDashboard.js", 96 "file": "src/components/settings/services/ServicesDashboard.js",
97 "start": { 97 "start": {
98 "line": 42, 98 "line": 43,
99 "column": 15 99 "column": 15
100 }, 100 },
101 "end": { 101 "end": {
102 "line": 45, 102 "line": 46,
103 "column": 3 103 "column": 3
104 } 104 }
105 }, 105 },
@@ -108,11 +108,11 @@
108 "defaultMessage": "!!!Service has been deleted", 108 "defaultMessage": "!!!Service has been deleted",
109 "file": "src/components/settings/services/ServicesDashboard.js", 109 "file": "src/components/settings/services/ServicesDashboard.js",
110 "start": { 110 "start": {
111 "line": 46, 111 "line": 47,
112 "column": 15 112 "column": 15
113 }, 113 },
114 "end": { 114 "end": {
115 "line": 49, 115 "line": 50,
116 "column": 3 116 "column": 3
117 } 117 }
118 } 118 }
diff --git a/src/i18n/messages/src/features/serviceLimit/components/AnnouncementScreen.json b/src/i18n/messages/src/features/serviceLimit/components/AnnouncementScreen.json
new file mode 100644
index 000000000..e6e3cef99
--- /dev/null
+++ b/src/i18n/messages/src/features/serviceLimit/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/serviceLimit/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/features/serviceLimit/components/LimitReachedInfobox.json b/src/i18n/messages/src/features/serviceLimit/components/LimitReachedInfobox.json
new file mode 100644
index 000000000..df5bc03e8
--- /dev/null
+++ b/src/i18n/messages/src/features/serviceLimit/components/LimitReachedInfobox.json
@@ -0,0 +1,28 @@
1[
2 {
3 "id": "feature.serviceLimit.limitReached",
4 "defaultMessage": "!!!You have added {amount} of {limit} services. Please upgrade your account to add more services.",
5 "file": "src/features/serviceLimit/components/LimitReachedInfobox.js",
6 "start": {
7 "line": 11,
8 "column": 16
9 },
10 "end": {
11 "line": 14,
12 "column": 3
13 }
14 },
15 {
16 "id": "premiumFeature.button.upgradeAccount",
17 "defaultMessage": "!!!Upgrade account",
18 "file": "src/features/serviceLimit/components/LimitReachedInfobox.js",
19 "start": {
20 "line": 15,
21 "column": 10
22 },
23 "end": {
24 "line": 18,
25 "column": 3
26 }
27 }
28] \ No newline at end of file
diff --git a/src/models/Service.js b/src/models/Service.js
index 88bce3360..848a84aa2 100644
--- a/src/models/Service.js
+++ b/src/models/Service.js
@@ -4,6 +4,11 @@ import normalizeUrl from 'normalize-url';
4 4
5const debug = require('debug')('Franz:Service'); 5const debug = require('debug')('Franz:Service');
6 6
7export const RESTRICTION_TYPES = {
8 SERVICE_LIMIT: 0,
9 CUSTOM_URL: 1,
10};
11
7export default class Service { 12export default class Service {
8 id = ''; 13 id = '';
9 14
@@ -59,6 +64,12 @@ export default class Service {
59 64
60 @observable errorMessage = ''; 65 @observable errorMessage = '';
61 66
67 @observable isUsingCustomUrl = false;
68
69 @observable isServiceAccessRestricted = false;
70
71 @observable restrictionType = null;
72
62 constructor(data, recipe) { 73 constructor(data, recipe) {
63 if (!data) { 74 if (!data) {
64 console.error('Service config not valid'); 75 console.error('Service config not valid');
@@ -111,6 +122,10 @@ export default class Service {
111 this.unreadDirectMessageCount = 0; 122 this.unreadDirectMessageCount = 0;
112 this.unreadIndirectMessageCount = 0; 123 this.unreadIndirectMessageCount = 0;
113 } 124 }
125
126 if (this.recipe.hasCustomUrl && this.customUrl) {
127 this.isUsingCustomUrl = true;
128 }
114 }); 129 });
115 } 130 }
116 131
diff --git a/src/stores/FeaturesStore.js b/src/stores/FeaturesStore.js
index 0f54a50af..27334c9a2 100644
--- a/src/stores/FeaturesStore.js
+++ b/src/stores/FeaturesStore.js
@@ -16,6 +16,7 @@ import workspaces from '../features/workspaces';
16import shareFranz from '../features/shareFranz'; 16import shareFranz from '../features/shareFranz';
17import announcements from '../features/announcements'; 17import announcements from '../features/announcements';
18import settingsWS from '../features/settingsWS'; 18import settingsWS from '../features/settingsWS';
19import serviceLimit from '../features/serviceLimit';
19import communityRecipes from '../features/communityRecipes'; 20import communityRecipes from '../features/communityRecipes';
20 21
21import { DEFAULT_FEATURES_CONFIG } from '../config'; 22import { DEFAULT_FEATURES_CONFIG } from '../config';
@@ -76,6 +77,7 @@ export default class FeaturesStore extends Store {
76 shareFranz(this.stores, this.actions); 77 shareFranz(this.stores, this.actions);
77 announcements(this.stores, this.actions); 78 announcements(this.stores, this.actions);
78 settingsWS(this.stores, this.actions); 79 settingsWS(this.stores, this.actions);
80 serviceLimit(this.stores, this.actions);
79 communityRecipes(this.stores, this.actions); 81 communityRecipes(this.stores, this.actions);
80 } 82 }
81} 83}
diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js
index 109ac5cd7..4cffea110 100644
--- a/src/stores/ServicesStore.js
+++ b/src/stores/ServicesStore.js
@@ -13,6 +13,8 @@ import CachedRequest from './lib/CachedRequest';
13import { matchRoute } from '../helpers/routing-helpers'; 13import { matchRoute } from '../helpers/routing-helpers';
14import { gaEvent, statsEvent } from '../lib/analytics'; 14import { gaEvent, statsEvent } from '../lib/analytics';
15import { workspaceStore } from '../features/workspaces'; 15import { workspaceStore } from '../features/workspaces';
16import { serviceLimitStore } from '../features/serviceLimit';
17import { RESTRICTION_TYPES } from '../models/Service';
16 18
17const debug = require('debug')('Franz:ServiceStore'); 19const debug = require('debug')('Franz:ServiceStore');
18 20
@@ -75,6 +77,7 @@ export default class ServicesStore extends Store {
75 this._saveActiveService.bind(this), 77 this._saveActiveService.bind(this),
76 this._logoutReaction.bind(this), 78 this._logoutReaction.bind(this),
77 this._handleMuteSettings.bind(this), 79 this._handleMuteSettings.bind(this),
80 this._restrictServiceAccess.bind(this),
78 ]); 81 ]);
79 82
80 // Just bind this 83 // Just bind this
@@ -98,7 +101,10 @@ export default class ServicesStore extends Store {
98 if (this.stores.user.isLoggedIn) { 101 if (this.stores.user.isLoggedIn) {
99 const services = this.allServicesRequest.execute().result; 102 const services = this.allServicesRequest.execute().result;
100 if (services) { 103 if (services) {
101 return observable(services.slice().slice().sort((a, b) => a.order - b.order)); 104 return observable(services.slice().slice().sort((a, b) => a.order - b.order).map((s, index) => {
105 s.index = index;
106 return s;
107 }));
102 } 108 }
103 } 109 }
104 return []; 110 return [];
@@ -153,6 +159,8 @@ export default class ServicesStore extends Store {
153 159
154 // Actions 160 // Actions
155 @action async _createService({ recipeId, serviceData, redirect = true }) { 161 @action async _createService({ recipeId, serviceData, redirect = true }) {
162 if (serviceLimitStore.userHasReachedServiceLimit) return;
163
156 const data = this._cleanUpTeamIdAndCustomUrl(recipeId, serviceData); 164 const data = this._cleanUpTeamIdAndCustomUrl(recipeId, serviceData);
157 165
158 const response = await this.createServiceRequest.execute(recipeId, data)._promise; 166 const response = await this.createServiceRequest.execute(recipeId, data)._promise;
@@ -678,6 +686,33 @@ export default class ServicesStore extends Store {
678 return serviceData; 686 return serviceData;
679 } 687 }
680 688
689 _restrictServiceAccess() {
690 const { features } = this.stores.features;
691 const { userHasReachedServiceLimit, serviceLimit } = this.stores.serviceLimit;
692
693 this.all.map((service, index) => {
694 if (userHasReachedServiceLimit) {
695 service.isServiceAccessRestricted = index >= serviceLimit;
696 service.restrictionType = RESTRICTION_TYPES.SERVICE_LIMIT;
697
698 if (index >= serviceLimit) {
699 debug('Restricting access to server due to service limit');
700 }
701 }
702
703 if (service.isUsingCustomUrl) {
704 service.isServiceAccessRestricted = features.isCustomUrlPremiumFeature;
705 service.restrictionType = RESTRICTION_TYPES.CUSTOM_URL;
706
707 if (features.isCustomUrlPremiumFeature) {
708 debug('Restricting access to server due to custom url');
709 }
710 }
711
712 return service;
713 });
714 }
715
681 // Helper 716 // Helper
682 _initializeServiceRecipeInWebview(serviceId) { 717 _initializeServiceRecipeInWebview(serviceId) {
683 const service = this.one(serviceId); 718 const service = this.one(serviceId);
diff --git a/src/stores/index.js b/src/stores/index.js
index 7f89bf1fb..c9ec77612 100644
--- a/src/stores/index.js
+++ b/src/stores/index.js
@@ -12,6 +12,7 @@ import RequestStore from './RequestStore';
12import GlobalErrorStore from './GlobalErrorStore'; 12import GlobalErrorStore from './GlobalErrorStore';
13import { workspaceStore } from '../features/workspaces'; 13import { workspaceStore } from '../features/workspaces';
14import { announcementsStore } from '../features/announcements'; 14import { announcementsStore } from '../features/announcements';
15import { serviceLimitStore } from '../features/serviceLimit';
15import { communityRecipesStore } from '../features/communityRecipes'; 16import { communityRecipesStore } from '../features/communityRecipes';
16 17
17export default (api, actions, router) => { 18export default (api, actions, router) => {
@@ -32,6 +33,7 @@ export default (api, actions, router) => {
32 globalError: new GlobalErrorStore(stores, api, actions), 33 globalError: new GlobalErrorStore(stores, api, actions),
33 workspaces: workspaceStore, 34 workspaces: workspaceStore,
34 announcements: announcementsStore, 35 announcements: announcementsStore,
36 serviceLimit: serviceLimitStore,
35 communityRecipes: communityRecipesStore, 37 communityRecipes: communityRecipesStore,
36 }); 38 });
37 // Initialize all stores 39 // Initialize all stores