@co0ontty/wand 1.25.1 → 1.25.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1076,6 +1076,49 @@
|
|
|
1076
1076
|
scheduleForegroundSync("android-resume", { immediate: true });
|
|
1077
1077
|
ensureTerminalFitWithRetry("android-resume");
|
|
1078
1078
|
});
|
|
1079
|
+
|
|
1080
|
+
// Bridge from Android IME animation. State values: "start" / "shown" / "hidden".
|
|
1081
|
+
// 原生层用 setPadding 在 WebView 父容器上 resize WebView, 视觉上键盘
|
|
1082
|
+
// 动画跟系统同步, 但带来一个副作用: window.innerHeight === visualViewport.height,
|
|
1083
|
+
// 导致 setupVisualViewportHandlers 里的 isKeyboardOpen 检测 (基于
|
|
1084
|
+
// offsetBottom) 永远是 false, 不会进 keyboard-open / keyboard-close 分支,
|
|
1085
|
+
// 终端 forceReplay 路径也就不跑了。
|
|
1086
|
+
//
|
|
1087
|
+
// 这里直接听原生层的"键盘动画收尾"事件, 触发 ensureTerminalFit
|
|
1088
|
+
// (forceReplay=true), 把 wterm 的网格按真实视口重排一遍。
|
|
1089
|
+
window.addEventListener("wand-ime-state", function(e) {
|
|
1090
|
+
var which = e && e.detail && e.detail.state;
|
|
1091
|
+
if (which === "shown" || which === "hidden") {
|
|
1092
|
+
try {
|
|
1093
|
+
ensureTerminalFit("native-ime-" + which, { forceReplay: true });
|
|
1094
|
+
maybeScrollTerminalToBottom("native-ime");
|
|
1095
|
+
} catch (_e) {}
|
|
1096
|
+
}
|
|
1097
|
+
});
|
|
1098
|
+
|
|
1099
|
+
// Bridge from Android ConnectivityManager.NetworkCallback. State values:
|
|
1100
|
+
// "available" — 默认网络刚刚可用 (启动期没网 → 接上)
|
|
1101
|
+
// "changed" — 已有网络切到另一个 (Wi-Fi ↔ 4G), socket 必死
|
|
1102
|
+
// "validated" — captive portal / VPN 验证完成, internet 才真正通
|
|
1103
|
+
// "lost" — 默认网络断了, 还没有备援网络
|
|
1104
|
+
// 前三种都强制重连; "lost" 不动 socket, 只更新 isOnline 让 UI 提示。
|
|
1105
|
+
// 这条路径比 navigator.online / visibilitychange 早 2-8 秒触发,
|
|
1106
|
+
// 切网后用户基本看不到断线提示。
|
|
1107
|
+
window.addEventListener("wand-android-network", function(e) {
|
|
1108
|
+
var which = e && e.detail && e.detail.state;
|
|
1109
|
+
if (which === "lost") {
|
|
1110
|
+
state.isOnline = false;
|
|
1111
|
+
try { updateOfflineBanner(); } catch (_e) {}
|
|
1112
|
+
return;
|
|
1113
|
+
}
|
|
1114
|
+
if (which === "available" || which === "changed" || which === "validated") {
|
|
1115
|
+
// 以原生信号为权威, 立刻翻 isOnline 给 UI; 有些 ROM 上
|
|
1116
|
+
// navigator.onLine 要等几秒才更新, 否则 banner 会闪一下。
|
|
1117
|
+
state.isOnline = true;
|
|
1118
|
+
try { updateOfflineBanner(); } catch (_e) {}
|
|
1119
|
+
forceReconnectWebSocket("android-network-" + which);
|
|
1120
|
+
}
|
|
1121
|
+
});
|
|
1079
1122
|
}
|
|
1080
1123
|
|
|
1081
1124
|
function restoreLoginSession() {
|
|
@@ -12868,20 +12911,31 @@
|
|
|
12868
12911
|
// 这里在 visualViewport 检测到键盘收起的瞬间直接强制复位一次,
|
|
12869
12912
|
// 并把 --app-viewport-height 兜底清掉,确保 .app-container 回到
|
|
12870
12913
|
// 100dvh、input-panel 重新贴屏幕底部。
|
|
12914
|
+
//
|
|
12915
|
+
// Android APK (window.__wandImeNative=true) 跳过这段 iOS hack —
|
|
12916
|
+
// MainActivity 已经在 IME 动画 callback 里逐帧把 root setPadding,
|
|
12917
|
+
// WebView 直接被原生层 resize 推回到了正确位置, 这里再调
|
|
12918
|
+
// scrollTo(0,0) 反而会跟原生 padding 打架, 偶尔产生一帧抖。
|
|
12919
|
+
// 只保留 refit / 滚底两个纯展示动作。
|
|
12871
12920
|
var rootEl = document.documentElement;
|
|
12872
|
-
|
|
12873
|
-
|
|
12874
|
-
|
|
12875
|
-
rootEl.scrollTop = 0;
|
|
12876
|
-
if (document.body) document.body.scrollTop = 0;
|
|
12877
|
-
setTimeout(function() {
|
|
12878
|
-
// 二次复位:等键盘收起动画 + iOS 自身的回滚跑完后再清一次,
|
|
12879
|
-
// 防止 iOS 在动画过程中又把 scrollTop 推上去。
|
|
12921
|
+
var imeIsNative = !!window.__wandImeNative;
|
|
12922
|
+
if (!imeIsNative) {
|
|
12923
|
+
rootEl.style.removeProperty('--app-viewport-height');
|
|
12880
12924
|
window.scrollTo(0, 0);
|
|
12881
12925
|
if (document.scrollingElement) document.scrollingElement.scrollTop = 0;
|
|
12882
12926
|
rootEl.scrollTop = 0;
|
|
12883
12927
|
if (document.body) document.body.scrollTop = 0;
|
|
12884
|
-
|
|
12928
|
+
}
|
|
12929
|
+
setTimeout(function() {
|
|
12930
|
+
if (!imeIsNative) {
|
|
12931
|
+
// 二次复位:等键盘收起动画 + iOS 自身的回滚跑完后再清一次,
|
|
12932
|
+
// 防止 iOS 在动画过程中又把 scrollTop 推上去。
|
|
12933
|
+
window.scrollTo(0, 0);
|
|
12934
|
+
if (document.scrollingElement) document.scrollingElement.scrollTop = 0;
|
|
12935
|
+
rootEl.scrollTop = 0;
|
|
12936
|
+
if (document.body) document.body.scrollTop = 0;
|
|
12937
|
+
syncAppViewportHeight();
|
|
12938
|
+
}
|
|
12885
12939
|
ensureTerminalFit("keyboard-close", { forceReplay: true });
|
|
12886
12940
|
maybeScrollTerminalToBottom("force");
|
|
12887
12941
|
}, 200);
|
|
@@ -151,14 +151,26 @@
|
|
|
151
151
|
Android 自 targetSdk=35 起强制边到边, WebView 内容会绘制到状态栏底下,
|
|
152
152
|
但 Android WebView 不会主动把 WindowInsets 暴露给 env(safe-area-inset-*),
|
|
153
153
|
所以纯 env() 在绝大多数 Android 机器上回落到 0 -> 顶部直接撞到状态栏。
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
154
|
+
这里给旧版 Wand APK 兜一个 32px 最小值, 确保它们的顶部抽屉/模态不撞
|
|
155
|
+
状态栏。新版 APK 已经在原生层 setPadding 把 WebView 整体往里缩 (见
|
|
156
|
+
MainActivity.installWindowInsetsBridge) 并注入 .is-wand-app-native-insets
|
|
157
|
+
类来关掉这个兜底, 否则会双重 inset 浪费空间。*/
|
|
157
158
|
.is-wand-app {
|
|
158
159
|
--wand-safe-top: max(var(--app-inset-top), env(safe-area-inset-top, 0px), 32px);
|
|
159
160
|
--wand-safe-bottom: max(var(--app-inset-bottom), env(safe-area-inset-bottom, 0px), 0px);
|
|
160
161
|
}
|
|
161
162
|
|
|
163
|
+
/* 新版 APK 原生已经 padding 过, 不需要 CSS 再加任何 safe-area。把所有
|
|
164
|
+
--wand-safe-* / --pwa-safe-top 全部归零, 让顶部抽屉 / 模态 / 顶栏直接顶
|
|
165
|
+
到 WebView 内容上沿 (= 状态栏下沿)。*/
|
|
166
|
+
.is-wand-app-native-insets {
|
|
167
|
+
--wand-safe-top: 0px;
|
|
168
|
+
--wand-safe-bottom: 0px;
|
|
169
|
+
--wand-safe-left: 0px;
|
|
170
|
+
--wand-safe-right: 0px;
|
|
171
|
+
--pwa-safe-top: 0px;
|
|
172
|
+
}
|
|
173
|
+
|
|
162
174
|
/* 在普通移动浏览器 / Android WebView 边到边渲染 / 旋转后地址栏隐藏等场景下,
|
|
163
175
|
.app-container 同样需要消费 safe-area-inset-top, 否则 .main-header-row
|
|
164
176
|
会被状态栏挡住。inset 为 0 的设备上为 0px, 不影响桌面。*/
|
|
@@ -10824,10 +10836,10 @@
|
|
|
10824
10836
|
.file-preview-modal {
|
|
10825
10837
|
width: 100vw;
|
|
10826
10838
|
max-width: 100vw;
|
|
10827
|
-
height
|
|
10828
|
-
|
|
10829
|
-
|
|
10830
|
-
max-height: 100dvh;
|
|
10839
|
+
/* 键盘弹起时跟随 --app-viewport-height (= visualViewport.height) 收缩,
|
|
10840
|
+
否则 100dvh 不响应键盘, 编辑文本框会被键盘盖住。 */
|
|
10841
|
+
height: var(--app-viewport-height, 100dvh);
|
|
10842
|
+
max-height: var(--app-viewport-height, 100dvh);
|
|
10831
10843
|
border-radius: 0;
|
|
10832
10844
|
border: none;
|
|
10833
10845
|
box-shadow: none;
|