Skip to content

View 命令带有界面,运行在 iframe 中。推荐使用 Vite 进行前端构建(React/Vue/原生均可)。

关键点

  • 宿主在加载时给 UI 入口附加查询参数:?sid=<sessionId>&cmd=<command>,可按需读取。
  • 与宿主的通信与能力调用通过 @sofastapp/api 暴露的 API 完成。
  • UI 需要被构建为静态资源,并由宿主通过本地 HTTP 服务托管。

读取会话信息

ts
// 在 UI 中可选读取 sessionId 与当前命令名
const sid = new URLSearchParams(location.search).get('sid');
const cmd = new URLSearchParams(location.search).get('cmd');

常用 API 示例(UI 环境)

ts
import { Context, Screenshot, LocalStorage } from '@sofastapp/api';

// 读取/清空/监听 搜索框内容
const text = await Context.getSearchContent();
await Context.clearSearchContent();
const unwatch = Context.watchSearchContent((val) => {
  console.log('context changed:', val);
});

// 触发宿主截图流程
await Screenshot.start();

// 插件私有存储(键值对)
const cur = (await LocalStorage.getItem<number>('counter')) ?? 0;
await LocalStorage.setItem('counter', cur + 1);
const all = await LocalStorage.allItems<Record<string, any>>();
await LocalStorage.clear();

Vite 基础配置(示例 React)

ts
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  base: './',
  plugins: [react()],
  build: {
    outDir: 'dist',
    rollupOptions: { output: { manualChunks: undefined } },
  },
});

说明 宿主会按命令启动一个会话,并通过本地 HTTP 服务托管插件目录,默认入口为 index.html,无需在清单中指定入口文件。

多指令路由(同一个 UI 复用)

  • 一个插件可以在 commands 中声明多个 view 指令,它们会共享同一个 index.html
  • 宿主在加载时会添加查询参数:?sid=<sessionId>&cmd=<command>
  • UI 侧应读取 cmd,据此切换到对应的页面/组件(可以是条件渲染,也可以映射到内部路由)。

示例(React):

tsx
import React from 'react';

const pages = {
  'hello-view': () => <div>Hello</div>,
  'time-view': () => <div>{new Date().toLocaleTimeString()}</div>,
  'api-storage': () => <StorageDemo />,
} as const;

export default function App() {
  const params = new URLSearchParams(location.search);
  const cmd = params.get('cmd') || 'hello-view';
  const Page = (pages as any)[cmd] || (() => <div>Unknown: {cmd}</div>);
  return <Page />;
}

要点

  • 不需要额外的清单配置,一个 index.html 可以承载所有 view 指令。
  • 只需在 UI 中读取 cmd 并切换渲染;sid 可用于需要与宿主进行会话关联的场景。