diff --git a/app/src/main/assets/h5/js/pages/settings.js b/app/src/main/assets/h5/js/pages/settings.js index 615ecca..6302c29 100644 --- a/app/src/main/assets/h5/js/pages/settings.js +++ b/app/src/main/assets/h5/js/pages/settings.js @@ -234,9 +234,13 @@ function setupCheckUpdate(page) { item.onclick = () => { state.textContent = '检查中…'; bridge.call('refreshManifest').then(result => { - let n = 0; - try { n = JSON.parse(result).count || 0; } catch (e) {} - state.textContent = n > 0 ? '已更新 ' + n + ' 个 ›' : '无更新 ›'; + let r = { added: 0, removed: 0, changed: 0 }; + try { r = JSON.parse(result); } catch (e) {} + const parts = []; + if (r.added > 0) parts.push('新增 ' + r.added); + if (r.removed > 0) parts.push('移除 ' + r.removed); + if (r.changed > 0) parts.push('更新 ' + r.changed); + state.textContent = parts.length ? parts.join(',') + ' ›' : '无更新 ›'; }).catch(() => { state.textContent = '失败 ›'; }); diff --git a/app/src/main/assets/h5/js/pages/webapplist.js b/app/src/main/assets/h5/js/pages/webapplist.js index f4f8760..4011434 100644 --- a/app/src/main/assets/h5/js/pages/webapplist.js +++ b/app/src/main/assets/h5/js/pages/webapplist.js @@ -163,3 +163,14 @@ window.HearthEvents.webappImported = function (id, ok) { if (!ok) return; refreshList(); }; + +// 检查更新后刷新列表:清 preload 缓存并重渲染 +// Refresh the list after check-update: clear the preload cache and re-render +window.HearthEvents.webappUpdated = function () { + if (window.preload) window.preload.webApps = null; + const page = document.querySelector('[data-page="webapplist"]'); + if (page) { + page.dataset.loaded = ''; + if (page.classList.contains('active')) window.loadWebAppList(); + } +}; diff --git a/app/src/main/java/top/yeij/hearth/webview/JsBridge.kt b/app/src/main/java/top/yeij/hearth/webview/JsBridge.kt index 850bdf2..caa7c57 100644 --- a/app/src/main/java/top/yeij/hearth/webview/JsBridge.kt +++ b/app/src/main/java/top/yeij/hearth/webview/JsBridge.kt @@ -419,16 +419,38 @@ class JsBridge( @android.webkit.JavascriptInterface fun getWallpaper(): String = wallpaper?.getWallpaperBase64() ?: "" - // 重新拉取 webAPP 清单 + 卡片目录,返回 { count } - // Re-fetch the webAPP manifest + card catalog, return { count } + // 重新拉取 webAPP 清单 + 卡片目录,返回 { added, removed, changed } + // Re-fetch the webAPP manifest + card catalog, return { added, removed, changed } @android.webkit.JavascriptInterface fun refreshManifest(): String { + val oldApps = manifestCache ?: emptyList() manifestCache = null val apps = webAppRepository?.fetchManifest() ?: emptyList() if (apps.isNotEmpty()) manifestCache = apps - val cards = cardRepository?.fetchCatalog() ?: emptyList() - Log.d("HearthBridge", "refreshManifest: ${apps.size} apps, ${cards.size} cards") - return gson.toJson(mapOf("count" to apps.size)) + cardRepository?.fetchCatalog() + + // 增量计算:新增 / 移除 / 更新(离线包版本或 URL/图标变化) + // Diff: added / removed / changed (offline version or URL/icon changed) + val oldIds = oldApps.map { it.id }.toSet() + val newIds = apps.map { it.id }.toSet() + val added = (newIds - oldIds).size + val removed = (oldIds - newIds).size + val changed = apps.count { new -> + val old = oldApps.find { it.id == new.id } + old != null && (old.offlineVersion != new.offlineVersion || + old.url != new.url || old.icon != new.icon) + } + Log.d("HearthBridge", "refreshManifest: added=$added removed=$removed changed=$changed (${apps.size} apps)") + + // 推送 H5 刷新列表(清 preload 缓存并重渲染) + // Push H5 to refresh the list (clear preload cache and re-render) + desktopWebViewRef?.post { + desktopWebViewRef?.evaluateJavascript( + "window.HearthEvents && window.HearthEvents.webappUpdated();", + null + ) + } + return gson.toJson(mapOf("added" to added, "removed" to removed, "changed" to changed)) } // 注册媒体会话监听,回调推送给 H5(info 为 null 时推 "null")