diff options
author | kytwb <412895+kytwb@users.noreply.github.com> | 2021-06-12 19:51:28 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-12 19:51:28 +0200 |
commit | b0ecce5eab2a6d0eed3ade7c43e252ca9bac7edb (patch) | |
tree | aed0253b61ca035f3388a7d6a369ffe75f195a58 /src/features/todos/components/TodosWebview.js | |
parent | Bypassed code signing since that is also incorrect in GH settings. (diff) | |
download | ferdium-app-b0ecce5eab2a6d0eed3ade7c43e252ca9bac7edb.tar.gz ferdium-app-b0ecce5eab2a6d0eed3ade7c43e252ca9bac7edb.tar.zst ferdium-app-b0ecce5eab2a6d0eed3ade7c43e252ca9bac7edb.zip |
Fix active Todos service behaviour (#1481)
* Return false instead of null in isTodosServiceAdded
* Resolve from TODOS_RECIPES_ID instead of hardcoded TODOS_RECIPE_ID
* Fix TodosWebview width toggling when isTodosServiceActive
* Add more todo service recipe IDs
* Refactor todos state management
* Moved todos service URL and recipe ID computation logic to todos/store
* Simplified TodosWebview by delegating to the store for the URL and
removing the (unused) payment logic
* Made the todos service computation logic in the Service model depend
on the logic in todos/store
* Made ServicesStore depend on the todos service logic from the Service
model
* Todos appearance fixes
* Hide double horizontal rules if todo settings are hidden due to an
added todo service
* Hide todos panel border when the panel is hidden or expanded
* Make expanded todos panel obey sidebar width and vertical style
settings
* Make todos/store use isValidExternalURL
* Harden isValidExternalURL against malformed URLs
* Reduce todo URL string duplication in config.js
Co-authored-by: Kristóf Marussy <kristof@marussy.com>
Diffstat (limited to 'src/features/todos/components/TodosWebview.js')
-rw-r--r-- | src/features/todos/components/TodosWebview.js | 96 |
1 files changed, 17 insertions, 79 deletions
diff --git a/src/features/todos/components/TodosWebview.js b/src/features/todos/components/TodosWebview.js index 634ec4caa..03bb5efe8 100644 --- a/src/features/todos/components/TodosWebview.js +++ b/src/features/todos/components/TodosWebview.js | |||
@@ -1,47 +1,12 @@ | |||
1 | import React, { Component } from 'react'; | 1 | import React, { Component } from 'react'; |
2 | import PropTypes from 'prop-types'; | 2 | import PropTypes from 'prop-types'; |
3 | import { observer, inject } from 'mobx-react'; | 3 | import { observer } from 'mobx-react'; |
4 | import injectSheet from 'react-jss'; | 4 | import injectSheet from 'react-jss'; |
5 | import Webview from 'react-electron-web-view'; | 5 | import Webview from 'react-electron-web-view'; |
6 | import { Icon } from '@meetfranz/ui'; | ||
7 | import { defineMessages, intlShape } from 'react-intl'; | ||
8 | import classnames from 'classnames'; | 6 | import classnames from 'classnames'; |
9 | 7 | ||
10 | import { mdiCheckAll } from '@mdi/js'; | ||
11 | import SettingsStore from '../../../stores/SettingsStore'; | ||
12 | |||
13 | import Appear from '../../../components/ui/effects/Appear'; | ||
14 | import UpgradeButton from '../../../components/ui/UpgradeButton'; | ||
15 | import { TODOS_PARTITION_ID } from '..'; | 8 | import { TODOS_PARTITION_ID } from '..'; |
16 | 9 | ||
17 | // NOTE: https://stackoverflow.com/questions/5717093/check-if-a-javascript-string-is-a-url | ||
18 | function validURL(str) { | ||
19 | let url; | ||
20 | |||
21 | try { | ||
22 | url = new URL(str); | ||
23 | } catch (_) { | ||
24 | return false; | ||
25 | } | ||
26 | |||
27 | return url.protocol === 'http:' || url.protocol === 'https:'; | ||
28 | } | ||
29 | |||
30 | const messages = defineMessages({ | ||
31 | premiumInfo: { | ||
32 | id: 'feature.todos.premium.info', | ||
33 | defaultMessage: '!!!Franz Todos are available to premium users now!', | ||
34 | }, | ||
35 | upgradeCTA: { | ||
36 | id: 'feature.todos.premium.upgrade', | ||
37 | defaultMessage: '!!!Upgrade Account', | ||
38 | }, | ||
39 | rolloutInfo: { | ||
40 | id: 'feature.todos.premium.rollout', | ||
41 | defaultMessage: '!!!Everyone else will have to wait a little longer.', | ||
42 | }, | ||
43 | }); | ||
44 | |||
45 | const styles = theme => ({ | 10 | const styles = theme => ({ |
46 | root: { | 11 | root: { |
47 | background: theme.colorBackground, | 12 | background: theme.colorBackground, |
@@ -96,10 +61,14 @@ const styles = theme => ({ | |||
96 | position: 'absolute', | 61 | position: 'absolute', |
97 | right: 0, | 62 | right: 0, |
98 | zIndex: 0, | 63 | zIndex: 0, |
64 | borderLeftWidth: 0, | ||
65 | }, | ||
66 | hidden: { | ||
67 | borderLeftWidth: 0, | ||
99 | }, | 68 | }, |
100 | }); | 69 | }); |
101 | 70 | ||
102 | @injectSheet(styles) @inject('stores') @observer | 71 | @injectSheet(styles) @observer |
103 | class TodosWebview extends Component { | 72 | class TodosWebview extends Component { |
104 | static propTypes = { | 73 | static propTypes = { |
105 | classes: PropTypes.object.isRequired, | 74 | classes: PropTypes.object.isRequired, |
@@ -111,10 +80,8 @@ class TodosWebview extends Component { | |||
111 | width: PropTypes.number.isRequired, | 80 | width: PropTypes.number.isRequired, |
112 | minWidth: PropTypes.number.isRequired, | 81 | minWidth: PropTypes.number.isRequired, |
113 | userAgent: PropTypes.string.isRequired, | 82 | userAgent: PropTypes.string.isRequired, |
114 | isTodosIncludedInCurrentPlan: PropTypes.bool.isRequired, | 83 | todoUrl: PropTypes.string.isRequired, |
115 | stores: PropTypes.shape({ | 84 | isTodoUrlValid: PropTypes.bool.isRequired, |
116 | settings: PropTypes.instanceOf(SettingsStore).isRequired, | ||
117 | }).isRequired, | ||
118 | }; | 85 | }; |
119 | 86 | ||
120 | state = { | 87 | state = { |
@@ -122,10 +89,6 @@ class TodosWebview extends Component { | |||
122 | width: 300, | 89 | width: 300, |
123 | }; | 90 | }; |
124 | 91 | ||
125 | static contextTypes = { | ||
126 | intl: intlShape, | ||
127 | }; | ||
128 | |||
129 | componentWillMount() { | 92 | componentWillMount() { |
130 | const { width } = this.props; | 93 | const { width } = this.props; |
131 | 94 | ||
@@ -209,8 +172,8 @@ class TodosWebview extends Component { | |||
209 | isTodosServiceActive, | 172 | isTodosServiceActive, |
210 | isVisible, | 173 | isVisible, |
211 | userAgent, | 174 | userAgent, |
212 | isTodosIncludedInCurrentPlan, | 175 | todoUrl, |
213 | stores, | 176 | isTodoUrlValid, |
214 | } = this.props; | 177 | } = this.props; |
215 | 178 | ||
216 | const { | 179 | const { |
@@ -219,29 +182,20 @@ class TodosWebview extends Component { | |||
219 | isDragging, | 182 | isDragging, |
220 | } = this.state; | 183 | } = this.state; |
221 | 184 | ||
222 | const { intl } = this.context; | 185 | let displayedWidth = isVisible ? width : 0; |
223 | 186 | if (isTodosServiceActive) { | |
224 | const isUsingPredefinedTodoServer = stores.settings.all.app.predefinedTodoServer !== 'isUsingCustomTodoService'; | 187 | displayedWidth = null; |
225 | const todoUrl = isUsingPredefinedTodoServer | ||
226 | ? stores.settings.all.app.predefinedTodoServer | ||
227 | : stores.settings.all.app.customTodoServer; | ||
228 | let isTodoUrlValid = true; | ||
229 | if (isUsingPredefinedTodoServer === false) { | ||
230 | isTodoUrlValid = validURL(todoUrl); | ||
231 | } | 188 | } |
232 | 189 | ||
233 | const todosPanelStyle = { | ||
234 | width: isVisible ? width : 0, | ||
235 | borderLeftWidth: isVisible ? '1px' : 0, | ||
236 | }; | ||
237 | |||
238 | return ( | 190 | return ( |
239 | <div | 191 | <div |
240 | className={classnames({ | 192 | className={classnames({ |
241 | [classes.root]: true, | 193 | [classes.root]: true, |
242 | [classes.isTodosServiceActive]: isTodosServiceActive, | 194 | [classes.isTodosServiceActive]: isTodosServiceActive, |
195 | 'todos__todos-panel--expanded': isTodosServiceActive, | ||
196 | [classes.hidden]: !isVisible, | ||
243 | })} | 197 | })} |
244 | style={todosPanelStyle} | 198 | style={{ width: displayedWidth }} |
245 | onMouseUp={() => this.stopResize()} | 199 | onMouseUp={() => this.stopResize()} |
246 | ref={(node) => { this.node = node; }} | 200 | ref={(node) => { this.node = node; }} |
247 | id="todos-panel" | 201 | id="todos-panel" |
@@ -257,9 +211,7 @@ class TodosWebview extends Component { | |||
257 | style={{ left: delta }} // This hack is required as resizing with webviews beneath behaves quite bad | 211 | style={{ left: delta }} // This hack is required as resizing with webviews beneath behaves quite bad |
258 | /> | 212 | /> |
259 | )} | 213 | )} |
260 | {isTodosIncludedInCurrentPlan ? ( | 214 | {isTodoUrlValid && ( |
261 | isTodoUrlValid | ||
262 | && ( | ||
263 | <Webview | 215 | <Webview |
264 | className={classes.webview} | 216 | className={classes.webview} |
265 | onDidAttach={() => { | 217 | onDidAttach={() => { |
@@ -273,20 +225,6 @@ class TodosWebview extends Component { | |||
273 | useragent={userAgent} | 225 | useragent={userAgent} |
274 | src={todoUrl} | 226 | src={todoUrl} |
275 | /> | 227 | /> |
276 | ) | ||
277 | ) : ( | ||
278 | <Appear> | ||
279 | <div className={classes.premiumContainer}> | ||
280 | <Icon icon={mdiCheckAll} className={classes.premiumIcon} size={4} /> | ||
281 | <p>{intl.formatMessage(messages.premiumInfo)}</p> | ||
282 | <p>{intl.formatMessage(messages.rolloutInfo)}</p> | ||
283 | <UpgradeButton | ||
284 | className={classes.premiumCTA} | ||
285 | gaEventInfo={{ category: 'Todos', event: 'upgrade' }} | ||
286 | short | ||
287 | /> | ||
288 | </div> | ||
289 | </Appear> | ||
290 | )} | 228 | )} |
291 | </div> | 229 | </div> |
292 | ); | 230 | ); |