从零开始开发聊天APP (前端篇二)

142 阅读2分钟

业务代码很长这里写下来不方便,这里只做一些关键点说明

仓库 github.com/NewSmallObj…

首页会话说明

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)
}