La interfaz de usuario de chat más completa para React Native y Web
¿Web de demostración?
Merienda GiftedChat área de juegos
Coding Bootcamp en París cofundado por Farid Safi
Haga clic para obtener más información
API/Servidor de chat escalable escrito en Go
Visita API | Tutorial de reacción nativa para superdotados
Un motor de aplicación completo con GiftedChat
Consulta nuestro GitHub
react-native-web
(desde 0.10.0)Hilo:
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
exposición
npx expo install react-native-gifted-chat react-native-reanimated react-native-safe-area-context react-native-get-random-values
npx pod-install
Siga la guía: reaccionar-nativo-área-segura-contexto
Siga la guía: reaccionar-nativo-reanimado
0.11.0
.video
, pero debes proporcionar el accesorio renderMessageVideo
. TEST_ID
se exporta como constantes que se pueden usar en la biblioteca de pruebas de su elección.
Gifted Chat usa onLayout
para determinar la altura del contenedor de chat. Para activar onLayout
durante sus pruebas, puede ejecutar los siguientes bits de código.
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 ,
} }
/>
)
}
¡Consulte App.tsx
para ver una demostración funcional!
Consulte los archivos en example/example-slack-message
para ver un ejemplo de cómo anular la interfaz de usuario predeterminada para crear algo que se parezca más a Slack, con los nombres de usuario mostrados y todos los mensajes a la izquierda.
por ejemplo, mensaje de chat
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
}
por ejemplo, mensaje del sistema
{
_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
}
por ejemplo, mensaje de chat con opciones de respuesta rápida
Ver 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) - Referencia a la lista planatextInputRef
(TextInput ref) - Referencia a la entrada de textomessages
(Array) - Mensajes para mostrarisTyping
(Bool) : estado del indicador de escritura; predeterminado false
. Si usa renderFooter
anulará esto.text
(Cadena) - Texto de entrada; El valor predeterminado undefined
, pero si se especifica, anulará el estado interno de GiftedChat (por ejemplo, para redux; consulte las notas a continuación)placeholder
(Cadena) : marcador de posición cuando text
está vacío; El valor predeterminado es 'Type a message...'
messageIdGenerator
(Función) : genera una identificación para mensajes nuevos. El valor predeterminado es UUID v4, generado por uuiduser
(Objeto) - Usuario que envía los mensajes: { _id, name, avatar }
onSend
(Función) - Devolución de llamada al enviar un mensajealwaysShowSend
(Bool) : muestra siempre el botón Enviar en el compositor de texto de entrada; predeterminado false
, se muestra solo cuando la entrada de texto no está vacíalocale
(Cadena) - Localidad para localizar las fechas. Primero debe importar la configuración regional que necesita (es decir, require('dayjs/locale/de')
o import 'dayjs/locale/fr'
).timeFormat
(String) : formato a utilizar para los tiempos de renderizado; el valor predeterminado es 'LT'
(consulte Formato Day.js)dateFormat
(String) : formato a utilizar para representar fechas; el valor predeterminado es 'll'
(consulte Formato Day.js)loadEarlier
(Bool) : habilita el botón "cargar mensajes anteriores", necesario para infiniteScroll
onLoadEarlier
(función) : devolución de llamada al cargar mensajes anterioresisLoadingEarlier
(Bool) : muestra un ActivityIndicator
al cargar mensajes anterioresrenderLoading
(Función) : renderiza una vista de carga al inicializarrenderLoadEarlier
(Función) - Botón personalizado "Cargar mensajes anteriores"renderAvatar
(Función) - Avatar de mensaje personalizado; establecido en null
para no representar ningún avatar para el mensajeshowUserAvatar
(Bool) : si se debe representar un avatar para el usuario actual; El valor predeterminado es false
, solo muestra avatares para otros usuarios.showAvatarForEveryMessage
(Bool) : cuando es falso, los avatares solo se mostrarán cuando un mensaje consecutivo sea del mismo usuario el mismo día; el valor predeterminado es false
onPressAvatar
(Función ( user
)) : devolución de llamada cuando se toca un avatar de mensajeonLongPressAvatar
(Función ( user
)) : devolución de llamada cuando se mantiene presionado un avatar de mensajerenderAvatarOnTop
(Bool) : representa el avatar del mensaje en la parte superior de los mensajes consecutivos, en lugar de en la parte inferior; el valor predeterminado es false
renderBubble
(Función) - Burbuja de mensaje personalizadarenderTicks
(Función ( message
)) : indicador de ticks personalizado para mostrar el estado del mensajerenderSystemMessage
(Función) - Mensaje personalizado del sistemaonPress
(Función ( context
, message
)) : devolución de llamada cuando se presiona una burbuja de mensajeonLongPress
(Función ( context
, message
)) : devolución de llamada cuando se mantiene presionada una burbuja de mensaje (ver ejemplo usando showActionSheetWithOptions()
)inverted
(Bool) : invierte el orden de visualización de messages
; el valor predeterminado es true
renderUsernameOnMessage
(Bool) : indica si se muestra el nombre de usuario del usuario dentro de la burbuja del mensaje; el valor predeterminado es false
renderUsername
(Función) - Contenedor de nombre de usuario personalizadorenderMessage
(Función) - Contenedor de mensajes personalizadorenderMessageText
(Función) - Texto de mensaje personalizadorenderMessageImage
(Función) - Imagen de mensaje personalizadarenderMessageVideo
(función) - Vídeo de mensaje personalizadoimageProps
(Objeto) : accesorios adicionales que se pasarán al componente <Image>
creado por el renderMessageImage
predeterminadovideoProps
(Objeto) : accesorios adicionales que se pasarán al componente de vídeo creado por el renderMessageVideo
requeridolightboxProps
(Objeto) : accesorios adicionales que se pasarán al Lightbox de MessageImage
isCustomViewBottom
(Bool) : determina si renderCustomView se muestra antes o después de las vistas de texto, imagen y video; el valor predeterminado es false
renderCustomView
(Función) - Vista personalizada dentro de la burbujarenderDay
(Función) - Día personalizado encima de un mensajerenderTime
(Función) - Tiempo personalizado dentro de un mensajerenderFooter
(Función) : componente de pie de página personalizado en ListView, por ejemplo, 'User is typing...'
; consulte App.tsx para ver un ejemplo. Anula el indicador de escritura predeterminado que se activa cuando isTyping
es verdadero.renderChatEmpty
(función) : componente personalizado para representar en ListView cuando los mensajes están vacíosrenderChatFooter
(función) : componente personalizado para representar debajo de MessageContainer (separado de ListView)renderInputToolbar
(función) : contenedor de redacción de mensajes personalizadorenderComposer
(Función) : compositor de mensajes de entrada de texto personalizadorenderActions
(función) : botón de acción personalizado a la izquierda del redactor del mensajerenderSend
(Función) : botón de envío personalizado; puede pasar niños al componente Send
original con bastante facilidad, por ejemplo, para usar un ícono personalizado (ejemplo)renderAccessory
(Función) : segunda línea personalizada de acciones debajo del redactor del mensajeonPressActionButton
(Función) : devolución de llamada cuando se presiona el botón Acción (si está configurado, no se usará la actionSheet
predeterminada)bottomOffset
(Entero) : distancia del chat desde la parte inferior de la pantalla (por ejemplo, útil si muestra una barra de pestañas)minInputToolbarHeight
(Entero) : altura mínima de la barra de herramientas de entrada; el valor predeterminado es 44
listViewProps
(Objeto) : accesorios adicionales que se pasarán a los mensajes <ListView>
; algunos accesorios no se pueden anular; consulte el código en MessageContainer.render()
para obtener más detalles.textInputProps
(Objeto) : accesorios adicionales que se pasarán a <TextInput>
textInputStyle
(Objeto) : estilo personalizado que se pasará a <TextInput>
multiline
(Bool) : indica si se permite que <TextInput>
tenga varias líneas o no; predeterminado true
.keyboardShouldPersistTaps
(Enum) : determina si el teclado debe permanecer visible después de un toque; ver documentos <ScrollView>
onInputTextChanged
(Función) : devolución de llamada cuando cambia el texto de entradamaxInputLength
(Integer) - Longitud máxima de TextInput del compositor de mensajesparsePatterns
(función) : patrones de análisis personalizados para texto analizado nativo de reacción que se utilizan para vincular el contenido del mensaje (como URL y números de teléfono), por ejemplo: < GiftedChat
parsePatterns = { ( linkStyle ) => [
{ type : 'phone' , style : linkStyle , onPress : this . onPressPhoneNumber } ,
{ pattern : / #(w+) / , style : { ... linkStyle , styles . hashtag } , onPress : this . onPressHashtag } ,
] }
/>
extraData
(Objeto) : accesorios adicionales para volver a renderizar FlatList bajo demanda. Esto será útil para renderizar el pie de página, etc.minComposerHeight
(Objeto) : altura mínima personalizada del compositor.maxComposerHeight
(Objeto) : altura máxima personalizada del compositor.scrollToBottom
(Bool) : permite desplazarse hasta el componente inferior (el valor predeterminado es falso)scrollToBottomComponent
(Función) : contenedor personalizado de desplazamiento al componente inferiorscrollToBottomOffset
(entero) : desplazamiento de altura personalizado a partir del cual comenzar a mostrar el componente de desplazamiento hasta la parte inferior (el valor predeterminado es 200)scrollToBottomStyle
(Objeto) : estilo personalizado para el contenedor de componentes inferioresalignTop
(Booleano) Controla si las burbujas de mensaje aparecen o no en la parte superior del chat (el valor predeterminado es falso: las burbujas se alinean hacia abajo)onQuickReply
(función) : devolución de llamada al enviar una respuesta rápida (al servidor backend)renderQuickReplies
(función) : vista personalizada de todas las respuestas rápidasquickReplyStyle
(StyleProp) : estilo de vista de respuesta rápida personalizadorenderQuickReplySend
(función) : vista personalizada de envío de respuesta rápidashouldUpdateMessage
(función) : permite que el componente del mensaje sepa cuándo actualizar fuera de los casos normales.infiniteScroll
(Bool) : desplazamiento infinito hacia arriba cuando llega a la parte superior del contenedor de mensajes, llama automáticamente a la función onLoadEarlier si existe (aún no es compatible con la web). También necesitas agregar el accesorio loadEarlier
.isStatusBarTranslucentAndroid
(Bool) : si usa una barra de estado translúcida en Android, configure esta opción en verdadero. Ignorado en iOS. La propiedad messages
debería funcionar de inmediato con Redux. En la mayoría de los casos, esto es todo lo que necesitas.
Si decide especificar un elemento text
, GiftedChat ya no administrará su propio estado text
interno y se remitirá por completo a su elemento. Esto es excelente para usar una herramienta como Redux, pero hay un paso adicional que deberás realizar: simplemente implementa onInputTextChanged
para recibir eventos de escritura y restablecer eventos (por ejemplo, para borrar el texto onSend
):
< GiftedChat
text = { customText }
onInputTextChanged = { text => this . setCustomText ( text ) }
/* ... */
/>
Si está utilizando la aplicación/Expo Create React Native, no se requieren pasos de instalación específicos de Android; puede omitir esta sección. De lo contrario, recomendamos modificar la configuración de su proyecto de la siguiente manera.
Asegúrate de tener android:windowSoftInputMode="adjustResize"
en tu AndroidManifest.xml
:
< activity
android : name = " .MainActivity "
android : label = " @string/app_name "
android : windowSoftInputMode = " adjustResize "
android : configChanges = " keyboard|keyboardHidden|orientation|screenSize " >
Para Expo , existen al menos 2 soluciones para solucionarlo:
KeyboardAvoidingView
después de GiftedChat. Esto solo debe hacerse para Android, ya que KeyboardAvoidingView
puede entrar en conflicto con la opción para evitar el teclado de iOS ya integrada en GiftedChat, por ejemplo: <View style={{ flex: 1 }}>
<GiftedChat />
{
Platform.OS === 'android' && <KeyboardAvoidingView behavior="padding" />
}
</View>
Si utiliza React Navigation, es posible que se requiera un manejo adicional para tener en cuenta los encabezados y pestañas de navegación. La propiedad keyboardVerticalOffset
de KeyboardAvoidingView
se puede configurar a la altura del encabezado de navegación y tabBarOptions.keyboardHidesTabBar
se puede configurar para evitar que la barra de pestañas se muestre cuando el teclado está arriba. Debido a un error al calcular la altura en teléfonos Android con muescas, se recomienda KeyboardAvoidingView
sobre otras soluciones que implican calcular la altura de la ventana.
agregar una barra de estado de fondo opaco en app.json (aunque android:windowSoftInputMode="adjustResize"
está configurado internamente en las aplicaciones de Android de Expo, la barra de estado translúcida hace que no funcione): https://docs.expo.io/versions /latest/guides/configuration.html#androidstatusbar
Si planea utilizar GiftedChat
dentro de un Modal
, consulte el punto 200.
yarn global add expo-cli
yarn install
expo start
yarn global add expo-cli
yarn install
expo start -w
Actualizar versión snack
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
}
Encontrará un ejemplo y una demostración web aquí: xcarpentier/gifted-chat-web-demo
Otro ejemplo con Gatsby : xcarpentier/clean-archi-boilerplate
¡No dudes en hacerme preguntas en Twitter @FaridSafi! o @xcapetir!
¿Busca un experto independiente en ReactNative con más de 14 años de experiencia? ¡Contacta con Xavier desde su web!