@tldraw/editor 3.7.0-canary.bbc8eb37ddd6 → 3.7.0-canary.c01564bb95bb
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-cjs/index.d.ts +3 -1
- package/dist-cjs/index.js +2 -1
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/TldrawEditor.js +1 -1
- package/dist-cjs/lib/TldrawEditor.js.map +2 -2
- package/dist-cjs/lib/components/LiveCollaborators.js +2 -1
- package/dist-cjs/lib/components/LiveCollaborators.js.map +2 -2
- package/dist-cjs/lib/components/Shape.js +6 -4
- package/dist-cjs/lib/components/Shape.js.map +2 -2
- package/dist-cjs/lib/editor/Editor.js +8 -2
- package/dist-cjs/lib/editor/Editor.js.map +2 -2
- package/dist-cjs/lib/editor/managers/TextManager.js +9 -15
- package/dist-cjs/lib/editor/managers/TextManager.js.map +2 -2
- package/dist-cjs/lib/exports/FontEmbedder.js +2 -1
- package/dist-cjs/lib/exports/FontEmbedder.js.map +2 -2
- package/dist-cjs/lib/hooks/useEvent.js +18 -1
- package/dist-cjs/lib/hooks/useEvent.js.map +2 -2
- package/dist-cjs/version.js +3 -3
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.d.mts +3 -1
- package/dist-esm/index.mjs +3 -2
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/TldrawEditor.mjs +1 -1
- package/dist-esm/lib/TldrawEditor.mjs.map +2 -2
- package/dist-esm/lib/components/LiveCollaborators.mjs +2 -1
- package/dist-esm/lib/components/LiveCollaborators.mjs.map +2 -2
- package/dist-esm/lib/components/Shape.mjs +6 -4
- package/dist-esm/lib/components/Shape.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +9 -2
- package/dist-esm/lib/editor/Editor.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/TextManager.mjs +9 -15
- package/dist-esm/lib/editor/managers/TextManager.mjs.map +2 -2
- package/dist-esm/lib/exports/FontEmbedder.mjs +2 -1
- package/dist-esm/lib/exports/FontEmbedder.mjs.map +2 -2
- package/dist-esm/lib/hooks/useEvent.mjs +18 -1
- package/dist-esm/lib/hooks/useEvent.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/package.json +7 -7
- package/src/index.ts +1 -1
- package/src/lib/TldrawEditor.tsx +1 -1
- package/src/lib/components/LiveCollaborators.tsx +3 -1
- package/src/lib/components/Shape.tsx +22 -10
- package/src/lib/editor/Editor.ts +12 -5
- package/src/lib/editor/managers/TextManager.ts +9 -17
- package/src/lib/exports/FontEmbedder.ts +2 -1
- package/src/lib/hooks/useEvent.tsx +29 -0
- package/src/version.ts +3 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/components/LiveCollaborators.tsx"],
|
|
4
|
-
"sourcesContent": ["import { track } from '@tldraw/state-react'\nimport { TLInstancePresence } from '@tldraw/tlschema'\nimport { useEffect, useRef, useState } from 'react'\nimport { Editor } from '../editor/Editor'\nimport { useEditor } from '../hooks/useEditor'\nimport { useEditorComponents } from '../hooks/useEditorComponents'\nimport { usePeerIds } from '../hooks/usePeerIds'\nimport { usePresence } from '../hooks/usePresence'\n\nexport const LiveCollaborators = track(function Collaborators() {\n\tconst peerIds = usePeerIds()\n\treturn peerIds.map((id) => <CollaboratorGuard key={id} collaboratorId={id} />)\n})\n\nconst CollaboratorGuard = track(function CollaboratorGuard({\n\tcollaboratorId,\n}: {\n\tcollaboratorId: string\n}) {\n\tconst editor = useEditor()\n\tconst presence = usePresence(collaboratorId)\n\tconst collaboratorState = useCollaboratorState(editor, presence)\n\n\tif (!(presence && presence.currentPageId === editor.getCurrentPageId())) {\n\t\t// No need to render if we don't have a presence or if they're on a different page\n\t\treturn null\n\t}\n\n\tswitch (collaboratorState) {\n\t\tcase 'inactive': {\n\t\t\tconst { followingUserId, highlightedUserIds } = editor.getInstanceState()\n\t\t\t// If they're inactive and unless we're following them or they're highlighted, hide them\n\t\t\tif (!(followingUserId === presence.userId || highlightedUserIds.includes(presence.userId))) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tcase 'idle': {\n\t\t\tconst { highlightedUserIds } = editor.getInstanceState()\n\t\t\t// If they're idle and following us and unless they have a chat message or are highlighted, hide them\n\t\t\tif (\n\t\t\t\tpresence.followingUserId === editor.user.getId() &&\n\t\t\t\t!(presence.chatMessage || highlightedUserIds.includes(presence.userId))\n\t\t\t) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tcase 'active': {\n\t\t\t// If they're active, show them\n\t\t\tbreak\n\t\t}\n\t}\n\n\treturn <Collaborator latestPresence={presence} />\n})\n\nconst Collaborator = track(function Collaborator({\n\tlatestPresence,\n}: {\n\tlatestPresence: TLInstancePresence\n}) {\n\tconst editor = useEditor()\n\n\tconst {\n\t\tCollaboratorBrush,\n\t\tCollaboratorScribble,\n\t\tCollaboratorCursor,\n\t\tCollaboratorHint,\n\t\tCollaboratorShapeIndicator,\n\t} = useEditorComponents()\n\n\tconst zoomLevel = editor.getZoomLevel()\n\tconst viewportPageBounds = editor.getViewportPageBounds()\n\tconst { userId, chatMessage, brush, scribbles, selectedShapeIds, userName, cursor, color } =\n\t\tlatestPresence\n\n\t// Add a little padding to the top-left of the viewport\n\t// so that the cursor doesn't get cut off\n\tconst isCursorInViewport = !(\n\t\tcursor.x < viewportPageBounds.minX - 12 / zoomLevel ||\n\t\tcursor.y < viewportPageBounds.minY - 16 / zoomLevel ||\n\t\tcursor.x > viewportPageBounds.maxX - 12 / zoomLevel ||\n\t\tcursor.y > viewportPageBounds.maxY - 16 / zoomLevel\n\t)\n\n\treturn (\n\t\t<>\n\t\t\t{brush && CollaboratorBrush ? (\n\t\t\t\t<CollaboratorBrush\n\t\t\t\t\tclassName=\"tl-collaborator__brush\"\n\t\t\t\t\tkey={userId + '_brush'}\n\t\t\t\t\tbrush={brush}\n\t\t\t\t\tcolor={color}\n\t\t\t\t\topacity={0.1}\n\t\t\t\t/>\n\t\t\t) : null}\n\t\t\t{isCursorInViewport && CollaboratorCursor ? (\n\t\t\t\t<CollaboratorCursor\n\t\t\t\t\tclassName=\"tl-collaborator__cursor\"\n\t\t\t\t\tkey={userId + '_cursor'}\n\t\t\t\t\tpoint={cursor}\n\t\t\t\t\tcolor={color}\n\t\t\t\t\tzoom={zoomLevel}\n\t\t\t\t\tname={userName !== 'New User' ? userName : null}\n\t\t\t\t\tchatMessage={chatMessage ?? ''}\n\t\t\t\t/>\n\t\t\t) : CollaboratorHint ? (\n\t\t\t\t<CollaboratorHint\n\t\t\t\t\tclassName=\"tl-collaborator__cursor-hint\"\n\t\t\t\t\tkey={userId + '_cursor_hint'}\n\t\t\t\t\tpoint={cursor}\n\t\t\t\t\tcolor={color}\n\t\t\t\t\tzoom={zoomLevel}\n\t\t\t\t\tviewport={viewportPageBounds}\n\t\t\t\t/>\n\t\t\t) : null}\n\t\t\t{CollaboratorScribble && scribbles.length ? (\n\t\t\t\t<>\n\t\t\t\t\t{scribbles.map((scribble) => (\n\t\t\t\t\t\t<CollaboratorScribble\n\t\t\t\t\t\t\tkey={userId + '_scribble_' + scribble.id}\n\t\t\t\t\t\t\tclassName=\"tl-collaborator__scribble\"\n\t\t\t\t\t\t\tscribble={scribble}\n\t\t\t\t\t\t\tcolor={color}\n\t\t\t\t\t\t\tzoom={zoomLevel}\n\t\t\t\t\t\t\topacity={scribble.color === 'laser' ? 0.5 : 0.1}\n\t\t\t\t\t\t/>\n\t\t\t\t\t))}\n\t\t\t\t</>\n\t\t\t) : null}\n\t\t\t{CollaboratorShapeIndicator &&\n\t\t\t\tselectedShapeIds\n\t\t\t\t\t.filter((id) => !editor.isShapeHidden(id))\n\t\t\t\t\t.map((shapeId) => (\n\t\t\t\t\t\t<CollaboratorShapeIndicator\n\t\t\t\t\t\t\tclassName=\"tl-collaborator__shape-indicator\"\n\t\t\t\t\t\t\tkey={userId + '_' + shapeId}\n\t\t\t\t\t\t\tshapeId={shapeId}\n\t\t\t\t\t\t\tcolor={color}\n\t\t\t\t\t\t\topacity={0.5}\n\t\t\t\t\t\t/>\n\t\t\t\t\t))}\n\t\t</>\n\t)\n})\n\nfunction getStateFromElapsedTime(editor: Editor, elapsed: number) {\n\treturn elapsed > editor.options.collaboratorInactiveTimeoutMs\n\t\t? 'inactive'\n\t\t: elapsed > editor.options.collaboratorIdleTimeoutMs\n\t\t\t? 'idle'\n\t\t\t: 'active'\n}\n\nfunction useCollaboratorState(editor: Editor, latestPresence: TLInstancePresence | null) {\n\tconst rLastActivityTimestamp = useRef(latestPresence?.lastActivityTimestamp ?? -1)\n\n\tconst [state, setState] = useState<'active' | 'idle' | 'inactive'>(() =>\n\t\tgetStateFromElapsedTime(editor, Date.now() - rLastActivityTimestamp.current)\n\t)\n\n\tuseEffect(() => {\n\t\tconst interval = editor.timers.setInterval(() => {\n\t\t\tsetState(getStateFromElapsedTime(editor, Date.now() - rLastActivityTimestamp.current))\n\t\t}, editor.options.collaboratorCheckIntervalMs)\n\n\t\treturn () => clearInterval(interval)\n\t}, [editor])\n\n\tif (latestPresence) {\n\t\t// We can do this on every render, it's free and cheaper than an effect\n\t\t// remember, there can be lots and lots of cursors moving around all the time\n\t\trLastActivityTimestamp.current = latestPresence.lastActivityTimestamp\n\t}\n\n\treturn state\n}\n"],
|
|
5
|
-
"mappings": "AAW4B,
|
|
4
|
+
"sourcesContent": ["import { track } from '@tldraw/state-react'\nimport { TLInstancePresence } from '@tldraw/tlschema'\nimport { useEffect, useRef, useState } from 'react'\nimport { Editor } from '../editor/Editor'\nimport { useEditor } from '../hooks/useEditor'\nimport { useEditorComponents } from '../hooks/useEditorComponents'\nimport { usePeerIds } from '../hooks/usePeerIds'\nimport { usePresence } from '../hooks/usePresence'\n\nexport const LiveCollaborators = track(function Collaborators() {\n\tconst peerIds = usePeerIds()\n\treturn peerIds.map((id) => <CollaboratorGuard key={id} collaboratorId={id} />)\n})\n\nconst CollaboratorGuard = track(function CollaboratorGuard({\n\tcollaboratorId,\n}: {\n\tcollaboratorId: string\n}) {\n\tconst editor = useEditor()\n\tconst presence = usePresence(collaboratorId)\n\tconst collaboratorState = useCollaboratorState(editor, presence)\n\n\tif (!(presence && presence.currentPageId === editor.getCurrentPageId())) {\n\t\t// No need to render if we don't have a presence or if they're on a different page\n\t\treturn null\n\t}\n\n\tswitch (collaboratorState) {\n\t\tcase 'inactive': {\n\t\t\tconst { followingUserId, highlightedUserIds } = editor.getInstanceState()\n\t\t\t// If they're inactive and unless we're following them or they're highlighted, hide them\n\t\t\tif (!(followingUserId === presence.userId || highlightedUserIds.includes(presence.userId))) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tcase 'idle': {\n\t\t\tconst { highlightedUserIds } = editor.getInstanceState()\n\t\t\t// If they're idle and following us and unless they have a chat message or are highlighted, hide them\n\t\t\tif (\n\t\t\t\tpresence.followingUserId === editor.user.getId() &&\n\t\t\t\t!(presence.chatMessage || highlightedUserIds.includes(presence.userId))\n\t\t\t) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tcase 'active': {\n\t\t\t// If they're active, show them\n\t\t\tbreak\n\t\t}\n\t}\n\n\treturn <Collaborator latestPresence={presence} />\n})\n\nconst Collaborator = track(function Collaborator({\n\tlatestPresence,\n}: {\n\tlatestPresence: TLInstancePresence\n}) {\n\tconst editor = useEditor()\n\n\tconst {\n\t\tCollaboratorBrush,\n\t\tCollaboratorScribble,\n\t\tCollaboratorCursor,\n\t\tCollaboratorHint,\n\t\tCollaboratorShapeIndicator,\n\t} = useEditorComponents()\n\n\tconst zoomLevel = editor.getZoomLevel()\n\tconst viewportPageBounds = editor.getViewportPageBounds()\n\tconst { userId, chatMessage, brush, scribbles, selectedShapeIds, userName, cursor, color } =\n\t\tlatestPresence\n\n\tif (!cursor) return null\n\n\t// Add a little padding to the top-left of the viewport\n\t// so that the cursor doesn't get cut off\n\tconst isCursorInViewport = !(\n\t\tcursor.x < viewportPageBounds.minX - 12 / zoomLevel ||\n\t\tcursor.y < viewportPageBounds.minY - 16 / zoomLevel ||\n\t\tcursor.x > viewportPageBounds.maxX - 12 / zoomLevel ||\n\t\tcursor.y > viewportPageBounds.maxY - 16 / zoomLevel\n\t)\n\n\treturn (\n\t\t<>\n\t\t\t{brush && CollaboratorBrush ? (\n\t\t\t\t<CollaboratorBrush\n\t\t\t\t\tclassName=\"tl-collaborator__brush\"\n\t\t\t\t\tkey={userId + '_brush'}\n\t\t\t\t\tbrush={brush}\n\t\t\t\t\tcolor={color}\n\t\t\t\t\topacity={0.1}\n\t\t\t\t/>\n\t\t\t) : null}\n\t\t\t{isCursorInViewport && CollaboratorCursor ? (\n\t\t\t\t<CollaboratorCursor\n\t\t\t\t\tclassName=\"tl-collaborator__cursor\"\n\t\t\t\t\tkey={userId + '_cursor'}\n\t\t\t\t\tpoint={cursor}\n\t\t\t\t\tcolor={color}\n\t\t\t\t\tzoom={zoomLevel}\n\t\t\t\t\tname={userName !== 'New User' ? userName : null}\n\t\t\t\t\tchatMessage={chatMessage ?? ''}\n\t\t\t\t/>\n\t\t\t) : CollaboratorHint ? (\n\t\t\t\t<CollaboratorHint\n\t\t\t\t\tclassName=\"tl-collaborator__cursor-hint\"\n\t\t\t\t\tkey={userId + '_cursor_hint'}\n\t\t\t\t\tpoint={cursor}\n\t\t\t\t\tcolor={color}\n\t\t\t\t\tzoom={zoomLevel}\n\t\t\t\t\tviewport={viewportPageBounds}\n\t\t\t\t/>\n\t\t\t) : null}\n\t\t\t{CollaboratorScribble && scribbles.length ? (\n\t\t\t\t<>\n\t\t\t\t\t{scribbles.map((scribble) => (\n\t\t\t\t\t\t<CollaboratorScribble\n\t\t\t\t\t\t\tkey={userId + '_scribble_' + scribble.id}\n\t\t\t\t\t\t\tclassName=\"tl-collaborator__scribble\"\n\t\t\t\t\t\t\tscribble={scribble}\n\t\t\t\t\t\t\tcolor={color}\n\t\t\t\t\t\t\tzoom={zoomLevel}\n\t\t\t\t\t\t\topacity={scribble.color === 'laser' ? 0.5 : 0.1}\n\t\t\t\t\t\t/>\n\t\t\t\t\t))}\n\t\t\t\t</>\n\t\t\t) : null}\n\t\t\t{CollaboratorShapeIndicator &&\n\t\t\t\tselectedShapeIds\n\t\t\t\t\t.filter((id) => !editor.isShapeHidden(id))\n\t\t\t\t\t.map((shapeId) => (\n\t\t\t\t\t\t<CollaboratorShapeIndicator\n\t\t\t\t\t\t\tclassName=\"tl-collaborator__shape-indicator\"\n\t\t\t\t\t\t\tkey={userId + '_' + shapeId}\n\t\t\t\t\t\t\tshapeId={shapeId}\n\t\t\t\t\t\t\tcolor={color}\n\t\t\t\t\t\t\topacity={0.5}\n\t\t\t\t\t\t/>\n\t\t\t\t\t))}\n\t\t</>\n\t)\n})\n\nfunction getStateFromElapsedTime(editor: Editor, elapsed: number) {\n\treturn elapsed > editor.options.collaboratorInactiveTimeoutMs\n\t\t? 'inactive'\n\t\t: elapsed > editor.options.collaboratorIdleTimeoutMs\n\t\t\t? 'idle'\n\t\t\t: 'active'\n}\n\nfunction useCollaboratorState(editor: Editor, latestPresence: TLInstancePresence | null) {\n\tconst rLastActivityTimestamp = useRef(latestPresence?.lastActivityTimestamp ?? -1)\n\n\tconst [state, setState] = useState<'active' | 'idle' | 'inactive'>(() =>\n\t\tgetStateFromElapsedTime(editor, Date.now() - rLastActivityTimestamp.current)\n\t)\n\n\tuseEffect(() => {\n\t\tconst interval = editor.timers.setInterval(() => {\n\t\t\tsetState(getStateFromElapsedTime(editor, Date.now() - rLastActivityTimestamp.current))\n\t\t}, editor.options.collaboratorCheckIntervalMs)\n\n\t\treturn () => clearInterval(interval)\n\t}, [editor])\n\n\tif (latestPresence) {\n\t\t// We can do this on every render, it's free and cheaper than an effect\n\t\t// remember, there can be lots and lots of cursors moving around all the time\n\t\trLastActivityTimestamp.current = latestPresence.lastActivityTimestamp ?? Infinity\n\t}\n\n\treturn state\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["CollaboratorGuard", "Collaborator"]
|
|
7
7
|
}
|
|
@@ -127,10 +127,11 @@ const InnerShape = memo(
|
|
|
127
127
|
// always fetch the latest shape from the store even if the props/meta have not changed, to avoid
|
|
128
128
|
// calling the render method with stale data.
|
|
129
129
|
(util.component(util.editor.store.unsafeGetWithoutCapture(shape.id)))
|
|
130
|
-
)
|
|
130
|
+
),
|
|
131
|
+
[util, shape.id]
|
|
131
132
|
);
|
|
132
133
|
},
|
|
133
|
-
(prev, next) => prev.shape.props === next.shape.props && prev.shape.meta === next.shape.meta
|
|
134
|
+
(prev, next) => prev.shape.props === next.shape.props && prev.shape.meta === next.shape.meta && prev.util === next.util
|
|
134
135
|
);
|
|
135
136
|
const InnerShapeBackground = memo(
|
|
136
137
|
function InnerShapeBackground2({
|
|
@@ -143,10 +144,11 @@ const InnerShapeBackground = memo(
|
|
|
143
144
|
// always fetch the latest shape from the store even if the props/meta have not changed, to avoid
|
|
144
145
|
// calling the render method with stale data.
|
|
145
146
|
(util.backgroundComponent?.(util.editor.store.unsafeGetWithoutCapture(shape.id)))
|
|
146
|
-
)
|
|
147
|
+
),
|
|
148
|
+
[util, shape.id]
|
|
147
149
|
);
|
|
148
150
|
},
|
|
149
|
-
(prev, next) => prev.shape.props === next.shape.props && prev.shape.meta === next.shape.meta
|
|
151
|
+
(prev, next) => prev.shape.props === next.shape.props && prev.shape.meta === next.shape.meta && prev.util === next.util
|
|
150
152
|
);
|
|
151
153
|
export {
|
|
152
154
|
InnerShape,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/components/Shape.tsx"],
|
|
4
|
-
"sourcesContent": ["import { useQuickReactor, useStateTracking } from '@tldraw/state-react'\nimport { TLShape, TLShapeId } from '@tldraw/tlschema'\nimport { memo, useCallback, useRef } from 'react'\nimport { ShapeUtil } from '../editor/shapes/ShapeUtil'\nimport { useEditor } from '../hooks/useEditor'\nimport { useEditorComponents } from '../hooks/useEditorComponents'\nimport { Mat } from '../primitives/Mat'\nimport { setStyleProperty } from '../utils/dom'\nimport { OptionalErrorBoundary } from './ErrorBoundary'\n\n/*\nThis component renders shapes on the canvas. There are two stages: positioning\nand styling the shape's container using CSS, and then rendering the shape's \nJSX using its shape util's render method. Rendering the \"inside\" of a shape is\nmore expensive than positioning it or changing its color, so we use memo\nto wrap the inner shape and only re-render it when the shape's props change. \n\nThe shape also receives props for its index and opacity. The index is used to\ndetermine the z-index of the shape, and the opacity is used to set the shape's\nopacity based on its own opacity and that of its parent's.\n*/\nexport const Shape = memo(function Shape({\n\tid,\n\tshape,\n\tutil,\n\tindex,\n\tbackgroundIndex,\n\topacity,\n}: {\n\tid: TLShapeId\n\tshape: TLShape\n\tutil: ShapeUtil\n\tindex: number\n\tbackgroundIndex: number\n\topacity: number\n}) {\n\tconst editor = useEditor()\n\n\tconst { ShapeErrorFallback } = useEditorComponents()\n\n\tconst containerRef = useRef<HTMLDivElement>(null)\n\tconst bgContainerRef = useRef<HTMLDivElement>(null)\n\n\tconst memoizedStuffRef = useRef({\n\t\ttransform: '',\n\t\tclipPath: 'none',\n\t\twidth: 0,\n\t\theight: 0,\n\t\tx: 0,\n\t\ty: 0,\n\t\tisCulled: false,\n\t})\n\n\tuseQuickReactor(\n\t\t'set shape stuff',\n\t\t() => {\n\t\t\tconst shape = editor.getShape(id)\n\t\t\tif (!shape) return // probably the shape was just deleted\n\n\t\t\tconst prev = memoizedStuffRef.current\n\n\t\t\t// Clip path\n\t\t\tconst clipPath = editor.getShapeClipPath(id) ?? 'none'\n\t\t\tif (clipPath !== prev.clipPath) {\n\t\t\t\tsetStyleProperty(containerRef.current, 'clip-path', clipPath)\n\t\t\t\tsetStyleProperty(bgContainerRef.current, 'clip-path', clipPath)\n\t\t\t\tprev.clipPath = clipPath\n\t\t\t}\n\n\t\t\t// Page transform\n\t\t\tconst pageTransform = editor.getShapePageTransform(id)\n\t\t\tconst transform = Mat.toCssString(pageTransform)\n\t\t\tconst bounds = editor.getShapeGeometry(shape).bounds\n\n\t\t\t// Update if the tranform has changed\n\t\t\tif (transform !== prev.transform) {\n\t\t\t\tsetStyleProperty(containerRef.current, 'transform', transform)\n\t\t\t\tsetStyleProperty(bgContainerRef.current, 'transform', transform)\n\t\t\t\tprev.transform = transform\n\t\t\t}\n\n\t\t\t// Width / Height\n\t\t\tconst width = Math.max(bounds.width, 1)\n\t\t\tconst height = Math.max(bounds.height, 1)\n\n\t\t\tif (width !== prev.width || height !== prev.height) {\n\t\t\t\tsetStyleProperty(containerRef.current, 'width', width + 'px')\n\t\t\t\tsetStyleProperty(containerRef.current, 'height', height + 'px')\n\t\t\t\tsetStyleProperty(bgContainerRef.current, 'width', width + 'px')\n\t\t\t\tsetStyleProperty(bgContainerRef.current, 'height', height + 'px')\n\t\t\t\tprev.width = width\n\t\t\t\tprev.height = height\n\t\t\t}\n\t\t},\n\t\t[editor]\n\t)\n\n\t// This stuff changes pretty infrequently, so we can change them together\n\tuseQuickReactor(\n\t\t'set opacity and z-index',\n\t\t() => {\n\t\t\tconst container = containerRef.current\n\t\t\tconst bgContainer = bgContainerRef.current\n\n\t\t\t// Opacity\n\t\t\tsetStyleProperty(container, 'opacity', opacity)\n\t\t\tsetStyleProperty(bgContainer, 'opacity', opacity)\n\n\t\t\t// Z-Index\n\t\t\tsetStyleProperty(container, 'z-index', index)\n\t\t\tsetStyleProperty(bgContainer, 'z-index', backgroundIndex)\n\t\t},\n\t\t[opacity, index, backgroundIndex]\n\t)\n\n\tuseQuickReactor(\n\t\t'set display',\n\t\t() => {\n\t\t\tconst shape = editor.getShape(id)\n\t\t\tif (!shape) return // probably the shape was just deleted\n\n\t\t\tconst culledShapes = editor.getCulledShapes()\n\t\t\tconst isCulled = culledShapes.has(id)\n\t\t\tif (isCulled !== memoizedStuffRef.current.isCulled) {\n\t\t\t\tsetStyleProperty(containerRef.current, 'display', isCulled ? 'none' : 'block')\n\t\t\t\tsetStyleProperty(bgContainerRef.current, 'display', isCulled ? 'none' : 'block')\n\t\t\t\tmemoizedStuffRef.current.isCulled = isCulled\n\t\t\t}\n\t\t},\n\t\t[editor]\n\t)\n\tconst annotateError = useCallback(\n\t\t(error: any) => editor.annotateError(error, { origin: 'shape', willCrashApp: false }),\n\t\t[editor]\n\t)\n\n\tif (!shape) return null\n\n\tconst isFilledShape = 'fill' in shape.props && shape.props.fill !== 'none'\n\n\treturn (\n\t\t<>\n\t\t\t{util.backgroundComponent && (\n\t\t\t\t<div\n\t\t\t\t\tref={bgContainerRef}\n\t\t\t\t\tclassName=\"tl-shape tl-shape-background\"\n\t\t\t\t\tdata-shape-type={shape.type}\n\t\t\t\t\tdata-shape-id={shape.id}\n\t\t\t\t\tdraggable={false}\n\t\t\t\t>\n\t\t\t\t\t<OptionalErrorBoundary fallback={ShapeErrorFallback} onError={annotateError}>\n\t\t\t\t\t\t<InnerShapeBackground shape={shape} util={util} />\n\t\t\t\t\t</OptionalErrorBoundary>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t<div\n\t\t\t\tref={containerRef}\n\t\t\t\tclassName=\"tl-shape\"\n\t\t\t\tdata-shape-type={shape.type}\n\t\t\t\tdata-shape-is-filled={isFilledShape}\n\t\t\t\tdata-shape-id={shape.id}\n\t\t\t\tdraggable={false}\n\t\t\t>\n\t\t\t\t<OptionalErrorBoundary fallback={ShapeErrorFallback as any} onError={annotateError}>\n\t\t\t\t\t<InnerShape shape={shape} util={util} />\n\t\t\t\t</OptionalErrorBoundary>\n\t\t\t</div>\n\t\t</>\n\t)\n})\n\nexport const InnerShape = memo(\n\tfunction InnerShape<T extends TLShape>({ shape, util }: { shape: T; util: ShapeUtil<T> }) {\n\t\treturn useStateTracking('InnerShape:' + shape.type
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import { useQuickReactor, useStateTracking } from '@tldraw/state-react'\nimport { TLShape, TLShapeId } from '@tldraw/tlschema'\nimport { memo, useCallback, useRef } from 'react'\nimport { ShapeUtil } from '../editor/shapes/ShapeUtil'\nimport { useEditor } from '../hooks/useEditor'\nimport { useEditorComponents } from '../hooks/useEditorComponents'\nimport { Mat } from '../primitives/Mat'\nimport { setStyleProperty } from '../utils/dom'\nimport { OptionalErrorBoundary } from './ErrorBoundary'\n\n/*\nThis component renders shapes on the canvas. There are two stages: positioning\nand styling the shape's container using CSS, and then rendering the shape's \nJSX using its shape util's render method. Rendering the \"inside\" of a shape is\nmore expensive than positioning it or changing its color, so we use memo\nto wrap the inner shape and only re-render it when the shape's props change. \n\nThe shape also receives props for its index and opacity. The index is used to\ndetermine the z-index of the shape, and the opacity is used to set the shape's\nopacity based on its own opacity and that of its parent's.\n*/\nexport const Shape = memo(function Shape({\n\tid,\n\tshape,\n\tutil,\n\tindex,\n\tbackgroundIndex,\n\topacity,\n}: {\n\tid: TLShapeId\n\tshape: TLShape\n\tutil: ShapeUtil\n\tindex: number\n\tbackgroundIndex: number\n\topacity: number\n}) {\n\tconst editor = useEditor()\n\n\tconst { ShapeErrorFallback } = useEditorComponents()\n\n\tconst containerRef = useRef<HTMLDivElement>(null)\n\tconst bgContainerRef = useRef<HTMLDivElement>(null)\n\n\tconst memoizedStuffRef = useRef({\n\t\ttransform: '',\n\t\tclipPath: 'none',\n\t\twidth: 0,\n\t\theight: 0,\n\t\tx: 0,\n\t\ty: 0,\n\t\tisCulled: false,\n\t})\n\n\tuseQuickReactor(\n\t\t'set shape stuff',\n\t\t() => {\n\t\t\tconst shape = editor.getShape(id)\n\t\t\tif (!shape) return // probably the shape was just deleted\n\n\t\t\tconst prev = memoizedStuffRef.current\n\n\t\t\t// Clip path\n\t\t\tconst clipPath = editor.getShapeClipPath(id) ?? 'none'\n\t\t\tif (clipPath !== prev.clipPath) {\n\t\t\t\tsetStyleProperty(containerRef.current, 'clip-path', clipPath)\n\t\t\t\tsetStyleProperty(bgContainerRef.current, 'clip-path', clipPath)\n\t\t\t\tprev.clipPath = clipPath\n\t\t\t}\n\n\t\t\t// Page transform\n\t\t\tconst pageTransform = editor.getShapePageTransform(id)\n\t\t\tconst transform = Mat.toCssString(pageTransform)\n\t\t\tconst bounds = editor.getShapeGeometry(shape).bounds\n\n\t\t\t// Update if the tranform has changed\n\t\t\tif (transform !== prev.transform) {\n\t\t\t\tsetStyleProperty(containerRef.current, 'transform', transform)\n\t\t\t\tsetStyleProperty(bgContainerRef.current, 'transform', transform)\n\t\t\t\tprev.transform = transform\n\t\t\t}\n\n\t\t\t// Width / Height\n\t\t\tconst width = Math.max(bounds.width, 1)\n\t\t\tconst height = Math.max(bounds.height, 1)\n\n\t\t\tif (width !== prev.width || height !== prev.height) {\n\t\t\t\tsetStyleProperty(containerRef.current, 'width', width + 'px')\n\t\t\t\tsetStyleProperty(containerRef.current, 'height', height + 'px')\n\t\t\t\tsetStyleProperty(bgContainerRef.current, 'width', width + 'px')\n\t\t\t\tsetStyleProperty(bgContainerRef.current, 'height', height + 'px')\n\t\t\t\tprev.width = width\n\t\t\t\tprev.height = height\n\t\t\t}\n\t\t},\n\t\t[editor]\n\t)\n\n\t// This stuff changes pretty infrequently, so we can change them together\n\tuseQuickReactor(\n\t\t'set opacity and z-index',\n\t\t() => {\n\t\t\tconst container = containerRef.current\n\t\t\tconst bgContainer = bgContainerRef.current\n\n\t\t\t// Opacity\n\t\t\tsetStyleProperty(container, 'opacity', opacity)\n\t\t\tsetStyleProperty(bgContainer, 'opacity', opacity)\n\n\t\t\t// Z-Index\n\t\t\tsetStyleProperty(container, 'z-index', index)\n\t\t\tsetStyleProperty(bgContainer, 'z-index', backgroundIndex)\n\t\t},\n\t\t[opacity, index, backgroundIndex]\n\t)\n\n\tuseQuickReactor(\n\t\t'set display',\n\t\t() => {\n\t\t\tconst shape = editor.getShape(id)\n\t\t\tif (!shape) return // probably the shape was just deleted\n\n\t\t\tconst culledShapes = editor.getCulledShapes()\n\t\t\tconst isCulled = culledShapes.has(id)\n\t\t\tif (isCulled !== memoizedStuffRef.current.isCulled) {\n\t\t\t\tsetStyleProperty(containerRef.current, 'display', isCulled ? 'none' : 'block')\n\t\t\t\tsetStyleProperty(bgContainerRef.current, 'display', isCulled ? 'none' : 'block')\n\t\t\t\tmemoizedStuffRef.current.isCulled = isCulled\n\t\t\t}\n\t\t},\n\t\t[editor]\n\t)\n\tconst annotateError = useCallback(\n\t\t(error: any) => editor.annotateError(error, { origin: 'shape', willCrashApp: false }),\n\t\t[editor]\n\t)\n\n\tif (!shape) return null\n\n\tconst isFilledShape = 'fill' in shape.props && shape.props.fill !== 'none'\n\n\treturn (\n\t\t<>\n\t\t\t{util.backgroundComponent && (\n\t\t\t\t<div\n\t\t\t\t\tref={bgContainerRef}\n\t\t\t\t\tclassName=\"tl-shape tl-shape-background\"\n\t\t\t\t\tdata-shape-type={shape.type}\n\t\t\t\t\tdata-shape-id={shape.id}\n\t\t\t\t\tdraggable={false}\n\t\t\t\t>\n\t\t\t\t\t<OptionalErrorBoundary fallback={ShapeErrorFallback} onError={annotateError}>\n\t\t\t\t\t\t<InnerShapeBackground shape={shape} util={util} />\n\t\t\t\t\t</OptionalErrorBoundary>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t<div\n\t\t\t\tref={containerRef}\n\t\t\t\tclassName=\"tl-shape\"\n\t\t\t\tdata-shape-type={shape.type}\n\t\t\t\tdata-shape-is-filled={isFilledShape}\n\t\t\t\tdata-shape-id={shape.id}\n\t\t\t\tdraggable={false}\n\t\t\t>\n\t\t\t\t<OptionalErrorBoundary fallback={ShapeErrorFallback as any} onError={annotateError}>\n\t\t\t\t\t<InnerShape shape={shape} util={util} />\n\t\t\t\t</OptionalErrorBoundary>\n\t\t\t</div>\n\t\t</>\n\t)\n})\n\nexport const InnerShape = memo(\n\tfunction InnerShape<T extends TLShape>({ shape, util }: { shape: T; util: ShapeUtil<T> }) {\n\t\treturn useStateTracking(\n\t\t\t'InnerShape:' + shape.type,\n\t\t\t() =>\n\t\t\t\t// always fetch the latest shape from the store even if the props/meta have not changed, to avoid\n\t\t\t\t// calling the render method with stale data.\n\t\t\t\tutil.component(util.editor.store.unsafeGetWithoutCapture(shape.id) as T),\n\t\t\t[util, shape.id]\n\t\t)\n\t},\n\t(prev, next) =>\n\t\tprev.shape.props === next.shape.props &&\n\t\tprev.shape.meta === next.shape.meta &&\n\t\tprev.util === next.util\n)\n\nexport const InnerShapeBackground = memo(\n\tfunction InnerShapeBackground<T extends TLShape>({\n\t\tshape,\n\t\tutil,\n\t}: {\n\t\tshape: T\n\t\tutil: ShapeUtil<T>\n\t}) {\n\t\treturn useStateTracking(\n\t\t\t'InnerShape:' + shape.type,\n\t\t\t() =>\n\t\t\t\t// always fetch the latest shape from the store even if the props/meta have not changed, to avoid\n\t\t\t\t// calling the render method with stale data.\n\t\t\t\tutil.backgroundComponent?.(util.editor.store.unsafeGetWithoutCapture(shape.id) as T),\n\t\t\t[util, shape.id]\n\t\t)\n\t},\n\t(prev, next) =>\n\t\tprev.shape.props === next.shape.props &&\n\t\tprev.shape.meta === next.shape.meta &&\n\t\tprev.util === next.util\n)\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["Shape", "shape", "InnerShape", "InnerShapeBackground"]
|
|
7
7
|
}
|
|
@@ -86,6 +86,7 @@ import {
|
|
|
86
86
|
hasOwnProperty,
|
|
87
87
|
last,
|
|
88
88
|
lerp,
|
|
89
|
+
maxBy,
|
|
89
90
|
sortById,
|
|
90
91
|
sortByIndex,
|
|
91
92
|
structuredClone,
|
|
@@ -1776,6 +1777,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
1776
1777
|
if (!followingUserId) return null;
|
|
1777
1778
|
const leaderPresence = this.getCollaborators().find((c) => c.userId === followingUserId);
|
|
1778
1779
|
if (!leaderPresence) return null;
|
|
1780
|
+
if (!leaderPresence.camera || !leaderPresence.screenBounds) return null;
|
|
1779
1781
|
const { w: lw, h: lh } = leaderPresence.screenBounds;
|
|
1780
1782
|
const { x: lx, y: ly, z: lz } = leaderPresence.camera;
|
|
1781
1783
|
const theirViewport = new Box(-lx, -ly, lw / lz, lh / lz);
|
|
@@ -2470,6 +2472,8 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
2470
2472
|
zoomToUser(userId, opts = { animation: { duration: 500 } }) {
|
|
2471
2473
|
const presence = this.getCollaborators().find((c) => c.userId === userId);
|
|
2472
2474
|
if (!presence) return this;
|
|
2475
|
+
const cursor = presence.cursor;
|
|
2476
|
+
if (!cursor) return this;
|
|
2473
2477
|
this.run(() => {
|
|
2474
2478
|
if (this.getInstanceState().followingUserId !== null) {
|
|
2475
2479
|
this.stopFollowingUser();
|
|
@@ -2481,7 +2485,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
2481
2485
|
if (opts && opts.animation && !isOnSamePage) {
|
|
2482
2486
|
opts.animation = void 0;
|
|
2483
2487
|
}
|
|
2484
|
-
this.centerOnPoint(
|
|
2488
|
+
this.centerOnPoint(cursor, opts);
|
|
2485
2489
|
const { highlightedUserIds } = this.getInstanceState();
|
|
2486
2490
|
this.updateInstanceState({ highlightedUserIds: [...highlightedUserIds, userId] });
|
|
2487
2491
|
this.timers.setTimeout(() => {
|
|
@@ -2638,7 +2642,10 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
2638
2642
|
if (!allPresenceRecords.length) return EMPTY_ARRAY;
|
|
2639
2643
|
const userIds = [...new Set(allPresenceRecords.map((c) => c.userId))].sort();
|
|
2640
2644
|
return userIds.map((id) => {
|
|
2641
|
-
const latestPresence =
|
|
2645
|
+
const latestPresence = maxBy(
|
|
2646
|
+
allPresenceRecords.filter((c) => c.userId === id),
|
|
2647
|
+
(p) => p.lastActivityTimestamp ?? 0
|
|
2648
|
+
);
|
|
2642
2649
|
return latestPresence;
|
|
2643
2650
|
});
|
|
2644
2651
|
}
|