自定义会话消息界面 UI

更新时间: 2024/10/29 10:04:33

如果默认会话界面(chat-kit)无法满足您的业务需求,您可通过聊天组件的自定义参数进行界面自定义。

自定义参数

chat-kit 提供的自定义参数如下:

参数
类型 说明
actions Action[]

消息发送按钮组配置,不传使用默认的配置

  • action: 按钮类型,内置类型包括表情(emoji)、发送图片(sendImg)、发送文字(sendMsg)和发送文件(sendFile),如需自定义请使用自定义 action 名称
  • visible:boolean 类型,是否显示该按钮,默认 true
  • render: (props: ActionRenderProps) => ReactNode} 类型,自定义渲染,如果不传则使用默认渲染方

具体的示例参考下文 自定义消息发送按钮
renderP2pInputPlaceHolder ((session: Session) => string) 自定义渲染单聊聊天输入框 placeholder,具体的示例参考下文 自定义输入框 placeholder
renderTeamInputPlaceHolder ((params: { session: Session; mute: boolean; }) => string) 自定义渲染群组聊天输入框 placeholder,具体的示例参考下文 自定义输入框 placeholder
renderTeamMemberItem ((params: { member: TeamMember & Partial<FriendProfile>; }) => Element | null) 自定义渲染 群组成员 itemmember 的类型请参考 TeamMember
onSendText ((data: { value: string; scene: "p2p" | "team" | "superTeam"; to: string; }) => Promise<void>) 发送文字消息的回调,一般用于默认的文字发送缺少想要的字段时。具体使用示例参考 实现自定义消息收发
afterTransferTeam (teamId: string) => Promise 转让群主后的回调。
renderP2pCustomMessage ((options: RenderP2pCustomMessageOptions) => Element | null) 渲染单聊中的自定义消息。
renderTeamCustomMessage ((options: RenderTeamCustomMessageOptions) => Element | null) 渲染群聊中的自定义消息 RenderTeamCustomMessageOptions.msg 的类型请参考 IMMessage
renderEmpty (() => Element) 自定义渲染未选中任何会话时的内容,具体示例参考下文 自定义未选中会话时的内容
renderHeader ((session: Session) => Element) 自定义渲染会话的 header 样式,具体示例参考下文 自定义会话 header 渲染
selectedSession string 自定义选中的会话 sessionId,若为群聊场景,则填入 team-teamId。若为单聊场景,则填入 p2p-accountId。一般不用传,内部会处理好选中逻辑。
prefix string 样式前缀,默认值:chat
commonPrefix string 公共样式前缀,默认值:common
renderMessageOuterContent ((msg: IMMessage) => JSX.Element | null | undefined) 自定义渲染会话消息,气泡样式也需要自定义,具体示例参考下文 自定义渲染消息体msg 的类型请参考 IMMessage
renderMessageInnerContent ((msg: IMMessage) => JSX.Element | null | undefined) 自定义渲染会话消息,不需要自定义气泡样式,具体示例参考下文 自定义渲染消息体msg 的类型请参考 IMMessage
msgOperMenu MsgOperMenuItem[] 自定义渲染消息右键菜单,包括菜单项是否显示(show)、菜单项名称(label、key、icon)、自定义单击事件(onClick),具体示例参考下文 自定义消息右键操作列表
p2pSettingActions ChatSettingActionItem[] 自定义单聊消息页面右侧的设置栏按钮,具体示例参考下文 自定义消息页面右侧设置栏按钮
teamSettingActions ChatSettingActionItem[] 自定义群聊消息页面右侧的设置栏按钮,具体示例参考下文 自定义消息页面右侧设置栏按钮
  • 对于单聊消息体的自定义渲染,若同时设置了 renderP2pCustomMessagerenderMessageOuterContentrenderMessageInnerContent,那么会按照一下优先级进行修改:renderP2pCustomMessage > renderMessageOuterContent> renderMessageInnerContent。

  • 同理,对于群聊消息体的自定义渲染,优先级为:renderTeamCustomMessage > renderMessageOuterContent> renderMessageInnerContent。

自定义示例

渲染消息体

