SuperAPI AI 工具集

cometchat-react-native-customization

前端与建站

查看项目

更新于 10-21 20:37

技能介绍

用途

本技能面向使用 CometChat React Native UI Kit v5(@cometchat/chat-uikit-react-native@5)的开发者,用于对聊天界面进行主题化、重新样式化以及扩展自定义消息类型。适用场景包括:更改聊天配色、品牌化聊天 UI、实现深色模式、重新设计消息气泡、添加自定义消息类型、渲染自定义气泡、在消息菜单中增加选项等。

使用前提:需要先掌握配套技能 cometchat-react-native-core(安装、Provider 链、init→login→render),本技能不再重复。主题化需要 CometChatThemeProvider 已在组件链中。

定制机制:三层,从成本最低开始

该 UI Kit 没有 CSS,没有样式表、className 或 --cometchat-* 变量。若手头是带 CSS 自定义属性的 React 片段,在此不适用。

第一层:主题模式 + 颜色令牌(全应用)

Provider 接收的 theme 属性形如 { mode, light, dark }。mode 可取 "light"、"dark"、"auto",其中 "auto" 使套件跟随设备(操作系统)的明暗设置(读取 useColorScheme()),Provider 默认即为 "auto"。

固定深色示例:

<CometChatThemeProvider theme={{ mode: "dark" }}>{/* … */}</CometChatThemeProvider>

跟随系统并在两种模式下品牌化:

<CometChatThemeProvider
  theme={{
    mode: "auto",
    light: { color: { primary: "#F76808" } },
    dark: { color: { primary: "#F8935B" } },
  }}
>
  {/* … */}
</CometChatThemeProvider>

primary 驱动按钮、发出消息气泡和激活状态,通常品牌变更只需这一个令牌。其他常见令牌:textPrimary、background1、neutral50、extendedPrimary500。完整列表应从 /ui-kit/react-native/colors.md 获取,不要猜测令牌名。

要跟随系统,使用 mode: "auto" 并同时设置 light 和 dark。若不使用 Provider,系统主题变化完全不会反映。

第二层:逐组件样式对象

每个组件接收 style 属性,其中包含具名子样式对象——是普通 RN 样式对象,不是 CSS:

<CometChatConversations style={{ containerStyle: { backgroundColor: "#F7F7F7" } }} />

同样的样式键也可通过主题全局设置,当变更应处处生效时更可取:

<CometChatThemeProvider theme={{ light: { conversationStyles: { /* … */ } } }}>

样式键名因组件而异。应从该组件页面(/ui-kit/react-native/component-styling.md 及组件自身页面)获取,不要从其他组件套用。

第三层:在自定义视图中读取当前主题

useTheme() 返回已解析的主题(已按 mode 解析为 light 或 dark),使自定义视图无需重新推导调色板即可与套件匹配:

import { useTheme } from "@cometchat/chat-uikit-react-native";
import { Text } from "react-native";

const Label = () => {
  const theme = useTheme();
  return <Text style={{ color: theme.color.textPrimary }}>Chats</Text>;
};

自定义消息类型:DataSource 装饰器链

注意:RN 没有 React 插件 API。CometChatMessagePlugin 和 CometChatPluginRegistry 在此套件中不存在,写出它们无法编译。RN 使用装饰器链。

扩展 DataSourceDecorator,覆盖所需方法,并用 ChatConfigurator.enable 注册:

import {
  ChatConfigurator, DataSourceDecorator, CometChatMessageTemplate,
} from "@cometchat/chat-uikit-react-native";

const ORDER_TYPE = "order";

class OrderDataSource extends DataSourceDecorator {
  // 0. 身份标识——必需。基类 DataSourceDecorator.getId() 会抛出
  // ("Method not implemented."),而 ChatConfigurator.enable() 调用 getId() 去重
  // 注册表——因此缺少此覆盖的子类会在 ChatConfigurator.enable(...) 处崩溃,
  // 而不是在渲染时。返回稳定、唯一的 id。
  getId(): string {
    return "order_message_datasource";
  }

  // 1. 渲染——气泡如何绘制。
  getAllMessageTemplates(theme?: any, params?: any): CometChatMessageTemplate[] {
    const templates = super.getAllMessageTemplates(theme, params);
    // 在此追加或替换模板
    return templates;
  }

