A UI de chat mais completa para React Native & Web
Web de demonstração?
Lanche GiftedChat playground
Coding Bootcamp em Paris co-fundado por Farid Safi
Clique para saber mais
API/servidor de chat escalável escrito em Go
Tour API | Tutorial de React Native Gifted
Um mecanismo de aplicativo completo com GiftedChat
Confira nosso GitHub
react-native-web
(desde 0.10.0)Fio:
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
Expo
npx expo install react-native-gifted-chat react-native-reanimated react-native-safe-area-context react-native-get-random-values
npx pod-install
Siga o guia: react-native-safe-area-context
Siga o guia: react-native-reanimated
0.11.0
.video
, mas precisa fornecer o suporte renderMessageVideo
. TEST_ID
é exportado como constantes que podem ser usadas na biblioteca de testes de sua escolha
Gifted Chat usa onLayout
para determinar a altura do contêiner de bate-papo. Para acionar onLayout
durante seus testes, você pode executar os seguintes trechos 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 uma demonstração funcional!
Veja os arquivos em example/example-slack-message
para ver um exemplo de como substituir a UI padrão para criar algo que se pareça mais com o Slack – com nomes de usuário exibidos e todas as mensagens à esquerda.
por exemplo, mensagem de bate-papo
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 exemplo, mensagem do 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 exemplo, mensagem de bate-papo com opções de resposta rápida
Veja RP #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) - Referência para a flatlisttextInputRef
(TextInput ref) - Referência para a entrada de textomessages
(Array) - Mensagens a serem exibidasisTyping
(Bool) - Estado do indicador de digitação; padrão false
. Se você usar renderFooter
ele substituirá isso.text
(String) - Texto de entrada; o padrão é undefined
, mas se especificado, substituirá o estado interno do GiftedChat (por exemplo, para redux; veja as notas abaixo)placeholder
(String) - Placeholder quando text
está vazio; o padrão é 'Type a message...'
messageIdGenerator
(Function) - Gera um id para novas mensagens. O padrão é UUID v4, gerado por uuiduser
(Object) - Usuário enviando as mensagens: { _id, name, avatar }
onSend
(Função) - Retorno de chamada ao enviar uma mensagemalwaysShowSend
(Bool) - Sempre mostra o botão enviar no compositor de texto de entrada; padrão false
, mostra apenas quando a entrada de texto não está vazialocale
(String) - Local para localizar as datas. Você precisa primeiro importar a localidade necessária (ou seja, require('dayjs/locale/de')
ou import 'dayjs/locale/fr'
)timeFormat
(String) - Formato a ser usado para tempos de renderização; o padrão é 'LT'
(consulte o formato Day.js)dateFormat
(String) - Formato a ser usado para renderização de datas; o padrão é 'll'
(consulte o formato Day.js)loadEarlier
(Bool) - Habilita o botão "carregar mensagens anteriores", necessário para infiniteScroll
onLoadEarlier
(Function) – Retorno de chamada ao carregar mensagens anterioresisLoadingEarlier
(Bool) – Exibe um ActivityIndicator
ao carregar mensagens anterioresrenderLoading
(Function) - Renderiza uma visualização de carregamento ao inicializarrenderLoadEarlier
(Function) - Botão personalizado "Carregar mensagens anteriores"renderAvatar
(Function) - Avatar de mensagem personalizada; definido como null
para não renderizar nenhum avatar para a mensagemshowUserAvatar
(Bool) - Se deve renderizar um avatar para o usuário atual; o padrão é false
, mostra apenas avatares para outros usuáriosshowAvatarForEveryMessage
(Bool) - Quando falso, os avatares só serão exibidos quando uma mensagem consecutiva for do mesmo usuário no mesmo dia; o padrão é false
onPressAvatar
(Function( user
)) – Retorno de chamada quando um avatar de mensagem é tocadoonLongPressAvatar
(Function( user
)) - Retorno de chamada quando um avatar de mensagem é pressionado longamenterenderAvatarOnTop
(Bool) - Renderiza o avatar da mensagem na parte superior das mensagens consecutivas, em vez de na parte inferior; o padrão é false
renderBubble
(Function) - Balão de mensagem personalizadorenderTicks
(Function( message
)) - Indicador de ticks personalizado para exibir o status da mensagemrenderSystemMessage
(Function) - Mensagem personalizada do sistemaonPress
(Function( context
, message
)) - Retorno de chamada quando um balão de mensagem é pressionadoonLongPress
(Function( context
, message
)) – Retorno de chamada quando um balão de mensagem é pressionado longamente (veja o exemplo usando showActionSheetWithOptions()
)inverted
(Bool) - Inverte a ordem de exibição das messages
; o padrão é true
renderUsernameOnMessage
(Bool) - Indica se deseja mostrar o nome de usuário do usuário dentro do balão de mensagem; o padrão é false
renderUsername
(Function) - contêiner de nome de usuário personalizadorenderMessage
(Function) - Contêiner de mensagem personalizadorenderMessageText
(Function) - Texto de mensagem personalizadorenderMessageImage
(Function) - Imagem de mensagem personalizadarenderMessageVideo
(Function) - Vídeo de mensagem personalizadaimageProps
(Object) - Props extras a serem passados para o componente <Image>
criado pelo renderMessageImage
padrãovideoProps
(Object) - Adereços extras a serem passados para o componente de vídeo criado pelo renderMessageVideo
necessáriolightboxProps
(Object) - Adereços extras a serem passados para o Lightbox do MessageImage
isCustomViewBottom
(Bool) - Determina se renderCustomView é exibido antes ou depois das visualizações de texto, imagem e vídeo; o padrão é false
renderCustomView
(Function) - Visualização personalizada dentro da bolharenderDay
(Function) – Dia personalizado acima de uma mensagemrenderTime
(Function) - Tempo personalizado dentro de uma mensagemrenderFooter
(Function) - Componente de rodapé personalizado no ListView, por exemplo 'User is typing...'
; veja App.tsx para ver um exemplo. Substitui o indicador de digitação padrão que é acionado quando isTyping
é verdadeiro.renderChatEmpty
(Function) – Componente personalizado para renderizar no ListView quando as mensagens estão vaziasrenderChatFooter
(Function) - Componente personalizado para renderizar abaixo do MessageContainer (separado do ListView)renderInputToolbar
(Function) - Contêiner de compositor de mensagem personalizadorenderComposer
(Function) - Compositor de mensagens de entrada de texto personalizadorenderActions
(Function) - Botão de ação personalizado à esquerda do compositor da mensagemrenderSend
(Function) - Botão de envio personalizado; você pode passar filhos para o componente Send
original com bastante facilidade, por exemplo, para usar um ícone personalizado (exemplo)renderAccessory
(Function) - Segunda linha personalizada de ações abaixo do compositor da mensagemonPressActionButton
(Function) - Retorno de chamada quando o botão Action é pressionado (se definido, o actionSheet
padrão não será usado)bottomOffset
(Integer) - Distância do chat até a parte inferior da tela (por exemplo, útil se você exibir uma barra de guias)minInputToolbarHeight
(Integer) - Altura mínima da barra de ferramentas de entrada; o padrão é 44
listViewProps
(Object) - Props extras a serem passados para as mensagens <ListView>
; alguns adereços não podem ser substituídos, consulte o código em MessageContainer.render()
para obter detalhestextInputProps
(Object) - Props extras a serem passados para o <TextInput>
textInputStyle
(Object) - Estilo personalizado a ser passado para o <TextInput>
multiline
(Bool) - Indica se deve permitir que o <TextInput>
tenha múltiplas linhas ou não; padrão true
.keyboardShouldPersistTaps
(Enum) - Determina se o teclado deve permanecer visível após um toque; consulte a documentação <ScrollView>
onInputTextChanged
(Function) – Retorno de chamada quando o texto de entrada mudamaxInputLength
(Integer) - Comprimento máximo do TextInput do compositor de mensagensparsePatterns
(Function) - Padrões de análise personalizados para texto react-native-parsed usado para vincular o conteúdo da mensagem (como URLs e números de telefone), por exemplo: < GiftedChat
parsePatterns = { ( linkStyle ) => [
{ type : 'phone' , style : linkStyle , onPress : this . onPressPhoneNumber } ,
{ pattern : / #(w+) / , style : { ... linkStyle , styles . hashtag } , onPress : this . onPressHashtag } ,
] }
/>
extraData
(Object) - Adereços extras para renderizar novamente FlatList sob demanda. Isso será útil para renderizar rodapé, etc.minComposerHeight
(Object) - Altura mínima personalizada do compositor.maxComposerHeight
(Object) - Altura máxima personalizada do compositor.scrollToBottom
(Bool) - Habilita a rolagem para o componente inferior (o padrão é falso)scrollToBottomComponent
(Function) - contêiner de componente Scroll To Bottom personalizadoscrollToBottomOffset
(Integer) - Deslocamento de altura personalizado no qual começar a mostrar o componente Scroll To Bottom (o padrão é 200)scrollToBottomStyle
(Object) - Estilo personalizado para contêiner de componente inferioralignTop
(Boolean) Controla se os balões de mensagem aparecem ou não na parte superior do chat (o padrão é falso - os balões são alinhados na parte inferior)onQuickReply
(Function) – Retorno de chamada ao enviar uma resposta rápida (para o servidor backend)renderQuickReplies
(Function) - Visualização personalizada de todas as respostas rápidasquickReplyStyle
(StyleProp) - Estilo personalizado de visualização de resposta rápidarenderQuickReplySend
(Function) - Visualização personalizada de envio de resposta rápidashouldUpdateMessage
(Function) - Permite que o componente da mensagem saiba quando atualizar fora dos casos normais.infiniteScroll
(Bool) - rolagem infinita para cima ao chegar ao topo do contêiner de mensagens, chama automaticamente a função onLoadEarlier se existir (ainda não suportada para a web). Você precisa adicionar o suporte loadEarlier
também.isStatusBarTranslucentAndroid
(Bool) – Se você usa a barra de status translúcida no Android, defina esta opção como verdadeira. Ignorado no iOS. O suporte messages
deve funcionar imediatamente com Redux. Na maioria dos casos, isso é tudo que você precisa.
Se você decidir especificar um suporte text
, o GiftedChat não gerenciará mais seu próprio estado text
interno e se submeterá inteiramente ao seu suporte. Isso é ótimo para usar uma ferramenta como Redux, mas há uma etapa extra que você precisa realizar: basta implementar onInputTextChanged
para receber eventos de digitação e redefinir eventos (por exemplo, para limpar o texto onSend
):
< GiftedChat
text = { customText }
onInputTextChanged = { text => this . setCustomText ( text ) }
/* ... */
/>
Se você estiver usando o Create React Native App / Expo, nenhuma etapa de instalação específica do Android será necessária – você pode pular esta seção. Caso contrário, recomendamos modificar a configuração do seu projeto da seguinte forma.
Certifique-se de ter android:windowSoftInputMode="adjustResize"
em seu AndroidManifest.xml
:
< activity
android : name = " .MainActivity "
android : label = " @string/app_name "
android : windowSoftInputMode = " adjustResize "
android : configChanges = " keyboard|keyboardHidden|orientation|screenSize " >
Para Expo , existem pelo menos 2 soluções para consertar:
KeyboardAvoidingView
após GiftedChat. Isso só deve ser feito para Android, pois KeyboardAvoidingView
pode entrar em conflito com a evitação de teclado iOS já incorporada ao GiftedChat, por exemplo: <View style={{ flex: 1 }}>
<GiftedChat />
{
Platform.OS === 'android' && <KeyboardAvoidingView behavior="padding" />
}
</View>
Se você usar o React Navigation, poderá ser necessário tratamento adicional para contabilizar cabeçalhos e guias de navegação. A propriedade keyboardVerticalOffset
de KeyboardAvoidingView
pode ser definida para a altura do cabeçalho de navegação e tabBarOptions.keyboardHidesTabBar
pode ser definida para evitar que a barra de guias seja mostrada quando o teclado estiver ativo. Devido a um bug no cálculo da altura em telefones Android com entalhes, KeyboardAvoidingView
é recomendado em vez de outras soluções que envolvem o cálculo da altura da janela.
adicionando uma barra de status de fundo opaca em app.json (mesmo que android:windowSoftInputMode="adjustResize"
esteja definido internamente nos aplicativos Android da Expo, a barra de status translúcida faz com que ela não funcione): https://docs.expo.io/versions /latest/guides/configuration.html#androidstatusbar
Se você planeja usar GiftedChat
dentro de um Modal
, consulte o item 200.
yarn global add expo-cli
yarn install
expo start
yarn global add expo-cli
yarn install
expo start -w
Atualizar versão de lanche
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
}
Você encontrará um exemplo e uma demonstração da web aqui: xcarpentier/gifted-chat-web-demo
Outro exemplo com Gatsby : xcarpentier/clean-archi-boilerplate
Sinta-se à vontade para me fazer perguntas no Twitter @FaridSafi! ou @xcapetir!
Procurando um especialista freelancer ReactNative com mais de 14 anos de experiência? Entre em contato com Xavier em seu site!