diff --git a/docs/superpowers/specs/2026-08-16-hearth-launcher-design.md b/docs/superpowers/specs/2026-08-16-hearth-launcher-design.md index aa310da..0e02f39 100644 --- a/docs/superpowers/specs/2026-08-16-hearth-launcher-design.md +++ b/docs/superpowers/specs/2026-08-16-hearth-launcher-design.md @@ -48,6 +48,7 @@ Hearth 是一个面向瑞芯微 RK3566 横屏开发板(立创·泰山派)的 │ │ 能力层(原生 Kotlin) │ │ │ │ ├─ AppRepository 查应用列表/图标/启动 │ │ │ │ ├─ WebAppRepository 拉 webAPP 清单/离线包 │ │ +│ │ ├─ WebAppContainer 多 WebView 管理(标签/导航) │ │ │ │ ├─ CardRepository 卡片清单拉取/缓存 │ │ │ │ ├─ MediaSessionSource 媒体状态监听 │ │ │ │ ├─ CacheManager 文件缓存(清单/离线包/图标) │ │ @@ -73,6 +74,7 @@ Hearth 是一个面向瑞芯微 RK3566 横屏开发板(立创·泰山派)的 | `JsBridge` | 所有 `@JavascriptInterface` 方法,H5 唯一入口 | 各 Repository/Source | | `AppRepository` | PackageManager 封装:应用列表、base64 图标、启动应用 | 无 | | `WebAppRepository` | 拉取 webAPP 清单、下载离线包、解析 | CacheManager | +| `WebAppContainer` | 多 WebView 管理:标签页打开/切换/关闭、前进后退、重载 | 无 | | `CardRepository` | 拉取卡片目录、下载卡片资源 | CacheManager | | `MediaSessionSource` | 监听活跃媒体会话,推送媒体元数据 | 无 | | `CacheManager` | 文件读写缓存(清单/离线包/卡片/图标) | 无 | @@ -83,7 +85,7 @@ Hearth 是一个面向瑞芯微 RK3566 横屏开发板(立创·泰山派)的 2. **渲染 APP 列表**:H5 调 `listApps()` → 原生查 PackageManager → 回调 JSON(含 base64 图标)→ H5 渲染网格。 3. **渲染 webAPP 列表**:H5 调 `fetchWebApps()` → 原生拉服务器清单 → 缓存 → 回调 → H5 渲染富卡片。 4. **启动 APP**:点击 → H5 调 `launchApp(pkg)` → 原生 `startActivity`。 -5. **打开 webAPP**:点击 → H5 调 `openUrl(url)` → WebView 加载;返回桌面 = 重新 load 本地 index.html。 +5. **打开 webAPP**:点击 → H5 调 `openWebApp(id)` → 原生新建内容 WebView(标签页)加载 URL,桌面 H5 顶部渲染浏览器式顶栏;回退/前进/重载/标签切换均经 JS Bridge 控制。 6. **首页卡片**:H5 调 `fetchCards()` → 原生拉卡片目录 → 下载卡片 HTML + 数据 → H5 渲染三栏卡片流。 7. **媒体卡**:原生 MediaSessionSource 监听媒体变化 → 事件推给 H5 → H5 显示/隐藏媒体卡。 @@ -98,8 +100,14 @@ H5 通过 `window.HearthBridge` 访问原生能力。所有方法异步回调( | `listApps()` | 无 | AppInfo[] | 已装应用列表(包名/名称/base64 图标) | | `launchApp(pkg)` | 包名 | void | 启动第三方应用 | | `fetchWebApps()` | 无 | WebApp[] | 拉取/返回 webAPP 清单(含缓存逻辑) | -| `openUrl(url)` | URL | void | WebView 加载 URL | -| `backToHome()` | 无 | void | 重新加载本地 index.html | +| `openWebApp(id)` | webAPP id | void | 打开 webAPP(新建内容 WebView 标签页 + 显示顶栏) | +| `closeWebApp(id)` | webAPP id | void | 关闭指定标签页 | +| `switchTab(id)` | 标签 id | void | 切换可见标签页 | +| `listTabs()` | 无 | Tab[] | 返回已打开标签列表 | +| `webGoBack()` | 无 | void | 当前标签回退 | +| `webGoForward()` | 无 | void | 当前标签前进 | +| `webReload()` | 无 | void | 当前标签重载 | +| `backToHome()` | 无 | void | 关闭全部标签,回到桌面 | | `fetchCards()` | 无 | Card[] | 拉取/返回卡片目录 | | `getDeviceInfo()` | 无 | DeviceInfo | 分辨率、density、深色模式等 | | `launchInBounds(pkg, x,y,w,h)` | 二期 | void | freeform 启动到指定区域 | @@ -206,6 +214,13 @@ cards// 3. 本地缓存失败降级:**有旧清单用旧清单,无清单显示空态 + 错误提示**。 4. webAPP 打开时:有离线包且离线 → 加载本地解压目录;否则加载远程 URL。 +### 6.3 webAPP 打开行为(浏览器式顶栏 + 多标签) + +- 打开 webAPP → 原生新建内容 WebView(标签页)加载,桌面 H5 顶部渲染浏览器式顶栏。 +- 顶栏:回退 / 前进 / 重载(作用于当前标签);右侧标签页入口,可切换 / 关闭已打开标签。 +- 每个标签页 = 一个独立 WebView,拥有独立前进后退历史。 +- 关闭全部标签 = 回到桌面。 + ## 7. UI 设计 ### 7.1 视觉规范(Miuix / HyperOS 风格,CSS 还原) @@ -231,17 +246,25 @@ cards// - 收起:80px,纯图标(无文字)。 - 展开:240px,图标 + 文字横排,选中项后橙色高亮药丸。 - 左上角按钮切换收起/展开。 +- **非首页时**:侧边栏最顶部(Header 区域)显示一个小时间;首页时不显示。 ### 7.4 夜间模式 - H5 用 CSS 变量 + `prefers-color-scheme` 跟随系统。 - 原生保证 WebView 跟随 `Configuration.uiMode`,无需额外处理。 +### 7.5 webAPP 顶栏 + +- 左侧:回退、前进、重载三个图标按钮。 +- 右侧:标签页入口按钮(点击展开标签列表,可切换 / 关闭)。 +- 顶栏随 webAPP 打开而显示,关闭全部标签后隐藏。 + ## 8. 窗口管理 - **全屏沉浸式**:`WindowInsetsController.hide(statusBars() | navigationBars())`,行为 `BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE`(系统默认:下滑一次展开、几秒自动收起)。 - **横屏锁定**:`screenOrientation = landscape`。 - **默认桌面**:Manifest 声明 `HOME` + `DEFAULT` intent-filter,用户手动设为默认。 +- **Back 键屏蔽**:桌面状态下拦截 Back 键(按返回无响应);webAPP 打开时 Back 先作用于标签页回退,无历史可回退则关闭标签。 ## 9. 权限模型 @@ -291,7 +314,7 @@ cards// ## 14. 明确不做(YAGNI) -- kiosk 防退出 / 屏蔽物理按键 +- 完整 kiosk 锁定(Home / 最近任务 / 系统手势全锁,仅 Back 键已做) - 屏幕常亮管理 - 多用户 / Widget 宿主 - 应用图标拖拽 / 文件夹 / Dock