import React, { useEffect, useLayoutEffect, useState } from 'react'; import { FlatList, StyleSheet } from 'react-native'; import { useSelector } from 'react-redux'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { HeaderBackButton, StackNavigationOptions, StackNavigationProp } from '@react-navigation/stack'; import { RouteProp } from '@react-navigation/core'; import { IApplicationState } 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 { themes } from '../../constants/colors'; 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 RocketChat from '../../lib/rocketchat'; import SearchHeader from '../../containers/SearchHeader'; import { TThreadModel } from '../../definitions/IThread'; import Item from './Item'; 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): JSX.Element => { const rid = route.params?.rid; const t = route.params?.t; const baseUrl = useSelector((state: IApplicationState) => state.server?.server); const isMasterDetail = useSelector((state: IApplicationState) => 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 { theme } = useTheme(); const insets = useSafeAreaInsets(); const load = async (text = '') => { if (loading) { return; } setLoading(true); try { const result = await RocketChat.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={themes[theme].headerTintColor} /> ), headerTitleAlign: 'center', headerTitle: I18n.t('Discussions'), headerTitleContainerStyle: { left: null, right: null }, 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: TThreadModel }) => ( ); if (!discussions?.length) { return ; } return ( item.msg} style={{ backgroundColor: themes[theme].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;