diff options
Diffstat (limited to 'src/components/settings/services')
-rw-r--r-- | src/components/settings/services/EditServiceForm.js | 173 | ||||
-rw-r--r-- | src/components/settings/services/ServiceError.js | 26 | ||||
-rw-r--r-- | src/components/settings/services/ServiceItem.js | 48 | ||||
-rw-r--r-- | src/components/settings/services/ServicesDashboard.js | 56 |
4 files changed, 157 insertions, 146 deletions
diff --git a/src/components/settings/services/EditServiceForm.js b/src/components/settings/services/EditServiceForm.js index c41cdd56a..22089ec45 100644 --- a/src/components/settings/services/EditServiceForm.js +++ b/src/components/settings/services/EditServiceForm.js | |||
@@ -2,13 +2,14 @@ import React, { Component } from 'react'; | |||
2 | import PropTypes from 'prop-types'; | 2 | import PropTypes from 'prop-types'; |
3 | import { observer } from 'mobx-react'; | 3 | import { observer } from 'mobx-react'; |
4 | import { Link } from 'react-router'; | 4 | import { Link } from 'react-router'; |
5 | import { defineMessages, intlShape } from 'react-intl'; | 5 | import { defineMessages, injectIntl } from 'react-intl'; |
6 | import normalizeUrl from 'normalize-url'; | 6 | import normalizeUrl from 'normalize-url'; |
7 | 7 | ||
8 | import Form from '../../../lib/Form'; | 8 | import Form from '../../../lib/Form'; |
9 | import Recipe from '../../../models/Recipe'; | 9 | import Recipe from '../../../models/Recipe'; |
10 | import Service from '../../../models/Service'; | 10 | import Service from '../../../models/Service'; |
11 | import Tabs, { TabItem } from '../../ui/Tabs'; | 11 | import Tabs from '../../ui/Tabs/Tabs'; |
12 | import { TabItem } from '../../ui/Tabs/TabItem'; | ||
12 | import Input from '../../ui/Input'; | 13 | import Input from '../../ui/Input'; |
13 | import Toggle from '../../ui/Toggle'; | 14 | import Toggle from '../../ui/Toggle'; |
14 | import Slider from '../../ui/Slider'; | 15 | import Slider from '../../ui/Slider'; |
@@ -22,111 +23,117 @@ import globalMessages from '../../../i18n/globalMessages'; | |||
22 | const messages = defineMessages({ | 23 | const messages = defineMessages({ |
23 | saveService: { | 24 | saveService: { |
24 | id: 'settings.service.form.saveButton', | 25 | id: 'settings.service.form.saveButton', |
25 | defaultMessage: '!!!Save service', | 26 | defaultMessage: 'Save service', |
26 | }, | 27 | }, |
27 | deleteService: { | 28 | deleteService: { |
28 | id: 'settings.service.form.deleteButton', | 29 | id: 'settings.service.form.deleteButton', |
29 | defaultMessage: '!!!Delete Service', | 30 | defaultMessage: 'Delete service', |
30 | }, | 31 | }, |
31 | openDarkmodeCss: { | 32 | openDarkmodeCss: { |
32 | id: 'settings.service.form.openDarkmodeCss', | 33 | id: 'settings.service.form.openDarkmodeCss', |
33 | defaultMessage: '!!!Open darkmode.css', | 34 | defaultMessage: 'Open darkmode.css', |
34 | }, | 35 | }, |
35 | openUserCss: { | 36 | openUserCss: { |
36 | id: 'settings.service.form.openUserCss', | 37 | id: 'settings.service.form.openUserCss', |
37 | defaultMessage: '!!!Open user.css', | 38 | defaultMessage: 'Open user.css', |
38 | }, | 39 | }, |
39 | openUserJs: { | 40 | openUserJs: { |
40 | id: 'settings.service.form.openUserJs', | 41 | id: 'settings.service.form.openUserJs', |
41 | defaultMessage: '!!!Open user.js', | 42 | defaultMessage: 'Open user.js', |
42 | }, | 43 | }, |
43 | recipeFileInfo: { | 44 | recipeFileInfo: { |
44 | id: 'settings.service.form.recipeFileInfo', | 45 | id: 'settings.service.form.recipeFileInfo', |
45 | defaultMessage: '!!!Your user files will be inserted into the webpage so you can customize services in any way you like. User files are only stored locally and are not transferred to other computers using the same account.', | 46 | defaultMessage: |
47 | 'Your user files will be inserted into the webpage so you can customize services in any way you like. User files are only stored locally and are not transferred to other computers using the same account.', | ||
46 | }, | 48 | }, |
47 | availableServices: { | 49 | availableServices: { |
48 | id: 'settings.service.form.availableServices', | 50 | id: 'settings.service.form.availableServices', |
49 | defaultMessage: '!!!Available services', | 51 | defaultMessage: 'Available services', |
50 | }, | 52 | }, |
51 | yourServices: { | 53 | yourServices: { |
52 | id: 'settings.service.form.yourServices', | 54 | id: 'settings.service.form.yourServices', |
53 | defaultMessage: '!!!Your services', | 55 | defaultMessage: 'Your services', |
54 | }, | 56 | }, |
55 | addServiceHeadline: { | 57 | addServiceHeadline: { |
56 | id: 'settings.service.form.addServiceHeadline', | 58 | id: 'settings.service.form.addServiceHeadline', |
57 | defaultMessage: '!!!Add {name}', | 59 | defaultMessage: 'Add {name}', |
58 | }, | 60 | }, |
59 | editServiceHeadline: { | 61 | editServiceHeadline: { |
60 | id: 'settings.service.form.editServiceHeadline', | 62 | id: 'settings.service.form.editServiceHeadline', |
61 | defaultMessage: '!!!Edit {name}', | 63 | defaultMessage: 'Edit {name}', |
62 | }, | 64 | }, |
63 | tabHosted: { | 65 | tabHosted: { |
64 | id: 'settings.service.form.tabHosted', | 66 | id: 'settings.service.form.tabHosted', |
65 | defaultMessage: '!!!Hosted', | 67 | defaultMessage: 'Hosted', |
66 | }, | 68 | }, |
67 | tabOnPremise: { | 69 | tabOnPremise: { |
68 | id: 'settings.service.form.tabOnPremise', | 70 | id: 'settings.service.form.tabOnPremise', |
69 | defaultMessage: '!!!Self hosted ⭐️', | 71 | defaultMessage: 'Self hosted ⭐️', |
70 | }, | 72 | }, |
71 | useHostedService: { | 73 | useHostedService: { |
72 | id: 'settings.service.form.useHostedService', | 74 | id: 'settings.service.form.useHostedService', |
73 | defaultMessage: '!!!Use the hosted {name} service.', | 75 | defaultMessage: 'Use the hosted {name} service.', |
74 | }, | 76 | }, |
75 | customUrlValidationError: { | 77 | customUrlValidationError: { |
76 | id: 'settings.service.form.customUrlValidationError', | 78 | id: 'settings.service.form.customUrlValidationError', |
77 | defaultMessage: '!!!Could not validate custom {name} server.', | 79 | defaultMessage: 'Could not validate custom {name} server.', |
78 | }, | 80 | }, |
79 | indirectMessageInfo: { | 81 | indirectMessageInfo: { |
80 | id: 'settings.service.form.indirectMessageInfo', | 82 | id: 'settings.service.form.indirectMessageInfo', |
81 | defaultMessage: '!!!You will be notified about all new messages in a channel, not just @username, @channel, @here, ...', | 83 | defaultMessage: |
84 | 'You will be notified about all new messages in a channel, not just @username, @channel, @here, ...', | ||
82 | }, | 85 | }, |
83 | isMutedInfo: { | 86 | isMutedInfo: { |
84 | id: 'settings.service.form.isMutedInfo', | 87 | id: 'settings.service.form.isMutedInfo', |
85 | defaultMessage: '!!!When disabled, all notification sounds and audio playback are muted', | 88 | defaultMessage: |
89 | 'When disabled, all notification sounds and audio playback are muted', | ||
86 | }, | 90 | }, |
87 | isHibernationEnabledInfo: { | 91 | isHibernationEnabledInfo: { |
88 | id: 'settings.service.form.isHibernatedEnabledInfo', | 92 | id: 'settings.service.form.isHibernatedEnabledInfo', |
89 | defaultMessage: '!!!When enabled, a service will be shut down after a period of time to save system resources.', | 93 | defaultMessage: |
94 | 'When enabled, a service will be shut down after a period of time to save system resources.', | ||
90 | }, | 95 | }, |
91 | headlineNotifications: { | 96 | headlineNotifications: { |
92 | id: 'settings.service.form.headlineNotifications', | 97 | id: 'settings.service.form.headlineNotifications', |
93 | defaultMessage: '!!!Notifications', | 98 | defaultMessage: 'Notifications', |
94 | }, | 99 | }, |
95 | headlineBadges: { | 100 | headlineBadges: { |
96 | id: 'settings.service.form.headlineBadges', | 101 | id: 'settings.service.form.headlineBadges', |
97 | defaultMessage: '!!!Unread message badges', | 102 | defaultMessage: 'Unread message badges', |
98 | }, | 103 | }, |
99 | headlineGeneral: { | 104 | headlineGeneral: { |
100 | id: 'settings.service.form.headlineGeneral', | 105 | id: 'settings.service.form.headlineGeneral', |
101 | defaultMessage: '!!!General', | 106 | defaultMessage: 'General', |
102 | }, | 107 | }, |
103 | headlineDarkReaderSettings: { | 108 | headlineDarkReaderSettings: { |
104 | id: 'settings.service.form.headlineDarkReaderSettings', | 109 | id: 'settings.service.form.headlineDarkReaderSettings', |
105 | defaultMessage: '!!!Dark Reader Settings', | 110 | defaultMessage: 'Dark Reader Settings', |
106 | }, | 111 | }, |
107 | iconDelete: { | 112 | iconDelete: { |
108 | id: 'settings.service.form.iconDelete', | 113 | id: 'settings.service.form.iconDelete', |
109 | defaultMessage: '!!!Delete', | 114 | defaultMessage: 'Delete', |
110 | }, | 115 | }, |
111 | iconUpload: { | 116 | iconUpload: { |
112 | id: 'settings.service.form.iconUpload', | 117 | id: 'settings.service.form.iconUpload', |
113 | defaultMessage: '!!!Drop your image, or click here', | 118 | defaultMessage: 'Drop your image, or click here', |
114 | }, | 119 | }, |
115 | headlineProxy: { | 120 | headlineProxy: { |
116 | id: 'settings.service.form.proxy.headline', | 121 | id: 'settings.service.form.proxy.headline', |
117 | defaultMessage: '!!!HTTP/HTTPS Proxy Settings', | 122 | defaultMessage: 'HTTP/HTTPS Proxy Settings', |
118 | }, | 123 | }, |
119 | proxyRestartInfo: { | 124 | proxyRestartInfo: { |
120 | id: 'settings.service.form.proxy.restartInfo', | 125 | id: 'settings.service.form.proxy.restartInfo', |
121 | defaultMessage: '!!!Please restart Ferdi after changing proxy Settings.', | 126 | defaultMessage: 'Please restart Ferdi after changing proxy Settings.', |
122 | }, | 127 | }, |
123 | proxyInfo: { | 128 | proxyInfo: { |
124 | id: 'settings.service.form.proxy.info', | 129 | id: 'settings.service.form.proxy.info', |
125 | defaultMessage: '!!!Proxy settings will not be synchronized with the Ferdi servers.', | 130 | defaultMessage: |
131 | 'Proxy settings will not be synchronized with the Ferdi servers.', | ||
126 | }, | 132 | }, |
127 | }); | 133 | }); |
128 | 134 | ||
129 | export default @observer class EditServiceForm extends Component { | 135 | @observer |
136 | class EditServiceForm extends Component { | ||
130 | static propTypes = { | 137 | static propTypes = { |
131 | recipe: PropTypes.instanceOf(Recipe).isRequired, | 138 | recipe: PropTypes.instanceOf(Recipe).isRequired, |
132 | service(props, propName) { | 139 | service(props, propName) { |
@@ -151,20 +158,16 @@ export default @observer class EditServiceForm extends Component { | |||
151 | service: {}, | 158 | service: {}, |
152 | }; | 159 | }; |
153 | 160 | ||
154 | static contextTypes = { | ||
155 | intl: intlShape, | ||
156 | }; | ||
157 | |||
158 | state = { | 161 | state = { |
159 | isValidatingCustomUrl: false, | 162 | isValidatingCustomUrl: false, |
160 | } | 163 | }; |
161 | 164 | ||
162 | submit(e) { | 165 | submit(e) { |
163 | const { recipe } = this.props; | 166 | const { recipe } = this.props; |
164 | 167 | ||
165 | e.preventDefault(); | 168 | e.preventDefault(); |
166 | this.props.form.submit({ | 169 | this.props.form.submit({ |
167 | onSuccess: async (form) => { | 170 | onSuccess: async form => { |
168 | const values = form.values(); | 171 | const values = form.values(); |
169 | let isValid = true; | 172 | let isValid = true; |
170 | 173 | ||
@@ -176,10 +179,13 @@ export default @observer class EditServiceForm extends Component { | |||
176 | if (recipe.validateUrl && values.customUrl) { | 179 | if (recipe.validateUrl && values.customUrl) { |
177 | this.setState({ isValidatingCustomUrl: true }); | 180 | this.setState({ isValidatingCustomUrl: true }); |
178 | try { | 181 | try { |
179 | values.customUrl = normalizeUrl(values.customUrl, { stripWWW: false, removeTrailingSlash: false }); | 182 | values.customUrl = normalizeUrl(values.customUrl, { |
183 | stripWWW: false, | ||
184 | removeTrailingSlash: false, | ||
185 | }); | ||
180 | isValid = await recipe.validateUrl(values.customUrl); | 186 | isValid = await recipe.validateUrl(values.customUrl); |
181 | } catch (err) { | 187 | } catch (error) { |
182 | console.warn('ValidateURL', err); | 188 | console.warn('ValidateURL', error); |
183 | isValid = false; | 189 | isValid = false; |
184 | } | 190 | } |
185 | } | 191 | } |
@@ -208,7 +214,7 @@ export default @observer class EditServiceForm extends Component { | |||
208 | openRecipeFile, | 214 | openRecipeFile, |
209 | isProxyFeatureEnabled, | 215 | isProxyFeatureEnabled, |
210 | } = this.props; | 216 | } = this.props; |
211 | const { intl } = this.context; | 217 | const { intl } = this.props; |
212 | 218 | ||
213 | const { isValidatingCustomUrl } = this.state; | 219 | const { isValidatingCustomUrl } = this.state; |
214 | 220 | ||
@@ -236,7 +242,8 @@ export default @observer class EditServiceForm extends Component { | |||
236 | activeTabIndex = 2; | 242 | activeTabIndex = 2; |
237 | } | 243 | } |
238 | 244 | ||
239 | const requiresUserInput = !recipe.hasHostedOption && (recipe.hasTeamId || recipe.hasCustomUrl); | 245 | const requiresUserInput = |
246 | !recipe.hasHostedOption && (recipe.hasTeamId || recipe.hasCustomUrl); | ||
240 | 247 | ||
241 | return ( | 248 | return ( |
242 | <div className="settings__main"> | 249 | <div className="settings__main"> |
@@ -254,29 +261,27 @@ export default @observer class EditServiceForm extends Component { | |||
254 | </span> | 261 | </span> |
255 | <span className="separator" /> | 262 | <span className="separator" /> |
256 | <span className="settings__header-item"> | 263 | <span className="settings__header-item"> |
257 | {action === 'add' ? ( | 264 | {action === 'add' |
258 | intl.formatMessage(messages.addServiceHeadline, { | 265 | ? intl.formatMessage(messages.addServiceHeadline, { |
259 | name: recipe.name, | 266 | name: recipe.name, |
260 | }) | 267 | }) |
261 | ) : ( | 268 | : intl.formatMessage(messages.editServiceHeadline, { |
262 | intl.formatMessage(messages.editServiceHeadline, { | 269 | name: service.name !== '' ? service.name : recipe.name, |
263 | name: service.name !== '' ? service.name : recipe.name, | 270 | })} |
264 | }) | ||
265 | )} | ||
266 | </span> | 271 | </span> |
267 | </div> | 272 | </div> |
268 | <div className="settings__body"> | 273 | <div className="settings__body"> |
269 | <form onSubmit={(e) => this.submit(e)} id="form"> | 274 | <form onSubmit={e => this.submit(e)} id="form"> |
270 | <div className="service-name"> | 275 | <div className="service-name"> |
271 | <Input field={form.$('name')} focus /> | 276 | <Input field={form.$('name')} focus /> |
272 | </div> | 277 | </div> |
273 | {(recipe.hasTeamId || recipe.hasCustomUrl) && ( | 278 | {(recipe.hasTeamId || recipe.hasCustomUrl) && ( |
274 | <Tabs | 279 | <Tabs active={activeTabIndex}> |
275 | active={activeTabIndex} | ||
276 | > | ||
277 | {recipe.hasHostedOption && ( | 280 | {recipe.hasHostedOption && ( |
278 | <TabItem title={recipe.name}> | 281 | <TabItem title={recipe.name}> |
279 | {intl.formatMessage(messages.useHostedService, { name: recipe.name })} | 282 | {intl.formatMessage(messages.useHostedService, { |
283 | name: recipe.name, | ||
284 | })} | ||
280 | </TabItem> | 285 | </TabItem> |
281 | )} | 286 | )} |
282 | {recipe.hasTeamId && ( | 287 | {recipe.hasTeamId && ( |
@@ -293,7 +298,9 @@ export default @observer class EditServiceForm extends Component { | |||
293 | <Input field={form.$('customUrl')} /> | 298 | <Input field={form.$('customUrl')} /> |
294 | {form.error === 'url-validation-error' && ( | 299 | {form.error === 'url-validation-error' && ( |
295 | <p className="franz-form__error"> | 300 | <p className="franz-form__error"> |
296 | {intl.formatMessage(messages.customUrlValidationError, { name: recipe.name })} | 301 | {intl.formatMessage(messages.customUrlValidationError, { |
302 | name: recipe.name, | ||
303 | })} | ||
297 | </p> | 304 | </p> |
298 | )} | 305 | )} |
299 | </TabItem> | 306 | </TabItem> |
@@ -326,13 +333,19 @@ export default @observer class EditServiceForm extends Component { | |||
326 | <div className="settings__settings-group"> | 333 | <div className="settings__settings-group"> |
327 | <h3>{intl.formatMessage(messages.headlineBadges)}</h3> | 334 | <h3>{intl.formatMessage(messages.headlineBadges)}</h3> |
328 | <Toggle field={form.$('isBadgeEnabled')} /> | 335 | <Toggle field={form.$('isBadgeEnabled')} /> |
329 | {recipe.hasIndirectMessages && form.$('isBadgeEnabled').value && ( | 336 | {recipe.hasIndirectMessages && |
330 | <> | 337 | form.$('isBadgeEnabled').value && ( |
331 | <Toggle field={form.$('isIndirectMessageBadgeEnabled')} /> | 338 | <> |
332 | <p className="settings__help indented__help"> | 339 | <Toggle |
333 | {intl.formatMessage(messages.indirectMessageInfo)} | 340 | field={form.$('isIndirectMessageBadgeEnabled')} |
334 | </p> | 341 | /> |
335 | </> | 342 | <p className="settings__help indented__help"> |
343 | {intl.formatMessage(messages.indirectMessageInfo)} | ||
344 | </p> | ||
345 | </> | ||
346 | )} | ||
347 | {recipe.allowFavoritesDelineationInUnreadCount && ( | ||
348 | <Toggle field={form.$('onlyShowFavoritesInUnreadCount')} /> | ||
336 | )} | 349 | )} |
337 | </div> | 350 | </div> |
338 | 351 | ||
@@ -344,15 +357,18 @@ export default @observer class EditServiceForm extends Component { | |||
344 | {intl.formatMessage(messages.isHibernationEnabledInfo)} | 357 | {intl.formatMessage(messages.isHibernationEnabledInfo)} |
345 | </p> | 358 | </p> |
346 | <Toggle field={form.$('isDarkModeEnabled')} /> | 359 | <Toggle field={form.$('isDarkModeEnabled')} /> |
347 | {form.$('isDarkModeEnabled').value | 360 | {form.$('isDarkModeEnabled').value && ( |
348 | && ( | 361 | <> |
349 | <> | 362 | <h3> |
350 | <h3>{intl.formatMessage(messages.headlineDarkReaderSettings)}</h3> | 363 | {intl.formatMessage( |
351 | <Slider field={form.$('darkReaderBrightness')} /> | 364 | messages.headlineDarkReaderSettings, |
352 | <Slider field={form.$('darkReaderContrast')} /> | 365 | )} |
353 | <Slider field={form.$('darkReaderSepia')} /> | 366 | </h3> |
354 | </> | 367 | <Slider field={form.$('darkReaderBrightness')} /> |
355 | )} | 368 | <Slider field={form.$('darkReaderContrast')} /> |
369 | <Slider field={form.$('darkReaderSepia')} /> | ||
370 | </> | ||
371 | )} | ||
356 | </div> | 372 | </div> |
357 | </div> | 373 | </div> |
358 | <div className="service-icon"> | 374 | <div className="service-icon"> |
@@ -381,7 +397,10 @@ export default @observer class EditServiceForm extends Component { | |||
381 | <> | 397 | <> |
382 | <div className="grid"> | 398 | <div className="grid"> |
383 | <div className="grid__row"> | 399 | <div className="grid__row"> |
384 | <Input field={form.$('proxy.host')} className="proxyHost" /> | 400 | <Input |
401 | field={form.$('proxy.host')} | ||
402 | className="proxyHost" | ||
403 | /> | ||
385 | <Input field={form.$('proxy.port')} /> | 404 | <Input field={form.$('proxy.port')} /> |
386 | </div> | 405 | </div> |
387 | </div> | 406 | </div> |
@@ -409,7 +428,9 @@ export default @observer class EditServiceForm extends Component { | |||
409 | 428 | ||
410 | <div className="user-agent"> | 429 | <div className="user-agent"> |
411 | <Input field={form.$('userAgentPref')} /> | 430 | <Input field={form.$('userAgentPref')} /> |
412 | <p className="settings__help">{intl.formatMessage(globalMessages.userAgentHelp)}</p> | 431 | <p className="settings__help"> |
432 | {intl.formatMessage(globalMessages.userAgentHelp)} | ||
433 | </p> | ||
413 | </div> | 434 | </div> |
414 | </form> | 435 | </form> |
415 | 436 | ||
@@ -464,7 +485,9 @@ export default @observer class EditServiceForm extends Component { | |||
464 | type="submit" | 485 | type="submit" |
465 | label={intl.formatMessage(messages.saveService)} | 486 | label={intl.formatMessage(messages.saveService)} |
466 | htmlForm="form" | 487 | htmlForm="form" |
467 | disabled={action !== 'edit' && (form.isPristine && requiresUserInput)} | 488 | disabled={ |
489 | action !== 'edit' && form.isPristine && requiresUserInput | ||
490 | } | ||
468 | /> | 491 | /> |
469 | )} | 492 | )} |
470 | </div> | 493 | </div> |
@@ -472,3 +495,5 @@ export default @observer class EditServiceForm extends Component { | |||
472 | ); | 495 | ); |
473 | } | 496 | } |
474 | } | 497 | } |
498 | |||
499 | export default injectIntl(EditServiceForm); | ||
diff --git a/src/components/settings/services/ServiceError.js b/src/components/settings/services/ServiceError.js index 3cfc080d6..d16d76db2 100644 --- a/src/components/settings/services/ServiceError.js +++ b/src/components/settings/services/ServiceError.js | |||
@@ -1,7 +1,7 @@ | |||
1 | import React, { Component } from 'react'; | 1 | import React, { Component } from 'react'; |
2 | import { observer } from 'mobx-react'; | 2 | import { observer } from 'mobx-react'; |
3 | import { Link } from 'react-router'; | 3 | import { Link } from 'react-router'; |
4 | import { defineMessages, intlShape } from 'react-intl'; | 4 | import { defineMessages, injectIntl } from 'react-intl'; |
5 | 5 | ||
6 | import Infobox from '../../ui/Infobox'; | 6 | import Infobox from '../../ui/Infobox'; |
7 | import Button from '../../ui/Button'; | 7 | import Button from '../../ui/Button'; |
@@ -9,29 +9,26 @@ import Button from '../../ui/Button'; | |||
9 | const messages = defineMessages({ | 9 | const messages = defineMessages({ |
10 | headline: { | 10 | headline: { |
11 | id: 'settings.service.error.headline', | 11 | id: 'settings.service.error.headline', |
12 | defaultMessage: '!!!Error', | 12 | defaultMessage: 'Error', |
13 | }, | 13 | }, |
14 | goBack: { | 14 | goBack: { |
15 | id: 'settings.service.error.goBack', | 15 | id: 'settings.service.error.goBack', |
16 | defaultMessage: '!!!Back to services', | 16 | defaultMessage: 'Back to services', |
17 | }, | 17 | }, |
18 | availableServices: { | 18 | availableServices: { |
19 | id: 'settings.service.form.availableServices', | 19 | id: 'settings.service.form.availableServices', |
20 | defaultMessage: '!!!Available services', | 20 | defaultMessage: 'Available services', |
21 | }, | 21 | }, |
22 | errorMessage: { | 22 | errorMessage: { |
23 | id: 'settings.service.error.message', | 23 | id: 'settings.service.error.message', |
24 | defaultMessage: '!!!Could not load service recipe.', | 24 | defaultMessage: 'Could not load service recipe.', |
25 | }, | 25 | }, |
26 | }); | 26 | }); |
27 | 27 | ||
28 | export default @observer class ServiceError extends Component { | 28 | @observer |
29 | static contextTypes = { | 29 | class ServiceError extends Component { |
30 | intl: intlShape, | ||
31 | }; | ||
32 | |||
33 | render() { | 30 | render() { |
34 | const { intl } = this.context; | 31 | const { intl } = this.props; |
35 | 32 | ||
36 | return ( | 33 | return ( |
37 | <div className="settings__main"> | 34 | <div className="settings__main"> |
@@ -47,10 +44,7 @@ export default @observer class ServiceError extends Component { | |||
47 | </span> | 44 | </span> |
48 | </div> | 45 | </div> |
49 | <div className="settings__body"> | 46 | <div className="settings__body"> |
50 | <Infobox | 47 | <Infobox type="danger" icon="alert"> |
51 | type="danger" | ||
52 | icon="alert" | ||
53 | > | ||
54 | {intl.formatMessage(messages.errorMessage)} | 48 | {intl.formatMessage(messages.errorMessage)} |
55 | </Infobox> | 49 | </Infobox> |
56 | </div> | 50 | </div> |
@@ -65,3 +59,5 @@ export default @observer class ServiceError extends Component { | |||
65 | ); | 59 | ); |
66 | } | 60 | } |
67 | } | 61 | } |
62 | |||
63 | export default injectIntl(ServiceError); | ||
diff --git a/src/components/settings/services/ServiceItem.js b/src/components/settings/services/ServiceItem.js index ebc618a00..4916e4ecc 100644 --- a/src/components/settings/services/ServiceItem.js +++ b/src/components/settings/services/ServiceItem.js | |||
@@ -1,6 +1,6 @@ | |||
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 { defineMessages, intlShape } from 'react-intl'; | 3 | import { defineMessages, injectIntl } from 'react-intl'; |
4 | import ReactTooltip from 'react-tooltip'; | 4 | import ReactTooltip from 'react-tooltip'; |
5 | import { observer } from 'mobx-react'; | 5 | import { observer } from 'mobx-react'; |
6 | import classnames from 'classnames'; | 6 | import classnames from 'classnames'; |
@@ -10,35 +10,32 @@ import ServiceModel from '../../../models/Service'; | |||
10 | const messages = defineMessages({ | 10 | const messages = defineMessages({ |
11 | tooltipIsDisabled: { | 11 | tooltipIsDisabled: { |
12 | id: 'settings.services.tooltip.isDisabled', | 12 | id: 'settings.services.tooltip.isDisabled', |
13 | defaultMessage: '!!!Service is disabled', | 13 | defaultMessage: 'Service is disabled', |
14 | }, | 14 | }, |
15 | tooltipNotificationsDisabled: { | 15 | tooltipNotificationsDisabled: { |
16 | id: 'settings.services.tooltip.notificationsDisabled', | 16 | id: 'settings.services.tooltip.notificationsDisabled', |
17 | defaultMessage: '!!!Notifications are disabled', | 17 | defaultMessage: 'Notifications are disabled', |
18 | }, | 18 | }, |
19 | tooltipIsMuted: { | 19 | tooltipIsMuted: { |
20 | id: 'settings.services.tooltip.isMuted', | 20 | id: 'settings.services.tooltip.isMuted', |
21 | defaultMessage: '!!!All sounds are muted', | 21 | defaultMessage: 'All sounds are muted', |
22 | }, | 22 | }, |
23 | }); | 23 | }); |
24 | 24 | ||
25 | export default @observer class ServiceItem extends Component { | 25 | @observer |
26 | class ServiceItem extends Component { | ||
26 | static propTypes = { | 27 | static propTypes = { |
27 | service: PropTypes.instanceOf(ServiceModel).isRequired, | 28 | service: PropTypes.instanceOf(ServiceModel).isRequired, |
28 | goToServiceForm: PropTypes.func.isRequired, | 29 | goToServiceForm: PropTypes.func.isRequired, |
29 | }; | 30 | }; |
30 | 31 | ||
31 | static contextTypes = { | ||
32 | intl: intlShape, | ||
33 | }; | ||
34 | |||
35 | render() { | 32 | render() { |
36 | const { | 33 | const { |
37 | service, | 34 | service, |
38 | // toggleAction, | 35 | // toggleAction, |
39 | goToServiceForm, | 36 | goToServiceForm, |
40 | } = this.props; | 37 | } = this.props; |
41 | const { intl } = this.context; | 38 | const { intl } = this.props; |
42 | 39 | ||
43 | return ( | 40 | return ( |
44 | <tr | 41 | <tr |
@@ -47,10 +44,7 @@ export default @observer class ServiceItem extends Component { | |||
47 | 'service-table__row--disabled': !service.isEnabled, | 44 | 'service-table__row--disabled': !service.isEnabled, |
48 | })} | 45 | })} |
49 | > | 46 | > |
50 | <td | 47 | <td className="service-table__column-icon" onClick={goToServiceForm}> |
51 | className="service-table__column-icon" | ||
52 | onClick={goToServiceForm} | ||
53 | > | ||
54 | <img | 48 | <img |
55 | src={service.icon} | 49 | src={service.icon} |
56 | className={classnames({ | 50 | className={classnames({ |
@@ -60,16 +54,10 @@ export default @observer class ServiceItem extends Component { | |||
60 | alt="" | 54 | alt="" |
61 | /> | 55 | /> |
62 | </td> | 56 | </td> |
63 | <td | 57 | <td className="service-table__column-name" onClick={goToServiceForm}> |
64 | className="service-table__column-name" | ||
65 | onClick={goToServiceForm} | ||
66 | > | ||
67 | {service.name !== '' ? service.name : service.recipe.name} | 58 | {service.name !== '' ? service.name : service.recipe.name} |
68 | </td> | 59 | </td> |
69 | <td | 60 | <td className="service-table__column-info" onClick={goToServiceForm}> |
70 | className="service-table__column-info" | ||
71 | onClick={goToServiceForm} | ||
72 | > | ||
73 | {service.isMuted && ( | 61 | {service.isMuted && ( |
74 | <span | 62 | <span |
75 | className="mdi mdi-bell-off" | 63 | className="mdi mdi-bell-off" |
@@ -77,10 +65,7 @@ export default @observer class ServiceItem extends Component { | |||
77 | /> | 65 | /> |
78 | )} | 66 | )} |
79 | </td> | 67 | </td> |
80 | <td | 68 | <td className="service-table__column-info" onClick={goToServiceForm}> |
81 | className="service-table__column-info" | ||
82 | onClick={goToServiceForm} | ||
83 | > | ||
84 | {!service.isEnabled && ( | 69 | {!service.isEnabled && ( |
85 | <span | 70 | <span |
86 | className="mdi mdi-power" | 71 | className="mdi mdi-power" |
@@ -88,14 +73,13 @@ export default @observer class ServiceItem extends Component { | |||
88 | /> | 73 | /> |
89 | )} | 74 | )} |
90 | </td> | 75 | </td> |
91 | <td | 76 | <td className="service-table__column-info" onClick={goToServiceForm}> |
92 | className="service-table__column-info" | ||
93 | onClick={goToServiceForm} | ||
94 | > | ||
95 | {!service.isNotificationEnabled && ( | 77 | {!service.isNotificationEnabled && ( |
96 | <span | 78 | <span |
97 | className="mdi mdi-message-bulleted-off" | 79 | className="mdi mdi-message-bulleted-off" |
98 | data-tip={intl.formatMessage(messages.tooltipNotificationsDisabled)} | 80 | data-tip={intl.formatMessage( |
81 | messages.tooltipNotificationsDisabled, | ||
82 | )} | ||
99 | /> | 83 | /> |
100 | )} | 84 | )} |
101 | <ReactTooltip place="top" type="dark" effect="solid" /> | 85 | <ReactTooltip place="top" type="dark" effect="solid" /> |
@@ -104,3 +88,5 @@ export default @observer class ServiceItem extends Component { | |||
104 | ); | 88 | ); |
105 | } | 89 | } |
106 | } | 90 | } |
91 | |||
92 | export default injectIntl(ServiceItem); | ||
diff --git a/src/components/settings/services/ServicesDashboard.js b/src/components/settings/services/ServicesDashboard.js index 11d3eaa79..bb52db97f 100644 --- a/src/components/settings/services/ServicesDashboard.js +++ b/src/components/settings/services/ServicesDashboard.js | |||
@@ -2,7 +2,7 @@ import React, { Component } from 'react'; | |||
2 | import PropTypes from 'prop-types'; | 2 | import PropTypes from 'prop-types'; |
3 | import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; | 3 | import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; |
4 | import { Link } from 'react-router'; | 4 | import { Link } from 'react-router'; |
5 | import { defineMessages, intlShape } from 'react-intl'; | 5 | import { defineMessages, injectIntl } from 'react-intl'; |
6 | 6 | ||
7 | import SearchInput from '../../ui/SearchInput'; | 7 | import SearchInput from '../../ui/SearchInput'; |
8 | import Infobox from '../../ui/Infobox'; | 8 | import Infobox from '../../ui/Infobox'; |
@@ -14,43 +14,45 @@ import Appear from '../../ui/effects/Appear'; | |||
14 | const messages = defineMessages({ | 14 | const messages = defineMessages({ |
15 | headline: { | 15 | headline: { |
16 | id: 'settings.services.headline', | 16 | id: 'settings.services.headline', |
17 | defaultMessage: '!!!Your services', | 17 | defaultMessage: 'Your services', |
18 | }, | 18 | }, |
19 | searchService: { | 19 | searchService: { |
20 | id: 'settings.searchService', | 20 | id: 'settings.searchService', |
21 | defaultMessage: '!!!Search service', | 21 | defaultMessage: 'Search service', |
22 | }, | 22 | }, |
23 | noServicesAdded: { | 23 | noServicesAdded: { |
24 | id: 'settings.services.noServicesAdded', | 24 | id: 'settings.services.noServicesAdded', |
25 | defaultMessage: '!!!Start by adding a service.', | 25 | defaultMessage: 'Start by adding a service.', |
26 | }, | 26 | }, |
27 | noServiceFound: { | 27 | noServiceFound: { |
28 | id: 'settings.recipes.nothingFound', | 28 | id: 'settings.services.nothingFound', |
29 | defaultMessage: '!!!Sorry, but no service matched your search term. Please note that the website might show more services that have been added to Ferdi since the version that you are currently on. To get those new services, please consider upgrading to a newer version of Ferdi.', | 29 | defaultMessage: |
30 | 'Sorry, but no service matched your search term - but you can still probably add it using the "Custom Website" option. Please note that the website might show more services that have been added to Ferdi since the version that you are currently on. To get those new services, please consider upgrading to a newer version of Ferdi.', | ||
30 | }, | 31 | }, |
31 | discoverServices: { | 32 | discoverServices: { |
32 | id: 'settings.services.discoverServices', | 33 | id: 'settings.services.discoverServices', |
33 | defaultMessage: '!!!Discover services', | 34 | defaultMessage: 'Discover services', |
34 | }, | 35 | }, |
35 | servicesRequestFailed: { | 36 | servicesRequestFailed: { |
36 | id: 'settings.services.servicesRequestFailed', | 37 | id: 'settings.services.servicesRequestFailed', |
37 | defaultMessage: '!!!Could not load your services', | 38 | defaultMessage: 'Could not load your services', |
38 | }, | 39 | }, |
39 | tryReloadServices: { | 40 | tryReloadServices: { |
40 | id: 'settings.account.tryReloadServices', | 41 | id: 'settings.account.tryReloadServices', |
41 | defaultMessage: '!!!Try again', | 42 | defaultMessage: 'Try again', |
42 | }, | 43 | }, |
43 | updatedInfo: { | 44 | updatedInfo: { |
44 | id: 'settings.services.updatedInfo', | 45 | id: 'settings.services.updatedInfo', |
45 | defaultMessage: '!!!Your changes have been saved', | 46 | defaultMessage: 'Your changes have been saved', |
46 | }, | 47 | }, |
47 | deletedInfo: { | 48 | deletedInfo: { |
48 | id: 'settings.services.deletedInfo', | 49 | id: 'settings.services.deletedInfo', |
49 | defaultMessage: '!!!Service has been deleted', | 50 | defaultMessage: 'Service has been deleted', |
50 | }, | 51 | }, |
51 | }); | 52 | }); |
52 | 53 | ||
53 | export default @observer class ServicesDashboard extends Component { | 54 | @observer |
55 | class ServicesDashboard extends Component { | ||
54 | static propTypes = { | 56 | static propTypes = { |
55 | services: MobxPropTypes.arrayOrObservableArray.isRequired, | 57 | services: MobxPropTypes.arrayOrObservableArray.isRequired, |
56 | isLoading: PropTypes.bool.isRequired, | 58 | isLoading: PropTypes.bool.isRequired, |
@@ -68,10 +70,6 @@ export default @observer class ServicesDashboard extends Component { | |||
68 | searchNeedle: '', | 70 | searchNeedle: '', |
69 | }; | 71 | }; |
70 | 72 | ||
71 | static contextTypes = { | ||
72 | intl: intlShape, | ||
73 | }; | ||
74 | |||
75 | render() { | 73 | render() { |
76 | const { | 74 | const { |
77 | services, | 75 | services, |
@@ -85,7 +83,7 @@ export default @observer class ServicesDashboard extends Component { | |||
85 | status, | 83 | status, |
86 | searchNeedle, | 84 | searchNeedle, |
87 | } = this.props; | 85 | } = this.props; |
88 | const { intl } = this.context; | 86 | const { intl } = this.props; |
89 | 87 | ||
90 | return ( | 88 | return ( |
91 | <div className="settings__main"> | 89 | <div className="settings__main"> |
@@ -93,10 +91,10 @@ export default @observer class ServicesDashboard extends Component { | |||
93 | <h1>{intl.formatMessage(messages.headline)}</h1> | 91 | <h1>{intl.formatMessage(messages.headline)}</h1> |
94 | </div> | 92 | </div> |
95 | <div className="settings__body"> | 93 | <div className="settings__body"> |
96 | {(services.length !== 0 || searchNeedle) && !isLoading && ( | 94 | {(services.length > 0 || searchNeedle) && !isLoading && ( |
97 | <SearchInput | 95 | <SearchInput |
98 | placeholder={intl.formatMessage(messages.searchService)} | 96 | placeholder={intl.formatMessage(messages.searchService)} |
99 | onChange={(needle) => filterServices({ needle })} | 97 | onChange={needle => filterServices({ needle })} |
100 | onReset={() => resetFilter()} | 98 | onReset={() => resetFilter()} |
101 | autoFocus | 99 | autoFocus |
102 | /> | 100 | /> |
@@ -145,7 +143,9 @@ export default @observer class ServicesDashboard extends Component { | |||
145 | </span> | 143 | </span> |
146 | {intl.formatMessage(messages.noServicesAdded)} | 144 | {intl.formatMessage(messages.noServicesAdded)} |
147 | </p> | 145 | </p> |
148 | <Link to="/settings/recipes" className="button">{intl.formatMessage(messages.discoverServices)}</Link> | 146 | <Link to="/settings/recipes" className="button"> |
147 | {intl.formatMessage(messages.discoverServices)} | ||
148 | </Link> | ||
149 | </div> | 149 | </div> |
150 | )} | 150 | )} |
151 | {!isLoading && services.length === 0 && searchNeedle && ( | 151 | {!isLoading && services.length === 0 && searchNeedle && ( |
@@ -163,12 +163,16 @@ export default @observer class ServicesDashboard extends Component { | |||
163 | ) : ( | 163 | ) : ( |
164 | <table className="service-table"> | 164 | <table className="service-table"> |
165 | <tbody> | 165 | <tbody> |
166 | {services.map((service) => ( | 166 | {services.map(service => ( |
167 | <ServiceItem | 167 | <ServiceItem |
168 | key={service.id} | 168 | key={service.id} |
169 | service={service} | 169 | service={service} |
170 | toggleAction={() => toggleService({ serviceId: service.id })} | 170 | toggleAction={() => |
171 | goToServiceForm={() => goTo(`/settings/services/edit/${service.id}`)} | 171 | toggleService({ serviceId: service.id }) |
172 | } | ||
173 | goToServiceForm={() => | ||
174 | goTo(`/settings/services/edit/${service.id}`) | ||
175 | } | ||
172 | /> | 176 | /> |
173 | ))} | 177 | ))} |
174 | </tbody> | 178 | </tbody> |
@@ -176,12 +180,12 @@ export default @observer class ServicesDashboard extends Component { | |||
176 | )} | 180 | )} |
177 | 181 | ||
178 | <FAB> | 182 | <FAB> |
179 | <Link to="/settings/recipes"> | 183 | <Link to="/settings/recipes">+</Link> |
180 | + | ||
181 | </Link> | ||
182 | </FAB> | 184 | </FAB> |
183 | </div> | 185 | </div> |
184 | </div> | 186 | </div> |
185 | ); | 187 | ); |
186 | } | 188 | } |
187 | } | 189 | } |
190 | |||
191 | export default injectIntl(ServicesDashboard); | ||