0.0.1 • Published 3 years ago

@dididc/dc-extension v0.0.1

Weekly downloads
-
License
ISC
Repository
-
Last release
3 years ago

IM 插件系统是针对外部业务高可定制化需求而提出的一个解决方案,致力于推动定制化需求的产出和落地。

IM 插件系统提供的丰富的注册点允许开发者可以直接插手到 D-Chat 的 UI 和 逻辑层面,并通过使用相同的 API,向 IM 内贡献新的能力。

IM 插件系统为各业务思考更多产品形态提供了可能,同时对于 D-Chat 而言,通过安装DC 小插件,扩展很多其他的功能和工具,以满足用户在不同的使用场景下所需的个性化和定制化需求,达到同时提高业务产品和 IM 用户使用体验的双赢。

插件系统支持在安全稳定的前提下

  • 开放代码执行,允许代码嵌入
  • 开放 IM 现有功能,允许扩展和定制
  • 提供方便快捷的开发方式,文档,脚手架,CLI
  • 提供简单灵活的开发流程,独立开发,独立发布,独立更新

针对内部定制化需求,还有一下优势

  • 清晰的开发分工,寻求一个更简单高效的协作方式
  • 解决现有的 PC 端开发问题,提高业务的开发效率

API

Registry 注册器

注册器是提供一系列注册点接口的集合,根据注册点的不同,会有以下类型

注册点:Pluggable 组件

示例:

image-20200709172034307

import React from 'react';

function UserLable(props) {
  // props 中可以拿到 IM 中的用户信息,可以进行业务数据二次处理
  return <div style={{ color: 'red', marginLeft: 5 }}>demo</div>;
}

export default class Plugin {
  initialize(registry, dcJSSDK) {
    // Pluggable 扩展,注册 user-label 组件
    registry.pluggableRegistry.register('user-label', UserLabel);
  }
}
注册点:Function Hook

示例:

registry.hookRegistry.register("di-picker-confirm",
  async ({ uids, currentUid }, next) => {
    // 调用业务服务接口
    const { data } = await getCallStatus({ call_dichat_uids: uids, dichat_uid: currentUid,});
    if (data.is_alert) {
      // 根据接口返回结果,干预逻辑处理
      dcJSSDK.confirm(
        { title: data.alert_title, content: data.alert_content },
        ({ response }) => {
          if (response === 0) return;
          const ignoreUids = ...;
          next({ ignoreUids });
        }
      );
      return;
    }
    // 不需要额外处理,继续 IM 逻辑
    next();
  }
);
注册点:消息类型

示例:

image-20200709172245323

import React from 'react';
import UserCardMessage from './LocationMessage';

function NewUserCard({ message }) {
  const cardInfo = message.getIn(['content', 'cardInfo']);
  return <UserCardMessage cardInfo={cardInfo} />;
}

export default class Plugin {
  initialize(registry, dcJSSDK) {
    // 消息类型扩展,注册定位消息类型展示
    registry.messageRegistry.register('card', {
      identify: ({ type }) => type === dcJSSDK.MessageTypes.Card,
      component: NewUserCard,
    });
  }
}
注册点:消息菜单类型

示例:

image-20200709172245323

export default class Plugin {
  initialize(registry, dcJSSDK) {
    // 消息类型扩展,注册定位消息类型展示
    registry.messageMenuRegistry.register(
      "card",
      {
        name: // 自定义菜单文案
        group: // 展示到菜单的那个分组
        order: // 菜单分组内排第几个
        shouldRender: // 是否展示
        clickHandler: // 点击菜单事件
      }
    );
  }
}

// 现在的分组情况
0  回复
──────────────────
0  撤回 / 无法撤回
1  复制 / 另存为
2  请求回执
3  转发
4  收藏
5  标记 / 取消标记
6  添加表情
7  翻译
8  转文字
9  收起文字
──────────────────
0  隐藏翻译
1  翻译反馈
──────────────────
0  多选
1  已读列表
2  更多
   0  管理员撤回

