0.4.14 • Published 3 years ago

react-native-easy-chat-ui v0.4.14

Weekly downloads
807
License
MIT
Repository
github
Last release
3 years ago

react-native-easy-chat-ui

中文文档

npm npm npm npm

ScreenShots

Installation

  • yarn add @react-native-community/viewpager
  • react-native link @react-native-community/viewpager
  • npm: npm install react-native-easy-chat-ui --save
  • Yarn: yarn add react-native-easy-chat-ui

Dependency

  • Use version 0.2.x for RN >= 0.44.0
  • Use version 0.1.x for RN < 0.44.0

Example

import React, { Component } from 'react';
import {
  Platform,
  StyleSheet,
  Text,
  View,
  StatusBar,
  PermissionsAndroid
} from 'react-native';
import { Header, NavigationActions } from 'react-navigation'
import {AudioRecorder, AudioUtils} from 'react-native-audio'
import RNFS from 'react-native-fs'
import Sound from 'react-native-sound'
import { ChatScreen } from 'react-native-easy-chat-ui'


class Example extends React.Component {
  state = {
     messages: [
            {
              id: `1`,
              type: 'text',
              content: 'hello world',
              targetId: '12345678',
              chatInfo: {
                avatar: require('../../source/defaultAvatar.png'),
                id: '12345678',
                nickName: 'Test'
              },
              renderTime: true,
              sendStatus: 0,
              time: '1542006036549'
            },
            {
              id: `2`,
              type: 'text',
              content: 'hi/{se}',
              targetId: '12345678',
              chatInfo: {
                avatar: require('../../source/defaultAvatar.png'),
                id: '12345678',
                nickName: 'Test'
              },
              renderTime: true,
              sendStatus: 0,
              time: '1542106036549'
            },
            {
              id: `3`,
              type: 'image',
              content: {
                uri: 'https://upload-images.jianshu.io/upload_images/11942126-044bd33212dcbfb8.jpg?imageMogr2/auto-orient/strip|imageView2/1/w/300/h/240',
                width: 100,
                height: 80,
              } ,
              targetId: '12345678',
              chatInfo: {
                avatar: require('../../source/defaultAvatar.png'),
                id: '12345678',
                nickName: 'Test'
              },
              renderTime: false,
              sendStatus: 0,
              time: '1542106037000'
            },
            {
              id: `4`,
              type: 'text',
              content: '你好/{weixiao}',
              targetId: '88886666',
              chatInfo: {
                avatar: require('../../source/avatar.png'),
                id: '12345678'
              },
              renderTime: true,
              sendStatus: -2,
              time: '1542177036549'
            },
            {
              id: `5`,
              type: 'voice',
              content: {
                uri: 'http://m10.music.126.net/20190810141311/78bf2f6e1080052bc0259afa91cf030d/ymusic/d60e/d53a/a031/1578f4093912b3c1f41a0bfd6c10115d.mp3',
                length: 10
              },
              targetId: '12345678',
              chatInfo: {
                avatar: require('../../source/defaultAvatar.png'),
                id: '12345678',
                nickName: 'Test'
              },
              renderTime: true,
              sendStatus: 1,
              time: '1542260667161'
            },
            {
              id: `6`,
              type: 'voice',
              content: {
                uri: 'http://m10.music.126.net/20190810141311/78bf2f6e1080052bc0259afa91cf030d/ymusic/d60e/d53a/a031/1578f4093912b3c1f41a0bfd6c10115d.mp3',
                length: 30
              },
              targetId: '88886666',
              chatInfo: {
                avatar: require('../../source/avatar.png'),
                id: '12345678'
              },
              renderTime: true,
              sendStatus: 0,
              time: '1542264667161'
            },
          ],
          // chatBg: require('../../source/bg.jpg'),
          inverted: false,  // require
          voiceHandle: true,
          currentTime: 0,
          recording: false,
          paused: false,
          stoppedRecording: false,
          finished: false,
          audioPath: '',
          voicePlaying: false,
          voiceLoading: false
  }


  sendMessage = (type, content, isInverted) => {
      console.log(type, content, isInverted, 'msg')
    }

  render() {
    return (
      <ChatScreen
        ref={(e) => this.chat = e}
        messageList={this.state.messages}
        sendMessage={this.sendMessage}
      />
    )
  }
}

Advanced example (How to record voice)

cd Demo
yarn
react-native run-ios or react-native run-android

About Message

