aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/services/content
diff options
context:
space:
mode:
authorLibravatar vantezzen <properly@protonmail.com>2019-09-07 15:50:23 +0200
committerLibravatar vantezzen <properly@protonmail.com>2019-09-07 15:50:23 +0200
commite7a74514c1e7c3833dfdcf5900cb87f9e6e8354e (patch)
treeb8314e4155503b135dcb07e8b4a0e847e25c19cf /src/components/services/content
parentUpdate CHANGELOG.md (diff)
parentUpdate CHANGELOG.md (diff)
downloadferdium-app-e7a74514c1e7c3833dfdcf5900cb87f9e6e8354e.tar.gz
ferdium-app-e7a74514c1e7c3833dfdcf5900cb87f9e6e8354e.tar.zst
ferdium-app-e7a74514c1e7c3833dfdcf5900cb87f9e6e8354e.zip
Merge branch 'master' of https://github.com/meetfranz/franz into franz-5.3.0
Diffstat (limited to 'src/components/services/content')
-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.js48
3 files changed, 144 insertions, 7 deletions
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 5fad070f0..1afbaabc4 100644
--- a/src/components/services/content/Services.js
+++ b/src/components/services/content/Services.js
@@ -3,6 +3,9 @@ import PropTypes from 'prop-types';
3import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; 3import { observer, PropTypes as MobxPropTypes } from 'mobx-react';
4import { Link } from 'react-router'; 4import { Link } from 'react-router';
5import { defineMessages, intlShape } from 'react-intl'; 5import { defineMessages, intlShape } from 'react-intl';
6import Confetti from 'react-confetti';
7import ms from 'ms';
8import injectSheet from 'react-jss';
6 9
7import ServiceView from './ServiceView'; 10import ServiceView from './ServiceView';
8import Appear from '../../ui/effects/Appear'; 11import Appear from '../../ui/effects/Appear';
@@ -26,7 +29,17 @@ const messages = defineMessages({
26 }, 29 },
27}); 30});
28 31
29export default @observer class Services extends Component { 32
33const styles = {
34 confettiContainer: {
35 position: 'absolute',
36 width: '100%',
37 zIndex: 9999,
38 pointerEvents: 'none',
39 },
40};
41
42export default @observer @injectSheet(styles) class Services extends Component {
30 static propTypes = { 43 static propTypes = {
31 services: MobxPropTypes.arrayOrObservableArray, 44 services: MobxPropTypes.arrayOrObservableArray,
32 setWebviewReference: PropTypes.func.isRequired, 45 setWebviewReference: PropTypes.func.isRequired,
@@ -36,6 +49,9 @@ export default @observer class Services extends Component {
36 reload: PropTypes.func.isRequired, 49 reload: PropTypes.func.isRequired,
37 openSettings: PropTypes.func.isRequired, 50 openSettings: PropTypes.func.isRequired,
38 update: PropTypes.func.isRequired, 51 update: PropTypes.func.isRequired,
52 userHasCompletedSignup: PropTypes.bool.isRequired,
53 hasActivatedTrial: PropTypes.bool.isRequired,
54 classes: PropTypes.object.isRequired,
39 }; 55 };
40 56
41 static defaultProps = { 57 static defaultProps = {
@@ -46,6 +62,18 @@ export default @observer class Services extends Component {
46 intl: intlShape, 62 intl: intlShape,
47 }; 63 };
48 64
65 state = {
66 showConfetti: true,
67 }
68
69 componentDidMount() {
70 window.setTimeout(() => {
71 this.setState({
72 showConfetti: false,
73 });
74 }, ms('8s'));
75 }
76
49 render() { 77 render() {
50 const { 78 const {
51 services, 79 services,
@@ -56,12 +84,29 @@ export default @observer class Services extends Component {
56 reload, 84 reload,
57 openSettings, 85 openSettings,
58 update, 86 update,
87 userHasCompletedSignup,
88 hasActivatedTrial,
89 classes,
59 } = this.props; 90 } = this.props;
91
92 const {
93 showConfetti,
94 } = this.state;
95
60 const { intl } = this.context; 96 const { intl } = this.context;
61 const isLoggedIn = Boolean(localStorage.getItem('authToken')); 97 const isLoggedIn = Boolean(localStorage.getItem('authToken'));
62 98
63 return ( 99 return (
64 <div className="services"> 100 <div className="services">
101 {(userHasCompletedSignup || hasActivatedTrial) && (
102 <div className={classes.confettiContainer}>
103 <Confetti
104 width={window.width}
105 height={window.height}
106 numberOfPieces={showConfetti ? 200 : 0}
107 />
108 </div>
109 )}
65 {services.length === 0 && ( 110 {services.length === 0 && (
66 <Appear 111 <Appear
67 timeout={1500} 112 timeout={1500}
@@ -104,6 +149,7 @@ export default @observer class Services extends Component {
104 }, 149 },
105 redirect: false, 150 redirect: false,
106 })} 151 })}
152 upgrade={() => openSettings({ path: 'user' })}
107 /> 153 />
108 ))} 154 ))}
109 </div> 155 </div>