@tldraw/commenting 0.0.0-bootstrap → 5.3.0-canary.31036673d3f8
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/README.md +0 -2
- package/commenting.css +1139 -329
- package/dist-cjs/canvas/anchor-lifecycle.js +148 -0
- package/dist-cjs/canvas/anchor-lifecycle.js.map +7 -0
- package/dist-cjs/canvas/cluster-input.js +2 -2
- package/dist-cjs/canvas/cluster-input.js.map +2 -2
- package/dist-cjs/canvas/comment-body.js +1 -1
- package/dist-cjs/canvas/comment-body.js.map +2 -2
- package/dist-cjs/canvas/comment-drafts.js +54 -0
- package/dist-cjs/canvas/comment-drafts.js.map +7 -0
- package/dist-cjs/canvas/comment-mutations.js +123 -0
- package/dist-cjs/canvas/comment-mutations.js.map +7 -0
- package/dist-cjs/canvas/comment-reactions.js +163 -0
- package/dist-cjs/canvas/comment-reactions.js.map +7 -0
- package/dist-cjs/canvas/comment-render.js +5 -3
- package/dist-cjs/canvas/comment-render.js.map +2 -2
- package/dist-cjs/canvas/comment-store.js +19 -9
- package/dist-cjs/canvas/comment-store.js.map +2 -2
- package/dist-cjs/canvas/comment-tool.js +64 -14
- package/dist-cjs/canvas/comment-tool.js.map +2 -2
- package/dist-cjs/canvas/comments-filter-menu.js +20 -38
- package/dist-cjs/canvas/comments-filter-menu.js.map +2 -2
- package/dist-cjs/canvas/comments-overflow-menu.js +22 -27
- package/dist-cjs/canvas/comments-overflow-menu.js.map +2 -2
- package/dist-cjs/canvas/comments-overlay.js +429 -474
- package/dist-cjs/canvas/comments-overlay.js.map +2 -2
- package/dist-cjs/canvas/comments-sidebar.js +35 -32
- package/dist-cjs/canvas/comments-sidebar.js.map +2 -2
- package/dist-cjs/canvas/comments-visibility-toggle.js +65 -0
- package/dist-cjs/canvas/comments-visibility-toggle.js.map +7 -0
- package/dist-cjs/canvas/context.js +17 -0
- package/dist-cjs/canvas/context.js.map +7 -0
- package/dist-cjs/canvas/hooks.js +22 -3
- package/dist-cjs/canvas/hooks.js.map +2 -2
- package/dist-cjs/canvas/options.js +19 -2
- package/dist-cjs/canvas/options.js.map +2 -2
- package/dist-cjs/canvas/pin-stacking.js +56 -0
- package/dist-cjs/canvas/pin-stacking.js.map +7 -0
- package/dist-cjs/canvas/sidebar-filters.js +2 -2
- package/dist-cjs/canvas/sidebar-filters.js.map +2 -2
- package/dist-cjs/canvas/state.js +28 -14
- package/dist-cjs/canvas/state.js.map +2 -2
- package/dist-cjs/canvas/thread-preview.js +185 -0
- package/dist-cjs/canvas/thread-preview.js.map +7 -0
- package/dist-cjs/canvas/thread-stack.js +199 -0
- package/dist-cjs/canvas/thread-stack.js.map +7 -0
- package/dist-cjs/canvas/thread-state.js +67 -21
- package/dist-cjs/canvas/thread-state.js.map +2 -2
- package/dist-cjs/canvas/thread-view.js +397 -0
- package/dist-cjs/canvas/thread-view.js.map +7 -0
- package/dist-cjs/clustering/computeClusterTable.js +4 -4
- package/dist-cjs/clustering/computeClusterTable.js.map +2 -2
- package/dist-cjs/clustering/runtime.js +119 -7
- package/dist-cjs/clustering/runtime.js.map +2 -2
- package/dist-cjs/clustering/types.js.map +1 -1
- package/dist-cjs/index.d.ts +763 -333
- package/dist-cjs/index.js +46 -28
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/ui/byline.js +6 -4
- package/dist-cjs/ui/byline.js.map +2 -2
- package/dist-cjs/ui/comment-card.js +15 -8
- package/dist-cjs/ui/comment-card.js.map +2 -2
- package/dist-cjs/ui/comment-composer.js +137 -36
- package/dist-cjs/ui/comment-composer.js.map +2 -2
- package/dist-cjs/ui/comment-pin.js +24 -2
- package/dist-cjs/ui/comment-pin.js.map +2 -2
- package/dist-cjs/ui/comment-thread.js +9 -7
- package/dist-cjs/ui/comment-thread.js.map +2 -2
- package/dist-cjs/ui/comments-list.js +30 -18
- package/dist-cjs/ui/comments-list.js.map +2 -2
- package/dist-cjs/ui/count-badge.js +3 -2
- package/dist-cjs/ui/count-badge.js.map +2 -2
- package/dist-cjs/ui/emoji-picker.js +54 -0
- package/dist-cjs/ui/emoji-picker.js.map +7 -0
- package/dist-cjs/ui/empty-state.js +3 -3
- package/dist-cjs/ui/empty-state.js.map +2 -2
- package/dist-cjs/ui/format-time.js +4 -1
- package/dist-cjs/ui/format-time.js.map +2 -2
- package/dist-cjs/ui/reaction-picker.js +73 -0
- package/dist-cjs/ui/reaction-picker.js.map +7 -0
- package/dist-cjs/ui/reaction.js +59 -6
- package/dist-cjs/ui/reaction.js.map +2 -2
- package/dist-cjs/ui/reactions.js +20 -7
- package/dist-cjs/ui/reactions.js.map +2 -2
- package/dist-cjs/ui/{mention.js → reply-count.js} +9 -11
- package/dist-cjs/ui/reply-count.js.map +7 -0
- package/dist-cjs/ui/send-button.js +20 -1
- package/dist-cjs/ui/send-button.js.map +2 -2
- package/dist-cjs/ui/{comment-text.js → tooltip-button.js} +12 -9
- package/dist-cjs/ui/tooltip-button.js.map +7 -0
- package/dist-esm/canvas/anchor-lifecycle.mjs +128 -0
- package/dist-esm/canvas/anchor-lifecycle.mjs.map +7 -0
- package/dist-esm/canvas/cluster-input.mjs +2 -2
- package/dist-esm/canvas/cluster-input.mjs.map +2 -2
- package/dist-esm/canvas/comment-body.mjs +1 -1
- package/dist-esm/canvas/comment-body.mjs.map +2 -2
- package/dist-esm/canvas/comment-drafts.mjs +34 -0
- package/dist-esm/canvas/comment-drafts.mjs.map +7 -0
- package/dist-esm/canvas/comment-mutations.mjs +103 -0
- package/dist-esm/canvas/comment-mutations.mjs.map +7 -0
- package/dist-esm/canvas/comment-reactions.mjs +152 -0
- package/dist-esm/canvas/comment-reactions.mjs.map +7 -0
- package/dist-esm/canvas/comment-render.mjs +5 -3
- package/dist-esm/canvas/comment-render.mjs.map +2 -2
- package/dist-esm/canvas/comment-store.mjs +19 -9
- package/dist-esm/canvas/comment-store.mjs.map +2 -2
- package/dist-esm/canvas/comment-tool.mjs +67 -17
- package/dist-esm/canvas/comment-tool.mjs.map +2 -2
- package/dist-esm/canvas/comments-filter-menu.mjs +20 -38
- package/dist-esm/canvas/comments-filter-menu.mjs.map +2 -2
- package/dist-esm/canvas/comments-overflow-menu.mjs +23 -27
- package/dist-esm/canvas/comments-overflow-menu.mjs.map +2 -2
- package/dist-esm/canvas/comments-overlay.mjs +450 -479
- package/dist-esm/canvas/comments-overlay.mjs.map +3 -3
- package/dist-esm/canvas/comments-sidebar.mjs +38 -35
- package/dist-esm/canvas/comments-sidebar.mjs.map +2 -2
- package/dist-esm/canvas/comments-visibility-toggle.mjs +45 -0
- package/dist-esm/canvas/comments-visibility-toggle.mjs.map +7 -0
- package/dist-esm/canvas/context.mjs +1 -0
- package/dist-esm/canvas/context.mjs.map +7 -0
- package/dist-esm/canvas/hooks.mjs +28 -5
- package/dist-esm/canvas/hooks.mjs.map +2 -2
- package/dist-esm/canvas/options.mjs +21 -3
- package/dist-esm/canvas/options.mjs.map +2 -2
- package/dist-esm/canvas/pin-stacking.mjs +36 -0
- package/dist-esm/canvas/pin-stacking.mjs.map +7 -0
- package/dist-esm/canvas/sidebar-filters.mjs +2 -2
- package/dist-esm/canvas/sidebar-filters.mjs.map +2 -2
- package/dist-esm/canvas/state.mjs +29 -19
- package/dist-esm/canvas/state.mjs.map +2 -2
- package/dist-esm/canvas/thread-preview.mjs +170 -0
- package/dist-esm/canvas/thread-preview.mjs.map +7 -0
- package/dist-esm/canvas/thread-stack.mjs +190 -0
- package/dist-esm/canvas/thread-stack.mjs.map +7 -0
- package/dist-esm/canvas/thread-state.mjs +71 -22
- package/dist-esm/canvas/thread-state.mjs.map +2 -2
- package/dist-esm/canvas/thread-view.mjs +402 -0
- package/dist-esm/canvas/thread-view.mjs.map +7 -0
- package/dist-esm/clustering/computeClusterTable.mjs +4 -4
- package/dist-esm/clustering/computeClusterTable.mjs.map +2 -2
- package/dist-esm/clustering/runtime.mjs +119 -7
- package/dist-esm/clustering/runtime.mjs.map +2 -2
- package/dist-esm/index.d.mts +763 -333
- package/dist-esm/index.mjs +87 -41
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/ui/byline.mjs +6 -4
- package/dist-esm/ui/byline.mjs.map +2 -2
- package/dist-esm/ui/comment-card.mjs +15 -8
- package/dist-esm/ui/comment-card.mjs.map +2 -2
- package/dist-esm/ui/comment-composer.mjs +148 -36
- package/dist-esm/ui/comment-composer.mjs.map +2 -2
- package/dist-esm/ui/comment-pin.mjs +24 -2
- package/dist-esm/ui/comment-pin.mjs.map +2 -2
- package/dist-esm/ui/comment-thread.mjs +9 -7
- package/dist-esm/ui/comment-thread.mjs.map +2 -2
- package/dist-esm/ui/comments-list.mjs +43 -29
- package/dist-esm/ui/comments-list.mjs.map +2 -2
- package/dist-esm/ui/count-badge.mjs +3 -2
- package/dist-esm/ui/count-badge.mjs.map +2 -2
- package/dist-esm/ui/emoji-picker.mjs +34 -0
- package/dist-esm/ui/emoji-picker.mjs.map +7 -0
- package/dist-esm/ui/empty-state.mjs +3 -3
- package/dist-esm/ui/empty-state.mjs.map +2 -2
- package/dist-esm/ui/format-time.mjs +4 -1
- package/dist-esm/ui/format-time.mjs.map +2 -2
- package/dist-esm/ui/reaction-picker.mjs +60 -0
- package/dist-esm/ui/reaction-picker.mjs.map +7 -0
- package/dist-esm/ui/reaction.mjs +60 -7
- package/dist-esm/ui/reaction.mjs.map +2 -2
- package/dist-esm/ui/reactions.mjs +21 -8
- package/dist-esm/ui/reactions.mjs.map +2 -2
- package/dist-esm/ui/reply-count.mjs +9 -0
- package/dist-esm/ui/reply-count.mjs.map +7 -0
- package/dist-esm/ui/send-button.mjs +20 -1
- package/dist-esm/ui/send-button.mjs.map +2 -2
- package/dist-esm/ui/tooltip-button.mjs +12 -0
- package/dist-esm/ui/tooltip-button.mjs.map +7 -0
- package/package.json +6 -6
- package/src/canvas/anchor-lifecycle.test.ts +290 -0
- package/src/canvas/anchor-lifecycle.ts +205 -0
- package/src/canvas/canvas.css +461 -46
- package/src/canvas/cluster-input.test.ts +31 -23
- package/src/canvas/cluster-input.ts +3 -4
- package/src/canvas/comment-body.tsx +1 -1
- package/src/canvas/comment-drafts.test.ts +55 -0
- package/src/canvas/comment-drafts.ts +46 -0
- package/src/canvas/comment-mutations.test.ts +410 -0
- package/src/canvas/comment-mutations.ts +288 -0
- package/src/canvas/comment-reactions.test.ts +132 -0
- package/src/canvas/comment-reactions.tsx +245 -0
- package/src/canvas/comment-render.test.ts +1 -1
- package/src/canvas/comment-render.ts +9 -5
- package/src/canvas/comment-store.ts +67 -27
- package/src/canvas/comment-tool.test.ts +162 -0
- package/src/canvas/comment-tool.tsx +105 -23
- package/src/canvas/comments-filter-menu.tsx +23 -32
- package/src/canvas/comments-overflow-menu.tsx +14 -21
- package/src/canvas/comments-overlay.tsx +695 -622
- package/src/canvas/comments-sidebar.test.ts +45 -0
- package/src/canvas/comments-sidebar.tsx +76 -58
- package/src/canvas/comments-visibility-toggle.tsx +49 -0
- package/src/canvas/context.ts +47 -0
- package/src/canvas/hooks.ts +52 -11
- package/src/canvas/options.test.ts +52 -2
- package/src/canvas/options.ts +133 -9
- package/src/canvas/pin-stacking.test.ts +114 -0
- package/src/canvas/pin-stacking.ts +57 -0
- package/src/canvas/sidebar-filters.ts +4 -3
- package/src/canvas/state.ts +92 -35
- package/src/canvas/thread-preview.test.ts +91 -0
- package/src/canvas/thread-preview.tsx +304 -0
- package/src/canvas/thread-stack.tsx +252 -0
- package/src/canvas/thread-state.test.ts +209 -0
- package/src/canvas/thread-state.ts +137 -36
- package/src/canvas/thread-view.tsx +516 -0
- package/src/clustering/computeClusterTable.test.ts +24 -23
- package/src/clustering/computeClusterTable.ts +5 -5
- package/src/clustering/runtime.test.ts +217 -7
- package/src/clustering/runtime.ts +171 -17
- package/src/clustering/types.ts +9 -9
- package/src/index.ts +76 -40
- package/src/ui/byline.tsx +7 -5
- package/src/ui/comment-card.tsx +20 -10
- package/src/ui/comment-composer.tsx +206 -40
- package/src/ui/comment-pin.tsx +26 -2
- package/src/ui/comment-thread.tsx +13 -6
- package/src/ui/comments-list.test.ts +31 -0
- package/src/ui/comments-list.tsx +45 -21
- package/src/ui/comments.css +566 -281
- package/src/ui/count-badge.tsx +9 -2
- package/src/ui/emoji-picker.test.ts +25 -0
- package/src/ui/emoji-picker.tsx +76 -0
- package/src/ui/empty-state.tsx +3 -3
- package/src/ui/format-time.ts +7 -2
- package/src/ui/reaction-picker.tsx +109 -0
- package/src/ui/reaction.tsx +121 -6
- package/src/ui/reactions.tsx +69 -10
- package/src/ui/reply-count.ts +16 -0
- package/src/ui/send-button.tsx +18 -3
- package/src/ui/tooltip-button.tsx +20 -0
- package/dist-cjs/canvas/region-options.js +0 -49
- package/dist-cjs/canvas/region-options.js.map +0 -7
- package/dist-cjs/ui/avatar.js +0 -43
- package/dist-cjs/ui/avatar.js.map +0 -7
- package/dist-cjs/ui/comment-mention.js +0 -42
- package/dist-cjs/ui/comment-mention.js.map +0 -7
- package/dist-cjs/ui/comment-text.js.map +0 -7
- package/dist-cjs/ui/mention-list.js +0 -70
- package/dist-cjs/ui/mention-list.js.map +0 -7
- package/dist-cjs/ui/mention-suggestion.js +0 -206
- package/dist-cjs/ui/mention-suggestion.js.map +0 -7
- package/dist-cjs/ui/mention.js.map +0 -7
- package/dist-cjs/ui/render-markdown.js +0 -63
- package/dist-cjs/ui/render-markdown.js.map +0 -7
- package/dist-esm/canvas/region-options.mjs +0 -29
- package/dist-esm/canvas/region-options.mjs.map +0 -7
- package/dist-esm/ui/avatar.mjs +0 -23
- package/dist-esm/ui/avatar.mjs.map +0 -7
- package/dist-esm/ui/comment-mention.mjs +0 -22
- package/dist-esm/ui/comment-mention.mjs.map +0 -7
- package/dist-esm/ui/comment-text.mjs +0 -9
- package/dist-esm/ui/comment-text.mjs.map +0 -7
- package/dist-esm/ui/mention-list.mjs +0 -50
- package/dist-esm/ui/mention-list.mjs.map +0 -7
- package/dist-esm/ui/mention-suggestion.mjs +0 -186
- package/dist-esm/ui/mention-suggestion.mjs.map +0 -7
- package/dist-esm/ui/mention.mjs +0 -11
- package/dist-esm/ui/mention.mjs.map +0 -7
- package/dist-esm/ui/render-markdown.mjs +0 -45
- package/dist-esm/ui/render-markdown.mjs.map +0 -7
- package/src/canvas/region-options.ts +0 -57
- package/src/ui/avatar.tsx +0 -31
- package/src/ui/comment-mention.ts +0 -47
- package/src/ui/comment-text.tsx +0 -12
- package/src/ui/mention-list.tsx +0 -106
- package/src/ui/mention-suggestion.test.ts +0 -18
- package/src/ui/mention-suggestion.tsx +0 -285
- package/src/ui/mention.tsx +0 -9
- package/src/ui/render-markdown.tsx +0 -72
|
@@ -22,94 +22,98 @@ __export(comments_overlay_exports, {
|
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(comments_overlay_exports);
|
|
24
24
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
25
|
+
var import_mentions = require("@tldraw/mentions");
|
|
25
26
|
var import_react = require("react");
|
|
26
27
|
var import_react_dom = require("react-dom");
|
|
27
28
|
var import_tldraw = require("tldraw");
|
|
28
29
|
var import_computeClusterTable = require("../clustering/computeClusterTable");
|
|
29
30
|
var import_runtime = require("../clustering/runtime");
|
|
30
|
-
var import_comment_card = require("../ui/comment-card");
|
|
31
31
|
var import_comment_composer = require("../ui/comment-composer");
|
|
32
32
|
var import_comment_extensions = require("../ui/comment-extensions");
|
|
33
33
|
var import_comment_pin = require("../ui/comment-pin");
|
|
34
|
-
var import_comment_thread = require("../ui/comment-thread");
|
|
35
34
|
var import_count_badge = require("../ui/count-badge");
|
|
36
|
-
var
|
|
35
|
+
var import_anchor_lifecycle = require("./anchor-lifecycle");
|
|
37
36
|
var import_cluster_input = require("./cluster-input");
|
|
38
|
-
var
|
|
37
|
+
var import_comment_drafts = require("./comment-drafts");
|
|
38
|
+
var import_comment_mutations = require("./comment-mutations");
|
|
39
39
|
var import_comment_render = require("./comment-render");
|
|
40
40
|
var import_comment_store = require("./comment-store");
|
|
41
41
|
var import_hooks = require("./hooks");
|
|
42
42
|
var import_license = require("./license");
|
|
43
43
|
var import_options = require("./options");
|
|
44
|
-
var
|
|
44
|
+
var import_pin_stacking = require("./pin-stacking");
|
|
45
45
|
var import_state = require("./state");
|
|
46
|
+
var import_thread_preview = require("./thread-preview");
|
|
47
|
+
var import_thread_stack = require("./thread-stack");
|
|
46
48
|
var import_thread_state = require("./thread-state");
|
|
49
|
+
var import_thread_view = require("./thread-view");
|
|
47
50
|
const stop = (e) => e.stopPropagation();
|
|
48
|
-
const
|
|
51
|
+
const isCanvasPanGesture = (editor, e) => e.button !== 0 || editor.inputs.keys.has("Space");
|
|
52
|
+
function forwardPointerEventToCanvas(container, e) {
|
|
53
|
+
const cvs = container.querySelector(".tl-canvas");
|
|
54
|
+
if (!cvs) return;
|
|
55
|
+
const newEvent = new PointerEvent(e.type, e.nativeEvent);
|
|
56
|
+
newEvent.isSpecialRedispatchedEvent = true;
|
|
57
|
+
cvs.dispatchEvent(newEvent);
|
|
58
|
+
}
|
|
49
59
|
const CLUSTER_FADE_MS = 150;
|
|
50
60
|
const CLUSTER_EXPAND_ZOOM_MS = 450;
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
viewBox: "0 0 24 24",
|
|
55
|
-
width: "15",
|
|
56
|
-
height: "15",
|
|
57
|
-
fill: "none",
|
|
58
|
-
stroke: "currentColor",
|
|
59
|
-
strokeWidth: "2",
|
|
60
|
-
strokeLinecap: "round",
|
|
61
|
-
strokeLinejoin: "round",
|
|
62
|
-
"aria-hidden": "true",
|
|
63
|
-
children: [
|
|
64
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 20h9" }),
|
|
65
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4 12.5-12.5z" })
|
|
66
|
-
]
|
|
67
|
-
}
|
|
68
|
-
) });
|
|
69
|
-
function toCardProps(comment, props, components) {
|
|
70
|
-
const Body = components.CommentBody;
|
|
71
|
-
const body = Body ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Body, { comment }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_comment_body.CommentBody, { richText: comment.body, resolveName: props.resolveName });
|
|
72
|
-
return {
|
|
73
|
-
author: props.resolveName(comment.authorId) ?? import_comment_render.UNKNOWN_AUTHOR,
|
|
74
|
-
body,
|
|
75
|
-
date: new Date(comment.createdAt).toISOString(),
|
|
76
|
-
you: comment.authorId === props.currentUserId,
|
|
77
|
-
edited: comment.editedAt != null
|
|
78
|
-
};
|
|
79
|
-
}
|
|
61
|
+
const CLUSTER_SPLIT_ZOOM_FACTOR = 1.05;
|
|
62
|
+
const CLUSTER_CULL_MARGIN_PX = 120;
|
|
63
|
+
const THREAD_HEADER_BLOCK = 36;
|
|
80
64
|
function CanvasComments(props) {
|
|
81
65
|
const commentingEnabled = (0, import_license.useCommentingEnabled)();
|
|
82
66
|
if (!commentingEnabled) return null;
|
|
83
67
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CanvasCommentsLayer, { ...props });
|
|
84
68
|
}
|
|
69
|
+
function useTrailingPortalHost(container) {
|
|
70
|
+
const [host, setHost] = (0, import_react.useState)(null);
|
|
71
|
+
(0, import_react.useLayoutEffect)(() => {
|
|
72
|
+
const elm = container.ownerDocument.createElement("div");
|
|
73
|
+
elm.style.display = "contents";
|
|
74
|
+
container.appendChild(elm);
|
|
75
|
+
setHost(elm);
|
|
76
|
+
return () => {
|
|
77
|
+
elm.remove();
|
|
78
|
+
setHost(null);
|
|
79
|
+
};
|
|
80
|
+
}, [container]);
|
|
81
|
+
return host;
|
|
82
|
+
}
|
|
85
83
|
function CanvasCommentsLayer(props) {
|
|
86
84
|
const editor = (0, import_tldraw.useEditor)();
|
|
87
85
|
const options = (0, import_options.useCommentingOptions)();
|
|
88
86
|
const container = (0, import_tldraw.useContainer)();
|
|
89
|
-
const
|
|
90
|
-
() => ({ ...import_region_options.DEFAULT_REGION_COMMENT_OPTIONS, ...props.regionOptions }),
|
|
91
|
-
[props.regionOptions]
|
|
92
|
-
);
|
|
93
|
-
(0, import_react.useEffect)(() => (0, import_region_options.setRegionCommentOptions)(editor, regionOptions), [editor, regionOptions]);
|
|
87
|
+
const portalHost = useTrailingPortalHost(container);
|
|
94
88
|
const layerRef = (0, import_react.useRef)(null);
|
|
95
|
-
(0, import_tldraw.usePassThroughWheelEvents)(layerRef);
|
|
96
89
|
(0, import_tldraw.usePassThroughMouseOverEvents)(layerRef);
|
|
97
|
-
const
|
|
98
|
-
const threads = (0, import_hooks.useCommentThreads)(editor);
|
|
90
|
+
const allThreads = (0, import_hooks.useCommentThreads)(editor);
|
|
99
91
|
const pending = (0, import_state.usePendingComment)();
|
|
92
|
+
const canComment = (0, import_options.useCanComment)(props.currentUserId);
|
|
93
|
+
const canRenderComposer = canComment || options.components.ComposerFallback != null;
|
|
94
|
+
const showPendingComposer = pending != null && canRenderComposer;
|
|
95
|
+
(0, import_react.useEffect)(() => {
|
|
96
|
+
if (pending && !showPendingComposer) import_state.pendingComment.set(editor, null);
|
|
97
|
+
}, [editor, pending, showPendingComposer]);
|
|
100
98
|
const openId = (0, import_tldraw.useValue)("open thread id", () => import_state.openThreadId.get(editor), [editor]);
|
|
101
|
-
const
|
|
102
|
-
|
|
99
|
+
const showResolved = (0, import_tldraw.useValue)("show resolved", () => import_state.sidebarFilters.get(editor).showResolved, [
|
|
100
|
+
editor
|
|
101
|
+
]);
|
|
102
|
+
const threads = (0, import_react.useMemo)(
|
|
103
|
+
() => allThreads.filter((t) => showResolved || t.resolved == null || t.id === openId),
|
|
104
|
+
[allThreads, showResolved, openId]
|
|
105
|
+
);
|
|
106
|
+
(0, import_react.useEffect)(() => (0, import_anchor_lifecycle.registerCommentAnchorLifecycle)(editor), [editor]);
|
|
107
|
+
const [heldThreadIds, setHeldThreadIds] = (0, import_react.useState)(EMPTY_SET);
|
|
103
108
|
const adoptOnRebuild = (0, import_react.useRef)(false);
|
|
104
109
|
const clusterLeaves = (0, import_tldraw.useValue)(
|
|
105
110
|
"comment cluster leaves",
|
|
106
111
|
() => (0, import_cluster_input.collectClusterLeaves)(
|
|
107
112
|
editor,
|
|
108
|
-
threads.filter((thread) => !
|
|
109
|
-
import_state.openThreadId.get(editor)
|
|
110
|
-
impreciseShapeAnchor
|
|
113
|
+
threads.filter((thread) => !heldThreadIds.has(thread.id)),
|
|
114
|
+
import_state.openThreadId.get(editor)
|
|
111
115
|
),
|
|
112
|
-
[editor, threads,
|
|
116
|
+
[editor, threads, heldThreadIds]
|
|
113
117
|
);
|
|
114
118
|
const clusterZoomBounds = (0, import_tldraw.useValue)(
|
|
115
119
|
"comment cluster zoom bounds",
|
|
@@ -124,21 +128,41 @@ function CanvasCommentsLayer(props) {
|
|
|
124
128
|
}, [clusterLeaves, clusterZoomBounds, editor]);
|
|
125
129
|
const [renderedModel, setRenderedModel] = (0, import_react.useState)(latestModel);
|
|
126
130
|
let clusterModel = renderedModel;
|
|
127
|
-
|
|
131
|
+
const pageId = (0, import_tldraw.useValue)("comment cluster page", () => editor.getCurrentPageId(), [editor]);
|
|
132
|
+
const pageRef = (0, import_react.useRef)(pageId);
|
|
133
|
+
if (pageRef.current !== pageId) {
|
|
134
|
+
pageRef.current = pageId;
|
|
135
|
+
adoptOnRebuild.current = false;
|
|
136
|
+
latestModel.runtime.seed(editor.getZoomLevel());
|
|
137
|
+
if (heldThreadIds.size > 0) setHeldThreadIds(EMPTY_SET);
|
|
138
|
+
setRenderedModel(latestModel);
|
|
139
|
+
clusterModel = latestModel;
|
|
140
|
+
}
|
|
141
|
+
const rejoinPending = heldThreadIds.size === 0 && adoptOnRebuild.current;
|
|
142
|
+
if (renderedModel !== latestModel && rejoinPending) {
|
|
128
143
|
adoptOnRebuild.current = false;
|
|
129
144
|
latestModel.runtime.seedFrom(editor.getZoomLevel(), renderedModel.runtime.getVisible());
|
|
130
145
|
setRenderedModel(latestModel);
|
|
131
146
|
clusterModel = latestModel;
|
|
147
|
+
} else if (heldThreadIds.size === 0 && renderedModel === latestModel) {
|
|
148
|
+
adoptOnRebuild.current = false;
|
|
132
149
|
}
|
|
133
150
|
const newlyMovedIds = findMovedClusteredLeafIds(clusterModel, latestModel);
|
|
134
151
|
if (newlyMovedIds.length > 0) {
|
|
135
|
-
|
|
136
|
-
const next = new Set(movedThreadIds);
|
|
152
|
+
const next = new Set(heldThreadIds);
|
|
137
153
|
for (const id of newlyMovedIds) next.add(id);
|
|
138
|
-
|
|
154
|
+
setHeldThreadIds(next);
|
|
155
|
+
}
|
|
156
|
+
{
|
|
157
|
+
const latestLeafIds = new Set(latestModel.table.leaves.map((leaf) => leaf.id));
|
|
158
|
+
for (const leaf of clusterModel.table.leaves) {
|
|
159
|
+
if (!latestLeafIds.has(leaf.id)) {
|
|
160
|
+
clusterModel.runtime.detachLeaf(leaf.id);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
139
163
|
}
|
|
140
164
|
(0, import_react.useEffect)(() => {
|
|
141
|
-
if (
|
|
165
|
+
if (heldThreadIds.size === 0) return;
|
|
142
166
|
let lastZoom = editor.getZoomLevel();
|
|
143
167
|
return (0, import_tldraw.react)("rejoin moved comment pins on zoom out", () => {
|
|
144
168
|
const zoom = editor.getZoomLevel();
|
|
@@ -146,9 +170,9 @@ function CanvasCommentsLayer(props) {
|
|
|
146
170
|
lastZoom = zoom;
|
|
147
171
|
if (zoom >= prevZoom) return;
|
|
148
172
|
adoptOnRebuild.current = true;
|
|
149
|
-
|
|
173
|
+
setHeldThreadIds(EMPTY_SET);
|
|
150
174
|
});
|
|
151
|
-
}, [
|
|
175
|
+
}, [heldThreadIds, editor]);
|
|
152
176
|
(0, import_react.useEffect)(() => {
|
|
153
177
|
if (clusterModel === latestModel) return;
|
|
154
178
|
let lastZoom = editor.getZoomLevel();
|
|
@@ -161,90 +185,113 @@ function CanvasCommentsLayer(props) {
|
|
|
161
185
|
setRenderedModel(latestModel);
|
|
162
186
|
});
|
|
163
187
|
}, [clusterModel, latestModel, editor]);
|
|
188
|
+
const partitionVersion = clusterModel.runtime.version;
|
|
164
189
|
const orphanThreads = (0, import_react.useMemo)(() => {
|
|
165
190
|
if (clusterModel === latestModel) return [];
|
|
166
|
-
const
|
|
191
|
+
const displayed = /* @__PURE__ */ new Set();
|
|
192
|
+
for (const node of clusterModel.runtime.getVisible().values()) {
|
|
193
|
+
for (const member of node.members) displayed.add(member);
|
|
194
|
+
}
|
|
167
195
|
const latestIds = new Set(latestModel.table.leaves.map((leaf) => leaf.id));
|
|
168
|
-
return threads.filter((thread) => latestIds.has(thread.id) && !
|
|
169
|
-
}, [clusterModel, latestModel, threads]);
|
|
170
|
-
const
|
|
171
|
-
() => threads.filter((thread) =>
|
|
172
|
-
[threads,
|
|
196
|
+
return threads.filter((thread) => latestIds.has(thread.id) && !displayed.has(thread.id));
|
|
197
|
+
}, [clusterModel, latestModel, threads, partitionVersion]);
|
|
198
|
+
const heldThreads = (0, import_react.useMemo)(
|
|
199
|
+
() => threads.filter((thread) => heldThreadIds.has(thread.id) && thread.id !== openId),
|
|
200
|
+
[threads, heldThreadIds, openId]
|
|
173
201
|
);
|
|
174
|
-
|
|
175
|
-
"comment cluster
|
|
202
|
+
(0, import_tldraw.useValue)(
|
|
203
|
+
"comment cluster version",
|
|
176
204
|
() => {
|
|
177
205
|
clusterModel.runtime.onCamera(editor.getZoomLevel());
|
|
178
|
-
return clusterModel.runtime.
|
|
206
|
+
return clusterModel.runtime.version;
|
|
179
207
|
},
|
|
180
208
|
[clusterModel, editor]
|
|
181
209
|
);
|
|
182
210
|
const visibleNodes = (0, import_react.useMemo)(() => {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
`[comments] cluster cursor k=${clusterCursor} \u2192 re-rendering ${nodes.length} visible nodes`
|
|
186
|
-
);
|
|
187
|
-
return nodes;
|
|
188
|
-
}, [clusterModel, clusterCursor]);
|
|
211
|
+
return Array.from(clusterModel.runtime.getVisible().values());
|
|
212
|
+
}, [clusterModel, partitionVersion]);
|
|
189
213
|
const fadeNodes = useFadeVisibleNodes(visibleNodes, clusterModel);
|
|
190
214
|
const threadsById = (0, import_react.useMemo)(
|
|
191
215
|
() => new Map(threads.map((thread) => [thread.id, thread])),
|
|
192
216
|
[threads]
|
|
193
217
|
);
|
|
218
|
+
const pinStacks = (0, import_tldraw.useValue)("comment pin stacks", () => (0, import_pin_stacking.computePinStacks)(editor, threads), [
|
|
219
|
+
editor,
|
|
220
|
+
threads
|
|
221
|
+
]);
|
|
194
222
|
const openThread = openId ? threadsById.get(openId) : null;
|
|
195
223
|
const hidden = (0, import_tldraw.useValue)("comments hidden", () => import_state.commentsHidden.get(editor), [editor]);
|
|
196
224
|
(0, import_react.useEffect)(() => {
|
|
197
225
|
return () => {
|
|
198
226
|
import_state.openThreadId.set(editor, null);
|
|
227
|
+
import_state.openStackId.set(editor, null);
|
|
199
228
|
import_state.pendingComment.set(editor, null);
|
|
229
|
+
import_state.revealThreadRequest.set(editor, null);
|
|
200
230
|
};
|
|
201
231
|
}, [editor]);
|
|
202
232
|
(0, import_react.useEffect)(() => {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
233
|
+
const key = import_state.openStackId.get(editor);
|
|
234
|
+
if (!key) return;
|
|
235
|
+
for (const id of pinStacks.keys()) {
|
|
236
|
+
const thread = threadsById.get(id);
|
|
237
|
+
if (!thread) continue;
|
|
238
|
+
const point = (0, import_thread_state.anchorPagePoint)(editor, thread.anchor);
|
|
239
|
+
if (point && (0, import_pin_stacking.pinStackKey)(point) === key) return;
|
|
208
240
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
);
|
|
227
|
-
|
|
228
|
-
|
|
241
|
+
import_state.openStackId.set(editor, null);
|
|
242
|
+
}, [editor, pinStacks, threadsById]);
|
|
243
|
+
const requestedRevealThread = (0, import_tldraw.useValue)(
|
|
244
|
+
"requested reveal thread",
|
|
245
|
+
() => {
|
|
246
|
+
const id = import_state.revealThreadRequest.get(editor);
|
|
247
|
+
if (!id) return null;
|
|
248
|
+
const record = (0, import_comment_store.getCommentRecord)(editor, id);
|
|
249
|
+
if (!record) return null;
|
|
250
|
+
const thread = record.typeName === "comment" ? (0, import_comment_store.getCommentRecord)(editor, record.threadId) : record;
|
|
251
|
+
return thread?.typeName === "comment-thread" ? thread : null;
|
|
252
|
+
},
|
|
253
|
+
[editor]
|
|
254
|
+
);
|
|
255
|
+
(0, import_react.useEffect)(() => {
|
|
256
|
+
if (!requestedRevealThread) return;
|
|
257
|
+
import_state.revealThreadRequest.set(editor, null);
|
|
258
|
+
import_state.commentsHidden.set(editor, false);
|
|
259
|
+
revealThreadPin(editor, requestedRevealThread, clusterModel.table, clusterZoomBounds, options);
|
|
260
|
+
import_state.openThreadId.set(editor, requestedRevealThread.id);
|
|
261
|
+
}, [requestedRevealThread, clusterModel.table, clusterZoomBounds, editor, options]);
|
|
262
|
+
const revealClusteredThread = (0, import_react.useCallback)(
|
|
263
|
+
(thread) => {
|
|
264
|
+
revealThreadPin(
|
|
265
|
+
editor,
|
|
266
|
+
thread,
|
|
267
|
+
clusterModel.table,
|
|
268
|
+
clusterZoomBounds,
|
|
269
|
+
options,
|
|
270
|
+
CLUSTER_EXPAND_ZOOM_MS
|
|
271
|
+
);
|
|
272
|
+
import_state.openThreadId.set(editor, thread.id);
|
|
273
|
+
},
|
|
274
|
+
[clusterModel.table, clusterZoomBounds, editor, options]
|
|
275
|
+
);
|
|
229
276
|
const zoomToClusterSplit = (0, import_react.useCallback)(
|
|
230
277
|
(node) => {
|
|
231
278
|
const event = clusterModel.table.events.find((e) => e.result.id === node.id);
|
|
232
279
|
if (!event || !Number.isFinite(event.zSplit)) return;
|
|
233
280
|
const zoom = clamp(
|
|
234
|
-
event.zSplit *
|
|
281
|
+
event.zSplit * CLUSTER_SPLIT_ZOOM_FACTOR,
|
|
235
282
|
clusterZoomBounds.minZoom,
|
|
236
283
|
clusterZoomBounds.maxZoom
|
|
237
284
|
);
|
|
238
285
|
centerOnPointAtZoom(editor, node.centroid, zoom, CLUSTER_EXPAND_ZOOM_MS);
|
|
239
286
|
},
|
|
240
|
-
[clusterModel, clusterZoomBounds, editor
|
|
287
|
+
[clusterModel, clusterZoomBounds, editor]
|
|
241
288
|
);
|
|
242
289
|
(0, import_react.useEffect)(() => {
|
|
243
290
|
const onKeyDown = (e) => {
|
|
244
291
|
if (e.key !== "Escape" || import_state.openThreadId.get(editor) === null) return;
|
|
245
|
-
if ((0,
|
|
292
|
+
if ((0, import_mentions.isMentionPickerOpen)()) return;
|
|
246
293
|
const target = e.target;
|
|
247
|
-
if (target && target.closest(".cmt-editing")) return;
|
|
294
|
+
if (target && target.closest(".tlui-cmt-editing")) return;
|
|
248
295
|
import_state.openThreadId.set(editor, null);
|
|
249
296
|
e.preventDefault();
|
|
250
297
|
e.stopPropagation();
|
|
@@ -264,79 +311,78 @@ function CanvasCommentsLayer(props) {
|
|
|
264
311
|
return () => document.removeEventListener("keydown", onKeyDown, true);
|
|
265
312
|
}, [editor]);
|
|
266
313
|
if (hidden) return null;
|
|
314
|
+
const stackGroupOf = (node) => {
|
|
315
|
+
const group = pinStacks.get(node.members[0]);
|
|
316
|
+
if (!group) return null;
|
|
317
|
+
return node.members.every((id) => group.includes(id)) ? group : null;
|
|
318
|
+
};
|
|
319
|
+
const renderedThreadIds = /* @__PURE__ */ new Set();
|
|
320
|
+
if (options.enableClustering) {
|
|
321
|
+
for (const { node } of fadeNodes) {
|
|
322
|
+
if (node.count === 1) renderedThreadIds.add(node.id);
|
|
323
|
+
else if (stackGroupOf(node)) for (const id of node.members) renderedThreadIds.add(id);
|
|
324
|
+
}
|
|
325
|
+
for (const thread of orphanThreads) renderedThreadIds.add(thread.id);
|
|
326
|
+
for (const thread of heldThreads) renderedThreadIds.add(thread.id);
|
|
327
|
+
} else {
|
|
328
|
+
for (const thread of threads) renderedThreadIds.add(thread.id);
|
|
329
|
+
}
|
|
330
|
+
if (openThread) renderedThreadIds.add(openThread.id);
|
|
331
|
+
const renderThreadPin = (thread) => {
|
|
332
|
+
const group = pinStacks.get(thread.id);
|
|
333
|
+
if (group) {
|
|
334
|
+
const owner = group.find((id) => renderedThreadIds.has(id));
|
|
335
|
+
if (owner !== thread.id) return null;
|
|
336
|
+
const stackThreads = group.map((id) => threadsById.get(id)).filter((t) => t !== void 0);
|
|
337
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_thread_stack.ThreadStackPin, { editor, threads: stackThreads, ...props });
|
|
338
|
+
}
|
|
339
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThreadPin, { editor, thread, ...props });
|
|
340
|
+
};
|
|
341
|
+
if (!portalHost) return null;
|
|
267
342
|
return (0, import_react_dom.createPortal)(
|
|
268
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { ref: layerRef, className: "cmt-canvas-layer", children: [
|
|
343
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { ref: layerRef, className: "tlui-cmt-canvas-layer", children: [
|
|
269
344
|
options.enableClustering ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
270
345
|
fadeNodes.map(({ node, phase }) => {
|
|
271
346
|
let content;
|
|
347
|
+
const stackGroup = node.count > 1 ? stackGroupOf(node) : null;
|
|
272
348
|
if (node.count === 1) {
|
|
273
349
|
const thread = threadsById.get(node.id);
|
|
274
350
|
if (!thread) return null;
|
|
351
|
+
content = renderThreadPin(thread);
|
|
352
|
+
} else if (stackGroup) {
|
|
353
|
+
const owner = stackGroup.find((id) => renderedThreadIds.has(id));
|
|
354
|
+
content = owner && node.members.includes(owner) ? renderThreadPin(threadsById.get(owner)) : null;
|
|
355
|
+
} else {
|
|
275
356
|
content = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
276
|
-
|
|
357
|
+
ClusterBadge,
|
|
277
358
|
{
|
|
278
359
|
editor,
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
360
|
+
node,
|
|
361
|
+
onExpand: zoomToClusterSplit,
|
|
362
|
+
onSelectThread: revealClusteredThread,
|
|
363
|
+
threadsById,
|
|
364
|
+
currentUserId: props.currentUserId,
|
|
365
|
+
resolveAuthor: props.resolveAuthor
|
|
282
366
|
}
|
|
283
367
|
);
|
|
284
|
-
} else {
|
|
285
|
-
content = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ClusterBadge, { editor, node, onExpand: zoomToClusterSplit });
|
|
286
368
|
}
|
|
287
369
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: clusterFadeClassName(phase), children: content }, `cluster-fade:${node.id}`);
|
|
288
370
|
}),
|
|
289
|
-
orphanThreads.map((thread) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
290
|
-
|
|
291
|
-
{
|
|
292
|
-
editor,
|
|
293
|
-
thread,
|
|
294
|
-
...props,
|
|
295
|
-
regionOptions
|
|
296
|
-
},
|
|
297
|
-
thread.id
|
|
298
|
-
)),
|
|
299
|
-
movedThreads.map((thread) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
300
|
-
ThreadPin,
|
|
301
|
-
{
|
|
302
|
-
editor,
|
|
303
|
-
thread,
|
|
304
|
-
...props,
|
|
305
|
-
regionOptions
|
|
306
|
-
},
|
|
307
|
-
thread.id
|
|
308
|
-
))
|
|
371
|
+
orphanThreads.map((thread) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react.Fragment, { children: renderThreadPin(thread) }, thread.id)),
|
|
372
|
+
heldThreads.map((thread) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react.Fragment, { children: renderThreadPin(thread) }, thread.id))
|
|
309
373
|
] }) : (
|
|
310
374
|
// Clustering off: every thread renders as its own live pin (each returns null when it's
|
|
311
375
|
// not on the current page or its anchor is missing). The open thread is excluded here and
|
|
312
376
|
// rendered once below, mirroring how the clustering path keeps it out of the cluster leaves —
|
|
313
377
|
// otherwise it would mount a second, stacked pin.
|
|
314
|
-
threads.filter((thread) => thread.id !== openId).map((thread) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
315
|
-
ThreadPin,
|
|
316
|
-
{
|
|
317
|
-
editor,
|
|
318
|
-
thread,
|
|
319
|
-
...props,
|
|
320
|
-
regionOptions
|
|
321
|
-
},
|
|
322
|
-
thread.id
|
|
323
|
-
))
|
|
324
|
-
),
|
|
325
|
-
openThread && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
326
|
-
ThreadPin,
|
|
327
|
-
{
|
|
328
|
-
editor,
|
|
329
|
-
thread: openThread,
|
|
330
|
-
...props,
|
|
331
|
-
regionOptions
|
|
332
|
-
},
|
|
333
|
-
`open:${openThread.id}`
|
|
378
|
+
threads.filter((thread) => thread.id !== openId).map((thread) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react.Fragment, { children: renderThreadPin(thread) }, thread.id))
|
|
334
379
|
),
|
|
380
|
+
openThread && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react.Fragment, { children: renderThreadPin(openThread) }, `open:${openThread.id}`),
|
|
335
381
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RegionDraftBox, { editor }),
|
|
336
|
-
pending?.anchor.type === "region" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RegionBox, { editor, box: pending.anchor }),
|
|
337
|
-
pending &&
|
|
382
|
+
pending?.anchor.type === "region" && showPendingComposer && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RegionBox, { editor, box: pending.anchor }),
|
|
383
|
+
pending && showPendingComposer && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PendingComposer, { editor, pending, ...props })
|
|
338
384
|
] }),
|
|
339
|
-
|
|
385
|
+
portalHost
|
|
340
386
|
);
|
|
341
387
|
}
|
|
342
388
|
const EMPTY_SET = /* @__PURE__ */ new Set();
|
|
@@ -405,7 +451,7 @@ function cancelClusterFadeFrame(frame) {
|
|
|
405
451
|
else window.clearTimeout(frame);
|
|
406
452
|
}
|
|
407
453
|
function clusterFadeClassName(phase) {
|
|
408
|
-
return `cmt-cluster-fade cmt-cluster-fade--${phase}`;
|
|
454
|
+
return `tlui-cmt-cluster-fade tlui-cmt-cluster-fade--${phase}`;
|
|
409
455
|
}
|
|
410
456
|
function findMovedClusteredLeafIds(rendered, latest) {
|
|
411
457
|
if (rendered.table === latest.table) return [];
|
|
@@ -422,11 +468,6 @@ function findMovedClusteredLeafIds(rendered, latest) {
|
|
|
422
468
|
}
|
|
423
469
|
return moved;
|
|
424
470
|
}
|
|
425
|
-
function hasRemovedLeaves(rendered, latest) {
|
|
426
|
-
if (rendered.leaves.length === 0) return false;
|
|
427
|
-
const latestIds = new Set(latest.leaves.map((leaf) => leaf.id));
|
|
428
|
-
return rendered.leaves.some((leaf) => !latestIds.has(leaf.id));
|
|
429
|
-
}
|
|
430
471
|
function getClusterZoomBounds(editor) {
|
|
431
472
|
const cameraOptions = editor.getCameraOptions();
|
|
432
473
|
const baseZoom = cameraOptions.constraints ? editor.getBaseZoom() : 1;
|
|
@@ -436,34 +477,36 @@ function getClusterZoomBounds(editor) {
|
|
|
436
477
|
maxZoom: zoomSteps[zoomSteps.length - 1] * baseZoom
|
|
437
478
|
};
|
|
438
479
|
}
|
|
439
|
-
function
|
|
480
|
+
function revealThreadPin(editor, thread, table, zoomBounds, options, duration = 200) {
|
|
440
481
|
if (thread.pageId !== editor.getCurrentPageId()) {
|
|
441
482
|
editor.setCurrentPage(thread.pageId);
|
|
442
483
|
}
|
|
443
|
-
const point = (0, import_thread_state.anchorPagePoint)(editor, thread.anchor
|
|
484
|
+
const point = (0, import_thread_state.anchorPagePoint)(editor, thread.anchor);
|
|
444
485
|
if (!point) return;
|
|
445
486
|
if (options.enableClustering) {
|
|
446
487
|
const parentEvent = findDirectParentEvent(table, thread.id);
|
|
447
488
|
if (parentEvent && Number.isFinite(parentEvent.zSplit) && parentEvent.zSplit <= zoomBounds.maxZoom) {
|
|
448
489
|
const zoom = clamp(
|
|
449
|
-
parentEvent.zSplit *
|
|
490
|
+
parentEvent.zSplit * CLUSTER_SPLIT_ZOOM_FACTOR,
|
|
450
491
|
zoomBounds.minZoom,
|
|
451
492
|
zoomBounds.maxZoom
|
|
452
493
|
);
|
|
453
|
-
centerOnPointAtZoom(editor, point, zoom);
|
|
494
|
+
centerOnPointAtZoom(editor, point, zoom, duration);
|
|
454
495
|
return;
|
|
455
496
|
}
|
|
456
497
|
}
|
|
457
|
-
|
|
498
|
+
const offset = (0, import_thread_state.commentCenterScreenOffset)(editor) / editor.getZoomLevel();
|
|
499
|
+
editor.centerOnPoint({ x: point.x + offset, y: point.y }, { animation: { duration } });
|
|
458
500
|
}
|
|
459
501
|
function findDirectParentEvent(table, threadId) {
|
|
460
502
|
return table.events.find((event) => event.children.some((child) => child.id === threadId));
|
|
461
503
|
}
|
|
462
504
|
function centerOnPointAtZoom(editor, point, zoom, duration = 200) {
|
|
463
505
|
const viewport = editor.getViewportScreenBounds();
|
|
506
|
+
const offset = (0, import_thread_state.commentCenterScreenOffset)(editor);
|
|
464
507
|
editor.setCamera(
|
|
465
508
|
{
|
|
466
|
-
x: viewport.w /
|
|
509
|
+
x: (viewport.w / 2 - offset) / zoom - point.x,
|
|
467
510
|
y: viewport.h / (2 * zoom) - point.y,
|
|
468
511
|
z: zoom
|
|
469
512
|
},
|
|
@@ -476,8 +519,16 @@ function clamp(value, min, max) {
|
|
|
476
519
|
const ClusterBadge = (0, import_react.memo)(function ClusterBadge2({
|
|
477
520
|
editor,
|
|
478
521
|
node,
|
|
479
|
-
onExpand
|
|
522
|
+
onExpand,
|
|
523
|
+
onSelectThread,
|
|
524
|
+
threadsById,
|
|
525
|
+
...props
|
|
480
526
|
}) {
|
|
527
|
+
const container = (0, import_tldraw.useContainer)();
|
|
528
|
+
const msg = (0, import_tldraw.useTranslation)();
|
|
529
|
+
const badgeRef = (0, import_react.useRef)(null);
|
|
530
|
+
const { previewShown, previewHandlers } = (0, import_thread_preview.useMarkerPreview)(editor, `cluster:${node.id}`);
|
|
531
|
+
(0, import_tldraw.usePassThroughWheelEvents)(badgeRef);
|
|
481
532
|
const point = (0, import_tldraw.useValue)(
|
|
482
533
|
"cluster badge point",
|
|
483
534
|
() => {
|
|
@@ -487,46 +538,63 @@ const ClusterBadge = (0, import_react.memo)(function ClusterBadge2({
|
|
|
487
538
|
},
|
|
488
539
|
[editor, node]
|
|
489
540
|
);
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
{
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
onPointerDown: stop,
|
|
497
|
-
onClick: (e) => {
|
|
498
|
-
e.stopPropagation();
|
|
499
|
-
onExpand(node);
|
|
500
|
-
},
|
|
501
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_count_badge.CountBadge, { count: node.count })
|
|
541
|
+
const previewThreads = (0, import_react.useMemo)(() => {
|
|
542
|
+
if (!previewShown) return [];
|
|
543
|
+
const threads = [];
|
|
544
|
+
for (const id of node.members) {
|
|
545
|
+
const thread = threadsById.get(id);
|
|
546
|
+
if (thread) threads.push(thread);
|
|
502
547
|
}
|
|
503
|
-
|
|
548
|
+
return (0, import_thread_preview.sortThreadsForPreview)(threads);
|
|
549
|
+
}, [previewShown, node.members, threadsById]);
|
|
550
|
+
if (!point) return null;
|
|
551
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
552
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
553
|
+
"button",
|
|
554
|
+
{
|
|
555
|
+
ref: badgeRef,
|
|
556
|
+
type: "button",
|
|
557
|
+
className: "tlui-cmt-button tlui-cmt-canvas-cluster",
|
|
558
|
+
style: { left: point.x, top: point.y },
|
|
559
|
+
"aria-label": msg("comments.cluster-label").replace("{count}", String(node.count)),
|
|
560
|
+
onPointerDown: (e) => {
|
|
561
|
+
if (isCanvasPanGesture(editor, e)) {
|
|
562
|
+
forwardPointerEventToCanvas(container, e);
|
|
563
|
+
return;
|
|
564
|
+
}
|
|
565
|
+
e.stopPropagation();
|
|
566
|
+
},
|
|
567
|
+
onClick: (e) => {
|
|
568
|
+
e.stopPropagation();
|
|
569
|
+
onExpand(node);
|
|
570
|
+
},
|
|
571
|
+
...previewHandlers,
|
|
572
|
+
onFocus: previewHandlers.onPointerEnter,
|
|
573
|
+
onBlur: previewHandlers.onPointerLeave,
|
|
574
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_count_badge.CountBadge, { count: node.count })
|
|
575
|
+
}
|
|
576
|
+
),
|
|
577
|
+
previewShown && previewThreads.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
578
|
+
import_thread_preview.ThreadPreview,
|
|
579
|
+
{
|
|
580
|
+
editor,
|
|
581
|
+
threads: previewThreads,
|
|
582
|
+
container,
|
|
583
|
+
variant: "list",
|
|
584
|
+
point,
|
|
585
|
+
onSelectThread,
|
|
586
|
+
...previewHandlers,
|
|
587
|
+
...props
|
|
588
|
+
}
|
|
589
|
+
)
|
|
590
|
+
] });
|
|
504
591
|
});
|
|
505
592
|
function isInInflatedViewport(editor, point) {
|
|
506
593
|
const viewport = editor.getViewportScreenBounds();
|
|
507
|
-
const margin =
|
|
594
|
+
const margin = CLUSTER_CULL_MARGIN_PX;
|
|
508
595
|
return point.x >= -margin && point.y >= -margin && point.x <= viewport.w + margin && point.y <= viewport.h + margin;
|
|
509
596
|
}
|
|
510
|
-
function
|
|
511
|
-
container,
|
|
512
|
-
style,
|
|
513
|
-
children
|
|
514
|
-
}) {
|
|
515
|
-
const ref = (0, import_react.useRef)(null);
|
|
516
|
-
(0, import_tldraw.usePassThroughWheelEvents)(ref);
|
|
517
|
-
(0, import_tldraw.usePassThroughMouseOverEvents)(ref);
|
|
518
|
-
return (0, import_react_dom.createPortal)(
|
|
519
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ref, className: "cmt-canvas-popover", style, onPointerDown: stop, children }),
|
|
520
|
-
container
|
|
521
|
-
);
|
|
522
|
-
}
|
|
523
|
-
function RegionBox({
|
|
524
|
-
editor,
|
|
525
|
-
box,
|
|
526
|
-
movable,
|
|
527
|
-
onPreview,
|
|
528
|
-
onCommit
|
|
529
|
-
}) {
|
|
597
|
+
function RegionBox({ editor, box }) {
|
|
530
598
|
const rect = (0, import_tldraw.useValue)(
|
|
531
599
|
"region rect",
|
|
532
600
|
() => {
|
|
@@ -536,38 +604,7 @@ function RegionBox({
|
|
|
536
604
|
},
|
|
537
605
|
[editor, box.x, box.y, box.w, box.h]
|
|
538
606
|
);
|
|
539
|
-
|
|
540
|
-
const translated = (e) => {
|
|
541
|
-
const g = grabRef.current;
|
|
542
|
-
const p = editor.screenToPage({ x: e.clientX, y: e.clientY });
|
|
543
|
-
return { ...g.box, x: g.box.x + (p.x - g.page.x), y: g.box.y + (p.y - g.page.y) };
|
|
544
|
-
};
|
|
545
|
-
const startMove = (e) => {
|
|
546
|
-
e.stopPropagation();
|
|
547
|
-
grabRef.current = { page: editor.screenToPage({ x: e.clientX, y: e.clientY }), box };
|
|
548
|
-
e.currentTarget.setPointerCapture(e.pointerId);
|
|
549
|
-
};
|
|
550
|
-
const onMove = (e) => {
|
|
551
|
-
if (grabRef.current) onPreview?.(translated(e));
|
|
552
|
-
};
|
|
553
|
-
const endMove = (e) => {
|
|
554
|
-
if (!grabRef.current) return;
|
|
555
|
-
const bounds = translated(e);
|
|
556
|
-
grabRef.current = null;
|
|
557
|
-
if (e.currentTarget.hasPointerCapture(e.pointerId))
|
|
558
|
-
e.currentTarget.releasePointerCapture(e.pointerId);
|
|
559
|
-
onCommit?.(bounds);
|
|
560
|
-
};
|
|
561
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
562
|
-
"div",
|
|
563
|
-
{
|
|
564
|
-
className: movable ? "cmt-canvas-region cmt-canvas-region--movable" : "cmt-canvas-region",
|
|
565
|
-
style: rect,
|
|
566
|
-
onPointerDown: movable ? startMove : void 0,
|
|
567
|
-
onPointerMove: movable ? onMove : void 0,
|
|
568
|
-
onPointerUp: movable ? endMove : void 0
|
|
569
|
-
}
|
|
570
|
-
);
|
|
607
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "tlui-cmt-canvas-region", style: rect });
|
|
571
608
|
}
|
|
572
609
|
function RegionDraftBox({ editor }) {
|
|
573
610
|
const box = (0, import_tldraw.useValue)("region draft", () => import_state.regionDraft.get(editor), [editor]);
|
|
@@ -580,12 +617,6 @@ const REGION_CORNERS = [
|
|
|
580
617
|
{ x: 0, y: 1, cursor: "nesw-resize" },
|
|
581
618
|
{ x: 1, y: 1, cursor: "nwse-resize" }
|
|
582
619
|
];
|
|
583
|
-
const REGION_EDGES = [
|
|
584
|
-
{ x: 0.5, y: 0, cursor: "ns-resize" },
|
|
585
|
-
{ x: 1, y: 0.5, cursor: "ew-resize" },
|
|
586
|
-
{ x: 0.5, y: 1, cursor: "ns-resize" },
|
|
587
|
-
{ x: 0, y: 0.5, cursor: "ew-resize" }
|
|
588
|
-
];
|
|
589
620
|
const REGION_HANDLE_MARGIN_PX = 12;
|
|
590
621
|
function resizeRegion(box, handle, cursor) {
|
|
591
622
|
const controlsX = handle.x !== 0.5;
|
|
@@ -635,7 +666,7 @@ function RegionResizeHandles({
|
|
|
635
666
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: points.map((h) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
636
667
|
"div",
|
|
637
668
|
{
|
|
638
|
-
className: "cmt-canvas-region-handle",
|
|
669
|
+
className: "tlui-cmt-canvas-region-handle",
|
|
639
670
|
style: { left: h.left, top: h.top, cursor: h.cursor },
|
|
640
671
|
onPointerDown: startResize,
|
|
641
672
|
onPointerMove: onResize(h),
|
|
@@ -647,33 +678,22 @@ function RegionResizeHandles({
|
|
|
647
678
|
const ThreadPin = (0, import_react.memo)(function ThreadPin2({
|
|
648
679
|
editor,
|
|
649
680
|
thread,
|
|
650
|
-
regionOptions,
|
|
651
681
|
...props
|
|
652
682
|
}) {
|
|
653
|
-
const {
|
|
654
|
-
currentUserId,
|
|
655
|
-
resolveName,
|
|
656
|
-
onPostComment,
|
|
657
|
-
isCommentUnread,
|
|
658
|
-
onCommentRead,
|
|
659
|
-
getMentionSuggestions,
|
|
660
|
-
renderMentionSuggestion
|
|
661
|
-
} = props;
|
|
683
|
+
const { resolveAuthor } = props;
|
|
662
684
|
const options = (0, import_options.useCommentingOptions)();
|
|
663
|
-
const
|
|
685
|
+
const canComment = (0, import_options.useCanComment)(props.currentUserId);
|
|
664
686
|
const container = (0, import_tldraw.useContainer)();
|
|
665
|
-
const comments = (0, import_hooks.useThreadComments)(editor, thread.id);
|
|
666
687
|
const msg = (0, import_tldraw.useTranslation)();
|
|
688
|
+
const comments = (0, import_hooks.useThreadComments)(editor, thread.id);
|
|
667
689
|
const open = (0, import_tldraw.useValue)("thread open", () => import_state.openThreadId.get(editor) === thread.id, [
|
|
668
690
|
editor,
|
|
669
691
|
thread.id
|
|
670
692
|
]);
|
|
671
|
-
const [reply, setReply] = (0, import_react.useState)(import_comment_extensions.EMPTY_COMMENT);
|
|
672
|
-
const [editingId, setEditingId] = (0, import_react.useState)(null);
|
|
673
|
-
const [editText, setEditText] = (0, import_react.useState)(import_comment_extensions.EMPTY_COMMENT);
|
|
674
693
|
const [dragPagePoint, setDragPagePoint] = (0, import_react.useState)(null);
|
|
675
694
|
const [resizeBounds, setResizeBounds] = (0, import_react.useState)(null);
|
|
676
|
-
const
|
|
695
|
+
const { previewShown, previewHandlers } = (0, import_thread_preview.useMarkerPreview)(editor, `pin:${thread.id}`);
|
|
696
|
+
const previewThreads = (0, import_react.useMemo)(() => [thread], [thread]);
|
|
677
697
|
const pointerInRegion = (0, import_tldraw.useValue)(
|
|
678
698
|
"pointer in region",
|
|
679
699
|
() => {
|
|
@@ -686,25 +706,30 @@ const ThreadPin = (0, import_react.memo)(function ThreadPin2({
|
|
|
686
706
|
},
|
|
687
707
|
[editor, thread.anchor, thread.pageId]
|
|
688
708
|
);
|
|
689
|
-
const revealed = open || resizeBounds != null ||
|
|
709
|
+
const revealed = open || resizeBounds != null || pointerInRegion;
|
|
710
|
+
const pinCorner = thread.anchor.type === "region" ? (0, import_thread_state.regionAnchorPinCorner)(thread.anchor) : import_thread_state.REGION_PIN_CORNER;
|
|
690
711
|
const resizeHandles = (0, import_react.useMemo)(
|
|
691
|
-
() =>
|
|
692
|
-
|
|
693
|
-
),
|
|
694
|
-
[regionOptions.resize, regionOptions.pinCorner]
|
|
712
|
+
() => REGION_CORNERS.filter((c) => c.x !== pinCorner.x || c.y !== pinCorner.y),
|
|
713
|
+
[pinCorner]
|
|
695
714
|
);
|
|
696
715
|
const dragRef = (0, import_react.useRef)(null);
|
|
697
716
|
const markerRef = (0, import_react.useRef)(null);
|
|
717
|
+
(0, import_tldraw.usePassThroughWheelEvents)(markerRef);
|
|
718
|
+
(0, import_react.useEffect)(() => {
|
|
719
|
+
return () => {
|
|
720
|
+
if (dragRef.current) editor.setHintingShapes([]);
|
|
721
|
+
};
|
|
722
|
+
}, [editor]);
|
|
698
723
|
(0, import_react.useEffect)(() => {
|
|
699
724
|
if (!open) return;
|
|
700
725
|
const onPointerDown = (e) => {
|
|
701
726
|
const target = e.target;
|
|
702
727
|
if (!target) return;
|
|
703
|
-
if (target.closest(".cmt-canvas-popover")) return;
|
|
728
|
+
if (target.closest(".tlui-cmt-canvas-popover")) return;
|
|
704
729
|
const marker = markerRef.current;
|
|
705
730
|
if (marker && marker.contains(target)) return;
|
|
706
|
-
if (target.closest(".cmt-canvas-region-handle, .cmt-canvas-region--movable")) return;
|
|
707
|
-
if (target.closest(".tlui-menu, [data-radix-popper-content-wrapper], .cmt-mention-popup"))
|
|
731
|
+
if (target.closest(".tlui-cmt-canvas-region-handle, .tlui-cmt-canvas-region--movable")) return;
|
|
732
|
+
if (target.closest(".tlui-menu, [data-radix-popper-content-wrapper], .tlui-cmt-mention-popup"))
|
|
708
733
|
return;
|
|
709
734
|
import_state.openThreadId.set(editor, null);
|
|
710
735
|
};
|
|
@@ -715,165 +740,68 @@ const ThreadPin = (0, import_react.memo)(function ThreadPin2({
|
|
|
715
740
|
"pin point",
|
|
716
741
|
() => {
|
|
717
742
|
if (thread.pageId !== editor.getCurrentPageId()) return null;
|
|
718
|
-
const pagePoint = (0, import_thread_state.anchorPagePoint)(editor, thread.anchor
|
|
719
|
-
|
|
743
|
+
const pagePoint = (0, import_thread_state.anchorPagePoint)(editor, thread.anchor);
|
|
744
|
+
if (!pagePoint) return null;
|
|
745
|
+
const viewportPoint = editor.pageToViewport(pagePoint);
|
|
746
|
+
const inset = (0, import_thread_state.impreciseShapePinInset)(editor, thread.anchor);
|
|
747
|
+
return inset ? { x: viewportPoint.x + inset.x, y: viewportPoint.y + inset.y } : viewportPoint;
|
|
720
748
|
},
|
|
721
|
-
[editor, thread.anchor, thread.pageId
|
|
749
|
+
[editor, thread.anchor, thread.pageId]
|
|
722
750
|
);
|
|
723
|
-
const visible = point !== null;
|
|
724
|
-
(0, import_react.useEffect)(() => {
|
|
725
|
-
if (!open || !visible || !isCommentUnread || !onCommentRead) return;
|
|
726
|
-
for (const comment of comments) {
|
|
727
|
-
if (isCommentUnread(comment.id)) {
|
|
728
|
-
onCommentRead(comment.id);
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
}, [open, visible, comments, isCommentUnread, onCommentRead]);
|
|
732
751
|
if (!point) return null;
|
|
733
|
-
const postReply = () => {
|
|
734
|
-
if ((0, import_comment_extensions.isCommentEmpty)(reply) || !currentUserId) return;
|
|
735
|
-
(0, import_state.commitCommentMutation)(editor, () => {
|
|
736
|
-
const comment = (0, import_tldraw.createComment)({
|
|
737
|
-
threadId: thread.id,
|
|
738
|
-
pageId: thread.pageId,
|
|
739
|
-
authorId: currentUserId,
|
|
740
|
-
body: reply
|
|
741
|
-
});
|
|
742
|
-
(0, import_comment_store.putCommentRecords)(editor, [comment]);
|
|
743
|
-
if (onPostComment) onPostComment(comment);
|
|
744
|
-
});
|
|
745
|
-
setReply(import_comment_extensions.EMPTY_COMMENT);
|
|
746
|
-
};
|
|
747
|
-
const toggleResolve = () => {
|
|
748
|
-
if (!currentUserId) return;
|
|
749
|
-
(0, import_state.commitCommentMutation)(editor, () => {
|
|
750
|
-
(0, import_comment_store.putCommentRecords)(editor, [
|
|
751
|
-
{
|
|
752
|
-
...thread,
|
|
753
|
-
resolved: thread.resolved ? null : { at: Date.now(), by: currentUserId }
|
|
754
|
-
}
|
|
755
|
-
]);
|
|
756
|
-
});
|
|
757
|
-
};
|
|
758
|
-
const deleteThread = () => {
|
|
759
|
-
import_state.openThreadId.set(editor, null);
|
|
760
|
-
(0, import_state.commitCommentMutation)(
|
|
761
|
-
editor,
|
|
762
|
-
() => (0, import_comment_store.removeCommentRecords)(editor, [thread.id, ...comments.map((c) => c.id)])
|
|
763
|
-
);
|
|
764
|
-
};
|
|
765
|
-
const startEdit = (comment) => {
|
|
766
|
-
setEditingId(comment.id);
|
|
767
|
-
setEditText(comment.body);
|
|
768
|
-
};
|
|
769
|
-
const saveEdit = () => {
|
|
770
|
-
const comment = comments.find((c) => c.id === editingId);
|
|
771
|
-
if (!comment || (0, import_comment_extensions.isCommentEmpty)(editText)) return;
|
|
772
|
-
(0, import_state.commitCommentMutation)(editor, () => {
|
|
773
|
-
(0, import_comment_store.putCommentRecords)(editor, [{ ...comment, body: editText, editedAt: Date.now() }]);
|
|
774
|
-
});
|
|
775
|
-
setEditingId(null);
|
|
776
|
-
};
|
|
777
|
-
const renderComment = (card, index) => {
|
|
778
|
-
const comment = comments[index];
|
|
779
|
-
if (editingId === comment.id) {
|
|
780
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
781
|
-
"div",
|
|
782
|
-
{
|
|
783
|
-
className: "cmt-editing",
|
|
784
|
-
onKeyDown: (e) => {
|
|
785
|
-
if (e.key === "Escape") {
|
|
786
|
-
setEditingId(null);
|
|
787
|
-
e.stopPropagation();
|
|
788
|
-
}
|
|
789
|
-
},
|
|
790
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
791
|
-
import_comment_composer.CommentComposer,
|
|
792
|
-
{
|
|
793
|
-
author: card.author,
|
|
794
|
-
placeholder: msg("comments.edit-placeholder"),
|
|
795
|
-
value: editText,
|
|
796
|
-
onChange: setEditText,
|
|
797
|
-
onSubmit: saveEdit,
|
|
798
|
-
sendLabel: msg("comments.save"),
|
|
799
|
-
disabled: (0, import_comment_extensions.isCommentEmpty)(editText),
|
|
800
|
-
getMentionSuggestions,
|
|
801
|
-
renderMentionSuggestion,
|
|
802
|
-
autoFocus: true
|
|
803
|
-
}
|
|
804
|
-
)
|
|
805
|
-
}
|
|
806
|
-
);
|
|
807
|
-
}
|
|
808
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
809
|
-
import_comment_card.CommentCard,
|
|
810
|
-
{
|
|
811
|
-
...card,
|
|
812
|
-
actions: comment.authorId === currentUserId ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
813
|
-
"button",
|
|
814
|
-
{
|
|
815
|
-
className: "cmt-thread__action",
|
|
816
|
-
title: msg("comments.edit"),
|
|
817
|
-
onClick: () => startEdit(comment),
|
|
818
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_tldraw.TldrawUiIcon, { icon: "dots-horizontal", label: msg("comments.edit"), small: true })
|
|
819
|
-
}
|
|
820
|
-
) : void 0
|
|
821
|
-
}
|
|
822
|
-
);
|
|
823
|
-
};
|
|
824
|
-
const headerActions = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
825
|
-
currentUserId && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
826
|
-
"button",
|
|
827
|
-
{
|
|
828
|
-
className: "cmt-thread__action",
|
|
829
|
-
title: msg(thread.resolved ? "comments.reopen" : "comments.resolve"),
|
|
830
|
-
onClick: toggleResolve,
|
|
831
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
832
|
-
import_tldraw.TldrawUiIcon,
|
|
833
|
-
{
|
|
834
|
-
icon: "check",
|
|
835
|
-
label: msg(thread.resolved ? "comments.reopen" : "comments.resolve"),
|
|
836
|
-
small: true
|
|
837
|
-
}
|
|
838
|
-
)
|
|
839
|
-
}
|
|
840
|
-
),
|
|
841
|
-
currentUserId && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
842
|
-
"button",
|
|
843
|
-
{
|
|
844
|
-
className: "cmt-thread__action",
|
|
845
|
-
title: msg("comments.delete"),
|
|
846
|
-
onClick: deleteThread,
|
|
847
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_tldraw.TldrawUiIcon, { icon: "trash", label: msg("comments.delete"), small: true })
|
|
848
|
-
}
|
|
849
|
-
),
|
|
850
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
851
|
-
"button",
|
|
852
|
-
{
|
|
853
|
-
className: "cmt-thread__action",
|
|
854
|
-
title: msg("comments.dismiss"),
|
|
855
|
-
onClick: () => import_state.openThreadId.set(editor, null),
|
|
856
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_tldraw.TldrawUiIcon, { icon: "cross-2", label: msg("comments.dismiss"), small: true })
|
|
857
|
-
}
|
|
858
|
-
)
|
|
859
|
-
] });
|
|
860
752
|
const PinContent = options.components.PinContent;
|
|
861
|
-
const
|
|
753
|
+
const threadAuthor = resolveAuthor(thread.createdBy);
|
|
754
|
+
const pinContent = PinContent ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PinContent, { thread, comments }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_mentions.Avatar, { author: threadAuthor ?? import_comment_render.UNKNOWN_COMMENT_AUTHOR });
|
|
755
|
+
const pinLabel = msg(
|
|
756
|
+
thread.resolved ? "comments.pin-label-resolved" : "comments.pin-label"
|
|
757
|
+
).replace("{name}", threadAuthor?.name ?? import_comment_render.UNKNOWN_AUTHOR);
|
|
862
758
|
const isRegion = thread.anchor.type === "region";
|
|
863
|
-
const pinMovable = regionOptions.move !== "body";
|
|
864
|
-
const bodyMovable = regionOptions.move !== "pin";
|
|
865
759
|
const startDrag = (e) => {
|
|
760
|
+
if (isCanvasPanGesture(editor, e)) {
|
|
761
|
+
forwardPointerEventToCanvas(container, e);
|
|
762
|
+
return;
|
|
763
|
+
}
|
|
866
764
|
e.stopPropagation();
|
|
867
|
-
|
|
765
|
+
const grabPage = editor.screenToPage({ x: e.clientX, y: e.clientY });
|
|
766
|
+
const anchorPage = (0, import_thread_state.anchorPagePoint)(editor, thread.anchor);
|
|
767
|
+
const inset = (0, import_thread_state.impreciseShapePinInset)(editor, thread.anchor);
|
|
768
|
+
if (anchorPage && inset) {
|
|
769
|
+
const zoom = editor.getZoomLevel();
|
|
770
|
+
anchorPage.x += inset.x / zoom;
|
|
771
|
+
anchorPage.y += inset.y / zoom;
|
|
772
|
+
}
|
|
773
|
+
dragRef.current = {
|
|
774
|
+
startX: e.clientX,
|
|
775
|
+
startY: e.clientY,
|
|
776
|
+
moved: false,
|
|
777
|
+
offsetX: anchorPage ? anchorPage.x - grabPage.x : 0,
|
|
778
|
+
offsetY: anchorPage ? anchorPage.y - grabPage.y : 0
|
|
779
|
+
};
|
|
868
780
|
e.currentTarget.setPointerCapture(e.pointerId);
|
|
869
781
|
};
|
|
870
782
|
const onDrag = (e) => {
|
|
871
783
|
const drag = dragRef.current;
|
|
872
784
|
if (!drag) return;
|
|
873
|
-
if (
|
|
785
|
+
if (!canComment) return;
|
|
874
786
|
if (!drag.moved && Math.hypot(e.clientX - drag.startX, e.clientY - drag.startY) < 4) return;
|
|
875
787
|
drag.moved = true;
|
|
876
|
-
|
|
788
|
+
const cursorPage = editor.screenToPage({ x: e.clientX, y: e.clientY });
|
|
789
|
+
const pagePoint = { x: cursorPage.x + drag.offsetX, y: cursorPage.y + drag.offsetY };
|
|
790
|
+
setDragPagePoint(pagePoint);
|
|
791
|
+
if (!isRegion) {
|
|
792
|
+
const hit = (0, import_thread_state.commentTargetShapeAt)(editor, pagePoint);
|
|
793
|
+
editor.setHintingShapes(hit ? [hit.id] : []);
|
|
794
|
+
}
|
|
795
|
+
};
|
|
796
|
+
const cancelDrag = (e) => {
|
|
797
|
+
const drag = dragRef.current;
|
|
798
|
+
dragRef.current = null;
|
|
799
|
+
if (e.currentTarget.hasPointerCapture(e.pointerId)) {
|
|
800
|
+
e.currentTarget.releasePointerCapture(e.pointerId);
|
|
801
|
+
}
|
|
802
|
+
if (!drag) return;
|
|
803
|
+
setDragPagePoint(null);
|
|
804
|
+
editor.setHintingShapes([]);
|
|
877
805
|
};
|
|
878
806
|
const endDrag = (e) => {
|
|
879
807
|
const drag = dragRef.current;
|
|
@@ -882,55 +810,59 @@ const ThreadPin = (0, import_react.memo)(function ThreadPin2({
|
|
|
882
810
|
e.currentTarget.releasePointerCapture(e.pointerId);
|
|
883
811
|
}
|
|
884
812
|
if (!drag) return;
|
|
813
|
+
editor.setHintingShapes([]);
|
|
885
814
|
if (!drag.moved) {
|
|
886
815
|
import_state.openThreadId.set(editor, import_state.openThreadId.get(editor) === thread.id ? null : thread.id);
|
|
887
816
|
return;
|
|
888
817
|
}
|
|
889
|
-
const
|
|
818
|
+
const cursorPage = editor.screenToPage({ x: e.clientX, y: e.clientY });
|
|
819
|
+
const pagePoint = { x: cursorPage.x + drag.offsetX, y: cursorPage.y + drag.offsetY };
|
|
890
820
|
setDragPagePoint(null);
|
|
891
821
|
let anchor;
|
|
892
822
|
if (thread.anchor.type === "region") {
|
|
893
823
|
anchor = {
|
|
894
824
|
...thread.anchor,
|
|
895
|
-
x: pagePoint.x -
|
|
896
|
-
y: pagePoint.y -
|
|
825
|
+
x: pagePoint.x - pinCorner.x * thread.anchor.w,
|
|
826
|
+
y: pagePoint.y - pinCorner.y * thread.anchor.h
|
|
897
827
|
};
|
|
898
828
|
} else {
|
|
899
|
-
const hit =
|
|
900
|
-
anchor = hit ? (0, import_thread_state.shapeAnchorAt)(
|
|
829
|
+
const hit = (0, import_thread_state.commentTargetShapeAt)(editor, pagePoint);
|
|
830
|
+
anchor = hit ? (0, import_thread_state.shapeAnchorAt)(
|
|
831
|
+
editor,
|
|
832
|
+
hit.id,
|
|
833
|
+
pagePoint,
|
|
834
|
+
(0, import_options.getCommentingOptions)(editor).shouldBePrecise(editor, {
|
|
835
|
+
shapeId: hit.id,
|
|
836
|
+
point: pagePoint,
|
|
837
|
+
altKey: e.altKey
|
|
838
|
+
})
|
|
839
|
+
) : { type: "point", x: pagePoint.x, y: pagePoint.y };
|
|
901
840
|
}
|
|
902
|
-
(0,
|
|
841
|
+
(0, import_comment_mutations.commitCommentMutation)(editor, () => (0, import_comment_mutations.putRecordsInCommit)(editor, [{ ...thread, anchor }]), "drag");
|
|
903
842
|
};
|
|
904
|
-
const livePinPage = resizeBounds ? (0, import_thread_state.regionPinPoint)(resizeBounds,
|
|
905
|
-
const
|
|
843
|
+
const livePinPage = resizeBounds ? (0, import_thread_state.regionPinPoint)(resizeBounds, pinCorner) : dragPagePoint;
|
|
844
|
+
const renderPointBase = livePinPage ? editor.pageToViewport(livePinPage) : point;
|
|
845
|
+
const renderPoint = isRegion ? { x: renderPointBase.x - 17, y: renderPointBase.y + 17 } : renderPointBase;
|
|
906
846
|
const regionAnchor = thread.anchor.type === "region" ? thread.anchor : void 0;
|
|
907
847
|
const movedRegion = regionAnchor && dragPagePoint ? {
|
|
908
848
|
...regionAnchor,
|
|
909
|
-
x: dragPagePoint.x -
|
|
910
|
-
y: dragPagePoint.y -
|
|
849
|
+
x: dragPagePoint.x - pinCorner.x * regionAnchor.w,
|
|
850
|
+
y: dragPagePoint.y - pinCorner.y * regionAnchor.h
|
|
911
851
|
} : regionAnchor;
|
|
912
852
|
const regionBoxBounds = resizeBounds ?? movedRegion;
|
|
913
853
|
const commitResize = (bounds) => {
|
|
914
854
|
setResizeBounds(null);
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
}
|
|
855
|
+
if (!canComment) return;
|
|
856
|
+
(0, import_comment_mutations.commitCommentMutation)(
|
|
857
|
+
editor,
|
|
858
|
+
// Spread the existing anchor first so the region's pin corner survives a resize.
|
|
859
|
+
() => (0, import_comment_mutations.putRecordsInCommit)(editor, [{ ...thread, anchor: { ...regionAnchor, ...bounds } }]),
|
|
860
|
+
"drag"
|
|
920
861
|
);
|
|
921
862
|
};
|
|
922
863
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
923
|
-
regionBoxBounds && (dragPagePoint || revealed) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
924
|
-
|
|
925
|
-
{
|
|
926
|
-
editor,
|
|
927
|
-
box: regionBoxBounds,
|
|
928
|
-
movable: bodyMovable && !dragPagePoint,
|
|
929
|
-
onPreview: setResizeBounds,
|
|
930
|
-
onCommit: commitResize
|
|
931
|
-
}
|
|
932
|
-
),
|
|
933
|
-
regionBoxBounds && revealed && !dragPagePoint && regionOptions.resize !== "none" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
864
|
+
regionBoxBounds && (dragPagePoint || revealed) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RegionBox, { editor, box: regionBoxBounds }),
|
|
865
|
+
regionBoxBounds && revealed && !dragPagePoint && canComment && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
934
866
|
RegionResizeHandles,
|
|
935
867
|
{
|
|
936
868
|
editor,
|
|
@@ -943,51 +875,59 @@ const ThreadPin = (0, import_react.memo)(function ThreadPin2({
|
|
|
943
875
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
944
876
|
"div",
|
|
945
877
|
{
|
|
946
|
-
className:
|
|
878
|
+
className: [
|
|
879
|
+
"tlui-cmt-canvas-pin",
|
|
880
|
+
open && "tlui-cmt-canvas-pin--open",
|
|
881
|
+
dragPagePoint && "tlui-cmt-canvas-pin--dragging"
|
|
882
|
+
].filter(Boolean).join(" "),
|
|
947
883
|
style: { left: renderPoint.x, top: renderPoint.y },
|
|
948
884
|
children: [
|
|
949
885
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
950
|
-
"
|
|
886
|
+
"button",
|
|
951
887
|
{
|
|
952
888
|
ref: markerRef,
|
|
953
|
-
|
|
889
|
+
type: "button",
|
|
890
|
+
className: "tlui-cmt-button tlui-cmt-canvas-pin__marker",
|
|
891
|
+
"aria-label": pinLabel,
|
|
892
|
+
"aria-expanded": open,
|
|
954
893
|
onPointerDown: startDrag,
|
|
955
894
|
onPointerMove: onDrag,
|
|
956
895
|
onPointerUp: endDrag,
|
|
957
|
-
|
|
958
|
-
|
|
896
|
+
onPointerCancel: cancelDrag,
|
|
897
|
+
onClick: (e) => {
|
|
898
|
+
if (e.detail !== 0) return;
|
|
899
|
+
import_state.openThreadId.set(editor, import_state.openThreadId.get(editor) === thread.id ? null : thread.id);
|
|
900
|
+
},
|
|
901
|
+
onPointerEnter: previewHandlers.onPointerEnter,
|
|
902
|
+
onPointerLeave: previewHandlers.onPointerLeave,
|
|
903
|
+
onFocus: previewHandlers.onPointerEnter,
|
|
904
|
+
onBlur: previewHandlers.onPointerLeave,
|
|
959
905
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_comment_pin.CommentPin, { resolved: thread.resolved != null, open, children: pinContent })
|
|
960
906
|
}
|
|
961
907
|
),
|
|
962
908
|
open && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
963
|
-
ThreadPopover,
|
|
909
|
+
import_thread_view.ThreadPopover,
|
|
964
910
|
{
|
|
965
911
|
container,
|
|
966
|
-
style: {
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
disabled: (0, import_comment_extensions.isCommentEmpty)(reply),
|
|
986
|
-
getMentionSuggestions,
|
|
987
|
-
renderMentionSuggestion
|
|
988
|
-
} : void 0
|
|
989
|
-
}
|
|
990
|
-
)
|
|
912
|
+
style: {
|
|
913
|
+
left: renderPoint.x + import_thread_view.POPOVER_OFFSET.thread.x,
|
|
914
|
+
top: renderPoint.y + import_thread_view.POPOVER_OFFSET.thread.y - THREAD_HEADER_BLOCK
|
|
915
|
+
},
|
|
916
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_thread_view.ThreadView, { editor, thread, ...props })
|
|
917
|
+
}
|
|
918
|
+
),
|
|
919
|
+
previewShown && !dragPagePoint && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
920
|
+
import_thread_preview.ThreadPreview,
|
|
921
|
+
{
|
|
922
|
+
editor,
|
|
923
|
+
threads: previewThreads,
|
|
924
|
+
container,
|
|
925
|
+
variant: "thread",
|
|
926
|
+
point: renderPoint,
|
|
927
|
+
onSelectThread: () => import_state.openThreadId.set(editor, thread.id),
|
|
928
|
+
...previewHandlers,
|
|
929
|
+
currentUserId: props.currentUserId,
|
|
930
|
+
resolveAuthor
|
|
991
931
|
}
|
|
992
932
|
)
|
|
993
933
|
]
|
|
@@ -999,12 +939,18 @@ function PendingComposer({
|
|
|
999
939
|
editor,
|
|
1000
940
|
pending,
|
|
1001
941
|
currentUserId,
|
|
1002
|
-
|
|
942
|
+
resolveAuthor,
|
|
1003
943
|
onPostComment,
|
|
1004
944
|
getMentionSuggestions,
|
|
1005
945
|
renderMentionSuggestion
|
|
1006
946
|
}) {
|
|
1007
|
-
const
|
|
947
|
+
const ComposerFallback = (0, import_options.useCommentingOptions)().components.ComposerFallback;
|
|
948
|
+
const canComment = (0, import_options.useCanComment)(currentUserId);
|
|
949
|
+
const me = currentUserId ? resolveAuthor(currentUserId) : void 0;
|
|
950
|
+
const draftAvatar = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_comment_pin.CommentPin, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_mentions.Avatar, { author: me ?? import_comment_render.UNKNOWN_COMMENT_AUTHOR }) });
|
|
951
|
+
const [text, setText] = (0, import_react.useState)(
|
|
952
|
+
() => (0, import_comment_drafts.getCommentDraft)(import_comment_drafts.NEW_COMMENT_DRAFT) ?? import_comment_extensions.EMPTY_COMMENT
|
|
953
|
+
);
|
|
1008
954
|
const ref = (0, import_react.useRef)(null);
|
|
1009
955
|
const msg = (0, import_tldraw.useTranslation)();
|
|
1010
956
|
const container = (0, import_tldraw.useContainer)();
|
|
@@ -1019,7 +965,7 @@ function PendingComposer({
|
|
|
1019
965
|
const el = ref.current;
|
|
1020
966
|
const target = e.target;
|
|
1021
967
|
if (!el || !target) return;
|
|
1022
|
-
if (el.contains(target) || target.closest(".cmt-mention-popup")) return;
|
|
968
|
+
if (el.contains(target) || target.closest(".tlui-cmt-mention-popup")) return;
|
|
1023
969
|
import_state.pendingComment.set(editor, null);
|
|
1024
970
|
};
|
|
1025
971
|
document.addEventListener("pointerdown", onPointerDown, true);
|
|
@@ -1027,7 +973,7 @@ function PendingComposer({
|
|
|
1027
973
|
}, [editor]);
|
|
1028
974
|
const submit = () => {
|
|
1029
975
|
if ((0, import_comment_extensions.isCommentEmpty)(text) || !currentUserId) return;
|
|
1030
|
-
(0,
|
|
976
|
+
(0, import_comment_mutations.commitCommentMutation)(editor, () => {
|
|
1031
977
|
const pageId = editor.getCurrentPageId();
|
|
1032
978
|
const thread = (0, import_tldraw.createCommentThread)({
|
|
1033
979
|
pageId,
|
|
@@ -1040,10 +986,11 @@ function PendingComposer({
|
|
|
1040
986
|
authorId: currentUserId,
|
|
1041
987
|
body: text
|
|
1042
988
|
});
|
|
1043
|
-
(0,
|
|
989
|
+
(0, import_comment_mutations.putRecordsInCommit)(editor, [thread, comment]);
|
|
1044
990
|
if (onPostComment) onPostComment(comment);
|
|
1045
991
|
});
|
|
1046
992
|
setText(import_comment_extensions.EMPTY_COMMENT);
|
|
993
|
+
(0, import_comment_drafts.clearCommentDraft)(import_comment_drafts.NEW_COMMENT_DRAFT);
|
|
1047
994
|
import_state.pendingComment.set(editor, null);
|
|
1048
995
|
};
|
|
1049
996
|
return (0, import_react_dom.createPortal)(
|
|
@@ -1051,28 +998,36 @@ function PendingComposer({
|
|
|
1051
998
|
"div",
|
|
1052
999
|
{
|
|
1053
1000
|
ref,
|
|
1054
|
-
className:
|
|
1001
|
+
className: [
|
|
1002
|
+
"tlui-cmt-canvas-composer",
|
|
1003
|
+
pending.anchor.type === "region" && "tlui-cmt-canvas-composer--region",
|
|
1004
|
+
!canComment && "tlui-cmt-canvas-composer--fallback"
|
|
1005
|
+
].filter(Boolean).join(" "),
|
|
1055
1006
|
style: { left: point.x, top: point.y },
|
|
1056
1007
|
onPointerDown: stop,
|
|
1008
|
+
onContextMenu: stop,
|
|
1057
1009
|
onKeyDown: (e) => {
|
|
1058
|
-
if (e.key === "Escape" && !(0,
|
|
1010
|
+
if (e.key === "Escape" && !(0, import_mentions.isMentionPickerOpen)()) import_state.pendingComment.set(editor, null);
|
|
1059
1011
|
},
|
|
1060
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1012
|
+
children: canComment ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1061
1013
|
import_comment_composer.CommentComposer,
|
|
1062
1014
|
{
|
|
1063
|
-
author:
|
|
1015
|
+
author: me ?? import_comment_render.UNKNOWN_COMMENT_AUTHOR,
|
|
1064
1016
|
placeholder: msg("comments.add-placeholder"),
|
|
1065
1017
|
sendLabel: msg("comments.send"),
|
|
1066
1018
|
value: text,
|
|
1067
|
-
onChange:
|
|
1019
|
+
onChange: (value) => {
|
|
1020
|
+
setText(value);
|
|
1021
|
+
(0, import_comment_drafts.saveCommentDraft)(import_comment_drafts.NEW_COMMENT_DRAFT, value);
|
|
1022
|
+
},
|
|
1068
1023
|
onSubmit: submit,
|
|
1069
|
-
disabled: (0, import_comment_extensions.isCommentEmpty)(text),
|
|
1024
|
+
disabled: (0, import_comment_extensions.isCommentEmpty)(text) || !currentUserId,
|
|
1070
1025
|
getMentionSuggestions,
|
|
1071
1026
|
renderMentionSuggestion,
|
|
1072
1027
|
autoFocus: true,
|
|
1073
1028
|
leading: draftAvatar
|
|
1074
1029
|
}
|
|
1075
|
-
)
|
|
1030
|
+
) : ComposerFallback && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ComposerFallback, { context: "pending" })
|
|
1076
1031
|
}
|
|
1077
1032
|
),
|
|
1078
1033
|
container
|