import * as React from 'react'; import type { // DefaultSectionT, SectionListData, // ViewabilityConfig, // ViewToken, } from 'react-native'; import { useDelayExecTask, useLifecycle } from '../../hook'; import type { FlatListRef } from '../../ui/FlatList'; import type { SectionListRef } from '../../ui/SectionList'; import { ListIndex } from '../ListIndex'; import type { DefaultListIndexPropsT, ListStateType } from '../types'; import type { UseListBasicProps } from './types'; export function useListBasic(props: UseListBasicProps) { const { onVisibleItems, onInit, onUnInit } = props; const listType = React.useRef<'FlatList' | 'SectionList'>('FlatList').current; const loadType = React.useRef<'once' | 'multiple'>( props.loadType ?? 'once' ).current; const [listState, setListState] = React.useState( props.listState ?? 'normal' ); const isAutoLoad = React.useRef(props.isAutoLoad ?? true).current; const isSort = React.useRef(props.isSort ?? true).current; const isLoadAll = React.useRef(props.isLoadAll ?? true).current; const isShowAfterLoaded = React.useRef( props.isShowAfterLoaded ?? true ).current; const isVisibleUpdate = React.useRef(props.isVisibleUpdate ?? false).current; const isAutoUpdate = React.useRef(props.isAutoUpdate ?? false).current; const isEventUpdate = React.useRef(props.isEventUpdate ?? true).current; const enableRefresh = React.useRef(props.enableRefresh ?? false).current; const enableMore = React.useRef(props.enableMore ?? true).current; const [refreshing, setRefreshing] = React.useState(props.refreshing ?? false); const onSearchRef = React.useRef<(keyword: string) => void>({} as any); const viewabilityConfigRef = React.useRef({ // minimumViewTime: 1000, viewAreaCoveragePercentThreshold: 50, itemVisiblePercentThreshold: 50, waitForInteraction: false, }); const { delayExecTask: onViewableItemsChanged } = useDelayExecTask( 500, React.useCallback( (info: { viewableItems: Array; changed: Array }) => { const list = info.viewableItems.map((v) => { return v.item as ItemT; }); onVisibleItems?.(list); }, [onVisibleItems] ) ); const setOnSearch = React.useCallback( (onSearch: (keyword: string) => void) => { onSearchRef.current = onSearch; }, [] ); const { delayExecTask: deferSearch } = useDelayExecTask( 500, React.useCallback((keyword: string) => { onSearchRef.current?.(keyword); }, []) ); const onRefresh = React.useCallback(() => { setRefreshing(true); setTimeout(() => { setRefreshing(false); }, 1000); }, []); const onMore = React.useCallback(() => {}, []); useLifecycle( React.useCallback(async (state: any) => { if (state === 'load') { onInit?.(); } else if (state === 'unload') { onUnInit?.(); } // eslint-disable-next-line react-hooks/exhaustive-deps }, []) ); return { listState, setListState, listType, onRefresh: enableRefresh === true ? onRefresh : undefined, onMore: enableMore === true ? onMore : undefined, isAutoLoad, isSort, isLoadAll, isShowAfterLoaded, loadType, isVisibleUpdate, isAutoUpdate, isEventUpdate, refreshing: enableRefresh === true ? refreshing : undefined, setRefreshing: enableRefresh === true ? setRefreshing : undefined, viewabilityConfig: isVisibleUpdate === true ? viewabilityConfigRef.current : undefined, onViewableItemsChanged: isVisibleUpdate === true ? onViewableItemsChanged : undefined, deferSearch, setOnSearch, enableRefresh, }; } export function useFlatList( props: Omit, 'listType'> ) { const basics = useListBasic({ ...props, listType: 'FlatList' }); const dataRef = React.useRef([]); const [data, setData] = React.useState>(dataRef.current); const ListItem: React.ComponentType = () => null; const ref = React.useRef>({} as any); return { ...basics, dataRef, data, setData, ListItem, ref, }; } export function useSectionList< ItemT, SectionT extends any, ListIndexPropsT extends DefaultListIndexPropsT, >(props: Omit, 'listType'>) { const basics = useListBasic({ ...props, listType: 'FlatList' }); const sectionsRef = React.useRef[]>([]); const [sections, setSection] = React.useState< ReadonlyArray> >([]); const [indexTitles, setIndexTitles] = React.useState([]); const ref = React.useRef>({} as any); const AlphabeticIndex: React.FC = ListIndex; return { ...basics, sectionsRef, sections, setSection, indexTitles, setIndexTitles, AlphabeticIndex, ref, }; }