@dxos/plugin-thread 0.6.13-main.ed424a1 → 0.6.13-staging.1e988a3
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-53PBPWLD.mjs → ThreadArticle-O64ZECMF.mjs} +3 -3
- package/dist/lib/browser/{ThreadMain-FZAZVPHO.mjs → ThreadMain-ZDCRC6RG.mjs} +3 -3
- package/dist/lib/browser/chunk-5IBJO53M.mjs +21 -0
- package/dist/lib/browser/chunk-5IBJO53M.mjs.map +7 -0
- package/dist/lib/browser/{chunk-JFQZ5W2I.mjs → chunk-GKPZHUT3.mjs} +2 -2
- package/dist/lib/browser/{chunk-JFQZ5W2I.mjs.map → chunk-GKPZHUT3.mjs.map} +1 -1
- package/dist/lib/browser/{chunk-DIFHKCVY.mjs → chunk-P7ZE5N5M.mjs} +11 -13
- package/dist/lib/browser/chunk-P7ZE5N5M.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +393 -411
- 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-UORKW5YD.cjs → ThreadArticle-DO56JXBU.cjs} +7 -7
- package/dist/lib/node/{ThreadMain-FVSLLIWS.cjs → ThreadMain-XJX75GHG.cjs} +7 -7
- package/dist/lib/node/{chunk-FK2N2QH7.cjs → chunk-5PZNPPQF.cjs} +63 -65
- package/dist/lib/node/chunk-5PZNPPQF.cjs.map +7 -0
- package/dist/lib/node/{chunk-JIJ7Z6NO.cjs → chunk-BWBONZGU.cjs} +22 -7
- package/dist/lib/node/chunk-BWBONZGU.cjs.map +7 -0
- package/dist/lib/node/{chunk-FOZUQZF4.cjs → chunk-D5GOVXHS.cjs} +6 -6
- package/dist/lib/node/{chunk-FOZUQZF4.cjs.map → chunk-D5GOVXHS.cjs.map} +1 -1
- package/dist/lib/node/index.cjs +441 -455
- 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/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 +5 -1
- 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/index.d.ts +3 -4
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/components/testing.d.ts +0 -2
- package/dist/types/src/components/testing.d.ts.map +1 -1
- package/dist/types/src/components/types.d.ts +2 -2
- package/dist/types/src/components/types.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +9 -3
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +1 -6
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/types/src/types.test.d.ts +2 -0
- package/dist/types/src/types.test.d.ts.map +1 -0
- package/package.json +37 -40
- package/src/ThreadPlugin.tsx +310 -120
- package/src/components/ChatContainer.tsx +8 -7
- package/src/components/CommentContainer.tsx +19 -18
- package/src/components/Comments.stories.tsx +2 -2
- package/src/components/CommentsContainer.tsx +31 -18
- package/src/components/MessageContainer.tsx +3 -3
- package/src/components/index.ts +2 -3
- package/src/components/types.ts +2 -2
- package/src/meta.tsx +20 -0
- package/src/types.test.ts +13 -0
- package/src/types.ts +3 -8
- package/dist/lib/browser/chunk-5G3KL6TC.mjs +0 -16
- package/dist/lib/browser/chunk-5G3KL6TC.mjs.map +0 -7
- package/dist/lib/browser/chunk-DIFHKCVY.mjs.map +0 -7
- package/dist/lib/node/chunk-FK2N2QH7.cjs.map +0 -7
- package/dist/lib/node/chunk-JIJ7Z6NO.cjs.map +0 -7
- package/dist/lib/node-esm/ThreadArticle-E4MLJZIM.mjs +0 -19
- package/dist/lib/node-esm/ThreadArticle-E4MLJZIM.mjs.map +0 -7
- package/dist/lib/node-esm/ThreadMain-Y6JU6S7A.mjs +0 -27
- package/dist/lib/node-esm/ThreadMain-Y6JU6S7A.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-DC5ZA6H5.mjs +0 -18
- package/dist/lib/node-esm/chunk-DC5ZA6H5.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-SJEUDBZV.mjs +0 -413
- package/dist/lib/node-esm/chunk-SJEUDBZV.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-ZXIPFXSA.mjs +0 -21
- package/dist/lib/node-esm/chunk-ZXIPFXSA.mjs.map +0 -7
- package/dist/lib/node-esm/index.mjs +0 -1121
- package/dist/lib/node-esm/index.mjs.map +0 -7
- package/dist/lib/node-esm/meta.json +0 -1
- package/dist/lib/node-esm/meta.mjs +0 -12
- package/dist/lib/node-esm/meta.mjs.map +0 -7
- package/dist/lib/node-esm/types.mjs +0 -9
- package/dist/lib/node-esm/types.mjs.map +0 -7
- package/dist/types/src/components/ThreadComplementary.d.ts +0 -10
- package/dist/types/src/components/ThreadComplementary.d.ts.map +0 -1
- package/dist/types/src/extensions/index.d.ts +0 -2
- package/dist/types/src/extensions/index.d.ts.map +0 -1
- package/dist/types/src/extensions/threads.d.ts +0 -9
- package/dist/types/src/extensions/threads.d.ts.map +0 -1
- package/src/components/ThreadComplementary.tsx +0 -113
- package/src/extensions/index.ts +0 -5
- package/src/extensions/threads.ts +0 -117
- package/src/meta.ts +0 -15
- /package/dist/lib/browser/{ThreadArticle-53PBPWLD.mjs.map → ThreadArticle-O64ZECMF.mjs.map} +0 -0
- /package/dist/lib/browser/{ThreadMain-FZAZVPHO.mjs.map → ThreadMain-ZDCRC6RG.mjs.map} +0 -0
- /package/dist/lib/node/{ThreadArticle-UORKW5YD.cjs.map → ThreadArticle-DO56JXBU.cjs.map} +0 -0
- /package/dist/lib/node/{ThreadMain-FVSLLIWS.cjs.map → ThreadMain-XJX75GHG.cjs.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ThreadAction
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-GKPZHUT3.mjs";
|
|
4
4
|
import {
|
|
5
5
|
ChatContainer,
|
|
6
6
|
ChatHeading,
|
|
@@ -10,49 +10,71 @@ import {
|
|
|
10
10
|
useAnalyticsCallback,
|
|
11
11
|
useOnEditAnalytics,
|
|
12
12
|
useStatus
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-P7ZE5N5M.mjs";
|
|
14
14
|
import {
|
|
15
15
|
THREAD_ITEM,
|
|
16
16
|
THREAD_PLUGIN,
|
|
17
17
|
meta_default
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-5IBJO53M.mjs";
|
|
19
19
|
|
|
20
20
|
// packages/plugins/plugin-thread/src/ThreadPlugin.tsx
|
|
21
|
-
import
|
|
22
|
-
import {
|
|
21
|
+
import { Chat } from "@phosphor-icons/react";
|
|
22
|
+
import { computed, effect } from "@preact/signals-core";
|
|
23
|
+
import React5 from "react";
|
|
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";
|
|
23
27
|
import { LocalStorageStore } from "@dxos/local-storage";
|
|
24
|
-
import {
|
|
28
|
+
import { parseAttentionPlugin } from "@dxos/plugin-attention";
|
|
25
29
|
import { parseClientPlugin } from "@dxos/plugin-client";
|
|
26
|
-
import { createExtension, isActionGroup
|
|
30
|
+
import { createExtension, isActionGroup } from "@dxos/plugin-graph";
|
|
31
|
+
import { DocumentType } from "@dxos/plugin-markdown/types";
|
|
27
32
|
import { ObservabilityAction } from "@dxos/plugin-observability/meta";
|
|
28
33
|
import { SpaceAction } from "@dxos/plugin-space";
|
|
29
|
-
import { ThreadType
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
34
|
+
import { ThreadType, MessageType as MessageType2, ChannelType } from "@dxos/plugin-space/types";
|
|
35
|
+
import { getSpace as getSpace2, getTextInRange, Filter, createDocAccessor, fullyQualifiedId, loadObjectReferences } from "@dxos/react-client/echo";
|
|
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";
|
|
32
39
|
import { translations as threadTranslations } from "@dxos/react-ui-thread";
|
|
40
|
+
import { nonNullable as nonNullable2 } from "@dxos/util";
|
|
33
41
|
|
|
34
42
|
// packages/plugins/plugin-thread/src/components/index.ts
|
|
35
|
-
import
|
|
43
|
+
import React4 from "react";
|
|
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
|
+
};
|
|
36
58
|
|
|
37
59
|
// packages/plugins/plugin-thread/src/components/CommentContainer.tsx
|
|
38
60
|
import { CheckCircle, X } from "@phosphor-icons/react";
|
|
39
|
-
import
|
|
61
|
+
import React2, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
40
62
|
import { create } from "@dxos/echo-schema";
|
|
41
63
|
import { MessageType } from "@dxos/plugin-space/types";
|
|
42
|
-
import {
|
|
64
|
+
import { getSpace, useMembers } from "@dxos/react-client/echo";
|
|
43
65
|
import { useIdentity } from "@dxos/react-client/halo";
|
|
44
|
-
import { Button, Tag, Tooltip, useThemeContext, useTranslation } from "@dxos/react-ui";
|
|
66
|
+
import { Button, Tag, Tooltip, useThemeContext, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
45
67
|
import { createBasicExtensions, createThemeExtensions, listener } from "@dxos/react-ui-editor";
|
|
46
68
|
import { getSize, hoverableControlItem, hoverableControls, hoverableFocusedWithinControls, mx } from "@dxos/react-ui-theme";
|
|
47
69
|
import { MessageTextbox, Thread, ThreadFooter, ThreadHeading } from "@dxos/react-ui-thread";
|
|
48
70
|
import { nonNullable } from "@dxos/util";
|
|
49
71
|
var sizeClass = getSize(4);
|
|
50
72
|
var ToggleResolvedButton = ({ isResolved, onResolve }) => {
|
|
51
|
-
const { t } =
|
|
73
|
+
const { t } = useTranslation2(THREAD_PLUGIN);
|
|
52
74
|
const label = t(isResolved ? "mark as unresolved label" : "mark as resolved label");
|
|
53
|
-
return /* @__PURE__ */
|
|
75
|
+
return /* @__PURE__ */ React2.createElement(Tooltip.Root, null, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
|
|
54
76
|
asChild: true
|
|
55
|
-
}, /* @__PURE__ */
|
|
77
|
+
}, /* @__PURE__ */ React2.createElement(Button, {
|
|
56
78
|
variant: "ghost",
|
|
57
79
|
"data-testid": "thread.toggle-resolved",
|
|
58
80
|
onClick: onResolve,
|
|
@@ -60,23 +82,23 @@ var ToggleResolvedButton = ({ isResolved, onResolve }) => {
|
|
|
60
82
|
"min-bs-0 p-1",
|
|
61
83
|
!isResolved && hoverableControlItem
|
|
62
84
|
]
|
|
63
|
-
}, /* @__PURE__ */
|
|
85
|
+
}, /* @__PURE__ */ React2.createElement("span", {
|
|
64
86
|
className: "sr-only"
|
|
65
|
-
}, label), isResolved ? /* @__PURE__ */
|
|
87
|
+
}, label), isResolved ? /* @__PURE__ */ React2.createElement(CheckCircle, {
|
|
66
88
|
className: sizeClass,
|
|
67
89
|
weight: "fill"
|
|
68
|
-
}) : /* @__PURE__ */
|
|
90
|
+
}) : /* @__PURE__ */ React2.createElement(CheckCircle, {
|
|
69
91
|
className: sizeClass
|
|
70
|
-
}))), /* @__PURE__ */
|
|
92
|
+
}))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, {
|
|
71
93
|
classNames: "z-[21]"
|
|
72
|
-
}, label, /* @__PURE__ */
|
|
94
|
+
}, label, /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
|
|
73
95
|
};
|
|
74
96
|
var DeleteThreadButton = ({ onDelete }) => {
|
|
75
|
-
const { t } =
|
|
97
|
+
const { t } = useTranslation2(THREAD_PLUGIN);
|
|
76
98
|
const label = t("delete thread label");
|
|
77
|
-
return /* @__PURE__ */
|
|
99
|
+
return /* @__PURE__ */ React2.createElement(Tooltip.Root, null, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
|
|
78
100
|
asChild: true
|
|
79
|
-
}, /* @__PURE__ */
|
|
101
|
+
}, /* @__PURE__ */ React2.createElement(Button, {
|
|
80
102
|
variant: "ghost",
|
|
81
103
|
"data-testid": "thread.delete",
|
|
82
104
|
onClick: onDelete,
|
|
@@ -84,23 +106,24 @@ var DeleteThreadButton = ({ onDelete }) => {
|
|
|
84
106
|
"min-bs-0 p-1",
|
|
85
107
|
hoverableControlItem
|
|
86
108
|
]
|
|
87
|
-
}, /* @__PURE__ */
|
|
109
|
+
}, /* @__PURE__ */ React2.createElement("span", {
|
|
88
110
|
className: "sr-only"
|
|
89
|
-
}, label), /* @__PURE__ */
|
|
111
|
+
}, label), /* @__PURE__ */ React2.createElement(X, {
|
|
90
112
|
className: sizeClass
|
|
91
|
-
}))), /* @__PURE__ */
|
|
113
|
+
}))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, {
|
|
92
114
|
classNames: "z-[21]"
|
|
93
|
-
}, label, /* @__PURE__ */
|
|
115
|
+
}, label, /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
|
|
94
116
|
};
|
|
95
|
-
var CommentContainer = ({ thread, detached, context, current, onAttend, onThreadDelete, onMessageDelete, onResolve, onComment }) => {
|
|
117
|
+
var CommentContainer = ({ thread, detached, context, current, autoFocusTextbox, onAttend, onThreadDelete, onMessageDelete, onResolve, onComment }) => {
|
|
96
118
|
const identity = useIdentity();
|
|
97
119
|
const space = getSpace(thread);
|
|
98
120
|
const members = useMembers(space?.key);
|
|
99
|
-
const activity = useStatus(space,
|
|
100
|
-
const { t } =
|
|
121
|
+
const activity = useStatus(space, thread.id);
|
|
122
|
+
const { t } = useTranslation2(THREAD_PLUGIN);
|
|
101
123
|
const threadScrollRef = useRef(null);
|
|
124
|
+
const [autoFocus, setAutoFocus] = useState(!!autoFocusTextbox);
|
|
102
125
|
const { themeMode } = useThemeContext();
|
|
103
|
-
const textboxMetadata = getMessageMetadata(
|
|
126
|
+
const textboxMetadata = getMessageMetadata(thread.id, identity);
|
|
104
127
|
const [_count, _setCount] = useState(0);
|
|
105
128
|
const rerenderEditor = () => _setCount((count) => count + 1);
|
|
106
129
|
const messageRef = useRef("");
|
|
@@ -118,6 +141,11 @@ var CommentContainer = ({ thread, detached, context, current, onAttend, onThread
|
|
|
118
141
|
], [
|
|
119
142
|
_count
|
|
120
143
|
]);
|
|
144
|
+
useEffect(() => {
|
|
145
|
+
setAutoFocus(!!autoFocusTextbox);
|
|
146
|
+
}, [
|
|
147
|
+
autoFocusTextbox
|
|
148
|
+
]);
|
|
121
149
|
const scrollToEnd = (behavior) => setTimeout(() => threadScrollRef.current?.scrollIntoView({
|
|
122
150
|
behavior,
|
|
123
151
|
block: "end"
|
|
@@ -136,6 +164,7 @@ var CommentContainer = ({ thread, detached, context, current, onAttend, onThread
|
|
|
136
164
|
}));
|
|
137
165
|
onComment?.(thread);
|
|
138
166
|
messageRef.current = "";
|
|
167
|
+
setAutoFocus(true);
|
|
139
168
|
scrollToEnd("instant");
|
|
140
169
|
rerenderEditor();
|
|
141
170
|
return true;
|
|
@@ -143,42 +172,44 @@ var CommentContainer = ({ thread, detached, context, current, onAttend, onThread
|
|
|
143
172
|
thread,
|
|
144
173
|
identity
|
|
145
174
|
]);
|
|
146
|
-
|
|
175
|
+
const handleDeleteMessage = (id) => onMessageDelete?.(id);
|
|
176
|
+
return /* @__PURE__ */ React2.createElement(Thread, {
|
|
147
177
|
onClickCapture: onAttend,
|
|
148
178
|
onFocusCapture: onAttend,
|
|
149
179
|
current,
|
|
150
|
-
id:
|
|
151
|
-
}, /* @__PURE__ */
|
|
180
|
+
id: thread.id
|
|
181
|
+
}, /* @__PURE__ */ React2.createElement("div", {
|
|
152
182
|
role: "none",
|
|
153
183
|
className: mx("col-span-2 grid grid-cols-[var(--rail-size)_1fr_min-content]", hoverableControls, hoverableFocusedWithinControls)
|
|
154
|
-
}, detached ? /* @__PURE__ */
|
|
184
|
+
}, detached ? /* @__PURE__ */ React2.createElement(Tooltip.Root, null, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
|
|
155
185
|
asChild: true
|
|
156
|
-
}, /* @__PURE__ */
|
|
186
|
+
}, /* @__PURE__ */ React2.createElement(ThreadHeading, {
|
|
157
187
|
detached: true
|
|
158
|
-
}, thread.name ?? t("thread title placeholder"))), /* @__PURE__ */
|
|
188
|
+
}, thread.name ?? t("thread title placeholder"))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, {
|
|
159
189
|
classNames: "z-[21]",
|
|
160
190
|
side: "top"
|
|
161
|
-
}, t("detached thread label"), /* @__PURE__ */
|
|
191
|
+
}, t("detached thread label"), /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null)))) : /* @__PURE__ */ React2.createElement(ThreadHeading, null, thread.name ?? t("thread title placeholder")), /* @__PURE__ */ React2.createElement("div", {
|
|
162
192
|
className: "flex flex-row items-center pli-1"
|
|
163
|
-
}, thread.status === "staged" && /* @__PURE__ */
|
|
193
|
+
}, thread.status === "staged" && /* @__PURE__ */ React2.createElement(Tag, {
|
|
164
194
|
palette: "neutral"
|
|
165
|
-
}, t("draft button")), onResolve && !(thread?.status === "staged") && /* @__PURE__ */
|
|
195
|
+
}, t("draft button")), onResolve && !(thread?.status === "staged") && /* @__PURE__ */ React2.createElement(ToggleResolvedButton, {
|
|
166
196
|
isResolved: thread?.status === "resolved",
|
|
167
197
|
onResolve
|
|
168
|
-
}), onThreadDelete && /* @__PURE__ */
|
|
198
|
+
}), onThreadDelete && /* @__PURE__ */ React2.createElement(DeleteThreadButton, {
|
|
169
199
|
onDelete: onThreadDelete
|
|
170
|
-
}))), thread.messages.filter(nonNullable).map((message) => /* @__PURE__ */
|
|
200
|
+
}))), thread.messages.filter(nonNullable).map((message) => /* @__PURE__ */ React2.createElement(MessageContainer, {
|
|
171
201
|
key: message.id,
|
|
172
202
|
message,
|
|
173
203
|
members,
|
|
174
|
-
onDelete:
|
|
175
|
-
})), /* @__PURE__ */
|
|
204
|
+
onDelete: handleDeleteMessage
|
|
205
|
+
})), /* @__PURE__ */ React2.createElement(MessageTextbox, {
|
|
176
206
|
extensions,
|
|
207
|
+
autoFocus,
|
|
177
208
|
onSend: handleCreate,
|
|
178
209
|
...textboxMetadata
|
|
179
|
-
}), /* @__PURE__ */
|
|
210
|
+
}), /* @__PURE__ */ React2.createElement(ThreadFooter, {
|
|
180
211
|
activity
|
|
181
|
-
}, t("activity message")), /* @__PURE__ */
|
|
212
|
+
}, t("activity message")), /* @__PURE__ */ React2.createElement("div", {
|
|
182
213
|
role: "none",
|
|
183
214
|
className: "bs-px -mbs-px",
|
|
184
215
|
ref: threadScrollRef
|
|
@@ -186,15 +217,26 @@ var CommentContainer = ({ thread, detached, context, current, onAttend, onThread
|
|
|
186
217
|
};
|
|
187
218
|
|
|
188
219
|
// packages/plugins/plugin-thread/src/components/CommentsContainer.tsx
|
|
189
|
-
import { ChatText } from "@phosphor-icons/react";
|
|
190
|
-
import
|
|
191
|
-
import {
|
|
192
|
-
import {
|
|
220
|
+
import { ChatText, Quotes } from "@phosphor-icons/react";
|
|
221
|
+
import React3, { useEffect as useEffect2 } from "react";
|
|
222
|
+
import { useTranslation as useTranslation3, Trans } from "@dxos/react-ui";
|
|
223
|
+
import { PlankHeading, plankHeadingIconProps } from "@dxos/react-ui-deck";
|
|
193
224
|
import { descriptionText, mx as mx2 } from "@dxos/react-ui-theme";
|
|
194
|
-
var
|
|
195
|
-
const { t } =
|
|
196
|
-
|
|
197
|
-
|
|
225
|
+
var CommentsHeading = ({ attendableId }) => {
|
|
226
|
+
const { t } = useTranslation3(THREAD_PLUGIN);
|
|
227
|
+
return /* @__PURE__ */ React3.createElement("div", {
|
|
228
|
+
role: "none",
|
|
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(() => {
|
|
198
240
|
if (currentId) {
|
|
199
241
|
document.getElementById(currentId)?.scrollIntoView({
|
|
200
242
|
behavior: "smooth",
|
|
@@ -204,260 +246,44 @@ var CommentsContainer = ({ threads: threads2, detached = [], currentId, showReso
|
|
|
204
246
|
}, [
|
|
205
247
|
currentId
|
|
206
248
|
]);
|
|
207
|
-
return /* @__PURE__ */
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
});
|
|
228
|
-
}) : /* @__PURE__ */ React2.createElement("div", {
|
|
249
|
+
return /* @__PURE__ */ React3.createElement(React3.Fragment, null, filteredThreads.length > 0 ? filteredThreads.map((thread) => /* @__PURE__ */ React3.createElement(CommentContainer, {
|
|
250
|
+
key: thread.id,
|
|
251
|
+
thread,
|
|
252
|
+
current: currentId === thread.id,
|
|
253
|
+
detached: detached.includes(thread.id),
|
|
254
|
+
autoFocusTextbox: autoFocusCurrentTextbox && currentId === thread.id,
|
|
255
|
+
...onThreadAttend && {
|
|
256
|
+
onAttend: () => onThreadAttend(thread)
|
|
257
|
+
},
|
|
258
|
+
...onThreadDelete && {
|
|
259
|
+
onThreadDelete: () => onThreadDelete(thread)
|
|
260
|
+
},
|
|
261
|
+
...onMessageDelete && {
|
|
262
|
+
onMessageDelete: (messageId) => onMessageDelete(thread, messageId)
|
|
263
|
+
},
|
|
264
|
+
...onThreadToggleResolved && {
|
|
265
|
+
onResolve: () => onThreadToggleResolved(thread)
|
|
266
|
+
},
|
|
267
|
+
...props
|
|
268
|
+
})) : /* @__PURE__ */ React3.createElement("div", {
|
|
229
269
|
role: "alert",
|
|
230
270
|
className: mx2(descriptionText, "place-self-center border border-dashed border-neutral-400/50 rounded-lg text-center p-4 m-4")
|
|
231
|
-
}, /* @__PURE__ */
|
|
271
|
+
}, /* @__PURE__ */ React3.createElement("h2", {
|
|
232
272
|
className: "mbe-2 font-medium text-baseText"
|
|
233
|
-
}, t("no comments title")), /* @__PURE__ */
|
|
273
|
+
}, t("no comments title")), /* @__PURE__ */ React3.createElement("p", null, /* @__PURE__ */ React3.createElement(Trans, {
|
|
234
274
|
t,
|
|
235
275
|
i18nKey: "no comments message",
|
|
236
276
|
components: {
|
|
237
|
-
commentIcon: /* @__PURE__ */
|
|
277
|
+
commentIcon: /* @__PURE__ */ React3.createElement(ChatText, {
|
|
238
278
|
className: "inline-block"
|
|
239
279
|
})
|
|
240
280
|
}
|
|
241
281
|
}))));
|
|
242
282
|
};
|
|
243
283
|
|
|
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
|
-
|
|
369
284
|
// packages/plugins/plugin-thread/src/components/index.ts
|
|
370
|
-
var ThreadMain =
|
|
371
|
-
var ThreadArticle =
|
|
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
|
-
};
|
|
285
|
+
var ThreadMain = React4.lazy(() => import("./ThreadMain-ZDCRC6RG.mjs"));
|
|
286
|
+
var ThreadArticle = React4.lazy(() => import("./ThreadArticle-O64ZECMF.mjs"));
|
|
461
287
|
|
|
462
288
|
// packages/plugins/plugin-thread/src/translations.ts
|
|
463
289
|
var translations_default = [
|
|
@@ -496,14 +322,14 @@ var translations_default = [
|
|
|
496
322
|
];
|
|
497
323
|
|
|
498
324
|
// packages/plugins/plugin-thread/src/ThreadPlugin.tsx
|
|
499
|
-
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/plugins/plugin-thread/src/ThreadPlugin.tsx";
|
|
500
325
|
var initialViewState = {
|
|
501
326
|
showResolvedThreads: false
|
|
502
327
|
};
|
|
328
|
+
var providesThreadsConfig = (plugin) => "thread" in plugin.provides ? plugin : void 0;
|
|
503
329
|
var ThreadPlugin = () => {
|
|
504
330
|
const settings = new LocalStorageStore(THREAD_PLUGIN);
|
|
505
331
|
const state = create2({
|
|
506
|
-
|
|
332
|
+
staging: {}
|
|
507
333
|
});
|
|
508
334
|
const viewStore = create2({});
|
|
509
335
|
const getViewState = (subjectId) => {
|
|
@@ -514,8 +340,10 @@ var ThreadPlugin = () => {
|
|
|
514
340
|
}
|
|
515
341
|
return viewStore[subjectId];
|
|
516
342
|
};
|
|
343
|
+
let attentionPlugin;
|
|
517
344
|
let navigationPlugin;
|
|
518
345
|
let intentPlugin;
|
|
346
|
+
let dispatch;
|
|
519
347
|
const unsubscribeCallbacks = [];
|
|
520
348
|
return {
|
|
521
349
|
meta: meta_default,
|
|
@@ -526,8 +354,36 @@ var ThreadPlugin = () => {
|
|
|
526
354
|
allowUndefined: true
|
|
527
355
|
})
|
|
528
356
|
});
|
|
357
|
+
attentionPlugin = resolvePlugin(plugins, parseAttentionPlugin);
|
|
529
358
|
navigationPlugin = resolvePlugin(plugins, parseNavigationPlugin);
|
|
530
359
|
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);
|
|
531
387
|
},
|
|
532
388
|
unload: async () => {
|
|
533
389
|
unsubscribeCallbacks.forEach((unsubscribe) => unsubscribe());
|
|
@@ -543,11 +399,12 @@ var ThreadPlugin = () => {
|
|
|
543
399
|
ns: THREAD_PLUGIN
|
|
544
400
|
}
|
|
545
401
|
],
|
|
546
|
-
icon:
|
|
402
|
+
icon: (props) => /* @__PURE__ */ React5.createElement(Chat, props),
|
|
403
|
+
iconSymbol: "ph--chat--regular",
|
|
547
404
|
// TODO(wittjosiah): Move out of metadata.
|
|
548
405
|
loadReferences: (channel) => loadObjectReferences(channel, (channel2) => channel2.threads)
|
|
549
406
|
},
|
|
550
|
-
[
|
|
407
|
+
[ThreadType.typename]: {
|
|
551
408
|
// TODO(wittjosiah): Move out of metadata.
|
|
552
409
|
loadReferences: (thread) => loadObjectReferences(thread, (thread2) => thread2.messages)
|
|
553
410
|
},
|
|
@@ -583,16 +440,16 @@ var ThreadPlugin = () => {
|
|
|
583
440
|
echo: {
|
|
584
441
|
schema: [
|
|
585
442
|
ChannelType,
|
|
586
|
-
|
|
443
|
+
ThreadType,
|
|
587
444
|
MessageType2
|
|
588
445
|
]
|
|
589
446
|
},
|
|
590
447
|
graph: {
|
|
591
448
|
builder: (plugins) => {
|
|
592
449
|
const client = resolvePlugin(plugins, parseClientPlugin)?.provides.client;
|
|
593
|
-
const
|
|
450
|
+
const dispatch2 = resolvePlugin(plugins, parseIntentPlugin)?.provides.intent.dispatch;
|
|
594
451
|
const metadataResolver = resolvePlugin(plugins, parseMetadataResolverPlugin)?.provides.metadata.resolver;
|
|
595
|
-
if (!client || !
|
|
452
|
+
if (!client || !dispatch2 || !metadataResolver) {
|
|
596
453
|
return [];
|
|
597
454
|
}
|
|
598
455
|
return [
|
|
@@ -602,36 +459,29 @@ var ThreadPlugin = () => {
|
|
|
602
459
|
if (!id.endsWith("~comments")) {
|
|
603
460
|
return;
|
|
604
461
|
}
|
|
605
|
-
const
|
|
606
|
-
const [spaceId, objectId] =
|
|
462
|
+
const docId = id.split("~").at(0);
|
|
463
|
+
const [spaceId, objectId] = docId?.split(":") ?? [];
|
|
607
464
|
const space = client.spaces.get().find((space2) => space2.id === spaceId);
|
|
608
|
-
const
|
|
609
|
-
|
|
610
|
-
await space?.db.loadObjectById(objectId);
|
|
611
|
-
onChange();
|
|
612
|
-
});
|
|
613
|
-
return () => clearTimeout(timeout);
|
|
614
|
-
}, () => space?.db.getObjectById(objectId), subjectId);
|
|
615
|
-
if (!object || !subjectId) {
|
|
465
|
+
const doc = space?.db.getObjectById(objectId);
|
|
466
|
+
if (!doc || !docId) {
|
|
616
467
|
return;
|
|
617
468
|
}
|
|
618
|
-
const
|
|
619
|
-
const label =
|
|
469
|
+
const docMeta = metadataResolver(getTypename(doc) ?? "");
|
|
470
|
+
const label = docMeta.label?.(doc) || doc.name || docMeta.placeholder || [
|
|
620
471
|
"unnamed object threads label",
|
|
621
472
|
{
|
|
622
473
|
ns: THREAD_PLUGIN
|
|
623
474
|
}
|
|
624
475
|
];
|
|
625
|
-
const viewState = getViewState(
|
|
476
|
+
const viewState = getViewState(docId);
|
|
626
477
|
return {
|
|
627
478
|
id,
|
|
628
479
|
type: "orphan-comments-for-subject",
|
|
629
|
-
data:
|
|
480
|
+
data: doc,
|
|
630
481
|
properties: {
|
|
631
|
-
icon:
|
|
482
|
+
icon: meta_default.iconComponent,
|
|
632
483
|
label,
|
|
633
|
-
showResolvedThreads: viewState.showResolvedThreads
|
|
634
|
-
object
|
|
484
|
+
showResolvedThreads: viewState.showResolvedThreads
|
|
635
485
|
}
|
|
636
486
|
};
|
|
637
487
|
},
|
|
@@ -645,7 +495,7 @@ var ThreadPlugin = () => {
|
|
|
645
495
|
const toggle = () => {
|
|
646
496
|
const newToggleState = !viewState.showResolvedThreads;
|
|
647
497
|
viewState.showResolvedThreads = newToggleState;
|
|
648
|
-
void
|
|
498
|
+
void dispatch2({
|
|
649
499
|
action: ObservabilityAction.SEND_EVENT,
|
|
650
500
|
data: {
|
|
651
501
|
name: "threads.toggle-show-resolved",
|
|
@@ -670,8 +520,7 @@ var ThreadPlugin = () => {
|
|
|
670
520
|
],
|
|
671
521
|
menuItemType: "toggle",
|
|
672
522
|
isChecked: viewState.showResolvedThreads,
|
|
673
|
-
testId: "threadPlugin.toggleShowResolved"
|
|
674
|
-
icon: viewState.showResolvedThreads ? "ph--eye-slash--regular" : "ph--eye--regular"
|
|
523
|
+
testId: "threadPlugin.toggleShowResolved"
|
|
675
524
|
}
|
|
676
525
|
}
|
|
677
526
|
];
|
|
@@ -693,7 +542,7 @@ var ThreadPlugin = () => {
|
|
|
693
542
|
{
|
|
694
543
|
id: `${THREAD_PLUGIN}/create/${node.id}`,
|
|
695
544
|
data: async () => {
|
|
696
|
-
await
|
|
545
|
+
await dispatch2([
|
|
697
546
|
{
|
|
698
547
|
plugin: THREAD_PLUGIN,
|
|
699
548
|
action: ThreadAction.CREATE
|
|
@@ -716,7 +565,8 @@ var ThreadPlugin = () => {
|
|
|
716
565
|
ns: THREAD_PLUGIN
|
|
717
566
|
}
|
|
718
567
|
],
|
|
719
|
-
icon:
|
|
568
|
+
icon: (props) => /* @__PURE__ */ React5.createElement(Chat, props),
|
|
569
|
+
iconSymbol: "ph--chat--regular",
|
|
720
570
|
testId: "threadPlugin.createObject"
|
|
721
571
|
}
|
|
722
572
|
}
|
|
@@ -730,17 +580,20 @@ var ThreadPlugin = () => {
|
|
|
730
580
|
component: ({ data, role }) => {
|
|
731
581
|
switch (role) {
|
|
732
582
|
case "main": {
|
|
733
|
-
return data.active instanceof ChannelType && data.active.threads[0] ? /* @__PURE__ */
|
|
583
|
+
return data.active instanceof ChannelType && data.active.threads[0] ? /* @__PURE__ */ React5.createElement(ThreadMain, {
|
|
734
584
|
thread: data.active.threads[0]
|
|
735
585
|
}) : null;
|
|
736
586
|
}
|
|
737
587
|
case "settings": {
|
|
738
|
-
return data.plugin === meta_default.id ? /* @__PURE__ */
|
|
588
|
+
return data.plugin === meta_default.id ? /* @__PURE__ */ React5.createElement(ThreadSettings, {
|
|
739
589
|
settings: settings.values
|
|
740
590
|
}) : null;
|
|
741
591
|
}
|
|
742
|
-
case "article":
|
|
592
|
+
case "article":
|
|
593
|
+
case "complementary": {
|
|
743
594
|
const location = navigationPlugin?.provides.location;
|
|
595
|
+
const threadsIntegrators = useResolvePlugins(providesThreadsConfig);
|
|
596
|
+
const threadProvides = threadsIntegrators.map((p) => p.provides.thread);
|
|
744
597
|
if (data.object instanceof ChannelType && data.object.threads[0]) {
|
|
745
598
|
const channel = data.object;
|
|
746
599
|
if (isLayoutParts(location?.active) && location.active.main) {
|
|
@@ -748,38 +601,103 @@ var ThreadPlugin = () => {
|
|
|
748
601
|
const currentPosition = layoutEntries.findIndex((entry) => channel.id === entry.id);
|
|
749
602
|
if (currentPosition > 0) {
|
|
750
603
|
const objectToTheLeft = layoutEntries[currentPosition - 1];
|
|
751
|
-
const context =
|
|
752
|
-
return /* @__PURE__ */
|
|
604
|
+
const context = getSpace2(data.object)?.db.getObjectById(objectToTheLeft.id);
|
|
605
|
+
return /* @__PURE__ */ React5.createElement(ThreadArticle, {
|
|
753
606
|
thread: data.object.threads[0],
|
|
754
607
|
context
|
|
755
608
|
});
|
|
756
609
|
}
|
|
757
610
|
}
|
|
758
|
-
return /* @__PURE__ */
|
|
611
|
+
return /* @__PURE__ */ React5.createElement(ThreadArticle, {
|
|
759
612
|
thread: data.object.threads[0]
|
|
760
613
|
});
|
|
761
614
|
}
|
|
762
|
-
if (data.subject instanceof
|
|
763
|
-
return /* @__PURE__ */
|
|
615
|
+
if (data.subject instanceof ThreadType) {
|
|
616
|
+
return /* @__PURE__ */ React5.createElement(React5.Fragment, null, /* @__PURE__ */ React5.createElement(ChatHeading, {
|
|
764
617
|
attendableId: data.subject.id
|
|
765
|
-
}), /* @__PURE__ */
|
|
618
|
+
}), /* @__PURE__ */ React5.createElement(ChatContainer, {
|
|
766
619
|
thread: data.subject
|
|
767
620
|
}));
|
|
768
621
|
}
|
|
769
|
-
break;
|
|
770
|
-
}
|
|
771
|
-
case "complementary--comments": {
|
|
772
622
|
if (data.subject && typeof data.subject === "object" && "threads" in data.subject && Array.isArray(data.subject.threads)) {
|
|
773
|
-
const
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
623
|
+
const threads = data.subject.threads.concat(state.staging[fullyQualifiedId(data.subject)]).filter(nonNullable2);
|
|
624
|
+
const createSort = threadProvides.find((p) => p.predicate(data.subject))?.createSort;
|
|
625
|
+
if (createSort) {
|
|
626
|
+
const sort = createSort(data.subject);
|
|
627
|
+
threads.sort((a, b) => sort(a.anchor, b.anchor));
|
|
628
|
+
}
|
|
629
|
+
const detached = data.subject.threads.filter(nonNullable2).filter(({ anchor }) => !anchor).map((thread) => thread.id);
|
|
630
|
+
const qualifiedSubjectId = fullyQualifiedId(data.subject);
|
|
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)))));
|
|
781
700
|
}
|
|
782
|
-
break;
|
|
783
701
|
}
|
|
784
702
|
}
|
|
785
703
|
return null;
|
|
@@ -791,31 +709,18 @@ var ThreadPlugin = () => {
|
|
|
791
709
|
case ThreadAction.CREATE: {
|
|
792
710
|
if (intent.data && intent.data.cursor !== void 0) {
|
|
793
711
|
const { cursor, name, subject } = intent.data;
|
|
794
|
-
|
|
795
|
-
|
|
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, {
|
|
712
|
+
const subjectId = fullyQualifiedId(subject);
|
|
713
|
+
const thread = create2(ThreadType, {
|
|
809
714
|
name,
|
|
810
715
|
anchor: cursor,
|
|
811
716
|
messages: [],
|
|
812
717
|
status: "staged"
|
|
813
718
|
});
|
|
814
|
-
const
|
|
815
|
-
if (
|
|
816
|
-
|
|
719
|
+
const stagingArea = state.staging[subjectId];
|
|
720
|
+
if (stagingArea) {
|
|
721
|
+
stagingArea.push(thread);
|
|
817
722
|
} else {
|
|
818
|
-
state.
|
|
723
|
+
state.staging[subjectId] = [
|
|
819
724
|
thread
|
|
820
725
|
];
|
|
821
726
|
}
|
|
@@ -823,20 +728,27 @@ var ThreadPlugin = () => {
|
|
|
823
728
|
data: thread,
|
|
824
729
|
intents: [
|
|
825
730
|
[
|
|
731
|
+
{
|
|
732
|
+
action: NavigationAction.OPEN,
|
|
733
|
+
data: {
|
|
734
|
+
activeParts: {
|
|
735
|
+
complementary: `${subjectId}${SLUG_PATH_SEPARATOR}comments${SLUG_COLLECTION_INDICATOR}`
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
},
|
|
826
739
|
{
|
|
827
740
|
action: ThreadAction.SELECT,
|
|
828
741
|
data: {
|
|
829
|
-
current:
|
|
742
|
+
current: thread.id,
|
|
743
|
+
focus: true
|
|
830
744
|
}
|
|
831
|
-
}
|
|
832
|
-
],
|
|
833
|
-
[
|
|
745
|
+
},
|
|
834
746
|
{
|
|
835
|
-
action:
|
|
747
|
+
action: LayoutAction.SET_LAYOUT,
|
|
836
748
|
data: {
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
749
|
+
element: "complementary",
|
|
750
|
+
subject: subjectId,
|
|
751
|
+
state: true
|
|
840
752
|
}
|
|
841
753
|
}
|
|
842
754
|
]
|
|
@@ -846,7 +758,7 @@ var ThreadPlugin = () => {
|
|
|
846
758
|
return {
|
|
847
759
|
data: create2(ChannelType, {
|
|
848
760
|
threads: [
|
|
849
|
-
create2(
|
|
761
|
+
create2(ThreadType, {
|
|
850
762
|
messages: []
|
|
851
763
|
})
|
|
852
764
|
]
|
|
@@ -855,26 +767,15 @@ var ThreadPlugin = () => {
|
|
|
855
767
|
}
|
|
856
768
|
}
|
|
857
769
|
case ThreadAction.SELECT: {
|
|
770
|
+
state.focus = intent.data?.current === state.current ? state.focus : intent.data?.focus;
|
|
858
771
|
state.current = intent.data?.current;
|
|
859
772
|
return {
|
|
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
|
-
] : []
|
|
773
|
+
data: true
|
|
873
774
|
};
|
|
874
775
|
}
|
|
875
776
|
case ThreadAction.TOGGLE_RESOLVED: {
|
|
876
777
|
const { thread } = intent.data ?? {};
|
|
877
|
-
if (!(thread instanceof
|
|
778
|
+
if (!(thread instanceof ThreadType)) {
|
|
878
779
|
return;
|
|
879
780
|
}
|
|
880
781
|
if (thread.status === "active" || thread.status === void 0) {
|
|
@@ -882,10 +783,9 @@ var ThreadPlugin = () => {
|
|
|
882
783
|
} else if (thread.status === "resolved") {
|
|
883
784
|
thread.status = "active";
|
|
884
785
|
}
|
|
885
|
-
const space =
|
|
786
|
+
const space = getSpace2(thread);
|
|
886
787
|
const spaceId = space?.id;
|
|
887
788
|
return {
|
|
888
|
-
data: true,
|
|
889
789
|
intents: [
|
|
890
790
|
[
|
|
891
791
|
{
|
|
@@ -904,21 +804,19 @@ var ThreadPlugin = () => {
|
|
|
904
804
|
}
|
|
905
805
|
case ThreadAction.DELETE: {
|
|
906
806
|
const { subject, thread } = intent.data ?? {};
|
|
907
|
-
if (!(
|
|
807
|
+
if (!(subject instanceof DocumentType) || !(thread instanceof ThreadType)) {
|
|
908
808
|
return;
|
|
909
809
|
}
|
|
910
|
-
const subjectId =
|
|
911
|
-
const
|
|
912
|
-
if (
|
|
913
|
-
const index =
|
|
810
|
+
const subjectId = fullyQualifiedId(subject);
|
|
811
|
+
const stagingArea = state.staging[subjectId];
|
|
812
|
+
if (stagingArea) {
|
|
813
|
+
const index = stagingArea.findIndex((t) => t.id === thread.id);
|
|
914
814
|
if (index !== -1) {
|
|
915
|
-
|
|
916
|
-
return
|
|
917
|
-
data: true
|
|
918
|
-
};
|
|
815
|
+
stagingArea.splice(index, 1);
|
|
816
|
+
return;
|
|
919
817
|
}
|
|
920
818
|
}
|
|
921
|
-
const space =
|
|
819
|
+
const space = getSpace2(thread);
|
|
922
820
|
if (!space || !subject.threads) {
|
|
923
821
|
return;
|
|
924
822
|
}
|
|
@@ -976,22 +874,22 @@ var ThreadPlugin = () => {
|
|
|
976
874
|
}
|
|
977
875
|
case ThreadAction.ON_MESSAGE_ADD: {
|
|
978
876
|
const { thread, subject } = intent.data ?? {};
|
|
979
|
-
if (!(thread instanceof
|
|
877
|
+
if (!(thread instanceof ThreadType) || !(subject && typeof subject === "object" && "threads" in subject)) {
|
|
980
878
|
return;
|
|
981
879
|
}
|
|
982
|
-
const subjectId =
|
|
983
|
-
const space =
|
|
880
|
+
const subjectId = fullyQualifiedId(subject);
|
|
881
|
+
const space = getSpace2(subject);
|
|
984
882
|
const intents = [];
|
|
985
883
|
const analyticsProperties = {
|
|
986
884
|
threadId: thread.id,
|
|
987
885
|
spaceId: space?.id
|
|
988
886
|
};
|
|
989
|
-
if (state.
|
|
887
|
+
if (state.staging[subjectId]?.find((t) => t === thread)) {
|
|
990
888
|
thread.status = "active";
|
|
991
889
|
subject.threads ? subject.threads.push(thread) : subject.threads = [
|
|
992
890
|
thread
|
|
993
891
|
];
|
|
994
|
-
state.
|
|
892
|
+
state.staging[subjectId] = state.staging[subjectId]?.filter((t) => t.id !== thread.id);
|
|
995
893
|
intents.push({
|
|
996
894
|
action: ObservabilityAction.SEND_EVENT,
|
|
997
895
|
data: {
|
|
@@ -1019,8 +917,8 @@ var ThreadPlugin = () => {
|
|
|
1019
917
|
}
|
|
1020
918
|
case ThreadAction.DELETE_MESSAGE: {
|
|
1021
919
|
const { subject, thread, messageId } = intent.data ?? {};
|
|
1022
|
-
const space =
|
|
1023
|
-
if (!(
|
|
920
|
+
const space = getSpace2(subject);
|
|
921
|
+
if (!(subject instanceof DocumentType) || !(thread instanceof ThreadType) || !space) {
|
|
1024
922
|
return;
|
|
1025
923
|
}
|
|
1026
924
|
if (!intent.undo) {
|
|
@@ -1062,7 +960,7 @@ var ThreadPlugin = () => {
|
|
|
1062
960
|
name: "threads.message.delete",
|
|
1063
961
|
properties: {
|
|
1064
962
|
threadId: thread.id,
|
|
1065
|
-
spaceId: space
|
|
963
|
+
spaceId: space.id
|
|
1066
964
|
}
|
|
1067
965
|
}
|
|
1068
966
|
}
|
|
@@ -1086,7 +984,7 @@ var ThreadPlugin = () => {
|
|
|
1086
984
|
name: "threads.message.undo-delete",
|
|
1087
985
|
properties: {
|
|
1088
986
|
threadId: thread.id,
|
|
1089
|
-
spaceId: space
|
|
987
|
+
spaceId: space.id
|
|
1090
988
|
}
|
|
1091
989
|
}
|
|
1092
990
|
}
|
|
@@ -1099,8 +997,92 @@ var ThreadPlugin = () => {
|
|
|
1099
997
|
}
|
|
1100
998
|
},
|
|
1101
999
|
markdown: {
|
|
1000
|
+
// TODO(burdon): Factor out extension factory into separate file (for simplicity).
|
|
1102
1001
|
extensions: ({ document: doc }) => {
|
|
1103
|
-
|
|
1002
|
+
const space = doc && getSpace2(doc);
|
|
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
|
+
];
|
|
1104
1086
|
}
|
|
1105
1087
|
}
|
|
1106
1088
|
}
|