diff options
author | 2018-11-25 23:02:12 +0100 | |
---|---|---|
committer | 2018-11-25 23:02:12 +0100 | |
commit | 0d9c7ff6a638861d54f29bf91c82847cfa62a24c (patch) | |
tree | 1091fc0fe9b498e7b6fa69386ed2586d298d9269 | |
parent | Fix delayApp issues (diff) | |
download | ferdium-app-0d9c7ff6a638861d54f29bf91c82847cfa62a24c.tar.gz ferdium-app-0d9c7ff6a638861d54f29bf91c82847cfa62a24c.tar.zst ferdium-app-0d9c7ff6a638861d54f29bf91c82847cfa62a24c.zip |
Move spellchecker to premium
-rw-r--r-- | .eslintrc | 1 | ||||
-rw-r--r-- | src/components/settings/settings/EditSettingsForm.js | 16 | ||||
-rw-r--r-- | src/components/subscription/SubscriptionForm.js | 29 | ||||
-rw-r--r-- | src/components/ui/PremiumFeatureContainer/index.js | 64 | ||||
-rw-r--r-- | src/components/ui/PremiumFeatureContainer/styles.js | 31 | ||||
-rw-r--r-- | src/components/ui/Toggle.js | 6 | ||||
-rw-r--r-- | src/config.js | 1 | ||||
-rw-r--r-- | src/containers/settings/EditSettingsScreen.js | 7 | ||||
-rw-r--r-- | src/features/spellchecker/index.js | 54 | ||||
-rw-r--r-- | src/features/spellchecker/styles.js | 26 | ||||
-rw-r--r-- | src/i18n/locales/en-US.json | 7 | ||||
-rw-r--r-- | src/models/Service.js | 4 | ||||
-rw-r--r-- | src/stores/FeaturesStore.js | 2 | ||||
-rw-r--r-- | src/theme/dark/index.js | 1 | ||||
-rw-r--r-- | src/theme/default/index.js | 23 |
15 files changed, 241 insertions, 31 deletions
@@ -13,6 +13,7 @@ | |||
13 | "react/jsx-filename-extension": [1, { | 13 | "react/jsx-filename-extension": [1, { |
14 | "extensions": [".js", ".jsx"] | 14 | "extensions": [".js", ".jsx"] |
15 | }], | 15 | }], |
16 | "react/forbid-prop-types": 1, | ||
16 | "no-underscore-dangle": 0, | 17 | "no-underscore-dangle": 0, |
17 | "max-len": 0, | 18 | "max-len": 0, |
18 | "class-methods-use-this": 0, | 19 | "class-methods-use-this": 0, |
diff --git a/src/components/settings/settings/EditSettingsForm.js b/src/components/settings/settings/EditSettingsForm.js index b5c048ebd..b87c11fc4 100644 --- a/src/components/settings/settings/EditSettingsForm.js +++ b/src/components/settings/settings/EditSettingsForm.js | |||
@@ -8,6 +8,7 @@ import Form from '../../../lib/Form'; | |||
8 | import Button from '../../ui/Button'; | 8 | import Button from '../../ui/Button'; |
9 | import Toggle from '../../ui/Toggle'; | 9 | import Toggle from '../../ui/Toggle'; |
10 | import Select from '../../ui/Select'; | 10 | import Select from '../../ui/Select'; |
11 | import PremiumFeatureContainer from '../../ui/PremiumFeatureContainer'; | ||
11 | 12 | ||
12 | import { FRANZ_TRANSLATION } from '../../../config'; | 13 | import { FRANZ_TRANSLATION } from '../../../config'; |
13 | 14 | ||
@@ -95,6 +96,8 @@ export default @observer class EditSettingsForm extends Component { | |||
95 | isClearingAllCache: PropTypes.bool.isRequired, | 96 | isClearingAllCache: PropTypes.bool.isRequired, |
96 | onClearAllCache: PropTypes.func.isRequired, | 97 | onClearAllCache: PropTypes.func.isRequired, |
97 | cacheSize: PropTypes.string.isRequired, | 98 | cacheSize: PropTypes.string.isRequired, |
99 | isPremiumUser: PropTypes.bool.isRequired, | ||
100 | isSpellcheckerPremiumFeature: PropTypes.bool.isRequired, | ||
98 | }; | 101 | }; |
99 | 102 | ||
100 | static contextTypes = { | 103 | static contextTypes = { |
@@ -124,6 +127,8 @@ export default @observer class EditSettingsForm extends Component { | |||
124 | isClearingAllCache, | 127 | isClearingAllCache, |
125 | onClearAllCache, | 128 | onClearAllCache, |
126 | cacheSize, | 129 | cacheSize, |
130 | isPremiumUser, | ||
131 | isSpellcheckerPremiumFeature, | ||
127 | } = this.props; | 132 | } = this.props; |
128 | const { intl } = this.context; | 133 | const { intl } = this.context; |
129 | 134 | ||
@@ -175,7 +180,16 @@ export default @observer class EditSettingsForm extends Component { | |||
175 | 180 | ||
176 | {/* Advanced */} | 181 | {/* Advanced */} |
177 | <h2 id="advanced">{intl.formatMessage(messages.headlineAdvanced)}</h2> | 182 | <h2 id="advanced">{intl.formatMessage(messages.headlineAdvanced)}</h2> |
178 | <Toggle field={form.$('enableSpellchecking')} /> | 183 | {!isPremiumUser && isSpellcheckerPremiumFeature ? ( |
184 | <PremiumFeatureContainer> | ||
185 | <Toggle | ||
186 | field={form.$('enableSpellchecking')} | ||
187 | disabled | ||
188 | /> | ||
189 | </PremiumFeatureContainer> | ||
190 | ) : ( | ||
191 | <Toggle field={form.$('enableSpellchecking')} /> | ||
192 | )} | ||
179 | <Toggle field={form.$('enableGPUAcceleration')} /> | 193 | <Toggle field={form.$('enableGPUAcceleration')} /> |
180 | <p className="settings__help">{intl.formatMessage(messages.enableGPUAccelerationInfo)}</p> | 194 | <p className="settings__help">{intl.formatMessage(messages.enableGPUAccelerationInfo)}</p> |
181 | {/* <Select field={form.$('spellcheckingLanguage')} /> */} | 195 | {/* <Select field={form.$('spellcheckingLanguage')} /> */} |
diff --git a/src/components/subscription/SubscriptionForm.js b/src/components/subscription/SubscriptionForm.js index 5992e4204..8b8fd4f18 100644 --- a/src/components/subscription/SubscriptionForm.js +++ b/src/components/subscription/SubscriptionForm.js | |||
@@ -36,26 +36,25 @@ const messages = defineMessages({ | |||
36 | defaultMessage: '!!!The Franz Premium Supporter Account includes', | 36 | defaultMessage: '!!!The Franz Premium Supporter Account includes', |
37 | }, | 37 | }, |
38 | features: { | 38 | features: { |
39 | unlimitedServices: { | ||
40 | id: 'subscription.features.unlimitedServices', | ||
41 | defaultMessage: '!!!Add unlimited services', | ||
42 | }, | ||
43 | onpremise: { | 39 | onpremise: { |
44 | id: 'subscription.features.onpremise', | 40 | id: 'subscription.features.onpremise.mattermost', |
45 | defaultMessage: '!!!Add on-premise/hosted services like HipChat', | 41 | defaultMessage: '!!!Add on-premise/hosted services like Mattermost', |
46 | }, | ||
47 | customServices: { | ||
48 | id: 'subscription.features.customServices', | ||
49 | defaultMessage: '!!!Add your custom services', | ||
50 | }, | 42 | }, |
51 | encryptedSync: { | 43 | encryptedSync: { |
52 | id: 'subscription.features.encryptedSync', | 44 | id: 'subscription.features.encryptedSync', |
53 | defaultMessage: '!!!Encrypted session synchronization', | 45 | defaultMessage: '!!!Encrypted session synchronization', |
46 | noInterruptions: { | ||
47 | id: 'subscription.features.noInterruptions', | ||
48 | defaultMessage: '!!!No app delays & nagging to upgrade license', | ||
54 | }, | 49 | }, |
55 | vpn: { | 50 | vpn: { |
56 | id: 'subscription.features.vpn', | 51 | id: 'subscription.features.vpn', |
57 | defaultMessage: '!!!Proxy & VPN support', | 52 | defaultMessage: '!!!Proxy & VPN support', |
58 | }, | 53 | }, |
54 | spellchecker: { | ||
55 | id: 'subscription.features.spellchecker', | ||
56 | defaultMessage: '!!!Support for Spellchecker', | ||
57 | }, | ||
59 | ads: { | 58 | ads: { |
60 | id: 'subscription.features.ads', | 59 | id: 'subscription.features.ads', |
61 | defaultMessage: '!!!No ads, ever!', | 60 | defaultMessage: '!!!No ads, ever!', |
@@ -170,16 +169,10 @@ export default @observer class SubscriptionForm extends Component { | |||
170 | <ul className="subscription__premium-features"> | 169 | <ul className="subscription__premium-features"> |
171 | <li>{intl.formatMessage(messages.features.onpremise)}</li> | 170 | <li>{intl.formatMessage(messages.features.onpremise)}</li> |
172 | <li> | 171 | <li> |
173 | {intl.formatMessage(messages.features.encryptedSync)} | 172 | {intl.formatMessage(messages.features.noInterruptions)} |
174 | <span className="badge">{intl.formatMessage(messages.features.comingSoon)}</span> | ||
175 | </li> | ||
176 | <li> | ||
177 | {intl.formatMessage(messages.features.customServices)} | ||
178 | <span className="badge">{intl.formatMessage(messages.features.comingSoon)}</span> | ||
179 | </li> | 173 | </li> |
180 | <li> | 174 | <li> |
181 | {intl.formatMessage(messages.features.vpn)} | 175 | {intl.formatMessage(messages.features.spellchecker)} |
182 | <span className="badge">{intl.formatMessage(messages.features.comingSoon)}</span> | ||
183 | </li> | 176 | </li> |
184 | <li> | 177 | <li> |
185 | {intl.formatMessage(messages.features.ads)} | 178 | {intl.formatMessage(messages.features.ads)} |
diff --git a/src/components/ui/PremiumFeatureContainer/index.js b/src/components/ui/PremiumFeatureContainer/index.js new file mode 100644 index 000000000..113fe2221 --- /dev/null +++ b/src/components/ui/PremiumFeatureContainer/index.js | |||
@@ -0,0 +1,64 @@ | |||
1 | import React, { Component } from 'react'; | ||
2 | import { inject, observer } from 'mobx-react'; | ||
3 | import PropTypes from 'prop-types'; | ||
4 | import { defineMessages, intlShape } from 'react-intl'; | ||
5 | import injectSheet from 'react-jss'; | ||
6 | |||
7 | import { oneOrManyChildElements } from '../../../prop-types'; | ||
8 | |||
9 | import styles from './styles'; | ||
10 | |||
11 | const messages = defineMessages({ | ||
12 | action: { | ||
13 | id: 'premiumFeature.button.upgradeAccount', | ||
14 | defaultMessage: '!!!Upgrade account', | ||
15 | }, | ||
16 | }); | ||
17 | |||
18 | export default @inject('actions') @injectSheet(styles) @observer class PremiumFeatureContainer extends Component { | ||
19 | static propTypes = { | ||
20 | classes: PropTypes.object.isRequired, | ||
21 | }; | ||
22 | |||
23 | static contextTypes = { | ||
24 | intl: intlShape, | ||
25 | }; | ||
26 | |||
27 | render() { | ||
28 | const { | ||
29 | classes, | ||
30 | children, | ||
31 | actions, | ||
32 | } = this.props; | ||
33 | |||
34 | const { intl } = this.context; | ||
35 | |||
36 | return ( | ||
37 | <div className={classes.container}> | ||
38 | <div className={classes.titleContainer}> | ||
39 | <p className={classes.title}>Premium Feature</p> | ||
40 | <button | ||
41 | className={classes.actionButton} | ||
42 | type="button" | ||
43 | onClick={() => actions.ui.openSettings({ path: 'user' })} | ||
44 | > | ||
45 | {intl.formatMessage(messages.action)} | ||
46 | </button> | ||
47 | </div> | ||
48 | <div className={classes.content}> | ||
49 | {children} | ||
50 | </div> | ||
51 | </div> | ||
52 | ); | ||
53 | } | ||
54 | } | ||
55 | |||
56 | PremiumFeatureContainer.wrappedComponent.propTypes = { | ||
57 | children: oneOrManyChildElements.isRequired, | ||
58 | actions: PropTypes.shape({ | ||
59 | ui: PropTypes.shape({ | ||
60 | openSettings: PropTypes.func.isRequired, | ||
61 | }).isRequired, | ||
62 | }).isRequired, | ||
63 | }; | ||
64 | |||
diff --git a/src/components/ui/PremiumFeatureContainer/styles.js b/src/components/ui/PremiumFeatureContainer/styles.js new file mode 100644 index 000000000..16c40d0ec --- /dev/null +++ b/src/components/ui/PremiumFeatureContainer/styles.js | |||
@@ -0,0 +1,31 @@ | |||
1 | export default theme => ({ | ||
2 | container: { | ||
3 | background: theme.colorSubscriptionContainerBackground, | ||
4 | border: theme.colorSubscriptionContainerBorder, | ||
5 | margin: [0, 0, 20, -20], | ||
6 | padding: 20, | ||
7 | 'border-radius': theme.borderRadius, | ||
8 | }, | ||
9 | titleContainer: { | ||
10 | display: 'flex', | ||
11 | }, | ||
12 | title: { | ||
13 | 'font-weight': 'bold', | ||
14 | color: theme.colorSubscriptionContainerTitle, | ||
15 | }, | ||
16 | actionButton: { | ||
17 | background: theme.colorSubscriptionContainerActionButtonBackground, | ||
18 | color: theme.colorSubscriptionContainerActionButtonColor, | ||
19 | 'margin-left': 'auto', | ||
20 | 'border-radius': theme.borderRadiusSmall, | ||
21 | padding: [2, 4], | ||
22 | 'font-size': 12, | ||
23 | }, | ||
24 | content: { | ||
25 | opacity: 0.5, | ||
26 | 'margin-top': 20, | ||
27 | '& :last-child': { | ||
28 | 'margin-bottom': 0, | ||
29 | }, | ||
30 | }, | ||
31 | }); | ||
diff --git a/src/components/ui/Toggle.js b/src/components/ui/Toggle.js index f7c2ec955..78fb77cbe 100644 --- a/src/components/ui/Toggle.js +++ b/src/components/ui/Toggle.js | |||
@@ -9,11 +9,13 @@ export default @observer class Toggle extends Component { | |||
9 | field: PropTypes.instanceOf(Field).isRequired, | 9 | field: PropTypes.instanceOf(Field).isRequired, |
10 | className: PropTypes.string, | 10 | className: PropTypes.string, |
11 | showLabel: PropTypes.bool, | 11 | showLabel: PropTypes.bool, |
12 | disabled: PropTypes.bool, | ||
12 | }; | 13 | }; |
13 | 14 | ||
14 | static defaultProps = { | 15 | static defaultProps = { |
15 | className: '', | 16 | className: '', |
16 | showLabel: true, | 17 | showLabel: true, |
18 | disabled: false, | ||
17 | }; | 19 | }; |
18 | 20 | ||
19 | onChange(e) { | 21 | onChange(e) { |
@@ -27,6 +29,7 @@ export default @observer class Toggle extends Component { | |||
27 | field, | 29 | field, |
28 | className, | 30 | className, |
29 | showLabel, | 31 | showLabel, |
32 | disabled, | ||
30 | } = this.props; | 33 | } = this.props; |
31 | 34 | ||
32 | if (field.value === '' && field.default !== '') { | 35 | if (field.value === '' && field.default !== '') { |
@@ -38,6 +41,7 @@ export default @observer class Toggle extends Component { | |||
38 | className={classnames([ | 41 | className={classnames([ |
39 | 'franz-form__field', | 42 | 'franz-form__field', |
40 | 'franz-form__toggle-wrapper', | 43 | 'franz-form__toggle-wrapper', |
44 | 'franz-form__toggle-disabled', | ||
41 | className, | 45 | className, |
42 | ])} | 46 | ])} |
43 | > | 47 | > |
@@ -55,7 +59,7 @@ export default @observer class Toggle extends Component { | |||
55 | name={field.name} | 59 | name={field.name} |
56 | value={field.name} | 60 | value={field.name} |
57 | checked={field.value} | 61 | checked={field.value} |
58 | onChange={e => this.onChange(e)} | 62 | onChange={e => (!disabled ? this.onChange(e) : null)} |
59 | /> | 63 | /> |
60 | </label> | 64 | </label> |
61 | {field.error && <div className={field.error}>{field.error}</div>} | 65 | {field.error && <div className={field.error}>{field.error}</div>} |
diff --git a/src/config.js b/src/config.js index ce946f00a..ebffacceb 100644 --- a/src/config.js +++ b/src/config.js | |||
@@ -23,6 +23,7 @@ export const DEFAULT_APP_SETTINGS = { | |||
23 | beta: false, | 23 | beta: false, |
24 | isAppMuted: false, | 24 | isAppMuted: false, |
25 | enableGPUAcceleration: true, | 25 | enableGPUAcceleration: true, |
26 | serviceLimit: 5, | ||
26 | }; | 27 | }; |
27 | 28 | ||
28 | export const FRANZ_SERVICE_REQUEST = 'https://bit.ly/franz-service-request'; | 29 | export const FRANZ_SERVICE_REQUEST = 'https://bit.ly/franz-service-request'; |
diff --git a/src/containers/settings/EditSettingsScreen.js b/src/containers/settings/EditSettingsScreen.js index df6442eb8..2fb6bed5f 100644 --- a/src/containers/settings/EditSettingsScreen.js +++ b/src/containers/settings/EditSettingsScreen.js | |||
@@ -10,6 +10,7 @@ import Form from '../../lib/Form'; | |||
10 | import { APP_LOCALES } from '../../i18n/languages'; | 10 | import { APP_LOCALES } from '../../i18n/languages'; |
11 | import { gaPage } from '../../lib/analytics'; | 11 | import { gaPage } from '../../lib/analytics'; |
12 | import { DEFAULT_APP_SETTINGS } from '../../config'; | 12 | import { DEFAULT_APP_SETTINGS } from '../../config'; |
13 | import { config as spellcheckerConfig } from '../../features/spellchecker'; | ||
13 | 14 | ||
14 | 15 | ||
15 | import EditSettingsForm from '../../components/settings/settings/EditSettingsForm'; | 16 | import EditSettingsForm from '../../components/settings/settings/EditSettingsForm'; |
@@ -161,8 +162,8 @@ export default @inject('stores', 'actions') @observer class EditSettingsScreen e | |||
161 | }, | 162 | }, |
162 | enableSpellchecking: { | 163 | enableSpellchecking: { |
163 | label: intl.formatMessage(messages.enableSpellchecking), | 164 | label: intl.formatMessage(messages.enableSpellchecking), |
164 | value: settings.all.app.enableSpellchecking, | 165 | value: !this.props.stores.user.data.isPremium && spellcheckerConfig.isPremiumFeature ? false : settings.all.app.enableSpellchecking, |
165 | default: DEFAULT_APP_SETTINGS.enableSpellchecking, | 166 | default: !this.props.stores.user.data.isPremium && spellcheckerConfig.isPremiumFeature ? false : DEFAULT_APP_SETTINGS.enableSpellchecking, |
166 | }, | 167 | }, |
167 | darkMode: { | 168 | darkMode: { |
168 | label: intl.formatMessage(messages.darkMode), | 169 | label: intl.formatMessage(messages.darkMode), |
@@ -218,6 +219,8 @@ export default @inject('stores', 'actions') @observer class EditSettingsScreen e | |||
218 | cacheSize={cacheSize} | 219 | cacheSize={cacheSize} |
219 | isClearingAllCache={isClearingAllCache} | 220 | isClearingAllCache={isClearingAllCache} |
220 | onClearAllCache={clearAllCache} | 221 | onClearAllCache={clearAllCache} |
222 | isPremiumUser={this.props.stores.user.data.isPremium} | ||
223 | isSpellcheckerPremiumFeature={spellcheckerConfig.isPremiumFeature} | ||
221 | /> | 224 | /> |
222 | ); | 225 | ); |
223 | } | 226 | } |
diff --git a/src/features/spellchecker/index.js b/src/features/spellchecker/index.js new file mode 100644 index 000000000..2627c9d17 --- /dev/null +++ b/src/features/spellchecker/index.js | |||
@@ -0,0 +1,54 @@ | |||
1 | import { autorun, reaction } from 'mobx'; | ||
2 | |||
3 | const debug = require('debug')('Franz:feature:spellchecker'); | ||
4 | |||
5 | const DEFAULT_IS_PREMIUM_FEATURE = true; | ||
6 | |||
7 | export const config = { | ||
8 | isPremiumFeature: DEFAULT_IS_PREMIUM_FEATURE, | ||
9 | }; | ||
10 | |||
11 | export default function init(stores) { | ||
12 | reaction( | ||
13 | () => stores.features.features.needToWaitToProceed, | ||
14 | (enabled, r) => { | ||
15 | if (enabled) { | ||
16 | debug('Initializing `spellchecker` feature'); | ||
17 | |||
18 | // Dispose the reaction to run this only once | ||
19 | r.dispose(); | ||
20 | |||
21 | const { isSpellcheckerPremiumFeature } = stores.features.features; | ||
22 | |||
23 | config.isPremiumFeature = isSpellcheckerPremiumFeature || DEFAULT_IS_PREMIUM_FEATURE; | ||
24 | |||
25 | // reaction( | ||
26 | // () => stores.settings.all.app.enableSpellchecking, | ||
27 | // (enabled, r) => { | ||
28 | // if (enabled) { | ||
29 | // // debug('Initializing `spellchecker` feature'); | ||
30 | |||
31 | // // // Dispose the reaction to run this only once | ||
32 | // // r.dispose(); | ||
33 | |||
34 | // // const { isSpellcheckerPremiumFeature } = stores.features.features; | ||
35 | |||
36 | // // config.isPremiumFeature = isSpellcheckerPremiumFeature || DEFAULT_IS_PREMIUM_FEATURE; | ||
37 | // } | ||
38 | // }, | ||
39 | // ); | ||
40 | |||
41 | autorun(() => { | ||
42 | if (!stores.user.data.isPremium && config.isPremiumFeature) { | ||
43 | debug('Override settings.spellcheckerEnabled flag to false'); | ||
44 | |||
45 | Object.assign(stores.settings.all.app, { | ||
46 | enableSpellchecker: false, | ||
47 | }); | ||
48 | } | ||
49 | }); | ||
50 | } | ||
51 | }, | ||
52 | ); | ||
53 | } | ||
54 | |||
diff --git a/src/features/spellchecker/styles.js b/src/features/spellchecker/styles.js new file mode 100644 index 000000000..097368d9a --- /dev/null +++ b/src/features/spellchecker/styles.js | |||
@@ -0,0 +1,26 @@ | |||
1 | export default (theme) => { | ||
2 | console.log(theme); | ||
3 | return ({ | ||
4 | container: { | ||
5 | background: theme.colorBackground, | ||
6 | position: 'absolute', | ||
7 | top: 0, | ||
8 | width: '100%', | ||
9 | display: 'flex', | ||
10 | 'flex-direction': 'column', | ||
11 | 'align-items': 'center', | ||
12 | 'justify-content': 'center', | ||
13 | 'z-index': 150, | ||
14 | }, | ||
15 | headline: { | ||
16 | color: theme.colorHeadline, | ||
17 | margin: [25, 0, 40], | ||
18 | 'max-width': 500, | ||
19 | 'text-align': 'center', | ||
20 | 'line-height': '1.3em', | ||
21 | }, | ||
22 | button: { | ||
23 | margin: [40, 0, 20], | ||
24 | }, | ||
25 | }); | ||
26 | }; | ||
diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 24e29df18..be2a38231 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json | |||
@@ -50,10 +50,12 @@ | |||
50 | "subscription.paymentSessionError": "Could not initialize payment form", | 50 | "subscription.paymentSessionError": "Could not initialize payment form", |
51 | "subscription.includedFeatures": "Paid Franz Premium Supporter Account includes", | 51 | "subscription.includedFeatures": "Paid Franz Premium Supporter Account includes", |
52 | "subscription.features.onpremise": "Add on-premise/hosted services like HipChat", | 52 | "subscription.features.onpremise": "Add on-premise/hosted services like HipChat", |
53 | "subscription.features.customServices": "Private services for you and your team", | 53 | "subscription.features.onpremise.mattermost": "Add on-premise/hosted services like Mattermost", |
54 | "subscription.features.encryptedSync": "Encrypted session synchronization", | 54 | "subscription.features.encryptedSync": "Encrypted session synchronization", |
55 | "subscription.features.vpn": "Proxy & VPN support", | 55 | "subscription.features.vpn": "Proxy & VPN support", |
56 | "subscription.features.ads": "No ads, ever!", | 56 | "subscription.features.ads": "No ads, ever!", |
57 | "subscription.features.spellchecker": "Support for spellchecker", | ||
58 | "subscription.features.noInterruptions": "No app delays & nagging to upgrade license", | ||
57 | "subscription.features.comingSoon": "coming soon", | 59 | "subscription.features.comingSoon": "coming soon", |
58 | "infobar.servicesUpdated": "Your services have been updated.", | 60 | "infobar.servicesUpdated": "Your services have been updated.", |
59 | "infobar.updateAvailable": "A new update for Franz is available.", | 61 | "infobar.updateAvailable": "A new update for Franz is available.", |
@@ -252,5 +254,6 @@ | |||
252 | "validation.minLength": "{field} should be at least {length} characters long", | 254 | "validation.minLength": "{field} should be at least {length} characters long", |
253 | "feature.delayApp.headline": "Please purchase a Franz Supporter License to skip waiting", | 255 | "feature.delayApp.headline": "Please purchase a Franz Supporter License to skip waiting", |
254 | "feature.delayApp.action": "Get a Franz Supporter License", | 256 | "feature.delayApp.action": "Get a Franz Supporter License", |
255 | "feature.delayApp.text": "Franz will continue in {seconds} seconds." | 257 | "feature.delayApp.text": "Franz will continue in {seconds} seconds.", |
258 | "premiumFeature.button.upgradeAccount": "Upgrade account" | ||
256 | } | 259 | } |
diff --git a/src/models/Service.js b/src/models/Service.js index 1bab8bd68..d04b34b7e 100644 --- a/src/models/Service.js +++ b/src/models/Service.js | |||
@@ -30,6 +30,10 @@ export default class Service { | |||
30 | @observable hasCrashed = false; | 30 | @observable hasCrashed = false; |
31 | @observable isDarkModeEnabled = false; | 31 | @observable isDarkModeEnabled = false; |
32 | 32 | ||
33 | // @observable proxy = { | ||
34 | // isEnabled: false, | ||
35 | // }; | ||
36 | |||
33 | constructor(data, recipe) { | 37 | constructor(data, recipe) { |
34 | if (!data) { | 38 | if (!data) { |
35 | console.error('Service config not valid'); | 39 | console.error('Service config not valid'); |
diff --git a/src/stores/FeaturesStore.js b/src/stores/FeaturesStore.js index 9740d078f..dd4827221 100644 --- a/src/stores/FeaturesStore.js +++ b/src/stores/FeaturesStore.js | |||
@@ -4,6 +4,7 @@ import Store from './lib/Store'; | |||
4 | import CachedRequest from './lib/CachedRequest'; | 4 | import CachedRequest from './lib/CachedRequest'; |
5 | 5 | ||
6 | import delayApp from '../features/delayApp'; | 6 | import delayApp from '../features/delayApp'; |
7 | import spellchecker from '../features/spellchecker'; | ||
7 | 8 | ||
8 | export default class FeaturesStore extends Store { | 9 | export default class FeaturesStore extends Store { |
9 | @observable defaultFeaturesRequest = new CachedRequest(this.api.features, 'default'); | 10 | @observable defaultFeaturesRequest = new CachedRequest(this.api.features, 'default'); |
@@ -36,5 +37,6 @@ export default class FeaturesStore extends Store { | |||
36 | 37 | ||
37 | _enableFeatures() { | 38 | _enableFeatures() { |
38 | delayApp(this.stores, this.actions); | 39 | delayApp(this.stores, this.actions); |
40 | spellchecker(this.stores, this.actions); | ||
39 | } | 41 | } |
40 | } | 42 | } |
diff --git a/src/theme/dark/index.js b/src/theme/dark/index.js index e0e017c7c..496a51119 100644 --- a/src/theme/dark/index.js +++ b/src/theme/dark/index.js | |||
@@ -1,5 +1,6 @@ | |||
1 | import * as legacyStyles from '../default/legacy'; | 1 | import * as legacyStyles from '../default/legacy'; |
2 | 2 | ||
3 | export const colorBackground = legacyStyles.darkThemeGrayDarkest; | 3 | export const colorBackground = legacyStyles.darkThemeGrayDarkest; |
4 | export const colorBackgroundSubscriptionContainer = legacyStyles.themeBrandInfo; | ||
4 | 5 | ||
5 | export const colorHeadline = legacyStyles.darkThemeTextColor; | 6 | export const colorHeadline = legacyStyles.darkThemeTextColor; |
diff --git a/src/theme/default/index.js b/src/theme/default/index.js index f8b6e898d..8766fb609 100644 --- a/src/theme/default/index.js +++ b/src/theme/default/index.js | |||
@@ -1,12 +1,21 @@ | |||
1 | import * as legacyStyles from './legacy'; | 1 | import * as legacyStyles from './legacy'; |
2 | 2 | ||
3 | /* legacy config, injected into sass */ | 3 | export const brandPrimary = '#3498db'; |
4 | export const themeBrandPrimary = '#3498db'; | 4 | export const brandSuccess = '#5cb85c'; |
5 | export const themeBrandSuccess = '#5cb85c'; | 5 | export const brandInfo = '#5bc0de'; |
6 | export const themeBrandInfo = '#5bc0de'; | 6 | export const brandWarning = '#FF9F00'; |
7 | export const themeBrandWarning = '#FF9F00'; | 7 | export const brandDanger = '#d9534f'; |
8 | export const themeBrandDanger = '#d9534f'; | ||
9 | 8 | ||
10 | export const colorBackground = legacyStyles.themeGrayLighter; | 9 | export const borderRadius = legacyStyles.themeBorderRadius; |
10 | export const borderRadiusSmall = legacyStyles.themeBorderRadiusSmall; | ||
11 | 11 | ||
12 | export const colorBackground = legacyStyles.themeGrayLighter; | ||
12 | export const colorHeadline = legacyStyles.themeGrayDark; | 13 | export const colorHeadline = legacyStyles.themeGrayDark; |
14 | |||
15 | // Subscription Container Component | ||
16 | export const colorSubscriptionContainerBackground = 'none'; | ||
17 | export const colorSubscriptionContainerBorder = [1, 'solid', brandPrimary]; | ||
18 | export const colorSubscriptionContainerTitle = brandPrimary; | ||
19 | export const colorSubscriptionContainerActionButtonBackground = brandPrimary; | ||
20 | export const colorSubscriptionContainerActionButtonColor = '#FFF'; | ||
21 | |||