import React, { useEffect, useLayoutEffect, useState } from 'react'; import { FlatList, StyleSheet } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { HeaderBackButton, StackNavigationOptions, StackNavigationProp } from '@react-navigation/stack'; import { RouteProp } from '@react-navigation/core'; import { IMessageFromServer } from '../../definitions'; import { ChatsStackParamList } from '../../stacks/types'; import ActivityIndicator from '../../containers/ActivityIndicator'; import I18n from '../../i18n'; import StatusBar from '../../containers/StatusBar'; import log from '../../utils/log'; import debounce from '../../utils/debounce'; import SafeAreaView from '../../containers/SafeAreaView'; import * as HeaderButton from '../../containers/HeaderButton'; import * as List from '../../containers/List'; import BackgroundContainer from '../../containers/BackgroundContainer'; import { isIOS } from '../../utils/deviceInfo'; import { getHeaderTitlePosition } from '../../containers/Header'; import { useTheme } from '../../theme'; import SearchHeader from '../../containers/SearchHeader'; import { TThreadModel } from '../../definitions/IThread'; import Item from './Item'; import { Services } from '../../lib/services'; import { useAppSelector } from '../../lib/hooks'; const API_FETCH_COUNT = 50; const styles = StyleSheet.create({ contentContainer: { marginBottom: 30 } }); interface IDiscussionsViewProps { navigation: StackNavigationProp; route: RouteProp; item: TThreadModel; } const DiscussionsView = ({ navigation, route }: IDiscussionsViewProps): React.ReactElement => { const rid = route.params?.rid; const t = route.params?.t; const baseUrl = useAppSelector(state => state.server?.server); const isMasterDetail = useAppSelector(state => state.app?.isMasterDetail); const [loading, setLoading] = useState(false); const [discussions, setDiscussions] = useState([]); const [search, setSearch] = useState([]); const [isSearching, setIsSearching] = useState(false); const [total, setTotal] = useState(0); const [searchTotal, setSearchTotal] = useState(0); const { colors } = useTheme(); const insets = useSafeAreaInsets(); const load = async (text = '') => { if (loading) { return; } setLoading(true); try { const result = await Services.getDiscussions({ roomId: rid, offset: isSearching ? search.length : discussions.length, count: API_FETCH_COUNT, text }); if (result.success) { if (isSearching) { setSearch(result.messages); setSearchTotal(result.total); } else { setDiscussions(result.messages); setTotal(result.total); } } setLoading(false); } catch (e) { log(e); setLoading(false); } }; const onSearchChangeText = debounce(async (text: string) => { setIsSearching(true); await load(text); }, 300); const onCancelSearchPress = () => { setIsSearching(false); setSearch([]); setSearchTotal(0); }; const onSearchPress = () => { setIsSearching(true); }; const setHeader = () => { let options: Partial; if (isSearching) { const headerTitlePosition = getHeaderTitlePosition({ insets, numIconsRight: 1 }); options = { headerTitleAlign: 'left', headerLeft: () => ( ), headerTitle: () => ( ), headerTitleContainerStyle: { left: headerTitlePosition.left, right: headerTitlePosition.right }, headerRight: () => null }; return options; } options = { headerLeft: () => ( navigation.pop()} tintColor={colors.headerTintColor} /> ), headerTitleAlign: 'center', headerTitle: I18n.t('Discussions'), headerTitleContainerStyle: { left: 0, right: 0 }, headerRight: () => ( ) }; if (isMasterDetail) { options.headerLeft = () => ; } return options; }; useEffect(() => { load(); }, []); useLayoutEffect(() => { const options = setHeader(); navigation.setOptions(options); }, [navigation, isSearching]); const onDiscussionPress = debounce( (item: TThreadModel) => { if (item.drid && item.t) { navigation.push('RoomView', { rid: item.drid, prid: item.rid, name: item.msg, t }); } }, 1000, true ); const renderItem = ({ item }: { item: IMessageFromServer }) => ( ); if (!discussions?.length) { return ; } return ( item.msg} style={{ backgroundColor: colors.backgroundColor }} contentContainerStyle={styles.contentContainer} onEndReachedThreshold={0.5} removeClippedSubviews={isIOS} onEndReached={() => (isSearching ? searchTotal : total) > API_FETCH_COUNT ?? load()} ItemSeparatorComponent={List.Separator} ListFooterComponent={loading ? : null} scrollIndicatorInsets={{ right: 1 }} /> ); }; export default DiscussionsView;