feat: webapp multi-tab JS bridge and multi-WebView management
This commit is contained in:
@@ -5,7 +5,9 @@ import top.yeij.hearth.app.AppRepository
|
||||
import top.yeij.hearth.card.Card
|
||||
import top.yeij.hearth.card.CardRepository
|
||||
import top.yeij.hearth.media.MediaSessionSource
|
||||
import top.yeij.hearth.webapp.Tab
|
||||
import top.yeij.hearth.webapp.WebApp
|
||||
import top.yeij.hearth.webapp.WebAppContainer
|
||||
import top.yeij.hearth.webapp.WebAppRepository
|
||||
|
||||
class JsBridge(
|
||||
@@ -16,6 +18,8 @@ class JsBridge(
|
||||
private val appRepository: AppRepository? = null,
|
||||
private val webAppRepository: WebAppRepository? = null,
|
||||
private val cardRepository: CardRepository? = null,
|
||||
private val webAppContainer: WebAppContainer? = null,
|
||||
private val webAppHost: WebAppHost? = null,
|
||||
) {
|
||||
private val gson = com.google.gson.Gson()
|
||||
|
||||
@@ -47,6 +51,94 @@ class JsBridge(
|
||||
@android.webkit.JavascriptInterface
|
||||
fun fetchWebApps(): String = gson.toJson(webAppRepository?.fetchManifest() ?: emptyList<WebApp>())
|
||||
|
||||
// 打开指定 id 的 webAPP:从清单找 url/name → 创建内容 WebView → 记录标签 → 同步顶栏
|
||||
// Open a web app by id: look up url/name from the manifest -> create content WebView
|
||||
// -> record the tab -> sync the topbar
|
||||
@android.webkit.JavascriptInterface
|
||||
fun openWebApp(id: String) {
|
||||
val repo = webAppRepository ?: return
|
||||
val container = webAppContainer ?: return
|
||||
val host = webAppHost ?: return
|
||||
val app = repo.fetchManifest().firstOrNull { it.id == id }
|
||||
if (app == null) {
|
||||
Log.d("HearthBridge", "openWebApp: unknown id=$id")
|
||||
return
|
||||
}
|
||||
host.openWebView(id, app.url)
|
||||
container.open(id, app.url, app.name)
|
||||
syncTabs()
|
||||
Log.d("HearthBridge", "openWebApp: id=$id name=${app.name} url=${app.url}")
|
||||
}
|
||||
|
||||
// 关闭指定 id 的标签:销毁 WebView → 移除标签 → 若剩标签激活第一个 → 同步顶栏
|
||||
// Close a tab by id: destroy WebView -> remove tab -> activate first if any remain
|
||||
// -> sync the topbar
|
||||
@android.webkit.JavascriptInterface
|
||||
fun closeWebApp(id: String) {
|
||||
val container = webAppContainer ?: return
|
||||
val host = webAppHost ?: return
|
||||
host.closeWebView(id)
|
||||
container.close(id)
|
||||
container.activeTabId()?.let { host.switchWebView(it) }
|
||||
syncTabs()
|
||||
Log.d("HearthBridge", "closeWebApp: id=$id remaining=${container.tabs().size}")
|
||||
}
|
||||
|
||||
// 切换激活标签并显示对应 WebView
|
||||
// Switch the active tab and show its WebView
|
||||
@android.webkit.JavascriptInterface
|
||||
fun switchTab(id: String) {
|
||||
val container = webAppContainer ?: return
|
||||
val host = webAppHost ?: return
|
||||
container.switchTo(id)
|
||||
host.switchWebView(id)
|
||||
syncTabs()
|
||||
Log.d("HearthBridge", "switchTab: id=$id")
|
||||
}
|
||||
|
||||
// 返回已打开标签列表 JSON(id/name/active)
|
||||
// Return the open tab list JSON (id/name/active)
|
||||
@android.webkit.JavascriptInterface
|
||||
fun listTabs(): String {
|
||||
val container = webAppContainer ?: return "[]"
|
||||
val tabs = container.tabs().map { tab ->
|
||||
mapOf("id" to tab.id, "name" to tab.name, "active" to tab.active)
|
||||
}
|
||||
return gson.toJson(tabs)
|
||||
}
|
||||
|
||||
// 当前激活标签回退
|
||||
// Go back on the active tab
|
||||
@android.webkit.JavascriptInterface
|
||||
fun webGoBack() {
|
||||
webAppHost?.goBack()
|
||||
Log.d("HearthBridge", "webGoBack called")
|
||||
}
|
||||
|
||||
// 当前激活标签前进
|
||||
// Go forward on the active tab
|
||||
@android.webkit.JavascriptInterface
|
||||
fun webGoForward() {
|
||||
webAppHost?.goForward()
|
||||
Log.d("HearthBridge", "webGoForward called")
|
||||
}
|
||||
|
||||
// 当前激活标签重载
|
||||
// Reload the active tab
|
||||
@android.webkit.JavascriptInterface
|
||||
fun webReload() {
|
||||
webAppHost?.reload()
|
||||
Log.d("HearthBridge", "webReload called")
|
||||
}
|
||||
|
||||
// 将容器标签状态推送给宿主(同步桌面 H5 顶栏)
|
||||
// Push the container tab state to the host (sync the desktop H5 topbar)
|
||||
private fun syncTabs() {
|
||||
val container = webAppContainer ?: return
|
||||
val host = webAppHost ?: return
|
||||
host.syncTabs(container.tabs())
|
||||
}
|
||||
|
||||
// 返回首页卡片目录 JSON(无仓库时返回空数组;有仓库时由 fetchCatalog 保证内置 time 卡)
|
||||
// Return the home card catalog JSON (empty array when no repository wired;
|
||||
// fetchCatalog guarantees the builtin time card when wired)
|
||||
|
||||
Reference in New Issue
Block a user