fix(android): usesCleartextTraffic=true — release APK blocked HTTP APIs (Android 9+ default)

release 构建默认禁明文 HTTP(debug 由 Flutter 自动放行)——服务暂时不可用
即此因。当前测试服务器 API/观众页均为 http://,需显式允许;上 https 后移除。

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
浅念
2026-09-23 18:10:46 +08:00
parent f7f24b0a0b
commit 65581b7920
8 changed files with 39 additions and 78 deletions
+19 -21
View File
@@ -217,40 +217,30 @@ function scheduleResume(): void {
function onPointerDown(event: PointerEvent): void {
if (event.pointerType === 'mouse' && event.button !== 0) return;
lastPointerTs = Date.now();
pointerDownY = event.clientY;
pointerMoved = 0;
const anchor = (event.target as HTMLElement).closest<HTMLElement>('a.stream-photo');
lockedTarget = anchor === null ? null : (anchor.dataset.photoId ?? null);
setReason('pointer', true);
// 指针捕获 + 看门狗(滚动卡死修复 2026-09-23):按下后拖出窗外松开时,
// pointerup 发生在宿主文档——iframe 内任何监听都收不到(capture 不跨文档),
// 'pointer' 暂停原因会永久残留 → 滚动停死。看门狗 2s 强制恢复是确定性兜底;
// capture/window 监听让 iframe 内的释放更快恢复。
try {
viewportEl.value?.setPointerCapture(event.pointerId);
} catch {
/* 指针已释放等:忽略 */
}
// 看门狗(滚动卡死修复 2026-09-23):按下后拖出窗外松开时,pointerup 发生
// 在宿主文档——iframe 内任何监听都收不到,'pointer'/'manual'/'hover' 暂停
// 原因会永久残留 → 滚动停死。2s 强制恢复是确定性兜底。注意不能用
// setPointerCapture:捕获会把 pointerup/click 重定向到视口元素——照片 <a>
// 的 click 处理收不到点击(曾致详情弹框打不开),已移除。
if (pointerWatchdog !== null) clearTimeout(pointerWatchdog);
pointerWatchdog = setTimeout(() => {
pointerWatchdog = null;
pointerDownY = null;
// 统一清指针族原因(滚动卡死第三层修复 2026-09-23):pointer capture 挂起
// 期间 pointerleave 不派发,而窗外释放使 up 永不送达 iframe → capture 不
// 释放 → hover 原因同样永久卡住。看门狗兜底:释放捕获 + 清
// pointer/manual/hover 三因(窗内正常路径由各事件自行清理,不受影响)。
try {
const el = viewportEl.value;
if (el !== null && el.hasPointerCapture(event.pointerId)) {
el.releasePointerCapture(event.pointerId);
}
} catch {
/* 指针已不在:忽略 */
}
// 统一清指针族原因(滚动卡死第三层修复 2026-09-23):拖出窗外后 leave
// 可能未派发(焦点/边界事件在 iframe 间不可靠),hover 原因同样可能卡住。
// 看门狗兜底清 pointer/manual/hover/focus 四因(窗内正常路径由各事件
// 自行清理,不受影响)。
hoverPointerIsMouse = false;
setReason('pointer', false);
setReason('manual', false);
setReason('hover', false);
setReason('focus', false);
scheduleResume();
}, POINTER_WATCHDOG_MS);
}
@@ -363,7 +353,14 @@ function onPointerLeave(event: PointerEvent): void {
scheduleResume();
}, RESUME_DELAY_MS);
}
/** 最近一次指针交互时刻(focusin 归因用)。 */
let lastPointerTs = 0;
function onFocusIn(): void {
// 鼠标点击/拖动会把焦点带到窗内元素(focusin 副作用)——此时暂停会永久
// 卡住(鼠标移开不清键盘焦点,滚动停死根因 2026-09-23)。仅键盘导航
// (Tab/方向键进入,非指针后短窗)才触发 focus 暂停(§4.2 本意)。
if (Date.now() - lastPointerTs < 500) return;
setReason('focus', true);
}
function onFocusOut(): void {
@@ -387,6 +384,7 @@ function onWindowBlur(): void {
pointerDownY = null;
setReason('pointer', false);
setReason('manual', false);
setReason('focus', false);
}
onMounted(() => {