import React , { useEffect , useRef } from 'react' ; import { StyleSheet , KeyboardAvoidingView , ScrollView , Dimensions , } from 'react-native' ; import Constants from 'expo-constants' ; import { Actions } from 'react-native-router-flux' ; import { isiOS } from '../../utils/platform' ; import MessageList from './MessageList' ; import Input from './Input' ; import PageContainer from '../../components/PageContainer' ; import { Friend , Group , Linkman } from '../../types/redux' ; import { useFocusLinkman , useIsLogin , useSelfId , useStore , } from '../../hooks/useStore' ; import { getDefaultGroupOnlineMembers , getGroupOnlineMembers , getUserOnlineStatus , } from '../../service' ; import action from '../../state/action' ; import { formatLinkmanName } from '../../utils/linkman' ; import fetch from '../../utils/fetch' ; let lastMessageIdCache = '' ; const keyboardOffset = ( ( ) => { const { width , height } = Dimensions . get ( 'window' ) ; const screenRatio = height / width ; if ( screenRatio === 667 / 375 ) { return 64 ; } if ( screenRatio === 736 / 414 ) { return 64 ; } if ( screenRatio === 812 / 375 ) { return 86 ; } if ( screenRatio === 896 / 414 ) { return 86 ; } if ( screenRatio === 844 / 390 ) { return 64 ; } if ( screenRatio === 926 / 428 ) { return 64 ; } return Constants . statusBarHeight + 44 ; } ) ( ) ; export default function Chat ( ) { const isLogin = useIsLogin ( ) ; const self = useSelfId ( ) ; const { focus } = useStore ( ) ; const linkman = useFocusLinkman ( ) ; const $messageList = useRef < ScrollView > ( ) ; async function fetchGroupOnlineMembers ( ) { let onlineMembers = [ ] ; if ( isLogin ) { onlineMembers = await getGroupOnlineMembers ( focus ) ; } else { onlineMembers = await getDefaultGroupOnlineMembers ( ) ; } if ( onlineMembers ) { action . updateGroupProperty ( focus , 'members' , onlineMembers ) ; } } async function fetchUserOnlineStatus ( ) { const isOnline = await getUserOnlineStatus ( focus . replace ( self , '' ) ) ; action . updateFriendProperty ( focus , 'isOnline' , isOnline ) ; } useEffect ( ( ) => { if ( ! linkman || ! isLogin ) { return ; } const request = linkman . type === 'group' ? fetchGroupOnlineMembers : fetchUserOnlineStatus ; request ( ) ; const timer = setInterval ( ( ) => request ( ) , 1000 * 60 ) ; return ( ) => clearInterval ( timer ) ; } , [ focus , isLogin ] ) ; useEffect ( ( ) => { if ( Actions . currentScene !== 'chat' ) { return ; } Actions . refresh ( { title : formatLinkmanName ( linkman as Linkman ) , } ) ; } , [ ( linkman as Group ) . members , ( linkman as Friend ) . isOnline ] ) ; async function intervalUpdateHistory ( ) { if ( isLogin && linkman ) { if ( linkman . messages . length > 0 ) { const lastMessageId = linkman . messages [ linkman . messages . length - 1 ] . _id ; if ( lastMessageId !== lastMessageIdCache ) { lastMessageIdCache = lastMessageId ; await fetch ( 'updateHistory' , { linkmanId : focus , messageId : lastMessageId , } ) ; } } } } useEffect ( ( ) => { const timer = setInterval ( intervalUpdateHistory , 1000 * 5 ) ; return ( ) => clearInterval ( timer ) ; } , [ focus ] ) ; function scrollToEnd ( time = 0 ) { if ( time > 200 ) { return ; } if ( $messageList . current ) { $messageList . current ! . scrollToEnd ( { animated : false } ) ; } setTimeout ( ( ) => { scrollToEnd ( time + 50 ) ; } , 50 ) ; } function handleInputHeightChange ( ) { if ( $messageList . current ) { scrollToEnd ( ) ; } } return ( < PageContainer disableSafeAreaView > < KeyboardAvoidingView style = { styles . container } behavior = { isiOS ? 'padding' : 'height' } keyboardVerticalOffset = { keyboardOffset } > { } < MessageList $scrollView = { $messageList } / > < Input onHeightChange = { handleInputHeightChange } /> < /KeyboardAvoidingView> < /PageContainer>); } const styles = StyleSheet . create ( { container : { flex : 1 , } , } ) ;