diff options
author | 2022-06-27 18:21:31 +0200 | |
---|---|---|
committer | 2022-06-27 17:21:31 +0100 | |
commit | 0bf13689d53bd493fb4d0a4213c1801013b5aa8a (patch) | |
tree | 2b5ae44e4f1aa73b49c011954ff1cb47e3959bad /src/containers/settings/EditServiceScreen.js | |
parent | chore: recommend specific vscode extensions to setup development [skip ci] (#... (diff) | |
download | ferdium-app-0bf13689d53bd493fb4d0a4213c1801013b5aa8a.tar.gz ferdium-app-0bf13689d53bd493fb4d0a4213c1801013b5aa8a.tar.zst ferdium-app-0bf13689d53bd493fb4d0a4213c1801013b5aa8a.zip |
chore: transform containers/settings from js to tsx (#384)
Diffstat (limited to 'src/containers/settings/EditServiceScreen.js')
-rw-r--r-- | src/containers/settings/EditServiceScreen.js | 472 |
1 files changed, 0 insertions, 472 deletions
diff --git a/src/containers/settings/EditServiceScreen.js b/src/containers/settings/EditServiceScreen.js deleted file mode 100644 index 4615a9cdf..000000000 --- a/src/containers/settings/EditServiceScreen.js +++ /dev/null | |||
@@ -1,472 +0,0 @@ | |||
1 | import { Component } from 'react'; | ||
2 | import PropTypes from 'prop-types'; | ||
3 | import { inject, observer } from 'mobx-react'; | ||
4 | import { defineMessages, injectIntl } from 'react-intl'; | ||
5 | |||
6 | import { RouterStore } from 'mobx-react-router'; | ||
7 | import UserStore from '../../stores/UserStore'; | ||
8 | import RecipesStore from '../../stores/RecipesStore'; | ||
9 | import ServicesStore from '../../stores/ServicesStore'; | ||
10 | import SettingsStore from '../../stores/SettingsStore'; | ||
11 | import Form from '../../lib/Form'; | ||
12 | |||
13 | import ServiceError from '../../components/settings/services/ServiceError'; | ||
14 | import EditServiceForm from '../../components/settings/services/EditServiceForm'; | ||
15 | import ErrorBoundary from '../../components/util/ErrorBoundary'; | ||
16 | |||
17 | import { required, url, oneRequired } from '../../helpers/validation-helpers'; | ||
18 | import { getSelectOptions } from '../../helpers/i18n-helpers'; | ||
19 | |||
20 | import { config as proxyFeature } from '../../features/serviceProxy'; | ||
21 | |||
22 | import { SPELLCHECKER_LOCALES } from '../../i18n/languages'; | ||
23 | |||
24 | import globalMessages from '../../i18n/globalMessages'; | ||
25 | import { DEFAULT_APP_SETTINGS, DEFAULT_SERVICE_SETTINGS } from '../../config'; | ||
26 | |||
27 | const messages = defineMessages({ | ||
28 | name: { | ||
29 | id: 'settings.service.form.name', | ||
30 | defaultMessage: 'Name', | ||
31 | }, | ||
32 | enableService: { | ||
33 | id: 'settings.service.form.enableService', | ||
34 | defaultMessage: 'Enable service', | ||
35 | }, | ||
36 | enableHibernation: { | ||
37 | id: 'settings.service.form.enableHibernation', | ||
38 | defaultMessage: 'Enable hibernation', | ||
39 | }, | ||
40 | enableWakeUp: { | ||
41 | id: 'settings.service.form.enableWakeUp', | ||
42 | defaultMessage: 'Enable wake up', | ||
43 | }, | ||
44 | enableNotification: { | ||
45 | id: 'settings.service.form.enableNotification', | ||
46 | defaultMessage: 'Enable notifications', | ||
47 | }, | ||
48 | enableBadge: { | ||
49 | id: 'settings.service.form.enableBadge', | ||
50 | defaultMessage: 'Show unread message badges', | ||
51 | }, | ||
52 | enableAudio: { | ||
53 | id: 'settings.service.form.enableAudio', | ||
54 | defaultMessage: 'Enable audio', | ||
55 | }, | ||
56 | team: { | ||
57 | id: 'settings.service.form.team', | ||
58 | defaultMessage: 'Team', | ||
59 | }, | ||
60 | customUrl: { | ||
61 | id: 'settings.service.form.customUrl', | ||
62 | defaultMessage: 'Custom server', | ||
63 | }, | ||
64 | indirectMessages: { | ||
65 | id: 'settings.service.form.indirectMessages', | ||
66 | defaultMessage: 'Show message badge for all new messages', | ||
67 | }, | ||
68 | icon: { | ||
69 | id: 'settings.service.form.icon', | ||
70 | defaultMessage: 'Custom icon', | ||
71 | }, | ||
72 | enableDarkMode: { | ||
73 | id: 'settings.service.form.enableDarkMode', | ||
74 | defaultMessage: 'Enable Dark Mode', | ||
75 | }, | ||
76 | darkReaderBrightness: { | ||
77 | id: 'settings.service.form.darkReaderBrightness', | ||
78 | defaultMessage: 'Dark Reader Brightness', | ||
79 | }, | ||
80 | darkReaderContrast: { | ||
81 | id: 'settings.service.form.darkReaderContrast', | ||
82 | defaultMessage: 'Dark Reader Contrast', | ||
83 | }, | ||
84 | darkReaderSepia: { | ||
85 | id: 'settings.service.form.darkReaderSepia', | ||
86 | defaultMessage: 'Dark Reader Sepia', | ||
87 | }, | ||
88 | enableProgressbar: { | ||
89 | id: 'settings.service.form.enableProgressbar', | ||
90 | defaultMessage: 'Enable Progress bar', | ||
91 | }, | ||
92 | trapLinkClicks: { | ||
93 | id: 'settings.service.form.trapLinkClicks', | ||
94 | defaultMessage: 'Open URLs within Ferdium', | ||
95 | }, | ||
96 | onlyShowFavoritesInUnreadCount: { | ||
97 | id: 'settings.service.form.onlyShowFavoritesInUnreadCount', | ||
98 | defaultMessage: 'Only show Favorites in unread count', | ||
99 | }, | ||
100 | enableProxy: { | ||
101 | id: 'settings.service.form.proxy.isEnabled', | ||
102 | defaultMessage: 'Use Proxy', | ||
103 | }, | ||
104 | proxyHost: { | ||
105 | id: 'settings.service.form.proxy.host', | ||
106 | defaultMessage: 'Proxy Host/IP', | ||
107 | }, | ||
108 | proxyPort: { | ||
109 | id: 'settings.service.form.proxy.port', | ||
110 | defaultMessage: 'Port', | ||
111 | }, | ||
112 | proxyUser: { | ||
113 | id: 'settings.service.form.proxy.user', | ||
114 | defaultMessage: 'User (optional)', | ||
115 | }, | ||
116 | proxyPassword: { | ||
117 | id: 'settings.service.form.proxy.password', | ||
118 | defaultMessage: 'Password (optional)', | ||
119 | }, | ||
120 | }); | ||
121 | |||
122 | class EditServiceScreen extends Component { | ||
123 | onSubmit(data) { | ||
124 | const { action } = this.props.router.params; | ||
125 | const { recipes, services } = this.props.stores; | ||
126 | const { createService, updateService } = this.props.actions.service; | ||
127 | data.darkReaderSettings = { | ||
128 | brightness: data.darkReaderBrightness, | ||
129 | contrast: data.darkReaderContrast, | ||
130 | sepia: data.darkReaderSepia, | ||
131 | }; | ||
132 | delete data.darkReaderContrast; | ||
133 | delete data.darkReaderBrightness; | ||
134 | delete data.darkReaderSepia; | ||
135 | |||
136 | const serviceData = data; | ||
137 | serviceData.isMuted = !serviceData.isMuted; | ||
138 | |||
139 | if (action === 'edit') { | ||
140 | updateService({ serviceId: services.activeSettings.id, serviceData }); | ||
141 | } else { | ||
142 | createService({ recipeId: recipes.active.id, serviceData }); | ||
143 | } | ||
144 | } | ||
145 | |||
146 | prepareForm(recipe, service, proxy) { | ||
147 | const { intl } = this.props; | ||
148 | |||
149 | const { stores, router } = this.props; | ||
150 | |||
151 | const { action } = router.params; | ||
152 | |||
153 | let defaultSpellcheckerLanguage = | ||
154 | SPELLCHECKER_LOCALES[stores.settings.app.spellcheckerLanguage]; | ||
155 | |||
156 | if (stores.settings.app.spellcheckerLanguage === 'automatic') { | ||
157 | defaultSpellcheckerLanguage = intl.formatMessage( | ||
158 | globalMessages.spellcheckerAutomaticDetectionShort, | ||
159 | ); | ||
160 | } | ||
161 | |||
162 | const spellcheckerLanguage = getSelectOptions({ | ||
163 | locales: SPELLCHECKER_LOCALES, | ||
164 | resetToDefaultText: intl.formatMessage( | ||
165 | globalMessages.spellcheckerSystemDefault, | ||
166 | { default: defaultSpellcheckerLanguage }, | ||
167 | ), | ||
168 | automaticDetectionText: | ||
169 | stores.settings.app.spellcheckerLanguage !== 'automatic' | ||
170 | ? intl.formatMessage(globalMessages.spellcheckerAutomaticDetection) | ||
171 | : '', | ||
172 | }); | ||
173 | |||
174 | const config = { | ||
175 | fields: { | ||
176 | name: { | ||
177 | label: intl.formatMessage(messages.name), | ||
178 | placeholder: intl.formatMessage(messages.name), | ||
179 | value: service.id ? service.name : recipe.name, | ||
180 | }, | ||
181 | isEnabled: { | ||
182 | label: intl.formatMessage(messages.enableService), | ||
183 | value: service.isEnabled, | ||
184 | default: DEFAULT_SERVICE_SETTINGS.isEnabled, | ||
185 | }, | ||
186 | isHibernationEnabled: { | ||
187 | label: intl.formatMessage(messages.enableHibernation), | ||
188 | value: | ||
189 | action !== 'edit' | ||
190 | ? recipe.autoHibernate | ||
191 | : service.isHibernationEnabled, | ||
192 | default: DEFAULT_SERVICE_SETTINGS.isHibernationEnabled, | ||
193 | }, | ||
194 | isWakeUpEnabled: { | ||
195 | label: intl.formatMessage(messages.enableWakeUp), | ||
196 | value: service.isWakeUpEnabled, | ||
197 | default: DEFAULT_SERVICE_SETTINGS.isWakeUpEnabled, | ||
198 | }, | ||
199 | isNotificationEnabled: { | ||
200 | label: intl.formatMessage(messages.enableNotification), | ||
201 | value: service.isNotificationEnabled, | ||
202 | default: DEFAULT_SERVICE_SETTINGS.isNotificationEnabled, | ||
203 | }, | ||
204 | isBadgeEnabled: { | ||
205 | label: intl.formatMessage(messages.enableBadge), | ||
206 | value: service.isBadgeEnabled, | ||
207 | default: DEFAULT_SERVICE_SETTINGS.isBadgeEnabled, | ||
208 | }, | ||
209 | trapLinkClicks: { | ||
210 | label: intl.formatMessage(messages.trapLinkClicks), | ||
211 | value: service.trapLinkClicks, | ||
212 | default: DEFAULT_SERVICE_SETTINGS.trapLinkClicks, | ||
213 | }, | ||
214 | isMuted: { | ||
215 | label: intl.formatMessage(messages.enableAudio), | ||
216 | value: !service.isMuted, | ||
217 | default: DEFAULT_SERVICE_SETTINGS.isMuted, | ||
218 | }, | ||
219 | customIcon: { | ||
220 | label: intl.formatMessage(messages.icon), | ||
221 | value: service.hasCustomUploadedIcon ? service.icon : false, | ||
222 | default: null, | ||
223 | type: 'file', | ||
224 | }, | ||
225 | isDarkModeEnabled: { | ||
226 | label: intl.formatMessage(messages.enableDarkMode), | ||
227 | value: service.isDarkModeEnabled, | ||
228 | default: stores.settings.app.darkMode, | ||
229 | }, | ||
230 | darkReaderBrightness: { | ||
231 | label: intl.formatMessage(messages.darkReaderBrightness), | ||
232 | value: service.darkReaderSettings | ||
233 | ? service.darkReaderSettings.brightness | ||
234 | : undefined, | ||
235 | default: 100, | ||
236 | }, | ||
237 | darkReaderContrast: { | ||
238 | label: intl.formatMessage(messages.darkReaderContrast), | ||
239 | value: service.darkReaderSettings | ||
240 | ? service.darkReaderSettings.contrast | ||
241 | : undefined, | ||
242 | default: 90, | ||
243 | }, | ||
244 | darkReaderSepia: { | ||
245 | label: intl.formatMessage(messages.darkReaderSepia), | ||
246 | value: service.darkReaderSettings | ||
247 | ? service.darkReaderSettings.sepia | ||
248 | : undefined, | ||
249 | default: 10, | ||
250 | }, | ||
251 | isProgressbarEnabled: { | ||
252 | label: intl.formatMessage(messages.enableProgressbar), | ||
253 | value: service.isProgressbarEnabled, | ||
254 | default: DEFAULT_SERVICE_SETTINGS.isProgressbarEnabled, | ||
255 | }, | ||
256 | spellcheckerLanguage: { | ||
257 | label: intl.formatMessage(globalMessages.spellcheckerLanguage), | ||
258 | value: service.spellcheckerLanguage, | ||
259 | options: spellcheckerLanguage, | ||
260 | disabled: !stores.settings.app.enableSpellchecking, | ||
261 | }, | ||
262 | userAgentPref: { | ||
263 | label: intl.formatMessage(globalMessages.userAgentPref), | ||
264 | placeholder: service.defaultUserAgent, | ||
265 | value: service.userAgentPref ? service.userAgentPref : '', | ||
266 | }, | ||
267 | }, | ||
268 | }; | ||
269 | |||
270 | if (recipe.hasTeamId) { | ||
271 | Object.assign(config.fields, { | ||
272 | team: { | ||
273 | label: intl.formatMessage(messages.team), | ||
274 | placeholder: intl.formatMessage(messages.team), | ||
275 | value: service.team, | ||
276 | validators: [required], | ||
277 | }, | ||
278 | }); | ||
279 | } | ||
280 | |||
281 | if (recipe.hasCustomUrl) { | ||
282 | Object.assign(config.fields, { | ||
283 | customUrl: { | ||
284 | label: intl.formatMessage(messages.customUrl), | ||
285 | placeholder: "'http://' or 'https://' or 'file:///'", | ||
286 | value: service.customUrl || recipe.serviceURL, | ||
287 | validators: [required, url], | ||
288 | }, | ||
289 | }); | ||
290 | } | ||
291 | |||
292 | // More fine grained and use case specific validation rules | ||
293 | if (recipe.hasTeamId && recipe.hasCustomUrl) { | ||
294 | config.fields.team.validators = [oneRequired(['team', 'customUrl'])]; | ||
295 | config.fields.customUrl.validators = [ | ||
296 | url, | ||
297 | oneRequired(['team', 'customUrl']), | ||
298 | ]; | ||
299 | } | ||
300 | |||
301 | // If a service can be hosted and has a teamId or customUrl | ||
302 | if (recipe.hasHostedOption && (recipe.hasTeamId || recipe.hasCustomUrl)) { | ||
303 | if (config.fields.team) { | ||
304 | config.fields.team.validators = []; | ||
305 | } | ||
306 | if (config.fields.customUrl) { | ||
307 | config.fields.customUrl.validators = [url]; | ||
308 | } | ||
309 | } | ||
310 | |||
311 | if (recipe.hasIndirectMessages) { | ||
312 | Object.assign(config.fields, { | ||
313 | isIndirectMessageBadgeEnabled: { | ||
314 | label: intl.formatMessage(messages.indirectMessages), | ||
315 | value: service.isIndirectMessageBadgeEnabled, | ||
316 | default: DEFAULT_SERVICE_SETTINGS.hasIndirectMessages, | ||
317 | }, | ||
318 | }); | ||
319 | } | ||
320 | |||
321 | if (recipe.allowFavoritesDelineationInUnreadCount) { | ||
322 | Object.assign(config.fields, { | ||
323 | onlyShowFavoritesInUnreadCount: { | ||
324 | label: intl.formatMessage(messages.onlyShowFavoritesInUnreadCount), | ||
325 | value: service.onlyShowFavoritesInUnreadCount, | ||
326 | default: DEFAULT_APP_SETTINGS.onlyShowFavoritesInUnreadCount, | ||
327 | }, | ||
328 | }); | ||
329 | } | ||
330 | |||
331 | if (proxy.isEnabled) { | ||
332 | const serviceProxyConfig = stores.settings.proxy[service.id] || {}; | ||
333 | |||
334 | Object.assign(config.fields, { | ||
335 | proxy: { | ||
336 | name: 'proxy', | ||
337 | label: 'proxy', | ||
338 | fields: { | ||
339 | isEnabled: { | ||
340 | label: intl.formatMessage(messages.enableProxy), | ||
341 | value: serviceProxyConfig.isEnabled, | ||
342 | default: DEFAULT_APP_SETTINGS.proxyFeatureEnabled, | ||
343 | }, | ||
344 | host: { | ||
345 | label: intl.formatMessage(messages.proxyHost), | ||
346 | value: serviceProxyConfig.host, | ||
347 | default: '', | ||
348 | }, | ||
349 | port: { | ||
350 | label: intl.formatMessage(messages.proxyPort), | ||
351 | value: serviceProxyConfig.port, | ||
352 | default: '', | ||
353 | }, | ||
354 | user: { | ||
355 | label: intl.formatMessage(messages.proxyUser), | ||
356 | value: serviceProxyConfig.user, | ||
357 | default: '', | ||
358 | }, | ||
359 | password: { | ||
360 | label: intl.formatMessage(messages.proxyPassword), | ||
361 | value: serviceProxyConfig.password, | ||
362 | default: '', | ||
363 | type: 'password', | ||
364 | }, | ||
365 | }, | ||
366 | }, | ||
367 | }); | ||
368 | } | ||
369 | |||
370 | return new Form(config); | ||
371 | } | ||
372 | |||
373 | deleteService() { | ||
374 | const { deleteService } = this.props.actions.service; | ||
375 | const { action } = this.props.router.params; | ||
376 | |||
377 | if (action === 'edit') { | ||
378 | const { activeSettings: service } = this.props.stores.services; | ||
379 | deleteService({ | ||
380 | serviceId: service.id, | ||
381 | redirect: '/settings/services', | ||
382 | }); | ||
383 | } | ||
384 | } | ||
385 | |||
386 | openRecipeFile(file) { | ||
387 | const { openRecipeFile } = this.props.actions.service; | ||
388 | const { action } = this.props.router.params; | ||
389 | |||
390 | if (action === 'edit') { | ||
391 | const { activeSettings: service } = this.props.stores.services; | ||
392 | openRecipeFile({ | ||
393 | recipe: service.recipe.id, | ||
394 | file, | ||
395 | }); | ||
396 | } | ||
397 | } | ||
398 | |||
399 | render() { | ||
400 | const { recipes, services, user } = this.props.stores; | ||
401 | const { action } = this.props.router.params; | ||
402 | |||
403 | let recipe; | ||
404 | let service = {}; | ||
405 | let isLoading = false; | ||
406 | |||
407 | if (action === 'add') { | ||
408 | recipe = recipes.active; | ||
409 | |||
410 | // TODO: render error message when recipe is `null` | ||
411 | if (!recipe) { | ||
412 | return <ServiceError />; | ||
413 | } | ||
414 | } else { | ||
415 | service = services.activeSettings; | ||
416 | isLoading = services.allServicesRequest.isExecuting; | ||
417 | |||
418 | if (!isLoading && service) { | ||
419 | recipe = service.recipe; | ||
420 | } | ||
421 | } | ||
422 | |||
423 | if (isLoading) { | ||
424 | return <div>Loading...</div>; | ||
425 | } | ||
426 | |||
427 | if (!recipe) { | ||
428 | return <div>something went wrong</div>; | ||
429 | } | ||
430 | |||
431 | const form = this.prepareForm(recipe, service, proxyFeature); | ||
432 | |||
433 | return ( | ||
434 | <ErrorBoundary> | ||
435 | <EditServiceForm | ||
436 | action={action} | ||
437 | recipe={recipe} | ||
438 | service={service} | ||
439 | user={user.data} | ||
440 | form={form} | ||
441 | status={services.actionStatus} | ||
442 | isSaving={ | ||
443 | services.updateServiceRequest.isExecuting || | ||
444 | services.createServiceRequest.isExecuting | ||
445 | } | ||
446 | isDeleting={services.deleteServiceRequest.isExecuting} | ||
447 | onSubmit={d => this.onSubmit(d)} | ||
448 | onDelete={() => this.deleteService()} | ||
449 | openRecipeFile={file => this.openRecipeFile(file)} | ||
450 | isProxyFeatureEnabled={proxyFeature.isEnabled} | ||
451 | /> | ||
452 | </ErrorBoundary> | ||
453 | ); | ||
454 | } | ||
455 | } | ||
456 | |||
457 | EditServiceScreen.propTypes = { | ||
458 | stores: PropTypes.shape({ | ||
459 | user: PropTypes.instanceOf(UserStore).isRequired, | ||
460 | recipes: PropTypes.instanceOf(RecipesStore).isRequired, | ||
461 | services: PropTypes.instanceOf(ServicesStore).isRequired, | ||
462 | settings: PropTypes.instanceOf(SettingsStore).isRequired, | ||
463 | }).isRequired, | ||
464 | router: PropTypes.instanceOf(RouterStore).isRequired, | ||
465 | actions: PropTypes.shape({ | ||
466 | service: PropTypes.instanceOf(ServicesStore).isRequired, | ||
467 | }).isRequired, | ||
468 | }; | ||
469 | |||
470 | export default injectIntl( | ||
471 | inject('stores', 'actions')(observer(EditServiceScreen)), | ||
472 | ); | ||