From f4a79436809d13e1d2c5337f79358c15310d08d2 Mon Sep 17 00:00:00 2001 From: kolaente Date: Fri, 2 Jun 2023 12:40:21 +0200 Subject: [PATCH] fix: bubble changes from the editor immediately and move the delay to callers This gives the callers more control over when to save data and show/hide additional controls based on the input text --- src/components/input/editor.vue | 55 +++++++++---------- src/components/tasks/partials/comments.vue | 22 +++++++- src/components/tasks/partials/description.vue | 20 ++++++- 3 files changed, 64 insertions(+), 33 deletions(-) diff --git a/src/components/input/editor.vue b/src/components/input/editor.vue index f428eb5c..e49c36e4 100644 --- a/src/components/input/editor.vue +++ b/src/components/input/editor.vue @@ -4,7 +4,7 @@ {{ $t('misc.save') }} @@ -56,7 +56,7 @@ @@ -84,8 +84,8 @@ import {createRandomID} from '@/helpers/randomId' import BaseButton from '@/components/base/BaseButton.vue' import ButtonLink from '@/components/misc/ButtonLink.vue' -import type { IAttachment } from '@/modelTypes/IAttachment' -import type { ITask } from '@/modelTypes/ITask' +import type {IAttachment} from '@/modelTypes/IAttachment' +import type {ITask} from '@/modelTypes/ITask' const props = defineProps({ modelValue: { @@ -115,7 +115,7 @@ const props = defineProps({ default: true, }, bottomActions: { - type: Array, + type: Array, default: () => [], }, emptyText: { @@ -134,10 +134,9 @@ const props = defineProps({ }, }) -const emit = defineEmits(['update:modelValue']) +const emit = defineEmits(['update:modelValue', 'save']) const text = ref('') -const changeTimeout = ref | null>(null) const isEditActive = ref(false) const isPreviewActive = ref(true) @@ -148,7 +147,7 @@ const preview = ref('') const attachmentService = new AttachmentService() type CacheKey = `${ITask['id']}-${IAttachment['id']}` -const loadedAttachments = ref<{[key: CacheKey]: string}>({}) +const loadedAttachments = ref<{ [key: CacheKey]: string }>({}) const config = ref(createEasyMDEConfig({ placeholder: props.placeholder, uploadImage: props.uploadEnabled, @@ -175,7 +174,7 @@ watch( if (oldVal === '' && text.value === modelValue.value) { return } - bubble() + bubbleNow() }, ) @@ -208,17 +207,11 @@ function handleInput(val: string) { } text.value = val - bubble(1000) + bubbleNow() } -function bubble(timeout = 5000) { - if (changeTimeout.value !== null) { - clearTimeout(changeTimeout.value) - } - - changeTimeout.value = setTimeout(() => { - emit('update:modelValue', text.value) - }, timeout) +function bubbleNow() { + emit('update:modelValue', text.value) } function replaceAt(str: string, index: number, replacement: string) { @@ -287,24 +280,26 @@ function handleCheckboxClick(e: Event) { return } const projectPrefix = text.value.substring(index, index + 1) - + console.debug({index, projectPrefix, checked, text: text.value}) text.value = replaceAt(text.value, index, `${projectPrefix} ${checked ? '[x]' : '[ ]'} `) - bubble() + bubbleNow() + emit('save', text.value) renderPreview() } function toggleEdit() { - if (isEditActive.value) { - isPreviewActive.value = true - isEditActive.value = false - renderPreview() - bubble(0) // save instantly - } else { - isPreviewActive.value = false - isEditActive.value = true - } + isPreviewActive.value = false + isEditActive.value = true +} + +function bubbleSaveClick() { + isPreviewActive.value = true + isEditActive.value = false + renderPreview() + bubbleNow() + emit('save', text.value) } diff --git a/src/components/tasks/partials/comments.vue b/src/components/tasks/partials/comments.vue index afaa37f2..95814a96 100644 --- a/src/components/tasks/partials/comments.vue +++ b/src/components/tasks/partials/comments.vue @@ -74,9 +74,13 @@ @update:model-value=" () => { toggleEdit(c) - editComment() + editCommentWithDelay() } " + @save="() => { + toggleEdit(c) + editComment() + }" :bottom-actions="actions[c.id]" :show-save="true" /> @@ -279,10 +283,26 @@ function toggleDelete(commentId: ITaskComment['id']) { commentToDelete.id = commentId } +const changeTimeout = ref | null>(null) + +async function editCommentWithDelay() { + if (changeTimeout.value !== null) { + clearTimeout(changeTimeout.value) + } + + changeTimeout.value = setTimeout(async () => { + await editComment() + }, 5000) +} + async function editComment() { if (commentEdit.comment === '') { return } + + if (changeTimeout.value !== null) { + clearTimeout(changeTimeout.value) + } saving.value = commentEdit.id diff --git a/src/components/tasks/partials/description.vue b/src/components/tasks/partials/description.vue index 4f73cdf8..c1ceedcb 100644 --- a/src/components/tasks/partials/description.vue +++ b/src/components/tasks/partials/description.vue @@ -25,7 +25,8 @@ :show-save="true" edit-shortcut="e" v-model="task.description" - @update:model-value="save" + @update:model-value="saveWithDelay" + @save="save" /> @@ -40,7 +41,6 @@ import type {ITask} from '@/modelTypes/ITask' import {useTaskStore} from '@/stores/tasks' import TaskModel from '@/models/task' - const props = defineProps({ modelValue: { type: Object as PropType, @@ -74,7 +74,23 @@ watch( {immediate: true}, ) +const changeTimeout = ref | null>(null) + +async function saveWithDelay() { + if (changeTimeout.value !== null) { + clearTimeout(changeTimeout.value) + } + + changeTimeout.value = setTimeout(async () => { + await save() + }, 5000) +} + async function save() { + if (changeTimeout.value !== null) { + clearTimeout(changeTimeout.value) + } + saving.value = true try {