From 134954335c60e0e69fe8c94f7f84e7c591f8be8f Mon Sep 17 00:00:00 2001 From: zoujing Date: Wed, 27 May 2026 12:51:17 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E5=8D=A1=E7=89=87?= =?UTF-8?q?=E6=BB=9A=E5=8A=A8=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/regression-card-swiper-gesture.mjs | 36 +++++++++++++++++++ .../Discovery/components/CardSwiper/index.vue | 6 +++- 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 scripts/regression-card-swiper-gesture.mjs diff --git a/scripts/regression-card-swiper-gesture.mjs b/scripts/regression-card-swiper-gesture.mjs new file mode 100644 index 0000000..fa13846 --- /dev/null +++ b/scripts/regression-card-swiper-gesture.mjs @@ -0,0 +1,36 @@ +import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; +import { dirname, resolve } from "node:path"; +import { fileURLToPath } from "node:url"; + +const scriptDir = dirname(fileURLToPath(import.meta.url)); +const componentPath = resolve( + scriptDir, + "../src/pages/Discovery/components/CardSwiper/index.vue" +); +const source = readFileSync(componentPath, "utf8"); + +assert.match( + source, + /@touchmove\.stop\.prevent="handleTouchMove"/, + "CardSwiper should keep native mini-program touchmove capture behavior" +); + +const touchStartMatch = source.match( + /const\s+handleTouchStart\s*=\s*\(event\)\s*=>\s*{([\s\S]*?)\n};/ +); + +assert.ok(touchStartMatch, "CardSwiper should define handleTouchStart"); + +assert.ok( + !/if\s*\([^)]*isRecycling\.value[^)]*\)\s*return/.test(touchStartMatch[1]), + "CardSwiper should accept the next touchstart during the recycle frame so quick follow-up swipes are not dropped" +); + +assert.ok( + /clearFillFadeTimer\(\)/.test(touchStartMatch[1]) && + /clearRecycleTimer\(\)/.test(touchStartMatch[1]) && + /isRecycling\.value\s*=\s*false/.test(touchStartMatch[1]) && + /fillFadeKey\.value\s*=\s*["']["']/.test(touchStartMatch[1]), + "CardSwiper should cancel recycle and decorative fill fade before starting a new gesture" +); diff --git a/src/pages/Discovery/components/CardSwiper/index.vue b/src/pages/Discovery/components/CardSwiper/index.vue index bd3bf40..c394d99 100644 --- a/src/pages/Discovery/components/CardSwiper/index.vue +++ b/src/pages/Discovery/components/CardSwiper/index.vue @@ -432,11 +432,15 @@ const finishSwipe = (step) => { }; const handleTouchStart = (event) => { - if (!canSwipe.value || isAnimating.value || isRecycling.value) return; + if (!canSwipe.value || isAnimating.value) return; const touch = event.touches?.[0] || event.changedTouches?.[0]; if (!touch) return; + clearRecycleTimer(); + clearFillFadeTimer(); + isRecycling.value = false; + fillFadeKey.value = ""; startX = touch.clientX; startY = touch.clientY; deltaX.value = 0;