From 7a9aa7771bd94df788463f113c66dfec2ae90fdd Mon Sep 17 00:00:00 2001 From: kolaente Date: Mon, 4 Sep 2023 20:14:00 +0200 Subject: [PATCH] fix(tasks): play pop sound directly and not from store This solves two problems: 1. Previously, changing anything on a done task would play the pop sound all the time, because the store only knew the new done status was "done" and not if it was done previously already. 2. Safari will prevent playing a sound without user interaction. This means the user has to interact directly with the method playing the sound which was not the case when the sound was played from the store. Resolves https://kolaente.dev/vikunja/frontend/issues/3292 --- src/components/tasks/partials/kanban-card.vue | 8 +++++++- src/components/tasks/partials/relatedTasks.vue | 6 ++++++ src/components/tasks/partials/singleTaskInProject.vue | 5 +++++ src/stores/tasks.ts | 4 ---- src/views/tasks/TaskDetailView.vue | 6 ++++++ 5 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/components/tasks/partials/kanban-card.vue b/src/components/tasks/partials/kanban-card.vue index 47dd11fbb8..d5043d216f 100644 --- a/src/components/tasks/partials/kanban-card.vue +++ b/src/components/tasks/partials/kanban-card.vue @@ -89,6 +89,8 @@ import {formatDateLong, formatISO, formatDateSince} from '@/helpers/time/formatD import {colorIsDark} from '@/helpers/color/colorIsDark' import {useTaskStore} from '@/stores/tasks' import AssigneeList from '@/components/tasks/partials/assigneeList.vue' +import {useAuthStore} from '@/stores/auth' +import {playPopSound} from '@/helpers/playPop' const router = useRouter() @@ -107,10 +109,14 @@ const color = computed(() => getHexColor(task.hexColor)) async function toggleTaskDone(task: ITask) { loadingInternal.value = true try { - await useTaskStore().update({ + const updatedTask = await useTaskStore().update({ ...task, done: !task.done, }) + + if (updatedTask.done && useAuthStore().settings.frontendSettings.playSoundWhenDone) { + playPopSound() + } } finally { loadingInternal.value = false } diff --git a/src/components/tasks/partials/relatedTasks.vue b/src/components/tasks/partials/relatedTasks.vue index bc3c1c9487..c2e19612cc 100644 --- a/src/components/tasks/partials/relatedTasks.vue +++ b/src/components/tasks/partials/relatedTasks.vue @@ -162,6 +162,8 @@ import Fancycheckbox from '@/components/input/fancycheckbox.vue' import {error, success} from '@/message' import {useTaskStore} from '@/stores/tasks' import {useProjectStore} from '@/stores/projects' +import {useAuthStore} from '@/stores/auth' +import {playPopSound} from '@/helpers/playPop' const props = defineProps({ taskId: { @@ -330,6 +332,10 @@ async function createAndRelateTask(title: string) { async function toggleTaskDone(task: ITask) { await taskStore.update(task) + if (task.done && useAuthStore().settings.frontendSettings.playSoundWhenDone) { + playPopSound() + } + // Find the task in the project and update it so that it is correctly strike through Object.entries(relatedTasks.value).some(([kind, tasks]) => { return (tasks as ITask[]).some((t, key) => { diff --git a/src/components/tasks/partials/singleTaskInProject.vue b/src/components/tasks/partials/singleTaskInProject.vue index f7974d86cb..880cca45da 100644 --- a/src/components/tasks/partials/singleTaskInProject.vue +++ b/src/components/tasks/partials/singleTaskInProject.vue @@ -151,6 +151,8 @@ import {useBaseStore} from '@/stores/base' import {useTaskStore} from '@/stores/tasks' import AssigneeList from '@/components/tasks/partials/assigneeList.vue' import {useIntervalFn} from '@vueuse/core' +import {playPopSound} from '@/helpers/playPop' +import {useAuthStore} from '@/stores/auth' const { theTask, @@ -232,6 +234,9 @@ async function markAsDone(checked: boolean) { const updateFunc = async () => { const newTask = await taskStore.update(task.value) task.value = newTask + if (checked && useAuthStore().settings.frontendSettings.playSoundWhenDone) { + playPopSound() + } emit('task-updated', newTask) success({ message: task.value.done ? diff --git a/src/stores/tasks.ts b/src/stores/tasks.ts index 3b103af9b8..9e02ea16ab 100644 --- a/src/stores/tasks.ts +++ b/src/stores/tasks.ts @@ -6,7 +6,6 @@ import TaskService from '@/services/task' import TaskAssigneeService from '@/services/taskAssignee' import LabelTaskService from '@/services/labelTask' -import {playPopSound} from '@/helpers/playPop' import {cleanupItemText, parseTaskText, PREFIXES} from '@/modules/parseTaskText' import TaskAssigneeModel from '@/models/taskAssignee' @@ -149,9 +148,6 @@ export const useTaskStore = defineStore('task', () => { try { const updatedTask = await taskService.update(task) kanbanStore.setTaskInBucket(updatedTask) - if (task.done && useAuthStore().settings.frontendSettings.playSoundWhenDone) { - playPopSound() - } return updatedTask } finally { cancel() diff --git a/src/views/tasks/TaskDetailView.vue b/src/views/tasks/TaskDetailView.vue index ab681ec4d2..b4ddb05049 100644 --- a/src/views/tasks/TaskDetailView.vue +++ b/src/views/tasks/TaskDetailView.vue @@ -499,6 +499,8 @@ import {success} from '@/message' import type {Action as MessageAction} from '@/message' import {useProjectStore} from '@/stores/projects' import {TASK_REPEAT_MODES} from '@/types/IRepeatMode' +import {useAuthStore} from '@/stores/auth' +import {playPopSound} from '@/helpers/playPop' const { taskId, @@ -735,6 +737,10 @@ function toggleTaskDone() { done: !task.value.done, } + if (newTask.done && useAuthStore().settings.frontendSettings.playSoundWhenDone) { + playPopSound() + } + saveTask( newTask, toggleTaskDone,