aboutsummaryrefslogtreecommitdiffstats
path: root/src/features
diff options
context:
space:
mode:
Diffstat (limited to 'src/features')
-rw-r--r--src/features/delayApp/Component.js88
-rw-r--r--src/features/delayApp/index.js70
-rw-r--r--src/features/delayApp/styles.js23
-rw-r--r--src/features/serviceProxy/index.js45
-rw-r--r--src/features/spellchecker/index.js27
5 files changed, 253 insertions, 0 deletions
diff --git a/src/features/delayApp/Component.js b/src/features/delayApp/Component.js
new file mode 100644
index 000000000..403340c7b
--- /dev/null
+++ b/src/features/delayApp/Component.js
@@ -0,0 +1,88 @@
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';
6
7import Button from '../../components/ui/Button';
8
9import { config } from './';
10import styles from './styles';
11
12const messages = defineMessages({
13 headline: {
14 id: 'feature.delayApp.headline',
15 defaultMessage: '!!!Please purchase license to skip waiting',
16 },
17 action: {
18 id: 'feature.delayApp.action',
19 defaultMessage: '!!!Get a Franz Supporter License',
20 },
21 text: {
22 id: 'feature.delayApp.text',
23 defaultMessage: '!!!Franz will continue in {seconds} seconds.',
24 },
25});
26
27export default @inject('actions') @injectSheet(styles) @observer class DelayApp extends Component {
28 static propTypes = {
29 // eslint-disable-next-line
30 classes: PropTypes.object.isRequired,
31 };
32
33 static contextTypes = {
34 intl: intlShape,
35 };
36
37 state = {
38 countdown: config.delayDuration,
39 }
40
41 componentDidMount() {
42 this.countdownInterval = setInterval(() => {
43 this.setState({
44 countdown: this.state.countdown - this.countdownIntervalTimeout,
45 });
46
47 if (this.state.countdown <= 0) {
48 // reload();
49 clearInterval(this.countdownInterval);
50 }
51 }, this.countdownIntervalTimeout);
52 }
53
54 componentWillUnmount() {
55 clearInterval(this.countdownInterval);
56 }
57
58 countdownInterval = null;
59 countdownIntervalTimeout = 1000;
60
61 render() {
62 const { classes, actions } = this.props;
63 const { intl } = this.context;
64
65 return (
66 <div className={`${classes.container}`}>
67 <h1 className={classes.headline}>{intl.formatMessage(messages.headline)}</h1>
68 <Button
69 label={intl.formatMessage(messages.action)}
70 className={classes.button}
71 buttonType="inverted"
72 onClick={() => actions.ui.openSettings({ path: 'user' })}
73 />
74 <p className="footnote">{intl.formatMessage(messages.text, {
75 seconds: this.state.countdown / 1000,
76 })}</p>
77 </div>
78 );
79 }
80}
81
82DelayApp.wrappedComponent.propTypes = {
83 actions: PropTypes.shape({
84 ui: PropTypes.shape({
85 openSettings: PropTypes.func.isRequired,
86 }).isRequired,
87 }).isRequired,
88};
diff --git a/src/features/delayApp/index.js b/src/features/delayApp/index.js
new file mode 100644
index 000000000..9ffa1d2fd
--- /dev/null
+++ b/src/features/delayApp/index.js
@@ -0,0 +1,70 @@
1import { autorun, observable, reaction } from 'mobx';
2import moment from 'moment';
3import DelayAppComponent from './Component';
4
5import { DEFAULT_FEATURES_CONFIG } from '../../config';
6
7const debug = require('debug')('Franz:feature:delayApp');
8
9export const config = {
10 delayOffset: DEFAULT_FEATURES_CONFIG.needToWaitToProceedConfig.delayOffset,
11 delayDuration: DEFAULT_FEATURES_CONFIG.needToWaitToProceedConfig.wait,
12};
13
14export const state = observable({
15 isDelayAppScreenVisible: DEFAULT_FEATURES_CONFIG.needToWaitToProceed,
16});
17
18function setVisibility(value) {
19 Object.assign(state, {
20 isDelayAppScreenVisible: value,
21 });
22}
23
24export default function init(stores) {
25 reaction(
26 () => stores.features.features.needToWaitToProceed,
27 (enabled, r) => {
28 if (enabled) {
29 debug('Initializing `delayApp` feature');
30
31 // Dispose the reaction to run this only once
32 r.dispose();
33
34 const { needToWaitToProceedConfig: globalConfig } = stores.features.features;
35
36 let shownAfterLaunch = false;
37 let timeLastDelay = moment();
38
39 config.delayOffset = globalConfig.delayOffset !== undefined ? globalConfig.delayOffset : DEFAULT_FEATURES_CONFIG.needToWaitToProceedConfig.delayOffset;
40 config.delayDuration = globalConfig.wait !== undefined ? globalConfig.wait : DEFAULT_FEATURES_CONFIG.needToWaitToProceedConfig.wait;
41
42 autorun(() => {
43 if (stores.services.all.length === 0) {
44 shownAfterLaunch = true;
45 return;
46 }
47
48 const diff = moment().diff(timeLastDelay);
49 if ((stores.app.isFocused && diff >= config.delayOffset) || !shownAfterLaunch) {
50 debug(`App will be delayed for ${config.delayDuration / 1000}s`);
51
52 setVisibility(true);
53
54 timeLastDelay = moment();
55 shownAfterLaunch = true;
56
57 setTimeout(() => {
58 debug('Resetting app delay');
59
60 setVisibility(false);
61 }, DEFAULT_FEATURES_CONFIG.needToWaitToProceedConfig.wait + 1000); // timer needs to be able to hit 0
62 }
63 });
64 }
65 },
66 );
67}
68
69export const Component = DelayAppComponent;
70
diff --git a/src/features/delayApp/styles.js b/src/features/delayApp/styles.js
new file mode 100644
index 000000000..5c214cfdf
--- /dev/null
+++ b/src/features/delayApp/styles.js
@@ -0,0 +1,23 @@
1export default theme => ({
2 container: {
3 background: theme.colorBackground,
4 position: 'absolute',
5 top: 0,
6 width: '100%',
7 display: 'flex',
8 'flex-direction': 'column',
9 'align-items': 'center',
10 'justify-content': 'center',
11 'z-index': 150,
12 },
13 headline: {
14 color: theme.colorHeadline,
15 margin: [25, 0, 40],
16 'max-width': 500,
17 'text-align': 'center',
18 'line-height': '1.3em',
19 },
20 button: {
21 margin: [40, 0, 20],
22 },
23});
diff --git a/src/features/serviceProxy/index.js b/src/features/serviceProxy/index.js
new file mode 100644
index 000000000..cad9844fd
--- /dev/null
+++ b/src/features/serviceProxy/index.js
@@ -0,0 +1,45 @@
1import { autorun, observable } from 'mobx';
2import { remote } from 'electron';
3
4import { DEFAULT_FEATURES_CONFIG } from '../../config';
5
6const { session } = remote;
7
8const debug = require('debug')('Franz:feature:serviceProxy');
9
10export const config = observable({
11 isEnabled: DEFAULT_FEATURES_CONFIG.isServiceProxyEnabled,
12 isPremium: DEFAULT_FEATURES_CONFIG.isServiceProxyPremiumFeature,
13});
14
15export default function init(stores) {
16 debug('Initializing `serviceProxy` feature');
17
18 autorun(() => {
19 const { isServiceProxyEnabled, isServiceProxyPremiumFeature } = stores.features.features;
20
21 config.isEnabled = isServiceProxyEnabled !== undefined ? isServiceProxyEnabled : DEFAULT_FEATURES_CONFIG.isServiceProxyEnabled;
22 config.isPremium = isServiceProxyPremiumFeature !== undefined ? isServiceProxyPremiumFeature : DEFAULT_FEATURES_CONFIG.isServiceProxyPremiumFeature;
23
24 const services = stores.services.all;
25 const isPremiumUser = stores.user.data.isPremium;
26
27 services.forEach((service) => {
28 const s = session.fromPartition(`persist:service-${service.id}`);
29 let proxyHost = 'direct://';
30
31 if (config.isEnabled && (isPremiumUser || !config.isPremium)) {
32 const serviceProxyConfig = stores.settings.proxy[service.id];
33
34 if (serviceProxyConfig && serviceProxyConfig.isEnabled && serviceProxyConfig.host) {
35 proxyHost = serviceProxyConfig.host;
36 }
37 }
38
39 s.setProxy({ proxyRules: proxyHost }, (e) => {
40 debug(`Using proxy "${proxyHost}" for "${service.name}" (${service.id})`, e);
41 });
42 });
43 });
44}
45
diff --git a/src/features/spellchecker/index.js b/src/features/spellchecker/index.js
new file mode 100644
index 000000000..63506103c
--- /dev/null
+++ b/src/features/spellchecker/index.js
@@ -0,0 +1,27 @@
1import { autorun, observable } from 'mobx';
2
3import { DEFAULT_FEATURES_CONFIG } from '../../config';
4
5const debug = require('debug')('Franz:feature:spellchecker');
6
7export const config = observable({
8 isPremiumFeature: DEFAULT_FEATURES_CONFIG.isSpellcheckerPremiumFeature,
9});
10
11export default function init(stores) {
12 debug('Initializing `spellchecker` feature');
13
14 autorun(() => {
15 const { isSpellcheckerPremiumFeature } = stores.features.features;
16
17 config.isPremiumFeature = isSpellcheckerPremiumFeature !== undefined ? isSpellcheckerPremiumFeature : DEFAULT_FEATURES_CONFIG.isSpellcheckerPremiumFeature;
18
19 if (!stores.user.data.isPremium && config.isPremiumFeature && stores.settings.app.enableSpellchecking) {
20 debug('Override settings.spellcheckerEnabled flag to false');
21
22 Object.assign(stores.settings.app, {
23 enableSpellchecking: false,
24 });
25 }
26 });
27}