diff --git a/src/screens/browse/components/BrowseTabs.tsx b/src/screens/browse/components/BrowseTabs.tsx index b091205ac..681575d3d 100644 --- a/src/screens/browse/components/BrowseTabs.tsx +++ b/src/screens/browse/components/BrowseTabs.tsx @@ -5,9 +5,7 @@ import { View, Text, StyleSheet, - SectionList, RefreshControl, - ListRenderItem, } from 'react-native'; import { useNavigation } from '@react-navigation/native'; import { useBrowseSettings, usePlugins } from '@hooks/persisted'; @@ -30,7 +28,6 @@ import Animated, { useSharedValue, withTiming, } from 'react-native-reanimated'; -import { groupBy } from 'lodash-es'; interface AvailableTabProps { searchText: string; @@ -248,7 +245,7 @@ export const InstalledTab = memo( ); interface AvailablePluginCardProps { - plugin: PluginItem; + plugin: PluginItem & { header: boolean }; theme: ThemeColors; installPlugin: (plugin: PluginItem) => Promise; } @@ -270,61 +267,76 @@ const AvailablePluginCard = ({ lineHeight: ratio.value * 20, })); return ( - - - - - - {plugin.name} - - + {plugin.header ? ( + + {plugin.lang} + + ) : null} + + + - {`${plugin.lang} - ${plugin.version}`} - + /> + + + {plugin.name} + + + {`${plugin.lang} - ${plugin.version}`} + + + { + ratio.value = withTiming(0, { duration: 500 }); + installPlugin(plugin) + .then(() => { + showToast( + getString('browseScreen.installedPlugin', { + name: plugin.name, + }), + ); + }) + .catch((error: Error) => { + showToast(error.message); + ratio.value = 1; + }); + }} + size={22} + theme={theme} + /> - { - ratio.value = withTiming(0, { duration: 500 }); - installPlugin(plugin) - .then(() => { - showToast( - getString('browseScreen.installedPlugin', { - name: plugin.name, - }), - ); - }) - .catch((error: Error) => { - showToast(error.message); - ratio.value = 1; - }); - }} - size={22} - theme={theme} - /> - + ); }; @@ -332,78 +344,55 @@ export const AvailableTab = memo(({ searchText, theme }: AvailableTabProps) => { const navigation = useNavigation(); const [refreshing, setRefreshing] = useState(false); - const { - filteredAvailablePlugins, - languagesFilter, - refreshPlugins, - installPlugin, - } = usePlugins(); + const { filteredAvailablePlugins, refreshPlugins, installPlugin } = + usePlugins(); - const sections = useMemo(() => { - const list = []; - const lowerCaseSearchText = searchText.toLocaleLowerCase(); - const group = groupBy( - searchText - ? filteredAvailablePlugins.filter( - plg => - plg.name.toLocaleLowerCase().includes(lowerCaseSearchText) || - plg.id.toLocaleLowerCase().includes(lowerCaseSearchText), - ) - : filteredAvailablePlugins, - 'lang', - ); - for (const language of languagesFilter) { - if (group[language]?.length) { - list.push({ - header: language, - data: group[language], - }); - } + const searchedPlugins = useMemo(() => { + let res = filteredAvailablePlugins; + if (searchText) { + const lowerCaseSearchText = searchText.toLocaleLowerCase(); + res = filteredAvailablePlugins.filter( + plg => + plg.name.toLocaleLowerCase().includes(lowerCaseSearchText) || + plg.id.includes(lowerCaseSearchText), + ); } - return list; + let previousLang: string | null = null; + return res + .sort((a, b) => a.lang.localeCompare(b.lang)) + .map(plg => { + if (plg.lang !== previousLang) { + previousLang = plg.lang; + return { ...plg, header: true }; + } else { + return { ...plg, header: false }; + } + }); }, [searchText, filteredAvailablePlugins]); - const renderItem: ListRenderItem = useCallback( - ({ item }) => { - return ( - - ); - }, - [theme, sections], - ); + const renderItem: FlashListRenderItem = + useCallback( + ({ item }) => { + return ( + + ); + }, + [theme, searchedPlugins], + ); return ( - item.id + '_available'} - contentContainerStyle={{ flexGrow: 1 }} - ListEmptyComponent={ - - navigation.navigate('MoreStack', { - screen: 'SettingsStack', - params: { - screen: 'RespositorySettings', - }, - }), - }, - ]} - theme={theme} - /> - } refreshControl={ { progressBackgroundColor={theme.primary} /> } - renderItem={renderItem} - renderSectionHeader={({ section: { header, data } }) => - data.length ? ( - - {header} - - ) : null + ListEmptyComponent={ + + + navigation.navigate('MoreStack', { + screen: 'SettingsStack', + params: { + screen: 'RespositorySettings', + }, + }), + }, + ]} + theme={theme} + /> + } /> ); @@ -467,8 +471,4 @@ const styles = StyleSheet.create({ alignItems: 'center', paddingHorizontal: 8, }, - spinner: { - marginRight: 12, - marginLeft: -1, - }, });