业务代码很长这里写下来不方便,这里只做一些关键点说明
首页会话说明
1.由于习惯使用ahooks的useRequest且内置了swr所以可以直接达成一些效果,请求设置cacheKey后每次重新发起请求会先展示上次请求结果再刷新数据,可以防止每次都白屏的尴尬
2.聊天会话滑动删除效果react-native-swipe-list-view可以轻松实现滑动删除效果
3.会话组件与通讯录组件使用公用组件,组件内部跳转至聊天页面(需要参数会话id),会话中可以直接携带id参数,通讯录中群可以直接传参群id也就是会话id,单独用户则需要获取会话后再进入聊天页面
4.会话数据中将获取100条未读消息,用于角标显示大于99则显示99+
通讯录说明
1.这里偷懒了直接获取了所有的用户信息,所以删除功能暂未开放
个人信息说明
1.实现侧滑菜单效果@react-navigation/bottom-tabs @react-navigation/drawer @react-navigation/drawer 代替 expo-router 重写了布局,可以手势向右滑动或点击按钮打开菜单
2.滚动吸顶效果 ScrollView组件stickyHeaderIndices属性设置好并且内部组件按顺序布置可以直接实现滚动吸顶。各大论坛的吸顶效果不是太老用不了就是性能很差滚动时有卡顿,本人亲测此方法完美实现。
聊天页面说明
1.react-native-gifted-chat聊天组件
2.根据会话ID查询出聊天记录 onLoadEarlier 触顶追加聊天记录
3.根据会话id查询会话详情
4.全局取出当前user信息
5.底部输入框如果出现被软键盘遮挡问题 useSafeAreaInsets 预留出安全距离
6.进入聊天页面及退出聊天页面更新消息已读状态,DeviceEventEmitter 通知会话列表更新,AppState监听切换后台状态更新已读及会话列表
webSocket
这里我用的是socket.io
npm i socket.io-client
import { Socket, io } from 'socket.io-client'
const skt = io(WS_URL, {
transports: ['websocket'],
auth: { token }, // token作为参数用于socket登录
})
socket.on('message', (message: string) => {
if (message === 'tokenRrror') {
showToast('登录失效')
router.replace('/login')
} else if (message === 'RepeatLogin') {
showToast('账号已在其他设备登录')
// router.replace('/login')
} else {
showToast(message)
}
})
socket.on('response', responentMessage)
socket.on('connect', () => {
console.log('connect')
})
socket.on('disconnect', (message: string) => {
console.log('关闭连接', message)
})
socket.on('error', (error) => {
console.log('error', error)
})
socket.connect()
...
// 信息推送至后端message监听
const sendMessage = (message: sendType) => {
socket?.emit('message', message)
}
...
使用 DeviceEventEmitter 将接收到的信息推送到各个位置
const responentMessage = (message: sendType) => {
console.log('接收到消息', message)
DeviceEventEmitter.emit(PUB_SUBSCRIBE_MESSAGE, message.message)
addConversationMessage(message.message)
}