واجهة مستخدم الدردشة الأكثر اكتمالاً لـ React Native & Web
الويب التجريبي؟
ملعب الوجبات الخفيفة GiftedChat
معسكر تدريب البرمجة في باريس شارك في تأسيسه فريد صافي
انقر لمعرفة المزيد
واجهة برمجة تطبيقات/خادم دردشة قابلة للتطوير مكتوبة بلغة Go
جولة API | برنامج React Native Gifted التعليمي
محرك تطبيق كامل يضم GiftedChat
تحقق من جيثب لدينا
react-native-web
قادرة (منذ 0.10.0) تكوين الويبغزل:
yarn add react-native-gifted-chat react-native-reanimated react-native-safe-area-context react-native-get-random-values
نبم:
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
اتبع الدليل: سياق الاستجابة الآمنة الأصلي
اتبع الدليل: رد الفعل الأصلي-إعادة إحياء
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
للحصول على مثال حول كيفية تجاوز واجهة المستخدم الافتراضية لإنشاء شيء يشبه 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
}
على سبيل المثال، رسالة دردشة مع خيارات الرد السريع
انظر العلاقات العامة رقم 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) - مرجع إلى القائمة المسطحةtextInputRef
(مرجع TextInput) - مرجع لإدخال النصmessages
(مصفوفة) - الرسائل المراد عرضهاisTyping
(Bool) - حالة مؤشر الكتابة؛ افتراضي false
إذا كنت تستخدم renderFooter
فسوف يتجاوز هذا.text
(سلسلة) - نص الإدخال؛ الإعداد الافتراضي undefined
، ولكن إذا تم تحديده، فسوف يتجاوز الحالة الداخلية لـ GiftedChat (على سبيل المثال، بالنسبة للإعادة؛ راجع الملاحظات أدناه)placeholder
(سلسلة) - العنصر النائب عندما يكون text
فارغًا؛ الافتراضي هو 'Type a message...'
messageIdGenerator
(وظيفة) - إنشاء معرف للرسائل الجديدة. الإعدادات الافتراضية هي UUID v4، التي تم إنشاؤها بواسطة uuiduser
(الكائن) - المستخدم الذي يرسل الرسائل: { _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
(Bool) - تمكين زر "تحميل الرسائل السابقة"، المطلوب من أجل infiniteScroll
onLoadEarlier
(وظيفة) - رد الاتصال عند تحميل الرسائل السابقةisLoadingEarlier
(Bool) - يعرض مؤشر ActivityIndicator
عند تحميل الرسائل السابقةrenderLoading
(الوظيفة) - عرض عرض التحميل عند التهيئةrenderLoadEarlier
(الوظيفة) - زر "تحميل الرسائل السابقة" المخصصrenderAvatar
(الوظيفة) - الصورة الرمزية للرسالة المخصصة؛ تم ضبطه على null
لعدم عرض أي صورة رمزية للرسالةshowUserAvatar
(Bool) - ما إذا كان سيتم عرض صورة رمزية للمستخدم الحالي أم لا؛ الافتراضي هو false
، فقط قم بإظهار الصور الرمزية للمستخدمين الآخرينshowAvatarForEveryMessage
(Bool) - عندما تكون القيمة "خطأ"، لن يتم عرض الصور الرمزية إلا عندما تكون هناك رسالة متتالية من نفس المستخدم في نفس اليوم؛ الافتراضي false
onPressAvatar
(Function( user
)) - رد الاتصال عند النقر على الصورة الرمزية للرسالةonLongPressAvatar
(الوظيفة( user
)) - رد الاتصال عند الضغط لفترة طويلة على الصورة الرمزية للرسالةrenderAvatarOnTop
(Bool) - عرض الصورة الرمزية للرسالة في أعلى الرسائل المتتالية، بدلاً من أسفلها؛ الافتراضي هو false
renderBubble
(وظيفة) - فقاعة رسائل مخصصةrenderTicks
(الوظيفة ( message
)) - مؤشر علامات التجزئة المخصص لعرض حالة الرسالةrenderSystemMessage
(وظيفة) - رسالة نظام مخصصةonPress
(Function( context
, message
)) - رد الاتصال عند الضغط على فقاعة الرسالةonLongPress
(Function( context
, message
)) - رد الاتصال عند الضغط لفترة طويلة على فقاعة الرسالة (راجع المثال باستخدام showActionSheetWithOptions()
)inverted
(منطقي) - يعكس ترتيب عرض messages
؛ الافتراضي true
renderUsernameOnMessage
(Bool) - تحديد ما إذا كان سيتم إظهار اسم المستخدم الخاص بالمستخدم داخل فقاعة الرسالة أم لا؛ الافتراضي false
renderUsername
(الوظيفة) - حاوية اسم المستخدم المخصصةrenderMessage
(وظيفة) - حاوية رسائل مخصصةrenderMessageText
(وظيفة) - نص رسالة مخصصةrenderMessageImage
(الوظيفة) - صورة رسالة مخصصةrenderMessageVideo
(الوظيفة) - فيديو رسالة مخصصةimageProps
(Object) - دعائم إضافية سيتم تمريرها إلى مكون <Image>
الذي تم إنشاؤه بواسطة renderMessageImage
الافتراضيvideoProps
(Object) - دعائم إضافية سيتم تمريرها إلى مكون الفيديو الذي تم إنشاؤه بواسطة renderMessageVideo
المطلوبlightboxProps
(Object) - دعائم إضافية سيتم تمريرها إلى Lightbox الخاص بـ MessageImage
isCustomViewBottom
(Bool) - تحديد ما إذا كان سيتم عرض renderCustomView قبل أو بعد عرض النص والصور والفيديو؛ الافتراضي هو false
renderCustomView
(Function) - عرض مخصص داخل الفقاعةrenderDay
(وظيفة) - يوم مخصص أعلى الرسالةrenderTime
(وظيفة) - وقت مخصص داخل الرسالةrenderFooter
(الوظيفة) - مكون تذييل مخصص في ListView، على سبيل المثال 'User is typing...'
؛ راجع App.tsx للحصول على مثال. يتجاوز مؤشر الكتابة الافتراضي الذي يتم تشغيله عندما تكون isTyping
صحيحة.renderChatEmpty
(وظيفة) - مكون مخصص لعرضه في ListView عندما تكون الرسائل فارغةrenderChatFooter
(وظيفة) - مكون مخصص لعرضه أسفل messageContainer (منفصل عن ListView)renderInputToolbar
(وظيفة) - حاوية مؤلف الرسائل المخصصةrenderComposer
(وظيفة) - مؤلف رسائل إدخال النص المخصصrenderActions
(الوظيفة) - زر إجراء مخصص على يسار مؤلف الرسالةrenderSend
(وظيفة) - زر إرسال مخصص؛ يمكنك تمرير العناصر الفرعية إلى مكون Send
الأصلي بسهولة تامة، على سبيل المثال، لاستخدام رمز مخصص (مثال)renderAccessory
(Function) - السطر الثاني المخصص من الإجراءات أسفل مؤلف الرسالةonPressActionButton
(الوظيفة) - رد الاتصال عند الضغط على زر الإجراء (في حالة التعيين، لن يتم استخدام actionSheet
الافتراضية)bottomOffset
(عدد صحيح) - مسافة الدردشة من أسفل الشاشة (على سبيل المثال، تكون مفيدة إذا قمت بعرض شريط علامات التبويب)minInputToolbarHeight
(Integer) - الحد الأدنى لارتفاع شريط أدوات الإدخال؛ الافتراضي هو 44
listViewProps
(Object) - الدعائم الإضافية التي سيتم تمريرها إلى الرسائل <ListView>
؛ لا يمكن تجاوز بعض الخاصيات، راجع الكود الموجود في MessageContainer.render()
لمزيد من التفاصيلtextInputProps
(Object) - الدعائم الإضافية التي سيتم تمريرها إلى <TextInput>
textInputStyle
(Object) - النمط المخصص الذي سيتم تمريره إلى <TextInput>
multiline
(Bool) - يشير إلى ما إذا كان سيتم السماح لـ <TextInput>
بأن يكون أسطرًا متعددة أم لا؛ true
الافتراضي.keyboardShouldPersistTaps
(Enum) - يحدد ما إذا كان يجب أن تظل لوحة المفاتيح مرئية بعد النقر أم لا؛ راجع مستندات <ScrollView>
onInputTextChanged
(وظيفة) - رد الاتصال عندما يتغير نص الإدخالmaxInputLength
(Integer) - الحد الأقصى لطول TextInput لمؤلف الرسالةparsePatterns
(وظيفة) - أنماط تحليل مخصصة للنص التحليلي الأصلي المستخدم لربط محتوى الرسالة (مثل عناوين URL وأرقام الهواتف)، على سبيل المثال: < GiftedChat
parsePatterns = { ( linkStyle ) => [
{ type : 'phone' , style : linkStyle , onPress : this . onPressPhoneNumber } ,
{ pattern : / #(w+) / , style : { ... linkStyle , styles . hashtag } , onPress : this . onPressHashtag } ,
] }
/>
extraData
(كائن) - دعائم إضافية لإعادة عرض FlatList عند الطلب. سيكون هذا مفيدًا لتقديم التذييل وما إلى ذلك.minComposerHeight
(كائن) - الارتفاع الأدنى المخصص للملحن.maxComposerHeight
(Object) - أقصى ارتفاع مخصص للملحن.scrollToBottom
(Bool) - تمكين التمرير إلى المكون السفلي (الافتراضي خطأ)scrollToBottomComponent
(وظيفة) - حاوية مخصصة للتمرير إلى أسفل المكونscrollToBottomOffset
(عدد صحيح) - إزاحة الارتفاع المخصصة التي يتم من خلالها البدء في عرض مكون التمرير إلى الأسفل (الافتراضي هو 200)scrollToBottomStyle
(Object) - نمط مخصص لحاوية المكونات السفليةalignTop
(منطقي) يتحكم في ظهور فقاعات الرسائل في الجزء العلوي من الدردشة أم لا (الافتراضي هو خطأ - تتم محاذاة الفقاعات إلى الأسفل)onQuickReply
(الوظيفة) - رد الاتصال عند إرسال رد سريع (إلى الخادم الخلفي)renderQuickReplies
(وظيفة) - تخصيص عرض الرد السريع بالكاملquickReplyStyle
(StyleProp) - نمط عرض الرد السريع المخصصrenderQuickReplySend
(وظيفة) - طريقة عرض إرسال الرد السريع المخصصةshouldUpdateMessage
(الوظيفة) - يتيح لمكون الرسالة معرفة متى يجب التحديث خارج الحالات العادية.infiniteScroll
(Bool) - قم بالتمرير اللانهائي لأعلى عند الوصول إلى الجزء العلوي من حاوية الرسائل، واستدعاء وظيفة onLoadEarlier تلقائيًا إذا كانت موجودة (غير مدعومة للويب بعد). تحتاج إلى إضافة خاصية 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 مطلوبة - يمكنك تخطي هذا القسم. بخلاف ذلك، نوصي بتعديل تكوين مشروعك على النحو التالي.
تأكد من أن لديك android:windowSoftInputMode="adjustResize"
في AndroidManifest.xml
الخاص بك:
< activity
android : name = " .MainActivity "
android : label = " @string/app_name "
android : windowSoftInputMode = " adjustResize "
android : configChanges = " keyboard|keyboardHidden|orientation|screenSize " >
بالنسبة إلى Expo ، هناك حلان على الأقل لإصلاحه:
KeyboardAvoidingView
بعد GiftedChat. يجب أن يتم ذلك فقط لنظام Android، حيث قد يتعارض KeyboardAvoidingView
مع ميزة تجنب لوحة مفاتيح iOS المضمنة بالفعل في GiftedChat، على سبيل المثال: <View style={{ flex: 1 }}>
<GiftedChat />
{
Platform.OS === 'android' && <KeyboardAvoidingView behavior="padding" />
}
</View>
إذا كنت تستخدم React Navigation، فقد تكون هناك حاجة إلى معالجة إضافية لمراعاة رؤوس التنقل وعلامات التبويب. يمكن تعيين خاصية KeyboardAvoidingView
لـ keyboardVerticalOffset
على ارتفاع رأس التنقل ويمكن تعيين tabBarOptions.keyboardHidesTabBar
لمنع ظهور شريط علامات التبويب عندما تكون لوحة المفاتيح في الأعلى. بسبب وجود خطأ في حساب الارتفاع على هواتف Android المزودة بالشقوق، يوصى باستخدام KeyboardAvoidingView
على الحلول الأخرى التي تتضمن حساب ارتفاع النافذة.
إضافة شريط حالة خلفية معتم على app.json (على الرغم من أن android:windowSoftInputMode="adjustResize"
تم تعيينه داخليًا في تطبيقات Expo على Android، إلا أن شريط الحالة الشفاف يتسبب في عدم عمله): https://docs.expo.io/versions /latest/guides/configuration.html#androidstatusbar
إذا كنت تخطط لاستخدام GiftedChat
داخل Modal
، فراجع رقم 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
مثال آخر مع Gatsby : xcarpentier/clean-archi-boilerplate
لا تتردد في طرح الأسئلة علي على تويتر @FaridSafi! أوxcapetir!
هل تبحث عن خبير مستقل في ReactNative يتمتع بخبرة تزيد عن 14 عامًا؟ اتصل بـ Xavier من موقعه على الإنترنت!