@dxos/plugin-thread 0.6.12-main.15a606f → 0.6.12-main.2d19bf1

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.
Files changed (74) hide show
  1. package/dist/lib/browser/{ThreadArticle-4VU752F4.mjs → ThreadArticle-GBPIH47W.mjs} +3 -3
  2. package/dist/lib/browser/{ThreadMain-ML3P4XSD.mjs → ThreadMain-PGF7W5EV.mjs} +3 -3
  3. package/dist/lib/browser/{chunk-7NUYW5IW.mjs → chunk-5G3KL6TC.mjs} +4 -6
  4. package/dist/lib/browser/chunk-5G3KL6TC.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-GJRBBPXI.mjs → chunk-JFQZ5W2I.mjs} +2 -2
  6. package/dist/lib/browser/{chunk-GJRBBPXI.mjs.map → chunk-JFQZ5W2I.mjs.map} +1 -1
  7. package/dist/lib/browser/{chunk-XF5QKI75.mjs → chunk-O4YRHIZC.mjs} +2 -2
  8. package/dist/lib/browser/index.mjs +185 -196
  9. package/dist/lib/browser/index.mjs.map +4 -4
  10. package/dist/lib/browser/meta.json +1 -1
  11. package/dist/lib/browser/meta.mjs +1 -1
  12. package/dist/lib/browser/types.mjs +2 -2
  13. package/dist/lib/node/{ThreadArticle-ERUHPHVT.cjs → ThreadArticle-GH5UBWFU.cjs} +7 -7
  14. package/dist/lib/node/{ThreadMain-6DN7FDNB.cjs → ThreadMain-CO6I3DNX.cjs} +7 -7
  15. package/dist/lib/node/{chunk-PZVUW4W2.cjs → chunk-FDYRG7HE.cjs} +9 -9
  16. package/dist/lib/node/{chunk-FXD3DYMO.cjs → chunk-FOZUQZF4.cjs} +6 -6
  17. package/dist/lib/node/{chunk-FXD3DYMO.cjs.map → chunk-FOZUQZF4.cjs.map} +1 -1
  18. package/dist/lib/node/{chunk-6EVXCSDS.cjs → chunk-JIJ7Z6NO.cjs} +6 -8
  19. package/dist/lib/node/chunk-JIJ7Z6NO.cjs.map +7 -0
  20. package/dist/lib/node/index.cjs +207 -220
  21. package/dist/lib/node/index.cjs.map +4 -4
  22. package/dist/lib/node/meta.cjs +4 -4
  23. package/dist/lib/node/meta.cjs.map +1 -1
  24. package/dist/lib/node/meta.json +1 -1
  25. package/dist/lib/node/types.cjs +3 -3
  26. package/dist/lib/node/types.cjs.map +1 -1
  27. package/dist/lib/node-esm/{ThreadArticle-NKI5F4W5.mjs → ThreadArticle-ZTYD52TR.mjs} +3 -3
  28. package/dist/lib/node-esm/{ThreadMain-2A3VQLCW.mjs → ThreadMain-LEHGOF7R.mjs} +3 -3
  29. package/dist/lib/node-esm/{chunk-Y475KZTX.mjs → chunk-DC5ZA6H5.mjs} +4 -6
  30. package/dist/lib/node-esm/chunk-DC5ZA6H5.mjs.map +7 -0
  31. package/dist/lib/node-esm/{chunk-A44C4MTQ.mjs → chunk-XOVJ65DG.mjs} +2 -2
  32. package/dist/lib/node-esm/{chunk-YO46JGAE.mjs → chunk-ZXIPFXSA.mjs} +2 -2
  33. package/dist/lib/node-esm/{chunk-YO46JGAE.mjs.map → chunk-ZXIPFXSA.mjs.map} +1 -1
  34. package/dist/lib/node-esm/index.mjs +185 -196
  35. package/dist/lib/node-esm/index.mjs.map +4 -4
  36. package/dist/lib/node-esm/meta.json +1 -1
  37. package/dist/lib/node-esm/meta.mjs +1 -1
  38. package/dist/lib/node-esm/types.mjs +2 -2
  39. package/dist/types/src/ThreadPlugin.d.ts.map +1 -1
  40. package/dist/types/src/components/CommentContainer.d.ts +1 -1
  41. package/dist/types/src/components/CommentContainer.d.ts.map +1 -1
  42. package/dist/types/src/components/CommentsContainer.d.ts +1 -5
  43. package/dist/types/src/components/CommentsContainer.d.ts.map +1 -1
  44. package/dist/types/src/components/ThreadComplementary.d.ts +2 -3
  45. package/dist/types/src/components/ThreadComplementary.d.ts.map +1 -1
  46. package/dist/types/src/extensions/index.d.ts +2 -0
  47. package/dist/types/src/extensions/index.d.ts.map +1 -0
  48. package/dist/types/src/extensions/threads.d.ts +9 -0
  49. package/dist/types/src/extensions/threads.d.ts.map +1 -0
  50. package/dist/types/src/meta.d.ts +3 -6
  51. package/dist/types/src/meta.d.ts.map +1 -1
  52. package/dist/types/src/types.d.ts +5 -0
  53. package/dist/types/src/types.d.ts.map +1 -1
  54. package/package.json +31 -31
  55. package/src/ThreadPlugin.tsx +58 -142
  56. package/src/components/CommentContainer.tsx +8 -12
  57. package/src/components/CommentsContainer.tsx +1 -18
  58. package/src/components/ThreadComplementary.tsx +9 -16
  59. package/src/extensions/index.ts +5 -0
  60. package/src/extensions/threads.ts +117 -0
  61. package/src/{meta.tsx → meta.ts} +3 -4
  62. package/src/types.ts +7 -2
  63. package/dist/lib/browser/chunk-7NUYW5IW.mjs.map +0 -7
  64. package/dist/lib/node/chunk-6EVXCSDS.cjs.map +0 -7
  65. package/dist/lib/node-esm/chunk-Y475KZTX.mjs.map +0 -7
  66. /package/dist/lib/browser/{ThreadArticle-4VU752F4.mjs.map → ThreadArticle-GBPIH47W.mjs.map} +0 -0
  67. /package/dist/lib/browser/{ThreadMain-ML3P4XSD.mjs.map → ThreadMain-PGF7W5EV.mjs.map} +0 -0
  68. /package/dist/lib/browser/{chunk-XF5QKI75.mjs.map → chunk-O4YRHIZC.mjs.map} +0 -0
  69. /package/dist/lib/node/{ThreadArticle-ERUHPHVT.cjs.map → ThreadArticle-GH5UBWFU.cjs.map} +0 -0
  70. /package/dist/lib/node/{ThreadMain-6DN7FDNB.cjs.map → ThreadMain-CO6I3DNX.cjs.map} +0 -0
  71. /package/dist/lib/node/{chunk-PZVUW4W2.cjs.map → chunk-FDYRG7HE.cjs.map} +0 -0
  72. /package/dist/lib/node-esm/{ThreadArticle-NKI5F4W5.mjs.map → ThreadArticle-ZTYD52TR.mjs.map} +0 -0
  73. /package/dist/lib/node-esm/{ThreadMain-2A3VQLCW.mjs.map → ThreadMain-LEHGOF7R.mjs.map} +0 -0
  74. /package/dist/lib/node-esm/{chunk-A44C4MTQ.mjs.map → chunk-XOVJ65DG.mjs.map} +0 -0