{
    messages: [
      {
        id: `${new Date().getTime()}`,
        type: 'text',
        content: 'hello world',
        targetId: '12345678',
        chatInfo: {
          avatar: require('./app/source/image/avatar.png'),
          id: '12345678',
          nickName: 'Test'   // not require
        },
        renderTime: true,
        sendStatus: 0,
        time: new Date().getTime()
      }
    ]
}
  • id: message id
  • about message type: 'text', 'image', 'voice', 'video', 'location', 'share', 'videoCall', 'voiceCall', 'redEnvelope', 'file', 'system'
  • targetId: The id of the person who sent the message
  • content: see example
  • chatInfo: The profile of the person you're chatting with
  • renderTime: Whether to render time above message
  • sendStatus: 0 ---> sending, 1 ---> sendSuccess, -1 ---> You are deleted or on the blacklist, -2 ---> error
  • time: moment,messageList sorted by time

Props

  • message
propsdefaultInfo
messageList[]Messages to display
invertedfalseWhen messageList exceeds the screen height, set it to true otherwise false (You can change this value when componentWillUnmount or delete message)
isIPhoneXfalseIs it full screen
chatBackgroundImagenullCustom BackgroundImage
onScroll() => {}ListView Props
onEndReachedThreshold0.1ListView Props
chatWindowStyleundefinedContainer style
sendMessage(type, content, isInverted) => {}Callback when sending a message
reSendMessage(message) => {}Callback when you want send again
delMessage(indexs, isInverted) => {}Callback when delete message
renderAvatar(message) => {}Custom avatar view
avatarStyleundefinedStyle of avatar
chatId'123455678'The id of the person you're chatting with
chatType'friend'Your relationship with the person you're chatting with
onMessagePress(type, index, content) => {}Callback when press a message
onMessageLongPress(type, index, content) => {}Callback when longPress a message and usePopView is false
pressAvatar(isSelf, targetId) => {}Callback when press avatar
headerHeight66navigation bar height + statusBar height
userProfile{id: '88888888', avatar: 'default.png'}Your own profile
showUserNamefalseWhether show userName
loadHistory() => {}Callback when loading earlier messages
renderMessageTime(time) => {}Custom time inside above message
renderChatBg(bg) => {}Custom chat background image
renderErrorMessage(messageStatus) => {}Custom a message when the friend relationship is abnormal
panelSource[]Custom panel source
renderPanelRow() => {}Custom a tab icon
allPanelHeight200emojiPanel and plusPanel height
messageErrorIconicon elementCustom a icon when message failed to be sent
leftMessageBackground'#fffff'Custom background color on left
rightMessageBackground'#a0e75a'Custom background color on right
leftMessageTextStyleundefinedCustom text message style on left
rightMessageTextStyleundefinedCustom text message style on right
  • inputBarProps

    propsdefaultInfo
    emojiIconicon elementCustom emoticons
    placeholder'请输入...'Placeholder when text is empty
    keyboardIconiconCustom keyboard icon
    plusIconicon elementCustom plus icon
    sendIconicon elementCustom send icon
  • popViewProps

    propsdefaultInfo
    usePopViewtrueDisplay a popView when longPress a message
    popoverStyle{backgroundColor: '#333'}popView style
    renderDelPanelundefinedCustom any what you want, (isSelect)=> {}
    changeHeaderLeft() => {}Custom headerLeft
    setPopItems(type, index, text) => {let items = [{title: '删除',onPress: () => {that.props.delMessage(index)}},{title: '多选',onPress: () => {that.multipleSelect(index)}}]if (type === 'text') {items = [{title: '复制',onPress: () => Clipboard.setString(text)},{title: '删除',onPress: () => {that.props.delMessage(index)}},{title: '多选', onPress: () => {that.multipleSelect(index)}}]}return items}Custom PopView
    messageDelIconicon elementCustom delete icon
    messageSelectIconicon elementCustom selected icon
    renderMessageCheckundefinedCustom selected icon, (isSelect)=> {}
  • voiceProps

    propsdefaultInfo
    useVoicetruesend voice message
    pressInText'按住 说话'Custom pressIn text
    pressOutText'松开 发送'Custom pressOut text
    voiceIconicon elementCustom voice icon
    voiceLeftIconundefinedCustom icon of the message on the left
    voiceRightIconundefinedCustom icon of the message on the right
    voiceErrorIconicon elementCustom icon when record error
    voiceErrorText'说话时间太短'Custom text when record error
    voiceCancelIconicon elementCustom icon when cancel record
    voiceCancelText'松开手指取消发送'Custom text when cancel record
    voiceNoteText'手指上划,取消发送'Custom text when pressIn record button
    voiceSpeakIcon[]Custom icon when pressIn record button
    audioPath''File path to store voice
    audioOnProgress() => {}Callback when recording
    audioOnFinish() => {}Callback when finish record
    audioInitPath() => {}Callback when init file path
    audioRecord() => {}Callback when start record
    audioStopRecord() => {}Callback when stop record
    audioPauseRecord() => {}Callback when pause record
    audioResumeRecord() => {}Callback when resume record
    audioCurrentTime0audio length
    audioHandletrueWhether to get a recording handle
    setAudioHandle(status) => {}Callback when get handle or not
    audioHasPermissionfalseWhether has permission
    requestAndroidPermission() => {}Callback when check permission on android
    checkPermission() => {}Callback whether has permission
    voiceLoadingfalseLoading voice or not
    voicePlayingfalsePlaying voice or not
    voiceLeftLoadingColor'#cccccc'Custom background color on left when load voice
    voiceVolume0Volume (0~10)
    voiceRightLoadingColor'#628b42'Custom background color on right when load voice
  • bubbleProps

