diff --git a/nginx.conf b/nginx.conf index 2a7f59ab5..784b09183 100644 --- a/nginx.conf +++ b/nginx.conf @@ -34,7 +34,7 @@ http { gzip_buffers 16 8k; gzip_http_version 1.1; gzip_min_length 256; - gzip_types text/plain text/css application/json application/x-javascript application/javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml font/woff2 image/x-icon; + gzip_types text/plain text/css application/json application/x-javascript application/javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml font/woff2 image/x-icon audio/wav; # Expires map map $sent_http_content_type $expires { @@ -49,6 +49,7 @@ http { font/woff2 max; image/svg+xml max; image/x-icon max; + audio/wav max; ~image/ max; ~font/ max; } diff --git a/public/audio/pop.wav b/public/audio/pop.wav new file mode 100644 index 000000000..bc56c9416 Binary files /dev/null and b/public/audio/pop.wav differ diff --git a/src/ServiceWorker/sw.js b/src/ServiceWorker/sw.js index 9730aef70..98d8bc293 100644 --- a/src/ServiceWorker/sw.js +++ b/src/ServiceWorker/sw.js @@ -4,7 +4,7 @@ // Cache assets workbox.routing.registerRoute( // This regexp matches all files in precache-manifest - new RegExp('.+\\.(css|json|js|svg|woff2|png|html|txt)$'), + new RegExp('.+\\.(css|json|js|svg|woff2|png|html|txt|wav)$'), new workbox.strategies.StaleWhileRevalidate(), ) diff --git a/src/components/tasks/partials/singleTaskInList.vue b/src/components/tasks/partials/singleTaskInList.vue index 081bdce20..aa02baf8a 100644 --- a/src/components/tasks/partials/singleTaskInList.vue +++ b/src/components/tasks/partials/singleTaskInList.vue @@ -92,6 +92,7 @@ import User from '../../misc/user' import Fancycheckbox from '../../input/fancycheckbox' import DeferTask from './defer-task' import {closeWhenClickedOutside} from '@/helpers/closeWhenClickedOutside' +import {playPop} from '@/helpers/playPop' export default { name: 'singleTaskInList', @@ -164,6 +165,9 @@ export default { const updateFunc = () => { this.taskService.update(this.task) .then(t => { + if(this.task.done) { + playPop() + } this.task = t this.$emit('task-updated', t) this.success( diff --git a/src/helpers/playPop.js b/src/helpers/playPop.js new file mode 100644 index 000000000..d65885a99 --- /dev/null +++ b/src/helpers/playPop.js @@ -0,0 +1,11 @@ +export const playSoundWhenDoneKey = 'playSoundWhenTaskDone' + +export const playPop = () => { + const enabled = localStorage.getItem(playSoundWhenDoneKey) === 'true' || localStorage.getItem(playSoundWhenDoneKey) === null + if(!enabled) { + return + } + + const popSound = new Audio('/audio/pop.wav') + popSound.play() +} \ No newline at end of file diff --git a/src/views/list/views/Kanban.vue b/src/views/list/views/Kanban.vue index 8731e2d4f..a03f3e5c1 100644 --- a/src/views/list/views/Kanban.vue +++ b/src/views/list/views/Kanban.vue @@ -265,6 +265,7 @@ import Rights from '../../../models/rights.json' import {LOADING, LOADING_MODULE} from '@/store/mutation-types' import FilterPopup from '@/components/list/partials/filter-popup' import Dropdown from '@/components/misc/dropdown' +import {playPop} from '@/helpers/playPop' export default { name: 'Kanban', @@ -421,6 +422,11 @@ export default { this.$set(this.taskUpdating, task.id, true) task.done = !task.done this.$store.dispatch('tasks/update', task) + .then(() => { + if(task.done) { + playPop() + } + }) .catch(e => { this.error(e, this) }) diff --git a/src/views/tasks/TaskDetailView.vue b/src/views/tasks/TaskDetailView.vue index 00061e212..ca300e1ae 100644 --- a/src/views/tasks/TaskDetailView.vue +++ b/src/views/tasks/TaskDetailView.vue @@ -421,6 +421,7 @@ import ColorPicker from '../../components/input/colorPicker' import attachmentUpload from '../../components/tasks/mixins/attachmentUpload' import heading from '@/components/tasks/partials/heading' import Datepicker from '@/components/input/datepicker' +import {playPop} from '@/helpers/playPop' export default { name: 'TaskDetailView', @@ -644,6 +645,11 @@ export default { }, toggleTaskDone() { this.task.done = !this.task.done + + if(this.task.done) { + playPop() + } + this.saveTask(true, () => this.toggleTaskDone()) }, setDescriptionChanged(e) { diff --git a/src/views/user/Settings.vue b/src/views/user/Settings.vue index b66bc7e75..f9f2463b1 100644 --- a/src/views/user/Settings.vue +++ b/src/views/user/Settings.vue @@ -108,6 +108,12 @@ Send me Reminders for tasks via Email +
+ +
this.error(e, this)) }, updateSettings() { + localStorage.setItem(playSoundWhenDoneKey, this.playSoundWhenDone) + this.userSettingsService.update(this.settings) .then(() => { this.$store.commit('auth/setUserSettings', this.settings)