fix: harden calendar subscriptions and add left-swipe reopen
ci / docker (push) Successful in 3m31s

This commit is contained in:
2026-09-06 09:45:00 +08:00
parent b937c8ca72
commit c98223b7d3
12 changed files with 264 additions and 103 deletions
+14 -6
View File
@@ -95,7 +95,12 @@ function moveHabitSwipe(h: Habit, event: TouchEvent) {
if (!start || start.id !== h.id || !touch) return
const deltaX = touch.clientX - start.x
const deltaY = touch.clientY - start.y
if (deltaX > 0 && Math.abs(deltaX) > Math.abs(deltaY)) habitSwipeOffsets.value[h.id] = Math.min(deltaX, 92)
const done = isDone(h, todayKey.value)
if (Math.abs(deltaX) > Math.abs(deltaY)) {
if ((!done && deltaX > 0) || (done && deltaX < 0)) {
habitSwipeOffsets.value[h.id] = Math.max(-92, Math.min(deltaX, 92))
}
}
}
async function finishHabitSwipe(h: Habit, event: TouchEvent) {
const start = habitSwipeStart.value
@@ -103,7 +108,10 @@ async function finishHabitSwipe(h: Habit, event: TouchEvent) {
habitSwipeOffsets.value[h.id] = 0
if (!start || start.id !== h.id || h.kind === 'numeric' || busy.value) return
const touch = event.changedTouches[0]
if (touch && shouldToggleRowSwipe(touch.clientX - start.x, touch.clientY - start.y)) {
const deltaX = touch ? touch.clientX - start.x : 0
const deltaY = touch ? touch.clientY - start.y : 0
const expectedDirection = isDone(h, todayKey.value) ? deltaX < 0 : deltaX > 0
if (touch && expectedDirection && shouldToggleRowSwipe(Math.abs(deltaX), deltaY)) {
await toggleHabit(h, todayKey.value)
}
}
@@ -283,11 +291,11 @@ onBeforeUnmount(() => {
<!-- 习惯列表布尔习惯整行右滑打卡数值习惯保留明确输入记录 -->
<div class="habit-list">
<article v-for="h in habits" :key="h.id" class="habit-row" :class="{ done: isDone(h, todayKey), swipeable: h.kind !== 'numeric', ready: (habitSwipeOffsets[h.id] ?? 0) >= 64 }" :style="{ '--swipe-x': `${habitSwipeOffsets[h.id] ?? 0}px` }" @touchstart.passive="startHabitSwipe(h, $event)" @touchmove.passive="moveHabitSwipe(h, $event)" @touchend="finishHabitSwipe(h, $event)" @touchcancel="cancelHabitSwipe(h)">
<span v-if="h.kind !== 'numeric'" class="swipe-bg"> 打卡</span>
<div v-if="view === 'habits'" class="habit-list">
<article v-for="h in habits" :key="h.id" class="habit-row" :class="{ done: isDone(h, todayKey), swipeable: h.kind !== 'numeric', ready: Math.abs(habitSwipeOffsets[h.id] ?? 0) >= 64 }" :style="{ '--swipe-x': `${habitSwipeOffsets[h.id] ?? 0}px`, '--swipe-width': `${Math.abs(habitSwipeOffsets[h.id] ?? 0)}px` }" @touchstart.passive="startHabitSwipe(h, $event)" @touchmove.passive="moveHabitSwipe(h, $event)" @touchend="finishHabitSwipe(h, $event)" @touchcancel="cancelHabitSwipe(h)">
<span v-if="h.kind !== 'numeric'" class="swipe-bg" :class="{ cancel: isDone(h, todayKey) }">{{ isDone(h, todayKey) ? ' 未完成' : ' 打卡' }}</span>
<div v-if="h.kind !== 'numeric'" class="habit-main">
<span><span class="habit-name">{{ h.name }}</span><small>{{ isDone(h, todayKey) ? '今天已完成 · 右滑可取消' : '右滑整行打卡' }}</small></span>
<span><span class="habit-name">{{ h.name }}</span><small>{{ isDone(h, todayKey) ? '今天已完成 · 左滑取消' : '右滑整行打卡' }}</small></span>
<button class="habit-swipe-hint" :aria-label="isDone(h, todayKey) ? `取消${h.name}今天的打卡` : `完成${h.name}今天的打卡`" :aria-pressed="isDone(h, todayKey)" @click.stop="toggleHabitFromButton(h)">{{ isDone(h, todayKey) ? '已完成' : '打卡' }}</button>
</div>
<div v-else class="habit-main numeric-habit">