在单聊界面,自定义渲染消息体(区分是否自定义气泡样式)。

  • 自定义渲染消息体(需要自定义气泡样式)的示例代码:

    React
    JSX/TSXconst renderMessageOuterContent = (msg) => {
        const msgText = msg.text
        return(
            <div style={{backgroundColor:'burlywood', margin:'20px'}}>
            { msgText }
            </div>
        )
        }
    
        <ChatContainer
            // ...
            renderMessageOuterContent={renderMessageOuterContents}
        />
    
    Vue2/Vue3
    TypeScript<template>
        <div ref="chat" />
    </template>
    
    <script>
        ...
            mounted() {
                this.$uikit.render(
                    ChatContainer,
                    {
                    renderMessageOuterContent: (msg) => {
                        const msgText = msg.text
                        return compile(
                        `<div style={{backgroundColor:'burlywood', margin:'20px'}}>
                            { context.msgText }
                        </div>`, { msgText })
                    }
                    },
                    this.$refs.chat
                );
            }
    </script>
    
  • 自定义渲染消息体(不需要自定义气泡样式)的示例代码:

    React
    JSX/TSXconst renderMessageInnerContent = (msg) => {
        const msgText = msg.text
        return(
            <div style={{backgroundColor:'burlywood', margin:'20px'}}>
            { msgText }
            </div>
        )
        }
    
        <ChatContainer
            // ...
            renderMessageInnerContent={renderMessageInnerContent}
        />
    
    Vue2/Vue3
    TypeScript<template>
        <div ref="chat" />
    </template>
    
    <script>
        ...
            mounted() {
                this.$uikit.render(
                    ChatContainer,
                    {
                    renderMessageInnerContent: (msg) => {
                        const msgText = msg.text
                        return compile(
                        `<div style={{backgroundColor:'burlywood', margin:'20px'}}>
                            { context.msgText }
                        </div>`, { msgText })
                    }
                    },
                    this.$refs.chat
                );
            }
    </script>
    
  • 效果比对

    默认消息体 自定义渲染消息体(需要自定义气泡样式) 自定义渲染消息体(不需要自定义气泡样式)
    Web 默认消息体.png 渲染消息体out.png 渲染消息体in.png

消息发送按钮

本节提供以下示例供您参考:

  • 示例 1:将默认的消息发送按钮删除,并新增一个自定义的消息发送按钮。

  • 示例 2:在保留默认的消息发送按钮的基础上,新增一个自定义的消息发送按钮。

  • 查看在线示例

    IMAppProps 传入正确的 appkeyaccounttoken 即可在线预览效果。

示例一

  • 示例代码

    React
    JSX/TSXimport { ComplexAvatarContainer } from '@xkit-yx/im-kit-ui'
    //全局上下文
    const { store } = useStateContext()
    const actions = [
        {
            action: 'emoji',
            visible: true,
            render: () => {
            return (
                //绑定的事件中可以从 store 中访问上下文
                <div style={{margin: '0 10px'}}>
                <i className="iconfont seeting">&#xe6d6;</i>
                </div>
            )
            }
        }
    ]
    
    <ChatContainer
        ...
        actions={actions}
        />
    
    Vue2/Vue3
    TypeScript<template>
        <div ref="chat" />
    </template>
    
    <script>
        ...
            mounted() {
                this.$uikit.render(
                ChatContainer,
                {
                actions:[{
                    action: 'emoji',
                    visible: true,
                    render: () => {
                    return compile(
                        `<div style={{margin: '0 10px'}}>
                        <i className="iconfont icon-logout" />
                        </div>`
                    )
                    }
                }]
                },
                this.$refs.chat
            );
            }
    </script>
    
  • 效果比对

    默认
    自定义后
    消息发送按钮.png 删除默认增加自定义按钮 1.png