注册点:输入框工具栏

registry.editorToolbarRegistry.registerToolItem('appShortcut', {
  component: AppPickerPopover, // optional|ReactComponent 组件库,props会包含自动生成的ToolIcon的组件
  name: reactDi18n.t('快捷应用'), // required| string hover展示的文案
  icon: 'icon_line_app', // required|string|ReactComponent icon路径 可以是 url 或者 内置的svg name 或者 react组件
  order: 5, // optional|number 排序索引,默认队尾
  shouldRender: () => !chatConfig.isAppStoreEnabled(), // required|function 是否渲染入口
  clickHandler: () => {
    // optional|function 事件处理,如果component属性传递,这个方法不会被调用,请自己实现
    console.log('发起收藏');
  },
  guideTip: {
    // optional|object 功能引导配置
    text: reactDi18n.t('新增「快捷应用」入口,帮助你通过应用更快地沟通。'), // funcion 展示文案
    bitIndex: TIPS_TABLE.APP_SHORTCUTS, // optional|string 记录用户已经关闭提示的唯一key
    placement: 'topLeft', // optional|sting 展示位置
    hideWay: [HIDE_WAY_SUPPORT.CLOSE_CLICK, HIDE_WAY_SUPPORT.CLICK], // optional|Array<string> 支持的关闭方式
    maxWidth: 260, // optional|number 最大宽度
  },
});

注册点:Module

示例:

image-20200709172245323

import React from 'react';
import Icon from './Icon';
import NoticePanel from './FavoritePanel';

export default class Plugin {
  initialize(registry, dcJSSDK) {
    registry.moduleRegistry.register(
      “new-notice",
      async ({ userInfo }) => {
        // 如果有必要,可以根据用户信息不同,返回不同的内容
        return {
            name: '通知',
            tip: '通知',
            icon: <Icon />,
            content: <NoticePanel />
        };
    );
  }
}
注册点:Welcome
import React from 'react';
import WelcomePage from './WelcomePage';

export default class Plugin {
  initialize(registry, dcJSSDK) {
    registry.welcomeRegistry.register(
      "rainbow-welcome",
      {
        component: // 组件
        width: // 窗口宽度
        height: // 窗口高度
        mask: // 遮罩是否开启,可以填入颜色
      }
    );
  }
}
注册点统计

现有注册点接口文档

Plugin 插件

插件是承载扩展代码的容器,用于和 IM 系统对接,IM 侧只认可 内部定制应用中心成功注册 的插件

生命周期函数
方法名触发时机用途参数
preInit插件初始化前前置代码,如 token 获取,权限校验等JSSDK
initialize初始化时注册注册点,注册点只可以在此方法处理Registry, JSSDK
postInit插件初始化后后置代码,根据需求JSSDK
destroy插件卸载前移除注册点JSSDK

开发流程

插件初始化

使用插件脚手架初始化插件项目,详细说明文档查看链接

插件开发

在入口文件里实现以下代码:

  • 新建一个 Plugin 类

  • 实现一个 initialize 方法

    • 编写业务逻辑
    • 使用 registry 提供的注册点注册,支持注册的类型为 React 组件函数
    • 使用 JSSDK 和 IM 进行交互
  • 注册 Plugin 实例到 IM 内

插件调试

  • IM 方提供 test 包
  • 使用提供的 cli 设置插件目录或开发环境 url,指定业务方本地插件代码
  • 通过 electron 提供的 devtools 进行调试

image-20200709165910851

插件部署和发布

待测试完成后使用 npm 发布新版本 package 包,

内部定制插件如果需要新版本 Registry 和 SDK 支持,需要同步修改 IM 侧配置代码,其他情况可以使用热更新(预计 Release 2.0 发布)方式

应用中心插件需要在中心上架新版本后使用热更新方式

大致的流程如下图

版本更新

Release 1.0 - 2020/7/9

支持 Npm package 发布

插件安装 重载 卸载

脚手架 CLI

文档完善

开放能力测试工具