@@ -1,7 +1,7 @@
1
1
  import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
2
  import {
3
3
  ThreadAction
4
- } from "./chunk-YO46JGAE.mjs";
4
+ } from "./chunk-ZXIPFXSA.mjs";
5
5
  import {
6
6
  ChatContainer,
7
7
  ChatHeading,
@@ -11,17 +11,16 @@ import {
11
11
  useAnalyticsCallback,
12
12
  useOnEditAnalytics,
13
13
  useStatus
14
- } from "./chunk-A44C4MTQ.mjs";
14
+ } from "./chunk-XOVJ65DG.mjs";
15
15
  import {
16
16
  THREAD_ITEM,
17
17
  THREAD_PLUGIN,
18
18
  meta_default
19
- } from "./chunk-Y475KZTX.mjs";
19
+ } from "./chunk-DC5ZA6H5.mjs";
20
20
 
21
21
  // packages/plugins/plugin-thread/src/ThreadPlugin.tsx
22
- import { computed, effect } from "@preact/signals-core";
23
22
  import React6 from "react";
24
- import { LayoutAction as LayoutAction2, NavigationAction, parseIntentPlugin, parseNavigationPlugin, resolvePlugin, isLayoutParts, parseMetadataResolverPlugin } from "@dxos/app-framework";
23
+ import { NavigationAction, parseIntentPlugin, parseNavigationPlugin, resolvePlugin, isLayoutParts, parseMetadataResolverPlugin } from "@dxos/app-framework";
25
24
  import { getTypename } from "@dxos/echo-schema";
26
25
  import { create as create2 } from "@dxos/echo-schema";
27
26
  import { LocalStorageStore } from "@dxos/local-storage";
@@ -30,11 +29,9 @@ import { parseClientPlugin } from "@dxos/plugin-client";
30
29
  import { createExtension, isActionGroup, toSignal } from "@dxos/plugin-graph";
31
30
  import { ObservabilityAction } from "@dxos/plugin-observability/meta";
32
31
  import { SpaceAction } from "@dxos/plugin-space";
33
- import { ThreadType, MessageType as MessageType2, ChannelType } from "@dxos/plugin-space/types";
34
- import { getSpace as getSpace2, getTextInRange, createDocAccessor, fullyQualifiedId as fullyQualifiedId4, loadObjectReferences } from "@dxos/react-client/echo";
35
- import { comments, createExternalCommentSync, listener as listener2 } from "@dxos/react-ui-editor";
32
+ import { ThreadType as ThreadType2, MessageType as MessageType2, ChannelType } from "@dxos/plugin-space/types";
33
+ import { getSpace as getSpace3, fullyQualifiedId as fullyQualifiedId5, loadObjectReferences } from "@dxos/react-client/echo";
36
34
  import { translations as threadTranslations } from "@dxos/react-ui-thread";