示例二

  • 示例代码

    React
    JSX/TSXimport { ComplexAvatarContainer } from '@xkit-yx/im-kit-ui'
    //全局上下文
    const { store } = useStateContext()
    const actions = [
        {
        action: 'setting',
        visible: true,
        render: () => {
            return (
            <div style={{margin: '0 10px', fontSize: '14px'}}>
                <i style={{ fontSize: '14px'}} className="iconfont seeting">&#xe6d6;</i>
            </div>
            )
        }
        },
        {
        action: 'emoji',
        visible: true,
        },
        {
        action: 'sendImg',
        visible: true,
        },
        {
        action: 'sendFile',
        visible: true,
        },
        {
        action: 'sendMsg',
        visible: true,
        }
    ]
    
    <ChatContainer
        ...
        actions={actions}
        />
    
    Vue2/Vue3
    TypeScript<template>
        <div ref="chat" />
    </template>
    
    <script>
        ...
            methods: {
            sendMsg() {
                console.log('==========sendMsg===========');
            }
            },
            mounted() {
                this.$uikit.render(
                ChatContainer,
                {
                actions: [
                    {
                    action: 'setting',
                    visible: true,
                    render: () => {
                        return compile(
                        `<div onClick={context.sendMsg} style={{margin: '0 10px', fontSize: '14px'}}>
                            <i className="iconfont icon-logout" />
                        </div>`, { sendMsg: this.sendMsg })
                    }
                    },
                    {
                    action: 'emoji',
                    visible: true,
                    },
                    {
                    action: 'sendImg',
                    visible: true,
                    },
                    {
                    action: 'sendFile',
                    visible: true,
                    },
                    {
                    action: 'sendMsg',
                    visible: true,
                    }
                ]
                },
                this.$refs.chat
            );
            }
    </script>
    
  • 效果比对

    默认
    自定义后
    消息发送按钮.png 新增按钮保留默认 1.png

输入框 placeholder

  • 查看在线示例

    IMAppProps 传入正确的 appkeyaccounttoken 即可在线预览效果。

  • 示例代码

    React
    JSX/TSXimport { ComplexAvatarContainer } from '@xkit-yx/im-kit-ui'
    //全局上下文
    const { store } = useStateContext()
    const renderP2pInputPlaceHolder = (options) => {
        return `发送给${store.uiStore.getAppellation({account: options.to})}`
    }
    
    <ChatContainer
        ...
        renderP2pInputPlaceHolder={renderP2pInputPlaceHolder}
        />
    
    Vue2/Vue3
    TypeScript<template>
        <div ref="chat" />
    </template>
    
    <script>
        ...
            mounted() {
                this.$uikit.render(
                ChatContainer,
                {
                renderP2pInputPlaceHolder :(options) => {
                    const { store, nim } = window.__xkit_store__
                    return `发送给${store.uiStore.getAppellation({account: options.to})}`
                }
                },
                this.$refs.chat
            );
            }
    </script>
    
  • 效果比对

    默认
    自定义后
    默认的输入框 placeholder.png 自定义输入框 placeholder1.png

未选中会话时的内容

  • 查看在线示例

    IMAppProps 传入正确的 appkeyaccounttoken 即可在线预览效果。

  • 示例代码

    React
    JSX/TSXconst renderEmpty = () => {
        return (
        <div>
            <img className='empty' src='https://yx-web-nosdn.netease.im/common/2946c48f29d747305e68b1ddf27f3472/无成员可添加@3x.png'/>
        </div>
        )
    }
    
        <ChatContainer
        ...
        renderEmpty={renderEmpty}
        />
    
    Vue2/Vue3
    TypeScript<template>
        <div ref="chat" />
    </template>
    
    <script>
        ...
            mounted() {
                this.$uikit.render(
                ChatContainer,
                {
                renderEmpty: () => {
                    return compile(
                    `<div>
                        <img className='empty' src='https://yx-web-nosdn.netease.im/common/2946c48f29d747305e68b1ddf27f3472/无成员可添加@3x.png'/>
                    </div>`
                    )
                }
                },
                this.$refs.chat
            );
            }
    </script>
    
  • 效果对比

    默认
    自定义后
    未选中会话时的默认展示.png 未选中会话时的默认展示自定义后1.png

