@dxos/plugin-thread 0.6.13 → 0.6.14-main.69511f5
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-2Y7UWZLA.mjs} +3 -3
- package/dist/lib/browser/{ThreadMain-ZDCRC6RG.mjs → ThreadMain-VK5UEBQ7.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-P7ZE5N5M.mjs → chunk-LHT42MTJ.mjs} +16 -16
- package/dist/lib/browser/chunk-LHT42MTJ.mjs.map +7 -0
- package/dist/lib/browser/{chunk-GKPZHUT3.mjs → chunk-WKCIKGGW.mjs} +2 -2
- package/dist/lib/browser/{chunk-GKPZHUT3.mjs.map → chunk-WKCIKGGW.mjs.map} +1 -1
- package/dist/lib/browser/index.mjs +431 -383
- 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-CIYBYISR.cjs} +7 -7
- package/dist/lib/node/{ThreadMain-XJX75GHG.cjs → ThreadMain-V6KBUQLH.cjs} +7 -7
- package/dist/lib/node/{chunk-D5GOVXHS.cjs → chunk-A2IORKQK.cjs} +6 -6
- package/dist/lib/node/{chunk-D5GOVXHS.cjs.map → chunk-A2IORKQK.cjs.map} +1 -1
- package/dist/lib/node/{chunk-5PZNPPQF.cjs → chunk-HWN7Q5XK.cjs} +65 -65
- package/dist/lib/node/chunk-HWN7Q5XK.cjs.map +7 -0
- 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 +480 -436
- 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-PXO4ZJFU.mjs +19 -0
- package/dist/lib/node-esm/ThreadArticle-PXO4ZJFU.mjs.map +7 -0
- package/dist/lib/node-esm/ThreadMain-U7R24CN3.mjs +27 -0
- package/dist/lib/node-esm/ThreadMain-U7R24CN3.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-KWNXG6FG.mjs +21 -0
- package/dist/lib/node-esm/chunk-KWNXG6FG.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-SXXOBRAX.mjs +411 -0
- package/dist/lib/node-esm/chunk-SXXOBRAX.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +1151 -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/Chat.stories.d.ts +3 -42
- package/dist/types/src/components/Chat.stories.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/Comments.stories.d.ts +3 -41
- package/dist/types/src/components/Comments.stories.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 +6 -6
- 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/components/types.d.ts +2 -2
- package/dist/types/src/components/types.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 +7 -2
- package/dist/types/src/types.d.ts.map +1 -1
- package/package.json +41 -46
- package/src/ThreadPlugin.tsx +146 -307
- package/src/components/Chat.stories.tsx +7 -4
- package/src/components/ChatContainer.tsx +7 -8
- package/src/components/CommentContainer.tsx +18 -19
- package/src/components/Comments.stories.tsx +9 -6
- package/src/components/CommentsContainer.tsx +18 -31
- package/src/components/MessageContainer.tsx +13 -23
- package/src/components/ThreadComplementary.tsx +113 -0
- package/src/components/ThreadSettings.tsx +3 -3
- package/src/components/index.ts +6 -6
- package/src/components/types.ts +2 -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 +9 -4
- 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-2Y7UWZLA.mjs.map} +0 -0
- /package/dist/lib/browser/{ThreadMain-ZDCRC6RG.mjs.map → ThreadMain-VK5UEBQ7.mjs.map} +0 -0
- /package/dist/lib/node/{ThreadArticle-DO56JXBU.cjs.map → ThreadArticle-CIYBYISR.cjs.map} +0 -0
- /package/dist/lib/node/{ThreadMain-XJX75GHG.cjs.map → ThreadMain-V6KBUQLH.cjs.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ThreadAction
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-WKCIKGGW.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-LHT42MTJ.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 { Chat } from "@phosphor-icons/react";
|
|
22
|
-
import { computed, effect } from "@preact/signals-core";
|
|
23
21
|
import React5 from "react";
|
|
24
|
-
import {
|
|
25
|
-
import { getTypename } from "@dxos/echo-schema";
|
|
26
|
-
import { create as create2 } from "@dxos/echo-schema";
|
|
22
|
+
import { NavigationAction, isLayoutParts, parseIntentPlugin, parseNavigationPlugin, parseMetadataResolverPlugin, resolvePlugin, LayoutAction as LayoutAction2 } from "@dxos/app-framework";
|
|
27
23
|
import { LocalStorageStore } from "@dxos/local-storage";
|
|
28
|
-
import {
|
|
24
|
+
import { log } from "@dxos/log";
|
|
29
25
|
import { parseClientPlugin } from "@dxos/plugin-client";
|
|
30
|
-
import { createExtension, isActionGroup } from "@dxos/plugin-graph";
|
|
31
|
-
import { DocumentType } from "@dxos/plugin-markdown/types";
|
|
26
|
+
import { createExtension, isActionGroup, toSignal } from "@dxos/plugin-graph";
|
|
32
27
|
import { ObservabilityAction } from "@dxos/plugin-observability/meta";
|
|
33
28
|
import { SpaceAction } from "@dxos/plugin-space";
|
|
34
|
-
import { ThreadType, MessageType as MessageType2, ChannelType } from "@dxos/plugin-space/types";
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
37
|
-
import { createAttendableAttributes } from "@dxos/react-ui-attention";
|
|
38
|
-
import { comments, createExternalCommentSync, listener as listener2 } from "@dxos/react-ui-editor";
|
|
29
|
+
import { ThreadType as ThreadType2, MessageType as MessageType2, ChannelType } from "@dxos/plugin-space/types";
|
|
30
|
+
import { create as create2, getTypename } from "@dxos/react-client/echo";
|
|
31
|
+
import { getSpace as getSpace3, fullyQualifiedId as fullyQualifiedId5, loadObjectReferences, parseId } 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 { lazy } 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 { Input, useTranslation as useTranslation3 } from "@dxos/react-ui";
|
|
358
|
+
import { FormInput } from "@dxos/react-ui-data";
|
|
359
|
+
var ThreadSettings = ({ settings }) => {
|
|
360
|
+
const { t } = useTranslation3(THREAD_PLUGIN);
|
|
361
|
+
return /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(FormInput, {
|
|
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 = lazy(() => import("./ThreadMain-VK5UEBQ7.mjs"));
|
|
371
|
+
var ThreadArticle = lazy(() => import("./ThreadArticle-2Y7UWZLA.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,18 +583,20 @@ 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
|
}
|
|
598
|
+
const type = "orphan-comments-for-subject";
|
|
599
|
+
const icon = "ph--chat-text--regular";
|
|
455
600
|
return [
|
|
456
601
|
createExtension({
|
|
457
602
|
id: `${THREAD_PLUGIN}/comments-for-subject`,
|
|
@@ -459,29 +604,55 @@ var ThreadPlugin = () => {
|
|
|
459
604
|
if (!id.endsWith("~comments")) {
|
|
460
605
|
return;
|
|
461
606
|
}
|
|
462
|
-
const
|
|
463
|
-
const
|
|
607
|
+
const [subjectId] = id.split("~");
|
|
608
|
+
const { spaceId, objectId } = parseId(subjectId);
|
|
464
609
|
const space = client.spaces.get().find((space2) => space2.id === spaceId);
|
|
465
|
-
|
|
466
|
-
|
|
610
|
+
if (!objectId) {
|
|
611
|
+
return {
|
|
612
|
+
id,
|
|
613
|
+
type,
|
|
614
|
+
data: null,
|
|
615
|
+
properties: {
|
|
616
|
+
icon,
|
|
617
|
+
label: [
|
|
618
|
+
"unnamed object threads label",
|
|
619
|
+
{
|
|
620
|
+
ns: THREAD_PLUGIN
|
|
621
|
+
}
|
|
622
|
+
],
|
|
623
|
+
showResolvedThreads: false,
|
|
624
|
+
object: null,
|
|
625
|
+
space
|
|
626
|
+
}
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
const object = toSignal((onChange) => {
|
|
630
|
+
const timeout = setTimeout(async () => {
|
|
631
|
+
await space?.db.loadObjectById(objectId);
|
|
632
|
+
onChange();
|
|
633
|
+
});
|
|
634
|
+
return () => clearTimeout(timeout);
|
|
635
|
+
}, () => space?.db.getObjectById(objectId), subjectId);
|
|
636
|
+
if (!object || !subjectId) {
|
|
467
637
|
return;
|
|
468
638
|
}
|
|
469
|
-
const
|
|
470
|
-
const label =
|
|
639
|
+
const meta = metadataResolver(getTypename(object) ?? "");
|
|
640
|
+
const label = meta.label?.(object) || object.name || meta.placeholder || [
|
|
471
641
|
"unnamed object threads label",
|
|
472
642
|
{
|
|
473
643
|
ns: THREAD_PLUGIN
|
|
474
644
|
}
|
|
475
645
|
];
|
|
476
|
-
const viewState = getViewState(
|
|
646
|
+
const viewState = getViewState(subjectId);
|
|
477
647
|
return {
|
|
478
648
|
id,
|
|
479
|
-
type
|
|
480
|
-
data:
|
|
649
|
+
type,
|
|
650
|
+
data: null,
|
|
481
651
|
properties: {
|
|
482
|
-
icon
|
|
652
|
+
icon,
|
|
483
653
|
label,
|
|
484
|
-
showResolvedThreads: viewState.showResolvedThreads
|
|
654
|
+
showResolvedThreads: viewState.showResolvedThreads,
|
|
655
|
+
object
|
|
485
656
|
}
|
|
486
657
|
};
|
|
487
658
|
},
|
|
@@ -495,7 +666,7 @@ var ThreadPlugin = () => {
|
|
|
495
666
|
const toggle = () => {
|
|
496
667
|
const newToggleState = !viewState.showResolvedThreads;
|
|
497
668
|
viewState.showResolvedThreads = newToggleState;
|
|
498
|
-
void
|
|
669
|
+
void dispatch({
|
|
499
670
|
action: ObservabilityAction.SEND_EVENT,
|
|
500
671
|
data: {
|
|
501
672
|
name: "threads.toggle-show-resolved",
|
|
@@ -520,7 +691,8 @@ var ThreadPlugin = () => {
|
|
|
520
691
|
],
|
|
521
692
|
menuItemType: "toggle",
|
|
522
693
|
isChecked: viewState.showResolvedThreads,
|
|
523
|
-
testId: "threadPlugin.toggleShowResolved"
|
|
694
|
+
testId: "threadPlugin.toggleShowResolved",
|
|
695
|
+
icon: viewState.showResolvedThreads ? "ph--eye-slash--regular" : "ph--eye--regular"
|
|
524
696
|
}
|
|
525
697
|
}
|
|
526
698
|
];
|
|
@@ -542,7 +714,7 @@ var ThreadPlugin = () => {
|
|
|
542
714
|
{
|
|
543
715
|
id: `${THREAD_PLUGIN}/create/${node.id}`,
|
|
544
716
|
data: async () => {
|
|
545
|
-
await
|
|
717
|
+
await dispatch([
|
|
546
718
|
{
|
|
547
719
|
plugin: THREAD_PLUGIN,
|
|
548
720
|
action: ThreadAction.CREATE
|
|
@@ -565,8 +737,7 @@ var ThreadPlugin = () => {
|
|
|
565
737
|
ns: THREAD_PLUGIN
|
|
566
738
|
}
|
|
567
739
|
],
|
|
568
|
-
icon:
|
|
569
|
-
iconSymbol: "ph--chat--regular",
|
|
740
|
+
icon: "ph--chat--regular",
|
|
570
741
|
testId: "threadPlugin.createObject"
|
|
571
742
|
}
|
|
572
743
|
}
|
|
@@ -589,11 +760,8 @@ var ThreadPlugin = () => {
|
|
|
589
760
|
settings: settings.values
|
|
590
761
|
}) : null;
|
|
591
762
|
}
|
|
592
|
-
case "article":
|
|
593
|
-
case "complementary": {
|
|
763
|
+
case "article": {
|
|
594
764
|
const location = navigationPlugin?.provides.location;
|
|
595
|
-
const threadsIntegrators = useResolvePlugins(providesThreadsConfig);
|
|
596
|
-
const threadProvides = threadsIntegrators.map((p) => p.provides.thread);
|
|
597
765
|
if (data.object instanceof ChannelType && data.object.threads[0]) {
|
|
598
766
|
const channel = data.object;
|
|
599
767
|
if (isLayoutParts(location?.active) && location.active.main) {
|
|
@@ -601,7 +769,7 @@ var ThreadPlugin = () => {
|
|
|
601
769
|
const currentPosition = layoutEntries.findIndex((entry) => channel.id === entry.id);
|
|
602
770
|
if (currentPosition > 0) {
|
|
603
771
|
const objectToTheLeft = layoutEntries[currentPosition - 1];
|
|
604
|
-
const context =
|
|
772
|
+
const context = getSpace3(data.object)?.db.getObjectById(objectToTheLeft.id);
|
|
605
773
|
return /* @__PURE__ */ React5.createElement(ThreadArticle, {
|
|
606
774
|
thread: data.object.threads[0],
|
|
607
775
|
context
|
|
@@ -612,92 +780,27 @@ var ThreadPlugin = () => {
|
|
|
612
780
|
thread: data.object.threads[0]
|
|
613
781
|
});
|
|
614
782
|
}
|
|
615
|
-
if (data.subject instanceof
|
|
783
|
+
if (data.subject instanceof ThreadType2) {
|
|
616
784
|
return /* @__PURE__ */ React5.createElement(React5.Fragment, null, /* @__PURE__ */ React5.createElement(ChatHeading, {
|
|
617
785
|
attendableId: data.subject.id
|
|
618
786
|
}), /* @__PURE__ */ React5.createElement(ChatContainer, {
|
|
619
787
|
thread: data.subject
|
|
620
788
|
}));
|
|
621
789
|
}
|
|
790
|
+
break;
|
|
791
|
+
}
|
|
792
|
+
case "complementary--comments": {
|
|
622
793
|
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)))));
|
|
794
|
+
const { showResolvedThreads } = getViewState(fullyQualifiedId5(data.subject));
|
|
795
|
+
return /* @__PURE__ */ React5.createElement(ThreadComplementary, {
|
|
796
|
+
role,
|
|
797
|
+
subject: data.subject,
|
|
798
|
+
drafts: state.drafts[fullyQualifiedId5(data.subject)],
|
|
799
|
+
current: state.current,
|
|
800
|
+
showResolvedThreads
|
|
801
|
+
});
|
|
700
802
|
}
|
|
803
|
+
break;
|
|
701
804
|
}
|
|
702
805
|
}
|
|
703
806
|
return null;
|
|
@@ -709,18 +812,31 @@ var ThreadPlugin = () => {
|
|
|
709
812
|
case ThreadAction.CREATE: {
|
|
710
813
|
if (intent.data && intent.data.cursor !== void 0) {
|
|
711
814
|
const { cursor, name, subject } = intent.data;
|
|
712
|
-
|
|
713
|
-
|
|
815
|
+
if (subject?.threads === void 0) {
|
|
816
|
+
try {
|
|
817
|
+
subject.threads = [];
|
|
818
|
+
} catch (err) {
|
|
819
|
+
log.error("Subject does not support threads array", subject?.typename, {
|
|
820
|
+
F: __dxlog_file,
|
|
821
|
+
L: 347,
|
|
822
|
+
S: void 0,
|
|
823
|
+
C: (f, a) => f(...a)
|
|
824
|
+
});
|
|
825
|
+
return;
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
const subjectId = fullyQualifiedId5(subject);
|
|
829
|
+
const thread = create2(ThreadType2, {
|
|
714
830
|
name,
|
|
715
831
|
anchor: cursor,
|
|
716
832
|
messages: [],
|
|
717
833
|
status: "staged"
|
|
718
834
|
});
|
|
719
|
-
const
|
|
720
|
-
if (
|
|
721
|
-
|
|
835
|
+
const draft = state.drafts[subjectId];
|
|
836
|
+
if (draft) {
|
|
837
|
+
draft.push(thread);
|
|
722
838
|
} else {
|
|
723
|
-
state.
|
|
839
|
+
state.drafts[subjectId] = [
|
|
724
840
|
thread
|
|
725
841
|
];
|
|
726
842
|
}
|
|
@@ -729,25 +845,27 @@ var ThreadPlugin = () => {
|
|
|
729
845
|
intents: [
|
|
730
846
|
[
|
|
731
847
|
{
|
|
732
|
-
action:
|
|
848
|
+
action: ThreadAction.SELECT,
|
|
733
849
|
data: {
|
|
734
|
-
|
|
735
|
-
complementary: `${subjectId}${SLUG_PATH_SEPARATOR}comments${SLUG_COLLECTION_INDICATOR}`
|
|
736
|
-
}
|
|
850
|
+
current: fullyQualifiedId5(thread)
|
|
737
851
|
}
|
|
738
|
-
}
|
|
852
|
+
}
|
|
853
|
+
],
|
|
854
|
+
[
|
|
739
855
|
{
|
|
740
|
-
action:
|
|
856
|
+
action: NavigationAction.OPEN,
|
|
741
857
|
data: {
|
|
742
|
-
|
|
743
|
-
|
|
858
|
+
activeParts: {
|
|
859
|
+
complementary: "comments"
|
|
860
|
+
}
|
|
744
861
|
}
|
|
745
|
-
}
|
|
862
|
+
}
|
|
863
|
+
],
|
|
864
|
+
[
|
|
746
865
|
{
|
|
747
|
-
action:
|
|
866
|
+
action: LayoutAction2.SET_LAYOUT,
|
|
748
867
|
data: {
|
|
749
868
|
element: "complementary",
|
|
750
|
-
subject: subjectId,
|
|
751
869
|
state: true
|
|
752
870
|
}
|
|
753
871
|
}
|
|
@@ -758,7 +876,7 @@ var ThreadPlugin = () => {
|
|
|
758
876
|
return {
|
|
759
877
|
data: create2(ChannelType, {
|
|
760
878
|
threads: [
|
|
761
|
-
create2(
|
|
879
|
+
create2(ThreadType2, {
|
|
762
880
|
messages: []
|
|
763
881
|
})
|
|
764
882
|
]
|
|
@@ -767,15 +885,26 @@ var ThreadPlugin = () => {
|
|
|
767
885
|
}
|
|
768
886
|
}
|
|
769
887
|
case ThreadAction.SELECT: {
|
|
770
|
-
state.focus = intent.data?.current === state.current ? state.focus : intent.data?.focus;
|
|
771
888
|
state.current = intent.data?.current;
|
|
772
889
|
return {
|
|
773
|
-
data: true
|
|
890
|
+
data: true,
|
|
891
|
+
intents: !intent.data?.skipOpen ? [
|
|
892
|
+
[
|
|
893
|
+
{
|
|
894
|
+
action: NavigationAction.OPEN,
|
|
895
|
+
data: {
|
|
896
|
+
activeParts: {
|
|
897
|
+
complementary: "comments"
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
]
|
|
902
|
+
] : []
|
|
774
903
|
};
|
|
775
904
|
}
|
|
776
905
|
case ThreadAction.TOGGLE_RESOLVED: {
|
|
777
906
|
const { thread } = intent.data ?? {};
|
|
778
|
-
if (!(thread instanceof
|
|
907
|
+
if (!(thread instanceof ThreadType2)) {
|
|
779
908
|
return;
|
|
780
909
|
}
|
|
781
910
|
if (thread.status === "active" || thread.status === void 0) {
|
|
@@ -783,9 +912,10 @@ var ThreadPlugin = () => {
|
|
|
783
912
|
} else if (thread.status === "resolved") {
|
|
784
913
|
thread.status = "active";
|
|
785
914
|
}
|
|
786
|
-
const space =
|
|
915
|
+
const space = getSpace3(thread);
|
|
787
916
|
const spaceId = space?.id;
|
|
788
917
|
return {
|
|
918
|
+
data: true,
|
|
789
919
|
intents: [
|
|
790
920
|
[
|
|
791
921
|
{
|
|
@@ -804,19 +934,21 @@ var ThreadPlugin = () => {
|
|
|
804
934
|
}
|
|
805
935
|
case ThreadAction.DELETE: {
|
|
806
936
|
const { subject, thread } = intent.data ?? {};
|
|
807
|
-
if (!(
|
|
937
|
+
if (!(thread instanceof ThreadType2) || !(subject && typeof subject === "object" && "threads" in subject)) {
|
|
808
938
|
return;
|
|
809
939
|
}
|
|
810
|
-
const subjectId =
|
|
811
|
-
const
|
|
812
|
-
if (
|
|
813
|
-
const index =
|
|
940
|
+
const subjectId = fullyQualifiedId5(subject);
|
|
941
|
+
const draft = state.drafts[subjectId];
|
|
942
|
+
if (draft) {
|
|
943
|
+
const index = draft.findIndex((t) => t.id === thread.id);
|
|
814
944
|
if (index !== -1) {
|
|
815
|
-
|
|
816
|
-
return
|
|
945
|
+
draft.splice(index, 1);
|
|
946
|
+
return {
|
|
947
|
+
data: true
|
|
948
|
+
};
|
|
817
949
|
}
|
|
818
950
|
}
|
|
819
|
-
const space =
|
|
951
|
+
const space = getSpace3(thread);
|
|
820
952
|
if (!space || !subject.threads) {
|
|
821
953
|
return;
|
|
822
954
|
}
|
|
@@ -874,22 +1006,22 @@ var ThreadPlugin = () => {
|
|
|
874
1006
|
}
|
|
875
1007
|
case ThreadAction.ON_MESSAGE_ADD: {
|
|
876
1008
|
const { thread, subject } = intent.data ?? {};
|
|
877
|
-
if (!(thread instanceof
|
|
1009
|
+
if (!(thread instanceof ThreadType2) || !(subject && typeof subject === "object" && "threads" in subject && Array.isArray(subject.threads))) {
|
|
878
1010
|
return;
|
|
879
1011
|
}
|
|
880
|
-
const subjectId =
|
|
881
|
-
const space =
|
|
1012
|
+
const subjectId = fullyQualifiedId5(subject);
|
|
1013
|
+
const space = getSpace3(subject);
|
|
882
1014
|
const intents = [];
|
|
883
1015
|
const analyticsProperties = {
|
|
884
1016
|
threadId: thread.id,
|
|
885
1017
|
spaceId: space?.id
|
|
886
1018
|
};
|
|
887
|
-
if (state.
|
|
1019
|
+
if (state.drafts[subjectId]?.find((t) => t === thread)) {
|
|
888
1020
|
thread.status = "active";
|
|
889
1021
|
subject.threads ? subject.threads.push(thread) : subject.threads = [
|
|
890
1022
|
thread
|
|
891
1023
|
];
|
|
892
|
-
state.
|
|
1024
|
+
state.drafts[subjectId] = state.drafts[subjectId]?.filter(({ id }) => id !== thread.id);
|
|
893
1025
|
intents.push({
|
|
894
1026
|
action: ObservabilityAction.SEND_EVENT,
|
|
895
1027
|
data: {
|
|
@@ -917,8 +1049,8 @@ var ThreadPlugin = () => {
|
|
|
917
1049
|
}
|
|
918
1050
|
case ThreadAction.DELETE_MESSAGE: {
|
|
919
1051
|
const { subject, thread, messageId } = intent.data ?? {};
|
|
920
|
-
const space =
|
|
921
|
-
if (!(
|
|
1052
|
+
const space = getSpace3(subject);
|
|
1053
|
+
if (!(thread instanceof ThreadType2) || !(subject && typeof subject === "object" && "threads" in subject)) {
|
|
922
1054
|
return;
|
|
923
1055
|
}
|
|
924
1056
|
if (!intent.undo) {
|
|
@@ -960,7 +1092,7 @@ var ThreadPlugin = () => {
|
|
|
960
1092
|
name: "threads.message.delete",
|
|
961
1093
|
properties: {
|
|
962
1094
|
threadId: thread.id,
|
|
963
|
-
spaceId: space
|
|
1095
|
+
spaceId: space?.id
|
|
964
1096
|
}
|
|
965
1097
|
}
|
|
966
1098
|
}
|
|
@@ -984,7 +1116,7 @@ var ThreadPlugin = () => {
|
|
|
984
1116
|
name: "threads.message.undo-delete",
|
|
985
1117
|
properties: {
|
|
986
1118
|
threadId: thread.id,
|
|
987
|
-
spaceId: space
|
|
1119
|
+
spaceId: space?.id
|
|
988
1120
|
}
|
|
989
1121
|
}
|
|
990
1122
|
}
|
|
@@ -997,92 +1129,8 @@ var ThreadPlugin = () => {
|
|
|
997
1129
|
}
|
|
998
1130
|
},
|
|
999
1131
|
markdown: {
|
|
1000
|
-
// TODO(burdon): Factor out extension factory into separate file (for simplicity).
|
|
1001
1132
|
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
|
-
];
|
|
1133
|
+
return threads(state, doc, intentPlugin?.provides.intent.dispatch);
|
|
1086
1134
|
}
|
|
1087
1135
|
}
|
|
1088
1136
|
}
|