Improved file dropzones
This commit is contained in:
@@ -30,18 +30,30 @@
|
||||
<PlusIcon class="w-5 h-5 text-foreground-2 rotate-45" />
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
<FormFileUploadZone
|
||||
v-if="modelValue.isExpanded && canPostComment"
|
||||
ref="threadContainer"
|
||||
class="sm:absolute w-full sm:w-[260px] bg-foundation dark:bg-foundation-2 border border-outline-2 sm:rounded-xl shadow-md"
|
||||
ref="uploadZone"
|
||||
v-slot="{ isDraggingFiles }"
|
||||
:size-limit="maxSizeInBytes"
|
||||
:accept="acceptValue"
|
||||
:disabled="isPostingNewThread"
|
||||
multiple
|
||||
@files-selected="onFilesSelected"
|
||||
>
|
||||
<div class="relative">
|
||||
<div
|
||||
ref="threadContainer"
|
||||
class="sm:absolute w-full sm:w-[260px] bg-foundation dark:bg-foundation-2 border sm:rounded-xl shadow-md"
|
||||
:class="
|
||||
isDraggingFiles ? 'border-dashed border-primary' : 'border-outline-2'
|
||||
"
|
||||
>
|
||||
<ViewerCommentsEditor
|
||||
ref="editor"
|
||||
v-model="commentValue"
|
||||
prompt="Add comment"
|
||||
max-height="300px"
|
||||
autofocus
|
||||
disable-drop-zone
|
||||
:disabled="isPostingNewThread"
|
||||
@submit="() => onSubmit()"
|
||||
@keydown="onKeyDownHandler"
|
||||
@@ -63,7 +75,7 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</FormFileUploadZone>
|
||||
</ViewerCommentsPortalOrDiv>
|
||||
</div>
|
||||
</div>
|
||||
@@ -84,6 +96,10 @@ import {
|
||||
import { useMixpanel } from '~~/lib/core/composables/mp'
|
||||
import { useThreadUtilities, useSelectionUtilities } from '~~/lib/viewer/composables/ui'
|
||||
import { useEmbed } from '~/lib/viewer/composables/setup/embed'
|
||||
import { useServerFileUploadLimit } from '~~/lib/common/composables/serverInfo'
|
||||
import { UniqueFileTypeSpecifier } from '~~/lib/core/helpers/file'
|
||||
import { acceptedFileExtensions } from '@speckle/shared/blobs'
|
||||
import type { UploadableFileItem } from '@speckle/ui-components'
|
||||
|
||||
const { isEnabled: isEmbedEnabled } = useEmbed()
|
||||
|
||||
@@ -101,12 +117,29 @@ const props = defineProps<{
|
||||
const { onKeyDownHandler, updateIsTyping, pauseAutomaticUpdates } =
|
||||
useIsTypingUpdateEmitter()
|
||||
const { closeAllThreads, open } = useThreadUtilities()
|
||||
const { maxSizeInBytes } = useServerFileUploadLimit()
|
||||
|
||||
const editor = ref(null as Nullable<{ openFilePicker: () => void }>)
|
||||
const editor = ref(
|
||||
null as Nullable<{
|
||||
openFilePicker: () => void
|
||||
onFilesSelected: (payload: { files: UploadableFileItem[] }) => void
|
||||
}>
|
||||
)
|
||||
const uploadZone = ref(null as Nullable<{ triggerPicker: () => void }>)
|
||||
const commentValue = ref<CommentEditorValue>({ doc: undefined, attachments: undefined })
|
||||
const threadContainer = ref(null as Nullable<HTMLElement>)
|
||||
const isPostingNewThread = ref(false)
|
||||
|
||||
const acceptValue = [
|
||||
UniqueFileTypeSpecifier.AnyImage,
|
||||
UniqueFileTypeSpecifier.AnyVideo,
|
||||
...acceptedFileExtensions.map((fileExtension) => `.${fileExtension}`)
|
||||
].join(',')
|
||||
|
||||
const onFilesSelected = (payload: { files: UploadableFileItem[] }) => {
|
||||
editor.value?.onFilesSelected(payload)
|
||||
}
|
||||
|
||||
// const { style } = useExpandedThreadResponsiveLocation({
|
||||
// threadContainer,
|
||||
// width: 320
|
||||
@@ -174,7 +207,7 @@ const onSubmit = (comment?: CommentEditorValue) => {
|
||||
}
|
||||
|
||||
const trackAttachAndOpenFilePicker = () => {
|
||||
editor.value?.openFilePicker()
|
||||
uploadZone.value?.triggerPicker()
|
||||
mp.track('Comment Action', { type: 'action', name: 'attach' })
|
||||
}
|
||||
|
||||
|
||||
@@ -1,32 +1,46 @@
|
||||
<!-- eslint-disable vuejs-accessibility/no-autofocus -->
|
||||
<template>
|
||||
<div class="w-full relative flex flex-col p-2 pt-1">
|
||||
<div class="border border-outline-2 rounded-lg dark:bg-foundation-2">
|
||||
<ViewerCommentsEditor
|
||||
ref="editor"
|
||||
v-model="commentValue"
|
||||
prompt="Add reply"
|
||||
autofocus
|
||||
@keydown="onKeyDownHandler"
|
||||
@submit="onSubmit"
|
||||
/>
|
||||
<div class="flex justify-between items-center p-1">
|
||||
<FormButton
|
||||
:icon-left="PaperClipIcon"
|
||||
:disabled="loading"
|
||||
color="subtle"
|
||||
hide-text
|
||||
class="!bg-foundation dark:!bg-foundation-2"
|
||||
@click="trackAttachAndOpenFilePicker()"
|
||||
/>
|
||||
<FormButton
|
||||
:icon-left="PaperAirplaneIcon"
|
||||
hide-text
|
||||
:disabled="loading"
|
||||
@click="onSubmit"
|
||||
<FormFileUploadZone
|
||||
ref="uploadZone"
|
||||
v-slot="{ isDraggingFiles }"
|
||||
:size-limit="maxSizeInBytes"
|
||||
:accept="acceptValue"
|
||||
:disabled="loading"
|
||||
multiple
|
||||
@files-selected="onFilesSelected"
|
||||
>
|
||||
<div
|
||||
class="border border-outline-2 rounded-lg dark:bg-foundation-2"
|
||||
:class="[isDraggingFiles && 'border-dashed border-primary']"
|
||||
>
|
||||
<ViewerCommentsEditor
|
||||
ref="editor"
|
||||
v-model="commentValue"
|
||||
prompt="Add reply"
|
||||
autofocus
|
||||
disable-drop-zone
|
||||
@keydown="onKeyDownHandler"
|
||||
@submit="onSubmit"
|
||||
/>
|
||||
<div class="flex justify-between items-center p-1">
|
||||
<FormButton
|
||||
:icon-left="PaperClipIcon"
|
||||
:disabled="loading"
|
||||
color="subtle"
|
||||
hide-text
|
||||
class="!bg-foundation dark:!bg-foundation-2"
|
||||
@click="trackAttachAndOpenFilePicker()"
|
||||
/>
|
||||
<FormButton
|
||||
:icon-left="PaperAirplaneIcon"
|
||||
hide-text
|
||||
:disabled="loading"
|
||||
@click="onSubmit"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</FormFileUploadZone>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
@@ -42,6 +56,10 @@ import {
|
||||
convertCommentEditorValueToInput,
|
||||
isValidCommentContentInput
|
||||
} from '~~/lib/viewer/helpers/comments'
|
||||
import { useServerFileUploadLimit } from '~~/lib/common/composables/serverInfo'
|
||||
import { UniqueFileTypeSpecifier } from '~~/lib/core/helpers/file'
|
||||
import { acceptedFileExtensions } from '@speckle/shared/blobs'
|
||||
import type { UploadableFileItem } from '@speckle/ui-components'
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: CommentBubbleModel
|
||||
@@ -54,15 +72,32 @@ const emit = defineEmits<{
|
||||
const createReply = useSubmitReply()
|
||||
const { onKeyDownHandler, updateIsTyping } = useIsTypingUpdateEmitter()
|
||||
const { projectId } = useInjectedViewerState()
|
||||
const { maxSizeInBytes } = useServerFileUploadLimit()
|
||||
|
||||
const loading = ref(false)
|
||||
const editor = ref(null as Nullable<{ openFilePicker: () => void }>)
|
||||
const editor = ref(
|
||||
null as Nullable<{
|
||||
openFilePicker: () => void
|
||||
onFilesSelected: (payload: { files: UploadableFileItem[] }) => void
|
||||
}>
|
||||
)
|
||||
const uploadZone = ref(null as Nullable<{ triggerPicker: () => void }>)
|
||||
const commentValue = ref<CommentEditorValue>({ doc: undefined, attachments: undefined })
|
||||
const threadId = computed(() => props.modelValue.id)
|
||||
|
||||
const acceptValue = [
|
||||
UniqueFileTypeSpecifier.AnyImage,
|
||||
UniqueFileTypeSpecifier.AnyVideo,
|
||||
...acceptedFileExtensions.map((fileExtension) => `.${fileExtension}`)
|
||||
].join(',')
|
||||
|
||||
const onFilesSelected = (payload: { files: UploadableFileItem[] }) => {
|
||||
editor.value?.onFilesSelected(payload)
|
||||
}
|
||||
|
||||
const mp = useMixpanel()
|
||||
const trackAttachAndOpenFilePicker = () => {
|
||||
editor.value?.openFilePicker()
|
||||
uploadZone.value?.triggerPicker()
|
||||
mp.track('Comment Action', { type: 'action', name: 'attach' })
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
v-slot="{ isDraggingFiles }"
|
||||
:size-limit="maxSizeInBytes"
|
||||
:accept="acceptValue"
|
||||
:disabled="disabled"
|
||||
:disabled="disabled || disableDropZone"
|
||||
multiple
|
||||
@files-selected="onFilesSelected"
|
||||
>
|
||||
@@ -14,7 +14,7 @@
|
||||
v-model="doc"
|
||||
:class="[
|
||||
'rounded-t-lg py-2.5 px-3 border-b border-outline-2 text-body-2xs min-h-[40px] flex',
|
||||
isDraggingFiles && 'border-dashed'
|
||||
isDraggingFiles && !disableDropZone && 'border-dashed'
|
||||
]"
|
||||
:autofocus="autofocus"
|
||||
:placeholder="prompt || 'Add comment'"
|
||||
@@ -58,6 +58,7 @@ const props = defineProps<{
|
||||
disabled?: boolean
|
||||
autofocus?: boolean
|
||||
prompt?: string
|
||||
disableDropZone?: boolean
|
||||
}>()
|
||||
|
||||
const {
|
||||
@@ -124,6 +125,7 @@ watch(
|
||||
)
|
||||
|
||||
defineExpose({
|
||||
openFilePicker
|
||||
openFilePicker,
|
||||
onFilesSelected
|
||||
})
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user