# UI 扩展:卡片 / 页面 / 菜单 / 前台组件

ASG.Director 插件可以往 UI 里“挂载”一些内容:

  • 启动台主页卡片(Card)
  • 插件页面(Page)
  • 主页菜单项(Menu Item)
  • 前台组件(Frontend Widget):在直播画面中显示,可拖拽/可编辑

这些能力都通过 context.api.components 完成。

# 1) 注册主页卡片(Card)

卡片通常出现在启动台主页,用于提供一个快捷入口或展示状态。

function activate(context) {
  const card = context.api.components.registerCard({
    id: `${context.pluginId}.card.demo`,
    pluginId: context.pluginId,
    title: '示例卡片',
    description: '点击按钮弹出提示',
    icon: '🧩',
    order: 50,
    html: '<div style="padding:12px">这是插件卡片内容</div>',
    actions: [{ id: 'hello', title: '打招呼' }],
    onAction: async (actionId) => {
      if (actionId === 'hello') {
        context.api.notifications.showInfo('你好!来自插件卡片')
      }
    }
  })

  context.subscriptions.push(card)
}

要点:

  • id 建议带上 pluginId 前缀,确保全局唯一。
  • 注册/注销会自动触发 UI 刷新(不需要手动刷新)。

# 2) 注册插件页面(Page)

插件页面适合放“设置页/工具页”。

function activate(context) {
  const page = context.api.components.registerPage({
    id: `${context.pluginId}.page.settings`,
    pluginId: context.pluginId,
    title: '示例:设置页',
    icon: '⚙️',
    order: 50,
    html: '<h2 style="padding:12px">Hello from plugin page</h2>'
  })

  context.subscriptions.push(page)
}

# 3) 注册菜单项(Menu Item)

菜单项用于把页面/命令挂到启动台的菜单区域。

function activate(context) {
  const item = context.api.components.registerMenuItem({
    id: `${context.pluginId}.menu.settings`,
    pluginId: context.pluginId,
    label: '示例:打开设置页',
    icon: '⚙️',
    order: 10,
    pageId: `${context.pluginId}.page.settings`
  })

  context.subscriptions.push(item)
}

pageIdcommand 二选一:

  • pageId:点击菜单打开对应插件页面
  • command:点击菜单执行命令(你仍需注册命令处理函数)

# 4) 注册前台组件(Frontend Widget)

前台组件会出现在“前台画面”里,并且支持在编辑模式下拖拽/改大小。

function activate(context) {
  const widget = context.api.components.registerFrontendWidget({
    id: `${context.pluginId}.widget.demoText`,
    pluginId: context.pluginId,
    type: 'html',
    label: '示例文本',
    icon: '🔤',
    order: 50,
    defaultPosition: { x: 100, y: 100 },
    defaultSize: { width: 320, height: 80 },
    html: '<div style="font-size:32px;color:white;text-shadow:0 0 6px #000">{{text}}</div>',
    data: { text: 'Hello ASG' },
    resizable: true,
    draggable: true
  })

  // 后续你可以更新 data(会推送到所有窗口/前台)
  widget.update({
    data: { text: '文本已更新' }
  })

  context.subscriptions.push(widget)
}

提示:

  • 组件的“数据更新”也可以由渲染进程触发(例如某个页面调用 plugins.updateFrontendWidget(...)),插件端只需要定义好 widget 并处理更新即可。
  • 如果你要做更复杂的交互(例如接入房间/比分/事件),建议先在本地用一个简单的 widget 验证渲染链路再逐步扩展。