aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/settings
diff options
context:
space:
mode:
authorLibravatar Romain <46404814+yourcontact@users.noreply.github.com>2020-04-22 17:48:49 +0200
committerLibravatar GitHub <noreply@github.com>2020-04-22 15:48:49 +0000
commitf4d9c4e3285bc9782187e46ee0f39748925c3689 (patch)
treee717e3976c334c244e9e32e1f3cdbd1622f8d395 /src/components/settings
parentdocs: add saruwman as a contributor (#627) (diff)
downloadferdium-app-f4d9c4e3285bc9782187e46ee0f39748925c3689.tar.gz
ferdium-app-f4d9c4e3285bc9782187e46ee0f39748925c3689.tar.zst
ferdium-app-f4d9c4e3285bc9782187e46ee0f39748925c3689.zip
Organize settings with horizontal tabs (#569)
* Align settings section titles on same row * Add className to Settings Titles to copy tab layout from 'Available Services' * Add all Settings Titles to the horizontal tab layout at the top of the form * Add state for active settings taband onClick * Add condition for each Settings div to show when activeSetttingsTab plus fix typo 'appearance' * Add condition for each Settings div to show when activeSetttingsTab plus fix typo 'appearance' * Add margins in between setting tabs * Remove 50px of top margin to minimize blank space above tabs * Remove temporary &nbsp;&nbsp; in between tabs now that CSS is in place * Apply code changes * Delete unused code const { activeSettingsTab } = this.state; Co-authored-by: Amine Mouafik <amine@mouafik.fr>
Diffstat (limited to 'src/components/settings')
-rw-r--r--src/components/settings/settings/EditSettingsForm.js582
1 files changed, 321 insertions, 261 deletions
diff --git a/src/components/settings/settings/EditSettingsForm.js b/src/components/settings/settings/EditSettingsForm.js
index 6d86c09ec..787623298 100644
--- a/src/components/settings/settings/EditSettingsForm.js
+++ b/src/components/settings/settings/EditSettingsForm.js
@@ -173,10 +173,17 @@ export default @observer class EditSettingsForm extends Component {
173 intl: intlShape, 173 intl: intlShape,
174 }; 174 };
175 175
176 state={ 176 state = {
177 activeSetttingsTab: 'general',
177 clearCacheButtonClicked: false, 178 clearCacheButtonClicked: false,
178 } 179 }
179 180
181 setActiveSettingsTab(tab) {
182 this.setState({
183 activeSetttingsTab: tab,
184 });
185 }
186
180 onClearCacheClicked=() => { 187 onClearCacheClicked=() => {
181 this.setState({ clearCacheButtonClicked: true }); 188 this.setState({ clearCacheButtonClicked: true });
182 } 189 }
@@ -241,190 +248,203 @@ export default @observer class EditSettingsForm extends Component {
241 onChange={e => this.submit(e)} 248 onChange={e => this.submit(e)}
242 id="form" 249 id="form"
243 > 250 >
251 {/* Titles */}
252 <div className="recipes__navigation">
253 <h2
254 id="general"
255 className={this.state.activeSetttingsTab === 'general' ? 'badge badge--primary' : 'badge'}
256 onClick={() => { this.setActiveSettingsTab('general'); }}
257 >
258 {intl.formatMessage(messages.headlineGeneral)}
259 </h2>
260 <h2
261 id="appearance"
262 className={this.state.activeSetttingsTab === 'appearance' ? 'badge badge--primary' : 'badge'}
263 onClick={() => { this.setActiveSettingsTab('appearance'); }}
264 >
265 {intl.formatMessage(messages.headlineAppearance)}
266 </h2>
267 <h2
268 id="language"
269 className={this.state.activeSetttingsTab === 'language' ? 'badge badge--primary' : 'badge'}
270 onClick={() => { this.setActiveSettingsTab('language'); }}
271 >
272 {intl.formatMessage(messages.headlineLanguage)}
273 </h2>
274 <h2
275 id="advanced"
276 className={this.state.activeSetttingsTab === 'advanced' ? 'badge badge--primary' : 'badge'}
277 onClick={() => { this.setActiveSettingsTab('advanced'); }}
278 >
279 {intl.formatMessage(messages.headlineAdvanced)}
280 </h2>
281 <h2
282 id="updates"
283 className={this.state.activeSetttingsTab === 'updates' ? 'badge badge--primary' : 'badge'}
284 onClick={() => { this.setActiveSettingsTab('updates'); }}
285 >
286 {intl.formatMessage(messages.headlineUpdates)}
287 </h2>
288 </div>
289
244 {/* General */} 290 {/* General */}
245 <h2 id="general">{intl.formatMessage(messages.headlineGeneral)}</h2> 291 { this.state.activeSetttingsTab === 'general' && (
246 <Toggle field={form.$('autoLaunchOnStart')} /> 292 <div>
247 <Toggle field={form.$('runInBackground')} /> 293 <Toggle field={form.$('autoLaunchOnStart')} />
248 <Toggle field={form.$('enableSystemTray')} /> 294 <Toggle field={form.$('runInBackground')} />
249 <Toggle field={form.$('reloadAfterResume')} /> 295 <Toggle field={form.$('enableSystemTray')} />
250 <Toggle field={form.$('startMinimized')} /> 296 <Toggle field={form.$('reloadAfterResume')} />
251 {process.platform === 'win32' && ( 297 <Toggle field={form.$('startMinimized')} />
252 <Toggle field={form.$('minimizeToSystemTray')} /> 298 {process.platform === 'win32' && (
253 )} 299 <Toggle field={form.$('minimizeToSystemTray')} />
254 <Toggle field={form.$('privateNotifications')} /> 300 )}
255 <Select field={form.$('navigationBarBehaviour')} /> 301 <Toggle field={form.$('privateNotifications')} />
302 <Select field={form.$('navigationBarBehaviour')} />
256 303
257 <Hr /> 304 <Hr />
258 305
259 <Toggle field={form.$('sentry')} /> 306 <Toggle field={form.$('sentry')} />
260 <p>{intl.formatMessage(messages.sentryInfo)}</p> 307 <p>{intl.formatMessage(messages.sentryInfo)}</p>
261 308
262 <Hr /> 309 <Hr />
263 310
264 <Toggle field={form.$('hibernate')} /> 311 <Toggle field={form.$('hibernate')} />
265 {hibernationEnabled && ( 312 {hibernationEnabled && (
266 <> 313 <>
267 <Select field={form.$('hibernationStrategy')} /> 314 <Select field={form.$('hibernationStrategy')} />
268 <Toggle field={form.$('hibernateOnStartup')} /> 315 <Toggle field={form.$('hibernateOnStartup')} />
269 </> 316 </>
270 )} 317 )}
271 <p 318 <p
272 className="settings__message" 319 className="settings__message"
273 style={{ 320 style={{
274 borderTop: 0, marginTop: 0, paddingTop: 0, marginBottom: '2rem', 321 borderTop: 0, marginTop: 0, paddingTop: 0, marginBottom: '2rem',
275 }} 322 }}
276 > 323 >
277 <span> 324 <span>
278 { intl.formatMessage(messages.hibernateInfo) } 325 { intl.formatMessage(messages.hibernateInfo) }
279 </span> 326 </span>
280 </p> 327 </p>
281
282 <Hr />
283
284 {isWorkspaceEnabled && (
285 <Toggle field={form.$('keepAllWorkspacesLoaded')} />
286 )}
287 328
288 <Hr /> 329 <Hr />
289 330
290 {isTodosEnabled && ( 331 {isWorkspaceEnabled && (
291 <> 332 <Toggle field={form.$('keepAllWorkspacesLoaded')} />
292 <Toggle field={form.$('enableTodos')} /> 333 )}
293 {isTodosActivated && ( 334
294 <div> 335 <Hr />
295 <Select field={form.$('predefinedTodoServer')} /> 336
296 {form.$('predefinedTodoServer').value === 'isUsingCustomTodoService' && ( 337 {isTodosEnabled && (
338 <>
339 <Toggle field={form.$('enableTodos')} />
340 {isTodosActivated && (
297 <div> 341 <div>
298 <Input 342 <Select field={form.$('predefinedTodoServer')} />
299 placeholder="Todo Server" 343 {form.$('predefinedTodoServer').value === 'isUsingCustomTodoService' && (
300 onChange={e => this.submit(e)} 344 <div>
301 field={form.$('customTodoServer')} 345 <Input
302 /> 346 placeholder="Todo Server"
303 <p 347 onChange={e => this.submit(e)}
304 className="settings__message" 348 field={form.$('customTodoServer')}
305 style={{ 349 />
306 borderTop: 0, marginTop: 0, paddingTop: 0, marginBottom: '2rem', 350 <p
307 }} 351 className="settings__message"
308 > 352 style={{
309 { intl.formatMessage(messages.todoServerInfo) } 353 borderTop: 0, marginTop: 0, paddingTop: 0, marginBottom: '2rem',
310 </p> 354 }}
355 >
356 { intl.formatMessage(messages.todoServerInfo) }
357 </p>
358 </div>
359 )}
311 </div> 360 </div>
312 )} 361 )}
313 </div> 362 </>
314 )} 363 )}
315 </>
316 )}
317
318 364
319 <Hr /> 365 <Hr />
320 366
321 <Toggle field={form.$('lockingFeatureEnabled')} /> 367 <Toggle field={form.$('lockingFeatureEnabled')} />
322 {lockingFeatureEnabled && ( 368 {lockingFeatureEnabled && (
323 <> 369 <>
324 {systemPreferences.canPromptTouchID() && ( 370 {systemPreferences.canPromptTouchID() && (
325 <Toggle field={form.$('useTouchIdToUnlock')} /> 371 <Toggle field={form.$('useTouchIdToUnlock')} />
326 )} 372 )}
327
328 <Input
329 placeholder={intl.formatMessage(messages.lockedPassword)}
330 onChange={e => this.submit(e)}
331 field={form.$('lockedPassword')}
332 type="password"
333 scorePassword
334 showPasswordToggle
335 />
336 <p>
337 { intl.formatMessage(messages.lockedPasswordInfo) }
338 </p>
339 373
340 <Input
341 placeholder="Lock after inactivity"
342 onChange={e => this.submit(e)}
343 field={form.$('inactivityLock')}
344 autoFocus
345 />
346 <p>
347 { intl.formatMessage(messages.inactivityLockInfo) }
348 </p>
349 </>
350 )}
351 <p
352 className="settings__message"
353 style={{
354 borderTop: 0, marginTop: 0, paddingTop: 0, marginBottom: '2rem',
355 }}
356 >
357 <span>
358 { intl.formatMessage(messages.lockInfo) }
359 </span>
360 </p>
361
362 <Hr />
363
364 <Toggle field={form.$('scheduledDNDEnabled')} />
365 {scheduledDNDEnabled && (
366 <>
367 <div style={{
368 display: 'flex',
369 justifyContent: 'center',
370 }}
371 >
372 <div style={{
373 padding: '0 1rem',
374 width: '100%',
375 }}
376 >
377 <Input 374 <Input
378 placeholder="17:00" 375 placeholder={intl.formatMessage(messages.lockedPassword)}
379 onChange={e => this.submit(e)} 376 onChange={e => this.submit(e)}
380 field={form.$('scheduledDNDStart')} 377 field={form.$('lockedPassword')}
381 type="time" 378 type="password"
379 scorePassword
380 showPasswordToggle
382 /> 381 />
383 </div> 382 <p>
384 <div style={{ 383 { intl.formatMessage(messages.lockedPasswordInfo) }
385 padding: '0 1rem', 384 </p>
386 width: '100%', 385
387 }}
388 >
389 <Input 386 <Input
390 placeholder="09:00" 387 placeholder="Lock after inactivity"
391 onChange={e => this.submit(e)} 388 onChange={e => this.submit(e)}
392 field={form.$('scheduledDNDEnd')} 389 field={form.$('inactivityLock')}
393 type="time" 390 autoFocus
394 /> 391 />
395 </div> 392 <p>
396 </div> 393 { intl.formatMessage(messages.inactivityLockInfo) }
397 <p> 394 </p>
398 { intl.formatMessage(messages.scheduledDNDTimeInfo) } 395 </>
396 )}
397 <p
398 className="settings__message"
399 style={{
400 borderTop: 0, marginTop: 0, paddingTop: 0, marginBottom: '2rem',
401 }}
402 >
403 <span>
404 { intl.formatMessage(messages.lockInfo) }
405 </span>
399 </p> 406 </p>
400 </>
401 )}
402 <p
403 className="settings__message"
404 style={{
405 borderTop: 0, marginTop: 0, paddingTop: 0, marginBottom: '2rem',
406 }}
407 >
408 <span>
409 { intl.formatMessage(messages.scheduledDNDInfo) }
410 </span>
411 </p>
412
413
414 {/* Appearance */}
415 <h2 id="apperance">{intl.formatMessage(messages.headlineAppearance)}</h2>
416 <Toggle field={form.$('showDisabledServices')} />
417 <Toggle field={form.$('showMessageBadgeWhenMuted')} />
418 407
419 {isMac && <Toggle field={form.$('showDragArea')} />} 408 <Hr />
420 409
421 <Hr /> 410 <Toggle field={form.$('scheduledDNDEnabled')} />
422 411 {scheduledDNDEnabled && (
423 {(isMac || isWindows) && <Toggle field={form.$('adaptableDarkMode')} />} 412 <>
424 {!((isMac || isWindows) && isAdaptableDarkModeEnabled) && <Toggle field={form.$('darkMode')} />} 413 <div style={{
425 {(isDarkmodeEnabled || isAdaptableDarkModeEnabled) && ( 414 display: 'flex',
426 <> 415 justifyContent: 'center',
427 <Toggle field={form.$('universalDarkMode')} /> 416 }}
417 >
418 <div style={{
419 padding: '0 1rem',
420 width: '100%',
421 }}
422 >
423 <Input
424 placeholder="17:00"
425 onChange={e => this.submit(e)}
426 field={form.$('scheduledDNDStart')}
427 type="time"
428 />
429 </div>
430 <div style={{
431 padding: '0 1rem',
432 width: '100%',
433 }}
434 >
435 <Input
436 placeholder="09:00"
437 onChange={e => this.submit(e)}
438 field={form.$('scheduledDNDEnd')}
439 type="time"
440 />
441 </div>
442 </div>
443 <p>
444 { intl.formatMessage(messages.scheduledDNDTimeInfo) }
445 </p>
446 </>
447 )}
428 <p 448 <p
429 className="settings__message" 449 className="settings__message"
430 style={{ 450 style={{
@@ -432,100 +452,138 @@ export default @observer class EditSettingsForm extends Component {
432 }} 452 }}
433 > 453 >
434 <span> 454 <span>
435 { intl.formatMessage(messages.universalDarkModeInfo) } 455 { intl.formatMessage(messages.scheduledDNDInfo) }
436 </span> 456 </span>
437 </p> 457 </p>
438 </> 458 </div>
439 )} 459 )}
440 460
441 <Hr /> 461 {/* Appearance */}
462 { this.state.activeSetttingsTab === 'appearance' && (
463 <div>
464 <Toggle field={form.$('showDisabledServices')} />
465 <Toggle field={form.$('showMessageBadgeWhenMuted')} />
466
467 {isMac && <Toggle field={form.$('showDragArea')} />}
468
469 <Hr />
470
471 {(isMac || isWindows) && <Toggle field={form.$('adaptableDarkMode')} />}
472 {!((isMac || isWindows) && isAdaptableDarkModeEnabled) && <Toggle field={form.$('darkMode')} />}
473 {(isDarkmodeEnabled || isAdaptableDarkModeEnabled) && (
474 <>
475 <Toggle field={form.$('universalDarkMode')} />
476 <p
477 className="settings__message"
478 style={{
479 borderTop: 0, marginTop: 0, paddingTop: 0, marginBottom: '2rem',
480 }}
481 >
482 <span>
483 { intl.formatMessage(messages.universalDarkModeInfo) }
484 </span>
485 </p>
486 </>
487 )}
442 488
443 <Select field={form.$('serviceRibbonWidth')} /> 489 <Hr />
444 490
445 <Select field={form.$('iconSize')} /> 491 <Select field={form.$('serviceRibbonWidth')} />
446 492
447 <Hr /> 493 <Select field={form.$('iconSize')} />
448 494
449 <Input 495 <Hr />
450 placeholder="Accent Color"
451 onChange={e => this.submit(e)}
452 field={form.$('accentColor')}
453 />
454 <p>{intl.formatMessage(messages.accentColorInfo)}</p>
455 496
456 {/* Language */} 497 <Input
457 <h2 id="language">{intl.formatMessage(messages.headlineLanguage)}</h2> 498 placeholder="Accent Color"
458 <Select field={form.$('locale')} showLabel={false} /> 499 onChange={e => this.submit(e)}
459 500 field={form.$('accentColor')}
460 <Hr />
461
462 <PremiumFeatureContainer
463 condition={!isSpellcheckerIncludedInCurrentPlan}
464 gaEventInfo={{ category: 'User', event: 'upgrade', label: 'spellchecker' }}
465 >
466 <Fragment>
467 <Toggle
468 field={form.$('enableSpellchecking')}
469 /> 501 />
470 {form.$('enableSpellchecking').value && ( 502 <p>{intl.formatMessage(messages.accentColorInfo)}</p>
471 <Select field={form.$('spellcheckerLanguage')} /> 503 </div>
472 )} 504 )}
473 </Fragment> 505
474 </PremiumFeatureContainer> 506 {/* Language */}
475 <a 507 { this.state.activeSetttingsTab === 'language' && (
476 href={FRANZ_TRANSLATION} 508 <div>
477 target="_blank" 509 <Select field={form.$('locale')} showLabel={false} />
478 className="link" 510
479 > 511 <Hr />
480 {intl.formatMessage(messages.translationHelp)} 512
481 {' '} 513 <PremiumFeatureContainer
482 <i className="mdi mdi-open-in-new" /> 514 condition={!isSpellcheckerIncludedInCurrentPlan}
483 </a> 515 gaEventInfo={{ category: 'User', event: 'upgrade', label: 'spellchecker' }}
516 >
517 <Fragment>
518 <Toggle
519 field={form.$('enableSpellchecking')}
520 />
521 {form.$('enableSpellchecking').value && (
522 <Select field={form.$('spellcheckerLanguage')} />
523 )}
524 </Fragment>
525 </PremiumFeatureContainer>
526 <a
527 href={FRANZ_TRANSLATION}
528 target="_blank"
529 className="link"
530 >
531 {intl.formatMessage(messages.translationHelp)}
532 {' '}
533 <i className="mdi mdi-open-in-new" />
534 </a>
535 </div>
536 )}
484 537
485 {/* Advanced */} 538 {/* Advanced */}
486 <h2 id="advanced">{intl.formatMessage(messages.headlineAdvanced)}</h2> 539 { this.state.activeSetttingsTab === 'advanced' && (
487 <Toggle field={form.$('enableGPUAcceleration')} /> 540 <div>
488 <p className="settings__help">{intl.formatMessage(messages.enableGPUAccelerationInfo)}</p> 541 <Toggle field={form.$('enableGPUAcceleration')} />
489 <div className="settings__settings-group"> 542 <p className="settings__help">{intl.formatMessage(messages.enableGPUAccelerationInfo)}</p>
490 <h3> 543 <div className="settings__settings-group">
491 {intl.formatMessage(messages.subheadlineCache)} 544 <h3>
492 </h3> 545 {intl.formatMessage(messages.subheadlineCache)}
493 <p> 546 </h3>
494 {intl.formatMessage(messages.cacheInfo, { 547 <p>
495 size: cacheSize, 548 {intl.formatMessage(messages.cacheInfo, {
496 })} 549 size: cacheSize,
497 </p> 550 })}
498 {notCleared && ( 551 </p>
499 <p> 552 {
500 {intl.formatMessage(messages.cacheNotCleared) 553 notCleared && (
501 } 554 <p>
502 </p> 555 {intl.formatMessage(messages.cacheNotCleared)}
503 )} 556 </p>
504 <p> 557 )
505 <Button 558 }
506 buttonType="secondary" 559 <p>
507 label={intl.formatMessage(messages.buttonClearAllCache)} 560 <Button
508 onClick={() => { onClearAllCache(); this.onClearCacheClicked(); }} 561 buttonType="secondary"
509 disabled={isClearingAllCache} 562 label={intl.formatMessage(messages.buttonClearAllCache)}
510 loaded={!isClearingAllCache} 563 onClick={() => { onClearAllCache(); this.onClearCacheClicked(); }}
511 /> 564 disabled={isClearingAllCache}
512 </p> 565 loaded={!isClearingAllCache}
513 <div style={{ 566 />
514 marginTop: 20, 567 </p>
515 }} 568 <div style={{
516 > 569 marginTop: 20,
517 <Button 570 }}
518 buttonType="secondary" 571 >
519 label="Open Process Manager" 572 <Button
520 onClick={openProcessManager} 573 buttonType="secondary"
521 /> 574 label="Open Process Manager"
575 onClick={openProcessManager}
576 />
577 </div>
578 </div>
522 </div> 579 </div>
523 </div> 580 )}
524 581
525 {/* Updates */} 582 {/* Updates */}
526 <h2 id="updates">{intl.formatMessage(messages.headlineUpdates)}</h2> 583 { this.state.activeSetttingsTab === 'updates' && (
527 <Toggle field={form.$('automaticUpdates')} /> 584 <div>
528 {automaticUpdates && ( 585 <Toggle field={form.$('automaticUpdates')} />
586 {automaticUpdates && (
529 <div> 587 <div>
530 <Toggle field={form.$('beta')} /> 588 <Toggle field={form.$('beta')} />
531 {updateIsReadyToInstall ? ( 589 {updateIsReadyToInstall ? (
@@ -544,37 +602,39 @@ export default @observer class EditSettingsForm extends Component {
544 )} 602 )}
545 <br /> 603 <br />
546 </div> 604 </div>
547 )} 605 )}
548 {intl.formatMessage(messages.currentVersion)} 606 {intl.formatMessage(messages.currentVersion)}
549 {' '} 607 {' '}
550 {remote.app.getVersion()} 608 {remote.app.getVersion()}
551 {noUpdateAvailable && ( 609 {noUpdateAvailable && (
552 <> 610 <>
553 <br /> 611 <br />
554 <br /> 612 <br />
555 {intl.formatMessage(messages.updateStatusUpToDate)} 613 {intl.formatMessage(messages.updateStatusUpToDate)}
556 </> 614 </>
557 ) 615 )
558 } 616 }
559 <p className="settings__message"> 617 <p className="settings__message">
560 <span className="mdi mdi-github-face" /> 618 <span className="mdi mdi-github-face" />
561 <span> 619 <span>
562 620
563 621
564 Ferdi is based on 622 Ferdi is based on
565 {' '} 623 {' '}
566 <a href="https://github.com/meetfranz/franz" target="_blank">Franz</a> 624 <a href="https://github.com/meetfranz/franz" target="_blank">Franz</a>
567 625
568 626
569 , a project published 627 , a project published
570 under the 628 under the
571 {' '} 629 {' '}
572 <a href="https://github.com/meetfranz/franz/blob/master/LICENSE" target="_blank">Apache-2.0 License</a> 630 <a href="https://github.com/meetfranz/franz/blob/master/LICENSE" target="_blank">Apache-2.0 License</a>
573 </span> 631 </span>
574 <br /> 632 <br />
575 <span className="mdi mdi-information" /> 633 <span className="mdi mdi-information" />
576 {intl.formatMessage(messages.languageDisclaimer)} 634 {intl.formatMessage(messages.languageDisclaimer)}
577 </p> 635 </p>
636 </div>
637 )}
578 </form> 638 </form>
579 </div> 639 </div>
580 </div> 640 </div>