diff --git a/packages/frontend-2/components/viewer/anchored-point/Thread.vue b/packages/frontend-2/components/viewer/anchored-point/Thread.vue
index 11d7836de..a855deec1 100644
--- a/packages/frontend-2/components/viewer/anchored-point/Thread.vue
+++ b/packages/frontend-2/components/viewer/anchored-point/Thread.vue
@@ -32,112 +32,121 @@
-
-
+
-
- {{ isTypingMessage }}
-
-
@@ -178,6 +187,7 @@ import {
StateApplyMode,
useApplySerializedState
} from '~~/lib/viewer/composables/serialization'
+import { useDisableGlobalTextSelection } from '~~/lib/common/composables/window'
const emit = defineEmits<{
(e: 'update:modelValue', v: CommentBubbleModel): void
@@ -203,6 +213,7 @@ const {
const { projectId } = useInjectedViewerState()
const canReply = useCheckViewerCommentingAccess()
+const { disableTextSelection } = useDisableGlobalTextSelection()
const markThreadViewed = useMarkThreadViewed()
const { usersTyping } = useViewerThreadTypingTracking(threadId)
@@ -248,28 +259,37 @@ const initialDragPosition = computed(() => {
})
const isDragged = ref(false)
-const { x, y } = useDraggable(threadContainer, {
+const { x, y, isDragging, position } = useDraggable(threadContainer, {
stopPropagation: true,
- handle, // note if linting error, this actually exists and is ok FFS
+ handle,
initialValue: initialDragPosition,
- onStart() {
+ onStart(_pos, event) {
+ // Only allow dragging by border
+ const target = event.target as HTMLElement
+ if (target !== handle.value) return false
+
+ // Reset pos, if starting dragging from scratch
+ if (!isDragged.value) position.value = { x: 0, y: 0 }
+
isDragged.value = true
- },
- onEnd() {
- // todo
}
})
const threadStyle = computed(() => {
if (!threadActivator.value) return props.modelValue.style
+
const activatorRect = threadActivator.value?.getBoundingClientRect()
- const xOffset = isDragged.value
- ? x.value
- : (props.modelValue.style.x as number) + activatorRect.width + 20
- const threadHeigth = threadContainer.value?.getBoundingClientRect().height || 0
- const yOffset = isDragged.value
- ? y.value
- : (props.modelValue.style.y as number) - threadHeigth / 2
+ const areDraggableCoordsInitialized = x.value && y.value
+ const xOffset =
+ isDragged.value && areDraggableCoordsInitialized
+ ? x.value
+ : (props.modelValue.style.x as number) + activatorRect.width + 20
+ const threadHeight = threadContainer.value?.getBoundingClientRect().height || 0
+ const yOffset =
+ isDragged.value && areDraggableCoordsInitialized
+ ? y.value
+ : (props.modelValue.style.y as number) - threadHeight / 2
+
const transition = isDragged.value ? 'none' : props.modelValue.style.transition
return {
...props.modelValue.style,
@@ -418,6 +438,13 @@ watch(
}
)
+watch(isDragging, (newVal, oldVal) => {
+ if (!!newVal === !!oldVal) return
+
+ // Disable text selection while dragging around
+ disableTextSelection.value = newVal
+})
+
onMounted(() => {
if (isExpanded.value) {
// update won't emit if thread was mounted already expanded, so we emit this to close any open thread editors
diff --git a/packages/frontend-2/lib/common/composables/window.ts b/packages/frontend-2/lib/common/composables/window.ts
index 388e3651f..2f9f3dd45 100644
--- a/packages/frontend-2/lib/common/composables/window.ts
+++ b/packages/frontend-2/lib/common/composables/window.ts
@@ -103,3 +103,21 @@ export function useResponsiveHorizontalDirectionCalculation(params: {
recalculateDirection
}
}
+
+export function useDisableGlobalTextSelection() {
+ const disableTextSelection = ref(false)
+
+ if (process.client) {
+ watch(disableTextSelection, (newVal, oldVal) => {
+ if (!!newVal === !!oldVal) return
+
+ if (newVal) {
+ document.body.classList.add('select-none')
+ } else {
+ document.body.classList.remove('select-none')
+ }
+ })
+ }
+
+ return { disableTextSelection }
+}