fix(task): don't drop the list-view done save during the check animation

Marking a task done via the list-view checkbox deferred the entire update
— including the network request — by 300ms to play the check animation. If
the page was torn down within that window (a refresh, tab close, or leaving
the app), the request was never sent and the save was silently lost. For
repeating tasks this is especially confusing: the due date never advances,
yet the checkbox un-checks itself anyway, so the failure looks identical to
success.

Fire the request immediately with the intended done value snapshotted, and
defer only the animation-coupled follow-up (result swap, pop sound, toast).
The optimistic v-model state already drives the check animation during the
300ms, so nothing visual is lost.
This commit is contained in:
kolaente 2026-06-27 10:32:28 +02:00 committed by kolaente
parent 330b94c3c4
commit 08890895de
1 changed files with 13 additions and 5 deletions

View File

@ -326,9 +326,17 @@ const isOverdue = computed(() => (
let oldTask
async function markAsDone(checked: boolean, wasReverted: boolean = false) {
const updateFunc = async () => {
oldTask = {...task.value}
const newTask = await taskStore.update(task.value)
oldTask = {...task.value}
// Fire the request immediately and with the intended done value snapshotted, so a re-render or
// teardown during the animation delay can neither drop the save nor make it send a stale state.
const updatePromise = taskStore.update({
...task.value,
done: checked,
})
const finish = async () => {
const newTask = await updatePromise
task.value = newTask
updateDueDate()
@ -354,9 +362,9 @@ async function markAsDone(checked: boolean, wasReverted: boolean = false) {
}
if (checked) {
setTimeout(updateFunc, 300) // Delay it to show the animation when marking a task as done
setTimeout(finish, 300) // Delay only the follow-up to show the animation when marking a task as done
} else {
await updateFunc() // Don't delay it when un-marking it as it doesn't have an animation the other way around
await finish() // Don't delay it when un-marking it as it doesn't have an animation the other way around
}
}