import * as React from 'react'; import { UpdateSettingValueCallback } from './types'; import { View, Text } from 'react-native'; import Setting, { AppType, SettingItem } from '@joplin/lib/models/Setting'; import Dropdown from '../../Dropdown'; import { ConfigScreenStyles } from './configScreenStyles'; import SettingsToggle from './SettingsToggle'; import FileSystemPathSelector from './FileSystemPathSelector'; import ValidatedIntegerInput from './ValidatedIntegerInput'; import SettingTextInput from './SettingTextInput'; import shim from '@joplin/lib/shim'; import { themeStyle } from '../../global-style'; import SettingsButton from './SettingsButton'; import { useCallback, useState } from 'react'; import { _ } from '@joplin/lib/locale'; type OnSettingButtonClick = (key: string)=> Promise; interface Props { settingId: string; // The value associated with the given settings key value: unknown; styles: ConfigScreenStyles; themeId: number; onUpdateSettingValue: UpdateSettingValueCallback; onSettingButtonClick: OnSettingButtonClick; } const SettingComponent: React.FunctionComponent = props => { const themeId = props.themeId; const theme = themeStyle(themeId); const output: React.ReactElement | null = null; const md = Setting.settingMetadata(props.settingId); const settingDescription = md.description ? md.description(AppType.Mobile) : ''; const styleSheet = props.styles.styleSheet; const descriptionComp = !settingDescription ? null : {settingDescription}; const containerStyles = props.styles.getContainerStyle(!!settingDescription); if (md.isEnum) { const value = props.value?.toString(); const items = Setting.enumOptionsToValueLabels(md.options(), md.optionsOrder ? md.optionsOrder() : []); const label = md.label(); return ( {label} { void props.onUpdateSettingValue(props.settingId, itemValue); }} accessibilityHint={label} /> {descriptionComp} ); } else if (md.type === Setting.TYPE_BOOL) { return ( ); } else if (md.type === Setting.TYPE_INT) { return ( ); } else if (md.type === Setting.TYPE_STRING) { if (['sync.2.path', 'plugins.devPluginPaths'].includes(md.key) && (shim.fsDriver().isUsingAndroidSAF() || shim.mobilePlatform() === 'web')) { return ( ); } return ( ); } else if (md.type === Setting.TYPE_BUTTON) { return ( ); } else if (Setting.value('env') === 'dev') { throw new Error(`Unsupported setting type: ${md.type}`); } return output; }; export default SettingComponent; interface SettingButtonProps { metadata: SettingItem; styles: ConfigScreenStyles; onSettingButtonClick: OnSettingButtonClick; } const SettingButtonComponent: React.FC = ({ metadata, styles, onSettingButtonClick }) => { const key = metadata.key; const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const onClick = useCallback(async () => { setError(null); setLoading(true); try { await onSettingButtonClick(key); } catch (error) { setError(String(error)); } finally { setLoading(false); } }, [key, onSettingButtonClick]); return {_('Failed: %s', error)}} disabled={loading} />; };