import React, { useEffect, useLayoutEffect, useRef, useState } from 'react'; import { FlatList, StyleSheet } from 'react-native'; import { StackNavigationOptions, StackNavigationProp } from '@react-navigation/stack'; import { HeaderBackButton } from '@react-navigation/elements'; import { RouteProp } from '@react-navigation/core'; import { IMessageFromServer, TThreadModel } from '../../definitions'; import { ChatsStackParamList } from '../../stacks/types'; import ActivityIndicator from '../../containers/ActivityIndicator'; import I18n from '../../i18n'; import StatusBar from '../../containers/StatusBar'; import log from '../../lib/methods/helpers/log'; import { isIOS, useDebounce } from '../../lib/methods/helpers'; import SafeAreaView from '../../containers/SafeAreaView'; import * as HeaderButton from '../../containers/HeaderButton'; import * as List from '../../containers/List'; import BackgroundContainer from '../../containers/BackgroundContainer'; import { useTheme } from '../../theme'; import SearchHeader from '../../containers/SearchHeader'; 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 = useRef(0); const searchText = useRef(''); const offset = useRef(0); const { colors } = useTheme(); const load = async () => { if (loading) { return; } setLoading(true); try { const result = await Services.getDiscussions({ roomId: rid, offset: offset.current, count: API_FETCH_COUNT, text: searchText.current }); if (result.success) { offset.current += result.count; total.current = result.total; if (isSearching) { setSearch(prevState => (offset.current ? [...prevState, ...result.messages] : result.messages)); } else { setDiscussions(result.messages); } } setLoading(false); } catch (e) { log(e); setLoading(false); } }; const onSearchChangeText = useDebounce((text: string) => { setIsSearching(true); setSearch([]); searchText.current = text; offset.current = 0; load(); }, 500); const onCancelSearchPress = () => { setIsSearching(false); setSearch([]); searchText.current = ''; offset.current = 0; }; const onSearchPress = () => { setIsSearching(true); }; const setHeader = () => { let options: Partial; if (isSearching) { options = { headerTitleAlign: 'left', headerTitleContainerStyle: { flex: 1, marginHorizontal: 0, marginRight: 15, maxWidth: undefined }, headerRightContainerStyle: { flexGrow: 0 }, headerLeft: () => ( ), headerTitle: () => ( ), headerRight: () => null }; return options; } options = { headerTitleAlign: 'center', headerTitle: I18n.t('Discussions'), headerTitleContainerStyle: {}, headerRightContainerStyle: { flexGrow: 1 }, headerLeft: () => ( navigation.pop()} tintColor={colors.headerTintColor} testID='header-back' /> ), headerRight: () => ( ) }; if (isMasterDetail) { options.headerLeft = () => ; } return options; }; useEffect(() => { load(); }, []); useLayoutEffect(() => { const options = setHeader(); navigation.setOptions(options); }, [navigation, isSearching]); const onDiscussionPress = (item: TThreadModel) => { if (item.drid && item.t) { navigation.push('RoomView', { rid: item.drid, prid: item.rid, name: item.msg, t }); } }; const renderItem = ({ item }: { item: IMessageFromServer }) => ( ); if (!discussions?.length) { return ; } return ( item._id} style={{ backgroundColor: colors.backgroundColor }} contentContainerStyle={styles.contentContainer} onEndReachedThreshold={0.5} removeClippedSubviews={isIOS} onEndReached={() => isSearching && offset.current < total.current && load()} ItemSeparatorComponent={List.Separator} ListFooterComponent={loading ? : null} scrollIndicatorInsets={{ right: 1 }} /> ); }; export default DiscussionsView;