propsdefaultInfo
renderTextMessageundefinedCustom message text, (data) => {}
renderImageMessageundefinedCustom message image, (data) => {}
renderVoiceMessageundefinedCustom message voice, (data) => {}
renderVoiceViewundefinedCustom voice container, (data) => {}
renderVideoMessageundefinedCustom message video, (data) => {}
renderLocationMessageundefinedCustom message location, (data) => {}
renderShareMessageundefinedCustom message share, (data) => {}
renderVideoCallMessageundefinedCustom message video call, (data) => {}
renderVoiceCallMessageundefinedCustom message voice call, (data) => {}
renderRedEnvelopeMessageundefinedCustom message red-envelope, (data) => {}
renderFileMessageundefinedCustom message file, (data) => {}
renderPatMessageundefinedCustom message pat, (data) => {}
renderCustomMessageundefinedCustom message custom, (data) => {}
renderSystemMessageundefinedCustom message system, (data) => {}

All Props

  propTypes = {
      /* defaultProps */
      messageList: PropTypes.array.isRequired,
      inverted: PropTypes.bool,
      isIPhoneX: PropTypes.bool.isRequired,
      lastReadAt: PropTypes.object,
      chatBackgroundImage: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
      onScroll: PropTypes.func,
      onEndReachedThreshold: PropTypes.number,
      chatWindowStyle: ViewPropTypes.style,
      sendMessage: PropTypes.func,
      renderAvatar: PropTypes.func,
      avatarStyle: ViewPropTypes.style,
      allPanelAnimateDuration: PropTypes.number,
      chatType: PropTypes.oneOf(['friend', 'group']),
      onMessagePress: PropTypes.func,
      onMessageLongPress: PropTypes.func,
      renderMessageTime: PropTypes.func,
      pressAvatar: PropTypes.func,
      renderErrorMessage: PropTypes.func,
      renderChatBg: PropTypes.func,
      reSendMessage: PropTypes.func,
      headerHeight: PropTypes.number.isRequired,
      iphoneXBottomPadding: PropTypes.number,
      showUserName: PropTypes.bool,
      showIsRead: PropTypes.bool,
      showInput: PropTypes.bool,
      isReadStyle: PropTypes.object,
      userProfile: PropTypes.shape({
        id: PropTypes.string.isRequired,
        avatar: PropTypes.isRequired,
        nickName: PropTypes.string
      }),
      panelSource: PropTypes.array,
      renderPanelRow: PropTypes.func,
      panelContainerStyle: ViewPropTypes.style,
      itemContainerStyle: ViewPropTypes.style,
      allPanelHeight: PropTypes.number,
      messageErrorIcon: PropTypes.element,
      loadHistory: PropTypes.func,
      leftMessageBackground: PropTypes.string,
      rightMessageBackground: PropTypes.string,
      leftMessageTextStyle: PropTypes.object,
      rightMessageTextStyle: PropTypes.object,
      renderLoadEarlier: PropTypes.func,
      extraData: PropTypes.any,
      containerBackgroundColor: PropTypes.string,
      showsVerticalScrollIndicator: PropTypes.bool,
      userNameStyle: PropTypes.object,
      panelContainerBackgroundColor: PropTypes.string,
      /* popProps */
      usePopView: PropTypes.bool,
      popoverStyle: ViewPropTypes.style,
      renderDelPanel: PropTypes.func,
      changeHeaderLeft: PropTypes.func,
      setPopItems: PropTypes.func,
      messageDelIcon: PropTypes.element,
      messageSelectIcon: PropTypes.element,
      delMessage: PropTypes.func,
      renderMessageCheck: PropTypes.func,
    
      /* inputBarProps */
      emojiIcon: PropTypes.element,
      placeholder: PropTypes.string,
      keyboardIcon: PropTypes.element,
      plusIcon: PropTypes.element,
      sendIcon: PropTypes.element,
      sendUnableIcon: PropTypes.element,
      inputStyle: ViewPropTypes.style,
      inputOutContainerStyle: ViewPropTypes.style,
      inputContainerStyle: ViewPropTypes.style,
      inputHeightFix: PropTypes.number,
      useEmoji: PropTypes.bool,
      usePlus: PropTypes.bool,
      /* voiceProps */
      useVoice: PropTypes.bool,
      pressInText: PropTypes.string,
      pressOutText: PropTypes.string,
      voiceIcon: PropTypes.element,
      voiceLeftIcon: PropTypes.element,
      voiceRightIcon: PropTypes.element,
      voiceErrorIcon: PropTypes.element,
      voiceCancelIcon: PropTypes.element,
      voiceSpeakIcon: PropTypes.array,
      audioPath: PropTypes.string,
      audioOnProgress: PropTypes.func,
      audioOnFinish: PropTypes.func,
      audioInitPath: PropTypes.func,
      audioRecord: PropTypes.func,
      audioStopRecord: PropTypes.func,
      audioPauseRecord: PropTypes.func,
      audioResumeRecord: PropTypes.func,
      audioCurrentTime: PropTypes.number,
      audioHandle: PropTypes.bool,
      setAudioHandle: PropTypes.func,
      audioHasPermission: PropTypes.bool,
      checkPermission: PropTypes.func,
      requestAndroidPermission: PropTypes.func,
      voiceErrorText: PropTypes.string,
      voiceCancelText: PropTypes.string,
      voiceNoteText: PropTypes.string,
      voiceLoading: PropTypes.bool,
      voicePlaying: PropTypes.bool,
      voiceLeftLoadingColor: PropTypes.string,
      voiceVolume: PropTypes.number,
      voiceRightLoadingColor: PropTypes.string,
      /* bubbleProps */
      renderTextMessage: PropTypes.func,
      renderImageMessage: PropTypes.func,
      renderVoiceMessage: PropTypes.func,
      renderVoiceView: PropTypes.func,
      renderVideoMessage: PropTypes.func,
      renderLocationMessage: PropTypes.func,
      renderShareMessage: PropTypes.func,
      renderVideoCallMessage: PropTypes.func,
      renderVoiceCallMessage: PropTypes.func,
      renderRedEnvelopeMessage: PropTypes.func,
      renderFileMessage: PropTypes.func,
      renderSystemMessage: PropTypes.func,
      renderCustomMessage: PropTypes.func,
      renderPatMessage: PropTypes.func,
      /* delPanelProps */
      delPanelStyle: ViewPropTypes.style,
      delPanelButtonStyle: ViewPropTypes.style,
      flatListProps: PropTypes.object
  }

