fix: restore apk tutorial scrolling and bump app to 1.0.19

This commit is contained in:
JOJO 2026-04-07 17:56:05 +08:00
parent 4e4186f87a
commit 7e1d9bfede
5 changed files with 60 additions and 10 deletions

View File

@ -1,5 +1,10 @@
# App 更新说明
# 1.0.19
- 修复 Android APK 内「个人空间-新手教程」期间无法上下滚动的问题:教程遮罩层现在会正确转发触摸滑动到可滚动容器
- 优化教程滚动目标识别:优先命中当前可滚动页面区域,减少 WebView 场景下滑动失效
- 调整软件更新页版本展示:移除括号内的构建代数,仅显示语义版本号(如 1.0.19
# 1.0.18
- 新增完整「新手教程」系统(高光 + 悬浮说明窗):覆盖桌面端与手机端核心功能入口
- 教程交互统一优化:仅保留“下一步”,支持自动点击与点击特效,避免误触真实页面

View File

@ -16,8 +16,8 @@ android {
applicationId = "com.cyjai.agent"
minSdk = 24
targetSdk = 35
versionCode = 20
versionName = "1.0.18"
versionCode = 21
versionName = "1.0.19"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}

View File

@ -1,5 +1,14 @@
<template>
<div v-if="running" class="tutorial-overlay" aria-live="polite" @wheel="handleWheel">
<div
v-if="running"
class="tutorial-overlay"
aria-live="polite"
@wheel="handleWheel"
@touchstart="handleTouchStart"
@touchmove.prevent="handleTouchMove"
@touchend="handleTouchEnd"
@touchcancel="handleTouchEnd"
>
<div class="tutorial-click-blocker" @click.stop></div>
<div v-if="stepReady && maskVisible" class="tutorial-mask" :style="[maskTopStyle, maskInteractivityStyle]" @click.stop></div>
<div v-if="stepReady && maskVisible" class="tutorial-mask" :style="[maskLeftStyle, maskInteractivityStyle]" @click.stop></div>
@ -70,6 +79,7 @@ const resolvedPlacement = ref<TutorialPlacement>('center');
const clickEffect = ref<{ x: number; y: number } | null>(null);
let refreshTimer: number | null = null;
let stepSettleTimer: number | null = null;
let lastTouchY: number | null = null;
const stepReady = ref(true);
const isMustClick = computed(() => step.value?.mode === 'must_click');
@ -310,14 +320,21 @@ const handleCaptureClick = (event: MouseEvent) => {
window.setTimeout(() => tutorialStore.goNext(), 280);
};
const getPersonalScrollTarget = () => {
const pageCandidates = Array.from(document.querySelectorAll('.personalization-content .personal-page')) as HTMLElement[];
const pageScrollable = pageCandidates.find((el) => el.scrollHeight - el.clientHeight > 2);
if (pageScrollable) return pageScrollable;
const content = document.querySelector('.personalization-content') as HTMLElement | null;
if (content && content.scrollHeight - content.clientHeight > 2) return content;
return (document.querySelector('[data-tutorial="personal-content-shell"]') as HTMLElement | null) || content;
};
const handleWheel = (event: WheelEvent) => {
if (!isPersonalTutorialPhase.value) {
event.preventDefault();
return;
}
const scrollTarget =
(document.querySelector('.personalization-content') as HTMLElement | null) ||
(document.querySelector('[data-tutorial="personal-content-shell"]') as HTMLElement | null);
const scrollTarget = getPersonalScrollTarget();
if (!scrollTarget) {
event.preventDefault();
return;
@ -326,6 +343,35 @@ const handleWheel = (event: WheelEvent) => {
event.preventDefault();
};
const handleTouchStart = (event: TouchEvent) => {
if (!event.touches.length) return;
lastTouchY = event.touches[0].clientY;
};
const handleTouchMove = (event: TouchEvent) => {
if (!event.touches.length) return;
const currentY = event.touches[0].clientY;
const prevY = lastTouchY ?? currentY;
const deltaY = prevY - currentY;
lastTouchY = currentY;
if (!isPersonalTutorialPhase.value) {
event.preventDefault();
return;
}
const scrollTarget = getPersonalScrollTarget();
if (!scrollTarget) {
event.preventDefault();
return;
}
scrollTarget.scrollBy({ top: deltaY, left: 0, behavior: 'auto' });
event.preventDefault();
};
const handleTouchEnd = () => {
lastTouchY = null;
};
const playClickEffect = (targetEl: HTMLElement | null) => {
if (!targetEl) return;
const rect = targetEl.getBoundingClientRect();

View File

@ -1166,14 +1166,12 @@ const hydrateAppVersionFromBridge = () => {
};
const appCurrentVersionText = computed(() => {
const vn = appCurrentVersionName.value || '未知';
const vc = appCurrentVersionCode.value ?? '?';
return `${vn} (${vc})`;
return appCurrentVersionName.value || '未知';
});
const appLatestVersionText = computed(() => {
if (!appUpdateInfo.value) return '--';
return `${appUpdateInfo.value.latestVersionName || '未知'} (${appUpdateInfo.value.latestVersionCode ?? '?'})`;
return `${appUpdateInfo.value.latestVersionName || '未知'}`;
});
const appLatestFileSizeText = computed(() => {

View File

@ -3604,6 +3604,7 @@ body[data-theme='dark'] {
inset: 0;
z-index: 3200;
pointer-events: auto;
touch-action: none;
}
.tutorial-click-blocker {