diff --git a/README.md b/README.md index 9a5fbe5dd..f13cefe27 100644 --- a/README.md +++ b/README.md @@ -67,12 +67,14 @@
-## The future of GiftedChat 🎉 +## The future of GiftedChat 🎉 + Please give us your advice: [Related PR](https://github.com/FaridSafi/react-native-gifted-chat/pull/1775) ## Please vote **GiftedChat** depends on other packages and some needs a boost, please vote for PRs will improve it, thanks: + - https://github.com/watadarkstar/react-native-typing-animation/issues/18 ## Features @@ -100,23 +102,24 @@ Please give us your advice: [Related PR](https://github.com/FaridSafi/react-nati - Use version `0.0.10` for RN `< 0.40.0` ## Testing + `Test_ID` is exported as constants that can be used in your testing library of choice -Gifted Chat uses `onLayout` to determine the height of the chat container. To trigger `onLayout` during your tests, you can run the following bits of code. +Gifted Chat uses `onLayout` to determine the height of the chat container. To trigger `onLayout` during your tests, you can run the following bits of code. ```typescript const WIDTH = 200 // or any number const HEIGHT = 2000 // or any number -const loadingWrapper = getByTestId(Test_ID.LOADING.WRAPPER) -fireEvent(loadingWrapper, "layout", { +const loadingWrapper = getByTestId(TEST_ID.LOADING_WRAPPER) +fireEvent(loadingWrapper, 'layout', { nativeEvent: { layout: { width: WIDTH, height: HEIGHT, }, }, -}); +}) ``` ## Installation @@ -143,7 +146,7 @@ import React, { useState, useCallback, useEffect } from 'react' import { GiftedChat } from 'react-native-gifted-chat' export function Example() { - const [messages, setMessages] = useState([]); + const [messages, setMessages] = useState([]) useEffect(() => { setMessages([ @@ -161,7 +164,9 @@ export function Example() { }, []) const onSend = useCallback((messages = []) => { - setMessages(previousMessages => GiftedChat.append(previousMessages, messages)) + setMessages(previousMessages => + GiftedChat.append(previousMessages, messages), + ) }, []) return ( diff --git a/example/App.tsx b/example/App.tsx index ef57ad4dc..56b5df8df 100644 --- a/example/App.tsx +++ b/example/App.tsx @@ -1,33 +1,20 @@ -import MaterialIcons from '@expo/vector-icons/MaterialIcons' -import * as Linking from 'expo-linking' -import { SafeAreaView } from 'react-native-safe-area-context' -import AppLoading from 'expo-app-loading' -import React, { Component } from 'react' -import { StyleSheet, View, Text, Platform, Alert } from 'react-native' +import { MaterialIcons } from '@expo/vector-icons' +import React, { useCallback, useReducer } from 'react' +import { Alert, Linking, Platform, StyleSheet, Text, View } from 'react-native' import { - Bubble, GiftedChat, - SystemMessage, IMessage, Send, SendProps, + SystemMessage, } from 'react-native-gifted-chat' - +import { SafeAreaView } from 'react-native-safe-area-context' +import { NavBar } from './components/navbar' import AccessoryBar from './example-expo/AccessoryBar' import CustomActions from './example-expo/CustomActions' import CustomView from './example-expo/CustomView' -import messagesData from './example-expo/data/messages' import earlierMessages from './example-expo/data/earlierMessages' -import { NavBar } from './components/navbar' - -const styles = StyleSheet.create({ - container: { flex: 1, backgroundColor: '#f5f5f5', }, - content: { backgroundColor: "#ffffff", flex: 1, } -}) - -const filterBotMessages = message => - !message.system && message.user && message.user._id && message.user._id === 2 -const findStep = step => message => message._id === step +import messagesData from './example-expo/data/messages' const user = { _id: 1, @@ -40,92 +27,98 @@ const otherUser = { avatar: 'https://facebook.github.io/react/img/logo_og.png', } -export default class App extends Component { - state = { - inverted: false, - step: 0, - messages: [], - loadEarlier: true, - typingText: null, - isLoadingEarlier: false, - appIsReady: false, - isTyping: false, - } - - _isMounted = false +interface IState { + messages: any[] + step: number + loadEarlier?: boolean + isLoadingEarlier?: boolean + isTyping: boolean +} - componentDidMount() { - this._isMounted = true - // init with only system messages - this.setState({ - messages: messagesData, // messagesData.filter(message => message.system), - appIsReady: true, - isTyping: false, - }) - } +enum ActionKind { + SEND_MESSAGE = 'SEND_MESSAGE', + LOAD_EARLIER_MESSAGES = 'LOAD_EARLIER_MESSAGES', + LOAD_EARLIER_START = 'LOAD_EARLIER_START', + SET_IS_TYPING = 'SET_IS_TYPING', + // LOAD_EARLIER_END = 'LOAD_EARLIER_END', +} - componentWillUnmount() { - this._isMounted = false - } +// An interface for our actions +interface StateAction { + type: ActionKind + payload?: any +} - onLoadEarlier = () => { - this.setState(() => { +function reducer(state: IState, action: StateAction) { + switch (action.type) { + case ActionKind.SEND_MESSAGE: { + return { + ...state, + step: state.step + 1, + messages: action.payload, + } + } + case ActionKind.LOAD_EARLIER_MESSAGES: { + return { + ...state, + loadEarlier: true, + isLoadingEarlier: false, + messages: action.payload, + } + } + case ActionKind.LOAD_EARLIER_START: { return { + ...state, isLoadingEarlier: true, } - }) - - setTimeout(() => { - if (this._isMounted === true) { - this.setState((previousState: any) => { - return { - messages: GiftedChat.prepend( - previousState.messages, - earlierMessages() as IMessage[], - Platform.OS !== 'web', - ), - loadEarlier: true, - isLoadingEarlier: false, - } - }) + } + case ActionKind.SET_IS_TYPING: { + return { + ...state, + isTyping: action.payload, } - }, 1500) // simulating network + } } +} - onSend = (messages = []) => { - const step = this.state.step + 1 - this.setState((previousState: any) => { +const App = () => { + const [state, dispatch] = useReducer(reducer, { + messages: messagesData, + step: 0, + loadEarlier: true, + isLoadingEarlier: false, + isTyping: false, + }) + + const onSend = useCallback( + (messages: any[]) => { const sentMessages = [{ ...messages[0], sent: true, received: true }] - return { - messages: GiftedChat.append( - previousState.messages, - sentMessages, - Platform.OS !== 'web', - ), - step, - } - }) - // for demo purpose - // setTimeout(() => this.botSend(step), Math.round(Math.random() * 1000)) - } + const newMessages = GiftedChat.append( + state.messages, + sentMessages, + Platform.OS !== 'web', + ) - botSend = (step = 0) => { - const newMessage = (messagesData as IMessage[]) - .reverse() - // .filter(filterBotMessages) - .find(findStep(step)) - if (newMessage) { - this.setState((previousState: any) => ({ - messages: GiftedChat.append( - previousState.messages, - [newMessage], - Platform.OS !== 'web', - ), - })) - } - } + dispatch({ type: ActionKind.SEND_MESSAGE, payload: newMessages }) + }, + [dispatch, state.messages], + ) + + const onLoadEarlier = useCallback(() => { + console.log('loading') + dispatch({ type: ActionKind.LOAD_EARLIER_START }) + setTimeout(() => { + const newMessages = GiftedChat.prepend( + state.messages, + earlierMessages() as IMessage[], + Platform.OS !== 'web', + ) - parsePatterns = (_linkStyle: any) => { + dispatch({ type: ActionKind.LOAD_EARLIER_MESSAGES, payload: newMessages }) + }, 1500) // simulating network + }, [dispatch, state.messages]) + + const parsePatterns = useCallback((_linkStyle: any) => { return [ { pattern: /#(\w+)/, @@ -133,79 +126,20 @@ export default class App extends Component { onPress: () => Linking.openURL('http://gifted.chat'), }, ] - } - - renderCustomView(props) { - return