Compare commits
2 Commits
main
...
fix-descri
| Author | SHA1 | Date |
|---|---|---|
|
|
8d86f09b50 | |
|
|
f86be0adf0 |
|
|
@ -172,8 +172,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref, shallowReactive, computed, watch} from 'vue'
|
import {ref, shallowReactive, computed, watch, onMounted, onUnmounted} from 'vue'
|
||||||
import {useDropZone} from '@vueuse/core'
|
|
||||||
|
|
||||||
import User from '@/components/misc/User.vue'
|
import User from '@/components/misc/User.vue'
|
||||||
import ProgressBar from '@/components/misc/ProgressBar.vue'
|
import ProgressBar from '@/components/misc/ProgressBar.vue'
|
||||||
|
|
@ -227,6 +226,17 @@ function eventTargetsEditor(event: Event | null | undefined): boolean {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isFileDrag(event: DragEvent | null | undefined): boolean {
|
||||||
|
if (!event?.dataTransfer) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the drag contains files
|
||||||
|
// dataTransfer.types is a DOMStringList containing the types of data
|
||||||
|
// 'Files' indicates a file drag from the OS or another application
|
||||||
|
return Array.from(event.dataTransfer.types).includes('Files')
|
||||||
|
}
|
||||||
|
|
||||||
const taskStore = useTaskStore()
|
const taskStore = useTaskStore()
|
||||||
const {t} = useI18n({useScope: 'global'})
|
const {t} = useI18n({useScope: 'global'})
|
||||||
|
|
||||||
|
|
@ -239,67 +249,112 @@ const loading = computed(() => attachmentService.loading || taskStore.isLoading)
|
||||||
|
|
||||||
const isDraggingFiles = ref(false)
|
const isDraggingFiles = ref(false)
|
||||||
const isDragOverEditor = ref(false)
|
const isDragOverEditor = ref(false)
|
||||||
|
// Track drag depth to handle nested elements properly
|
||||||
|
const dragDepth = ref(0)
|
||||||
|
|
||||||
function resetDragState() {
|
function resetDragState() {
|
||||||
isDraggingFiles.value = false
|
isDraggingFiles.value = false
|
||||||
isDragOverEditor.value = false
|
isDragOverEditor.value = false
|
||||||
|
dragDepth.value = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
const {isOverDropZone} = useDropZone(document, {
|
function handleDragEnter(event: DragEvent) {
|
||||||
onEnter(files, event) {
|
// Only handle file drags - let text drags work natively
|
||||||
if (!props.editEnabled) {
|
if (!isFileDrag(event)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dragDepth.value++
|
||||||
|
|
||||||
|
if (dragDepth.value === 1) {
|
||||||
isDraggingFiles.value = true
|
isDraggingFiles.value = true
|
||||||
|
}
|
||||||
isDragOverEditor.value = eventTargetsEditor(event)
|
isDragOverEditor.value = eventTargetsEditor(event)
|
||||||
},
|
}
|
||||||
onOver(files, event) {
|
|
||||||
if (!props.editEnabled) {
|
function handleDragOver(event: DragEvent) {
|
||||||
|
// Only prevent default for file drags - this is the key fix!
|
||||||
|
// Not preventing default allows native text dragging to work
|
||||||
|
if (!isFileDrag(event)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event.preventDefault()
|
||||||
isDragOverEditor.value = eventTargetsEditor(event)
|
isDragOverEditor.value = eventTargetsEditor(event)
|
||||||
},
|
}
|
||||||
onLeave(files, event) {
|
|
||||||
if (!props.editEnabled) {
|
function handleDragLeave(event: DragEvent) {
|
||||||
|
if (!isFileDrag(event)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isOverDropZone.value) {
|
dragDepth.value--
|
||||||
|
|
||||||
|
if (dragDepth.value === 0) {
|
||||||
resetDragState()
|
resetDragState()
|
||||||
|
} else {
|
||||||
|
isDragOverEditor.value = eventTargetsEditor(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDrop(event: DragEvent) {
|
||||||
|
// Only handle file drops - let text drops work natively
|
||||||
|
if (!isFileDrag(event)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
isDragOverEditor.value = eventTargetsEditor(event)
|
event.preventDefault()
|
||||||
},
|
dragDepth.value = 0
|
||||||
onDrop(files, event) {
|
|
||||||
if (!props.editEnabled) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const dropOverEditor = eventTargetsEditor(event)
|
const dropOverEditor = eventTargetsEditor(event)
|
||||||
resetDragState()
|
resetDragState()
|
||||||
|
|
||||||
// Ignore drops over editor - let TipTap handle them
|
// Ignore drops over editor - let TipTap handle them
|
||||||
|
const files = event.dataTransfer?.files
|
||||||
if (dropOverEditor || !files || files.length === 0) {
|
if (dropOverEditor || !files || files.length === 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
uploadFilesToTask(files)
|
uploadFilesToTask(files)
|
||||||
},
|
}
|
||||||
|
|
||||||
|
function addDragListeners() {
|
||||||
|
document.addEventListener('dragenter', handleDragEnter)
|
||||||
|
document.addEventListener('dragover', handleDragOver)
|
||||||
|
document.addEventListener('dragleave', handleDragLeave)
|
||||||
|
document.addEventListener('drop', handleDrop)
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeDragListeners() {
|
||||||
|
document.removeEventListener('dragenter', handleDragEnter)
|
||||||
|
document.removeEventListener('dragover', handleDragOver)
|
||||||
|
document.removeEventListener('dragleave', handleDragLeave)
|
||||||
|
document.removeEventListener('drop', handleDrop)
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (props.editEnabled) {
|
||||||
|
addDragListeners()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
removeDragListeners()
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(() => props.editEnabled, (enabled) => {
|
||||||
|
if (enabled) {
|
||||||
|
addDragListeners()
|
||||||
|
} else {
|
||||||
|
removeDragListeners()
|
||||||
|
resetDragState()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const showDropzone = computed(() =>
|
const showDropzone = computed(() =>
|
||||||
props.editEnabled && isDraggingFiles.value && !isDragOverEditor.value,
|
props.editEnabled && isDraggingFiles.value && !isDragOverEditor.value,
|
||||||
)
|
)
|
||||||
|
|
||||||
watch(() => props.editEnabled, enabled => {
|
|
||||||
if (!enabled) {
|
|
||||||
resetDragState()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
function downloadAttachment(attachment: IAttachment) {
|
function downloadAttachment(attachment: IAttachment) {
|
||||||
attachmentService.download(attachment)
|
attachmentService.download(attachment)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue