diff --git a/excalidraw-app/sentry.ts b/excalidraw-app/sentry.ts index 30b84f3f69..58e34bba53 100644 --- a/excalidraw-app/sentry.ts +++ b/excalidraw-app/sentry.ts @@ -1,3 +1,4 @@ +import { getFeatureFlag } from "@excalidraw/common"; import * as Sentry from "@sentry/browser"; import callsites from "callsites"; @@ -33,6 +34,7 @@ Sentry.init({ Sentry.captureConsoleIntegration({ levels: ["error"], }), + Sentry.featureFlagsIntegration(), ], beforeSend(event) { if (event.request?.url) { @@ -79,3 +81,14 @@ Sentry.init({ return event; }, }); + +const flagsIntegration = + Sentry.getClient()?.getIntegrationByName( + "FeatureFlags", + ); +if (flagsIntegration) { + flagsIntegration.addFeatureFlag( + "COMPLEX_BINDINGS", + getFeatureFlag("COMPLEX_BINDINGS"), + ); +} diff --git a/packages/element/src/binding.ts b/packages/element/src/binding.ts index a7a4d7ffb3..ce0d5fada9 100644 --- a/packages/element/src/binding.ts +++ b/packages/element/src/binding.ts @@ -631,6 +631,7 @@ const getBindingStrategyForDraggingBindingElementEndpoints_simple = ( ); } + const otherBinding = startDragged ? arrow.endBinding : arrow.startBinding; const localPoint = draggingPoints.get( startDragged ? startIdx : endIdx, )?.point; @@ -651,8 +652,31 @@ const getBindingStrategyForDraggingBindingElementEndpoints_simple = ( elementsMap, (e) => maxBindingGap_simple(e, e.width, e.height, appState.zoom), ); + const pointInElement = hit && isPointInElement(globalPoint, hit, elementsMap); + + // Handle outside-outside binding with the same element + if (otherBinding && otherBinding.elementId === hit?.id && !pointInElement) { + const [startFixedPoint, endFixedPoint] = getGlobalFixedPoints( + arrow, + elementsMap, + ); + + return { + start: { + mode: "inside", + element: hit, + focusPoint: startDragged ? globalPoint : startFixedPoint, + }, + end: { + mode: "inside", + element: hit, + focusPoint: endDragged ? globalPoint : endFixedPoint, + }, + }; + } + const current: BindingStrategy = hit - ? isPointInElement(globalPoint, hit, elementsMap) + ? pointInElement ? { mode: "inside", element: hit, diff --git a/packages/excalidraw/components/Settings/Settings.tsx b/packages/excalidraw/components/Settings/Settings.tsx index 1b37b9a099..ce12c5d6cb 100644 --- a/packages/excalidraw/components/Settings/Settings.tsx +++ b/packages/excalidraw/components/Settings/Settings.tsx @@ -1,6 +1,7 @@ import { useState } from "react"; import { getFeatureFlag, setFeatureFlag } from "@excalidraw/common"; +import * as Sentry from "@sentry/browser"; import { CheckboxItem } from "../CheckboxItem"; import { Dialog } from "../Dialog"; @@ -42,7 +43,17 @@ export const Settings = () => { category: DEFAULT_SETTINGS_CATEGORIES.experimental, flagKey: "COMPLEX_BINDINGS", getValue: () => getFeatureFlag("COMPLEX_BINDINGS"), - setValue: (value: boolean) => setFeatureFlag("COMPLEX_BINDINGS", value), + setValue: (value: boolean) => { + const flagsIntegration = + Sentry.getClient()?.getIntegrationByName( + "FeatureFlags", + ); + if (flagsIntegration) { + flagsIntegration.addFeatureFlag("COMPLEX_BINDINGS", value); + } + + setFeatureFlag("COMPLEX_BINDINGS", value); + }, }, ];