diff options
Diffstat (limited to 'src/components/services/content')
7 files changed, 29 insertions, 118 deletions
diff --git a/src/components/services/content/ConnectionLostBanner.js b/src/components/services/content/ConnectionLostBanner.js index e54a88faa..ebe863333 100644 --- a/src/components/services/content/ConnectionLostBanner.js +++ b/src/components/services/content/ConnectionLostBanner.js | |||
@@ -5,9 +5,7 @@ import injectSheet from 'react-jss'; | |||
5 | import { Icon } from '@meetfranz/ui'; | 5 | import { Icon } from '@meetfranz/ui'; |
6 | import { intlShape, defineMessages } from 'react-intl'; | 6 | import { intlShape, defineMessages } from 'react-intl'; |
7 | 7 | ||
8 | import { | 8 | import { mdiAlert } from '@mdi/js'; |
9 | mdiAlert, | ||
10 | } from '@mdi/js'; | ||
11 | import { LIVE_API_FERDI_WEBSITE } from '../../../config'; | 9 | import { LIVE_API_FERDI_WEBSITE } from '../../../config'; |
12 | // import { Button } from '@meetfranz/forms'; | 10 | // import { Button } from '@meetfranz/forms'; |
13 | 11 | ||
@@ -26,6 +24,12 @@ const messages = defineMessages({ | |||
26 | }, | 24 | }, |
27 | }); | 25 | }); |
28 | 26 | ||
27 | let buttonTransition = 'none'; | ||
28 | |||
29 | if (window && window.matchMedia('(prefers-reduced-motion: no-preference)')) { | ||
30 | buttonTransition = 'opacity 0.25s'; | ||
31 | } | ||
32 | |||
29 | const styles = theme => ({ | 33 | const styles = theme => ({ |
30 | root: { | 34 | root: { |
31 | background: theme.colorBackground, | 35 | background: theme.colorBackground, |
@@ -47,7 +51,7 @@ const styles = theme => ({ | |||
47 | opacity: 0.7, | 51 | opacity: 0.7, |
48 | }, | 52 | }, |
49 | button: { | 53 | button: { |
50 | transition: 'opacity 0.25s', | 54 | transition: buttonTransition, |
51 | color: theme.colorText, | 55 | color: theme.colorText, |
52 | border: [1, 'solid', theme.colorText], | 56 | border: [1, 'solid', theme.colorText], |
53 | borderRadius: theme.borderRadiusSmall, | 57 | borderRadius: theme.borderRadiusSmall, |
@@ -65,13 +69,14 @@ const styles = theme => ({ | |||
65 | }, | 69 | }, |
66 | }); | 70 | }); |
67 | 71 | ||
68 | @injectSheet(styles) @observer | 72 | @injectSheet(styles) |
73 | @observer | ||
69 | class ConnectionLostBanner extends Component { | 74 | class ConnectionLostBanner extends Component { |
70 | static propTypes = { | 75 | static propTypes = { |
71 | classes: PropTypes.object.isRequired, | 76 | classes: PropTypes.object.isRequired, |
72 | name: PropTypes.string.isRequired, | 77 | name: PropTypes.string.isRequired, |
73 | reload: PropTypes.func.isRequired, | 78 | reload: PropTypes.func.isRequired, |
74 | } | 79 | }; |
75 | 80 | ||
76 | static contextTypes = { | 81 | static contextTypes = { |
77 | intl: intlShape, | 82 | intl: intlShape, |
@@ -80,20 +85,13 @@ class ConnectionLostBanner extends Component { | |||
80 | inputRef = React.createRef(); | 85 | inputRef = React.createRef(); |
81 | 86 | ||
82 | render() { | 87 | render() { |
83 | const { | 88 | const { classes, name, reload } = this.props; |
84 | classes, | ||
85 | name, | ||
86 | reload, | ||
87 | } = this.props; | ||
88 | 89 | ||
89 | const { intl } = this.context; | 90 | const { intl } = this.context; |
90 | 91 | ||
91 | return ( | 92 | return ( |
92 | <div className={classes.root}> | 93 | <div className={classes.root}> |
93 | <Icon | 94 | <Icon icon={mdiAlert} className={classes.icon} /> |
94 | icon={mdiAlert} | ||
95 | className={classes.icon} | ||
96 | /> | ||
97 | <p> | 95 | <p> |
98 | {intl.formatMessage(messages.text, { name })} | 96 | {intl.formatMessage(messages.text, { name })} |
99 | <br /> | 97 | <br /> |
@@ -104,11 +102,7 @@ class ConnectionLostBanner extends Component { | |||
104 | {intl.formatMessage(messages.moreInformation)} | 102 | {intl.formatMessage(messages.moreInformation)} |
105 | </a> | 103 | </a> |
106 | </p> | 104 | </p> |
107 | <button | 105 | <button type="button" className={classes.button} onClick={reload}> |
108 | type="button" | ||
109 | className={classes.button} | ||
110 | onClick={reload} | ||
111 | > | ||
112 | {intl.formatMessage(messages.cta)} | 106 | {intl.formatMessage(messages.cta)} |
113 | </button> | 107 | </button> |
114 | </div> | 108 | </div> |
diff --git a/src/components/services/content/ErrorHandlers/styles.js b/src/components/services/content/ErrorHandlers/styles.js index 9e2509ee5..72d62f5e3 100644 --- a/src/components/services/content/ErrorHandlers/styles.js +++ b/src/components/services/content/ErrorHandlers/styles.js | |||
@@ -1,4 +1,4 @@ | |||
1 | export default theme => ({ | 1 | export default (theme) => ({ |
2 | component: { | 2 | component: { |
3 | left: 0, | 3 | left: 0, |
4 | position: 'absolute', | 4 | position: 'absolute', |
diff --git a/src/components/services/content/ServiceRestricted.js b/src/components/services/content/ServiceRestricted.js deleted file mode 100644 index 4b8d926aa..000000000 --- a/src/components/services/content/ServiceRestricted.js +++ /dev/null | |||
@@ -1,78 +0,0 @@ | |||
1 | import React, { Component } from 'react'; | ||
2 | import PropTypes from 'prop-types'; | ||
3 | import { observer } from 'mobx-react'; | ||
4 | import { defineMessages, intlShape } from 'react-intl'; | ||
5 | |||
6 | import { serviceLimitStore } from '../../../features/serviceLimit'; | ||
7 | import Button from '../../ui/Button'; | ||
8 | import { RESTRICTION_TYPES } from '../../../models/Service'; | ||
9 | |||
10 | const 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 | |||
33 | export 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 17d2db5a0..3fc084ff0 100644 --- a/src/components/services/content/ServiceView.js +++ b/src/components/services/content/ServiceView.js | |||
@@ -145,19 +145,17 @@ export default @inject('stores', 'actions') @observer class ServiceView extends | |||
145 | </> | 145 | </> |
146 | ) : ( | 146 | ) : ( |
147 | <> | 147 | <> |
148 | {(!service.isHibernating || service.isHibernationEnabled) ? ( | 148 | {!service.isHibernating ? ( |
149 | <> | 149 | <> |
150 | {showNavBar && ( | 150 | {showNavBar && ( |
151 | <WebControlsScreen service={service} /> | 151 | <WebControlsScreen service={service} /> |
152 | )} | 152 | )} |
153 | {!service.isHibernating && ( | 153 | <ServiceWebview |
154 | <ServiceWebview | 154 | service={service} |
155 | service={service} | 155 | setWebviewReference={setWebviewReference} |
156 | setWebviewReference={setWebviewReference} | 156 | detachService={detachService} |
157 | detachService={detachService} | 157 | isSpellcheckerEnabled={isSpellcheckerEnabled} |
158 | isSpellcheckerEnabled={isSpellcheckerEnabled} | 158 | /> |
159 | /> | ||
160 | )} | ||
161 | </> | 159 | </> |
162 | ) : ( | 160 | ) : ( |
163 | <div> | 161 | <div> |
diff --git a/src/components/services/content/ServiceWebview.js b/src/components/services/content/ServiceWebview.js index 9e5fed996..3b499a5db 100644 --- a/src/components/services/content/ServiceWebview.js +++ b/src/components/services/content/ServiceWebview.js | |||
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; | |||
3 | import { observer } from 'mobx-react'; | 3 | import { observer } from 'mobx-react'; |
4 | import { observable, reaction } from 'mobx'; | 4 | import { observable, reaction } from 'mobx'; |
5 | import ElectronWebView from 'react-electron-web-view'; | 5 | import ElectronWebView from 'react-electron-web-view'; |
6 | import path from 'path'; | 6 | import { join } from 'path'; |
7 | 7 | ||
8 | import ServiceModel from '../../../models/Service'; | 8 | import ServiceModel from '../../../models/Service'; |
9 | 9 | ||
@@ -59,7 +59,7 @@ class ServiceWebview extends Component { | |||
59 | isSpellcheckerEnabled, | 59 | isSpellcheckerEnabled, |
60 | } = this.props; | 60 | } = this.props; |
61 | 61 | ||
62 | const preloadScript = path.join(__dirname, '../../../', 'webview', 'recipe.js'); | 62 | const preloadScript = join(__dirname, '..', '..', '..', 'webview', 'recipe.js'); |
63 | 63 | ||
64 | return ( | 64 | return ( |
65 | <ElectronWebView | 65 | <ElectronWebView |
@@ -83,7 +83,7 @@ class ServiceWebview extends Component { | |||
83 | useragent={service.userAgent} | 83 | useragent={service.userAgent} |
84 | disablewebsecurity={service.recipe.disablewebsecurity ? true : undefined} | 84 | disablewebsecurity={service.recipe.disablewebsecurity ? true : undefined} |
85 | allowpopups | 85 | allowpopups |
86 | webpreferences={`spellcheck=${isSpellcheckerEnabled ? 1 : 0}, contextIsolation=false`} | 86 | webpreferences={`spellcheck=${isSpellcheckerEnabled ? 1 : 0}`} |
87 | /> | 87 | /> |
88 | ); | 88 | ); |
89 | } | 89 | } |
diff --git a/src/components/services/content/Services.js b/src/components/services/content/Services.js index caa3cf9aa..bb93ff7d4 100644 --- a/src/components/services/content/Services.js +++ b/src/components/services/content/Services.js | |||
@@ -30,7 +30,7 @@ const messages = defineMessages({ | |||
30 | }, | 30 | }, |
31 | serverInfo: { | 31 | serverInfo: { |
32 | id: 'services.serverInfo', | 32 | id: 'services.serverInfo', |
33 | defaultMessage: '!!!Optionally, you can change your Ferdi server by clicking the cog in the bottom left corner.', | 33 | defaultMessage: '!!!Optionally, you can change your Ferdi server by clicking the cog in the bottom left corner. If you are switching over (from one of the hosted servers) to using Ferdi without an account, please be informed that you can export your data from that server and subsequently import it using the Help menu to resurrect all your workspaces and configured services!', |
34 | }, | 34 | }, |
35 | }); | 35 | }); |
36 | 36 | ||
@@ -54,7 +54,6 @@ export default @injectSheet(styles) @inject('actions') @observer class Services | |||
54 | openSettings: PropTypes.func.isRequired, | 54 | openSettings: PropTypes.func.isRequired, |
55 | update: PropTypes.func.isRequired, | 55 | update: PropTypes.func.isRequired, |
56 | userHasCompletedSignup: PropTypes.bool.isRequired, | 56 | userHasCompletedSignup: PropTypes.bool.isRequired, |
57 | hasActivatedTrial: PropTypes.bool.isRequired, | ||
58 | classes: PropTypes.object.isRequired, | 57 | classes: PropTypes.object.isRequired, |
59 | actions: PropTypes.object.isRequired, | 58 | actions: PropTypes.object.isRequired, |
60 | isSpellcheckerEnabled: PropTypes.bool.isRequired, | 59 | isSpellcheckerEnabled: PropTypes.bool.isRequired, |
@@ -109,7 +108,6 @@ export default @injectSheet(styles) @inject('actions') @observer class Services | |||
109 | openSettings, | 108 | openSettings, |
110 | update, | 109 | update, |
111 | userHasCompletedSignup, | 110 | userHasCompletedSignup, |
112 | hasActivatedTrial, | ||
113 | classes, | 111 | classes, |
114 | isSpellcheckerEnabled, | 112 | isSpellcheckerEnabled, |
115 | } = this.props; | 113 | } = this.props; |
@@ -123,7 +121,7 @@ export default @injectSheet(styles) @inject('actions') @observer class Services | |||
123 | 121 | ||
124 | return ( | 122 | return ( |
125 | <div className="services"> | 123 | <div className="services"> |
126 | {(userHasCompletedSignup || hasActivatedTrial) && ( | 124 | {userHasCompletedSignup && ( |
127 | <div className={classes.confettiContainer}> | 125 | <div className={classes.confettiContainer}> |
128 | <Confetti | 126 | <Confetti |
129 | width={window.width} | 127 | width={window.width} |
@@ -169,7 +167,7 @@ export default @injectSheet(styles) @inject('actions') @observer class Services | |||
169 | </div> | 167 | </div> |
170 | </Appear> | 168 | </Appear> |
171 | )} | 169 | )} |
172 | {services.filter(service => !service.isTodosService).map(service => ( | 170 | {services.filter((service) => !service.isTodosService).map((service) => ( |
173 | <ServiceView | 171 | <ServiceView |
174 | key={service.id} | 172 | key={service.id} |
175 | service={service} | 173 | service={service} |
@@ -186,7 +184,6 @@ export default @injectSheet(styles) @inject('actions') @observer class Services | |||
186 | }, | 184 | }, |
187 | redirect: false, | 185 | redirect: false, |
188 | })} | 186 | })} |
189 | upgrade={() => openSettings({ path: 'user' })} | ||
190 | isSpellcheckerEnabled={isSpellcheckerEnabled} | 187 | isSpellcheckerEnabled={isSpellcheckerEnabled} |
191 | /> | 188 | /> |
192 | ))} | 189 | ))} |
diff --git a/src/components/services/content/WebviewCrashHandler.js b/src/components/services/content/WebviewCrashHandler.js index b62940c06..10ff0bbbb 100644 --- a/src/components/services/content/WebviewCrashHandler.js +++ b/src/components/services/content/WebviewCrashHandler.js | |||
@@ -47,7 +47,7 @@ export default @observer class WebviewCrashHandler extends Component { | |||
47 | const { reload } = this.props; | 47 | const { reload } = this.props; |
48 | 48 | ||
49 | this.countdownInterval = setInterval(() => { | 49 | this.countdownInterval = setInterval(() => { |
50 | this.setState(prevState => ({ | 50 | this.setState((prevState) => ({ |
51 | countdown: prevState.countdown - this.countdownIntervalTimeout, | 51 | countdown: prevState.countdown - this.countdownIntervalTimeout, |
52 | })); | 52 | })); |
53 | 53 | ||