@dxos/plugin-thread 0.6.12 → 0.6.13-main.09887cd
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/lib/browser/{ThreadArticle-O64ZECMF.mjs → ThreadArticle-GBPIH47W.mjs} +3 -3
- package/dist/lib/browser/{ThreadMain-ZDCRC6RG.mjs → ThreadMain-PGF7W5EV.mjs} +3 -3
- package/dist/lib/browser/chunk-5G3KL6TC.mjs +16 -0
- package/dist/lib/browser/chunk-5G3KL6TC.mjs.map +7 -0
- package/dist/lib/browser/{chunk-GKPZHUT3.mjs → chunk-JFQZ5W2I.mjs} +2 -2
- package/dist/lib/browser/{chunk-GKPZHUT3.mjs.map → chunk-JFQZ5W2I.mjs.map} +1 -1
- package/dist/lib/browser/{chunk-P7ZE5N5M.mjs → chunk-O4YRHIZC.mjs} +13 -11
- package/dist/lib/browser/chunk-O4YRHIZC.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +411 -393
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/meta.mjs +1 -1
- package/dist/lib/browser/types.mjs +2 -2
- package/dist/lib/node/{ThreadArticle-DO56JXBU.cjs → ThreadArticle-GH5UBWFU.cjs} +7 -7
- package/dist/lib/node/{ThreadMain-XJX75GHG.cjs → ThreadMain-CO6I3DNX.cjs} +7 -7
- package/dist/lib/node/{chunk-5PZNPPQF.cjs → chunk-FDYRG7HE.cjs} +65 -63
- package/dist/lib/node/chunk-FDYRG7HE.cjs.map +7 -0
- package/dist/lib/node/{chunk-D5GOVXHS.cjs → chunk-FOZUQZF4.cjs} +6 -6
- package/dist/lib/node/{chunk-D5GOVXHS.cjs.map → chunk-FOZUQZF4.cjs.map} +1 -1
- package/dist/lib/node/{chunk-BWBONZGU.cjs → chunk-JIJ7Z6NO.cjs} +7 -22
- package/dist/lib/node/chunk-JIJ7Z6NO.cjs.map +7 -0
- package/dist/lib/node/index.cjs +442 -428
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.cjs +4 -4
- package/dist/lib/node/meta.cjs.map +1 -1
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/types.cjs +3 -3
- package/dist/lib/node/types.cjs.map +1 -1
- package/dist/lib/node-esm/ThreadArticle-ZTYD52TR.mjs +19 -0
- package/dist/lib/node-esm/ThreadArticle-ZTYD52TR.mjs.map +7 -0
- package/dist/lib/node-esm/ThreadMain-LEHGOF7R.mjs +27 -0
- package/dist/lib/node-esm/ThreadMain-LEHGOF7R.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-DC5ZA6H5.mjs +18 -0
- package/dist/lib/node-esm/chunk-DC5ZA6H5.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-XOVJ65DG.mjs +413 -0
- package/dist/lib/node-esm/chunk-XOVJ65DG.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-ZXIPFXSA.mjs +21 -0
- package/dist/lib/node-esm/chunk-ZXIPFXSA.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +1121 -0
- package/dist/lib/node-esm/index.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -0
- package/dist/lib/node-esm/meta.mjs +12 -0
- package/dist/lib/node-esm/meta.mjs.map +7 -0
- package/dist/lib/node-esm/types.mjs +9 -0
- package/dist/lib/node-esm/types.mjs.map +7 -0
- package/dist/types/src/ThreadPlugin.d.ts.map +1 -1
- package/dist/types/src/components/ChatContainer.d.ts.map +1 -1
- package/dist/types/src/components/CommentContainer.d.ts +1 -1
- package/dist/types/src/components/CommentContainer.d.ts.map +1 -1
- package/dist/types/src/components/CommentsContainer.d.ts +1 -5
- package/dist/types/src/components/CommentsContainer.d.ts.map +1 -1
- package/dist/types/src/components/MessageContainer.d.ts.map +1 -1
- package/dist/types/src/components/ThreadComplementary.d.ts +10 -0
- package/dist/types/src/components/ThreadComplementary.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +3 -2
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/components/testing.d.ts +2 -0
- package/dist/types/src/components/testing.d.ts.map +1 -1
- package/dist/types/src/extensions/index.d.ts +2 -0
- package/dist/types/src/extensions/index.d.ts.map +1 -0
- package/dist/types/src/extensions/threads.d.ts +9 -0
- package/dist/types/src/extensions/threads.d.ts.map +1 -0
- package/dist/types/src/meta.d.ts +3 -9
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +6 -1
- package/dist/types/src/types.d.ts.map +1 -1
- package/package.json +40 -37
- package/src/ThreadPlugin.tsx +120 -310
- package/src/components/ChatContainer.tsx +7 -8
- package/src/components/CommentContainer.tsx +18 -19
- package/src/components/Comments.stories.tsx +2 -2
- package/src/components/CommentsContainer.tsx +18 -31
- package/src/components/MessageContainer.tsx +2 -1
- package/src/components/ThreadComplementary.tsx +113 -0
- package/src/components/index.ts +3 -2
- package/src/extensions/index.ts +5 -0
- package/src/extensions/threads.ts +117 -0
- package/src/meta.ts +15 -0
- package/src/types.ts +8 -3
- package/dist/lib/browser/chunk-5IBJO53M.mjs +0 -21
- package/dist/lib/browser/chunk-5IBJO53M.mjs.map +0 -7
- package/dist/lib/browser/chunk-P7ZE5N5M.mjs.map +0 -7
- package/dist/lib/node/chunk-5PZNPPQF.cjs.map +0 -7
- package/dist/lib/node/chunk-BWBONZGU.cjs.map +0 -7
- package/dist/types/src/types.test.d.ts +0 -2
- package/dist/types/src/types.test.d.ts.map +0 -1
- package/src/meta.tsx +0 -20
- package/src/types.test.ts +0 -13
- /package/dist/lib/browser/{ThreadArticle-O64ZECMF.mjs.map → ThreadArticle-GBPIH47W.mjs.map} +0 -0
- /package/dist/lib/browser/{ThreadMain-ZDCRC6RG.mjs.map → ThreadMain-PGF7W5EV.mjs.map} +0 -0
- /package/dist/lib/node/{ThreadArticle-DO56JXBU.cjs.map → ThreadArticle-GH5UBWFU.cjs.map} +0 -0
- /package/dist/lib/node/{ThreadMain-XJX75GHG.cjs.map → ThreadMain-CO6I3DNX.cjs.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ThreadAction
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-JFQZ5W2I.mjs";
|
|
4
4
|
import {
|
|
5
5
|
ChatContainer,
|
|
6
6
|
ChatHeading,
|
|
@@ -10,71 +10,49 @@ import {
|
|
|
10
10
|
useAnalyticsCallback,
|
|
11
11
|
useOnEditAnalytics,
|
|
12
12
|
useStatus
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-O4YRHIZC.mjs";
|
|
14
14
|
import {
|
|
15
15
|
THREAD_ITEM,
|
|
16
16
|
THREAD_PLUGIN,
|
|
17
17
|
meta_default
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-5G3KL6TC.mjs";
|
|
19
19
|
|
|
20
20
|
// packages/plugins/plugin-thread/src/ThreadPlugin.tsx
|
|
21
|
-
import
|
|
22
|
-
import {
|
|
23
|
-
import
|
|
24
|
-
import { LayoutAction, NavigationAction, parseIntentPlugin, parseNavigationPlugin, resolvePlugin, parseGraphPlugin, SLUG_PATH_SEPARATOR, SLUG_COLLECTION_INDICATOR, isLayoutParts, parseMetadataResolverPlugin, useResolvePlugins } from "@dxos/app-framework";
|
|
25
|
-
import { getTypename } from "@dxos/echo-schema";
|
|
26
|
-
import { create as create2 } from "@dxos/echo-schema";
|
|
21
|
+
import React6 from "react";
|
|
22
|
+
import { NavigationAction, isLayoutParts, parseIntentPlugin, parseNavigationPlugin, parseMetadataResolverPlugin, resolvePlugin } from "@dxos/app-framework";
|
|
23
|
+
import { create as create2, getTypename } from "@dxos/echo-schema";
|
|
27
24
|
import { LocalStorageStore } from "@dxos/local-storage";
|
|
28
|
-
import {
|
|
25
|
+
import { log } from "@dxos/log";
|
|
29
26
|
import { parseClientPlugin } from "@dxos/plugin-client";
|
|
30
|
-
import { createExtension, isActionGroup } from "@dxos/plugin-graph";
|
|
31
|
-
import { DocumentType } from "@dxos/plugin-markdown/types";
|
|
27
|
+
import { createExtension, isActionGroup, toSignal } from "@dxos/plugin-graph";
|
|
32
28
|
import { ObservabilityAction } from "@dxos/plugin-observability/meta";
|
|
33
29
|
import { SpaceAction } from "@dxos/plugin-space";
|
|
34
|
-
import { ThreadType, MessageType as MessageType2, ChannelType } from "@dxos/plugin-space/types";
|
|
35
|
-
import { getSpace as
|
|
36
|
-
import { ScrollArea } from "@dxos/react-ui";
|
|
37
|
-
import { createAttendableAttributes } from "@dxos/react-ui-attention";
|
|
38
|
-
import { comments, createExternalCommentSync, listener as listener2 } from "@dxos/react-ui-editor";
|
|
30
|
+
import { ThreadType as ThreadType2, MessageType as MessageType2, ChannelType } from "@dxos/plugin-space/types";
|
|
31
|
+
import { getSpace as getSpace3, fullyQualifiedId as fullyQualifiedId5, loadObjectReferences, parseFullyQualifiedId } from "@dxos/react-client/echo";
|
|
39
32
|
import { translations as threadTranslations } from "@dxos/react-ui-thread";
|
|
40
|
-
import { nonNullable as nonNullable2 } from "@dxos/util";
|
|
41
33
|
|
|
42
34
|
// packages/plugins/plugin-thread/src/components/index.ts
|
|
43
|
-
import
|
|
44
|
-
|
|
45
|
-
// packages/plugins/plugin-thread/src/components/ThreadSettings.tsx
|
|
46
|
-
import React from "react";
|
|
47
|
-
import { SettingsValue } from "@dxos/plugin-settings";
|
|
48
|
-
import { Input, useTranslation } from "@dxos/react-ui";
|
|
49
|
-
var ThreadSettings = ({ settings }) => {
|
|
50
|
-
const { t } = useTranslation(THREAD_PLUGIN);
|
|
51
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(SettingsValue, {
|
|
52
|
-
label: t("settings standalone label")
|
|
53
|
-
}, /* @__PURE__ */ React.createElement(Input.Switch, {
|
|
54
|
-
checked: settings.standalone,
|
|
55
|
-
onCheckedChange: (checked) => settings.standalone = !!checked
|
|
56
|
-
})));
|
|
57
|
-
};
|
|
35
|
+
import React5 from "react";
|
|
58
36
|
|
|
59
37
|
// packages/plugins/plugin-thread/src/components/CommentContainer.tsx
|
|
60
38
|
import { CheckCircle, X } from "@phosphor-icons/react";
|
|
61
|
-
import
|
|
39
|
+
import React, { useCallback, useMemo, useRef, useState } from "react";
|
|
62
40
|
import { create } from "@dxos/echo-schema";
|
|
63
41
|
import { MessageType } from "@dxos/plugin-space/types";
|
|
64
|
-
import { getSpace, useMembers } from "@dxos/react-client/echo";
|
|
42
|
+
import { fullyQualifiedId, getSpace, useMembers } from "@dxos/react-client/echo";
|
|
65
43
|
import { useIdentity } from "@dxos/react-client/halo";
|
|
66
|
-
import { Button, Tag, Tooltip, useThemeContext, useTranslation
|
|
44
|
+
import { Button, Tag, Tooltip, useThemeContext, useTranslation } from "@dxos/react-ui";
|
|
67
45
|
import { createBasicExtensions, createThemeExtensions, listener } from "@dxos/react-ui-editor";
|
|
68
46
|
import { getSize, hoverableControlItem, hoverableControls, hoverableFocusedWithinControls, mx } from "@dxos/react-ui-theme";
|
|
69
47
|
import { MessageTextbox, Thread, ThreadFooter, ThreadHeading } from "@dxos/react-ui-thread";
|
|
70
48
|
import { nonNullable } from "@dxos/util";
|
|
71
49
|
var sizeClass = getSize(4);
|
|
72
50
|
var ToggleResolvedButton = ({ isResolved, onResolve }) => {
|
|
73
|
-
const { t } =
|
|
51
|
+
const { t } = useTranslation(THREAD_PLUGIN);
|
|
74
52
|
const label = t(isResolved ? "mark as unresolved label" : "mark as resolved label");
|
|
75
|
-
return /* @__PURE__ */
|
|
53
|
+
return /* @__PURE__ */ React.createElement(Tooltip.Root, null, /* @__PURE__ */ React.createElement(Tooltip.Trigger, {
|
|
76
54
|
asChild: true
|
|
77
|
-
}, /* @__PURE__ */
|
|
55
|
+
}, /* @__PURE__ */ React.createElement(Button, {
|
|
78
56
|
variant: "ghost",
|
|
79
57
|
"data-testid": "thread.toggle-resolved",
|
|
80
58
|
onClick: onResolve,
|
|
@@ -82,23 +60,23 @@ var ToggleResolvedButton = ({ isResolved, onResolve }) => {
|
|
|
82
60
|
"min-bs-0 p-1",
|
|
83
61
|
!isResolved && hoverableControlItem
|
|
84
62
|
]
|
|
85
|
-
}, /* @__PURE__ */
|
|
63
|
+
}, /* @__PURE__ */ React.createElement("span", {
|
|
86
64
|
className: "sr-only"
|
|
87
|
-
}, label), isResolved ? /* @__PURE__ */
|
|
65
|
+
}, label), isResolved ? /* @__PURE__ */ React.createElement(CheckCircle, {
|
|
88
66
|
className: sizeClass,
|
|
89
67
|
weight: "fill"
|
|
90
|
-
}) : /* @__PURE__ */
|
|
68
|
+
}) : /* @__PURE__ */ React.createElement(CheckCircle, {
|
|
91
69
|
className: sizeClass
|
|
92
|
-
}))), /* @__PURE__ */
|
|
70
|
+
}))), /* @__PURE__ */ React.createElement(Tooltip.Portal, null, /* @__PURE__ */ React.createElement(Tooltip.Content, {
|
|
93
71
|
classNames: "z-[21]"
|
|
94
|
-
}, label, /* @__PURE__ */
|
|
72
|
+
}, label, /* @__PURE__ */ React.createElement(Tooltip.Arrow, null))));
|
|
95
73
|
};
|
|
96
74
|
var DeleteThreadButton = ({ onDelete }) => {
|
|
97
|
-
const { t } =
|
|
75
|
+
const { t } = useTranslation(THREAD_PLUGIN);
|
|
98
76
|
const label = t("delete thread label");
|
|
99
|
-
return /* @__PURE__ */
|
|
77
|
+
return /* @__PURE__ */ React.createElement(Tooltip.Root, null, /* @__PURE__ */ React.createElement(Tooltip.Trigger, {
|
|
100
78
|
asChild: true
|
|
101
|
-
}, /* @__PURE__ */
|
|
79
|
+
}, /* @__PURE__ */ React.createElement(Button, {
|
|
102
80
|
variant: "ghost",
|
|
103
81
|
"data-testid": "thread.delete",
|
|
104
82
|
onClick: onDelete,
|
|
@@ -106,24 +84,23 @@ var DeleteThreadButton = ({ onDelete }) => {
|
|
|
106
84
|
"min-bs-0 p-1",
|
|
107
85
|
hoverableControlItem
|
|
108
86
|
]
|
|
109
|
-
}, /* @__PURE__ */
|
|
87
|
+
}, /* @__PURE__ */ React.createElement("span", {
|
|
110
88
|
className: "sr-only"
|
|
111
|
-
}, label), /* @__PURE__ */
|
|
89
|
+
}, label), /* @__PURE__ */ React.createElement(X, {
|
|
112
90
|
className: sizeClass
|
|
113
|
-
}))), /* @__PURE__ */
|
|
91
|
+
}))), /* @__PURE__ */ React.createElement(Tooltip.Portal, null, /* @__PURE__ */ React.createElement(Tooltip.Content, {
|
|
114
92
|
classNames: "z-[21]"
|
|
115
|
-
}, label, /* @__PURE__ */
|
|
93
|
+
}, label, /* @__PURE__ */ React.createElement(Tooltip.Arrow, null))));
|
|
116
94
|
};
|
|
117
|
-
var CommentContainer = ({ thread, detached, context, current,
|
|
95
|
+
var CommentContainer = ({ thread, detached, context, current, onAttend, onThreadDelete, onMessageDelete, onResolve, onComment }) => {
|
|
118
96
|
const identity = useIdentity();
|
|
119
97
|
const space = getSpace(thread);
|
|
120
98
|
const members = useMembers(space?.key);
|
|
121
|
-
const activity = useStatus(space, thread
|
|
122
|
-
const { t } =
|
|
99
|
+
const activity = useStatus(space, fullyQualifiedId(thread));
|
|
100
|
+
const { t } = useTranslation(THREAD_PLUGIN);
|
|
123
101
|
const threadScrollRef = useRef(null);
|
|
124
|
-
const [autoFocus, setAutoFocus] = useState(!!autoFocusTextbox);
|
|
125
102
|
const { themeMode } = useThemeContext();
|
|
126
|
-
const textboxMetadata = getMessageMetadata(thread
|
|
103
|
+
const textboxMetadata = getMessageMetadata(fullyQualifiedId(thread), identity);
|
|
127
104
|
const [_count, _setCount] = useState(0);
|
|
128
105
|
const rerenderEditor = () => _setCount((count) => count + 1);
|
|
129
106
|
const messageRef = useRef("");
|
|
@@ -141,11 +118,6 @@ var CommentContainer = ({ thread, detached, context, current, autoFocusTextbox,
|
|
|
141
118
|
], [
|
|
142
119
|
_count
|
|
143
120
|
]);
|
|
144
|
-
useEffect(() => {
|
|
145
|
-
setAutoFocus(!!autoFocusTextbox);
|
|
146
|
-
}, [
|
|
147
|
-
autoFocusTextbox
|
|
148
|
-
]);
|
|
149
121
|
const scrollToEnd = (behavior) => setTimeout(() => threadScrollRef.current?.scrollIntoView({
|
|
150
122
|
behavior,
|
|
151
123
|
block: "end"
|
|
@@ -164,7 +136,6 @@ var CommentContainer = ({ thread, detached, context, current, autoFocusTextbox,
|
|
|
164
136
|
}));
|
|
165
137
|
onComment?.(thread);
|
|
166
138
|
messageRef.current = "";
|
|
167
|
-
setAutoFocus(true);
|
|
168
139
|
scrollToEnd("instant");
|
|
169
140
|
rerenderEditor();
|
|
170
141
|
return true;
|
|
@@ -172,44 +143,42 @@ var CommentContainer = ({ thread, detached, context, current, autoFocusTextbox,
|
|
|
172
143
|
thread,
|
|
173
144
|
identity
|
|
174
145
|
]);
|
|
175
|
-
|
|
176
|
-
return /* @__PURE__ */ React2.createElement(Thread, {
|
|
146
|
+
return /* @__PURE__ */ React.createElement(Thread, {
|
|
177
147
|
onClickCapture: onAttend,
|
|
178
148
|
onFocusCapture: onAttend,
|
|
179
149
|
current,
|
|
180
|
-
id: thread
|
|
181
|
-
}, /* @__PURE__ */
|
|
150
|
+
id: fullyQualifiedId(thread)
|
|
151
|
+
}, /* @__PURE__ */ React.createElement("div", {
|
|
182
152
|
role: "none",
|
|
183
153
|
className: mx("col-span-2 grid grid-cols-[var(--rail-size)_1fr_min-content]", hoverableControls, hoverableFocusedWithinControls)
|
|
184
|
-
}, detached ? /* @__PURE__ */
|
|
154
|
+
}, detached ? /* @__PURE__ */ React.createElement(Tooltip.Root, null, /* @__PURE__ */ React.createElement(Tooltip.Trigger, {
|
|
185
155
|
asChild: true
|
|
186
|
-
}, /* @__PURE__ */
|
|
156
|
+
}, /* @__PURE__ */ React.createElement(ThreadHeading, {
|
|
187
157
|
detached: true
|
|
188
|
-
}, thread.name ?? t("thread title placeholder"))), /* @__PURE__ */
|
|
158
|
+
}, thread.name ?? t("thread title placeholder"))), /* @__PURE__ */ React.createElement(Tooltip.Portal, null, /* @__PURE__ */ React.createElement(Tooltip.Content, {
|
|
189
159
|
classNames: "z-[21]",
|
|
190
160
|
side: "top"
|
|
191
|
-
}, t("detached thread label"), /* @__PURE__ */
|
|
161
|
+
}, t("detached thread label"), /* @__PURE__ */ React.createElement(Tooltip.Arrow, null)))) : /* @__PURE__ */ React.createElement(ThreadHeading, null, thread.name ?? t("thread title placeholder")), /* @__PURE__ */ React.createElement("div", {
|
|
192
162
|
className: "flex flex-row items-center pli-1"
|
|
193
|
-
}, thread.status === "staged" && /* @__PURE__ */
|
|
163
|
+
}, thread.status === "staged" && /* @__PURE__ */ React.createElement(Tag, {
|
|
194
164
|
palette: "neutral"
|
|
195
|
-
}, t("draft button")), onResolve && !(thread?.status === "staged") && /* @__PURE__ */
|
|
165
|
+
}, t("draft button")), onResolve && !(thread?.status === "staged") && /* @__PURE__ */ React.createElement(ToggleResolvedButton, {
|
|
196
166
|
isResolved: thread?.status === "resolved",
|
|
197
167
|
onResolve
|
|
198
|
-
}), onThreadDelete && /* @__PURE__ */
|
|
168
|
+
}), onThreadDelete && /* @__PURE__ */ React.createElement(DeleteThreadButton, {
|
|
199
169
|
onDelete: onThreadDelete
|
|
200
|
-
}))), thread.messages.filter(nonNullable).map((message) => /* @__PURE__ */
|
|
170
|
+
}))), thread.messages.filter(nonNullable).map((message) => /* @__PURE__ */ React.createElement(MessageContainer, {
|
|
201
171
|
key: message.id,
|
|
202
172
|
message,
|
|
203
173
|
members,
|
|
204
|
-
onDelete:
|
|
205
|
-
})), /* @__PURE__ */
|
|
174
|
+
onDelete: (id) => onMessageDelete?.(id)
|
|
175
|
+
})), /* @__PURE__ */ React.createElement(MessageTextbox, {
|
|
206
176
|
extensions,
|
|
207
|
-
autoFocus,
|
|
208
177
|
onSend: handleCreate,
|
|
209
178
|
...textboxMetadata
|
|
210
|
-
}), /* @__PURE__ */
|
|
179
|
+
}), /* @__PURE__ */ React.createElement(ThreadFooter, {
|
|
211
180
|
activity
|
|
212
|
-
}, t("activity message")), /* @__PURE__ */
|
|
181
|
+
}, t("activity message")), /* @__PURE__ */ React.createElement("div", {
|
|
213
182
|
role: "none",
|
|
214
183
|
className: "bs-px -mbs-px",
|
|
215
184
|
ref: threadScrollRef
|
|
@@ -217,26 +186,15 @@ var CommentContainer = ({ thread, detached, context, current, autoFocusTextbox,
|
|
|
217
186
|
};
|
|
218
187
|
|
|
219
188
|
// packages/plugins/plugin-thread/src/components/CommentsContainer.tsx
|
|
220
|
-
import { ChatText
|
|
221
|
-
import
|
|
222
|
-
import {
|
|
223
|
-
import {
|
|
189
|
+
import { ChatText } from "@phosphor-icons/react";
|
|
190
|
+
import React2, { useEffect } from "react";
|
|
191
|
+
import { fullyQualifiedId as fullyQualifiedId2 } from "@dxos/react-client/echo";
|
|
192
|
+
import { useTranslation as useTranslation2, Trans } from "@dxos/react-ui";
|
|
224
193
|
import { descriptionText, mx as mx2 } from "@dxos/react-ui-theme";
|
|
225
|
-
var
|
|
226
|
-
const { t } =
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
className: "flex items-center"
|
|
230
|
-
}, /* @__PURE__ */ React3.createElement(PlankHeading.Button, {
|
|
231
|
-
attendableId
|
|
232
|
-
}, /* @__PURE__ */ React3.createElement(Quotes, plankHeadingIconProps)), /* @__PURE__ */ React3.createElement(PlankHeading.Label, {
|
|
233
|
-
attendableId
|
|
234
|
-
}, t("comments heading")));
|
|
235
|
-
};
|
|
236
|
-
var CommentsContainer = ({ threads, detached = [], currentId, autoFocusCurrentTextbox, showResolvedThreads, onThreadAttend, onThreadDelete, onMessageDelete, onThreadToggleResolved, ...props }) => {
|
|
237
|
-
const { t } = useTranslation3(THREAD_PLUGIN);
|
|
238
|
-
const filteredThreads = showResolvedThreads ? threads : threads.filter((thread) => !(thread?.status === "resolved"));
|
|
239
|
-
useEffect2(() => {
|
|
194
|
+
var CommentsContainer = ({ threads: threads2, detached = [], currentId, showResolvedThreads, onThreadAttend, onThreadDelete, onMessageDelete, onThreadToggleResolved, ...props }) => {
|
|
195
|
+
const { t } = useTranslation2(THREAD_PLUGIN);
|
|
196
|
+
const filteredThreads = showResolvedThreads ? threads2 : threads2.filter((thread) => !(thread?.status === "resolved"));
|
|
197
|
+
useEffect(() => {
|
|
240
198
|
if (currentId) {
|
|
241
199
|
document.getElementById(currentId)?.scrollIntoView({
|
|
242
200
|
behavior: "smooth",
|
|
@@ -246,44 +204,260 @@ var CommentsContainer = ({ threads, detached = [], currentId, autoFocusCurrentTe
|
|
|
246
204
|
}, [
|
|
247
205
|
currentId
|
|
248
206
|
]);
|
|
249
|
-
return /* @__PURE__ */
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
onThreadDelete
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
onMessageDelete
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
207
|
+
return /* @__PURE__ */ React2.createElement(React2.Fragment, null, filteredThreads.length > 0 ? filteredThreads.map((thread) => {
|
|
208
|
+
const threadId = fullyQualifiedId2(thread);
|
|
209
|
+
return /* @__PURE__ */ React2.createElement(CommentContainer, {
|
|
210
|
+
key: threadId,
|
|
211
|
+
thread,
|
|
212
|
+
current: currentId === threadId,
|
|
213
|
+
detached: detached.includes(threadId),
|
|
214
|
+
...onThreadAttend && {
|
|
215
|
+
onAttend: () => onThreadAttend(thread)
|
|
216
|
+
},
|
|
217
|
+
...onThreadDelete && {
|
|
218
|
+
onThreadDelete: () => onThreadDelete(thread)
|
|
219
|
+
},
|
|
220
|
+
...onMessageDelete && {
|
|
221
|
+
onMessageDelete: (messageId) => onMessageDelete(thread, messageId)
|
|
222
|
+
},
|
|
223
|
+
...onThreadToggleResolved && {
|
|
224
|
+
onResolve: () => onThreadToggleResolved(thread)
|
|
225
|
+
},
|
|
226
|
+
...props
|
|
227
|
+
});
|
|
228
|
+
}) : /* @__PURE__ */ React2.createElement("div", {
|
|
269
229
|
role: "alert",
|
|
270
230
|
className: mx2(descriptionText, "place-self-center border border-dashed border-neutral-400/50 rounded-lg text-center p-4 m-4")
|
|
271
|
-
}, /* @__PURE__ */
|
|
231
|
+
}, /* @__PURE__ */ React2.createElement("h2", {
|
|
272
232
|
className: "mbe-2 font-medium text-baseText"
|
|
273
|
-
}, t("no comments title")), /* @__PURE__ */
|
|
233
|
+
}, t("no comments title")), /* @__PURE__ */ React2.createElement("p", null, /* @__PURE__ */ React2.createElement(Trans, {
|
|
274
234
|
t,
|
|
275
235
|
i18nKey: "no comments message",
|
|
276
236
|
components: {
|
|
277
|
-
commentIcon: /* @__PURE__ */
|
|
237
|
+
commentIcon: /* @__PURE__ */ React2.createElement(ChatText, {
|
|
278
238
|
className: "inline-block"
|
|
279
239
|
})
|
|
280
240
|
}
|
|
281
241
|
}))));
|
|
282
242
|
};
|
|
283
243
|
|
|
244
|
+
// packages/plugins/plugin-thread/src/components/ThreadComplementary.tsx
|
|
245
|
+
import React3, { useEffect as useEffect2, useMemo as useMemo2 } from "react";
|
|
246
|
+
import { LayoutAction, useIntentDispatcher, useResolvePlugins } from "@dxos/app-framework";
|
|
247
|
+
import { fullyQualifiedId as fullyQualifiedId3 } from "@dxos/react-client/echo";
|
|
248
|
+
import { ScrollArea } from "@dxos/react-ui";
|
|
249
|
+
import { useAttended } from "@dxos/react-ui-attention";
|
|
250
|
+
import { nonNullable as nonNullable2 } from "@dxos/util";
|
|
251
|
+
var providesThreadsConfig = (plugin) => "thread" in plugin.provides ? plugin : void 0;
|
|
252
|
+
var ThreadComplementary = ({ role, subject, drafts, current, showResolvedThreads }) => {
|
|
253
|
+
const dispatch = useIntentDispatcher();
|
|
254
|
+
const threadsIntegrators = useResolvePlugins(providesThreadsConfig);
|
|
255
|
+
const threadProvides = useMemo2(() => threadsIntegrators.map((p) => p.provides.thread), [
|
|
256
|
+
threadsIntegrators
|
|
257
|
+
]);
|
|
258
|
+
const createSort = useMemo2(() => threadProvides.find((p) => p.predicate(subject))?.createSort, [
|
|
259
|
+
threadProvides,
|
|
260
|
+
subject
|
|
261
|
+
]);
|
|
262
|
+
const sort = useMemo2(() => createSort?.(subject), [
|
|
263
|
+
createSort,
|
|
264
|
+
subject
|
|
265
|
+
]);
|
|
266
|
+
const threads2 = useMemo2(() => {
|
|
267
|
+
return subject.threads.concat(drafts ?? []).filter(nonNullable2);
|
|
268
|
+
}, [
|
|
269
|
+
JSON.stringify(subject.threads),
|
|
270
|
+
JSON.stringify(drafts)
|
|
271
|
+
]);
|
|
272
|
+
const detachedIds = useMemo2(() => {
|
|
273
|
+
return threads2.filter(({ anchor }) => !anchor).map((thread) => fullyQualifiedId3(thread));
|
|
274
|
+
}, [
|
|
275
|
+
threads2
|
|
276
|
+
]);
|
|
277
|
+
useEffect2(() => {
|
|
278
|
+
if (!sort) {
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
threads2.sort((a, b) => sort(a?.anchor, b?.anchor));
|
|
282
|
+
}, [
|
|
283
|
+
sort,
|
|
284
|
+
threads2
|
|
285
|
+
]);
|
|
286
|
+
const attended = useAttended();
|
|
287
|
+
const qualifiedSubjectId = fullyQualifiedId3(subject);
|
|
288
|
+
return /* @__PURE__ */ React3.createElement("div", {
|
|
289
|
+
role: "none",
|
|
290
|
+
className: "contents"
|
|
291
|
+
}, /* @__PURE__ */ React3.createElement(ScrollArea.Root, {
|
|
292
|
+
classNames: "row-span-2"
|
|
293
|
+
}, /* @__PURE__ */ React3.createElement(ScrollArea.Viewport, null, /* @__PURE__ */ React3.createElement(CommentsContainer, {
|
|
294
|
+
threads: threads2,
|
|
295
|
+
detached: detachedIds,
|
|
296
|
+
currentId: attended.includes(qualifiedSubjectId) ? current : void 0,
|
|
297
|
+
showResolvedThreads,
|
|
298
|
+
onThreadAttend: (thread) => {
|
|
299
|
+
const threadId = fullyQualifiedId3(thread);
|
|
300
|
+
if (current !== threadId) {
|
|
301
|
+
current = threadId;
|
|
302
|
+
void dispatch?.([
|
|
303
|
+
{
|
|
304
|
+
action: LayoutAction.SCROLL_INTO_VIEW,
|
|
305
|
+
data: {
|
|
306
|
+
id: fullyQualifiedId3(subject),
|
|
307
|
+
thread: threadId,
|
|
308
|
+
cursor: thread.anchor
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
]);
|
|
312
|
+
}
|
|
313
|
+
},
|
|
314
|
+
onThreadDelete: (thread) => {
|
|
315
|
+
return dispatch({
|
|
316
|
+
plugin: THREAD_PLUGIN,
|
|
317
|
+
action: ThreadAction.DELETE,
|
|
318
|
+
data: {
|
|
319
|
+
subject,
|
|
320
|
+
thread
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
},
|
|
324
|
+
onMessageDelete: (thread, messageId) => dispatch({
|
|
325
|
+
plugin: THREAD_PLUGIN,
|
|
326
|
+
action: ThreadAction.DELETE_MESSAGE,
|
|
327
|
+
data: {
|
|
328
|
+
subject,
|
|
329
|
+
thread,
|
|
330
|
+
messageId
|
|
331
|
+
}
|
|
332
|
+
}),
|
|
333
|
+
onThreadToggleResolved: (thread) => dispatch({
|
|
334
|
+
plugin: THREAD_PLUGIN,
|
|
335
|
+
action: ThreadAction.TOGGLE_RESOLVED,
|
|
336
|
+
data: {
|
|
337
|
+
thread
|
|
338
|
+
}
|
|
339
|
+
}),
|
|
340
|
+
onComment: (thread) => {
|
|
341
|
+
void dispatch({
|
|
342
|
+
action: ThreadAction.ON_MESSAGE_ADD,
|
|
343
|
+
data: {
|
|
344
|
+
thread,
|
|
345
|
+
subject
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
}), /* @__PURE__ */ React3.createElement("div", {
|
|
350
|
+
role: "none",
|
|
351
|
+
className: "bs-10"
|
|
352
|
+
}), /* @__PURE__ */ React3.createElement(ScrollArea.Scrollbar, null, /* @__PURE__ */ React3.createElement(ScrollArea.Thumb, null)))));
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
// packages/plugins/plugin-thread/src/components/ThreadSettings.tsx
|
|
356
|
+
import React4 from "react";
|
|
357
|
+
import { SettingsValue } from "@dxos/plugin-settings";
|
|
358
|
+
import { Input, useTranslation as useTranslation3 } from "@dxos/react-ui";
|
|
359
|
+
var ThreadSettings = ({ settings }) => {
|
|
360
|
+
const { t } = useTranslation3(THREAD_PLUGIN);
|
|
361
|
+
return /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(SettingsValue, {
|
|
362
|
+
label: t("settings standalone label")
|
|
363
|
+
}, /* @__PURE__ */ React4.createElement(Input.Switch, {
|
|
364
|
+
checked: settings.standalone,
|
|
365
|
+
onCheckedChange: (checked) => settings.standalone = !!checked
|
|
366
|
+
})));
|
|
367
|
+
};
|
|
368
|
+
|
|
284
369
|
// packages/plugins/plugin-thread/src/components/index.ts
|
|
285
|
-
var ThreadMain =
|
|
286
|
-
var ThreadArticle =
|
|
370
|
+
var ThreadMain = React5.lazy(() => import("./ThreadMain-PGF7W5EV.mjs"));
|
|
371
|
+
var ThreadArticle = React5.lazy(() => import("./ThreadArticle-GBPIH47W.mjs"));
|
|
372
|
+
|
|
373
|
+
// packages/plugins/plugin-thread/src/extensions/threads.ts
|
|
374
|
+
import { EditorView } from "@codemirror/view";
|
|
375
|
+
import { computed, effect } from "@preact/signals-core";
|
|
376
|
+
import { ThreadType } from "@dxos/plugin-space/types";
|
|
377
|
+
import { getSpace as getSpace2, getTextInRange, createDocAccessor, fullyQualifiedId as fullyQualifiedId4 } from "@dxos/react-client/echo";
|
|
378
|
+
import { comments, createExternalCommentSync } from "@dxos/react-ui-editor";
|
|
379
|
+
import { nonNullable as nonNullable3 } from "@dxos/util";
|
|
380
|
+
var getName = (doc, anchor) => {
|
|
381
|
+
if (doc.content) {
|
|
382
|
+
const [start, end] = anchor.split(":");
|
|
383
|
+
return getTextInRange(createDocAccessor(doc.content, [
|
|
384
|
+
"content"
|
|
385
|
+
]), start, end);
|
|
386
|
+
}
|
|
387
|
+
};
|
|
388
|
+
var threads = (state, doc, dispatch) => {
|
|
389
|
+
const space = doc && getSpace2(doc);
|
|
390
|
+
if (!doc || !space || !dispatch) {
|
|
391
|
+
return [
|
|
392
|
+
comments()
|
|
393
|
+
];
|
|
394
|
+
}
|
|
395
|
+
const threads2 = computed(() => [
|
|
396
|
+
...doc.threads.filter(nonNullable3),
|
|
397
|
+
...state.drafts[fullyQualifiedId4(doc)] ?? []
|
|
398
|
+
].filter((thread) => !(thread?.status === "resolved")));
|
|
399
|
+
return [
|
|
400
|
+
EditorView.updateListener.of((update) => {
|
|
401
|
+
if (update.docChanged) {
|
|
402
|
+
doc.threads.forEach((thread) => {
|
|
403
|
+
if (thread?.anchor) {
|
|
404
|
+
const name = getName(doc, thread.anchor);
|
|
405
|
+
if (name && name !== thread.name) {
|
|
406
|
+
thread.name = name;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
}),
|
|
412
|
+
createExternalCommentSync(fullyQualifiedId4(doc), (sink) => effect(() => sink()), () => threads2.value.filter((thread) => thread?.anchor).map((thread) => ({
|
|
413
|
+
id: fullyQualifiedId4(thread),
|
|
414
|
+
cursor: thread.anchor
|
|
415
|
+
}))),
|
|
416
|
+
comments({
|
|
417
|
+
id: fullyQualifiedId4(doc),
|
|
418
|
+
onCreate: ({ cursor }) => {
|
|
419
|
+
const name = getName(doc, cursor);
|
|
420
|
+
void dispatch({
|
|
421
|
+
action: ThreadAction.CREATE,
|
|
422
|
+
data: {
|
|
423
|
+
cursor,
|
|
424
|
+
name,
|
|
425
|
+
subject: doc
|
|
426
|
+
}
|
|
427
|
+
});
|
|
428
|
+
},
|
|
429
|
+
onDelete: ({ id }) => {
|
|
430
|
+
const draft = state.drafts[fullyQualifiedId4(doc)];
|
|
431
|
+
if (draft) {
|
|
432
|
+
const index = draft.findIndex((thread2) => fullyQualifiedId4(thread2) === id);
|
|
433
|
+
if (index !== -1) {
|
|
434
|
+
draft.splice(index, 1);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
const thread = doc.threads.find((thread2) => thread2?.id === id);
|
|
438
|
+
if (thread) {
|
|
439
|
+
thread.anchor = void 0;
|
|
440
|
+
}
|
|
441
|
+
},
|
|
442
|
+
onUpdate: ({ id, cursor }) => {
|
|
443
|
+
const thread = state.drafts[fullyQualifiedId4(doc)]?.find((thread2) => fullyQualifiedId4(thread2) === id) ?? doc.threads.find((thread2) => thread2?.id === id);
|
|
444
|
+
if (thread instanceof ThreadType && thread.anchor) {
|
|
445
|
+
thread.name = getName(doc, thread.anchor);
|
|
446
|
+
thread.anchor = cursor;
|
|
447
|
+
}
|
|
448
|
+
},
|
|
449
|
+
onSelect: ({ selection: { current, closest } }) => {
|
|
450
|
+
void dispatch({
|
|
451
|
+
action: ThreadAction.SELECT,
|
|
452
|
+
data: {
|
|
453
|
+
current: current ?? closest,
|
|
454
|
+
skipOpen: true
|
|
455
|
+
}
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
})
|
|
459
|
+
];
|
|
460
|
+
};
|
|
287
461
|
|
|
288
462
|
// packages/plugins/plugin-thread/src/translations.ts
|
|
289
463
|
var translations_default = [
|
|
@@ -322,14 +496,14 @@ var translations_default = [
|
|
|
322
496
|
];
|
|
323
497
|
|
|
324
498
|
// packages/plugins/plugin-thread/src/ThreadPlugin.tsx
|
|
499
|
+
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/plugins/plugin-thread/src/ThreadPlugin.tsx";
|
|
325
500
|
var initialViewState = {
|
|
326
501
|
showResolvedThreads: false
|
|
327
502
|
};
|
|
328
|
-
var providesThreadsConfig = (plugin) => "thread" in plugin.provides ? plugin : void 0;
|
|
329
503
|
var ThreadPlugin = () => {
|
|
330
504
|
const settings = new LocalStorageStore(THREAD_PLUGIN);
|
|
331
505
|
const state = create2({
|
|
332
|
-
|
|
506
|
+
drafts: {}
|
|
333
507
|
});
|
|
334
508
|
const viewStore = create2({});
|
|
335
509
|
const getViewState = (subjectId) => {
|
|
@@ -340,10 +514,8 @@ var ThreadPlugin = () => {
|
|
|
340
514
|
}
|
|
341
515
|
return viewStore[subjectId];
|
|
342
516
|
};
|
|
343
|
-
let attentionPlugin;
|
|
344
517
|
let navigationPlugin;
|
|
345
518
|
let intentPlugin;
|
|
346
|
-
let dispatch;
|
|
347
519
|
const unsubscribeCallbacks = [];
|
|
348
520
|
return {
|
|
349
521
|
meta: meta_default,
|
|
@@ -354,36 +526,8 @@ var ThreadPlugin = () => {
|
|
|
354
526
|
allowUndefined: true
|
|
355
527
|
})
|
|
356
528
|
});
|
|
357
|
-
attentionPlugin = resolvePlugin(plugins, parseAttentionPlugin);
|
|
358
529
|
navigationPlugin = resolvePlugin(plugins, parseNavigationPlugin);
|
|
359
530
|
intentPlugin = resolvePlugin(plugins, parseIntentPlugin);
|
|
360
|
-
dispatch = intentPlugin?.provides.intent.dispatch;
|
|
361
|
-
const graphPlugin = resolvePlugin(plugins, parseGraphPlugin);
|
|
362
|
-
const client = resolvePlugin(plugins, parseClientPlugin)?.provides.client;
|
|
363
|
-
if (!client) {
|
|
364
|
-
return;
|
|
365
|
-
}
|
|
366
|
-
const channelsQuery = client.spaces.query(Filter.schema(ChannelType));
|
|
367
|
-
const queryUnsubscribe = channelsQuery.subscribe();
|
|
368
|
-
const unsubscribe = effect(() => {
|
|
369
|
-
const attention = attentionPlugin?.provides.attention;
|
|
370
|
-
if (!attention?.attended) {
|
|
371
|
-
return;
|
|
372
|
-
}
|
|
373
|
-
const firstAttendedNodeWithComments = Array.from(attention.attended).map((id) => graphPlugin?.provides.graph.findNode(id)).find((node) => node?.data instanceof DocumentType && (node.data.threads?.length ?? 0) > 0);
|
|
374
|
-
if (firstAttendedNodeWithComments) {
|
|
375
|
-
void intentPlugin?.provides.intent.dispatch({
|
|
376
|
-
action: NavigationAction.OPEN,
|
|
377
|
-
data: {
|
|
378
|
-
activeParts: {
|
|
379
|
-
complementary: `${firstAttendedNodeWithComments.id}${SLUG_PATH_SEPARATOR}comments`
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
});
|
|
383
|
-
}
|
|
384
|
-
});
|
|
385
|
-
unsubscribeCallbacks.push(queryUnsubscribe);
|
|
386
|
-
unsubscribeCallbacks.push(unsubscribe);
|
|
387
531
|
},
|
|
388
532
|
unload: async () => {
|
|
389
533
|
unsubscribeCallbacks.forEach((unsubscribe) => unsubscribe());
|
|
@@ -399,12 +543,11 @@ var ThreadPlugin = () => {
|
|
|
399
543
|
ns: THREAD_PLUGIN
|
|
400
544
|
}
|
|
401
545
|
],
|
|
402
|
-
icon:
|
|
403
|
-
iconSymbol: "ph--chat--regular",
|
|
546
|
+
icon: "ph--chat--regular",
|
|
404
547
|
// TODO(wittjosiah): Move out of metadata.
|
|
405
548
|
loadReferences: (channel) => loadObjectReferences(channel, (channel2) => channel2.threads)
|
|
406
549
|
},
|
|
407
|
-
[
|
|
550
|
+
[ThreadType2.typename]: {
|
|
408
551
|
// TODO(wittjosiah): Move out of metadata.
|
|
409
552
|
loadReferences: (thread) => loadObjectReferences(thread, (thread2) => thread2.messages)
|
|
410
553
|
},
|
|
@@ -440,16 +583,16 @@ var ThreadPlugin = () => {
|
|
|
440
583
|
echo: {
|
|
441
584
|
schema: [
|
|
442
585
|
ChannelType,
|
|
443
|
-
|
|
586
|
+
ThreadType2,
|
|
444
587
|
MessageType2
|
|
445
588
|
]
|
|
446
589
|
},
|
|
447
590
|
graph: {
|
|
448
591
|
builder: (plugins) => {
|
|
449
592
|
const client = resolvePlugin(plugins, parseClientPlugin)?.provides.client;
|
|
450
|
-
const
|
|
593
|
+
const dispatch = resolvePlugin(plugins, parseIntentPlugin)?.provides.intent.dispatch;
|
|
451
594
|
const metadataResolver = resolvePlugin(plugins, parseMetadataResolverPlugin)?.provides.metadata.resolver;
|
|
452
|
-
if (!client || !
|
|
595
|
+
if (!client || !dispatch || !metadataResolver) {
|
|
453
596
|
return [];
|
|
454
597
|
}
|
|
455
598
|
return [
|
|
@@ -459,29 +602,36 @@ var ThreadPlugin = () => {
|
|
|
459
602
|
if (!id.endsWith("~comments")) {
|
|
460
603
|
return;
|
|
461
604
|
}
|
|
462
|
-
const
|
|
463
|
-
const [spaceId, objectId] =
|
|
605
|
+
const [subjectId] = id.split("~");
|
|
606
|
+
const [spaceId, objectId] = parseFullyQualifiedId(subjectId);
|
|
464
607
|
const space = client.spaces.get().find((space2) => space2.id === spaceId);
|
|
465
|
-
const
|
|
466
|
-
|
|
608
|
+
const object = toSignal((onChange) => {
|
|
609
|
+
const timeout = setTimeout(async () => {
|
|
610
|
+
await space?.db.loadObjectById(objectId);
|
|
611
|
+
onChange();
|
|
612
|
+
});
|
|
613
|
+
return () => clearTimeout(timeout);
|
|
614
|
+
}, () => space?.db.getObjectById(objectId), subjectId);
|
|
615
|
+
if (!object || !subjectId) {
|
|
467
616
|
return;
|
|
468
617
|
}
|
|
469
|
-
const
|
|
470
|
-
const label =
|
|
618
|
+
const meta = metadataResolver(getTypename(object) ?? "");
|
|
619
|
+
const label = meta.label?.(object) || object.name || meta.placeholder || [
|
|
471
620
|
"unnamed object threads label",
|
|
472
621
|
{
|
|
473
622
|
ns: THREAD_PLUGIN
|
|
474
623
|
}
|
|
475
624
|
];
|
|
476
|
-
const viewState = getViewState(
|
|
625
|
+
const viewState = getViewState(subjectId);
|
|
477
626
|
return {
|
|
478
627
|
id,
|
|
479
628
|
type: "orphan-comments-for-subject",
|
|
480
|
-
data:
|
|
629
|
+
data: null,
|
|
481
630
|
properties: {
|
|
482
|
-
icon:
|
|
631
|
+
icon: "ph--chat-text--regular",
|
|
483
632
|
label,
|
|
484
|
-
showResolvedThreads: viewState.showResolvedThreads
|
|
633
|
+
showResolvedThreads: viewState.showResolvedThreads,
|
|
634
|
+
object
|
|
485
635
|
}
|
|
486
636
|
};
|
|
487
637
|
},
|
|
@@ -495,7 +645,7 @@ var ThreadPlugin = () => {
|
|
|
495
645
|
const toggle = () => {
|
|
496
646
|
const newToggleState = !viewState.showResolvedThreads;
|
|
497
647
|
viewState.showResolvedThreads = newToggleState;
|
|
498
|
-
void
|
|
648
|
+
void dispatch({
|
|
499
649
|
action: ObservabilityAction.SEND_EVENT,
|
|
500
650
|
data: {
|
|
501
651
|
name: "threads.toggle-show-resolved",
|
|
@@ -520,7 +670,8 @@ var ThreadPlugin = () => {
|
|
|
520
670
|
],
|
|
521
671
|
menuItemType: "toggle",
|
|
522
672
|
isChecked: viewState.showResolvedThreads,
|
|
523
|
-
testId: "threadPlugin.toggleShowResolved"
|
|
673
|
+
testId: "threadPlugin.toggleShowResolved",
|
|
674
|
+
icon: viewState.showResolvedThreads ? "ph--eye-slash--regular" : "ph--eye--regular"
|
|
524
675
|
}
|
|
525
676
|
}
|
|
526
677
|
];
|
|
@@ -542,7 +693,7 @@ var ThreadPlugin = () => {
|
|
|
542
693
|
{
|
|
543
694
|
id: `${THREAD_PLUGIN}/create/${node.id}`,
|
|
544
695
|
data: async () => {
|
|
545
|
-
await
|
|
696
|
+
await dispatch([
|
|
546
697
|
{
|
|
547
698
|
plugin: THREAD_PLUGIN,
|
|
548
699
|
action: ThreadAction.CREATE
|
|
@@ -565,8 +716,7 @@ var ThreadPlugin = () => {
|
|
|
565
716
|
ns: THREAD_PLUGIN
|
|
566
717
|
}
|
|
567
718
|
],
|
|
568
|
-
icon:
|
|
569
|
-
iconSymbol: "ph--chat--regular",
|
|
719
|
+
icon: "ph--chat--regular",
|
|
570
720
|
testId: "threadPlugin.createObject"
|
|
571
721
|
}
|
|
572
722
|
}
|
|
@@ -580,20 +730,17 @@ var ThreadPlugin = () => {
|
|
|
580
730
|
component: ({ data, role }) => {
|
|
581
731
|
switch (role) {
|
|
582
732
|
case "main": {
|
|
583
|
-
return data.active instanceof ChannelType && data.active.threads[0] ? /* @__PURE__ */
|
|
733
|
+
return data.active instanceof ChannelType && data.active.threads[0] ? /* @__PURE__ */ React6.createElement(ThreadMain, {
|
|
584
734
|
thread: data.active.threads[0]
|
|
585
735
|
}) : null;
|
|
586
736
|
}
|
|
587
737
|
case "settings": {
|
|
588
|
-
return data.plugin === meta_default.id ? /* @__PURE__ */
|
|
738
|
+
return data.plugin === meta_default.id ? /* @__PURE__ */ React6.createElement(ThreadSettings, {
|
|
589
739
|
settings: settings.values
|
|
590
740
|
}) : null;
|
|
591
741
|
}
|
|
592
|
-
case "article":
|
|
593
|
-
case "complementary": {
|
|
742
|
+
case "article": {
|
|
594
743
|
const location = navigationPlugin?.provides.location;
|
|
595
|
-
const threadsIntegrators = useResolvePlugins(providesThreadsConfig);
|
|
596
|
-
const threadProvides = threadsIntegrators.map((p) => p.provides.thread);
|
|
597
744
|
if (data.object instanceof ChannelType && data.object.threads[0]) {
|
|
598
745
|
const channel = data.object;
|
|
599
746
|
if (isLayoutParts(location?.active) && location.active.main) {
|
|
@@ -601,103 +748,38 @@ var ThreadPlugin = () => {
|
|
|
601
748
|
const currentPosition = layoutEntries.findIndex((entry) => channel.id === entry.id);
|
|
602
749
|
if (currentPosition > 0) {
|
|
603
750
|
const objectToTheLeft = layoutEntries[currentPosition - 1];
|
|
604
|
-
const context =
|
|
605
|
-
return /* @__PURE__ */
|
|
751
|
+
const context = getSpace3(data.object)?.db.getObjectById(objectToTheLeft.id);
|
|
752
|
+
return /* @__PURE__ */ React6.createElement(ThreadArticle, {
|
|
606
753
|
thread: data.object.threads[0],
|
|
607
754
|
context
|
|
608
755
|
});
|
|
609
756
|
}
|
|
610
757
|
}
|
|
611
|
-
return /* @__PURE__ */
|
|
758
|
+
return /* @__PURE__ */ React6.createElement(ThreadArticle, {
|
|
612
759
|
thread: data.object.threads[0]
|
|
613
760
|
});
|
|
614
761
|
}
|
|
615
|
-
if (data.subject instanceof
|
|
616
|
-
return /* @__PURE__ */
|
|
762
|
+
if (data.subject instanceof ThreadType2) {
|
|
763
|
+
return /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(ChatHeading, {
|
|
617
764
|
attendableId: data.subject.id
|
|
618
|
-
}), /* @__PURE__ */
|
|
765
|
+
}), /* @__PURE__ */ React6.createElement(ChatContainer, {
|
|
619
766
|
thread: data.subject
|
|
620
767
|
}));
|
|
621
768
|
}
|
|
769
|
+
break;
|
|
770
|
+
}
|
|
771
|
+
case "complementary--comments": {
|
|
622
772
|
if (data.subject && typeof data.subject === "object" && "threads" in data.subject && Array.isArray(data.subject.threads)) {
|
|
623
|
-
const
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
const attention = attentionPlugin?.provides.attention?.attended ?? /* @__PURE__ */ new Set([
|
|
632
|
-
qualifiedSubjectId
|
|
633
|
-
]);
|
|
634
|
-
const attendableAttrs = createAttendableAttributes(qualifiedSubjectId);
|
|
635
|
-
const { showResolvedThreads } = getViewState(qualifiedSubjectId);
|
|
636
|
-
return /* @__PURE__ */ React5.createElement("div", {
|
|
637
|
-
role: "none",
|
|
638
|
-
className: "contents group/attention",
|
|
639
|
-
...attendableAttrs
|
|
640
|
-
}, role === "complementary" && /* @__PURE__ */ React5.createElement(CommentsHeading, {
|
|
641
|
-
attendableId: qualifiedSubjectId
|
|
642
|
-
}), /* @__PURE__ */ React5.createElement(ScrollArea.Root, {
|
|
643
|
-
classNames: "row-span-2"
|
|
644
|
-
}, /* @__PURE__ */ React5.createElement(ScrollArea.Viewport, null, /* @__PURE__ */ React5.createElement(CommentsContainer, {
|
|
645
|
-
threads,
|
|
646
|
-
detached,
|
|
647
|
-
currentId: attention.has(qualifiedSubjectId) ? state.current : void 0,
|
|
648
|
-
autoFocusCurrentTextbox: state.focus,
|
|
649
|
-
showResolvedThreads,
|
|
650
|
-
onThreadAttend: (thread) => {
|
|
651
|
-
if (state.current !== thread.id) {
|
|
652
|
-
state.current = thread.id;
|
|
653
|
-
void dispatch?.({
|
|
654
|
-
action: LayoutAction.SCROLL_INTO_VIEW,
|
|
655
|
-
data: {
|
|
656
|
-
id: fullyQualifiedId(data.subject),
|
|
657
|
-
thread: fullyQualifiedId(thread),
|
|
658
|
-
cursor: thread.anchor
|
|
659
|
-
}
|
|
660
|
-
});
|
|
661
|
-
}
|
|
662
|
-
},
|
|
663
|
-
onThreadDelete: (thread) => dispatch?.({
|
|
664
|
-
plugin: THREAD_PLUGIN,
|
|
665
|
-
action: ThreadAction.DELETE,
|
|
666
|
-
data: {
|
|
667
|
-
subject: data.subject,
|
|
668
|
-
thread
|
|
669
|
-
}
|
|
670
|
-
}),
|
|
671
|
-
onMessageDelete: (thread, messageId) => dispatch?.({
|
|
672
|
-
plugin: THREAD_PLUGIN,
|
|
673
|
-
action: ThreadAction.DELETE_MESSAGE,
|
|
674
|
-
data: {
|
|
675
|
-
subject: data.subject,
|
|
676
|
-
thread,
|
|
677
|
-
messageId
|
|
678
|
-
}
|
|
679
|
-
}),
|
|
680
|
-
onThreadToggleResolved: (thread) => dispatch?.({
|
|
681
|
-
plugin: THREAD_PLUGIN,
|
|
682
|
-
action: ThreadAction.TOGGLE_RESOLVED,
|
|
683
|
-
data: {
|
|
684
|
-
thread
|
|
685
|
-
}
|
|
686
|
-
}),
|
|
687
|
-
onComment: (thread) => {
|
|
688
|
-
void intentPlugin?.provides.intent.dispatch({
|
|
689
|
-
action: ThreadAction.ON_MESSAGE_ADD,
|
|
690
|
-
data: {
|
|
691
|
-
thread,
|
|
692
|
-
subject: data.subject
|
|
693
|
-
}
|
|
694
|
-
});
|
|
695
|
-
}
|
|
696
|
-
}), /* @__PURE__ */ React5.createElement("div", {
|
|
697
|
-
role: "none",
|
|
698
|
-
className: "bs-10"
|
|
699
|
-
}), /* @__PURE__ */ React5.createElement(ScrollArea.Scrollbar, null, /* @__PURE__ */ React5.createElement(ScrollArea.Thumb, null)))));
|
|
773
|
+
const { showResolvedThreads } = getViewState(fullyQualifiedId5(data.subject));
|
|
774
|
+
return /* @__PURE__ */ React6.createElement(ThreadComplementary, {
|
|
775
|
+
role,
|
|
776
|
+
subject: data.subject,
|
|
777
|
+
drafts: state.drafts[fullyQualifiedId5(data.subject)],
|
|
778
|
+
current: state.current,
|
|
779
|
+
showResolvedThreads
|
|
780
|
+
});
|
|
700
781
|
}
|
|
782
|
+
break;
|
|
701
783
|
}
|
|
702
784
|
}
|
|
703
785
|
return null;
|
|
@@ -709,18 +791,31 @@ var ThreadPlugin = () => {
|
|
|
709
791
|
case ThreadAction.CREATE: {
|
|
710
792
|
if (intent.data && intent.data.cursor !== void 0) {
|
|
711
793
|
const { cursor, name, subject } = intent.data;
|
|
712
|
-
|
|
713
|
-
|
|
794
|
+
if (subject?.threads === void 0) {
|
|
795
|
+
try {
|
|
796
|
+
subject.threads = [];
|
|
797
|
+
} catch (err) {
|
|
798
|
+
log.error("Subject does not support threads array", subject?.typename, {
|
|
799
|
+
F: __dxlog_file,
|
|
800
|
+
L: 327,
|
|
801
|
+
S: void 0,
|
|
802
|
+
C: (f, a) => f(...a)
|
|
803
|
+
});
|
|
804
|
+
return;
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
const subjectId = fullyQualifiedId5(subject);
|
|
808
|
+
const thread = create2(ThreadType2, {
|
|
714
809
|
name,
|
|
715
810
|
anchor: cursor,
|
|
716
811
|
messages: [],
|
|
717
812
|
status: "staged"
|
|
718
813
|
});
|
|
719
|
-
const
|
|
720
|
-
if (
|
|
721
|
-
|
|
814
|
+
const draft = state.drafts[subjectId];
|
|
815
|
+
if (draft) {
|
|
816
|
+
draft.push(thread);
|
|
722
817
|
} else {
|
|
723
|
-
state.
|
|
818
|
+
state.drafts[subjectId] = [
|
|
724
819
|
thread
|
|
725
820
|
];
|
|
726
821
|
}
|
|
@@ -728,27 +823,20 @@ var ThreadPlugin = () => {
|
|
|
728
823
|
data: thread,
|
|
729
824
|
intents: [
|
|
730
825
|
[
|
|
731
|
-
{
|
|
732
|
-
action: NavigationAction.OPEN,
|
|
733
|
-
data: {
|
|
734
|
-
activeParts: {
|
|
735
|
-
complementary: `${subjectId}${SLUG_PATH_SEPARATOR}comments${SLUG_COLLECTION_INDICATOR}`
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
},
|
|
739
826
|
{
|
|
740
827
|
action: ThreadAction.SELECT,
|
|
741
828
|
data: {
|
|
742
|
-
current: thread
|
|
743
|
-
focus: true
|
|
829
|
+
current: fullyQualifiedId5(thread)
|
|
744
830
|
}
|
|
745
|
-
}
|
|
831
|
+
}
|
|
832
|
+
],
|
|
833
|
+
[
|
|
746
834
|
{
|
|
747
|
-
action:
|
|
835
|
+
action: NavigationAction.OPEN,
|
|
748
836
|
data: {
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
837
|
+
activeParts: {
|
|
838
|
+
complementary: "comments"
|
|
839
|
+
}
|
|
752
840
|
}
|
|
753
841
|
}
|
|
754
842
|
]
|
|
@@ -758,7 +846,7 @@ var ThreadPlugin = () => {
|
|
|
758
846
|
return {
|
|
759
847
|
data: create2(ChannelType, {
|
|
760
848
|
threads: [
|
|
761
|
-
create2(
|
|
849
|
+
create2(ThreadType2, {
|
|
762
850
|
messages: []
|
|
763
851
|
})
|
|
764
852
|
]
|
|
@@ -767,15 +855,26 @@ var ThreadPlugin = () => {
|
|
|
767
855
|
}
|
|
768
856
|
}
|
|
769
857
|
case ThreadAction.SELECT: {
|
|
770
|
-
state.focus = intent.data?.current === state.current ? state.focus : intent.data?.focus;
|
|
771
858
|
state.current = intent.data?.current;
|
|
772
859
|
return {
|
|
773
|
-
data: true
|
|
860
|
+
data: true,
|
|
861
|
+
intents: !intent.data?.skipOpen ? [
|
|
862
|
+
[
|
|
863
|
+
{
|
|
864
|
+
action: NavigationAction.OPEN,
|
|
865
|
+
data: {
|
|
866
|
+
activeParts: {
|
|
867
|
+
complementary: "comments"
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
]
|
|
872
|
+
] : []
|
|
774
873
|
};
|
|
775
874
|
}
|
|
776
875
|
case ThreadAction.TOGGLE_RESOLVED: {
|
|
777
876
|
const { thread } = intent.data ?? {};
|
|
778
|
-
if (!(thread instanceof
|
|
877
|
+
if (!(thread instanceof ThreadType2)) {
|
|
779
878
|
return;
|
|
780
879
|
}
|
|
781
880
|
if (thread.status === "active" || thread.status === void 0) {
|
|
@@ -783,9 +882,10 @@ var ThreadPlugin = () => {
|
|
|
783
882
|
} else if (thread.status === "resolved") {
|
|
784
883
|
thread.status = "active";
|
|
785
884
|
}
|
|
786
|
-
const space =
|
|
885
|
+
const space = getSpace3(thread);
|
|
787
886
|
const spaceId = space?.id;
|
|
788
887
|
return {
|
|
888
|
+
data: true,
|
|
789
889
|
intents: [
|
|
790
890
|
[
|
|
791
891
|
{
|
|
@@ -804,19 +904,21 @@ var ThreadPlugin = () => {
|
|
|
804
904
|
}
|
|
805
905
|
case ThreadAction.DELETE: {
|
|
806
906
|
const { subject, thread } = intent.data ?? {};
|
|
807
|
-
if (!(
|
|
907
|
+
if (!(thread instanceof ThreadType2) || !(subject && typeof subject === "object" && "threads" in subject)) {
|
|
808
908
|
return;
|
|
809
909
|
}
|
|
810
|
-
const subjectId =
|
|
811
|
-
const
|
|
812
|
-
if (
|
|
813
|
-
const index =
|
|
910
|
+
const subjectId = fullyQualifiedId5(subject);
|
|
911
|
+
const draft = state.drafts[subjectId];
|
|
912
|
+
if (draft) {
|
|
913
|
+
const index = draft.findIndex((t) => t.id === thread.id);
|
|
814
914
|
if (index !== -1) {
|
|
815
|
-
|
|
816
|
-
return
|
|
915
|
+
draft.splice(index, 1);
|
|
916
|
+
return {
|
|
917
|
+
data: true
|
|
918
|
+
};
|
|
817
919
|
}
|
|
818
920
|
}
|
|
819
|
-
const space =
|
|
921
|
+
const space = getSpace3(thread);
|
|
820
922
|
if (!space || !subject.threads) {
|
|
821
923
|
return;
|
|
822
924
|
}
|
|
@@ -874,22 +976,22 @@ var ThreadPlugin = () => {
|
|
|
874
976
|
}
|
|
875
977
|
case ThreadAction.ON_MESSAGE_ADD: {
|
|
876
978
|
const { thread, subject } = intent.data ?? {};
|
|
877
|
-
if (!(thread instanceof
|
|
979
|
+
if (!(thread instanceof ThreadType2) || !(subject && typeof subject === "object" && "threads" in subject && Array.isArray(subject.threads))) {
|
|
878
980
|
return;
|
|
879
981
|
}
|
|
880
|
-
const subjectId =
|
|
881
|
-
const space =
|
|
982
|
+
const subjectId = fullyQualifiedId5(subject);
|
|
983
|
+
const space = getSpace3(subject);
|
|
882
984
|
const intents = [];
|
|
883
985
|
const analyticsProperties = {
|
|
884
986
|
threadId: thread.id,
|
|
885
987
|
spaceId: space?.id
|
|
886
988
|
};
|
|
887
|
-
if (state.
|
|
989
|
+
if (state.drafts[subjectId]?.find((t) => t === thread)) {
|
|
888
990
|
thread.status = "active";
|
|
889
991
|
subject.threads ? subject.threads.push(thread) : subject.threads = [
|
|
890
992
|
thread
|
|
891
993
|
];
|
|
892
|
-
state.
|
|
994
|
+
state.drafts[subjectId] = state.drafts[subjectId]?.filter(({ id }) => id !== thread.id);
|
|
893
995
|
intents.push({
|
|
894
996
|
action: ObservabilityAction.SEND_EVENT,
|
|
895
997
|
data: {
|
|
@@ -917,8 +1019,8 @@ var ThreadPlugin = () => {
|
|
|
917
1019
|
}
|
|
918
1020
|
case ThreadAction.DELETE_MESSAGE: {
|
|
919
1021
|
const { subject, thread, messageId } = intent.data ?? {};
|
|
920
|
-
const space =
|
|
921
|
-
if (!(
|
|
1022
|
+
const space = getSpace3(subject);
|
|
1023
|
+
if (!(thread instanceof ThreadType2) || !(subject && typeof subject === "object" && "threads" in subject)) {
|
|
922
1024
|
return;
|
|
923
1025
|
}
|
|
924
1026
|
if (!intent.undo) {
|
|
@@ -960,7 +1062,7 @@ var ThreadPlugin = () => {
|
|
|
960
1062
|
name: "threads.message.delete",
|
|
961
1063
|
properties: {
|
|
962
1064
|
threadId: thread.id,
|
|
963
|
-
spaceId: space
|
|
1065
|
+
spaceId: space?.id
|
|
964
1066
|
}
|
|
965
1067
|
}
|
|
966
1068
|
}
|
|
@@ -984,7 +1086,7 @@ var ThreadPlugin = () => {
|
|
|
984
1086
|
name: "threads.message.undo-delete",
|
|
985
1087
|
properties: {
|
|
986
1088
|
threadId: thread.id,
|
|
987
|
-
spaceId: space
|
|
1089
|
+
spaceId: space?.id
|
|
988
1090
|
}
|
|
989
1091
|
}
|
|
990
1092
|
}
|
|
@@ -997,92 +1099,8 @@ var ThreadPlugin = () => {
|
|
|
997
1099
|
}
|
|
998
1100
|
},
|
|
999
1101
|
markdown: {
|
|
1000
|
-
// TODO(burdon): Factor out extension factory into separate file (for simplicity).
|
|
1001
1102
|
extensions: ({ document: doc }) => {
|
|
1002
|
-
|
|
1003
|
-
if (!doc || !space) {
|
|
1004
|
-
return [
|
|
1005
|
-
comments()
|
|
1006
|
-
];
|
|
1007
|
-
}
|
|
1008
|
-
const threads = computed(() => [
|
|
1009
|
-
...doc.threads.filter(nonNullable2),
|
|
1010
|
-
...state.staging[fullyQualifiedId(doc)] ?? []
|
|
1011
|
-
].filter((thread) => !(thread?.status === "resolved")));
|
|
1012
|
-
return [
|
|
1013
|
-
listener2({
|
|
1014
|
-
onChange: () => {
|
|
1015
|
-
doc.threads.forEach((thread) => {
|
|
1016
|
-
if (thread?.anchor) {
|
|
1017
|
-
const [start, end] = thread.anchor.split(":");
|
|
1018
|
-
const name = doc.content && getTextInRange(createDocAccessor(doc.content, [
|
|
1019
|
-
"content"
|
|
1020
|
-
]), start, end);
|
|
1021
|
-
if (name && name !== thread.name) {
|
|
1022
|
-
thread.name = name;
|
|
1023
|
-
}
|
|
1024
|
-
}
|
|
1025
|
-
});
|
|
1026
|
-
}
|
|
1027
|
-
}),
|
|
1028
|
-
createExternalCommentSync(doc.id, (sink) => effect(() => sink()), () => threads.value.filter((thread) => thread?.anchor).map((thread) => ({
|
|
1029
|
-
id: thread.id,
|
|
1030
|
-
cursor: thread.anchor
|
|
1031
|
-
}))),
|
|
1032
|
-
comments({
|
|
1033
|
-
id: doc.id,
|
|
1034
|
-
onCreate: ({ cursor }) => {
|
|
1035
|
-
const [start, end] = cursor.split(":");
|
|
1036
|
-
const name = doc.content && getTextInRange(createDocAccessor(doc.content, [
|
|
1037
|
-
"content"
|
|
1038
|
-
]), start, end);
|
|
1039
|
-
void intentPlugin?.provides.intent.dispatch({
|
|
1040
|
-
action: ThreadAction.CREATE,
|
|
1041
|
-
data: {
|
|
1042
|
-
cursor,
|
|
1043
|
-
name,
|
|
1044
|
-
subject: doc
|
|
1045
|
-
}
|
|
1046
|
-
});
|
|
1047
|
-
},
|
|
1048
|
-
onDelete: ({ id }) => {
|
|
1049
|
-
const stagingArea = state.staging[fullyQualifiedId(doc)];
|
|
1050
|
-
if (stagingArea) {
|
|
1051
|
-
const index = stagingArea.findIndex((thread2) => thread2.id === id);
|
|
1052
|
-
if (index !== -1) {
|
|
1053
|
-
stagingArea.splice(index, 1);
|
|
1054
|
-
}
|
|
1055
|
-
}
|
|
1056
|
-
const thread = doc.threads.find((thread2) => thread2?.id === id);
|
|
1057
|
-
if (thread) {
|
|
1058
|
-
thread.anchor = void 0;
|
|
1059
|
-
}
|
|
1060
|
-
},
|
|
1061
|
-
onUpdate: ({ id, cursor }) => {
|
|
1062
|
-
const thread = state.staging[fullyQualifiedId(doc)]?.find((thread2) => thread2.id === id) ?? doc.threads.find((thread2) => thread2?.id === id);
|
|
1063
|
-
if (thread instanceof ThreadType && thread.anchor) {
|
|
1064
|
-
const [start, end] = thread.anchor.split(":");
|
|
1065
|
-
thread.name = doc.content && getTextInRange(createDocAccessor(doc.content, [
|
|
1066
|
-
"content"
|
|
1067
|
-
]), start, end);
|
|
1068
|
-
thread.anchor = cursor;
|
|
1069
|
-
}
|
|
1070
|
-
},
|
|
1071
|
-
onSelect: ({ selection: { current, closest } }) => {
|
|
1072
|
-
const dispatch2 = intentPlugin?.provides.intent.dispatch;
|
|
1073
|
-
if (dispatch2) {
|
|
1074
|
-
void dispatch2([
|
|
1075
|
-
{
|
|
1076
|
-
action: ThreadAction.SELECT,
|
|
1077
|
-
data: {
|
|
1078
|
-
current: current ?? closest
|
|
1079
|
-
}
|
|
1080
|
-
}
|
|
1081
|
-
]);
|
|
1082
|
-
}
|
|
1083
|
-
}
|
|
1084
|
-
})
|
|
1085
|
-
];
|
|
1103
|
+
return threads(state, doc, intentPlugin?.provides.intent.dispatch);
|
|
1086
1104
|
}
|
|
1087
1105
|
}
|
|
1088
1106
|
}
|