feat: webapp container tab state management

This commit is contained in:
2026-08-16 16:30:45 +08:00
parent ce55905e59
commit f8639917f3
2 changed files with 115 additions and 0 deletions
@@ -0,0 +1,54 @@
package top.yeij.hearth.webapp
// 单个 WebView 标签:id 唯一标识,active 表示是否为当前激活标签
// Single WebView tab: id is the unique key, active marks the currently-focused tab
data class Tab(val id: String, val url: String, val active: Boolean = false)
// 多标签状态管理(纯 Kotlin 数据层,不依赖 WebView,可 JVM 单测)
// 真实 WebView 导航(goBack/goForward/reload)留待 Task 13 集成时接入
// Multi-tab state management (pure Kotlin data layer, WebView-free, JVM-testable)
// Real WebView navigation (goBack/goForward/reload) is wired up in Task 13
class WebAppContainer {
private val tabs = mutableListOf<Tab>()
// 打开标签:已存在则激活它(不重复添加),否则新增并激活
// Open a tab: if it already exists just activate it, otherwise add and activate
fun open(id: String, url: String) {
val existing = tabs.find { it.id == id }
if (existing != null) {
setActive(id)
return
}
for (i in tabs.indices) tabs[i] = tabs[i].copy(active = false)
tabs.add(Tab(id, url, active = true))
}
// 关闭标签:若关闭后没有激活标签则激活第一个
// Close a tab: if none remain active, activate the first one
fun close(id: String) {
tabs.removeAll { it.id == id }
if (tabs.isNotEmpty() && tabs.none { it.active }) {
tabs[0] = tabs[0].copy(active = true)
}
}
// 切换激活标签
// Switch the active tab
fun switchTo(id: String) {
setActive(id)
}
// 返回标签列表副本(外部无法直接改动内部状态)
// Return a defensive copy of the tab list
fun tabs(): List<Tab> = tabs.toList()
private fun setActive(id: String) {
for (i in tabs.indices) tabs[i] = tabs[i].copy(active = tabs[i].id == id)
}
// 真实回退由 WebView 层实现,数据层仅占位返回 false
// Real back navigation lives in the WebView layer; data layer is a stub
fun goBack(): Boolean = false
fun goForward(): Boolean = false
fun reload() {}
}