import * as React from 'react'; import { AppType, SettingMetadataSection, SettingSectionSource } from '@joplin/lib/models/Setting'; import { FunctionComponent, useEffect, useMemo, useState } from 'react'; import { ConfigScreenStyles } from '../configScreenStyles'; import { FlatList, View, ViewStyle } from 'react-native'; import { Text } from 'react-native-paper'; import { settingsSections } from '@joplin/lib/components/shared/config/config-shared'; import { _ } from '@joplin/lib/locale'; import SectionTab from './SectionTab'; interface Props { styles: ConfigScreenStyles; width: number|undefined; // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied settings: Record; selectedSectionName: string|null; openSection: (sectionName: string)=> void; } type SectionDivider = { divider: boolean; label: string; name: string; source?: string }; const SectionSelector: FunctionComponent = props => { type SectionListType = (SectionDivider|SettingMetadataSection)[]; const sections = useMemo((): SectionListType => { const allSections = settingsSections({ device: AppType.Mobile, settings: props.settings }); const builtInSections = []; const pluginSections = []; for (const section of allSections) { if (section.source === SettingSectionSource.Plugin) { pluginSections.push(section); } else { builtInSections.push(section); } } let result: SectionListType = builtInSections; if (pluginSections.length > 0) { result = result.concat([ { label: _('Plugins'), name: 'plugins-divider', divider: true }, ...pluginSections, ]); } return result; }, [props.settings]); const styles = props.styles.styleSheet; const onRenderButton = ({ item }: { item: SettingMetadataSection|SectionDivider }) => { const section = item; const selected = props.selectedSectionName === section.name; if ('divider' in item && item.divider) { return ( {item.label} ); } else { return ( props.openSection(section.name)} /> ); } }; const [flatListRef, setFlatListRef] = useState(null); useEffect(() => { if (flatListRef && props.selectedSectionName) { let selectedIndex = 0; for (const section of sections) { if (section.name === props.selectedSectionName) { break; } selectedIndex ++; } flatListRef.scrollToIndex({ index: selectedIndex, viewPosition: 0.5, }); } }, [props.selectedSectionName, flatListRef, sections]); const containerStyle: ViewStyle = useMemo(() => ({ width: props.width, maxWidth: props.width, minWidth: props.width, flex: 1, }), [props.width]); return ( item.name} onScrollToIndexFailed={({ index, averageItemLength }) => { // Scrolling to a particular index can fail if the item at that index hasn't been rendered yet. // This shouldn't happen often, so a guess should be sufficient. flatListRef.scrollToOffset({ offset: (index + 0.5) * averageItemLength }); }} /> ); }; export default SectionSelector;