React Native および Web 向けの最も完全なチャット UI
デモウェブ?
スナック ギフトチャット遊び場
ファリド・サフィ氏が共同設立したパリのコーディングブートキャンプ
クリックして詳細を確認する
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
Npm:
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-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
参照してください。
デフォルトの UI をオーバーライドして Slack に似たものを作成する方法の例については、 example/example-slack-message
のファイルを参照してください。ユーザー名が表示され、すべてのメッセージが左側に表示されます。
例: チャットメッセージ
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
(配列) - 表示するメッセージisTyping
(Bool) - タイピング インジケーターの状態。デフォルトはfalse
。 renderFooter
使用すると、これがオーバーライドされます。text
(文字列) - 入力テキスト。デフォルトはundefined
ですが、指定すると GiftedChat の内部状態がオーバーライドされます (redux の場合など。以下の注を参照)placeholder
(String) - text
が空の場合のプレースホルダー。デフォルトは'Type a message...'
です。messageIdGenerator
(関数) - 新しいメッセージの ID を生成します。デフォルトは UUID v4 で、uuid によって生成されます。user
(オブジェクト) - メッセージを送信するユーザー: { _id, name, avatar }
onSend
(関数) - メッセージ送信時のコールバックalwaysShowSend
(Bool) - 入力テキスト コンポーザーに送信ボタンを常に表示します。デフォルトはfalse
、テキスト入力が空でない場合にのみ表示されますlocale
(文字列) - 日付をローカライズするロケール。まず必要なロケールをインポートする必要があります (つまり、 require('dayjs/locale/de')
またはimport 'dayjs/locale/fr'
)timeFormat
(String) - レンダリング時間に使用する形式。デフォルトは'LT'
(Day.js 形式を参照)dateFormat
(String) - 日付のレンダリングに使用する形式。デフォルトは'll'
(Day.js 形式を参照)loadEarlier
(ブール) - infiniteScroll
に必要な「以前のメッセージを読み込む」ボタンを有効にします。onLoadEarlier
(関数) - 以前のメッセージをロードするときのコールバックisLoadingEarlier
(Bool) - 以前のメッセージをロードするときにActivityIndicator
を表示します。renderLoading
(関数) - 初期化時にロード中のビューをレンダリングします。renderLoadEarlier
(関数) - カスタムの「以前のメッセージを読み込む」ボタンrenderAvatar
(関数) - カスタム メッセージ アバター。メッセージのアバターを表示しない場合は、 null
に設定します。showUserAvatar
(Bool) - 現在のユーザーのアバターをレンダリングするかどうか。デフォルトはfalse
で、他のユーザーのアバターのみを表示しますshowAvatarForEveryMessage
(Bool) - false の場合、同じ日に同じユーザーからの連続メッセージがある場合にのみアバターが表示されます。デフォルトはfalse
ですonPressAvatar
(Function( user
)) - メッセージアバターがタップされたときのコールバックonLongPressAvatar
(Function( user
)) - メッセージアバターが長押しされたときのコールバックrenderAvatarOnTop
(Bool) - 連続するメッセージの下部ではなく上部にメッセージ アバターをレンダリングします。デフォルトはfalse
ですrenderBubble
(関数) - カスタム メッセージ バブルrenderTicks
(Function( message
)) - メッセージのステータスを表示するカスタム ティック インジケーターrenderSystemMessage
(関数) - カスタム システム メッセージonPress
(Function( context
, message
)) - メッセージバブルが押されたときのコールバックonLongPress
(Function( context
, message
)) - メッセージバブルが長押しされたときのコールバック ( showActionSheetWithOptions()
の使用例を参照)inverted
(Bool) - messages
の表示順序を逆にします。デフォルトはtrue
ですrenderUsernameOnMessage
(Bool) - メッセージ バブル内にユーザーのユーザー名を表示するかどうかを示します。デフォルトはfalse
ですrenderUsername
(関数) - カスタム ユーザー名コンテナrenderMessage
(関数) - カスタム メッセージ コンテナーrenderMessageText
(関数) - カスタム メッセージ テキストrenderMessageImage
(関数) - カスタム メッセージ画像renderMessageVideo
(関数) - カスタム メッセージ ビデオimageProps
(オブジェクト) - デフォルトのrenderMessageImage
によって作成される<Image>
コンポーネントに渡される追加の小道具videoProps
(オブジェクト) - 必要なrenderMessageVideo
によって作成されたビデオ コンポーネントに渡される追加の小道具lightboxProps
(オブジェクト) - MessageImage
のライトボックスに渡される追加の小道具isCustomViewBottom
(Bool) - renderCustomView がテキスト、イメージ、ビデオ ビューの前か後に表示されるかを決定します。デフォルトはfalse
ですrenderCustomView
(関数) - バブル内のカスタム ビューrenderDay
(関数) - メッセージの上のカスタム日renderTime
(関数) - メッセージ内のカスタム時間renderFooter
(関数) - ListView のカスタム フッター コンポーネント。例: 'User is typing...'
;例については、App.tsx を参照してください。 isTyping
が true の場合にトリガーされるデフォルトの入力インジケーターをオーバーライドします。renderChatEmpty
(関数) - メッセージが空の場合に ListView にレンダリングするカスタム コンポーネントrenderChatFooter
(関数) - MessageContainer の下にレンダリングするカスタム コンポーネント (ListView とは別)renderInputToolbar
(関数) - カスタム メッセージ コンポーザ コンテナrenderComposer
(関数) - カスタム テキスト入力メッセージ コンポーザーrenderActions
(関数) - メッセージ コンポーザーの左側にあるカスタム アクション ボタンrenderSend
(関数) - カスタム送信ボタン。たとえば、カスタム アイコンを使用するなど、子を元のSend
コンポーネントに非常に簡単に渡すことができます (例)renderAccessory
(関数) - メッセージ コンポーザーの下のカスタム 2 行目のアクションonPressActionButton
(関数) - アクション ボタンが押されたときのコールバック (設定されている場合、デフォルトのactionSheet
使用されません)bottomOffset
(整数) - 画面の下部からチャットまでの距離 (例: タブ バーを表示する場合に便利)minInputToolbarHeight
(整数) - 入力ツールバーの最小の高さ。デフォルトは44
ですlistViewProps
(オブジェクト) - メッセージ<ListView>
に渡される追加の小道具。一部のプロパティはオーバーライドできません。詳細については、 MessageContainer.render()
のコードを参照してください。textInputProps
(Object) - <TextInput>
に渡される追加の小道具textInputStyle
(オブジェクト) - <TextInput>
に渡されるカスタム スタイルmultiline
(Bool) - <TextInput>
複数行になることを許可するかどうかを示します。デフォルトはtrue
。keyboardShouldPersistTaps
(列挙型) - タップ後にキーボードを表示したままにするかどうかを決定します。 <ScrollView>
ドキュメントを参照してくださいonInputTextChanged
(関数) - 入力テキストが変更されたときのコールバックmaxInputLength
(整数) - メッセージ コンポーザーの TextInput の最大長parsePatterns
(関数) - メッセージ コンテンツ (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
(オブジェクト) - オンデマンドで FlatList を再レンダリングするための追加の小道具。これはフッターなどのレンダリングに役立ちます。minComposerHeight
(オブジェクト) - コンポーザーのカスタム最小高さ。maxComposerHeight
(オブジェクト) - コンポーザーのカスタム最大高さ。scrollToBottom
(Bool) - 最下部のコンポーネントへのスクロールを有効にします (デフォルトは false)scrollToBottomComponent
(関数) - カスタム Scroll To Bottom コンポーネント コンテナscrollToBottomOffset
(整数) - Scroll To Bottom コンポーネントの表示を開始するカスタムの高さのオフセット (デフォルトは 200)scrollToBottomStyle
(オブジェクト) - Bottom Component コンテナのカスタム スタイルalignTop
(ブール値)メッセージバブルをチャットの上部に表示するかどうかを制御します (デフォルトは false - バブルは下部に揃えられます)onQuickReply
(関数) - クイック応答を送信するときのコールバック (バックエンド サーバーに)renderQuickReplies
(関数) - すべてのクイック返信ビューをカスタマイズしますquickReplyStyle
(StyleProp) - カスタムのクイック返信ビュー スタイルrenderQuickReplySend
(関数) - カスタムのクイック返信送信ビューshouldUpdateMessage
(関数) - 通常のケース以外でいつ更新するかをメッセージ コンポーネントに知らせます。infiniteScroll
(ブール値) - メッセージ コンテナーの最上部に達すると上に無限にスクロールし、onLoadEarlier 関数が存在する場合は自動的に呼び出します (Web ではまだサポートされていません)。 loadEarlier
プロパティも追加する必要があります。isStatusBarTranslucentAndroid
(Bool) - Android で半透明のステータス バーを使用する場合は、このオプションを true に設定します。 iOSでは無視されます。 messages
プロップは、そのまま Redux で動作するはずです。ほとんどの場合、必要なのはこれだけです。
text
プロップを指定することにした場合、 GiftedChat は独自の内部text
状態を管理しなくなり、プロップに完全に従うことになります。これは Redux などのツールを使用する場合には便利ですが、追加の手順が 1 つ必要です。単に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
を追加します。 KeyboardAvoidingView
GiftedChat にすでに組み込まれている iOS キーボード回避と競合する可能性があるため、これは Android に対してのみ行う必要があります。例: <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
}
ここに例とWeb デモがあります: xcarpentier/gifted-chat-web-demo
Gatsbyを使用した別の例: xcarpentier/clean-archi-boilerplate
Twitter @FaridSafi でお気軽にご質問ください。または@xcapetir!
14 年以上の経験を持つ ReactNative フリーランスのエキスパートをお探しですか?ザビエルのウェブサイトから連絡してください。