自定义会话消息界面 UI

更新时间: 2024/05/10 13:41:15

如果默认会话界面(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) 自定义渲染群组成员 item
注:member 的类型请参考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
    const renderMessageOuterContent = (msg) => {
        const msgText =  msg.text
        return(
          <div style={{backgroundColor:'burlywood', margin:'20px'}}>
            { msgText }
          </div>
        )
      }
      
      <ChatContainer
          // ...
          renderMessageOuterContent={renderMessageOuterContents}
        />
    
    Vue
    <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
    const renderMessageInnerContent = (msg) => {
        const msgText =  msg.text
        return(
          <div style={{backgroundColor:'burlywood', margin:'20px'}}>
            { msgText }
          </div>
        )
      }
      
      <ChatContainer
          // ...
          renderMessageInnerContent={renderMessageInnerContent}
        />
    
    Vue
    <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 即可在线预览效果。

示例1

  • 示例代码

    React
    import { 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}
      />
    
    Vue
    <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

示例2

  • 示例代码

    React
    import { 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}
      />
    
    Vue
    <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
    import { ComplexAvatarContainer } from '@xkit-yx/im-kit-ui'
    //全局上下文
    const { store } = useStateContext()
    const renderP2pInputPlaceHolder = (options) => {
        return `发送给${store.uiStore.getAppellation({account: options.to})}`
    }
    
    <ChatContainer
      ...
        renderP2pInputPlaceHolder={renderP2pInputPlaceHolder}
      />
    
    Vue
    <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
    const renderEmpty = () => {
      return (
        <div>
          <img className='empty' src='https://yx-web-nosdn.netease.im/common/2946c48f29d747305e68b1ddf27f3472/无成员可添加@3x.png'/>
        </div>
      )
    }
      
      <ChatContainer
        ...
        renderEmpty={renderEmpty}
      />
    
    Vue
    <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
    const [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>)
      }
    
    Vue
    <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
    const 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}
        />
    
    Vue
    <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
    const menuItems = [
        {
          key: 'recall',
          show: 0,
        },
        {
          key: 'reply',
        },
        {
          key: 'delete',
          show: 0,
        },
        {
          key: 'forward',
        },
      ]
      
      <ChatContainer
          //...
          msgOperMenu={menuItems}
        />
    
    Vue
    <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
    const 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}
        />
    
    Vue
    <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
    //若需要在群聊消息页面设置,将 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}
        />
    
    Vue
    <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:

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

MsgOperMenuItem:

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

p2pSettingActions:

interface MsgOperMenuItem {
  // 唯一 key
  action: 'chatSetting' | 'chatRecord' | string
  // 是否显示,自带按钮默认 true,新增自定义按钮默认 false
  visible?: boolean
  // 自定义渲染函数
  render?: () => JSX.Element
  onClick?: () => void
}
此文档是否对你有帮助?
有帮助
去反馈
  • 自定义参数概览
  • 自定义示例
  • 自定义渲染消息体
  • 自定义消息发送按钮
  • 示例1
  • 示例2
  • 自定义输入框 placeholder
  • 自定义未选中会话时的内容
  • 自定义会话 header 渲染
  • 自定义消息右键操作列表
  • 新增复制操作
  • 移除原有操作项
  • 替换操作项的样式
  • 自定义消息页面右侧设置栏按钮
  • 相关图例参考
  • 群成员 Item
  • 已读未读标记
  • 消息右键操作菜单
  • 参数说明