L'interface utilisateur de chat la plus complète pour React Native & Web
Démo Web ?
Aire de jeux Snack GiftedChat
Coding Bootcamp à Paris co-fondé par Farid Safi
Cliquez pour en savoir plus
API/serveur de chat évolutif écrit en Go
Visite API | Tutoriel React Native Gifted
Un moteur d'application complet avec GiftedChat
Consultez notre GitHub
react-native-web
(depuis 0.10.0)Fil:
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
Exposition
npx expo install react-native-gifted-chat react-native-reanimated react-native-safe-area-context react-native-get-random-values
npx pod-install
Suivez le guide : react-native-safe-area-context
Suivez le guide : réagir-natif-réanimé
0.11.0
.video
, mais vous devez fournir la prop renderMessageVideo
. TEST_ID
est exporté sous forme de constantes pouvant être utilisées dans la bibliothèque de tests de votre choix
Gifted Chat utilise onLayout
pour déterminer la hauteur du conteneur de discussion. Pour déclencher onLayout
lors de vos tests, vous pouvez exécuter les morceaux de code suivants.
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 ,
} }
/>
)
}
Voir App.tsx
pour une démo fonctionnelle !
Consultez les fichiers dans example/example-slack-message
pour un exemple de comment remplacer l'interface utilisateur par défaut pour créer quelque chose qui ressemble davantage à Slack - avec les noms d'utilisateur affichés et tous les messages sur la gauche.
par exemple, message de discussion
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
}
par exemple, message système
{
_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
}
par exemple, message de discussion avec options de réponse rapide
Voir 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) - Référence à la flatlisttextInputRef
(TextInput ref) - Référence à la saisie de textemessages
(Array) - Messages à afficherisTyping
(Bool) - État de l'indicateur de saisie ; false
par défaut. Si vous utilisez renderFooter
cela remplacera cela.text
(String) - Texte de saisie ; La valeur par défaut est undefined
, mais si elle est spécifiée, elle remplacera l'état interne de GiftedChat (par exemple pour Redux ; voir les notes ci-dessous)placeholder
(String) - Espace réservé lorsque text
est vide ; la valeur par défaut est 'Type a message...'
messageIdGenerator
(Fonction) - Génère un identifiant pour les nouveaux messages. La valeur par défaut est UUID v4, généré par uuiduser
(Object) - Utilisateur envoyant les messages : { _id, name, avatar }
onSend
(Fonction) - Rappel lors de l'envoi d'un messagealwaysShowSend
(Bool) - Toujours afficher le bouton d'envoi dans le composeur de texte d'entrée ; false
par défaut, affiché uniquement lorsque la saisie de texte n'est pas videlocale
(String) - Locale pour localiser les dates. Vous devez d'abord importer les paramètres régionaux dont vous avez besoin (c'est-à-dire require('dayjs/locale/de')
ou import 'dayjs/locale/fr'
)timeFormat
(String) - Format à utiliser pour les temps de rendu ; la valeur par défaut est 'LT'
(voir Format Day.js)dateFormat
(String) - Format à utiliser pour le rendu des dates ; la valeur par défaut est 'll'
(voir Format Day.js)loadEarlier
(Bool) - Active le bouton "charger les messages antérieurs", requis pour infiniteScroll
onLoadEarlier
(Fonction) - Rappel lors du chargement de messages antérieursisLoadingEarlier
(Bool) - Afficher un ActivityIndicator
lors du chargement de messages antérieursrenderLoading
(Fonction) - Rendre une vue de chargement lors de l'initialisationrenderLoadEarlier
(Fonction) - Bouton personnalisé "Charger les messages précédents"renderAvatar
(Fonction) - Avatar de message personnalisé ; défini sur null
pour ne rendre aucun avatar pour le messageshowUserAvatar
(Bool) - S'il faut afficher un avatar pour l'utilisateur actuel ; la valeur par défaut est false
, affiche uniquement les avatars des autres utilisateursshowAvatarForEveryMessage
(Bool) - Lorsque faux, les avatars ne seront affichés que lorsqu'un message consécutif provient du même utilisateur le même jour ; la valeur par défaut est false
onPressAvatar
(Fonction ( user
)) - Rappel lorsqu'un avatar de message est tapéonLongPressAvatar
(Fonction ( user
)) - Rappel lorsqu'un avatar de message est appuyé longuementrenderAvatarOnTop
(Bool) - Afficher l'avatar du message en haut des messages consécutifs, plutôt qu'en bas ; la valeur par défaut est false
renderBubble
(Fonction) - Bulle de message personnaliséerenderTicks
(Fonction ( message
)) - Indicateur de ticks personnalisé pour afficher l'état du messagerenderSystemMessage
(Fonction) - Message système personnaliséonPress
(Fonction ( context
, message
)) - Rappel lorsqu'une bulle de message est enfoncéeonLongPress
(Function( context
, message
)) - Rappel lorsqu'une bulle de message est enfoncée longuement (voir exemple utilisant showActionSheetWithOptions()
)inverted
(Bool) - Inverse l'ordre d'affichage des messages
; la valeur par défaut est true
renderUsernameOnMessage
(Bool) - Indique s'il faut afficher le nom d'utilisateur de l'utilisateur dans la bulle de message ; la valeur par défaut est false
renderUsername
(Fonction) - Conteneur de nom d'utilisateur personnalisérenderMessage
(Fonction) - Conteneur de messages personnalisérenderMessageText
(Fonction) - Texte du message personnalisérenderMessageImage
(Fonction) - Image de message personnaliséerenderMessageVideo
(Fonction) - Message vidéo personnaliséimageProps
(Object) - Accessoires supplémentaires à transmettre au composant <Image>
créé par le renderMessageImage
par défautvideoProps
(Object) - Accessoires supplémentaires à transmettre au composant vidéo créé par le renderMessageVideo
requislightboxProps
(Object) - Accessoires supplémentaires à transmettre à la Lightbox de MessageImage
isCustomViewBottom
(Bool) - Détermine si renderCustomView est affiché avant ou après les vues de texte, d'image et de vidéo ; la valeur par défaut est false
renderCustomView
(Fonction) - Vue personnalisée à l'intérieur de la bullerenderDay
(Fonction) - Jour personnalisé au dessus d'un messagerenderTime
(Fonction) - Heure personnalisée dans un messagerenderFooter
(Fonction) - Composant de pied de page personnalisé sur ListView, par exemple 'User is typing...'
; voir App.tsx pour un exemple. Remplace l'indicateur de saisie par défaut qui se déclenche lorsque isTyping
est vrai.renderChatEmpty
(Fonction) - Composant personnalisé à restituer dans ListView lorsque les messages sont videsrenderChatFooter
(Fonction) - Composant personnalisé à restituer sous le MessageContainer (séparé du ListView)renderInputToolbar
(Fonction) - Conteneur de composition de message personnalisérenderComposer
(Fonction) - Compositeur de message de saisie de texte personnalisérenderActions
(Fonction) - Bouton d'action personnalisé à gauche du compositeur du messagerenderSend
(Fonction) - Bouton d'envoi personnalisé ; vous pouvez transmettre les enfants au composant Send
d'origine assez facilement, par exemple, pour utiliser une icône personnalisée (exemple)renderAccessory
(Fonction) - Deuxième ligne d'actions personnalisée sous le compositeur du messageonPressActionButton
(Fonction) - Rappel lorsque le bouton d'action est enfoncé (si défini, la actionSheet
par défaut ne sera pas utilisée)bottomOffset
(Integer) - Distance du chat depuis le bas de l'écran (par exemple utile si vous affichez une barre d'onglets)minInputToolbarHeight
(Integer) - Hauteur minimale de la barre d'outils de saisie ; la valeur par défaut est 44
listViewProps
(Object) - Accessoires supplémentaires à transmettre aux messages <ListView>
; certains accessoires ne peuvent pas être remplacés, voir le code dans MessageContainer.render()
pour plus de détailstextInputProps
(Object) - Accessoires supplémentaires à transmettre au <TextInput>
textInputStyle
(Object) - Style personnalisé à transmettre au <TextInput>
multiline
(Bool) - Indique s'il faut autoriser ou non le <TextInput>
à être sur plusieurs lignes ; true
par défaut.keyboardShouldPersistTaps
(Enum) - Détermine si le clavier doit rester visible après une pression ; voir la documentation <ScrollView>
onInputTextChanged
(Fonction) - Rappel lorsque le texte d'entrée changemaxInputLength
(Integer) - Longueur maximale du TextInput du compositeur du messageparsePatterns
(Fonction) - Modèles d'analyse personnalisés pour le texte analysé natif de réaction utilisé pour lier le contenu du message (comme les URL et les numéros de téléphone), par exemple : < GiftedChat
parsePatterns = { ( linkStyle ) => [
{ type : 'phone' , style : linkStyle , onPress : this . onPressPhoneNumber } ,
{ pattern : / #(w+) / , style : { ... linkStyle , styles . hashtag } , onPress : this . onPressHashtag } ,
] }
/>
extraData
(Object) - Accessoires supplémentaires pour restituer FlatList à la demande. Cela sera utile pour le rendu du pied de page, etc.minComposerHeight
(Object) - Hauteur minimale personnalisée du compositeur.maxComposerHeight
(Object) - Hauteur maximale personnalisée du compositeur.scrollToBottom
(Bool) - Active le composant de défilement vers le bas (la valeur par défaut est false)scrollToBottomComponent
(Fonction) - Conteneur personnalisé de composants de défilement vers le basscrollToBottomOffset
(Integer) - Décalage de hauteur personnalisé à partir duquel commencer à afficher le composant de défilement vers le bas (la valeur par défaut est 200)scrollToBottomStyle
(Object) - Style personnalisé pour le conteneur de composants inférieursalignTop
(booléen) Contrôle si les bulles de message apparaissent ou non en haut du chat (la valeur par défaut est false - les bulles s'alignent vers le bas)onQuickReply
(Fonction) - Rappel lors de l'envoi d'une réponse rapide (au serveur backend)renderQuickReplies
(Fonction) - Affichage personnalisé de toutes les réponses rapidesquickReplyStyle
(StyleProp) - Style d'affichage de réponse rapide personnalisérenderQuickReplySend
(Fonction) - Vue d'envoi de réponse rapide personnaliséeshouldUpdateMessage
(Fonction) - Permet au composant de message de savoir quand mettre à jour en dehors des cas normaux.infiniteScroll
(Bool) - défilement infini vers le haut lorsque vous atteignez le haut du conteneur de messages, appelle automatiquement la fonction onLoadEarlier si elle existe (pas encore prise en charge pour le Web). Vous devez également ajouter la prop loadEarlier
.isStatusBarTranslucentAndroid
(Bool) - Si vous utilisez une barre d'état translucide sur Android, définissez cette option sur true. Ignoré sur iOS. L'accessoire messages
devrait fonctionner immédiatement avec Redux. Dans la plupart des cas, c’est tout ce dont vous avez besoin.
Si vous décidez de spécifier un accessoire text
, GiftedChat ne gérera plus son propre état text
interne et s'en remettra entièrement à votre accessoire. C'est idéal pour utiliser un outil comme Redux, mais vous devrez suivre une étape supplémentaire : implémentez simplement onInputTextChanged
pour recevoir des événements de saisie et réinitialiser les événements (par exemple, pour effacer le texte onSend
) :
< GiftedChat
text = { customText }
onInputTextChanged = { text => this . setCustomText ( text ) }
/* ... */
/>
Si vous utilisez Create React Native App/Expo, aucune étape d'installation spécifique à Android n'est requise : vous pouvez ignorer cette section. Sinon, nous vous recommandons de modifier la configuration de votre projet comme suit.
Assurez-vous d'avoir android:windowSoftInputMode="adjustResize"
dans votre AndroidManifest.xml
:
< activity
android : name = " .MainActivity "
android : label = " @string/app_name "
android : windowSoftInputMode = " adjustResize "
android : configChanges = " keyboard|keyboardHidden|orientation|screenSize " >
Pour Expo , il existe au moins 2 solutions pour y remédier :
KeyboardAvoidingView
après GiftedChat. Cela ne devrait être fait que pour Android, car KeyboardAvoidingView
peut entrer en conflit avec l'évitement du clavier iOS déjà intégré à GiftedChat, par exemple : <View style={{ flex: 1 }}>
<GiftedChat />
{
Platform.OS === 'android' && <KeyboardAvoidingView behavior="padding" />
}
</View>
Si vous utilisez React Navigation, une gestion supplémentaire peut être nécessaire pour prendre en compte les en-têtes et les onglets de navigation. La propriété keyboardVerticalOffset
de KeyboardAvoidingView
peut être définie sur la hauteur de l'en-tête de navigation et tabBarOptions.keyboardHidesTabBar
peut être définie pour empêcher la barre d'onglets de s'afficher lorsque le clavier est relevé. En raison d'un bug de calcul de la hauteur sur les téléphones Android dotés d'encoches, KeyboardAvoidingView
est recommandé par rapport aux autres solutions impliquant le calcul de la hauteur de la fenêtre.
ajout d'une barre d'état d'arrière-plan opaque sur app.json (même si android:windowSoftInputMode="adjustResize"
est défini en interne sur les applications Android d'Expo, la barre d'état translucide l'empêche de fonctionner) : https://docs.expo.io/versions /latest/guides/configuration.html#androidstatusbar
Si vous prévoyez d'utiliser GiftedChat
dans un Modal
, voir #200.
yarn global add expo-cli
yarn install
expo start
yarn global add expo-cli
yarn install
expo start -w
Mise à niveau de la version collation
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
}
Vous trouverez un exemple et une démo web ici : xcarpentier/gifted-chat-web-demo
Autre exemple avec Gatsby : xcarpentier/clean-archi-boilerplate
N'hésitez pas à me poser des questions sur Twitter @FaridSafi ! ou @xcapetir !
Vous recherchez un expert freelance ReactNative avec plus de 14 ans d’expérience ? Contactez Xavier depuis son site internet !