Notes for Android

  • Make sure you have android:windowSoftInputMode="adjustResize" in your AndroidManifest.xml:
android:windowSoftInputMode="adjustResize"

Donation

☕️☕️

License

0.4.14

3 years ago

0.4.13

3 years ago

0.4.12

3 years ago

0.4.11

4 years ago

0.4.10

4 years ago

0.4.9

4 years ago

0.4.8

4 years ago

0.4.5

4 years ago

0.4.6

4 years ago

0.4.4

4 years ago

0.4.3

4 years ago

0.4.2

4 years ago

0.4.1

4 years ago

0.4.0

4 years ago

0.3.15

4 years ago

0.3.14

5 years ago

0.3.13

5 years ago

0.3.12

5 years ago

0.3.11

5 years ago

0.3.10

5 years ago

0.3.9

5 years ago

0.3.8

5 years ago

0.3.7

5 years ago

0.3.6

5 years ago

0.3.5

5 years ago

0.3.4

5 years ago

0.3.3

5 years ago

0.3.2

5 years ago

0.3.1

5 years ago

0.3.0

5 years ago

0.2.13

5 years ago

0.2.12

5 years ago

0.2.11

5 years ago

0.2.10

5 years ago

0.2.9

5 years ago

0.2.8

5 years ago

0.2.7

5 years ago

0.2.6

5 years ago

0.2.5

5 years ago

0.1.9

5 years ago

0.1.8

5 years ago

0.2.4

5 years ago

0.2.3

5 years ago

0.2.2

5 years ago

0.2.1

5 years ago

0.2.0

5 years ago

0.1.7

5 years ago

0.1.6

5 years ago

0.1.5

5 years ago

0.1.4

5 years ago

0.1.3

5 years ago

0.1.2

5 years ago

0.1.1

5 years ago

0.1.0

5 years ago