Appearance
detail
为详情页提供数据。detail 不是用户可添加的入口,也不会显示在 Dashboard 中。
widget / search 不实现此 protocol,仅提供 ref。App 会根据解析规则查找并调用相应的 detail 扩展。
字段
| 字段 | 必填 | 含义 |
|---|---|---|
type | 是 | "detail" |
id / title | 是 | 服务选择器里的名称 |
accepts | 是 | { sources, mediaTypes? } |
cache | 否 | 默认 ttlSeconds: 60 |
load | 是 | protocol 方法 |
Protocol
ts
load(ctx, input) => Promise<DetailItem | null>
input: {
ref: MediaRef;
instanceId?: string;
params?: Record<string, unknown>;
}返回 null 表示对应条目不存在。对于 tmdb / imdb / douban,App 可能直接使用内置详情,而不调用此扩展。对于 url / custom,返回 null 表示没有可用详情。
从 widget 实例进入时,App 会传入该实例的 instanceId 和 params,例如 host。服务器配置应从 input.params 读取,而不是从 ctx.settings 查找。instanceId 位于输入对象顶层,不应写入 params。服务型扩展不提供独立的配置页。
和 widget 的关系
| 做法 | 行不行 |
|---|---|
同一包导出 widget 和 detail,且 detail.accepts.sources 覆盖 widget 生成的 source | 推荐。点击后会优先匹配同源包 |
仅导出 widget,且所有条目均使用 tmdb | 可以。详情由 App 内置服务提供 |
仅导出 widget,条目使用 url,且未提供 detail | 不支持。点击卡片后无法打开详情页 |
在 widget.load 中同时返回完整的 DetailItem | 不支持。Dashboard 模板不会使用这些数据,搜索及其他入口也无法复用 |
在 widget protocol 中增加 loadDetail(link) | 不支持。搜索结果和跨包条目无法复用该实现 |
详情页中的播放按钮不调用 detail 扩展,而是调用 playback。detail 扩展可以返回 episodes,供用户在详情页选择季和集;选择完成后,App 使用 ref 和 episode 解析 playback。