fix: per-app scale via CSS zoom, hide download icon when local version matches

This commit is contained in:
2026-08-17 21:40:06 +08:00
parent 0194a57734
commit 06377f067f
3 changed files with 37 additions and 20 deletions
+17 -8
View File
@@ -29,13 +29,16 @@ window.loadWebAppList = async function () {
tag.className = 'tag'; tag.className = 'tag';
tag.textContent = a.offline ? '离线' : '在线'; tag.textContent = a.offline ? '离线' : '在线';
btn.append(img, lbl, tag); btn.append(img, lbl, tag);
// 云端有离线包 → 加下载图标(点击自动拉取安装 // 云端有离线包 → 加下载图标(默认隐藏,异步按本地状态决定是否显示
// Cloud has an offline package -> add a download icon (tap to auto-install) // Cloud has an offline package -> add a download icon (hidden by default,
// shown based on local state asynchronously)
let dl = null;
if (a.offline) { if (a.offline) {
const dl = document.createElement('span'); dl = document.createElement('span');
dl.className = 'wcell-dl'; dl.className = 'wcell-dl';
dl.title = '下载离线包'; dl.title = '下载离线包';
dl.innerHTML = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3v12"/><path d="M7 10l5 5 5-5"/><path d="M5 21h14"/></svg>'; dl.innerHTML = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3v12"/><path d="M7 10l5 5 5-5"/><path d="M5 21h14"/></svg>';
dl.style.display = 'none';
dl.onclick = (e) => { dl.onclick = (e) => {
e.stopPropagation(); e.stopPropagation();
bridge.call('updateOfflinePackage', a.id).then(() => refreshList()).catch(() => {}); bridge.call('updateOfflinePackage', a.id).then(() => refreshList()).catch(() => {});
@@ -46,7 +49,7 @@ window.loadWebAppList = async function () {
setupLongPress(btn, a); setupLongPress(btn, a);
grid.appendChild(btn); grid.appendChild(btn);
// 异步检查本地离线包状态 + 版本对比,更新标签 // 异步检查本地离线包状态 + 版本对比,更新标签
refreshBadge(tag, a); refreshBadge(tag, a, dl);
}); });
}; };
render(apps); render(apps);
@@ -56,14 +59,19 @@ window.loadWebAppList = async function () {
}; };
}; };
// 异步刷新列表项标签(离线 / 可更新) // 异步刷新列表项标签(离线 / 可更新)+ 下载图标显隐
// Refresh the badge asynchronously (offline / updatable) // Refresh the badge asynchronously (offline / updatable) + download icon visibility
async function refreshBadge(tag, app) { async function refreshBadge(tag, app, dl) {
try { try {
const hasLocal = await bridge.call('hasLocalPackage', app.id); const hasLocal = await bridge.call('hasLocalPackage', app.id);
const localVer = await bridge.call('getLocalVersion', app.id); const localVer = await bridge.call('getLocalVersion', app.id);
const cloudVer = app.offlineVersion || ''; const cloudVer = app.offlineVersion || '';
if (hasLocal && cloudVer && cloudVer !== localVer) { const updatable = hasLocal && cloudVer && cloudVer !== localVer;
// 下载图标仅在「未安装且有离线包」或「有可更新版本」时显示
// Download icon shows only when there's no local package but cloud has one,
// or when a newer version is available
const needDownload = app.offline && (!hasLocal || updatable);
if (updatable) {
tag.textContent = '可更新'; tag.textContent = '可更新';
} else if (hasLocal) { } else if (hasLocal) {
tag.textContent = '离线'; tag.textContent = '离线';
@@ -72,6 +80,7 @@ async function refreshBadge(tag, app) {
} else { } else {
tag.textContent = '在线'; tag.textContent = '在线';
} }
if (dl) dl.style.display = needDownload ? '' : 'none';
} catch (e) { /* 忽略 */ } } catch (e) { /* 忽略 */ }
} }
@@ -278,6 +278,22 @@ class MainActivity : Activity() {
} }
val webView = WebViewManager(this@MainActivity).createContentWebView(ua, scale) val webView = WebViewManager(this@MainActivity).createContentWebView(ua, scale)
webView.webViewClient = object : WebViewClient() { webView.webViewClient = object : WebViewClient() {
override fun onPageFinished(view: WebView?, url: String?) {
Log.d(TAG, "content onPageFinished: url=$url scale=$scale")
// 缩放:网易云 PC 版不响应 viewport meta 的 initial-scale
// 改用 CSS zoom(会 reflow,内容填满不留白),对任何页面可靠生效
// Zoom: desktop pages (e.g. NetEase Music) ignore viewport-meta
// initial-scale, so use CSS zoom (reflows, no blank space), which
// works reliably on any page
if (scale != null && scale in 1..100) {
val zoom = scale / 100f
view?.evaluateJavascript(
"(function(){var z='$zoom';var s=document.createElement('style');s.innerHTML='html{zoom:'+z+'}';document.head.appendChild(s);})();",
null
)
}
}
@Suppress("DEPRECATION", "OVERRIDE_DEPRECATION") @Suppress("DEPRECATION", "OVERRIDE_DEPRECATION")
override fun onReceivedError( override fun onReceivedError(
view: WebView?, view: WebView?,
@@ -43,18 +43,10 @@ class WebViewManager(private val activity: Activity) {
ua == "desktop" || ua == "pc" -> UA_DESKTOP ua == "desktop" || ua == "pc" -> UA_DESKTOP
else -> ua else -> ua
} }
// 缩放(1-100):View 级别 scaleX/scaleY,不依赖页面渲染或 viewport,对任何页面可靠生效。 // scale 由 WebAppHost 在 onPageFinished 里通过 CSS zoom 实现(reflow 缩放),
// 缩放后内容相对左上角缩小;触摸坐标由 View 自动映射 // 此处不再做 View 级别缩放
// Zoom (1-100): view-level scaleX/scaleY, independent of page rendering or // scale is applied by WebAppHost via CSS zoom in onPageFinished (reflow
// viewport, so it reliably works for any page. Content shrinks toward the // scaling); no view-level scaling here
// top-left; touch coordinates are auto-mapped by the View
if (scale != null && scale in 1..100) {
val s = scale / 100f
webView.scaleX = s
webView.scaleY = s
webView.pivotX = 0f
webView.pivotY = 0f
}
return webView return webView
} }