React 控制台与 OBS 前端
Vite 在 Docker build stage 编译本目录,最终静态文件由 Rust 同域托管。生产容器不包含 Node。
路由
| 路由 | 权限 | 作用 |
|---|---|---|
/control/ |
登录用户 | 组件实例、测试、设置和 OBS token |
/control/invitations |
system admin | 创建/撤销绑定房间的邀请码 |
/control/components/:id/song-requests |
登录用户 | 点歌队列、统计与管理操作 |
/control/login |
匿名 | 用户名 + TOTP/恢复码登录 |
/control/register |
匿名受邀用户 | 邀请码注册与 TOTP enrollment |
/control/setup |
首次部署 | 创建唯一 system admin |
/obs/:publicId |
component token | 透明 OBS 浏览器源 |
main.tsx
在初始化控制台前先识别 OBS 路由,因此 OBS 不会注册 PWA 或请求账户 session。控制台允许同一组件类型创建多个命名实例;列表必须显示实例名称而不是只显示类型,以便不同 OBS 场景的样式和地址可被区分。
文件职责
| 文件 | 职责 |
|---|---|
src/api.ts |
same-origin fetch、错误模型和兼容性 normalizer |
src/auth.tsx |
passwordless login、TOTP QR 与恢复码 |
src/control.tsx |
tenant component studio 和 system-admin 邀请码页面 |
src/stream.ts |
通用组件 WebSocket 鉴权、重连和 renderer 分流 |
src/overlay.tsx |
弹幕、礼物/表情和 OBS 自适应渲染 |
src/songOverlay.tsx |
点歌快照 reducer、revision 校验与往返滚动 |
src/giftEffect.tsx |
礼物流星与视口自适应渲染 |
src/giftThemes.ts |
可扩展礼物特效主题注册表与 CSS 变量 |
src/guardEffect.tsx |
独立大航海视频、感谢卷轴与月夜庆祝渲染 |
src/guardThemes.ts |
可扩展大航海特效主题注册表与 CSS 变量 |
src/giftMenu.tsx |
礼物菜单无限循环、触发定位与高亮 reducer |
src/giftMenuThemes.ts |
可扩展礼物菜单主题注册表 |
src/pwa.tsx |
install prompt、离线状态、显式更新和敏感状态 blocker |
src/i18n.tsx |
TOML 语言资源、浏览器回退和运行时切换 |
src/types.ts |
sanitized API view model 与 overlay settings |
pwa/control-sw.js |
/control/ 静态壳层的缓存策略 |
Secret 与状态
- TOTP Secret、恢复码、邀请码和新 OBS 地址只保存在当前 React state。
- API normalizer 不把未知对象直接传播到组件。
- API mutation 离线时立即失败,不进入 Background Sync。
- PWA 更新在 dirty form 或一次性 secret 可见时被阻止。
- OBS token 从 URL fragment 读取,只在 WebSocket 第一帧发送。
- OBS 收到坏 JSON、坏图片或未知事件时局部降级,不让浏览器源崩溃。
PWA
manifest、start URL 与 Service Worker scope 均为 /control/。worker 使用 network-first
HTML 和 cache-first build assets;/api/*、/obs/*、WebSocket 和用户数据永不缓存。每次 Vite
build 把同一个 build ID 注入浏览器 bundle 与 worker,发现更新后等待用户确认激活。
语言资源
../../resources/i18n.toml 是控制台、OBS 组件、API 错误和 PWA
metadata 的唯一文案来源。Vite 在构建时解析并注入它,Rust 则嵌入同一文件来验证允许保存的 locale。增加文案键时必须为每个 locale 提供值;增加语言时同时增加完整
[locales."<code>".messages] 段。业务命令如“点歌”是 Bilibili 输入协议,不属于 UI 翻译。
字体资源
Noto Serif SC、ZCOOL XiaoWei 与 LXGW
WenKai 由锁定的 Fontsource 依赖提供;漓雨手书与鸿雷行书简体则以固定 WOFF2 文件保存在
public/fonts/。浏览器从 Rust 静态服务同域加载这些字体,不依赖 OBS 设备的系统字体。前三套 Fontsource 字体与漓雨手书的 OFL-1.1 许可证输出到
/fonts/licenses/;鸿雷行书的随附说明不构成开放授权,公开或商业部署前必须确认 Web 嵌入与再分发权利,具体摘要见
public/fonts/NOTICE.md。
格式化与构建
npm run format
npm run format:check
npm run docs:check
npm run build
npm run format
使用仓库根目录的 Prettier 配置,同时格式化 TypeScript、TSX、CSS、HTML、JSON、Markdown、Compose
YAML 和项目文档。
组件协议与弹幕姬行为分别见: