@dxos/plugin-thread 0.6.11 → 0.6.12-main.5cc132e

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 (64) hide show
  1. package/dist/lib/browser/{ThreadArticle-O64ZECMF.mjs → ThreadArticle-6L6BGE4Z.mjs} +2 -2
  2. package/dist/lib/browser/{ThreadMain-ZDCRC6RG.mjs → ThreadMain-DU6LBSN3.mjs} +2 -2
  3. package/dist/lib/browser/{chunk-P7ZE5N5M.mjs → chunk-AVC4CGJM.mjs} +6 -6
  4. package/dist/lib/browser/chunk-AVC4CGJM.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-GKPZHUT3.mjs → chunk-U5UVX4ZP.mjs} +1 -1
  6. package/dist/lib/browser/{chunk-GKPZHUT3.mjs.map → chunk-U5UVX4ZP.mjs.map} +1 -1
  7. package/dist/lib/browser/index.mjs +217 -153
  8. package/dist/lib/browser/index.mjs.map +4 -4
  9. package/dist/lib/browser/meta.json +1 -1
  10. package/dist/lib/browser/types.mjs +1 -1
  11. package/dist/lib/node/{ThreadArticle-DO56JXBU.cjs → ThreadArticle-7BWXVIJ4.cjs} +6 -6
  12. package/dist/lib/node/{ThreadMain-XJX75GHG.cjs → ThreadMain-XSRB6NKJ.cjs} +6 -6
  13. package/dist/lib/node/{chunk-D5GOVXHS.cjs → chunk-4B2ARV7L.cjs} +4 -4
  14. package/dist/lib/node/{chunk-D5GOVXHS.cjs.map → chunk-4B2ARV7L.cjs.map} +1 -1
  15. package/dist/lib/node/{chunk-5PZNPPQF.cjs → chunk-T7TXCNHL.cjs} +8 -8
  16. package/dist/lib/node/chunk-T7TXCNHL.cjs.map +7 -0
  17. package/dist/lib/node/index.cjs +258 -196
  18. package/dist/lib/node/index.cjs.map +4 -4
  19. package/dist/lib/node/meta.json +1 -1
  20. package/dist/lib/node/types.cjs +2 -2
  21. package/dist/lib/node/types.cjs.map +1 -1
  22. package/dist/lib/node-esm/ThreadArticle-6L6BGE4Z.mjs +18 -0
  23. package/dist/lib/node-esm/ThreadArticle-6L6BGE4Z.mjs.map +7 -0
  24. package/dist/lib/node-esm/ThreadMain-DU6LBSN3.mjs +26 -0
  25. package/dist/lib/node-esm/ThreadMain-DU6LBSN3.mjs.map +7 -0
  26. package/dist/lib/node-esm/chunk-5IBJO53M.mjs +21 -0
  27. package/dist/lib/node-esm/chunk-5IBJO53M.mjs.map +7 -0
  28. package/dist/lib/node-esm/chunk-AVC4CGJM.mjs +410 -0
  29. package/dist/lib/node-esm/chunk-AVC4CGJM.mjs.map +7 -0
  30. package/dist/lib/node-esm/chunk-U5UVX4ZP.mjs +20 -0
  31. package/dist/lib/node-esm/chunk-U5UVX4ZP.mjs.map +7 -0
  32. package/dist/lib/node-esm/index.mjs +1166 -0
  33. package/dist/lib/node-esm/index.mjs.map +7 -0
  34. package/dist/lib/node-esm/meta.json +1 -0
  35. package/dist/lib/node-esm/meta.mjs +11 -0
  36. package/dist/lib/node-esm/meta.mjs.map +7 -0
  37. package/dist/lib/node-esm/types.mjs +8 -0
  38. package/dist/lib/node-esm/types.mjs.map +7 -0
  39. package/dist/types/src/ThreadPlugin.d.ts.map +1 -1
  40. package/dist/types/src/components/CommentContainer.d.ts.map +1 -1
  41. package/dist/types/src/components/CommentsContainer.d.ts.map +1 -1
  42. package/dist/types/src/components/MessageContainer.d.ts.map +1 -1
  43. package/dist/types/src/components/ThreadComplementary.d.ts +11 -0
  44. package/dist/types/src/components/ThreadComplementary.d.ts.map +1 -0
  45. package/dist/types/src/types.d.ts +1 -1
  46. package/dist/types/src/types.d.ts.map +1 -1
  47. package/package.json +35 -32
  48. package/src/ThreadPlugin.tsx +46 -111
  49. package/src/components/ChatContainer.tsx +4 -4
  50. package/src/components/CommentContainer.tsx +10 -7
  51. package/src/components/Comments.stories.tsx +2 -2
  52. package/src/components/CommentsContainer.tsx +18 -14
  53. package/src/components/MessageContainer.tsx +2 -1
  54. package/src/components/ThreadComplementary.tsx +120 -0
  55. package/src/types.ts +1 -1
  56. package/dist/lib/browser/chunk-P7ZE5N5M.mjs.map +0 -7
  57. package/dist/lib/node/chunk-5PZNPPQF.cjs.map +0 -7
  58. package/dist/types/src/types.test.d.ts +0 -2
  59. package/dist/types/src/types.test.d.ts.map +0 -1
  60. package/src/types.test.ts +0 -13
  61. /package/dist/lib/browser/{ThreadArticle-O64ZECMF.mjs.map → ThreadArticle-6L6BGE4Z.mjs.map} +0 -0
  62. /package/dist/lib/browser/{ThreadMain-ZDCRC6RG.mjs.map → ThreadMain-DU6LBSN3.mjs.map} +0 -0
  63. /package/dist/lib/node/{ThreadArticle-DO56JXBU.cjs.map → ThreadArticle-7BWXVIJ4.cjs.map} +0 -0
  64. /package/dist/lib/node/{ThreadMain-XJX75GHG.cjs.map → ThreadMain-XSRB6NKJ.cjs.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ThreadAction
3
- } from "./chunk-GKPZHUT3.mjs";
3
+ } from "./chunk-U5UVX4ZP.mjs";
4
4
  import {
5
5
  ChatContainer,
6
6
  ChatHeading,
@@ -10,7 +10,7 @@ import {
10
10
  useAnalyticsCallback,
11
11
  useOnEditAnalytics,
12
12
  useStatus
13
- } from "./chunk-P7ZE5N5M.mjs";
13
+ } from "./chunk-AVC4CGJM.mjs";
14
14
  import {
15
15
  THREAD_ITEM,
16
16
  THREAD_PLUGIN,
@@ -20,24 +20,22 @@ import {
20
20
  // packages/plugins/plugin-thread/src/ThreadPlugin.tsx
21
21
  import { Chat } from "@phosphor-icons/react";
22
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";
23
+ import React6 from "react";
24
+ import { LayoutAction as LayoutAction2, NavigationAction, parseIntentPlugin, parseNavigationPlugin, resolvePlugin, parseGraphPlugin, SLUG_PATH_SEPARATOR, SLUG_COLLECTION_INDICATOR, isLayoutParts, parseMetadataResolverPlugin } from "@dxos/app-framework";
25
25
  import { getTypename } from "@dxos/echo-schema";
26
26
  import { create as create2 } from "@dxos/echo-schema";
27
27
  import { LocalStorageStore } from "@dxos/local-storage";
28
+ import { log } from "@dxos/log";
28
29
  import { parseAttentionPlugin } from "@dxos/plugin-attention";
29
30
  import { parseClientPlugin } from "@dxos/plugin-client";
30
31
  import { createExtension, isActionGroup } from "@dxos/plugin-graph";
31
- import { DocumentType } from "@dxos/plugin-markdown/types";
32
32
  import { ObservabilityAction } from "@dxos/plugin-observability/meta";
33
33
  import { SpaceAction } from "@dxos/plugin-space";
34
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";
35
+ import { getSpace as getSpace2, getTextInRange, Filter, createDocAccessor, fullyQualifiedId as fullyQualifiedId4, loadObjectReferences } from "@dxos/react-client/echo";
38
36
  import { comments, createExternalCommentSync, listener as listener2 } from "@dxos/react-ui-editor";
39
37
  import { translations as threadTranslations } from "@dxos/react-ui-thread";
40
- import { nonNullable as nonNullable2 } from "@dxos/util";
38
+ import { nonNullable as nonNullable3 } from "@dxos/util";
41
39
 
42
40
  // packages/plugins/plugin-thread/src/components/index.ts
43
41
  import React4 from "react";
@@ -61,7 +59,7 @@ import { CheckCircle, X } from "@phosphor-icons/react";
61
59
  import React2, { useCallback, useEffect, useMemo, useRef, useState } from "react";
62
60
  import { create } from "@dxos/echo-schema";
63
61
  import { MessageType } from "@dxos/plugin-space/types";
64
- import { getSpace, useMembers } from "@dxos/react-client/echo";
62
+ import { fullyQualifiedId, getSpace, useMembers } from "@dxos/react-client/echo";
65
63
  import { useIdentity } from "@dxos/react-client/halo";
66
64
  import { Button, Tag, Tooltip, useThemeContext, useTranslation as useTranslation2 } from "@dxos/react-ui";
67
65
  import { createBasicExtensions, createThemeExtensions, listener } from "@dxos/react-ui-editor";
@@ -118,12 +116,12 @@ var CommentContainer = ({ thread, detached, context, current, autoFocusTextbox,
118
116
  const identity = useIdentity();
119
117
  const space = getSpace(thread);
120
118
  const members = useMembers(space?.key);
121
- const activity = useStatus(space, thread.id);
119
+ const activity = useStatus(space, fullyQualifiedId(thread));
122
120
  const { t } = useTranslation2(THREAD_PLUGIN);
123
121
  const threadScrollRef = useRef(null);
124
122
  const [autoFocus, setAutoFocus] = useState(!!autoFocusTextbox);
125
123
  const { themeMode } = useThemeContext();
126
- const textboxMetadata = getMessageMetadata(thread.id, identity);
124
+ const textboxMetadata = getMessageMetadata(fullyQualifiedId(thread), identity);
127
125
  const [_count, _setCount] = useState(0);
128
126
  const rerenderEditor = () => _setCount((count) => count + 1);
129
127
  const messageRef = useRef("");
@@ -172,12 +170,11 @@ var CommentContainer = ({ thread, detached, context, current, autoFocusTextbox,
172
170
  thread,
173
171
  identity
174
172
  ]);
175
- const handleDeleteMessage = (id) => onMessageDelete?.(id);
176
173
  return /* @__PURE__ */ React2.createElement(Thread, {
177
174
  onClickCapture: onAttend,
178
175
  onFocusCapture: onAttend,
179
176
  current,
180
- id: thread.id
177
+ id: fullyQualifiedId(thread)
181
178
  }, /* @__PURE__ */ React2.createElement("div", {
182
179
  role: "none",
183
180
  className: mx("col-span-2 grid grid-cols-[var(--rail-size)_1fr_min-content]", hoverableControls, hoverableFocusedWithinControls)
@@ -201,7 +198,7 @@ var CommentContainer = ({ thread, detached, context, current, autoFocusTextbox,
201
198
  key: message.id,
202
199
  message,
203
200
  members,
204
- onDelete: handleDeleteMessage
201
+ onDelete: (id) => onMessageDelete?.(id)
205
202
  })), /* @__PURE__ */ React2.createElement(MessageTextbox, {
206
203
  extensions,
207
204
  autoFocus,
@@ -219,6 +216,7 @@ var CommentContainer = ({ thread, detached, context, current, autoFocusTextbox,
219
216
  // packages/plugins/plugin-thread/src/components/CommentsContainer.tsx
220
217
  import { ChatText, Quotes } from "@phosphor-icons/react";
221
218
  import React3, { useEffect as useEffect2 } from "react";
219
+ import { fullyQualifiedId as fullyQualifiedId2 } from "@dxos/react-client/echo";
222
220
  import { useTranslation as useTranslation3, Trans } from "@dxos/react-ui";
223
221
  import { PlankHeading, plankHeadingIconProps } from "@dxos/react-ui-deck";
224
222
  import { descriptionText, mx as mx2 } from "@dxos/react-ui-theme";
@@ -246,26 +244,29 @@ var CommentsContainer = ({ threads, detached = [], currentId, autoFocusCurrentTe
246
244
  }, [
247
245
  currentId
248
246
  ]);
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", {
247
+ return /* @__PURE__ */ React3.createElement(React3.Fragment, null, filteredThreads.length > 0 ? filteredThreads.map((thread) => {
248
+ const threadId = fullyQualifiedId2(thread);
249
+ return /* @__PURE__ */ React3.createElement(CommentContainer, {
250
+ key: threadId,
251
+ thread,
252
+ current: currentId === threadId,
253
+ detached: detached.includes(threadId),
254
+ autoFocusTextbox: autoFocusCurrentTextbox && currentId === threadId,
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
+ });
269
+ }) : /* @__PURE__ */ React3.createElement("div", {
269
270
  role: "alert",
270
271
  className: mx2(descriptionText, "place-self-center border border-dashed border-neutral-400/50 rounded-lg text-center p-4 m-4")
271
272
  }, /* @__PURE__ */ React3.createElement("h2", {
@@ -282,8 +283,124 @@ var CommentsContainer = ({ threads, detached = [], currentId, autoFocusCurrentTe
282
283
  };
283
284
 
284
285
  // packages/plugins/plugin-thread/src/components/index.ts
285
- var ThreadMain = React4.lazy(() => import("./ThreadMain-ZDCRC6RG.mjs"));
286
- var ThreadArticle = React4.lazy(() => import("./ThreadArticle-O64ZECMF.mjs"));
286
+ var ThreadMain = React4.lazy(() => import("./ThreadMain-DU6LBSN3.mjs"));
287
+ var ThreadArticle = React4.lazy(() => import("./ThreadArticle-6L6BGE4Z.mjs"));
288
+
289
+ // packages/plugins/plugin-thread/src/components/ThreadComplementary.tsx
290
+ import React5, { useEffect as useEffect3, useMemo as useMemo2 } from "react";
291
+ import { LayoutAction, useIntentDispatcher, useResolvePlugins } from "@dxos/app-framework";
292
+ import { fullyQualifiedId as fullyQualifiedId3 } from "@dxos/react-client/echo";
293
+ import { ScrollArea } from "@dxos/react-ui";
294
+ import { createAttendableAttributes, useAttentionContext } from "@dxos/react-ui-attention";
295
+ import { nonNullable as nonNullable2 } from "@dxos/util";
296
+ var providesThreadsConfig = (plugin) => "thread" in plugin.provides ? plugin : void 0;
297
+ var ThreadComplementary = ({ role, subject, stagedThreads, current, focus, showResolvedThreads }) => {
298
+ const dispatch = useIntentDispatcher();
299
+ const threadsIntegrators = useResolvePlugins(providesThreadsConfig);
300
+ const threadProvides = useMemo2(() => threadsIntegrators.map((p) => p.provides.thread), [
301
+ threadsIntegrators
302
+ ]);
303
+ const createSort = useMemo2(() => threadProvides.find((p) => p.predicate(subject))?.createSort, [
304
+ threadProvides,
305
+ subject
306
+ ]);
307
+ const sort = useMemo2(() => createSort?.(subject), [
308
+ createSort,
309
+ subject
310
+ ]);
311
+ const threads = useMemo2(() => {
312
+ return subject.threads.concat(stagedThreads ?? []).filter(nonNullable2);
313
+ }, [
314
+ JSON.stringify(subject.threads),
315
+ JSON.stringify(stagedThreads)
316
+ ]);
317
+ const detachedIds = useMemo2(() => {
318
+ return threads.filter(({ anchor }) => !anchor).map((thread) => fullyQualifiedId3(thread));
319
+ }, [
320
+ threads
321
+ ]);
322
+ useEffect3(() => {
323
+ if (!sort) {
324
+ return;
325
+ }
326
+ threads.sort((a, b) => sort(a?.anchor, b?.anchor));
327
+ }, [
328
+ sort,
329
+ threads
330
+ ]);
331
+ const { attended } = useAttentionContext("Thread Complementary");
332
+ const qualifiedSubjectId = fullyQualifiedId3(subject);
333
+ const attendableAttrs = createAttendableAttributes(qualifiedSubjectId);
334
+ return /* @__PURE__ */ React5.createElement("div", {
335
+ role: "none",
336
+ className: "contents group/attention",
337
+ ...attendableAttrs
338
+ }, role === "complementary" && /* @__PURE__ */ React5.createElement(CommentsHeading, {
339
+ attendableId: qualifiedSubjectId
340
+ }), /* @__PURE__ */ React5.createElement(ScrollArea.Root, {
341
+ classNames: "row-span-2"
342
+ }, /* @__PURE__ */ React5.createElement(ScrollArea.Viewport, null, /* @__PURE__ */ React5.createElement(CommentsContainer, {
343
+ threads,
344
+ detached: detachedIds,
345
+ currentId: attended.has(qualifiedSubjectId) ? current : void 0,
346
+ autoFocusCurrentTextbox: focus,
347
+ showResolvedThreads,
348
+ onThreadAttend: (thread) => {
349
+ const threadId = fullyQualifiedId3(thread);
350
+ if (current !== threadId) {
351
+ current = threadId;
352
+ void dispatch?.([
353
+ {
354
+ action: LayoutAction.SCROLL_INTO_VIEW,
355
+ data: {
356
+ id: fullyQualifiedId3(subject),
357
+ thread: threadId,
358
+ cursor: thread.anchor
359
+ }
360
+ }
361
+ ]);
362
+ }
363
+ },
364
+ onThreadDelete: (thread) => {
365
+ return dispatch({
366
+ plugin: THREAD_PLUGIN,
367
+ action: ThreadAction.DELETE,
368
+ data: {
369
+ subject,
370
+ thread
371
+ }
372
+ });
373
+ },
374
+ onMessageDelete: (thread, messageId) => dispatch({
375
+ plugin: THREAD_PLUGIN,
376
+ action: ThreadAction.DELETE_MESSAGE,
377
+ data: {
378
+ subject,
379
+ thread,
380
+ messageId
381
+ }
382
+ }),
383
+ onThreadToggleResolved: (thread) => dispatch({
384
+ plugin: THREAD_PLUGIN,
385
+ action: ThreadAction.TOGGLE_RESOLVED,
386
+ data: {
387
+ thread
388
+ }
389
+ }),
390
+ onComment: (thread) => {
391
+ void dispatch({
392
+ action: ThreadAction.ON_MESSAGE_ADD,
393
+ data: {
394
+ thread,
395
+ subject
396
+ }
397
+ });
398
+ }
399
+ }), /* @__PURE__ */ React5.createElement("div", {
400
+ role: "none",
401
+ className: "bs-10"
402
+ }), /* @__PURE__ */ React5.createElement(ScrollArea.Scrollbar, null, /* @__PURE__ */ React5.createElement(ScrollArea.Thumb, null)))));
403
+ };
287
404
 
288
405
  // packages/plugins/plugin-thread/src/translations.ts
289
406
  var translations_default = [
@@ -322,10 +439,10 @@ var translations_default = [
322
439
  ];
323
440
 
324
441
  // packages/plugins/plugin-thread/src/ThreadPlugin.tsx
442
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/plugins/plugin-thread/src/ThreadPlugin.tsx";
325
443
  var initialViewState = {
326
444
  showResolvedThreads: false
327
445
  };
328
- var providesThreadsConfig = (plugin) => "thread" in plugin.provides ? plugin : void 0;
329
446
  var ThreadPlugin = () => {
330
447
  const settings = new LocalStorageStore(THREAD_PLUGIN);
331
448
  const state = create2({
@@ -343,7 +460,6 @@ var ThreadPlugin = () => {
343
460
  let attentionPlugin;
344
461
  let navigationPlugin;
345
462
  let intentPlugin;
346
- let dispatch;
347
463
  const unsubscribeCallbacks = [];
348
464
  return {
349
465
  meta: meta_default,
@@ -357,7 +473,6 @@ var ThreadPlugin = () => {
357
473
  attentionPlugin = resolvePlugin(plugins, parseAttentionPlugin);
358
474
  navigationPlugin = resolvePlugin(plugins, parseNavigationPlugin);
359
475
  intentPlugin = resolvePlugin(plugins, parseIntentPlugin);
360
- dispatch = intentPlugin?.provides.intent.dispatch;
361
476
  const graphPlugin = resolvePlugin(plugins, parseGraphPlugin);
362
477
  const client = resolvePlugin(plugins, parseClientPlugin)?.provides.client;
363
478
  if (!client) {
@@ -370,7 +485,10 @@ var ThreadPlugin = () => {
370
485
  if (!attention?.attended) {
371
486
  return;
372
487
  }
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);
488
+ const firstAttendedNodeWithComments = Array.from(attention.attended).map((id) => graphPlugin?.provides.graph.findNode(id)).find((node) => {
489
+ const data = node?.data;
490
+ return Array.isArray(data?.threads) && data.threads.length > 0;
491
+ });
374
492
  if (firstAttendedNodeWithComments) {
375
493
  void intentPlugin?.provides.intent.dispatch({
376
494
  action: NavigationAction.OPEN,
@@ -399,7 +517,7 @@ var ThreadPlugin = () => {
399
517
  ns: THREAD_PLUGIN
400
518
  }
401
519
  ],
402
- icon: (props) => /* @__PURE__ */ React5.createElement(Chat, props),
520
+ icon: (props) => /* @__PURE__ */ React6.createElement(Chat, props),
403
521
  iconSymbol: "ph--chat--regular",
404
522
  // TODO(wittjosiah): Move out of metadata.
405
523
  loadReferences: (channel) => loadObjectReferences(channel, (channel2) => channel2.threads)
@@ -447,9 +565,9 @@ var ThreadPlugin = () => {
447
565
  graph: {
448
566
  builder: (plugins) => {
449
567
  const client = resolvePlugin(plugins, parseClientPlugin)?.provides.client;
450
- const dispatch2 = resolvePlugin(plugins, parseIntentPlugin)?.provides.intent.dispatch;
568
+ const dispatch = resolvePlugin(plugins, parseIntentPlugin)?.provides.intent.dispatch;
451
569
  const metadataResolver = resolvePlugin(plugins, parseMetadataResolverPlugin)?.provides.metadata.resolver;
452
- if (!client || !dispatch2 || !metadataResolver) {
570
+ if (!client || !dispatch || !metadataResolver) {
453
571
  return [];
454
572
  }
455
573
  return [
@@ -495,7 +613,7 @@ var ThreadPlugin = () => {
495
613
  const toggle = () => {
496
614
  const newToggleState = !viewState.showResolvedThreads;
497
615
  viewState.showResolvedThreads = newToggleState;
498
- void dispatch2({
616
+ void dispatch({
499
617
  action: ObservabilityAction.SEND_EVENT,
500
618
  data: {
501
619
  name: "threads.toggle-show-resolved",
@@ -520,7 +638,8 @@ var ThreadPlugin = () => {
520
638
  ],
521
639
  menuItemType: "toggle",
522
640
  isChecked: viewState.showResolvedThreads,
523
- testId: "threadPlugin.toggleShowResolved"
641
+ testId: "threadPlugin.toggleShowResolved",
642
+ iconSymbol: viewState.showResolvedThreads ? "ph--eye-slash--regular" : "ph--eye--regular"
524
643
  }
525
644
  }
526
645
  ];
@@ -542,7 +661,7 @@ var ThreadPlugin = () => {
542
661
  {
543
662
  id: `${THREAD_PLUGIN}/create/${node.id}`,
544
663
  data: async () => {
545
- await dispatch2([
664
+ await dispatch([
546
665
  {
547
666
  plugin: THREAD_PLUGIN,
548
667
  action: ThreadAction.CREATE
@@ -565,7 +684,7 @@ var ThreadPlugin = () => {
565
684
  ns: THREAD_PLUGIN
566
685
  }
567
686
  ],
568
- icon: (props) => /* @__PURE__ */ React5.createElement(Chat, props),
687
+ icon: (props) => /* @__PURE__ */ React6.createElement(Chat, props),
569
688
  iconSymbol: "ph--chat--regular",
570
689
  testId: "threadPlugin.createObject"
571
690
  }
@@ -580,20 +699,18 @@ var ThreadPlugin = () => {
580
699
  component: ({ data, role }) => {
581
700
  switch (role) {
582
701
  case "main": {
583
- return data.active instanceof ChannelType && data.active.threads[0] ? /* @__PURE__ */ React5.createElement(ThreadMain, {
702
+ return data.active instanceof ChannelType && data.active.threads[0] ? /* @__PURE__ */ React6.createElement(ThreadMain, {
584
703
  thread: data.active.threads[0]
585
704
  }) : null;
586
705
  }
587
706
  case "settings": {
588
- return data.plugin === meta_default.id ? /* @__PURE__ */ React5.createElement(ThreadSettings, {
707
+ return data.plugin === meta_default.id ? /* @__PURE__ */ React6.createElement(ThreadSettings, {
589
708
  settings: settings.values
590
709
  }) : null;
591
710
  }
592
711
  case "article":
593
712
  case "complementary": {
594
713
  const location = navigationPlugin?.provides.location;
595
- const threadsIntegrators = useResolvePlugins(providesThreadsConfig);
596
- const threadProvides = threadsIntegrators.map((p) => p.provides.thread);
597
714
  if (data.object instanceof ChannelType && data.object.threads[0]) {
598
715
  const channel = data.object;
599
716
  if (isLayoutParts(location?.active) && location.active.main) {
@@ -602,101 +719,33 @@ var ThreadPlugin = () => {
602
719
  if (currentPosition > 0) {
603
720
  const objectToTheLeft = layoutEntries[currentPosition - 1];
604
721
  const context = getSpace2(data.object)?.db.getObjectById(objectToTheLeft.id);
605
- return /* @__PURE__ */ React5.createElement(ThreadArticle, {
722
+ return /* @__PURE__ */ React6.createElement(ThreadArticle, {
606
723
  thread: data.object.threads[0],
607
724
  context
608
725
  });
609
726
  }
610
727
  }
611
- return /* @__PURE__ */ React5.createElement(ThreadArticle, {
728
+ return /* @__PURE__ */ React6.createElement(ThreadArticle, {
612
729
  thread: data.object.threads[0]
613
730
  });
614
731
  }
615
732
  if (data.subject instanceof ThreadType) {
616
- return /* @__PURE__ */ React5.createElement(React5.Fragment, null, /* @__PURE__ */ React5.createElement(ChatHeading, {
733
+ return /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(ChatHeading, {
617
734
  attendableId: data.subject.id
618
- }), /* @__PURE__ */ React5.createElement(ChatContainer, {
735
+ }), /* @__PURE__ */ React6.createElement(ChatContainer, {
619
736
  thread: data.subject
620
737
  }));
621
738
  }
622
739
  if (data.subject && typeof data.subject === "object" && "threads" in data.subject && Array.isArray(data.subject.threads)) {
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)))));
740
+ const { showResolvedThreads } = getViewState(fullyQualifiedId4(data.subject));
741
+ return /* @__PURE__ */ React6.createElement(ThreadComplementary, {
742
+ role,
743
+ subject: data.subject,
744
+ stagedThreads: state.staging[fullyQualifiedId4(data.subject)],
745
+ current: state.current,
746
+ focus: true,
747
+ showResolvedThreads
748
+ });
700
749
  }
701
750
  }
702
751
  }
@@ -709,7 +758,20 @@ var ThreadPlugin = () => {
709
758
  case ThreadAction.CREATE: {
710
759
  if (intent.data && intent.data.cursor !== void 0) {
711
760
  const { cursor, name, subject } = intent.data;
712
- const subjectId = fullyQualifiedId(subject);
761
+ if (subject?.threads === void 0) {
762
+ try {
763
+ subject.threads = [];
764
+ } catch (e) {
765
+ log.error("Subject does not support threads array", subject?.typename, {
766
+ F: __dxlog_file,
767
+ L: 369,
768
+ S: void 0,
769
+ C: (f, a) => f(...a)
770
+ });
771
+ return;
772
+ }
773
+ }
774
+ const subjectId = fullyQualifiedId4(subject);
713
775
  const thread = create2(ThreadType, {
714
776
  name,
715
777
  anchor: cursor,
@@ -739,12 +801,12 @@ var ThreadPlugin = () => {
739
801
  {
740
802
  action: ThreadAction.SELECT,
741
803
  data: {
742
- current: thread.id,
804
+ current: fullyQualifiedId4(thread),
743
805
  focus: true
744
806
  }
745
807
  },
746
808
  {
747
- action: LayoutAction.SET_LAYOUT,
809
+ action: LayoutAction2.SET_LAYOUT,
748
810
  data: {
749
811
  element: "complementary",
750
812
  subject: subjectId,
@@ -804,16 +866,18 @@ var ThreadPlugin = () => {
804
866
  }
805
867
  case ThreadAction.DELETE: {
806
868
  const { subject, thread } = intent.data ?? {};
807
- if (!(subject instanceof DocumentType) || !(thread instanceof ThreadType)) {
869
+ if (!(thread instanceof ThreadType) || !(subject && typeof subject === "object" && "threads" in subject)) {
808
870
  return;
809
871
  }
810
- const subjectId = fullyQualifiedId(subject);
872
+ const subjectId = fullyQualifiedId4(subject);
811
873
  const stagingArea = state.staging[subjectId];
812
874
  if (stagingArea) {
813
875
  const index = stagingArea.findIndex((t) => t.id === thread.id);
814
876
  if (index !== -1) {
815
877
  stagingArea.splice(index, 1);
816
- return;
878
+ return {
879
+ data: true
880
+ };
817
881
  }
818
882
  }
819
883
  const space = getSpace2(thread);
@@ -874,10 +938,10 @@ var ThreadPlugin = () => {
874
938
  }
875
939
  case ThreadAction.ON_MESSAGE_ADD: {
876
940
  const { thread, subject } = intent.data ?? {};
877
- if (!(thread instanceof ThreadType) || !(subject && typeof subject === "object" && "threads" in subject)) {
941
+ if (!(thread instanceof ThreadType) || !(subject && typeof subject === "object" && "threads" in subject && Array.isArray(subject.threads))) {
878
942
  return;
879
943
  }
880
- const subjectId = fullyQualifiedId(subject);
944
+ const subjectId = fullyQualifiedId4(subject);
881
945
  const space = getSpace2(subject);
882
946
  const intents = [];
883
947
  const analyticsProperties = {
@@ -918,7 +982,7 @@ var ThreadPlugin = () => {
918
982
  case ThreadAction.DELETE_MESSAGE: {
919
983
  const { subject, thread, messageId } = intent.data ?? {};
920
984
  const space = getSpace2(subject);
921
- if (!(subject instanceof DocumentType) || !(thread instanceof ThreadType) || !space) {
985
+ if (!(thread instanceof ThreadType) || !(subject && typeof subject === "object" && "threads" in subject)) {
922
986
  return;
923
987
  }
924
988
  if (!intent.undo) {
@@ -960,7 +1024,7 @@ var ThreadPlugin = () => {
960
1024
  name: "threads.message.delete",
961
1025
  properties: {
962
1026
  threadId: thread.id,
963
- spaceId: space.id
1027
+ spaceId: space?.id
964
1028
  }
965
1029
  }
966
1030
  }
@@ -984,7 +1048,7 @@ var ThreadPlugin = () => {
984
1048
  name: "threads.message.undo-delete",
985
1049
  properties: {
986
1050
  threadId: thread.id,
987
- spaceId: space.id
1051
+ spaceId: space?.id
988
1052
  }
989
1053
  }
990
1054
  }
@@ -1006,8 +1070,8 @@ var ThreadPlugin = () => {
1006
1070
  ];
1007
1071
  }
1008
1072
  const threads = computed(() => [
1009
- ...doc.threads.filter(nonNullable2),
1010
- ...state.staging[fullyQualifiedId(doc)] ?? []
1073
+ ...doc.threads.filter(nonNullable3),
1074
+ ...state.staging[fullyQualifiedId4(doc)] ?? []
1011
1075
  ].filter((thread) => !(thread?.status === "resolved")));
1012
1076
  return [
1013
1077
  listener2({
@@ -1026,7 +1090,7 @@ var ThreadPlugin = () => {
1026
1090
  }
1027
1091
  }),
1028
1092
  createExternalCommentSync(doc.id, (sink) => effect(() => sink()), () => threads.value.filter((thread) => thread?.anchor).map((thread) => ({
1029
- id: thread.id,
1093
+ id: fullyQualifiedId4(thread),
1030
1094
  cursor: thread.anchor
1031
1095
  }))),
1032
1096
  comments({
@@ -1046,9 +1110,9 @@ var ThreadPlugin = () => {
1046
1110
  });
1047
1111
  },
1048
1112
  onDelete: ({ id }) => {
1049
- const stagingArea = state.staging[fullyQualifiedId(doc)];
1113
+ const stagingArea = state.staging[fullyQualifiedId4(doc)];
1050
1114
  if (stagingArea) {
1051
- const index = stagingArea.findIndex((thread2) => thread2.id === id);
1115
+ const index = stagingArea.findIndex((thread2) => fullyQualifiedId4(thread2) === id);
1052
1116
  if (index !== -1) {
1053
1117
  stagingArea.splice(index, 1);
1054
1118
  }
@@ -1059,7 +1123,7 @@ var ThreadPlugin = () => {
1059
1123
  }
1060
1124
  },
1061
1125
  onUpdate: ({ id, cursor }) => {
1062
- const thread = state.staging[fullyQualifiedId(doc)]?.find((thread2) => thread2.id === id) ?? doc.threads.find((thread2) => thread2?.id === id);
1126
+ const thread = state.staging[fullyQualifiedId4(doc)]?.find((thread2) => fullyQualifiedId4(thread2) === id) ?? doc.threads.find((thread2) => thread2?.id === id);
1063
1127
  if (thread instanceof ThreadType && thread.anchor) {
1064
1128
  const [start, end] = thread.anchor.split(":");
1065
1129
  thread.name = doc.content && getTextInRange(createDocAccessor(doc.content, [
@@ -1069,9 +1133,9 @@ var ThreadPlugin = () => {
1069
1133
  }
1070
1134
  },
1071
1135
  onSelect: ({ selection: { current, closest } }) => {
1072
- const dispatch2 = intentPlugin?.provides.intent.dispatch;
1073
- if (dispatch2) {
1074
- void dispatch2([
1136
+ const dispatch = intentPlugin?.provides.intent.dispatch;
1137
+ if (dispatch) {
1138
+ void dispatch([
1075
1139
  {
1076
1140
  action: ThreadAction.SELECT,
1077
1141
  data: {