  // 2. 拉取——没有这两个方法消息永远不会被检索到。
  // CometChatMessageList 由此构建请求:
  //   requestBuilder.setTypes(ChatConfigurator.dataSource.getAllMessageTypes())
  //   requestBuilder.setCategories(ChatConfigurator.dataSource.getAllMessageCategories())
  // 未出现在这些过滤器中的类型会被服务端排除。发送时气泡乐观出现,
  // 重新加载后消失——且任何地方都没有错误。
  getAllMessageTypes(): string[] {
    return [...super.getAllMessageTypes(), ORDER_TYPE];
  }

  getAllMessageCategories(): string[] {
    const categories = super.getAllMessageCategories();
    return categories.includes(CometChat.CATEGORY_CUSTOM)
      ? categories
      : [...categories, CometChat.CATEGORY_CUSTOM];
  }
}

// 在 login() 之后,而非仅在 init() 之后。CometChatUIKit.login() 调用 enableExtensions(),
// 其第一条语句是 ChatConfigurator.init()——“重新初始化数据源”。更早注册的任何内容
// 都会被丢弃,因此在模块作用域或紧接 init() 之后注册的装饰器会静默消失。
await CometChatUIKit.login({ uid: UID });
ChatConfigurator.enable((source) => new OrderDataSource(source));

getId() 对每个 DataSourceDecorator 子类都是必需的。它是唯一不委托给被包装源的基类方法——基类抛出 Error("Method not implemented."),而 ChatConfigurator.enable() 调用 getId() 去重注册表。省略它,注册会在 ChatConfigurator.enable(...) 处崩溃并报 Method not implemented——而不是在渲染时,因此看起来不相关。每个内置装饰器(Polls、Stickers、Translation、LinkPreview、Collaborative*)都覆盖了它;你的也必须覆盖,返回稳定唯一的字符串。

自定义消息类型有两半,只有一半是显而易见的。渲染是 getAllMessageTemplates / getMessageTemplate。拉取是 getAllMessageTypes / getAllMessageCategories。只交付渲染那一半,一切看起来正常,直到第一次重新加载,该类型的所有消息都消失了——没有错误,没有警告。

DataSourceDecorator 暴露约 50 个可覆盖方法;通常需要的是 getId(必需——见上)、getAllMessageTemplates、getMessageTemplate、getAllMessageTypes、getAllMessageCategories、getMessageOptions(长按菜单)和 getAuxiliaryOptions(输入框操作)。始终调用 super.<method>(...) 并修改结果——整体替换会丢弃所有内置消息类型。

文档缺口(RN-G10):DataSourceDecorator / MessageDataSource / ExtensionsDataSource 和 ChatConfigurator.enable 未在任何 RN 页面记录——文档仅展示通过 getAllMessageTemplates() 修改现有模板。此内容基于套件源码构建;应向开发者说明,而非当作已记录内容呈现。

部分关闭(2026-08-20)。ui-kit/react-native/message-list 现已记录真正破坏构建的那一半:自定义类型必须为拉取注册(getAllMessageTypes / getAllMessageCategories),而不仅为渲染,且装饰器必须在 login() 之后注册,因为 enableExtensions() 会重新运行 ChatConfigurator.init()。仍缺失:一个专门的 RN 自定义消息类型页面,端到端覆盖 DataSourceDecorator / MessageDataSource / ExtensionsDataSource。负责人:docs。

不使用装饰器定制现有气泡

若要重新样式化而非替换,优先使用主题的气泡样式键——textBubbleStyles、imageBubbleStyles、fileBubbleStyles、pollBubbleStyles 及同类。确切键名从 /ui-kit/react-native/message-bubble-styling.md 获取。

常见陷阱

  • 试图使用 CSS——没有样式表、className、--cometchat-*。使用主题对象 + RN 样式。
  • 写出 React 插件 API——不存在;使用 ChatConfigurator + DataSourceDecorator。
  • 装饰器省略 getId()——基类抛出;ChatConfigurator.enable() 调用它 → 注册时崩溃并报 Method not implemented。
  • 装饰器覆盖中不调用 super——静默丢弃所有内置模板。
  • 应用跟随系统时只设置 light——深色模式回退到默认值。
  • 猜测令牌或样式键名——应获取;错误的键会静默失败而非报错。

验证是否生效

  • 每个符号都出现在 catalogs/rn-v5.json 中。
  • npm run verify:fences:rn-v5 针对固定版本的套件编译示例。
  • 在设备上:切换操作系统深色模式并确认界面跟随;确认自定义模板渲染且内置类型仍一并渲染。