From 0cd54f2fe3977b260272d5766d7f131c4812a714 Mon Sep 17 00:00:00 2001 From: xhon-pelushi Date: Thu, 13 Aug 2026 23:48:45 -0400 Subject: [PATCH] Refresh relative due date display in task list The due date shown in the task list (e.g. "Today", "Yesterday") was computed once when the task item was rendered and never updated afterwards, since moment().calendar() defaults to the time at evaluation and Vue only recomputes when a tracked reactive dependency changes. If a task stayed on screen for a while (e.g. across midnight), the list kept showing a stale relative label while the sidebar, which re-mounts per task selection, showed the correct one. Track a periodically updated timestamp and pass it as the reference time to calendar(), so the computed properties stay reactive to the passage of time. Fixes #3203 Signed-off-by: xhon-pelushi --- src/components/TaskBody.vue | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/components/TaskBody.vue b/src/components/TaskBody.vue index 779a499d1..c14ec790d 100644 --- a/src/components/TaskBody.vue +++ b/src/components/TaskBody.vue @@ -280,6 +280,7 @@ export default { showCreateMultipleTasksModal: false, multipleTasks: { numberOfTasks: 0, tasks: {} }, additionalTaskProperties: {}, + now: Date.now(), } }, computed: { @@ -291,7 +292,7 @@ export default { dueDateShort() { if (!this.task.completed) { return this.task.dueMoment.isValid() - ? this.task.dueMoment.calendar(null, { + ? this.task.dueMoment.calendar(moment(this.now), { // TRANSLATORS This is a string for moment.js. The square brackets escape the string from moment.js. Please translate the string and keep the brackets. lastDay: t('tasks', '[Yesterday]'), // TRANSLATORS This is a string for moment.js. The square brackets escape the string from moment.js. Please translate the string and keep the brackets. @@ -305,7 +306,7 @@ export default { : '' } else { return this.task.completedDateMoment.isValid() - ? this.task.completedDateMoment.calendar(null, { + ? this.task.completedDateMoment.calendar(moment(this.now), { // TRANSLATORS This is a string for moment.js. The square brackets escape the string from moment.js. Please translate the string and keep the brackets. lastDay: t('tasks', '[Completed yesterday]'), // TRANSLATORS This is a string for moment.js. The square brackets escape the string from moment.js. Please translate the string and keep the brackets. @@ -329,7 +330,7 @@ export default { } if (!this.task.completed) { return this.task.dueMoment.isValid() - ? this.task.dueMoment.calendar(null, { + ? this.task.dueMoment.calendar(moment(this.now), { // TRANSLATORS This is a string for moment.js. The square brackets escape the string from moment.js. Please translate the string and keep the brackets. lastDay: t('tasks', '[Yesterday at] LT'), // TRANSLATORS This is a string for moment.js. The square brackets escape the string from moment.js. Please translate the string and keep the brackets. @@ -346,7 +347,7 @@ export default { : '' } else { return this.task.completedDateMoment.isValid() - ? this.task.completedDateMoment.calendar(null, { + ? this.task.completedDateMoment.calendar(moment(this.now), { // TRANSLATORS This is a string for moment.js. The square brackets escape the string from moment.js. Please translate the string and keep the brackets. lastDay: t('tasks', '[Completed yesterday at] LT'), // TRANSLATORS This is a string for moment.js. The square brackets escape the string from moment.js. Please translate the string and keep the brackets. @@ -492,6 +493,18 @@ export default { } }, + mounted() { + // Keep the relative due date (e.g. "Today", "Yesterday") up to date + // even if the task itself isn't modified while the component stays mounted. + this.nowInterval = setInterval(() => { + this.now = Date.now() + }, 60000) + }, + + beforeUnmount() { + clearInterval(this.nowInterval) + }, + methods: { t, n,