最完整的 React Native 和 Web 聊天 UI
演示網?
小吃 GiftedChat 遊樂場
巴黎程式設計訓練營由 Farid Safi 共同創立
點擊了解更多
用 Go 編寫的可擴展聊天 API/伺服器
API 之旅 | React Native 天才教程
具有 GiftedChat 功能的完整應用程式引擎
看看我們的 GitHub
react-native-web
能夠(自 0.10.0 起) Web 配置紗:
yarn add react-native-gifted-chat react-native-reanimated react-native-safe-area-context react-native-get-random-values
國家PM:
npm install --save react-native-gifted-chat react-native-reanimated react-native-safe-area-context react-native-get-random-values
世博會
npx expo install react-native-gifted-chat react-native-reanimated react-native-safe-area-context react-native-get-random-values
npx pod-install
遵循指南:react-native-safe-area-context
遵循指南:react-native-reanimated
0.11.0
開始,這兩個依賴項都被刪除。video
,但需要提供renderMessageVideo
屬性。 TEST_ID
匯出為常數,可在您選擇的測試庫中使用
Gifted Chat 使用onLayout
來確定聊天容器的高度。要在測試期間觸發onLayout
,您可以執行以下程式碼。
const WIDTH = 200 ; // or any number
const HEIGHT = 2000 ; // or any number
const loadingWrapper = getByTestId ( TEST_ID . LOADING_WRAPPER )
fireEvent ( loadingWrapper , 'layout' , {
nativeEvent : {
layout : {
width : WIDTH ,
height : HEIGHT ,
} ,
} ,
} )
import React , { useState , useCallback , useEffect } from 'react'
import { GiftedChat } from 'react-native-gifted-chat'
export function Example ( ) {
const [ messages , setMessages ] = useState ( [ ] )
useEffect ( ( ) => {
setMessages ( [
{
_id : 1 ,
text : 'Hello developer' ,
createdAt : new Date ( ) ,
user : {
_id : 2 ,
name : 'React Native' ,
avatar : 'https://placeimg.com/140/140/any' ,
} ,
} ,
] )
} , [ ] )
const onSend = useCallback ( ( messages = [ ] ) => {
setMessages ( previousMessages =>
GiftedChat . append ( previousMessages , messages ) ,
)
} , [ ] )
return (
< GiftedChat
messages = { messages }
onSend = { messages => onSend ( messages ) }
user = { {
_id : 1 ,
} }
/>
)
}
請參閱App.tsx
以取得工作演示!
請參閱example/example-slack-message
中的文件,以取得有關如何覆蓋預設 UI 以使內容看起來更像 Slack 的範例 - 顯示使用者名稱並將所有訊息顯示在左側。
例如聊天訊息
export interface IMessage {
_id : string | number
text : string
createdAt : Date | number
user : User
image ?: string
video ?: string
audio ?: string
system ?: boolean
sent ?: boolean
received ?: boolean
pending ?: boolean
quickReplies ?: QuickReplies
}
{
_id : 1 ,
text : 'My message' ,
createdAt : new Date ( Date . UTC ( 2016 , 5 , 11 , 17 , 20 , 0 ) ) ,
user : {
_id : 2 ,
name : 'React Native' ,
avatar : 'https://facebook.github.io/react/img/logo_og.png' ,
} ,
image : 'https://facebook.github.io/react/img/logo_og.png' ,
// You can also add a video prop:
video : 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4' ,
// Mark the message as sent, using one tick
sent : true ,
// Mark the message as received, using two tick
received : true ,
// Mark the message as pending with a clock loader
pending : true ,
// Any additional custom parameters are passed through
}
例如係統訊息
{
_id : 1 ,
text : 'This is a system message' ,
createdAt : new Date ( Date . UTC ( 2016 , 5 , 11 , 17 , 20 , 0 ) ) ,
system : true ,
// Any additional custom parameters are passed through
}
例如有快速回覆選項的聊天訊息
請參閱 PR #1211
interface Reply {
title : string
value : string
messageId ?: number | string
}
interface QuickReplies {
type : 'radio' | 'checkbox'
values : Reply [ ]
keepIt ?: boolean
}
{
_id : 1 ,
text : 'This is a quick reply. Do you love Gifted Chat? (radio) KEEP IT' ,
createdAt : new Date ( ) ,
quickReplies : {
type : 'radio' , // or 'checkbox',
keepIt : true ,
values : [
{
title : '? Yes' ,
value : 'yes' ,
} ,
{
title : '? Yes, let me show you with a picture!' ,
value : 'yes_picture' ,
} ,
{
title : '? Nope. What?' ,
value : 'no' ,
} ,
] ,
} ,
user : {
_id : 2 ,
name : 'React Native' ,
} ,
} ,
{
_id : 2 ,
text : 'This is a quick reply. Do you love Gifted Chat? (checkbox)' ,
createdAt : new Date ( ) ,
quickReplies : {
type : 'checkbox' , // or 'radio',
values : [
{
title : 'Yes' ,
value : 'yes' ,
} ,
{
title : 'Yes, let me show you with a picture!' ,
value : 'yes_picture' ,
} ,
{
title : 'Nope. What?' ,
value : 'no' ,
} ,
] ,
} ,
user : {
_id : 2 ,
name : 'React Native' ,
} ,
}
messageContainerRef
(FlatList ref) - 引用平面列表textInputRef
(TextInput ref) - 文字輸入的引用messages
(Array) - 要顯示的訊息isTyping
(Bool) - 打字指示器狀態;預設false
。如果你使用renderFooter
它將覆蓋它。text
(字串) - 輸入文字;預設為undefined
,但如果指定,它將覆蓋 GiftedChat 的內部狀態(例如,對於 redux;請參閱下面的註釋)placeholder
(String) - text
為空時的佔位符;預設為'Type a message...'
messageIdGenerator
(函數) - 為新訊息產生 ID。預設為UUID v4,由uuid生成user
(Object) - 傳送訊息的使用者: { _id, name, avatar }
onSend
(Function) - 發送訊息時回調alwaysShowSend
(Bool) - 始終在輸入文字編輯器中顯示發送按鈕;預設false
,僅當文字輸入不為空時顯示locale
(String) - 用於局部化日期的區域設定。您首先需要匯入所需的語言環境(即require('dayjs/locale/de')
或import 'dayjs/locale/fr'
)timeFormat
(String) - 用於渲染時間的格式;預設為'LT'
(請參閱 Day.js 格式)dateFormat
(String) - 用於渲染日期的格式;預設為'll'
(請參閱 Day.js 格式)loadEarlier
(Bool) - 啟用「載入較早訊息」按鈕,這是infiniteScroll
所必需的onLoadEarlier
(Function) - 載入較早訊息時的回呼isLoadingEarlier
(Bool) - 載入早期訊息時顯示ActivityIndicator
renderLoading
(函數) - 初始化時渲染載入視圖renderLoadEarlier
(函數) - 自訂「載入早期訊息」按鈕renderAvatar
(Function) - 自訂訊息頭像;設定為null
以不呈現訊息的任何頭像showUserAvatar
(Bool) - 是否為目前使用者渲染頭像;預設為false
,僅顯示其他使用者的頭像showAvatarForEveryMessage
(Bool) - 當為 false 時,僅當同一天來自同一使用者的連續訊息時才會顯示頭像;預設為false
onPressAvatar
(Function( user
)) - 點選訊息頭像時的回呼onLongPressAvatar
(Function( user
)) - 長按訊息頭像時的回呼renderAvatarOnTop
(Bool) - 在連續訊息的頂部而不是底部渲染訊息頭像;預設為false
renderBubble
(函數) - 自訂訊息氣泡renderTicks
(Function( message
)) - 自訂刻度指示器以顯示訊息狀態renderSystemMessage
(Function) - 自訂系統訊息onPress
(Function( context
, message
)) - 按下訊息氣泡時的回調onLongPress
(Function( context
, message
)) - 長按訊息氣泡時的回呼(請參閱使用showActionSheetWithOptions()
的範例)inverted
(Bool) - 反轉messages
的顯示順序;預設為true
renderUsernameOnMessage
(Bool) - 指示是否在訊息氣泡內顯示使用者的使用者名稱;預設為false
renderUsername
(函數) - 自訂使用者名稱容器renderMessage
(函數) - 自訂訊息容器renderMessageText
(函數) - 自訂訊息文本renderMessageImage
(函數) - 自訂訊息圖像renderMessageVideo
(Function) - 自訂訊息視頻imageProps
(Object) - 要傳遞給預設renderMessageImage
所建立的<Image>
元件的額外道具videoProps
(Object) - 要傳遞給由所需renderMessageVideo
創建的視訊元件的額外道具lightboxProps
(Object) - 要傳遞到MessageImage
的 Lightbox 的額外道具isCustomViewBottom
(Bool) - 確定 renderCustomView 是顯示在文字、圖像和影片視圖之前還是之後;預設為false
renderCustomView
(Function) - 氣泡內的自訂視圖renderDay
(函數) - 訊息上方的自訂日期renderTime
(函數) - 訊息內的自訂時間renderFooter
(Function) - ListView 上的自訂頁尾元件,例如'User is typing...'
;有關範例,請參閱 App.tsx。覆蓋當isTyping
為 true 時觸發的預設鍵入指示器。renderChatEmpty
(函數) - 當訊息為空時在 ListView 中呈現的自訂元件renderChatFooter
(函數) - 在 MessageContainer 下方呈現的自訂元件(與 ListView 分開)renderInputToolbar
(函數) - 自訂訊息編輯器容器renderComposer
(Function) - 自訂文字輸入訊息編輯器renderActions
(函數) - 訊息編輯器左側的自訂操作按鈕renderSend
(Function) - 自訂發送按鈕;您可以輕鬆地將子項目傳遞給原始Send
元件,例如,使用自訂圖示(範例)renderAccessory
(Function) - 訊息編輯器下方的自訂第二行操作onPressActionButton
(Function) - 按下 Action 按鈕時的回呼(如果設置,將不會使用預設的actionSheet
)bottomOffset
(整數) - 聊天與螢幕底部的距離(例如,如果您顯示選項卡欄,則很有用)minInputToolbarHeight
(Integer) - 輸入工具列的最小高度;預設為44
listViewProps
(Object) - 要傳遞給訊息<ListView>
額外道具;有些道具無法被覆蓋,請參閱MessageContainer.render()
中的程式碼以了解詳細信息textInputProps
(Object) - 要傳遞給<TextInput>
的額外道具textInputStyle
(Object) - 要傳遞給<TextInput>
的自訂樣式multiline
(Bool) - 指示是否允許<TextInput>
為多行;預設true
。keyboardShouldPersistTaps
(Enum) - 決定鍵盤在點擊後是否應保持可見;請參閱<ScrollView>
文檔onInputTextChanged
(Function) - 輸入文字改變時回調maxInputLength
(整數) - 最大訊息編輯器文字輸入長度parsePatterns
(Function) - 用於連結訊息內容(如 URL 和電話號碼)的react-native-parsed-text 的自訂解析模式,例如: < GiftedChat
parsePatterns = { ( linkStyle ) => [
{ type : 'phone' , style : linkStyle , onPress : this . onPressPhoneNumber } ,
{ pattern : / #(w+) / , style : { ... linkStyle , styles . hashtag } , onPress : this . onPressHashtag } ,
] }
/>
extraData
(Object) - 用於根據需要重新渲染 FlatList 的額外道具。這對於渲染頁腳等很有用。minComposerHeight
(物件) - 作曲家的自訂最小高度。maxComposerHeight
(物件) - 編輯器的自訂最大高度。scrollToBottom
(Bool) - 啟用捲動到底部元件(預設為 false)scrollToBottomComponent
(函數) - 自訂捲動到底部元件容器scrollToBottomOffset
(整數) - 開始顯示捲動到底部組件的自訂高度偏移(預設值為 200)scrollToBottomStyle
(Object) - 底部元件容器的自訂樣式alignTop
(布林值)控制訊息氣泡是否出現在聊天的頂部(預設為 false - 氣泡與底部對齊)onQuickReply
(Function) - 發送快速回覆時的回呼(到後端伺服器)renderQuickReplies
(Function) - 自訂所有快速回覆視圖quickReplyStyle
(StyleProp) - 自訂快速回覆視圖樣式renderQuickReplySend
(Function) - 自訂快速回覆發送視圖shouldUpdateMessage
(函數) - 讓訊息元件知道何時在正常情況之外進行更新。infiniteScroll
(Bool) - 當到達訊息容器頂部時無限向上滾動,如果存在則自動呼叫 onLoadEarlier 函數(Web 尚未支援)。您還需要新增loadEarlier
屬性。isStatusBarTranslucentAndroid
(Bool) - 如果您在 Android 上使用半透明狀態欄,請將此選項設為 true。在 iOS 上被忽略。 messages
屬性應該可以與 Redux 一起開箱即用。在大多數情況下,這就是您所需要的。
如果您決定指定text
道具,GiftedChat 將不再管理自己的內部text
狀態,並將完全遵循您的道具。這對於使用 Redux 這樣的工具來說非常有用,但是您需要採取一個額外的步驟:只需實作onInputTextChanged
來接收鍵入事件和重置事件(例如清除onSend
文字):
< GiftedChat
text = { customText }
onInputTextChanged = { text => this . setCustomText ( text ) }
/* ... */
/>
如果您使用 Create React Native App / Expo,則不需要特定 Android 的安裝步驟 - 您可以跳過本節。否則,我們建議按如下方式修改您的專案配置。
確保AndroidManifest.xml
中有android:windowSoftInputMode="adjustResize"
:
< activity
android : name = " .MainActivity "
android : label = " @string/app_name "
android : windowSoftInputMode = " adjustResize "
android : configChanges = " keyboard|keyboardHidden|orientation|screenSize " >
對於Expo來說,至少有 2 個解決方案可以修復它:
KeyboardAvoidingView
。這應該只適用於 Android,因為KeyboardAvoidingView
可能與 GiftedChat 中內建的 iOS 鍵盤避免衝突,例如: <View style={{ flex: 1 }}>
<GiftedChat />
{
Platform.OS === 'android' && <KeyboardAvoidingView behavior="padding" />
}
</View>
如果您使用 React Navigation,可能需要額外的處理來考慮導覽標題和標籤。 KeyboardAvoidingView
的keyboardVerticalOffset
屬性可以設定為導覽標題的高度,並且可以設定tabBarOptions.keyboardHidesTabBar
以防止鍵盤彈起時顯示選項卡列。由於在具有凹口的 Android 手機上計算高度時存在錯誤,因此建議使用KeyboardAvoidingView
而不是涉及計算視窗高度的其他解決方案。
在 app.json 上新增不透明的背景狀態列(即使在 Expo 的 Android 應用程式內部設定了android:windowSoftInputMode="adjustResize"
,半透明的狀態列會導致其無法工作):https://docs.expo. io/versions /latest/guides/configuration.html#androidstatusbar
如果您打算在Modal
中使用GiftedChat
,請參閱#200。
yarn global add expo-cli
yarn install
expo start
yarn global add expo-cli
yarn install
expo start -w
升級零食版
yarn add -D react-app-rewired
touch config-overrides.js
module . exports = function override ( config , env ) {
config . module . rules . push ( {
test : / .js$ / ,
exclude : / node_modules[/\](?!react-native-gifted-chat|react-native-lightbox|react-native-parsed-text) / ,
use : {
loader : 'babel-loader' ,
options : {
babelrc : false ,
configFile : false ,
presets : [
[ '@babel/preset-env' , { useBuiltIns : 'usage' } ] ,
'@babel/preset-react' ,
] ,
plugins : [ '@babel/plugin-proposal-class-properties' ] ,
} ,
} ,
} )
return config
}
您可以在這裡找到範例和網路示範:xcarpentier/gifted-chat-web-demo
蓋茲比的另一個例子:xcarpentier/clean-archi-boilerplate
請隨時在 Twitter @FaridSafi 上向我提問!或@xcapetir!
正在尋找擁有超過 14 年經驗的 ReactNative 自由專家?從澤維爾的網站聯絡他!