@@ -464,7 +464,7 @@ class EditServiceForm extends Component {
)}
-
+
{intl.formatMessage(globalMessages.userAgentHelp)}
diff --git a/src/components/settings/settings/EditSettingsForm.jsx b/src/components/settings/settings/EditSettingsForm.jsx
deleted file mode 100644
index a327dccac..000000000
--- a/src/components/settings/settings/EditSettingsForm.jsx
+++ /dev/null
@@ -1,1131 +0,0 @@
-import { systemPreferences } from '@electron/remote';
-import { Component } from 'react';
-import PropTypes from 'prop-types';
-import { observer } from 'mobx-react';
-import prettyBytes from 'pretty-bytes';
-import { defineMessages, injectIntl } from 'react-intl';
-
-import { mdiGithub, mdiOpenInNew, mdiPowerPlug } from '@mdi/js';
-
-import Form from '../../../lib/Form';
-import Button from '../../ui/button';
-import Toggle from '../../ui/Toggle';
-import Select from '../../ui/Select';
-import Input from '../../ui/Input';
-import ColorPickerInput from '../../ui/ColorPickerInput';
-import Infobox from '../../ui/Infobox';
-import { H1, H2, H3, H5 } from '../../ui/headline';
-import {
- ferdiumVersion,
- userDataPath,
- userDataRecipesPath,
-} from '../../../environment-remote';
-
-import { updateVersionParse } from '../../../helpers/update-helpers';
-
-import {
- DEFAULT_ACCENT_COLOR,
- DEFAULT_APP_SETTINGS,
- FERDIUM_TRANSLATION,
- GITHUB_FRANZ_URL,
- GITHUB_FERDIUM_URL,
- SPLIT_COLUMNS_MAX,
- SPLIT_COLUMNS_MIN,
-} from '../../../config';
-import { isMac, isWindows, lockFerdiumShortcutKey } from '../../../environment';
-import { openExternalUrl, openPath } from '../../../helpers/url-helpers';
-import globalMessages from '../../../i18n/globalMessages';
-import Icon from '../../ui/icon';
-import Slider from '../../ui/Slider';
-
-const debug = require('../../../preload-safe-debug')(
- 'Ferdium:EditSettingsForm',
-);
-
-const messages = defineMessages({
- headlineGeneral: {
- id: 'settings.app.headlineGeneral',
- defaultMessage: 'General',
- },
- headlineServices: {
- id: 'settings.app.headlineServices',
- defaultMessage: 'Services',
- },
- hibernateInfo: {
- id: 'settings.app.hibernateInfo',
- defaultMessage:
- 'By default, Ferdium will keep all your services open and loaded in the background so they are ready when you want to use them. Service Hibernation will unload your services after a specified amount. This is useful to save RAM or keeping services from slowing down your computer.',
- },
- inactivityLockInfo: {
- id: 'settings.app.inactivityLockInfo',
- defaultMessage:
- 'Minutes of inactivity, after which Ferdium should automatically lock. Use 0 to disable',
- },
- todoServerInfo: {
- id: 'settings.app.todoServerInfo',
- defaultMessage: 'This server will be used for the "Ferdium Todo" feature.',
- },
- lockedPassword: {
- id: 'settings.app.lockedPassword',
- defaultMessage: 'Password',
- },
- lockedPasswordInfo: {
- id: 'settings.app.lockedPasswordInfo',
- defaultMessage:
- "Please make sure to set a password you'll remember.\nIf you loose this password, you will have to reinstall Ferdium.",
- },
- lockInfo: {
- id: 'settings.app.lockInfo',
- defaultMessage:
- 'Password Lock allows you to keep your messages protected.\nUsing Password Lock, you will be prompted to enter your password everytime you start Ferdium or lock Ferdium yourself using the lock symbol in the bottom left corner or the shortcut {lockShortcut}.',
- },
- scheduledDNDTimeInfo: {
- id: 'settings.app.scheduledDNDTimeInfo',
- defaultMessage:
- 'Times in 24-Hour-Format. End time can be before start time (e.g. start 17:00, end 09:00) to enable Do-not-Disturb overnight.',
- },
- scheduledDNDInfo: {
- id: 'settings.app.scheduledDNDInfo',
- defaultMessage:
- 'Scheduled Do-not-Disturb allows you to define a period of time in which you do not want to get Notifications from Ferdium.',
- },
- headlineLanguage: {
- id: 'settings.app.headlineLanguage',
- defaultMessage: 'Language',
- },
- headlineUpdates: {
- id: 'settings.app.headlineUpdates',
- defaultMessage: 'Updates',
- },
- headlineAppearance: {
- id: 'settings.app.headlineAppearance',
- defaultMessage: 'Appearance',
- },
- sectionMain: {
- id: 'settings.app.sectionMain',
- defaultMessage: 'Main',
- },
- sectionHibernation: {
- id: 'settings.app.sectionHibernation',
- defaultMessage: 'Hibernation',
- },
- sectionGeneralUi: {
- id: 'settings.app.sectionGeneralUi',
- defaultMessage: 'General UI',
- },
- sectionSidebarSettings: {
- id: 'settings.app.sectionSidebarSettings',
- defaultMessage: 'Sidebar Settings',
- },
- sectionPrivacy: {
- id: 'settings.app.sectionPrivacy',
- defaultMessage: 'Privacy Settings',
- },
- sectionLanguage: {
- id: 'settings.app.sectionLanguage',
- defaultMessage: 'Language Settings',
- },
- sectionAdvanced: {
- id: 'settings.app.sectionAdvanced',
- defaultMessage: 'Advanced Settings',
- },
- sectionUpdates: {
- id: 'settings.app.sectionUpdates',
- defaultMessage: 'App Updates Settings',
- },
- sectionServiceIconsSettings: {
- id: 'settings.app.sectionServiceIconsSettings',
- defaultMessage: 'Service Icons Settings',
- },
- sectionAccentColorSettings: {
- id: 'settings.app.sectionAccentColorSettings',
- defaultMessage: 'Accent Color Settings',
- },
- accentColorInfo: {
- id: 'settings.app.accentColorInfo',
- defaultMessage:
- 'Write your color choice in a CSS-compatible format. (Default: {defaultAccentColor} or clear the input field)',
- },
- overallTheme: {
- id: 'settings.app.overallTheme',
- defaultMessage: 'Overall Theme',
- },
- progressbarTheme: {
- id: 'settings.app.progressbarTheme',
- defaultMessage: 'Progressbar Theme',
- },
- universalDarkModeInfo: {
- id: 'settings.app.universalDarkModeInfo',
- defaultMessage:
- 'Universal Dark Mode tries to dynamically generate dark mode styles for services that are otherwise not currently supported.',
- },
- headlinePrivacy: {
- id: 'settings.app.headlinePrivacy',
- defaultMessage: 'Privacy',
- },
- headlineAdvanced: {
- id: 'settings.app.headlineAdvanced',
- defaultMessage: 'Advanced',
- },
- translationHelp: {
- id: 'settings.app.translationHelp',
- defaultMessage: 'Help us to translate Ferdium into your language.',
- },
- spellCheckerLanguageInfo: {
- id: 'settings.app.spellCheckerLanguageInfo',
- defaultMessage:
- "Ferdium uses your Mac's build-in spellchecker to check for typos. If you want to change the languages the spellchecker checks for, you can do so in your Mac's System Preferences.",
- },
- subheadlineCache: {
- id: 'settings.app.subheadlineCache',
- defaultMessage: 'Cache',
- },
- cacheInfo: {
- id: 'settings.app.cacheInfo',
- defaultMessage: 'Ferdium cache is currently using {size} of disk space.',
- },
- cacheNotCleared: {
- id: 'settings.app.cacheNotCleared',
- defaultMessage: "Couldn't clear all cache",
- },
- buttonClearAllCache: {
- id: 'settings.app.buttonClearAllCache',
- defaultMessage: 'Clear cache',
- },
- subheadlineFerdiumProfile: {
- id: 'settings.app.subheadlineFerdiumProfile',
- defaultMessage: 'Ferdium Profile',
- },
- buttonOpenFerdiumProfileFolder: {
- id: 'settings.app.buttonOpenFerdiumProfileFolder',
- defaultMessage: 'Open Profile folder',
- },
- buttonOpenFerdiumServiceRecipesFolder: {
- id: 'settings.app.buttonOpenFerdiumServiceRecipesFolder',
- defaultMessage: 'Open Service Recipes folder',
- },
- buttonOpenImportExport: {
- id: 'settings.app.buttonOpenImportExport',
- defaultMessage: 'Import / Export',
- },
- serverHelp: {
- id: 'settings.app.serverHelp',
- defaultMessage: 'Connected to server at {serverURL}',
- },
- buttonSearchForUpdate: {
- id: 'settings.app.buttonSearchForUpdate',
- defaultMessage: 'Check for updates',
- },
- buttonInstallUpdate: {
- id: 'settings.app.buttonInstallUpdate',
- defaultMessage: 'Restart & install update',
- },
- buttonShowChangelog: {
- id: 'settings.app.buttonShowChangelog',
- defaultMessage: 'Show changelog',
- },
- updateStatusSearching: {
- id: 'settings.app.updateStatusSearching',
- defaultMessage: 'Searching for updates...',
- },
- updateStatusAvailable: {
- id: 'settings.app.updateStatusAvailable',
- defaultMessage: 'Update available, downloading...',
- },
- updateStatusUpToDate: {
- id: 'settings.app.updateStatusUpToDate',
- defaultMessage: 'You are using the latest version of Ferdium',
- },
- currentVersion: {
- id: 'settings.app.currentVersion',
- defaultMessage: 'Current version:',
- },
- appRestartRequired: {
- id: 'settings.app.restartRequired',
- defaultMessage: 'Changes require restart',
- },
- servicesUpdated: {
- id: 'infobar.servicesUpdated',
- defaultMessage: 'Your services have been updated.',
- },
- buttonReloadServices: {
- id: 'infobar.buttonReloadServices',
- defaultMessage: 'Reload services',
- },
- numberOfColumns: {
- id: 'settings.app.form.splitColumns',
- defaultMessage: 'Number of columns',
- },
-});
-
-const Hr = () => (
-
-);
-const HrSections = () => (
-
-);
-
-class EditSettingsForm extends Component {
- static propTypes = {
- checkForUpdates: PropTypes.func.isRequired,
- installUpdate: PropTypes.func.isRequired,
- form: PropTypes.instanceOf(Form).isRequired,
- onSubmit: PropTypes.func.isRequired,
- isCheckingForUpdates: PropTypes.bool.isRequired,
- isUpdateAvailable: PropTypes.bool.isRequired,
- noUpdateAvailable: PropTypes.bool.isRequired,
- updateIsReadyToInstall: PropTypes.bool.isRequired,
- updateFailed: PropTypes.bool.isRequired,
- isClearingAllCache: PropTypes.bool.isRequired,
- onClearAllCache: PropTypes.func.isRequired,
- getCacheSize: PropTypes.func.isRequired,
- isTodosActivated: PropTypes.bool.isRequired,
- automaticUpdates: PropTypes.bool.isRequired,
- isDarkmodeEnabled: PropTypes.bool.isRequired,
- isAdaptableDarkModeEnabled: PropTypes.bool.isRequired,
- isUseGrayscaleServicesEnabled: PropTypes.bool.isRequired,
- openProcessManager: PropTypes.func.isRequired,
- isSplitModeEnabled: PropTypes.bool.isRequired,
- isOnline: PropTypes.bool.isRequired,
- serverURL: PropTypes.string.isRequired,
- };
-
- constructor(props) {
- super(props);
-
- this.state = {
- activeSetttingsTab: 'general',
- clearCacheButtonClicked: false,
- };
- }
-
- setActiveSettingsTab(tab) {
- this.setState({
- activeSetttingsTab: tab,
- });
- }
-
- onClearCacheClicked = () => {
- this.setState({ clearCacheButtonClicked: true });
- };
-
- submit(e) {
- e.preventDefault();
- this.props.form.submit({
- onSuccess: form => {
- const values = form.values();
- const { accentColor } = values;
- if (accentColor.trim().length === 0) {
- values.accentColor = DEFAULT_ACCENT_COLOR;
- }
- const { progressbarAccentColor } = values;
- if (progressbarAccentColor.trim().length === 0) {
- values.progressbarAccentColor = DEFAULT_ACCENT_COLOR;
- }
- this.props.onSubmit(values);
- },
- onError: () => {},
- });
- }
-
- render() {
- const {
- checkForUpdates,
- installUpdate,
- form,
- updateVersion,
- isCheckingForUpdates,
- isAdaptableDarkModeEnabled,
- isUseGrayscaleServicesEnabled,
- isUpdateAvailable,
- noUpdateAvailable,
- updateIsReadyToInstall,
- updateFailed,
- showServicesUpdatedInfoBar,
- isClearingAllCache,
- onClearAllCache,
- getCacheSize,
- automaticUpdates,
- isDarkmodeEnabled,
- isSplitModeEnabled,
- openProcessManager,
- isTodosActivated,
- isOnline,
- serverURL,
- } = this.props;
- const { intl } = this.props;
-
- let updateButtonLabelMessage = messages.buttonSearchForUpdate;
- if (isCheckingForUpdates) {
- updateButtonLabelMessage = messages.updateStatusSearching;
- } else if (isUpdateAvailable) {
- updateButtonLabelMessage = messages.updateStatusAvailable;
- } else {
- updateButtonLabelMessage = messages.buttonSearchForUpdate;
- }
-
- const { lockingFeatureEnabled, scheduledDNDEnabled, reloadAfterResume } =
- window['ferdium'].stores.settings.all.app;
-
- let cacheSize;
- let notCleared;
- if (this.state.activeSetttingsTab === 'advanced') {
- const cacheSizeBytes = getCacheSize();
- debug('cacheSizeBytes:', cacheSizeBytes);
- if (typeof cacheSizeBytes === 'number') {
- cacheSize = prettyBytes(cacheSizeBytes);
- debug('cacheSize:', cacheSize);
- notCleared =
- this.state.clearCacheButtonClicked &&
- isClearingAllCache === false &&
- cacheSizeBytes !== 0;
- } else {
- cacheSize = '…';
- notCleared = false;
- }
- }
-
- const profileFolder = userDataPath();
- const recipeFolder = userDataRecipesPath();
-
- return (
-
-
-
{intl.formatMessage(globalMessages.settings)}
-
-
-
- );
- }
-}
-
-export default injectIntl(observer(EditSettingsForm));
diff --git a/src/components/settings/settings/EditSettingsForm.tsx b/src/components/settings/settings/EditSettingsForm.tsx
new file mode 100644
index 000000000..5c422b977
--- /dev/null
+++ b/src/components/settings/settings/EditSettingsForm.tsx
@@ -0,0 +1,1136 @@
+import { systemPreferences } from '@electron/remote';
+import { Component } from 'react';
+import { observer } from 'mobx-react';
+import prettyBytes from 'pretty-bytes';
+import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl';
+import { mdiGithub, mdiOpenInNew, mdiPowerPlug } from '@mdi/js';
+import Form from '../../../lib/Form';
+import Button from '../../ui/button';
+import Toggle from '../../ui/Toggle.js';
+import Select from '../../ui/Select';
+import Input from '../../ui/input/index';
+import ColorPickerInput from '../../ui/ColorPickerInput';
+import Infobox from '../../ui/Infobox';
+import { H1, H2, H3, H5 } from '../../ui/headline';
+import {
+ ferdiumVersion,
+ userDataPath,
+ userDataRecipesPath,
+} from '../../../environment-remote';
+import { updateVersionParse } from '../../../helpers/update-helpers';
+import {
+ DEFAULT_ACCENT_COLOR,
+ DEFAULT_APP_SETTINGS,
+ FERDIUM_TRANSLATION,
+ GITHUB_FRANZ_URL,
+ GITHUB_FERDIUM_URL,
+ SPLIT_COLUMNS_MAX,
+ SPLIT_COLUMNS_MIN,
+} from '../../../config';
+import { isMac, isWindows, lockFerdiumShortcutKey } from '../../../environment';
+import { openExternalUrl, openPath } from '../../../helpers/url-helpers';
+import globalMessages from '../../../i18n/globalMessages';
+import Icon from '../../ui/icon';
+import Slider from '../../ui/Slider';
+
+const debug = require('../../../preload-safe-debug')(
+ 'Ferdium:EditSettingsForm',
+);
+
+const messages = defineMessages({
+ headlineGeneral: {
+ id: 'settings.app.headlineGeneral',
+ defaultMessage: 'General',
+ },
+ headlineServices: {
+ id: 'settings.app.headlineServices',
+ defaultMessage: 'Services',
+ },
+ hibernateInfo: {
+ id: 'settings.app.hibernateInfo',
+ defaultMessage:
+ 'By default, Ferdium will keep all your services open and loaded in the background so they are ready when you want to use them. Service Hibernation will unload your services after a specified amount. This is useful to save RAM or keeping services from slowing down your computer.',
+ },
+ inactivityLockInfo: {
+ id: 'settings.app.inactivityLockInfo',
+ defaultMessage:
+ 'Minutes of inactivity, after which Ferdium should automatically lock. Use 0 to disable',
+ },
+ todoServerInfo: {
+ id: 'settings.app.todoServerInfo',
+ defaultMessage: 'This server will be used for the "Ferdium Todo" feature.',
+ },
+ lockedPassword: {
+ id: 'settings.app.lockedPassword',
+ defaultMessage: 'Password',
+ },
+ lockedPasswordInfo: {
+ id: 'settings.app.lockedPasswordInfo',
+ defaultMessage:
+ "Please make sure to set a password you'll remember.\nIf you loose this password, you will have to reinstall Ferdium.",
+ },
+ lockInfo: {
+ id: 'settings.app.lockInfo',
+ defaultMessage:
+ 'Password Lock allows you to keep your messages protected.\nUsing Password Lock, you will be prompted to enter your password everytime you start Ferdium or lock Ferdium yourself using the lock symbol in the bottom left corner or the shortcut {lockShortcut}.',
+ },
+ scheduledDNDTimeInfo: {
+ id: 'settings.app.scheduledDNDTimeInfo',
+ defaultMessage:
+ 'Times in 24-Hour-Format. End time can be before start time (e.g. start 17:00, end 09:00) to enable Do-not-Disturb overnight.',
+ },
+ scheduledDNDInfo: {
+ id: 'settings.app.scheduledDNDInfo',
+ defaultMessage:
+ 'Scheduled Do-not-Disturb allows you to define a period of time in which you do not want to get Notifications from Ferdium.',
+ },
+ headlineLanguage: {
+ id: 'settings.app.headlineLanguage',
+ defaultMessage: 'Language',
+ },
+ headlineUpdates: {
+ id: 'settings.app.headlineUpdates',
+ defaultMessage: 'Updates',
+ },
+ headlineAppearance: {
+ id: 'settings.app.headlineAppearance',
+ defaultMessage: 'Appearance',
+ },
+ sectionMain: {
+ id: 'settings.app.sectionMain',
+ defaultMessage: 'Main',
+ },
+ sectionHibernation: {
+ id: 'settings.app.sectionHibernation',
+ defaultMessage: 'Hibernation',
+ },
+ sectionGeneralUi: {
+ id: 'settings.app.sectionGeneralUi',
+ defaultMessage: 'General UI',
+ },
+ sectionSidebarSettings: {
+ id: 'settings.app.sectionSidebarSettings',
+ defaultMessage: 'Sidebar Settings',
+ },
+ sectionPrivacy: {
+ id: 'settings.app.sectionPrivacy',
+ defaultMessage: 'Privacy Settings',
+ },
+ sectionLanguage: {
+ id: 'settings.app.sectionLanguage',
+ defaultMessage: 'Language Settings',
+ },
+ sectionAdvanced: {
+ id: 'settings.app.sectionAdvanced',
+ defaultMessage: 'Advanced Settings',
+ },
+ sectionUpdates: {
+ id: 'settings.app.sectionUpdates',
+ defaultMessage: 'App Updates Settings',
+ },
+ sectionServiceIconsSettings: {
+ id: 'settings.app.sectionServiceIconsSettings',
+ defaultMessage: 'Service Icons Settings',
+ },
+ sectionAccentColorSettings: {
+ id: 'settings.app.sectionAccentColorSettings',
+ defaultMessage: 'Accent Color Settings',
+ },
+ accentColorInfo: {
+ id: 'settings.app.accentColorInfo',
+ defaultMessage:
+ 'Write your color choice in a CSS-compatible format. (Default: {defaultAccentColor} or clear the input field)',
+ },
+ overallTheme: {
+ id: 'settings.app.overallTheme',
+ defaultMessage: 'Overall Theme',
+ },
+ progressbarTheme: {
+ id: 'settings.app.progressbarTheme',
+ defaultMessage: 'Progressbar Theme',
+ },
+ universalDarkModeInfo: {
+ id: 'settings.app.universalDarkModeInfo',
+ defaultMessage:
+ 'Universal Dark Mode tries to dynamically generate dark mode styles for services that are otherwise not currently supported.',
+ },
+ headlinePrivacy: {
+ id: 'settings.app.headlinePrivacy',
+ defaultMessage: 'Privacy',
+ },
+ headlineAdvanced: {
+ id: 'settings.app.headlineAdvanced',
+ defaultMessage: 'Advanced',
+ },
+ translationHelp: {
+ id: 'settings.app.translationHelp',
+ defaultMessage: 'Help us to translate Ferdium into your language.',
+ },
+ spellCheckerLanguageInfo: {
+ id: 'settings.app.spellCheckerLanguageInfo',
+ defaultMessage:
+ "Ferdium uses your Mac's build-in spellchecker to check for typos. If you want to change the languages the spellchecker checks for, you can do so in your Mac's System Preferences.",
+ },
+ subheadlineCache: {
+ id: 'settings.app.subheadlineCache',
+ defaultMessage: 'Cache',
+ },
+ cacheInfo: {
+ id: 'settings.app.cacheInfo',
+ defaultMessage: 'Ferdium cache is currently using {size} of disk space.',
+ },
+ cacheNotCleared: {
+ id: 'settings.app.cacheNotCleared',
+ defaultMessage: "Couldn't clear all cache",
+ },
+ buttonClearAllCache: {
+ id: 'settings.app.buttonClearAllCache',
+ defaultMessage: 'Clear cache',
+ },
+ subheadlineFerdiumProfile: {
+ id: 'settings.app.subheadlineFerdiumProfile',
+ defaultMessage: 'Ferdium Profile',
+ },
+ buttonOpenFerdiumProfileFolder: {
+ id: 'settings.app.buttonOpenFerdiumProfileFolder',
+ defaultMessage: 'Open Profile folder',
+ },
+ buttonOpenFerdiumServiceRecipesFolder: {
+ id: 'settings.app.buttonOpenFerdiumServiceRecipesFolder',
+ defaultMessage: 'Open Service Recipes folder',
+ },
+ buttonOpenImportExport: {
+ id: 'settings.app.buttonOpenImportExport',
+ defaultMessage: 'Import / Export',
+ },
+ serverHelp: {
+ id: 'settings.app.serverHelp',
+ defaultMessage: 'Connected to server at {serverURL}',
+ },
+ buttonSearchForUpdate: {
+ id: 'settings.app.buttonSearchForUpdate',
+ defaultMessage: 'Check for updates',
+ },
+ buttonInstallUpdate: {
+ id: 'settings.app.buttonInstallUpdate',
+ defaultMessage: 'Restart & install update',
+ },
+ buttonShowChangelog: {
+ id: 'settings.app.buttonShowChangelog',
+ defaultMessage: 'Show changelog',
+ },
+ updateStatusSearching: {
+ id: 'settings.app.updateStatusSearching',
+ defaultMessage: 'Searching for updates...',
+ },
+ updateStatusAvailable: {
+ id: 'settings.app.updateStatusAvailable',
+ defaultMessage: 'Update available, downloading...',
+ },
+ updateStatusUpToDate: {
+ id: 'settings.app.updateStatusUpToDate',
+ defaultMessage: 'You are using the latest version of Ferdium',
+ },
+ currentVersion: {
+ id: 'settings.app.currentVersion',
+ defaultMessage: 'Current version:',
+ },
+ appRestartRequired: {
+ id: 'settings.app.restartRequired',
+ defaultMessage: 'Changes require restart',
+ },
+ servicesUpdated: {
+ id: 'infobar.servicesUpdated',
+ defaultMessage: 'Your services have been updated.',
+ },
+ buttonReloadServices: {
+ id: 'infobar.buttonReloadServices',
+ defaultMessage: 'Reload services',
+ },
+ numberOfColumns: {
+ id: 'settings.app.form.splitColumns',
+ defaultMessage: 'Number of columns',
+ },
+});
+
+const Hr = () => (
+
+);
+
+const HrSections = () => (
+
+);
+
+interface IProps extends WrappedComponentProps {
+ form: Form;
+ isCheckingForUpdates: boolean;
+ isUpdateAvailable: boolean;
+ noUpdateAvailable: boolean;
+ updateIsReadyToInstall: boolean;
+ updateFailed: boolean;
+ isClearingAllCache: boolean;
+ isTodosActivated: boolean;
+ automaticUpdates: boolean;
+ isDarkmodeEnabled: boolean;
+ isAdaptableDarkModeEnabled: boolean;
+ isUseGrayscaleServicesEnabled: boolean;
+ lockingFeatureEnabled: boolean;
+ isSplitModeEnabled: boolean;
+ isOnline: boolean;
+ showServicesUpdatedInfoBar: boolean;
+ updateVersion: string;
+ serverURL: string;
+ onClearAllCache: () => void;
+ getCacheSize: () => void;
+ checkForUpdates: () => void;
+ installUpdate: () => void;
+ openProcessManager: () => void;
+ onSubmit: (...args: any[]) => void;
+}
+
+interface IState {
+ activeSetttingsTab: string;
+ clearCacheButtonClicked: boolean;
+}
+
+@observer
+class EditSettingsForm extends Component
{
+ constructor(props: IProps) {
+ super(props);
+
+ this.state = {
+ activeSetttingsTab: 'general',
+ clearCacheButtonClicked: false,
+ };
+ }
+
+ setActiveSettingsTab(tab) {
+ this.setState({
+ activeSetttingsTab: tab,
+ });
+ }
+
+ onClearCacheClicked = () => {
+ this.setState({ clearCacheButtonClicked: true });
+ };
+
+ submit(e) {
+ e.preventDefault();
+ this.props.form.submit({
+ onSuccess: form => {
+ const values = form.values();
+ const { accentColor } = values;
+ if (accentColor.trim().length === 0) {
+ values.accentColor = DEFAULT_ACCENT_COLOR;
+ }
+ const { progressbarAccentColor } = values;
+ if (progressbarAccentColor.trim().length === 0) {
+ values.progressbarAccentColor = DEFAULT_ACCENT_COLOR;
+ }
+ this.props.onSubmit(values);
+ },
+ onError: () => {},
+ });
+ }
+
+ render() {
+ const {
+ checkForUpdates,
+ installUpdate,
+ form,
+ updateVersion,
+ isCheckingForUpdates,
+ isAdaptableDarkModeEnabled,
+ isUseGrayscaleServicesEnabled,
+ isUpdateAvailable,
+ noUpdateAvailable,
+ updateIsReadyToInstall,
+ updateFailed,
+ showServicesUpdatedInfoBar,
+ isClearingAllCache,
+ onClearAllCache,
+ getCacheSize,
+ automaticUpdates,
+ isDarkmodeEnabled,
+ isSplitModeEnabled,
+ openProcessManager,
+ isTodosActivated,
+ isOnline,
+ serverURL,
+ intl,
+ } = this.props;
+
+ let updateButtonLabelMessage = messages.buttonSearchForUpdate;
+ if (isCheckingForUpdates) {
+ updateButtonLabelMessage = messages.updateStatusSearching;
+ } else if (isUpdateAvailable) {
+ updateButtonLabelMessage = messages.updateStatusAvailable;
+ } else {
+ updateButtonLabelMessage = messages.buttonSearchForUpdate;
+ }
+
+ const { lockingFeatureEnabled, scheduledDNDEnabled, reloadAfterResume } =
+ window['ferdium'].stores.settings.all.app;
+
+ let cacheSize;
+ let notCleared;
+ if (this.state.activeSetttingsTab === 'advanced') {
+ const cacheSizeBytes = getCacheSize();
+ debug('cacheSizeBytes:', cacheSizeBytes);
+ if (typeof cacheSizeBytes === 'number') {
+ cacheSize = prettyBytes(cacheSizeBytes);
+ debug('cacheSize:', cacheSize);
+ notCleared =
+ this.state.clearCacheButtonClicked &&
+ isClearingAllCache === false &&
+ cacheSizeBytes !== 0;
+ } else {
+ cacheSize = '…';
+ notCleared = false;
+ }
+ }
+
+ const profileFolder = userDataPath();
+ const recipeFolder = userDataRecipesPath();
+
+ return (
+
+
+
{intl.formatMessage(globalMessages.settings)}
+
+
+
+ );
+ }
+}
+
+export default injectIntl(EditSettingsForm);
diff --git a/src/components/settings/user/EditUserForm.js b/src/components/settings/user/EditUserForm.js
deleted file mode 100644
index c2773a47d..000000000
--- a/src/components/settings/user/EditUserForm.js
+++ /dev/null
@@ -1,131 +0,0 @@
-import { Component } from 'react';
-import PropTypes from 'prop-types';
-import { observer, PropTypes as MobxPropTypes } from 'mobx-react';
-import { defineMessages, injectIntl } from 'react-intl';
-import { Link } from 'react-router-dom';
-
-import Input from '../../ui/input/index';
-import Form from '../../../lib/Form';
-import Button from '../../ui/button';
-import Radio from '../../ui/Radio';
-import Infobox from '../../ui/Infobox';
-import { H2 } from '../../ui/headline';
-
-const messages = defineMessages({
- headline: {
- id: 'settings.account.headline',
- defaultMessage: 'Account',
- },
- headlineProfile: {
- id: 'settings.account.headlineProfile',
- defaultMessage: 'Update profile',
- },
- headlineAccount: {
- id: 'settings.account.headlineAccount',
- defaultMessage: 'Account information',
- },
- headlinePassword: {
- id: 'settings.account.headlinePassword',
- defaultMessage: 'Change password',
- },
- successInfo: {
- id: 'settings.account.successInfo',
- defaultMessage: 'Your changes have been saved',
- },
- buttonSave: {
- id: 'settings.account.buttonSave',
- defaultMessage: 'Update profile',
- },
-});
-
-class EditUserForm extends Component {
- static propTypes = {
- status: MobxPropTypes.observableArray.isRequired,
- form: PropTypes.instanceOf(Form).isRequired,
- onSubmit: PropTypes.func.isRequired,
- isSaving: PropTypes.bool.isRequired,
- };
-
- submit(e) {
- e.preventDefault();
- this.props.form.submit({
- onSuccess: form => {
- const values = form.values();
- this.props.onSubmit(values);
- },
- onError: () => {},
- });
- }
-
- render() {
- const {
- // user,
- status,
- form,
- isSaving,
- } = this.props;
- const { intl } = this.props;
-
- return (
-
-
-
-
- {intl.formatMessage(messages.headline)}
-
-
-
-
- {intl.formatMessage(messages.headlineProfile)}
-
-
-
-
- {/* Save Button */}
- {isSaving ? (
-
- ) : (
-
- )}
-
-
- );
- }
-}
-
-export default injectIntl(observer(EditUserForm));
diff --git a/src/components/settings/user/EditUserForm.tsx b/src/components/settings/user/EditUserForm.tsx
new file mode 100644
index 000000000..3b604a79f
--- /dev/null
+++ b/src/components/settings/user/EditUserForm.tsx
@@ -0,0 +1,133 @@
+import { Component, FormEvent, FormEventHandler, ReactElement } from 'react';
+import { observer } from 'mobx-react';
+import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl';
+import { Link } from 'react-router-dom';
+import { noop } from 'lodash';
+import Input from '../../ui/input/index';
+import Form from '../../../lib/Form';
+import Button from '../../ui/button';
+import Radio from '../../ui/Radio';
+import Infobox from '../../ui/Infobox';
+import { H2 } from '../../ui/headline';
+
+const messages = defineMessages({
+ headline: {
+ id: 'settings.account.headline',
+ defaultMessage: 'Account',
+ },
+ headlineProfile: {
+ id: 'settings.account.headlineProfile',
+ defaultMessage: 'Update profile',
+ },
+ headlineAccount: {
+ id: 'settings.account.headlineAccount',
+ defaultMessage: 'Account information',
+ },
+ headlinePassword: {
+ id: 'settings.account.headlinePassword',
+ defaultMessage: 'Change password',
+ },
+ successInfo: {
+ id: 'settings.account.successInfo',
+ defaultMessage: 'Your changes have been saved',
+ },
+ buttonSave: {
+ id: 'settings.account.buttonSave',
+ defaultMessage: 'Update profile',
+ },
+});
+
+interface IProps extends WrappedComponentProps {
+ status: string[];
+ form: Form;
+ onSubmit: FormEventHandler;
+ isSaving: boolean;
+}
+
+@observer
+class EditUserForm extends Component {
+ submit(e: FormEvent): void {
+ e.preventDefault();
+ this.props.form.submit({
+ onSuccess: form => {
+ const values = form.values();
+ this.props.onSubmit(values);
+ },
+ onError: () => {},
+ });
+ }
+
+ render(): ReactElement {
+ const {
+ // user,
+ status,
+ form,
+ isSaving,
+ intl,
+ } = this.props;
+
+ return (
+
+
+
+
+ {intl.formatMessage(messages.headline)}
+
+
+
+
+ {intl.formatMessage(messages.headlineProfile)}
+
+
+
+
+ {/* Save Button */}
+ {isSaving ? (
+
+ ) : (
+
+ )}
+
+
+ );
+ }
+}
+
+export default injectIntl(EditUserForm);
diff --git a/src/components/ui/ColorPickerInput.tsx b/src/components/ui/ColorPickerInput.tsx
index 7e3965331..da1fffb71 100644
--- a/src/components/ui/ColorPickerInput.tsx
+++ b/src/components/ui/ColorPickerInput.tsx
@@ -1,15 +1,25 @@
-import { ChangeEvent, Component, createRef, RefObject } from 'react';
+import {
+ ChangeEvent,
+ ChangeEventHandler,
+ Component,
+ createRef,
+ RefObject,
+} from 'react';
import { observer } from 'mobx-react';
import classnames from 'classnames';
import { SliderPicker } from 'react-color';
+import { noop } from 'lodash';
import { Field } from '../../@types/mobx-form.types';
interface IProps {
field: Field;
className?: string;
focus?: boolean;
+ onChange: ChangeEventHandler;
}
+// TODO - [TS DEBT] check if field can be spread instead of having it single field attribute in interface
+@observer
class ColorPickerInput extends Component {
private inputElement: RefObject =
createRef();
@@ -22,7 +32,9 @@ class ColorPickerInput extends Component {
}
onChange(e: ChangeEvent) {
- const { field } = this.props;
+ const { field, onChange = noop } = this.props;
+
+ onChange(e);
if (field.onChange) {
field.onChange(e);
}
@@ -87,4 +99,4 @@ class ColorPickerInput extends Component {
}
}
-export default observer(ColorPickerInput);
+export default ColorPickerInput;
diff --git a/src/components/ui/Input.tsx b/src/components/ui/Input.tsx
deleted file mode 100644
index c22dc5838..000000000
--- a/src/components/ui/Input.tsx
+++ /dev/null
@@ -1,170 +0,0 @@
-import {
- ChangeEvent,
- ChangeEventHandler,
- Component,
- createRef,
- ReactElement,
- RefObject,
-} from 'react';
-import { observer } from 'mobx-react';
-import classnames from 'classnames';
-import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl';
-import { mdiEye, mdiEyeOff } from '@mdi/js';
-import { noop } from 'lodash';
-import { scorePassword as scorePasswordFunc } from '../../helpers/password-helpers';
-import Icon from './icon';
-import { Field } from '../../@types/mobx-form.types';
-
-const messages = defineMessages({
- passwordToggle: {
- id: 'settings.app.form.passwordToggle',
- defaultMessage: 'Password toggle',
- },
-});
-
-interface IProps extends WrappedComponentProps {
- field: Field;
- className?: string;
- focus?: boolean;
- showPasswordToggle?: boolean;
- showLabel?: boolean;
- scorePassword?: boolean;
- prefix?: string;
- suffix?: string;
- placeholder?: string;
- onChange?: ChangeEventHandler;
-}
-
-interface IState {
- showPassword: boolean;
- passwordScore: number;
-}
-
-// Can this file be merged into the './input/index.tsx' file?
-@observer
-class Input extends Component {
- private inputElement: RefObject =
- createRef();
-
- constructor(props: IProps) {
- super(props);
-
- this.state = {
- showPassword: false,
- passwordScore: 0,
- };
- }
-
- componentDidMount(): void {
- const { focus = false } = this.props;
- if (focus) {
- this.focus();
- }
- }
-
- onChange(e: ChangeEvent): void {
- const { field, scorePassword, onChange = noop } = this.props;
-
- if (field.onChange) {
- onChange(e);
- field.onChange(e);
- }
-
- if (scorePassword) {
- this.setState({
- passwordScore: scorePasswordFunc(field.value as string),
- });
- }
- }
-
- focus() {
- if (this.inputElement && this.inputElement.current) {
- this.inputElement.current!.focus();
- }
- }
-
- render(): ReactElement {
- const {
- field,
- className = null,
- showPasswordToggle = false,
- showLabel = true,
- scorePassword = false,
- prefix = '',
- suffix = '',
- intl,
- } = this.props;
-
- const { passwordScore } = this.state;
-
- let { type } = field;
- if (type === 'password' && this.state.showPassword) {
- type = 'text';
- }
-
- return (
-
-
- {prefix &&
{prefix}}
-
this.onChange(e)}
- onBlur={field.onBlur}
- onFocus={field.onFocus}
- ref={this.inputElement}
- disabled={field.disabled}
- />
- {suffix &&
{suffix}}
- {showPasswordToggle && (
-
- )}
- {scorePassword && (
-
- )}
-
- {field.label && showLabel && (
-
- )}
- {field.error &&
{field.error}
}
-
- );
- }
-}
-
-export default injectIntl(Input);
diff --git a/src/components/ui/input/index.tsx b/src/components/ui/input/index.tsx
index 2a36d7aa9..cb26c0ea4 100644
--- a/src/components/ui/input/index.tsx
+++ b/src/components/ui/input/index.tsx
@@ -1,5 +1,4 @@
import { mdiEye, mdiEyeOff } from '@mdi/js';
-import Icon from '@mdi/react';
import classnames from 'classnames';
import {
Component,
@@ -7,9 +6,13 @@ import {
InputHTMLAttributes,
ReactElement,
RefObject,
+ KeyboardEvent,
} from 'react';
-import injectSheet, { WithStylesProps } from 'react-jss';
+import withStyles, { WithStylesProps } from 'react-jss';
import { noop } from 'lodash';
+import { observer } from 'mobx-react';
+import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl';
+import Icon from '../icon';
import { IFormField } from '../typings/generic';
import Error from '../error';
import Label from '../label';
@@ -17,6 +20,12 @@ import Wrapper from '../wrapper';
import { scorePasswordFunc } from './scorePassword';
import styles from './styles';
+const messages = defineMessages({
+ passwordToggle: {
+ id: 'settings.app.form.passwordToggle',
+ defaultMessage: 'Password toggle',
+ },
+});
interface IData {
[index: string]: string;
}
@@ -24,7 +33,8 @@ interface IData {
interface IProps
extends InputHTMLAttributes,
IFormField,
- WithStylesProps {
+ WithStylesProps,
+ WrappedComponentProps {
focus?: boolean;
prefix?: string;
suffix?: string;
@@ -40,8 +50,10 @@ interface IState {
passwordScore: number;
}
-class InputComponent extends Component {
- private inputRef: RefObject = createRef();
+@observer
+class Input extends Component {
+ private inputElement: RefObject =
+ createRef();
constructor(props: IProps) {
super(props);
@@ -53,36 +65,40 @@ class InputComponent extends Component {
}
componentDidMount(): void {
- const { focus, data = {} } = this.props;
+ const { focus = false, data = {} } = this.props;
- if (this.inputRef && this.inputRef.current) {
+ if (this.inputElement && this.inputElement.current) {
if (focus) {
- this.inputRef.current.focus();
+ this.inputElement.current.focus();
}
- for (const key of Object.keys(data))
- this.inputRef.current!.dataset[key] = data[key];
+ for (const key of Object.keys(data)) {
+ this.inputElement.current.dataset[key] = data[key];
+ }
}
}
onChange(e: React.ChangeEvent): void {
- const { scorePassword, onChange } = this.props;
+ const { scorePassword, onChange = noop } = this.props;
- if (onChange) {
- onChange(e);
- }
+ onChange(e);
- if (this.inputRef && this.inputRef.current && scorePassword) {
+ if (scorePassword) {
+ console.log(
+ '--->',
+ e.target.value,
+ scorePasswordFunc(e.target.value as string),
+ );
this.setState({
- passwordScore: scorePasswordFunc(this.inputRef.current.value),
+ passwordScore: scorePasswordFunc(e.target.value),
});
}
}
- onInputKeyPress(e: React.KeyboardEvent): void {
+ onInputKeyPress(e: KeyboardEvent): void {
if (e.key === 'Enter') {
- const { onEnterKey } = this.props;
- onEnterKey && onEnterKey();
+ const { onEnterKey = noop } = this.props;
+ onEnterKey();
}
}
@@ -113,10 +129,9 @@ class InputComponent extends Component {
type = 'text',
disabled = false,
readOnly,
+ intl,
} = this.props;
-
const { showPassword, passwordScore } = this.state;
-
const inputType = type === 'password' && showPassword ? 'text' : type;
return (
@@ -125,79 +140,85 @@ class InputComponent extends Component {
identifier="franz-input"
noMargin={noMargin}
>
-
+ )}
+
+ {prefix && {prefix}}
+
+
+ {suffix && {suffix}}
+
+ {showPasswordToggle && (
+
+ )}
+
+ {scorePassword && (
- {prefix && {prefix}}
-
- {suffix && {suffix}}
- {showPasswordToggle && (
-
- )}
- {scorePassword && (
-
-
-
- )}
-
+ )}
{error && }
);
}
}
-export default injectSheet(styles, { injectTheme: true })(InputComponent);
+export default injectIntl(withStyles(styles, { injectTheme: true })(Input));
diff --git a/src/components/ui/input/styles.ts b/src/components/ui/input/styles.ts
index 04c1b3991..ebae0e40d 100644
--- a/src/components/ui/input/styles.ts
+++ b/src/components/ui/input/styles.ts
@@ -49,7 +49,6 @@ export default (theme: Theme) => ({
},
passwordScore: {
background: theme.inputScorePasswordBackground,
- border: theme.inputBorder,
borderTopWidth: 0,
borderBottomLeftRadius: theme.borderRadiusSmall,
borderBottomRightRadius: theme.borderRadiusSmall,
diff --git a/src/containers/auth/LockedScreen.tsx b/src/containers/auth/LockedScreen.tsx
index 611a0757c..a4cb43f73 100644
--- a/src/containers/auth/LockedScreen.tsx
+++ b/src/containers/auth/LockedScreen.tsx
@@ -12,16 +12,19 @@ interface IProps {
stores?: RealStores;
}
+interface IState {
+ error: boolean;
+}
+
@inject('stores', 'actions')
@observer
-class LockedScreen extends Component {
- state = {
- error: false,
- };
-
+class LockedScreen extends Component {
constructor(props: StoresProps) {
super(props);
+ this.state = {
+ error: false,
+ };
this.onSubmit = this.onSubmit.bind(this);
this.unlock = this.unlock.bind(this);
}
@@ -43,9 +46,7 @@ class LockedScreen extends Component {
});
} else {
this.setState({
- error: {
- code: 'invalid-credentials',
- },
+ error: true,
});
}
}
@@ -71,7 +72,7 @@ class LockedScreen extends Component {
unlock={this.unlock}
useTouchIdToUnlock={useTouchIdToUnlock}
isSubmitting={stores!.user.loginRequest.isExecuting}
- error={this.state.error || {}}
+ error={this.state.error}
/>