import * as React from 'react'; import { UpdateSettingValueCallback } from './types'; import { View, Text, TextInput } from 'react-native'; import Setting, { AppType } from '@joplin/lib/models/Setting'; import Dropdown from '../../Dropdown'; import { ConfigScreenStyles } from './configScreenStyles'; import Slider from '@react-native-community/slider'; import SettingsToggle from './SettingsToggle'; import FileSystemPathSelector from './FileSystemPathSelector'; import shim from '@joplin/lib/shim'; import { themeStyle } from '../../global-style'; import { useId } from 'react'; interface Props { settingId: string; // The value associated with the given settings key // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied value: any; styles: ConfigScreenStyles; themeId: number; updateSettingValue: UpdateSettingValueCallback; } const SettingComponent: React.FunctionComponent = props => { const themeId = props.themeId; const theme = themeStyle(themeId); // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied const output: any = 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 containerStyle = props.styles.getContainerStyle(!!settingDescription); const labelId = useId(); 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.updateSettingValue(props.settingId, itemValue); }} accessibilityHint={label} /> {descriptionComp} ); } else if (md.type === Setting.TYPE_BOOL) { return ( ); } else if (md.type === Setting.TYPE_INT) { const unitLabel = md.unitLabel ? md.unitLabel(props.value) : props.value; const minimum = 'minimum' in md ? md.minimum : 0; const maximum = 'maximum' in md ? md.maximum : 10; const label = md.label(); // Note: Do NOT add the minimumTrackTintColor and maximumTrackTintColor props // on the Slider as they are buggy and can crash the app on certain devices. // https://github.com/laurent22/joplin/issues/2733 // https://github.com/react-native-community/react-native-slider/issues/161 return ( {label} {unitLabel} void props.updateSettingValue(props.settingId, newValue)} accessibilityHint={label} /> ); } else if (md.type === Setting.TYPE_STRING) { if (['sync.2.path', 'plugins.devPluginPaths'].includes(md.key) && (shim.fsDriver().isUsingAndroidSAF() || shim.mobilePlatform() === 'web')) { return ( ); } return ( {md.label()} void props.updateSettingValue(props.settingId, newValue)} secureTextEntry={!!md.secure} aria-labelledby={labelId} /> {descriptionComp} ); } else if (md.type === Setting.TYPE_BUTTON) { // TODO: Not yet supported } else if (Setting.value('env') === 'dev') { throw new Error(`Unsupported setting type: ${md.type}`); } return output; }; export default SettingComponent;