aboutsummaryrefslogtreecommitdiffstats
path: root/src/features/delayApp
diff options
context:
space:
mode:
Diffstat (limited to 'src/features/delayApp')
-rw-r--r--src/features/delayApp/Component.js120
-rw-r--r--src/features/delayApp/constants.js6
-rw-r--r--src/features/delayApp/index.js80
-rw-r--r--src/features/delayApp/styles.js22
4 files changed, 0 insertions, 228 deletions
diff --git a/src/features/delayApp/Component.js b/src/features/delayApp/Component.js
deleted file mode 100644
index 6471240ab..000000000
--- a/src/features/delayApp/Component.js
+++ /dev/null
@@ -1,120 +0,0 @@
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 '@meetfranz/forms';
8
9import { config } from './constants';
10import styles from './styles';
11import UserStore from '../../stores/UserStore';
12import UIStore from '../../stores/UIStore';
13import { FeatureStore } from '../utils/FeatureStore';
14
15const messages = defineMessages({
16 headline: {
17 id: 'feature.delayApp.headline',
18 defaultMessage: '!!!Please purchase license to skip waiting',
19 },
20 headlineTrial: {
21 id: 'feature.delayApp.trial.headline',
22 defaultMessage: '!!!Get the free Franz Professional 14 day trial and skip the line',
23 },
24 action: {
25 id: 'feature.delayApp.upgrade.action',
26 defaultMessage: '!!!Upgrade Franz',
27 },
28 actionTrial: {
29 id: 'feature.delayApp.trial.action',
30 defaultMessage: '!!!Yes, I want the free 14 day trial of Franz Professional',
31 },
32 text: {
33 id: 'feature.delayApp.text',
34 defaultMessage: '!!!Ferdi will continue in {seconds} seconds.',
35 },
36});
37
38export default @inject('stores', 'actions') @injectSheet(styles) @observer class DelayApp extends Component {
39 static propTypes = {
40 // eslint-disable-next-line
41 classes: PropTypes.object.isRequired,
42 };
43
44 static contextTypes = {
45 intl: intlShape,
46 };
47
48 state = {
49 countdown: config.delayDuration,
50 };
51
52 countdownInterval = null;
53
54 countdownIntervalTimeout = 1000;
55
56 componentDidMount() {
57 this.countdownInterval = setInterval(() => {
58 this.setState(prevState => ({
59 countdown: prevState.countdown - this.countdownIntervalTimeout,
60 }));
61
62 if (this.state.countdown <= 0) {
63 // reload();
64 clearInterval(this.countdownInterval);
65 }
66 }, this.countdownIntervalTimeout);
67 }
68
69 componentWillUnmount() {
70 clearInterval(this.countdownInterval);
71 }
72
73 handleCTAClick() {
74 const { actions, stores } = this.props;
75 const { hadSubscription } = stores.user.data;
76 const { defaultTrialPlan } = stores.features.features;
77
78 if (!hadSubscription) {
79 actions.user.activateTrial({ planId: defaultTrialPlan });
80 } else {
81 actions.ui.openSettings({ path: 'user' });
82 }
83 }
84
85 render() {
86 const { classes, stores } = this.props;
87 const { intl } = this.context;
88
89 const { hadSubscription } = stores.user.data;
90
91 return (
92 <div className={`${classes.container}`}>
93 <h1 className={classes.headline}>{intl.formatMessage(hadSubscription ? messages.headline : messages.headlineTrial)}</h1>
94 <Button
95 label={intl.formatMessage(hadSubscription ? messages.action : messages.actionTrial)}
96 className={classes.button}
97 buttonType="inverted"
98 onClick={this.handleCTAClick.bind(this)}
99 busy={stores.user.activateTrialRequest.isExecuting}
100 />
101 <p className="footnote">
102 {intl.formatMessage(messages.text, {
103 seconds: this.state.countdown / 1000,
104 })}
105 </p>
106 </div>
107 );
108 }
109}
110
111DelayApp.wrappedComponent.propTypes = {
112 stores: PropTypes.shape({
113 user: PropTypes.instanceOf(UserStore).isRequired,
114 features: PropTypes.instanceOf(FeatureStore).isRequired,
115 }).isRequired,
116 actions: PropTypes.shape({
117 ui: PropTypes.instanceOf(UIStore).isRequired,
118 user: PropTypes.instanceOf(UserStore).isRequired,
119 }).isRequired,
120};
diff --git a/src/features/delayApp/constants.js b/src/features/delayApp/constants.js
deleted file mode 100644
index 72cc4246e..000000000
--- a/src/features/delayApp/constants.js
+++ /dev/null
@@ -1,6 +0,0 @@
1import { DEFAULT_FEATURES_CONFIG } from '../../config';
2
3export const config = {
4 delayOffset: DEFAULT_FEATURES_CONFIG.needToWaitToProceedConfig.delayOffset,
5 delayDuration: DEFAULT_FEATURES_CONFIG.needToWaitToProceedConfig.wait,
6};
diff --git a/src/features/delayApp/index.js b/src/features/delayApp/index.js
deleted file mode 100644
index f0c2bdc82..000000000
--- a/src/features/delayApp/index.js
+++ /dev/null
@@ -1,80 +0,0 @@
1import { autorun, observable, reaction } from 'mobx';
2import moment from 'moment';
3import DelayAppComponent from './Component';
4import { config } from './constants';
5import { DEFAULT_FEATURES_CONFIG } from '../../config';
6import { getUserWorkspacesRequest } from '../workspaces/api';
7
8const debug = require('debug')('Ferdi:feature:delayApp');
9
10export const state = observable({
11 isDelayAppScreenVisible: DEFAULT_FEATURES_CONFIG.needToWaitToProceed,
12});
13
14function setVisibility(value) {
15 Object.assign(state, {
16 isDelayAppScreenVisible: value,
17 });
18}
19
20export default function init(stores) {
21 debug('Initializing `delayApp` feature');
22
23 let shownAfterLaunch = false;
24 let timeLastDelay = moment();
25
26 window.ferdi.features.delayApp = {
27 state,
28 };
29
30 reaction(
31 () => (
32 stores.user.isLoggedIn
33 && stores.services.allServicesRequest.wasExecuted
34 && getUserWorkspacesRequest.wasExecuted
35 && stores.features.features.needToWaitToProceed
36 && !stores.user.data.isPremium
37 ),
38 (isEnabled) => {
39 if (isEnabled) {
40 debug('Enabling `delayApp` feature');
41
42 const { needToWaitToProceedConfig: globalConfig } = stores.features.features;
43
44 config.delayOffset = globalConfig.delayOffset !== undefined ? globalConfig.delayOffset : DEFAULT_FEATURES_CONFIG.needToWaitToProceedConfig.delayOffset;
45 config.delayDuration = globalConfig.wait !== undefined ? globalConfig.wait : DEFAULT_FEATURES_CONFIG.needToWaitToProceedConfig.wait;
46
47 autorun(() => {
48 const { isAnnouncementShown } = stores.announcements;
49 if (stores.services.allDisplayed.length === 0 || isAnnouncementShown) {
50 shownAfterLaunch = true;
51 setVisibility(false);
52 return;
53 }
54
55 const diff = moment().diff(timeLastDelay);
56 const itsTimeToWait = diff >= config.delayOffset;
57 if (!isAnnouncementShown && ((stores.app.isFocused && itsTimeToWait) || !shownAfterLaunch)) {
58 debug(`App will be delayed for ${config.delayDuration / 1000}s`);
59
60 setVisibility(true);
61
62 setTimeout(() => {
63 debug('Resetting app delay');
64
65 shownAfterLaunch = true;
66 timeLastDelay = moment();
67 setVisibility(false);
68 }, config.delayDuration + 1000); // timer needs to be able to hit 0
69 } else {
70 setVisibility(false);
71 }
72 });
73 } else {
74 setVisibility(false);
75 }
76 },
77 );
78}
79
80export const Component = DelayAppComponent;
diff --git a/src/features/delayApp/styles.js b/src/features/delayApp/styles.js
deleted file mode 100644
index 69c3c7a27..000000000
--- a/src/features/delayApp/styles.js
+++ /dev/null
@@ -1,22 +0,0 @@
1export default theme => ({
2 container: {
3 background: theme.colorBackground,
4 top: 0,
5 width: '100%',
6 display: 'flex',
7 'flex-direction': 'column',
8 'align-items': 'center',
9 'justify-content': 'center',
10 'z-index': 150,
11 },
12 headline: {
13 color: theme.colorHeadline,
14 margin: [25, 0, 40],
15 'max-width': 500,
16 'text-align': 'center',
17 'line-height': '1.3em',
18 },
19 button: {
20 margin: [40, 0, 20],
21 },
22});