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 vikunja/frontend#3292
This commit is contained in:
kolaente 2023-09-04 20:14:00 +02:00
parent abbc11528e
commit 7a9aa7771b
Signed by untrusted user: konrad
GPG Key ID: F40E70337AB24C9B
5 changed files with 24 additions and 5 deletions

View File

@ -89,6 +89,8 @@ import {formatDateLong, formatISO, formatDateSince} from '@/helpers/time/formatD
import {colorIsDark} from '@/helpers/color/colorIsDark' import {colorIsDark} from '@/helpers/color/colorIsDark'
import {useTaskStore} from '@/stores/tasks' import {useTaskStore} from '@/stores/tasks'
import AssigneeList from '@/components/tasks/partials/assigneeList.vue' import AssigneeList from '@/components/tasks/partials/assigneeList.vue'
import {useAuthStore} from '@/stores/auth'
import {playPopSound} from '@/helpers/playPop'
const router = useRouter() const router = useRouter()
@ -107,10 +109,14 @@ const color = computed(() => getHexColor(task.hexColor))
async function toggleTaskDone(task: ITask) { async function toggleTaskDone(task: ITask) {
loadingInternal.value = true loadingInternal.value = true
try { try {
await useTaskStore().update({ const updatedTask = await useTaskStore().update({
...task, ...task,
done: !task.done, done: !task.done,
}) })
if (updatedTask.done && useAuthStore().settings.frontendSettings.playSoundWhenDone) {
playPopSound()
}
} finally { } finally {
loadingInternal.value = false loadingInternal.value = false
} }

View File

@ -162,6 +162,8 @@ import Fancycheckbox from '@/components/input/fancycheckbox.vue'
import {error, success} from '@/message' import {error, success} from '@/message'
import {useTaskStore} from '@/stores/tasks' import {useTaskStore} from '@/stores/tasks'
import {useProjectStore} from '@/stores/projects' import {useProjectStore} from '@/stores/projects'
import {useAuthStore} from '@/stores/auth'
import {playPopSound} from '@/helpers/playPop'
const props = defineProps({ const props = defineProps({
taskId: { taskId: {
@ -330,6 +332,10 @@ async function createAndRelateTask(title: string) {
async function toggleTaskDone(task: ITask) { async function toggleTaskDone(task: ITask) {
await taskStore.update(task) 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 // Find the task in the project and update it so that it is correctly strike through
Object.entries(relatedTasks.value).some(([kind, tasks]) => { Object.entries(relatedTasks.value).some(([kind, tasks]) => {
return (tasks as ITask[]).some((t, key) => { return (tasks as ITask[]).some((t, key) => {

View File

@ -151,6 +151,8 @@ import {useBaseStore} from '@/stores/base'
import {useTaskStore} from '@/stores/tasks' import {useTaskStore} from '@/stores/tasks'
import AssigneeList from '@/components/tasks/partials/assigneeList.vue' import AssigneeList from '@/components/tasks/partials/assigneeList.vue'
import {useIntervalFn} from '@vueuse/core' import {useIntervalFn} from '@vueuse/core'
import {playPopSound} from '@/helpers/playPop'
import {useAuthStore} from '@/stores/auth'
const { const {
theTask, theTask,
@ -232,6 +234,9 @@ async function markAsDone(checked: boolean) {
const updateFunc = async () => { const updateFunc = async () => {
const newTask = await taskStore.update(task.value) const newTask = await taskStore.update(task.value)
task.value = newTask task.value = newTask
if (checked && useAuthStore().settings.frontendSettings.playSoundWhenDone) {
playPopSound()
}
emit('task-updated', newTask) emit('task-updated', newTask)
success({ success({
message: task.value.done ? message: task.value.done ?

View File

@ -6,7 +6,6 @@ import TaskService from '@/services/task'
import TaskAssigneeService from '@/services/taskAssignee' import TaskAssigneeService from '@/services/taskAssignee'
import LabelTaskService from '@/services/labelTask' import LabelTaskService from '@/services/labelTask'
import {playPopSound} from '@/helpers/playPop'
import {cleanupItemText, parseTaskText, PREFIXES} from '@/modules/parseTaskText' import {cleanupItemText, parseTaskText, PREFIXES} from '@/modules/parseTaskText'
import TaskAssigneeModel from '@/models/taskAssignee' import TaskAssigneeModel from '@/models/taskAssignee'
@ -149,9 +148,6 @@ export const useTaskStore = defineStore('task', () => {
try { try {
const updatedTask = await taskService.update(task) const updatedTask = await taskService.update(task)
kanbanStore.setTaskInBucket(updatedTask) kanbanStore.setTaskInBucket(updatedTask)
if (task.done && useAuthStore().settings.frontendSettings.playSoundWhenDone) {
playPopSound()
}
return updatedTask return updatedTask
} finally { } finally {
cancel() cancel()

View File

@ -499,6 +499,8 @@ import {success} from '@/message'
import type {Action as MessageAction} from '@/message' import type {Action as MessageAction} from '@/message'
import {useProjectStore} from '@/stores/projects' import {useProjectStore} from '@/stores/projects'
import {TASK_REPEAT_MODES} from '@/types/IRepeatMode' import {TASK_REPEAT_MODES} from '@/types/IRepeatMode'
import {useAuthStore} from '@/stores/auth'
import {playPopSound} from '@/helpers/playPop'
const { const {
taskId, taskId,
@ -735,6 +737,10 @@ function toggleTaskDone() {
done: !task.value.done, done: !task.value.done,
} }
if (newTask.done && useAuthStore().settings.frontendSettings.playSoundWhenDone) {
playPopSound()
}
saveTask( saveTask(
newTask, newTask,
toggleTaskDone, toggleTaskDone,