会话 header 渲染

  • 查看在线示例

    IMAppProps 传入正确的 appkeyaccounttoken 即可在线预览效果。

  • 示例代码

    React
    JSX/TSXconst [teamInfo, setTeamInfo] = useState({})
        const renderHeader = (options) => {
        store.teamStore.getTeamForceActive(options.to).then(res => {
            setTeamInfo(res)
        })
        return (
        <div style={{display: 'flex', alignItems: 'center'}}>
            <img className='avatar' src={teamInfo.avatar} alt="" />
            <div style={{fontWeight: 'bold'}}>网易云信-{teamInfo.name}-自定义</div>
        </div>)
        }
    
    Vue2/Vue3
    TypeScript<template>
        <div ref="chat" />
    </template>
    
    <script>
        ...
        data: function () {
            return {
            };
            },
            methods: {
            sendMsg() {
                console.log('==========sendMsg===========');
            }
            },
            mounted() {
                this.$uikit.render(
                ChatContainer,
                {
                renderHeader :(options) => {
                    console.log('==========renderHeader===========', options);
                    const { store, nim } = window.__xkit_store__
                    const teamInfo = store.teamStore.teams.get(options.to)
                    return compile(
                    `<div onClick={context.sendMsg} style={{display: 'flex', alignItems: 'center'}}>
                    <img className='avatar' src={context.teamInfo.avatar} />
                    <div style={{fontWeight: 'bold'}}>网易云信-{context.teamInfo.name}-自定义</div>
                    </div>`, { teamInfo: teamInfo, sendMsg: this.sendMsg })
                }
                },
                this.$refs.chat
            );
            }
    </script>
    
  • 效果对比

    默认
    自定义后
    默认会话 header 渲染.png 会话 header 渲染自定义后 1.png

消息右键操作列表

本节提供三个示例供您参考

  • 新增复制操作:在原有菜单基础上新增一项 复制 操作。
  • 移除原有操作项:移除原有消息操作菜单相关配置项,例如不希望消息可以 删除 或者 撤回
  • 替换操作项的样式:对原有消息菜单操作配置项进行自定义渲染和自定义单击事件,例如替换 删除 消息的文字和 icon。

新增复制操作

在原有的消息右键菜单基础上新增一项 复制 操作。

  • 示例代码

    React
    JSX/TSXconst menuItems = [
        {
            key: 'recall',
        },
        {
            key: 'reply',
        },
        {
            key: 'delete',
        },
        {
            key: 'forward',
        },
        {
            key: 'copy',
            icon: <CopyOutlined />,
            label: '复制',
            show: 1,
            onClick: (msg) => {
            console.log('========msg========', msg)
            // do something
            },
        },
        ]
    
        <ChatContainer
            //...
            msgOperMenu={menuItems}
        />
    
    Vue2/Vue3
    TypeScript<template>
        <div ref="chat" />
    </template>
    
    <script>
        ...
            mounted() {
                this.$uikit.render(
                ChatContainer,
                {
                msgOperMenu:[
                    {
                    key: 'recall',
                    },
                    {
                    key: 'reply',
                    },
                    {
                    key: 'delete',
                    },
                    {
                    key: 'forward',
                    },
                    {
                    key: 'copy',
                    icon: compile(`<i className="iconfont icon-logout" />`),
                    label: '复制',
                    show: 1,
                    onClick: (msg) => {
                        console.log('========msg========', msg)
                        // do something
                    },
                    },
                ]
                },
                this.$refs.chat
            );
            }
    </script>
    
  • 效果比对

    默认
    自定义后
    web 消息右键默认.png web 消息右键复制.png

移除原有操作项

移除原有消息操作菜单相关配置项,例如不希望消息可以 删除 或者 撤回

  • 示例代码

    React
    JSX/TSXconst menuItems = [
        {
            key: 'recall',
            show: 0,
        },
        {
            key: 'reply',
        },
        {
            key: 'delete',
            show: 0,
        },
        {
            key: 'forward',
        },
        ]
    
        <ChatContainer
            //...
            msgOperMenu={menuItems}
        />
    
    Vue2/Vue3
    TypeScript<template>
        <div ref="chat" />
    </template>
    
    <script>
        ...
            mounted() {
                this.$uikit.render(
                ChatContainer,
                {
                msgOperMenu:[
                    {
                        key: 'recall',
                        show: 0,
                    },
                    {
                        key: 'reply',
                    },
                    {
                        key: 'delete',
                        show: 0,
                    },
                    {
                        key: 'forward',
                    },
                    ]
                },
                this.$refs.chat
            );
            }
    </script>
    
  • 效果比对

    默认
    自定义后
    web 消息右键默认.png web 消息右键删除.png

替换操作项的样式

