aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Vijay Aravamudhan <vraravam@users.noreply.github.com>2022-11-07 06:50:40 +0530
committerLibravatar GitHub <noreply@github.com>2022-11-07 01:20:40 +0000
commit93a5de8d8e725cb6fff256a54544d39cf50a16f8 (patch)
tree6772686892a9e63e183109944c2845fcdeeb8939
parent6.2.1-nightly.40 [skip ci] (diff)
downloadferdium-app-93a5de8d8e725cb6fff256a54544d39cf50a16f8.tar.gz
ferdium-app-93a5de8d8e725cb6fff256a54544d39cf50a16f8.tar.zst
ferdium-app-93a5de8d8e725cb6fff256a54544d39cf50a16f8.zip
Revert "Remove duplicated Toggle.js component" (#742)
Revert "Remove duplicated Toggle.js component (#741)" This reverts commit dd238ae7949e72e3b90235f56e14686cc5231f34.
-rw-r--r--src/components/auth/Import.js2
-rw-r--r--src/components/settings/services/EditServiceForm.js28
-rw-r--r--src/components/settings/settings/EditSettingsForm.tsx92
-rw-r--r--src/components/ui/Toggle.js72
-rw-r--r--src/components/ui/toggle/index.tsx56
-rw-r--r--src/features/workspaces/components/EditWorkspaceForm.js2
-rw-r--r--src/features/workspaces/components/WorkspaceServiceListItem.tsx26
-rw-r--r--src/lib/Tray.ts36
8 files changed, 193 insertions, 121 deletions
diff --git a/src/components/auth/Import.js b/src/components/auth/Import.js
index 93ca124db..41b887974 100644
--- a/src/components/auth/Import.js
+++ b/src/components/auth/Import.js
@@ -97,7 +97,7 @@ class Import extends Component {
97 {this.form.$('import').map((service, i) => ( 97 {this.form.$('import').map((service, i) => (
98 <tr key={service.id} className="service-table__row"> 98 <tr key={service.id} className="service-table__row">
99 <td className="service-table__toggle"> 99 <td className="service-table__toggle">
100 <Toggle {...service.$('add').bind()} showLabel={false} /> 100 <Toggle field={service.$('add')} showLabel={false} />
101 </td> 101 </td>
102 <td className="service-table__column-icon"> 102 <td className="service-table__column-icon">
103 <img 103 <img
diff --git a/src/components/settings/services/EditServiceForm.js b/src/components/settings/services/EditServiceForm.js
index 30a78c807..eeb9ef54d 100644
--- a/src/components/settings/services/EditServiceForm.js
+++ b/src/components/settings/services/EditServiceForm.js
@@ -342,22 +342,22 @@ class EditServiceForm extends Component {
342 <div className="settings__options"> 342 <div className="settings__options">
343 <div className="settings__settings-group"> 343 <div className="settings__settings-group">
344 <H3>{intl.formatMessage(messages.headlineNotifications)}</H3> 344 <H3>{intl.formatMessage(messages.headlineNotifications)}</H3>
345 <Toggle {...form.$('isNotificationEnabled').bind()} /> 345 <Toggle field={form.$('isNotificationEnabled')} />
346 <Toggle {...form.$('isMuted').bind()} /> 346 <Toggle field={form.$('isMuted')} />
347 <p className="settings__help indented__help"> 347 <p className="settings__help indented__help">
348 {intl.formatMessage(messages.isMutedInfo)} 348 {intl.formatMessage(messages.isMutedInfo)}
349 </p> 349 </p>
350 <Toggle {...form.$('isMediaBadgeEnabled').bind()} /> 350 <Toggle field={form.$('isMediaBadgeEnabled')} />
351 </div> 351 </div>
352 352
353 <div className="settings__settings-group"> 353 <div className="settings__settings-group">
354 <H3>{intl.formatMessage(messages.headlineBadges)}</H3> 354 <H3>{intl.formatMessage(messages.headlineBadges)}</H3>
355 <Toggle {...form.$('isBadgeEnabled').bind()} /> 355 <Toggle field={form.$('isBadgeEnabled')} />
356 {recipe.hasIndirectMessages && 356 {recipe.hasIndirectMessages &&
357 form.$('isBadgeEnabled').value && ( 357 form.$('isBadgeEnabled').value && (
358 <> 358 <>
359 <Toggle 359 <Toggle
360 {...form.$('isIndirectMessageBadgeEnabled').bind()} 360 field={form.$('isIndirectMessageBadgeEnabled')}
361 /> 361 />
362 <p className="settings__help indented__help"> 362 <p className="settings__help indented__help">
363 {intl.formatMessage(messages.indirectMessageInfo)} 363 {intl.formatMessage(messages.indirectMessageInfo)}
@@ -365,21 +365,19 @@ class EditServiceForm extends Component {
365 </> 365 </>
366 )} 366 )}
367 {recipe.allowFavoritesDelineationInUnreadCount && ( 367 {recipe.allowFavoritesDelineationInUnreadCount && (
368 <Toggle 368 <Toggle field={form.$('onlyShowFavoritesInUnreadCount')} />
369 {...form.$('onlyShowFavoritesInUnreadCount').bind()}
370 />
371 )} 369 )}
372 </div> 370 </div>
373 371
374 <div className="settings__settings-group"> 372 <div className="settings__settings-group">
375 <H3>{intl.formatMessage(messages.headlineGeneral)}</H3> 373 <H3>{intl.formatMessage(messages.headlineGeneral)}</H3>
376 <Toggle {...form.$('isEnabled').bind()} /> 374 <Toggle field={form.$('isEnabled')} />
377 <Toggle {...form.$('isHibernationEnabled').bind()} /> 375 <Toggle field={form.$('isHibernationEnabled')} />
378 <p className="settings__help indented__help"> 376 <p className="settings__help indented__help">
379 {intl.formatMessage(messages.isHibernationEnabledInfo)} 377 {intl.formatMessage(messages.isHibernationEnabledInfo)}
380 </p> 378 </p>
381 <Toggle {...form.$('isWakeUpEnabled').bind()} /> 379 <Toggle field={form.$('isWakeUpEnabled')} />
382 <Toggle {...form.$('trapLinkClicks').bind()} /> 380 <Toggle field={form.$('trapLinkClicks')} />
383 {/* TODO: Need to figure out how to effect this change without a reload of the recipe */} 381 {/* TODO: Need to figure out how to effect this change without a reload of the recipe */}
384 <p className="settings__help indented__help"> 382 <p className="settings__help indented__help">
385 {intl.formatMessage(messages.serviceReloadRequired)} 383 {intl.formatMessage(messages.serviceReloadRequired)}
@@ -388,7 +386,7 @@ class EditServiceForm extends Component {
388 386
389 <div className="settings__settings-group"> 387 <div className="settings__settings-group">
390 <H3>{intl.formatMessage(messages.headlineAppearance)}</H3> 388 <H3>{intl.formatMessage(messages.headlineAppearance)}</H3>
391 <Toggle {...form.$('isDarkModeEnabled').bind()} /> 389 <Toggle field={form.$('isDarkModeEnabled')} />
392 {form.$('isDarkModeEnabled').value && ( 390 {form.$('isDarkModeEnabled').value && (
393 <> 391 <>
394 <H3> 392 <H3>
@@ -401,7 +399,7 @@ class EditServiceForm extends Component {
401 <Slider field={form.$('darkReaderSepia')} /> 399 <Slider field={form.$('darkReaderSepia')} />
402 </> 400 </>
403 )} 401 )}
404 <Toggle {...form.$('isProgressbarEnabled').bind()} /> 402 <Toggle field={form.$('isProgressbarEnabled')} />
405 </div> 403 </div>
406 </div> 404 </div>
407 <div className="service-icon"> 405 <div className="service-icon">
@@ -431,7 +429,7 @@ class EditServiceForm extends Component {
431 {intl.formatMessage(messages.headlineProxy)} 429 {intl.formatMessage(messages.headlineProxy)}
432 <span className="badge badge--success">beta</span> 430 <span className="badge badge--success">beta</span>
433 </H3> 431 </H3>
434 <Toggle {...form.$('proxy.isEnabled').bind()} /> 432 <Toggle field={form.$('proxy.isEnabled')} />
435 {form.$('proxy.isEnabled').value && ( 433 {form.$('proxy.isEnabled').value && (
436 <> 434 <>
437 <div className="grid"> 435 <div className="grid">
diff --git a/src/components/settings/settings/EditSettingsForm.tsx b/src/components/settings/settings/EditSettingsForm.tsx
index e796a48ec..1d89b53a9 100644
--- a/src/components/settings/settings/EditSettingsForm.tsx
+++ b/src/components/settings/settings/EditSettingsForm.tsx
@@ -6,7 +6,7 @@ import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl';
6import { mdiGithub, mdiOpenInNew, mdiPowerPlug } from '@mdi/js'; 6import { mdiGithub, mdiOpenInNew, mdiPowerPlug } from '@mdi/js';
7import Form from '../../../lib/Form'; 7import Form from '../../../lib/Form';
8import Button from '../../ui/button'; 8import Button from '../../ui/button';
9import Toggle from '../../ui/toggle'; 9import Toggle from '../../ui/Toggle.js';
10import Select from '../../ui/Select'; 10import Select from '../../ui/Select';
11import Input from '../../ui/input/index'; 11import Input from '../../ui/input/index';
12import ColorPickerInput from '../../ui/ColorPickerInput'; 12import ColorPickerInput from '../../ui/ColorPickerInput';
@@ -522,30 +522,26 @@ class EditSettingsForm extends Component<IProps, IState> {
522 <H2 className="settings__section_header"> 522 <H2 className="settings__section_header">
523 {intl.formatMessage(messages.sectionMain)} 523 {intl.formatMessage(messages.sectionMain)}
524 </H2> 524 </H2>
525 <Toggle {...form.$('autoLaunchOnStart').bind()} /> 525 <Toggle field={form.$('autoLaunchOnStart')} />
526 <Toggle {...form.$('runInBackground').bind()} /> 526 <Toggle field={form.$('runInBackground')} />
527 <Toggle {...form.$('confirmOnQuit').bind()} /> 527 <Toggle field={form.$('confirmOnQuit')} />
528 <Toggle {...form.$('enableSystemTray').bind()} /> 528 <Toggle field={form.$('enableSystemTray')} />
529 {reloadAfterResume && <Hr />} 529 {reloadAfterResume && <Hr />}
530 <Toggle {...form.$('reloadAfterResume').bind()} /> 530 <Toggle field={form.$('reloadAfterResume')} />
531 {reloadAfterResume && ( 531 {reloadAfterResume && (
532 <div> 532 <div>
533 <Input {...form.$('reloadAfterResumeTime').bind()} /> 533 <Input {...form.$('reloadAfterResumeTime').bind()} />
534 <Hr /> 534 <Hr />
535 </div> 535 </div>
536 )} 536 )}
537 <Toggle {...form.$('startMinimized').bind()} /> 537 <Toggle field={form.$('startMinimized')} />
538 {isWindows && ( 538 {isWindows && <Toggle field={form.$('minimizeToSystemTray')} />}
539 <Toggle {...form.$('minimizeToSystemTray').bind()} /> 539 {isWindows && <Toggle field={form.$('closeToSystemTray')} />}
540 )}
541 {isWindows && (
542 <Toggle {...form.$('closeToSystemTray').bind()} />
543 )}
544 540
545 <Toggle {...form.$('keepAllWorkspacesLoaded').bind()} /> 541 <Toggle field={form.$('keepAllWorkspacesLoaded')} />
546 542
547 {isTodosActivated && <Hr />} 543 {isTodosActivated && <Hr />}
548 <Toggle {...form.$('enableTodos').bind()} /> 544 <Toggle field={form.$('enableTodos')} />
549 {isTodosActivated && ( 545 {isTodosActivated && (
550 <div> 546 <div>
551 <Select field={form.$('predefinedTodoServer')} /> 547 <Select field={form.$('predefinedTodoServer')} />
@@ -575,7 +571,7 @@ class EditSettingsForm extends Component<IProps, IState> {
575 {isTodosActivated && <Hr />} 571 {isTodosActivated && <Hr />}
576 572
577 {scheduledDNDEnabled && <Hr />} 573 {scheduledDNDEnabled && <Hr />}
578 <Toggle {...form.$('scheduledDNDEnabled').bind()} /> 574 <Toggle field={form.$('scheduledDNDEnabled')} />
579 575
580 {scheduledDNDEnabled && ( 576 {scheduledDNDEnabled && (
581 <> 577 <>
@@ -636,12 +632,12 @@ class EditSettingsForm extends Component<IProps, IState> {
636 {intl.formatMessage(messages.sectionServiceIconsSettings)} 632 {intl.formatMessage(messages.sectionServiceIconsSettings)}
637 </H2> 633 </H2>
638 634
639 <Toggle {...form.$('showDisabledServices').bind()} /> 635 <Toggle field={form.$('showDisabledServices')} />
640 <Toggle {...form.$('showServiceName').bind()} /> 636 <Toggle field={form.$('showServiceName')} />
641 637
642 {isUseGrayscaleServicesEnabled && <Hr />} 638 {isUseGrayscaleServicesEnabled && <Hr />}
643 639
644 <Toggle {...form.$('useGrayscaleServices').bind()} /> 640 <Toggle field={form.$('useGrayscaleServices')} />
645 641
646 {isUseGrayscaleServicesEnabled && ( 642 {isUseGrayscaleServicesEnabled && (
647 <> 643 <>
@@ -654,8 +650,8 @@ class EditSettingsForm extends Component<IProps, IState> {
654 </> 650 </>
655 )} 651 )}
656 652
657 <Toggle {...form.$('showMessageBadgeWhenMuted').bind()} /> 653 <Toggle field={form.$('showMessageBadgeWhenMuted')} />
658 <Toggle {...form.$('enableLongPressServiceHint').bind()} /> 654 <Toggle field={form.$('enableLongPressServiceHint')} />
659 <Select field={form.$('iconSize')} /> 655 <Select field={form.$('iconSize')} />
660 656
661 <Select field={form.$('navigationBarBehaviour')} /> 657 <Select field={form.$('navigationBarBehaviour')} />
@@ -666,7 +662,7 @@ class EditSettingsForm extends Component<IProps, IState> {
666 {intl.formatMessage(messages.sectionHibernation)} 662 {intl.formatMessage(messages.sectionHibernation)}
667 </H2> 663 </H2>
668 <Select field={form.$('hibernationStrategy')} /> 664 <Select field={form.$('hibernationStrategy')} />
669 <Toggle {...form.$('hibernateOnStartup').bind()} /> 665 <Toggle field={form.$('hibernateOnStartup')} />
670 <p 666 <p
671 className="settings__message" 667 className="settings__message"
672 style={{ 668 style={{
@@ -681,7 +677,7 @@ class EditSettingsForm extends Component<IProps, IState> {
681 677
682 <Select field={form.$('wakeUpStrategy')} /> 678 <Select field={form.$('wakeUpStrategy')} />
683 <Select field={form.$('wakeUpHibernationStrategy')} /> 679 <Select field={form.$('wakeUpHibernationStrategy')} />
684 <Toggle {...form.$('wakeUpHibernationSplay').bind()} /> 680 <Toggle field={form.$('wakeUpHibernationSplay')} />
685 </div> 681 </div>
686 )} 682 )}
687 683
@@ -691,15 +687,15 @@ class EditSettingsForm extends Component<IProps, IState> {
691 <H2 className="settings__section_header"> 687 <H2 className="settings__section_header">
692 {intl.formatMessage(messages.sectionGeneralUi)} 688 {intl.formatMessage(messages.sectionGeneralUi)}
693 </H2> 689 </H2>
694 {isMac && <Toggle {...form.$('showDragArea').bind()} />} 690 {isMac && <Toggle field={form.$('showDragArea')} />}
695 691
696 <Toggle {...form.$('adaptableDarkMode').bind()} /> 692 <Toggle field={form.$('adaptableDarkMode')} />
697 {!isAdaptableDarkModeEnabled && ( 693 {!isAdaptableDarkModeEnabled && (
698 <Toggle {...form.$('darkMode').bind()} /> 694 <Toggle field={form.$('darkMode')} />
699 )} 695 )}
700 {(isDarkmodeEnabled || isAdaptableDarkModeEnabled) && ( 696 {(isDarkmodeEnabled || isAdaptableDarkModeEnabled) && (
701 <> 697 <>
702 <Toggle {...form.$('universalDarkMode').bind()} /> 698 <Toggle field={form.$('universalDarkMode')} />
703 <p 699 <p
704 className="settings__message" 700 className="settings__message"
705 style={{ 701 style={{
@@ -717,7 +713,7 @@ class EditSettingsForm extends Component<IProps, IState> {
717 )} 713 )}
718 714
719 {isSplitModeEnabled && <Hr />} 715 {isSplitModeEnabled && <Hr />}
720 <Toggle {...form.$('splitMode').bind()} /> 716 <Toggle field={form.$('splitMode')} />
721 {isSplitModeEnabled && ( 717 {isSplitModeEnabled && (
722 <Input 718 <Input
723 type="number" 719 type="number"
@@ -780,21 +776,21 @@ class EditSettingsForm extends Component<IProps, IState> {
780 776
781 <Select field={form.$('sidebarServicesLocation')} /> 777 <Select field={form.$('sidebarServicesLocation')} />
782 778
783 <Toggle {...form.$('useHorizontalStyle').bind()} /> 779 <Toggle field={form.$('useHorizontalStyle')} />
784 780
785 <Toggle {...form.$('hideCollapseButton').bind()} /> 781 <Toggle field={form.$('hideCollapseButton')} />
786 782
787 <Toggle {...form.$('hideRecipesButton').bind()} /> 783 <Toggle field={form.$('hideRecipesButton')} />
788 784
789 <Toggle {...form.$('hideSplitModeButton').bind()} /> 785 <Toggle field={form.$('hideSplitModeButton')} />
790 786
791 <Toggle {...form.$('hideWorkspacesButton').bind()} /> 787 <Toggle field={form.$('hideWorkspacesButton')} />
792 788
793 <Toggle {...form.$('hideNotificationsButton').bind()} /> 789 <Toggle field={form.$('hideNotificationsButton')} />
794 790
795 <Toggle {...form.$('hideSettingsButton').bind()} /> 791 <Toggle field={form.$('hideSettingsButton')} />
796 792
797 <Toggle {...form.$('alwaysShowWorkspaces').bind()} /> 793 <Toggle field={form.$('alwaysShowWorkspaces')} />
798 </div> 794 </div>
799 )} 795 )}
800 796
@@ -805,17 +801,17 @@ class EditSettingsForm extends Component<IProps, IState> {
805 {intl.formatMessage(messages.sectionPrivacy)} 801 {intl.formatMessage(messages.sectionPrivacy)}
806 </H2> 802 </H2>
807 803
808 <Toggle {...form.$('privateNotifications').bind()} /> 804 <Toggle field={form.$('privateNotifications')} />
809 <Toggle {...form.$('clipboardNotifications').bind()} /> 805 <Toggle field={form.$('clipboardNotifications')} />
810 {(isWindows || isMac) && ( 806 {(isWindows || isMac) && (
811 <Toggle {...form.$('notifyTaskBarOnMessage').bind()} /> 807 <Toggle field={form.$('notifyTaskBarOnMessage')} />
812 )} 808 )}
813 809
814 <Hr /> 810 <Hr />
815 811
816 <Select field={form.$('webRTCIPHandlingPolicy')} /> 812 <Select field={form.$('webRTCIPHandlingPolicy')} />
817 813
818 <Toggle {...form.$('sentry').bind()} /> 814 <Toggle field={form.$('sentry')} />
819 <p className="settings__help"> 815 <p className="settings__help">
820 {intl.formatMessage(messages.sentryInfo)} 816 {intl.formatMessage(messages.sentryInfo)}
821 </p> 817 </p>
@@ -834,11 +830,11 @@ class EditSettingsForm extends Component<IProps, IState> {
834 830
835 <Hr /> 831 <Hr />
836 832
837 <Toggle {...form.$('lockingFeatureEnabled').bind()} /> 833 <Toggle field={form.$('lockingFeatureEnabled')} />
838 {lockingFeatureEnabled && ( 834 {lockingFeatureEnabled && (
839 <> 835 <>
840 {isMac && systemPreferences.canPromptTouchID() && ( 836 {isMac && systemPreferences.canPromptTouchID() && (
841 <Toggle {...form.$('useTouchIdToUnlock').bind()} /> 837 <Toggle field={form.$('useTouchIdToUnlock')} />
842 )} 838 )}
843 839
844 <Input 840 <Input
@@ -889,7 +885,7 @@ class EditSettingsForm extends Component<IProps, IState> {
889 885
890 <Hr /> 886 <Hr />
891 887
892 <Toggle {...form.$('enableSpellchecking').bind()} /> 888 <Toggle field={form.$('enableSpellchecking')} />
893 {!isMac && form.$('enableSpellchecking').value && ( 889 {!isMac && form.$('enableSpellchecking').value && (
894 <Select field={form.$('spellcheckerLanguage')} /> 890 <Select field={form.$('spellcheckerLanguage')} />
895 )} 891 )}
@@ -905,7 +901,7 @@ class EditSettingsForm extends Component<IProps, IState> {
905 901
906 <Hr /> 902 <Hr />
907 903
908 <Toggle {...form.$('enableTranslator').bind()} /> 904 <Toggle field={form.$('enableTranslator')} />
909 905
910 {form.$('enableTranslator').value && ( 906 {form.$('enableTranslator').value && (
911 <Select field={form.$('translatorEngine')} /> 907 <Select field={form.$('translatorEngine')} />
@@ -935,8 +931,8 @@ class EditSettingsForm extends Component<IProps, IState> {
935 {intl.formatMessage(messages.sectionAdvanced)} 931 {intl.formatMessage(messages.sectionAdvanced)}
936 </H2> 932 </H2>
937 933
938 <Toggle {...form.$('enableGPUAcceleration').bind()} /> 934 <Toggle field={form.$('enableGPUAcceleration')} />
939 <Toggle {...form.$('enableGlobalHideShortcut').bind()} /> 935 <Toggle field={form.$('enableGlobalHideShortcut')} />
940 <p className="settings__help indented__help"> 936 <p className="settings__help indented__help">
941 {intl.formatMessage(messages.appRestartRequired)} 937 {intl.formatMessage(messages.appRestartRequired)}
942 </p> 938 </p>
@@ -1040,12 +1036,12 @@ class EditSettingsForm extends Component<IProps, IState> {
1040 {intl.formatMessage(messages.sectionUpdates)} 1036 {intl.formatMessage(messages.sectionUpdates)}
1041 </H2> 1037 </H2>
1042 1038
1043 <Toggle {...form.$('automaticUpdates').bind()} /> 1039 <Toggle field={form.$('automaticUpdates')} />
1044 {automaticUpdates && ( 1040 {automaticUpdates && (
1045 <> 1041 <>
1046 <> 1042 <>
1047 <div> 1043 <div>
1048 <Toggle {...form.$('beta').bind()} /> 1044 <Toggle field={form.$('beta')} />
1049 {updateIsReadyToInstall ? ( 1045 {updateIsReadyToInstall ? (
1050 <Button 1046 <Button
1051 label={intl.formatMessage( 1047 label={intl.formatMessage(
diff --git a/src/components/ui/Toggle.js b/src/components/ui/Toggle.js
new file mode 100644
index 000000000..c1d86a7f6
--- /dev/null
+++ b/src/components/ui/Toggle.js
@@ -0,0 +1,72 @@
1import { Component } from 'react';
2import PropTypes from 'prop-types';
3import { observer } from 'mobx-react';
4import classnames from 'classnames';
5import { Field } from 'mobx-react-form';
6
7// Can this file be merged into the './toggle/index.tsx' file?
8class Toggle extends Component {
9 static propTypes = {
10 field: PropTypes.instanceOf(Field).isRequired,
11 className: PropTypes.string,
12 showLabel: PropTypes.bool,
13 disabled: PropTypes.bool,
14 };
15
16 static defaultProps = {
17 className: '',
18 showLabel: true,
19 disabled: false,
20 };
21
22 onChange(e) {
23 const { field } = this.props;
24
25 field.onChange(e);
26 }
27
28 render() {
29 const { field, className, showLabel, disabled } = this.props;
30
31 if (field.value === '' && field.default !== '') {
32 field.value = field.default;
33 }
34
35 return (
36 <div
37 className={classnames([
38 'franz-form__field',
39 'franz-form__toggle-wrapper',
40 'franz-form__toggle-disabled',
41 className,
42 ])}
43 >
44 <label
45 htmlFor={field.id}
46 className={classnames({
47 'franz-form__toggle': true,
48 'is-active': field.value,
49 })}
50 >
51 <div className="franz-form__toggle-button" />
52 <input
53 type="checkbox"
54 id={field.id}
55 name={field.name}
56 value={field.name}
57 checked={field.value}
58 onChange={e => (!disabled ? this.onChange(e) : null)}
59 />
60 </label>
61 {field.error && <div className={field.error}>{field.error}</div>}
62 {field.label && showLabel && (
63 <label className="franz-form__label" htmlFor={field.id}>
64 {field.label}
65 </label>
66 )}
67 </div>
68 );
69 }
70}
71
72export default observer(Toggle);
diff --git a/src/components/ui/toggle/index.tsx b/src/components/ui/toggle/index.tsx
index fee8adbc7..d478cbba5 100644
--- a/src/components/ui/toggle/index.tsx
+++ b/src/components/ui/toggle/index.tsx
@@ -1,26 +1,27 @@
1import classnames from 'classnames'; 1import classnames from 'classnames';
2import { Property } from 'csstype'; 2import { Property } from 'csstype';
3import { noop } from 'lodash';
4import { Component, InputHTMLAttributes } from 'react'; 3import { Component, InputHTMLAttributes } from 'react';
5import withStyles, { WithStylesProps } from 'react-jss'; 4import injectStyle, { WithStylesProps } from 'react-jss';
5
6import { Theme } from '../../../themes'; 6import { Theme } from '../../../themes';
7import { IFormField } from '../typings/generic';
8
7import Error from '../error'; 9import Error from '../error';
8import Label from '../label'; 10import Label from '../label';
9import { IFormField } from '../typings/generic';
10import Wrapper from '../wrapper'; 11import Wrapper from '../wrapper';
11 12
12interface IProps 13interface IProps
13 extends Omit<InputHTMLAttributes<HTMLInputElement>, 'value'>, 14 extends InputHTMLAttributes<HTMLInputElement>,
14 IFormField, 15 IFormField,
15 WithStylesProps<typeof styles> { 16 WithStylesProps<typeof styles> {
16 className?: string; 17 className?: string;
17 value: boolean | undefined; // due to type capability between InputHTMLAttributes and mobx-react-form
18} 18}
19 19
20const buttonTransition: string = 20let buttonTransition: string = 'none';
21 window && window.matchMedia('(prefers-reduced-motion: no-preference)') 21
22 ? 'all .5s' 22if (window && window.matchMedia('(prefers-reduced-motion: no-preference)')) {
23 : 'none'; 23 buttonTransition = 'all .5s';
24}
24 25
25const styles = (theme: Theme) => ({ 26const styles = (theme: Theme) => ({
26 toggle: { 27 toggle: {
@@ -63,18 +64,25 @@ const styles = (theme: Theme) => ({
63}); 64});
64 65
65class ToggleComponent extends Component<IProps> { 66class ToggleComponent extends Component<IProps> {
67 public static defaultProps = {
68 onChange: () => {},
69 showLabel: true,
70 disabled: false,
71 error: '',
72 };
73
66 render() { 74 render() {
67 const { 75 const {
68 classes, 76 classes,
69 className, 77 className,
70 id = '', 78 disabled,
71 name = '', 79 error,
72 label = '', 80 id,
73 error = '', 81 label,
74 value = false, 82 showLabel,
75 showLabel = true, 83 checked,
76 disabled = false, 84 value,
77 onChange = noop, 85 onChange,
78 } = this.props; 86 } = this.props;
79 87
80 return ( 88 return (
@@ -94,24 +102,24 @@ class ToggleComponent extends Component<IProps> {
94 <div 102 <div
95 className={classnames({ 103 className={classnames({
96 [`${classes.button}`]: true, 104 [`${classes.button}`]: true,
97 [`${classes.buttonActive}`]: value, 105 [`${classes.buttonActive}`]: checked,
98 })} 106 })}
99 /> 107 />
100 <input 108 <input
101 type="checkbox"
102 id={id}
103 name={name}
104 checked={value as boolean | undefined}
105 className={classes.input} 109 className={classes.input}
110 id={id}
111 type="checkbox"
112 checked={checked}
113 value={value}
106 onChange={onChange} 114 onChange={onChange}
107 disabled={disabled} 115 disabled={disabled}
108 /> 116 />
109 </div> 117 </div>
110 </Label> 118 </Label>
111 {error ? <Error message={error as string} /> : null} 119 {error && <Error message={error} />}
112 </Wrapper> 120 </Wrapper>
113 ); 121 );
114 } 122 }
115} 123}
116 124
117export default withStyles(styles, { injectTheme: true })(ToggleComponent); 125export default injectStyle(styles, { injectTheme: true })(ToggleComponent);
diff --git a/src/features/workspaces/components/EditWorkspaceForm.js b/src/features/workspaces/components/EditWorkspaceForm.js
index 509df97e6..6bc9ae6f0 100644
--- a/src/features/workspaces/components/EditWorkspaceForm.js
+++ b/src/features/workspaces/components/EditWorkspaceForm.js
@@ -176,7 +176,7 @@ class EditWorkspaceForm extends Component {
176 )} 176 )}
177 <div className={classes.nameInput}> 177 <div className={classes.nameInput}>
178 <Input {...form.$('name').bind()} /> 178 <Input {...form.$('name').bind()} />
179 <Toggle {...form.$('keepLoaded').bind()} /> 179 <Toggle field={form.$('keepLoaded')} />
180 <p className={`${classes.keepLoadedInfo} franz-form__label`}> 180 <p className={`${classes.keepLoadedInfo} franz-form__label`}>
181 {intl.formatMessage(messages.keepLoadedInfo)} 181 {intl.formatMessage(messages.keepLoadedInfo)}
182 </p> 182 </p>
diff --git a/src/features/workspaces/components/WorkspaceServiceListItem.tsx b/src/features/workspaces/components/WorkspaceServiceListItem.tsx
index 420aed595..0233d5749 100644
--- a/src/features/workspaces/components/WorkspaceServiceListItem.tsx
+++ b/src/features/workspaces/components/WorkspaceServiceListItem.tsx
@@ -1,10 +1,10 @@
1import { Component, ReactElement } from 'react'; 1import { Component } from 'react';
2import { observer } from 'mobx-react'; 2import { observer } from 'mobx-react';
3import withStyles, { WithStylesProps } from 'react-jss'; 3import injectSheet from 'react-jss';
4import classnames from 'classnames'; 4import classnames from 'classnames';
5import Toggle from '../../../components/ui/toggle'; 5
6import Toggle from '../../../components/ui/toggle/index';
6import ServiceIcon from '../../../components/ui/ServiceIcon'; 7import ServiceIcon from '../../../components/ui/ServiceIcon';
7import Service from '../../../models/Service';
8 8
9const styles = theme => ({ 9const styles = theme => ({
10 listItem: { 10 listItem: {
@@ -29,15 +29,15 @@ const styles = theme => ({
29 }, 29 },
30}); 30});
31 31
32interface IProps extends WithStylesProps<typeof styles> { 32type Props = {
33 classes: any;
33 isInWorkspace: boolean; 34 isInWorkspace: boolean;
34 onToggle: () => void; 35 onToggle: () => void;
35 service: Service; 36 service: any;
36} 37};
37 38
38@observer 39class WorkspaceServiceListItem extends Component<Props> {
39class WorkspaceServiceListItem extends Component<IProps> { 40 render() {
40 render(): ReactElement {
41 const { classes, isInWorkspace, onToggle, service } = this.props; 41 const { classes, isInWorkspace, onToggle, service } = this.props;
42 42
43 return ( 43 return (
@@ -53,7 +53,7 @@ class WorkspaceServiceListItem extends Component<IProps> {
53 </span> 53 </span>
54 <Toggle 54 <Toggle
55 className={classes.toggle} 55 className={classes.toggle}
56 value={isInWorkspace} 56 checked={isInWorkspace}
57 onChange={onToggle} 57 onChange={onToggle}
58 /> 58 />
59 </div> 59 </div>
@@ -61,6 +61,6 @@ class WorkspaceServiceListItem extends Component<IProps> {
61 } 61 }
62} 62}
63 63
64export default withStyles(styles, { injectTheme: true })( 64export default injectSheet(styles, { injectTheme: true })(
65 WorkspaceServiceListItem, 65 observer(WorkspaceServiceListItem),
66); 66);
diff --git a/src/lib/Tray.ts b/src/lib/Tray.ts
index dafbb68aa..8e489edde 100644
--- a/src/lib/Tray.ts
+++ b/src/lib/Tray.ts
@@ -20,7 +20,7 @@ const INDICATOR_TRAY_INDIRECT = 'tray-indirect';
20 20
21// TODO: Need to support i18n for a lot of the hard-coded strings in this file 21// TODO: Need to support i18n for a lot of the hard-coded strings in this file
22export default class TrayIcon { 22export default class TrayIcon {
23 tray: Tray | null = null; 23 trayIcon: Tray | null = null;
24 24
25 indicator: string | number = 0; 25 indicator: string | number = 0;
26 26
@@ -97,9 +97,7 @@ export default class TrayIcon {
97 } 97 }
98 98
99 _updateTrayMenu(appSettings): void { 99 _updateTrayMenu(appSettings): void {
100 if (!this.tray) { 100 if (!this.trayIcon) return;
101 return;
102 }
103 101
104 if (appSettings && appSettings.type === 'app') { 102 if (appSettings && appSettings.type === 'app') {
105 this.isAppMuted = appSettings.data.isAppMuted; // save current state after a change 103 this.isAppMuted = appSettings.data.isAppMuted; // save current state after a change
@@ -107,7 +105,7 @@ export default class TrayIcon {
107 105
108 this.trayMenu = Menu.buildFromTemplate(this.trayMenuTemplate(this)); 106 this.trayMenu = Menu.buildFromTemplate(this.trayMenuTemplate(this));
109 if (isLinux) { 107 if (isLinux) {
110 this.tray.setContextMenu(this.trayMenu); 108 this.trayIcon.setContextMenu(this.trayMenu);
111 } 109 }
112 } 110 }
113 111
@@ -117,26 +115,26 @@ export default class TrayIcon {
117 } 115 }
118 116
119 _show(): void { 117 _show(): void {
120 if (this.tray) { 118 if (this.trayIcon) {
121 return; 119 return;
122 } 120 }
123 121
124 this.tray = new Tray(this._getAsset('tray', INDICATOR_TRAY_PLAIN)); 122 this.trayIcon = new Tray(this._getAsset('tray', INDICATOR_TRAY_PLAIN));
125 this.tray.setToolTip('Ferdium'); 123 this.trayIcon.setToolTip('Ferdium');
126 124
127 this.trayMenu = Menu.buildFromTemplate(this.trayMenuTemplate(this)); 125 this.trayMenu = Menu.buildFromTemplate(this.trayMenuTemplate(this));
128 if (isLinux) { 126 if (isLinux) {
129 this.tray.setContextMenu(this.trayMenu); 127 this.trayIcon.setContextMenu(this.trayMenu);
130 } 128 }
131 129
132 this.tray.on('click', () => { 130 this.trayIcon.on('click', () => {
133 this._toggleWindow(); 131 this._toggleWindow();
134 }); 132 });
135 133
136 if (isMac || isWindows) { 134 if (isMac || isWindows) {
137 this.tray.on('right-click', () => { 135 this.trayIcon.on('right-click', () => {
138 if (this.tray && this.trayMenu) { 136 if (this.trayIcon && this.trayMenu) {
139 this.tray.popUpContextMenu(this.trayMenu); 137 this.trayIcon.popUpContextMenu(this.trayMenu);
140 } 138 }
141 }); 139 });
142 } 140 }
@@ -179,10 +177,10 @@ export default class TrayIcon {
179 } 177 }
180 178
181 _hide(): void { 179 _hide(): void {
182 if (!this.tray) return; 180 if (!this.trayIcon) return;
183 181
184 this.tray.destroy(); 182 this.trayIcon.destroy();
185 this.tray = null; 183 this.trayIcon = null;
186 184
187 if (isMac && this.themeChangeSubscriberId) { 185 if (isMac && this.themeChangeSubscriberId) {
188 systemPreferences.unsubscribeNotification(this.themeChangeSubscriberId); 186 systemPreferences.unsubscribeNotification(this.themeChangeSubscriberId);
@@ -218,16 +216,16 @@ export default class TrayIcon {
218 } 216 }
219 217
220 _refreshIcon(): void { 218 _refreshIcon(): void {
221 if (!this.tray) { 219 if (!this.trayIcon) {
222 return; 220 return;
223 } 221 }
224 222
225 this.tray.setImage( 223 this.trayIcon.setImage(
226 this._getAsset('tray', this._getAssetFromIndicator(this.indicator)), 224 this._getAsset('tray', this._getAssetFromIndicator(this.indicator)),
227 ); 225 );
228 226
229 if (isMac && !macosVersion.isGreaterThanOrEqualTo('11')) { 227 if (isMac && !macosVersion.isGreaterThanOrEqualTo('11')) {
230 this.tray.setPressedImage( 228 this.trayIcon.setPressedImage(
231 this._getAsset( 229 this._getAsset(
232 'tray', 230 'tray',
233 `${this._getAssetFromIndicator(this.indicator)}-active`, 231 `${this._getAssetFromIndicator(this.indicator)}-active`,