37
- import { nonNullable as nonNullable3 } from "@dxos/util";
38
35
 
39
36
  // packages/plugins/plugin-thread/src/components/index.ts
40
37
  import React4 from "react";
@@ -55,7 +52,7 @@ var ThreadSettings = ({ settings }) => {
55
52
 
56
53
  // packages/plugins/plugin-thread/src/components/CommentContainer.tsx
57
54
  import { CheckCircle, X } from "@phosphor-icons/react";
58
- import React2, { useCallback, useEffect, useMemo, useRef, useState } from "react";
55
+ import React2, { useCallback, useMemo, useRef, useState } from "react";
59
56
  import { create } from "@dxos/echo-schema";
60
57
  import { MessageType } from "@dxos/plugin-space/types";
61
58
  import { fullyQualifiedId, getSpace, useMembers } from "@dxos/react-client/echo";
@@ -111,14 +108,13 @@ var DeleteThreadButton = ({ onDelete }) => {
111
108
  classNames: "z-[21]"
112
109
  }, label, /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
113
110
  };
114
- var CommentContainer = ({ thread, detached, context, current, autoFocusTextbox, onAttend, onThreadDelete, onMessageDelete, onResolve, onComment }) => {
111
+ var CommentContainer = ({ thread, detached, context, current, onAttend, onThreadDelete, onMessageDelete, onResolve, onComment }) => {
115
112
  const identity = useIdentity();
116
113
  const space = getSpace(thread);
117
114
  const members = useMembers(space?.key);
118
115
  const activity = useStatus(space, fullyQualifiedId(thread));
119
116
  const { t } = useTranslation2(THREAD_PLUGIN);
120
117
  const threadScrollRef = useRef(null);
121
- const [autoFocus, setAutoFocus] = useState(!!autoFocusTextbox);
122
118
  const { themeMode } = useThemeContext();
123
119
  const textboxMetadata = getMessageMetadata(fullyQualifiedId(thread), identity);
124
120
  const [_count, _setCount] = useState(0);
@@ -138,11 +134,6 @@ var CommentContainer = ({ thread, detached, context, current, autoFocusTextbox,
138
134
  ], [
139
135
  _count
140
136
  ]);
141
- useEffect(() => {
142
- setAutoFocus(!!autoFocusTextbox);
143
- }, [
144
- autoFocusTextbox
145
- ]);
146
137
  const scrollToEnd = (behavior) => setTimeout(() => threadScrollRef.current?.scrollIntoView({
147
138
  behavior,
148
139
  block: "end"
@@ -161,7 +152,6 @@ var CommentContainer = ({ thread, detached, context, current, autoFocusTextbox,
161
152
  }));
162
153
  onComment?.(thread);
163
154
  messageRef.current = "";
164
- setAutoFocus(true);
165
155
  scrollToEnd("instant");
166
156
  rerenderEditor();
167
157
  return true;
@@ -200,7 +190,6 @@ var CommentContainer = ({ thread, detached, context, current, autoFocusTextbox,
200
190
  onDelete: (id) => onMessageDelete?.(id)
201
191
  })), /* @__PURE__ */ React2.createElement(MessageTextbox, {
202
192
  extensions,
203
- autoFocus,
204
193
  onSend: handleCreate,
205
194
  ...textboxMetadata
206
195
  }), /* @__PURE__ */ React2.createElement(ThreadFooter, {
@@ -214,29 +203,14 @@ var CommentContainer = ({ thread, detached, context, current, autoFocusTextbox,
214
203
 
215
204
  // packages/plugins/plugin-thread/src/components/CommentsContainer.tsx
216
205
  import { ChatText } from "@phosphor-icons/react";
217
- import React3, { useEffect as useEffect2 } from "react";
206
+ import React3, { useEffect } from "react";
218
207
  import { fullyQualifiedId as fullyQualifiedId2 } from "@dxos/react-client/echo";
219
- import { useTranslation as useTranslation3, Icon, Trans } from "@dxos/react-ui";
220
- import { PlankHeading } from "@dxos/react-ui-deck";
208
+ import { useTranslation as useTranslation3, Trans } from "@dxos/react-ui";
221
209
  import { descriptionText, mx as mx2 } from "@dxos/react-ui-theme";
222
- var CommentsHeading = ({ attendableId }) => {
210
+ var CommentsContainer = ({ threads: threads2, detached = [], currentId, showResolvedThreads, onThreadAttend, onThreadDelete, onMessageDelete, onThreadToggleResolved, ...props }) => {
223
211
  const { t } = useTranslation3(THREAD_PLUGIN);
224
- return /* @__PURE__ */ React3.createElement("div", {
225
- role: "none",
226
- className: "flex items-center"
227
- }, /* @__PURE__ */ React3.createElement(PlankHeading.Button, {
228
- attendableId
229
- }, /* @__PURE__ */ React3.createElement(Icon, {
230
- icon: "ph--quotes--regular",
231
- size: 5
232
- })), /* @__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(() => {
212
+ const filteredThreads = showResolvedThreads ? threads2 : threads2.filter((thread) => !(thread?.status === "resolved"));
213
+ useEffect(() => {
240
214
  if (currentId) {
241
215
  document.getElementById(currentId)?.scrollIntoView({
242
216
  behavior: "smooth",
@@ -253,7 +227,6 @@ var CommentsContainer = ({ threads, detached = [], currentId, autoFocusCurrentTe
253
227
  thread,
254
228
  current: currentId === threadId,
255
229
  detached: detached.includes(threadId),
256
- autoFocusTextbox: autoFocusCurrentTextbox && currentId === threadId,
257
230
  ...onThreadAttend && {
258
231
  onAttend: () => onThreadAttend(thread)
259
232
  },
@@ -285,18 +258,18 @@ var CommentsContainer = ({ threads, detached = [], currentId, autoFocusCurrentTe
285
258
  };
286
259
 
287
260
  // packages/plugins/plugin-thread/src/components/index.ts
288
- var ThreadMain = React4.lazy(() => import("./ThreadMain-2A3VQLCW.mjs"));
289
- var ThreadArticle = React4.lazy(() => import("./ThreadArticle-NKI5F4W5.mjs"));
261
+ var ThreadMain = React4.lazy(() => import("./ThreadMain-LEHGOF7R.mjs"));
262
+ var ThreadArticle = React4.lazy(() => import("./ThreadArticle-ZTYD52TR.mjs"));
290
263
 
291
264
  // packages/plugins/plugin-thread/src/components/ThreadComplementary.tsx
292
- import React5, { useEffect as useEffect3, useMemo as useMemo2 } from "react";
265
+ import React5, { useEffect as useEffect2, useMemo as useMemo2 } from "react";
293
266
  import { LayoutAction, useIntentDispatcher, useResolvePlugins } from "@dxos/app-framework";
294
267
  import { fullyQualifiedId as fullyQualifiedId3 } from "@dxos/react-client/echo";
295
268
  import { ScrollArea } from "@dxos/react-ui";
296
- import { createAttendableAttributes, useAttentionContext } from "@dxos/react-ui-attention";
269
+ import { useAttended } from "@dxos/react-ui-attention";
297
270
  import { nonNullable as nonNullable2 } from "@dxos/util";
298
271
  var providesThreadsConfig = (plugin) => "thread" in plugin.provides ? plugin : void 0;
299
- var ThreadComplementary = ({ role, subject, stagedThreads, current, focus, showResolvedThreads }) => {
272
+ var ThreadComplementary = ({ role, subject, drafts, current, showResolvedThreads }) => {
300
273
  const dispatch = useIntentDispatcher();
301
274
  const threadsIntegrators = useResolvePlugins(providesThreadsConfig);
302
275
  const threadProvides = useMemo2(() => threadsIntegrators.map((p) => p.provides.thread), [
@@ -310,42 +283,37 @@ var ThreadComplementary = ({ role, subject, stagedThreads, current, focus, showR
310
283
  createSort,
311
284
  subject
312
285
  ]);
313
- const threads = useMemo2(() => {
314
- return subject.threads.concat(stagedThreads ?? []).filter(nonNullable2);
286
+ const threads2 = useMemo2(() => {
287
+ return subject.threads.concat(drafts ?? []).filter(nonNullable2);
315
288
  }, [
316
289
  JSON.stringify(subject.threads),
317
- JSON.stringify(stagedThreads)
290
+ JSON.stringify(drafts)
318
291
  ]);
319
292
  const detachedIds = useMemo2(() => {
320
- return threads.filter(({ anchor }) => !anchor).map((thread) => fullyQualifiedId3(thread));
293
+ return threads2.filter(({ anchor }) => !anchor).map((thread) => fullyQualifiedId3(thread));
321
294
  }, [
322
- threads
295
+ threads2
323
296
  ]);
324
- useEffect3(() => {
297
+ useEffect2(() => {
325
298
  if (!sort) {
326
299
  return;
327
300
  }
328
- threads.sort((a, b) => sort(a?.anchor, b?.anchor));
301
+ threads2.sort((a, b) => sort(a?.anchor, b?.anchor));
329
302
  }, [
330
303
  sort,
331
- threads
304
+ threads2
332
305
  ]);
333
- const { attended } = useAttentionContext("Thread Complementary");
306
+ const attended = useAttended();
334
307
  const qualifiedSubjectId = fullyQualifiedId3(subject);
335
- const attendableAttrs = createAttendableAttributes(qualifiedSubjectId);
336
308
  return /* @__PURE__ */ React5.createElement("div", {
337
309
  role: "none",
338
- className: "contents group/attention",
339
- ...attendableAttrs
340
- }, role === "complementary" && /* @__PURE__ */ React5.createElement(CommentsHeading, {
341
- attendableId: qualifiedSubjectId
342
- }), /* @__PURE__ */ React5.createElement(ScrollArea.Root, {
310
+ className: "contents"
311
+ }, /* @__PURE__ */ React5.createElement(ScrollArea.Root, {
343
312
  classNames: "row-span-2"
344
313
  }, /* @__PURE__ */ React5.createElement(ScrollArea.Viewport, null, /* @__PURE__ */ React5.createElement(CommentsContainer, {
345
- threads,
314
+ threads: threads2,
346
315
  detached: detachedIds,
347
- currentId: attended.has(qualifiedSubjectId) ? current : void 0,
348
- autoFocusCurrentTextbox: focus,
316
+ currentId: attended.includes(qualifiedSubjectId) ? current : void 0,
349
317
  showResolvedThreads,
350
318
  onThreadAttend: (thread) => {
351
319
  const threadId = fullyQualifiedId3(thread);
@@ -404,6 +372,95 @@ var ThreadComplementary = ({ role, subject, stagedThreads, current, focus, showR
404
372
  }), /* @__PURE__ */ React5.createElement(ScrollArea.Scrollbar, null, /* @__PURE__ */ React5.createElement(ScrollArea.Thumb, null)))));
405
373
  };
406
374
 
375
+ // packages/plugins/plugin-thread/src/extensions/threads.ts
376
+ import { EditorView } from "@codemirror/view";
377
+ import { computed, effect } from "@preact/signals-core";
378
+ import { ThreadType } from "@dxos/plugin-space/types";
379
+ import { getSpace as getSpace2, getTextInRange, createDocAccessor, fullyQualifiedId as fullyQualifiedId4 } from "@dxos/react-client/echo";
380
+ import { comments, createExternalCommentSync } from "@dxos/react-ui-editor";
381
+ import { nonNullable as nonNullable3 } from "@dxos/util";
382
+ var getName = (doc, anchor) => {
383
+ if (doc.content) {
384
+ const [start, end] = anchor.split(":");
385
+ return getTextInRange(createDocAccessor(doc.content, [
386
+ "content"
387
+ ]), start, end);
388
+ }
389
+ };
390
+ var threads = (state, doc, dispatch) => {
391
+ const space = doc && getSpace2(doc);
392
+ if (!doc || !space || !dispatch) {
393
+ return [
394
+ comments()
395
+ ];
396
+ }
397
+ const threads2 = computed(() => [
398
+ ...doc.threads.filter(nonNullable3),
399
+ ...state.drafts[fullyQualifiedId4(doc)] ?? []
400
+ ].filter((thread) => !(thread?.status === "resolved")));
401
+ return [
402
+ EditorView.updateListener.of((update) => {
403
+ if (update.docChanged) {
404
+ doc.threads.forEach((thread) => {
405
+ if (thread?.anchor) {
406
+ const name = getName(doc, thread.anchor);
407
+ if (name && name !== thread.name) {
408
+ thread.name = name;
409
+ }
410
+ }
411
+ });
412
+ }
413
+ }),
414
+ createExternalCommentSync(fullyQualifiedId4(doc), (sink) => effect(() => sink()), () => threads2.value.filter((thread) => thread?.anchor).map((thread) => ({
415
+ id: fullyQualifiedId4(thread),
416
+ cursor: thread.anchor
417
+ }))),
418
+ comments({
419
+ id: fullyQualifiedId4(doc),
420
+ onCreate: ({ cursor }) => {
421
+ const name = getName(doc, cursor);
422
+ void dispatch({
423
+ action: ThreadAction.CREATE,
424
+ data: {
425
+ cursor,
426
+ name,
427
+ subject: doc
428
+ }
429
+ });
430
+ },
431
+ onDelete: ({ id }) => {
432
+ const draft = state.drafts[fullyQualifiedId4(doc)];
433
+ if (draft) {
434
+ const index = draft.findIndex((thread2) => fullyQualifiedId4(thread2) === id);
435
+ if (index !== -1) {
436
+ draft.splice(index, 1);
437
+ }
438
+ }
439
+ const thread = doc.threads.find((thread2) => thread2?.id === id);
440
+ if (thread) {
441
+ thread.anchor = void 0;
442
+ }
443
+ },
444
+ onUpdate: ({ id, cursor }) => {
445
+ const thread = state.drafts[fullyQualifiedId4(doc)]?.find((thread2) => fullyQualifiedId4(thread2) === id) ?? doc.threads.find((thread2) => thread2?.id === id);
446
+ if (thread instanceof ThreadType && thread.anchor) {
447
+ thread.name = getName(doc, thread.anchor);
448
+ thread.anchor = cursor;
449
+ }
450
+ },
451
+ onSelect: ({ selection: { current, closest } }) => {
452
+ void dispatch({
453
+ action: ThreadAction.SELECT,
454
+ data: {
455
+ current: current ?? closest,
456
+ skipOpen: true
457
+ }
458
+ });
459
+ }
460
+ })
461
+ ];
462
+ };
463
+
407
464
  // packages/plugins/plugin-thread/src/translations.ts
408
465
  var translations_default = [
409
466
  {
@@ -448,7 +505,7 @@ var initialViewState = {
448
505
  var ThreadPlugin = () => {
449
506
  const settings = new LocalStorageStore(THREAD_PLUGIN);
450
507
  const state = create2({
451
- staging: {}
508
+ drafts: {}
452
509
  });
453
510
  const viewStore = create2({});
454
511
  const getViewState = (subjectId) => {
@@ -492,7 +549,7 @@ var ThreadPlugin = () => {
492
549
  // TODO(wittjosiah): Move out of metadata.
493
550
  loadReferences: (channel) => loadObjectReferences(channel, (channel2) => channel2.threads)
494
551
  },
495
- [ThreadType.typename]: {
552
+ [ThreadType2.typename]: {
496
553
  // TODO(wittjosiah): Move out of metadata.
497
554
  loadReferences: (thread) => loadObjectReferences(thread, (thread2) => thread2.messages)
498
555
  },
@@ -528,7 +585,7 @@ var ThreadPlugin = () => {
528
585
  echo: {
529
586
  schema: [
530
587
  ChannelType,
531
- ThreadType,
588
+ ThreadType2,
532
589
  MessageType2
533
590
  ]
534
591
  },
@@ -556,7 +613,7 @@ var ThreadPlugin = () => {
556
613
  onChange();
557
614
  });
558
615
  return () => clearTimeout(timeout);
559
- }, () => space?.db.getObjectById(objectId));
616
+ }, () => space?.db.getObjectById(objectId), subjectId);
560
617
  if (!object || !subjectId) {
561
618
  return;
562
619
  }
@@ -571,11 +628,12 @@ var ThreadPlugin = () => {
571
628
  return {
572
629
  id,
573
630
  type: "orphan-comments-for-subject",
574
- data: object,
631
+ data: null,
575
632
  properties: {
576
- icon: meta.icon,
633
+ icon: "ph--chat-text--regular",
577
634
  label,
578
- showResolvedThreads: viewState.showResolvedThreads
635
+ showResolvedThreads: viewState.showResolvedThreads,
636
+ object
579
637
  }
580
638
  };
581
639
  },
@@ -683,8 +741,7 @@ var ThreadPlugin = () => {
683
741
  settings: settings.values
684
742
  }) : null;
685
743
  }
686
- case "article":
687
- case "complementary": {
744
+ case "article": {
688
745
  const location = navigationPlugin?.provides.location;
689
746
  if (data.object instanceof ChannelType && data.object.threads[0]) {
690
747
  const channel = data.object;
@@ -693,7 +750,7 @@ var ThreadPlugin = () => {
693
750
  const currentPosition = layoutEntries.findIndex((entry) => channel.id === entry.id);
694
751
  if (currentPosition > 0) {
695
752
  const objectToTheLeft = layoutEntries[currentPosition - 1];
696
- const context = getSpace2(data.object)?.db.getObjectById(objectToTheLeft.id);
753
+ const context = getSpace3(data.object)?.db.getObjectById(objectToTheLeft.id);
697
754
  return /* @__PURE__ */ React6.createElement(ThreadArticle, {
698
755
  thread: data.object.threads[0],
699
756
  context
@@ -704,24 +761,27 @@ var ThreadPlugin = () => {
704
761
  thread: data.object.threads[0]
705
762
  });
706
763
  }
707
- if (data.subject instanceof ThreadType) {
764
+ if (data.subject instanceof ThreadType2) {
708
765
  return /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(ChatHeading, {
709
766
  attendableId: data.subject.id
710
767
  }), /* @__PURE__ */ React6.createElement(ChatContainer, {
711
768
  thread: data.subject
712
769
  }));
713
770
  }
771
+ break;
772
+ }
773
+ case "complementary--comments": {
714
774
  if (data.subject && typeof data.subject === "object" && "threads" in data.subject && Array.isArray(data.subject.threads)) {
715
- const { showResolvedThreads } = getViewState(fullyQualifiedId4(data.subject));
775
+ const { showResolvedThreads } = getViewState(fullyQualifiedId5(data.subject));
716
776
  return /* @__PURE__ */ React6.createElement(ThreadComplementary, {
717
777
  role,
718
778
  subject: data.subject,
719
- stagedThreads: state.staging[fullyQualifiedId4(data.subject)],
779
+ drafts: state.drafts[fullyQualifiedId5(data.subject)],
720
780
  current: state.current,
721
- focus: true,
722
781
  showResolvedThreads
723
782
  });
724
783
  }
784
+ break;
725
785
  }
726
786
  }
727
787
  return null;
@@ -736,28 +796,28 @@ var ThreadPlugin = () => {
736
796
  if (subject?.threads === void 0) {
737
797
  try {
738
798
  subject.threads = [];
739
- } catch (e) {
799
+ } catch (err) {
740
800
  log.error("Subject does not support threads array", subject?.typename, {
741
801
  F: __dxlog_file,
742
- L: 331,
802
+ L: 322,
743
803
  S: void 0,
744
804
  C: (f, a) => f(...a)
745
805
  });
746
806
  return;
747
807
  }
748
808
  }
749
- const subjectId = fullyQualifiedId4(subject);
750
- const thread = create2(ThreadType, {
809
+ const subjectId = fullyQualifiedId5(subject);
810
+ const thread = create2(ThreadType2, {
751
811
  name,
752
812
  anchor: cursor,
753
813
  messages: [],
754
814
  status: "staged"
755
815
  });
756
- const stagingArea = state.staging[subjectId];
757
- if (stagingArea) {
758
- stagingArea.push(thread);
816
+ const draft = state.drafts[subjectId];
817
+ if (draft) {
818
+ draft.push(thread);
759
819
  } else {
760
- state.staging[subjectId] = [
820
+ state.drafts[subjectId] = [
761
821
  thread
762
822
  ];
763
823
  }
@@ -768,16 +828,17 @@ var ThreadPlugin = () => {
768
828
  {
769
829
  action: ThreadAction.SELECT,
770
830
  data: {
771
- current: fullyQualifiedId4(thread),
772
- focus: true
831
+ current: fullyQualifiedId5(thread)
773
832
  }
774
- },
833
+ }
834
+ ],
835
+ [
775
836
  {
776
- action: LayoutAction2.SET_LAYOUT,
837
+ action: NavigationAction.OPEN,
777
838
  data: {
778
- element: "complementary",
779
- subject: subjectId,
780
- state: true
839
+ activeParts: {
840
+ complementary: "comments"
841
+ }
781
842
  }
782
843
  }
783
844
  ]
@@ -787,7 +848,7 @@ var ThreadPlugin = () => {
787
848
  return {
788
849
  data: create2(ChannelType, {
789
850
  threads: [
790
- create2(ThreadType, {
851
+ create2(ThreadType2, {
791
852
  messages: []
792
853
  })
793
854
  ]
@@ -796,15 +857,26 @@ var ThreadPlugin = () => {
796
857
  }
797
858
  }
798
859
  case ThreadAction.SELECT: {
799
- state.focus = intent.data?.current === state.current ? state.focus : intent.data?.focus;
800
860
  state.current = intent.data?.current;
801
861
  return {
802
- data: true
862
+ data: true,
863
+ intents: !intent.data?.skipOpen ? [
864
+ [
865
+ {
866
+ action: NavigationAction.OPEN,
867
+ data: {
868
+ activeParts: {
869
+ complementary: "comments"
870
+ }
871
+ }
872
+ }
873
+ ]
874
+ ] : []
803
875
  };
804
876
  }
805
877
  case ThreadAction.TOGGLE_RESOLVED: {
806
878
  const { thread } = intent.data ?? {};
807
- if (!(thread instanceof ThreadType)) {
879
+ if (!(thread instanceof ThreadType2)) {
808
880
  return;
809
881
  }
810
882
  if (thread.status === "active" || thread.status === void 0) {
@@ -812,9 +884,10 @@ var ThreadPlugin = () => {
812
884
  } else if (thread.status === "resolved") {
813
885
  thread.status = "active";
814
886
  }
815
- const space = getSpace2(thread);
887
+ const space = getSpace3(thread);
816
888
  const spaceId = space?.id;
817
889
  return {
890
+ data: true,
818
891
  intents: [
819
892
  [
820
893
  {
@@ -833,21 +906,21 @@ var ThreadPlugin = () => {
833
906
  }
834
907
  case ThreadAction.DELETE: {
835
908
  const { subject, thread } = intent.data ?? {};
836
- if (!(thread instanceof ThreadType) || !(subject && typeof subject === "object" && "threads" in subject)) {
909
+ if (!(thread instanceof ThreadType2) || !(subject && typeof subject === "object" && "threads" in subject)) {
837
910
  return;
838
911
  }
839
- const subjectId = fullyQualifiedId4(subject);
840
- const stagingArea = state.staging[subjectId];
841
- if (stagingArea) {
842
- const index = stagingArea.findIndex((t) => t.id === thread.id);
912
+ const subjectId = fullyQualifiedId5(subject);
913
+ const draft = state.drafts[subjectId];
914
+ if (draft) {
915
+ const index = draft.findIndex((t) => t.id === thread.id);
843
916
  if (index !== -1) {
844
- stagingArea.splice(index, 1);
917
+ draft.splice(index, 1);
845
918
  return {
846
919
  data: true
847
920
  };
848
921
  }
849
922
  }
850
- const space = getSpace2(thread);
923
+ const space = getSpace3(thread);
851
924
  if (!space || !subject.threads) {
852
925
  return;
853
926
  }
@@ -905,22 +978,22 @@ var ThreadPlugin = () => {
905
978
  }
906
979
  case ThreadAction.ON_MESSAGE_ADD: {
907
980
  const { thread, subject } = intent.data ?? {};
908
- if (!(thread instanceof ThreadType) || !(subject && typeof subject === "object" && "threads" in subject && Array.isArray(subject.threads))) {
981
+ if (!(thread instanceof ThreadType2) || !(subject && typeof subject === "object" && "threads" in subject && Array.isArray(subject.threads))) {
909
982
  return;
910
983
  }
911
- const subjectId = fullyQualifiedId4(subject);
912
- const space = getSpace2(subject);
984
+ const subjectId = fullyQualifiedId5(subject);
985
+ const space = getSpace3(subject);
913
986
  const intents = [];
914
987
  const analyticsProperties = {
915
988
  threadId: thread.id,
916
989
  spaceId: space?.id
917
990
  };
918
- if (state.staging[subjectId]?.find((t) => t === thread)) {
991
+ if (state.drafts[subjectId]?.find((t) => t === thread)) {
919
992
  thread.status = "active";
920
993
  subject.threads ? subject.threads.push(thread) : subject.threads = [
921
994
  thread
922
995
  ];
923
- state.staging[subjectId] = state.staging[subjectId]?.filter((t) => t.id !== thread.id);
996
+ state.drafts[subjectId] = state.drafts[subjectId]?.filter(({ id }) => id !== thread.id);
924
997
  intents.push({
925
998
  action: ObservabilityAction.SEND_EVENT,
926
999
  data: {
@@ -948,8 +1021,8 @@ var ThreadPlugin = () => {
948
1021
  }
949
1022
  case ThreadAction.DELETE_MESSAGE: {
950
1023
  const { subject, thread, messageId } = intent.data ?? {};
951
- const space = getSpace2(subject);
952
- if (!(thread instanceof ThreadType) || !(subject && typeof subject === "object" && "threads" in subject)) {
1024
+ const space = getSpace3(subject);
1025
+ if (!(thread instanceof ThreadType2) || !(subject && typeof subject === "object" && "threads" in subject)) {
953
1026
  return;
954
1027
  }
955
1028
  if (!intent.undo) {
@@ -1028,92 +1101,8 @@ var ThreadPlugin = () => {
1028
1101
  }
1029
1102
  },
1030
1103
  markdown: {
1031
- // TODO(burdon): Factor out extension factory into separate file (for simplicity).
1032
1104
  extensions: ({ document: doc }) => {
1033
- const space = doc && getSpace2(doc);
1034
- if (!doc || !space) {
1035
- return [
1036
- comments()
1037
- ];
1038
- }
1039
- const threads = computed(() => [
1040
- ...doc.threads.filter(nonNullable3),
1041
- ...state.staging[fullyQualifiedId4(doc)] ?? []
1042
- ].filter((thread) => !(thread?.status === "resolved")));
1043
- return [
1044
- listener2({
1045
- onChange: () => {
1046
- doc.threads.forEach((thread) => {
1047
- if (thread?.anchor) {
1048
- const [start, end] = thread.anchor.split(":");
1049
- const name = doc.content && getTextInRange(createDocAccessor(doc.content, [
1050
- "content"
1051
- ]), start, end);
1052
- if (name && name !== thread.name) {
1053
- thread.name = name;
1054
- }
1055
- }
1056
- });
1057
- }
1058
- }),
1059
- createExternalCommentSync(doc.id, (sink) => effect(() => sink()), () => threads.value.filter((thread) => thread?.anchor).map((thread) => ({
1060
- id: fullyQualifiedId4(thread),
1061
- cursor: thread.anchor
1062
- }))),
1063
- comments({
1064
- id: doc.id,
1065
- onCreate: ({ cursor }) => {
1066
- const [start, end] = cursor.split(":");
1067
- const name = doc.content && getTextInRange(createDocAccessor(doc.content, [
1068
- "content"
1069
- ]), start, end);
1070
- void intentPlugin?.provides.intent.dispatch({
1071
- action: ThreadAction.CREATE,
1072
- data: {
1073
- cursor,
1074
- name,
1075
- subject: doc
1076
- }
1077
- });
1078
- },
1079
- onDelete: ({ id }) => {
1080
- const stagingArea = state.staging[fullyQualifiedId4(doc)];
1081
- if (stagingArea) {
1082
- const index = stagingArea.findIndex((thread2) => fullyQualifiedId4(thread2) === id);
1083
- if (index !== -1) {
1084
- stagingArea.splice(index, 1);
1085
- }
1086
- }
1087
- const thread = doc.threads.find((thread2) => thread2?.id === id);
1088
- if (thread) {
1089
- thread.anchor = void 0;
1090
- }
1091
- },
1092
- onUpdate: ({ id, cursor }) => {
1093
- const thread = state.staging[fullyQualifiedId4(doc)]?.find((thread2) => fullyQualifiedId4(thread2) === id) ?? doc.threads.find((thread2) => thread2?.id === id);
1094
- if (thread instanceof ThreadType && thread.anchor) {
1095
- const [start, end] = thread.anchor.split(":");
1096
- thread.name = doc.content && getTextInRange(createDocAccessor(doc.content, [
1097
- "content"
1098
- ]), start, end);
1099
- thread.anchor = cursor;
1100
- }
1101
- },
1102
- onSelect: ({ selection: { current, closest } }) => {
1103
- const dispatch = intentPlugin?.provides.intent.dispatch;
1104
- if (dispatch) {
1105
- void dispatch([
1106
- {
1107
- action: ThreadAction.SELECT,
1108
- data: {
1109
- current: current ?? closest
1110
- }
1111
- }
1112
- ]);
1113
- }
1114
- }
1115
- })
1116
- ];
1105
+ return threads(state, doc, intentPlugin?.provides.intent.dispatch);
1117
1106
  }
1118
1107
  }
1119
1108
  }