对原有消息菜单操作配置项进行自定义渲染和自定义单击事件,例如替换 删除 消息的文字和图标(icon)。

  • 示例代码

    React
    JSX/TSXconst menuItems = [
        {
            key: 'recall',
        },
        {
            key: 'reply',
        },
        {
            key: 'delete',
            icon: <FileExcelOutlined />,
            label: 'delete',
            show: 1,
            onClick: (msg) => {
            console.log('========msg========', msg)
            // do something
            },
        },
        {
            key: 'forward',
        },
        ]
    
        <ChatContainer
            //...
            msgOperMenu={menuItems}
        />
    
    Vue2/Vue3
    TypeScript<template>
        <div ref="chat" />
    </template>
    
    <script>
        ...
            mounted() {
                this.$uikit.render(
                ChatContainer,
                {
                msgOperMenu: [
                    {
                    key: 'recall',
                    },
                    {
                    key: 'reply',
                    },
                    {
                    key: 'delete',
                    icon: compile(`<i className="iconfont icon-logout" />`),
                    label: 'delete',
                    show: 1,
                    onClick: (msg) => {
                        console.log('========msg========', msg)
                        // do something
                    },
                    },
                    {
                    key: 'forward',
                    },
                ]
                },
                this.$refs.chat
            );
            }
    </script>
    
  • 效果比对

    默认
    自定义后
    web 消息右键默认.png web 消息右键自定义.png

消息页面右侧设置栏按钮

单聊消息页面群聊消息页面 的右侧设置栏可以自定义按钮。

本文提供 在单聊消息页面隐藏原有的设置按钮, 并在右侧设置栏新增一个按钮 的示例供您参考。

  • 示例代码

    React
    JSX/TSX//若需要在群聊消息页面设置,将 p2pSettingActions 替换为 teamSettingActions 即可
    const p2pSettingActions = [
        {
            action: 'chatSetting',
            visible: false,
        },
        {
            action: 'chatHistory',
            visible: true,
            render: () => {
            //todo
            return <i className="iconfont">&#xe6c9;</i>
            },
            onClick: () => {
            //todo
            },
        },
        ]
    
        <ChatContainer
            //...
            p2pSettingActions={p2pSettingActions}
        />
    
    Vue2/Vue3
    JSX/TSX<template>
        <div ref="chat" />
    </template>
    
    <script>
        mounted() {
            this.$uikit.render(
            ChatContainer,
            {
                teamSettingActions: [
                {
                    action: 'chatSetting',
                    visible: false,
                },
                {
                    action: 'chatHistory',
                    visible: true,
                    render: () => {
                    //todo
                    return compile(`<i className="iconfont">&#xe6c9;</i>`)
                    },
                    onClick: () => {
                    //todo
                    },
                },
                ]
            },
            this.$refs.chat
            );
        }
        ...
    </script>
    
  • 效果比对

    默认
    自定义后
    消息页面右侧按钮.png 消息页面右侧按钮自定义.png

图例参考

群成员 Item

已读未读标记

Web 单聊已读未读标记.png

消息右键操作菜单

参数说明

  • Action

    JavaScriptinterface Action {
    /**
        按钮类型
        */
    action: 'emoji' | 'sendImg' | 'sendFile' | 'sendMsg' |string
    /**
        是否显示该按钮,自带按钮默认 true,新增自定义按钮默认 false
        */
    visible?: boolean
    /**
        自定义渲染,如果不传则使用默认渲染方式
        */
    render?: (props: ActionRenderProps) => ReactNode
    }
    
  • MsgOperMenuItem

    JavaScriptinterface MsgOperMenuItem {
    // 是否显示
    show?: 1 | 0
    // 名称
    label?: string
    // 唯一 key
    key: MenuItemKey
    // 图标
    icon?: React.ReactNode
    onClick?: (msg: IMMessage) => void
    }
    
  • p2pSettingActions

    JavaScriptinterface MsgOperMenuItem {
    // 唯一 key
    action: 'chatSetting' | 'chatRecord' | string
    // 是否显示,自带按钮默认 true,新增自定义按钮默认 false
    visible?: boolean
    // 自定义渲染函数
    render?: () => JSX.Element
    onClick?: () => void
    }
    
此文档是否对你有帮助?
有帮助
去反馈
  • 自定义参数
  • 自定义示例
  • 渲染消息体
  • 消息发送按钮
  • 输入框 placeholder
  • 未选中会话时的内容
  • 会话 header 渲染
  • 消息右键操作列表
  • 消息页面右侧设置栏按钮
  • 图例参考
  • 参数说明