fix: restore apk tutorial scrolling and bump app to 1.0.19
This commit is contained in:
parent
4e4186f87a
commit
7e1d9bfede
@ -1,5 +1,10 @@
|
|||||||
# App 更新说明
|
# App 更新说明
|
||||||
|
|
||||||
|
# 1.0.19
|
||||||
|
- 修复 Android APK 内「个人空间-新手教程」期间无法上下滚动的问题:教程遮罩层现在会正确转发触摸滑动到可滚动容器
|
||||||
|
- 优化教程滚动目标识别:优先命中当前可滚动页面区域,减少 WebView 场景下滑动失效
|
||||||
|
- 调整软件更新页版本展示:移除括号内的构建代数,仅显示语义版本号(如 1.0.19)
|
||||||
|
|
||||||
# 1.0.18
|
# 1.0.18
|
||||||
- 新增完整「新手教程」系统(高光 + 悬浮说明窗):覆盖桌面端与手机端核心功能入口
|
- 新增完整「新手教程」系统(高光 + 悬浮说明窗):覆盖桌面端与手机端核心功能入口
|
||||||
- 教程交互统一优化:仅保留“下一步”,支持自动点击与点击特效,避免误触真实页面
|
- 教程交互统一优化:仅保留“下一步”,支持自动点击与点击特效,避免误触真实页面
|
||||||
|
|||||||
@ -16,8 +16,8 @@ android {
|
|||||||
applicationId = "com.cyjai.agent"
|
applicationId = "com.cyjai.agent"
|
||||||
minSdk = 24
|
minSdk = 24
|
||||||
targetSdk = 35
|
targetSdk = 35
|
||||||
versionCode = 20
|
versionCode = 21
|
||||||
versionName = "1.0.18"
|
versionName = "1.0.19"
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,14 @@
|
|||||||
<template>
|
<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 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="[maskTopStyle, maskInteractivityStyle]" @click.stop></div>
|
||||||
<div v-if="stepReady && maskVisible" class="tutorial-mask" :style="[maskLeftStyle, 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);
|
const clickEffect = ref<{ x: number; y: number } | null>(null);
|
||||||
let refreshTimer: number | null = null;
|
let refreshTimer: number | null = null;
|
||||||
let stepSettleTimer: number | null = null;
|
let stepSettleTimer: number | null = null;
|
||||||
|
let lastTouchY: number | null = null;
|
||||||
const stepReady = ref(true);
|
const stepReady = ref(true);
|
||||||
|
|
||||||
const isMustClick = computed(() => step.value?.mode === 'must_click');
|
const isMustClick = computed(() => step.value?.mode === 'must_click');
|
||||||
@ -310,14 +320,21 @@ const handleCaptureClick = (event: MouseEvent) => {
|
|||||||
window.setTimeout(() => tutorialStore.goNext(), 280);
|
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) => {
|
const handleWheel = (event: WheelEvent) => {
|
||||||
if (!isPersonalTutorialPhase.value) {
|
if (!isPersonalTutorialPhase.value) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const scrollTarget =
|
const scrollTarget = getPersonalScrollTarget();
|
||||||
(document.querySelector('.personalization-content') as HTMLElement | null) ||
|
|
||||||
(document.querySelector('[data-tutorial="personal-content-shell"]') as HTMLElement | null);
|
|
||||||
if (!scrollTarget) {
|
if (!scrollTarget) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
return;
|
return;
|
||||||
@ -326,6 +343,35 @@ const handleWheel = (event: WheelEvent) => {
|
|||||||
event.preventDefault();
|
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) => {
|
const playClickEffect = (targetEl: HTMLElement | null) => {
|
||||||
if (!targetEl) return;
|
if (!targetEl) return;
|
||||||
const rect = targetEl.getBoundingClientRect();
|
const rect = targetEl.getBoundingClientRect();
|
||||||
|
|||||||
@ -1166,14 +1166,12 @@ const hydrateAppVersionFromBridge = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const appCurrentVersionText = computed(() => {
|
const appCurrentVersionText = computed(() => {
|
||||||
const vn = appCurrentVersionName.value || '未知';
|
return appCurrentVersionName.value || '未知';
|
||||||
const vc = appCurrentVersionCode.value ?? '?';
|
|
||||||
return `${vn} (${vc})`;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const appLatestVersionText = computed(() => {
|
const appLatestVersionText = computed(() => {
|
||||||
if (!appUpdateInfo.value) return '--';
|
if (!appUpdateInfo.value) return '--';
|
||||||
return `${appUpdateInfo.value.latestVersionName || '未知'} (${appUpdateInfo.value.latestVersionCode ?? '?'})`;
|
return `${appUpdateInfo.value.latestVersionName || '未知'}`;
|
||||||
});
|
});
|
||||||
|
|
||||||
const appLatestFileSizeText = computed(() => {
|
const appLatestFileSizeText = computed(() => {
|
||||||
|
|||||||
@ -3604,6 +3604,7 @@ body[data-theme='dark'] {
|
|||||||
inset: 0;
|
inset: 0;
|
||||||
z-index: 3200;
|
z-index: 3200;
|
||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
|
touch-action: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tutorial-click-blocker {
|
.tutorial-click-blocker {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user