@dxos/plugin-thread 0.7.4 → 0.7.5-labs.a279d8c

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 (197) hide show
  1. package/dist/lib/browser/ThreadContainer-4VLBSBI7.mjs +19 -0
  2. package/dist/lib/browser/ThreadContainer-4VLBSBI7.mjs.map +7 -0
  3. package/dist/lib/browser/app-graph-builder-Q7A2ZRUA.mjs +121 -0
  4. package/dist/lib/browser/app-graph-builder-Q7A2ZRUA.mjs.map +7 -0
  5. package/dist/lib/browser/chunk-2B3EXYZ7.mjs +18 -0
  6. package/dist/lib/browser/chunk-2B3EXYZ7.mjs.map +7 -0
  7. package/dist/lib/browser/{chunk-ENERBDYI.mjs → chunk-636QDHE3.mjs} +3 -3
  8. package/dist/lib/browser/chunk-636QDHE3.mjs.map +7 -0
  9. package/dist/lib/browser/chunk-BNEWNQBO.mjs +71 -0
  10. package/dist/lib/browser/chunk-BNEWNQBO.mjs.map +7 -0
  11. package/dist/lib/browser/{chunk-52HWDLBR.mjs → chunk-GQONSZ3J.mjs} +31 -117
  12. package/dist/lib/browser/chunk-GQONSZ3J.mjs.map +7 -0
  13. package/dist/lib/browser/chunk-NAO3LZMZ.mjs +16 -0
  14. package/dist/lib/browser/chunk-NAO3LZMZ.mjs.map +7 -0
  15. package/dist/lib/browser/chunk-NO5AZLUZ.mjs +81 -0
  16. package/dist/lib/browser/chunk-NO5AZLUZ.mjs.map +7 -0
  17. package/dist/lib/browser/index.mjs +147 -1094
  18. package/dist/lib/browser/index.mjs.map +4 -4
  19. package/dist/lib/browser/intent-resolver-PIEZ3LKQ.mjs +275 -0
  20. package/dist/lib/browser/intent-resolver-PIEZ3LKQ.mjs.map +7 -0
  21. package/dist/lib/browser/markdown-2NBXKXCY.mjs +112 -0
  22. package/dist/lib/browser/markdown-2NBXKXCY.mjs.map +7 -0
  23. package/dist/lib/browser/meta.json +1 -1
  24. package/dist/lib/browser/react-surface-CHCZO4TI.mjs +412 -0
  25. package/dist/lib/browser/react-surface-CHCZO4TI.mjs.map +7 -0
  26. package/dist/lib/browser/settings-TKOPRXSU.mjs +22 -0
  27. package/dist/lib/browser/settings-TKOPRXSU.mjs.map +7 -0
  28. package/dist/lib/browser/state-GNFUURIC.mjs +33 -0
  29. package/dist/lib/browser/state-GNFUURIC.mjs.map +7 -0
  30. package/dist/lib/browser/types.mjs +6 -4
  31. package/dist/lib/node/{ThreadArticle-I7ADXDW3.cjs → ThreadContainer-VOYLV4UL.cjs} +14 -13
  32. package/dist/lib/node/ThreadContainer-VOYLV4UL.cjs.map +7 -0
  33. package/dist/lib/node/app-graph-builder-ZXW5KUDK.cjs +135 -0
  34. package/dist/lib/node/app-graph-builder-ZXW5KUDK.cjs.map +7 -0
  35. package/dist/lib/node/{chunk-YCDM2SZM.cjs → chunk-6PUGKCPR.cjs} +76 -165
  36. package/dist/lib/node/chunk-6PUGKCPR.cjs.map +7 -0
  37. package/dist/lib/node/chunk-AUVKOX5Q.cjs +101 -0
  38. package/dist/lib/node/chunk-AUVKOX5Q.cjs.map +7 -0
  39. package/dist/lib/node/chunk-AWSTZ2KN.cjs +93 -0
  40. package/dist/lib/node/chunk-AWSTZ2KN.cjs.map +7 -0
  41. package/dist/lib/node/{chunk-IC2NICNC.cjs → chunk-F735VMTN.cjs} +7 -7
  42. package/dist/lib/node/chunk-F735VMTN.cjs.map +7 -0
  43. package/dist/lib/node/{meta.cjs → chunk-FPWNZ6TB.cjs} +13 -10
  44. package/dist/lib/node/chunk-FPWNZ6TB.cjs.map +7 -0
  45. package/dist/lib/node/{ThreadMain-MRNJC3TI.cjs → chunk-ZRN7B26W.cjs} +26 -23
  46. package/dist/lib/node/chunk-ZRN7B26W.cjs.map +7 -0
  47. package/dist/lib/node/index.cjs +142 -1083
  48. package/dist/lib/node/index.cjs.map +4 -4
  49. package/dist/lib/node/intent-resolver-X5O3SVLF.cjs +287 -0
  50. package/dist/lib/node/intent-resolver-X5O3SVLF.cjs.map +7 -0
  51. package/dist/lib/node/markdown-FWRKMSKV.cjs +122 -0
  52. package/dist/lib/node/markdown-FWRKMSKV.cjs.map +7 -0
  53. package/dist/lib/node/meta.json +1 -1
  54. package/dist/lib/node/react-surface-LO7S2HPR.cjs +414 -0
  55. package/dist/lib/node/react-surface-LO7S2HPR.cjs.map +7 -0
  56. package/dist/lib/node/settings-TH4YSUVU.cjs +36 -0
  57. package/dist/lib/node/settings-TH4YSUVU.cjs.map +7 -0
  58. package/dist/lib/node/state-TQWEZ6B3.cjs +49 -0
  59. package/dist/lib/node/state-TQWEZ6B3.cjs.map +7 -0
  60. package/dist/lib/node/types.cjs +6 -4
  61. package/dist/lib/node/types.cjs.map +2 -2
  62. package/dist/lib/node-esm/ThreadContainer-7DZY2MWA.mjs +20 -0
  63. package/dist/lib/node-esm/ThreadContainer-7DZY2MWA.mjs.map +7 -0
  64. package/dist/lib/node-esm/app-graph-builder-ATS6HGE6.mjs +122 -0
  65. package/dist/lib/node-esm/app-graph-builder-ATS6HGE6.mjs.map +7 -0
  66. package/dist/lib/node-esm/chunk-B3CF35MY.mjs +82 -0
  67. package/dist/lib/node-esm/chunk-B3CF35MY.mjs.map +7 -0
  68. package/dist/lib/node-esm/{chunk-JG7MXH6O.mjs → chunk-DYFIKKDT.mjs} +31 -117
  69. package/dist/lib/node-esm/chunk-DYFIKKDT.mjs.map +7 -0
  70. package/dist/lib/node-esm/{chunk-7QRGG25F.mjs → chunk-FXUATCLW.mjs} +3 -3
  71. package/dist/lib/node-esm/chunk-FXUATCLW.mjs.map +7 -0
  72. package/dist/lib/node-esm/chunk-GS2OILYF.mjs +20 -0
  73. package/dist/lib/node-esm/chunk-GS2OILYF.mjs.map +7 -0
  74. package/dist/lib/node-esm/chunk-HLWJTUWZ.mjs +73 -0
  75. package/dist/lib/node-esm/chunk-HLWJTUWZ.mjs.map +7 -0
  76. package/dist/lib/node-esm/chunk-ZJITX3TO.mjs +17 -0
  77. package/dist/lib/node-esm/chunk-ZJITX3TO.mjs.map +7 -0
  78. package/dist/lib/node-esm/index.mjs +147 -1094
  79. package/dist/lib/node-esm/index.mjs.map +4 -4
  80. package/dist/lib/node-esm/intent-resolver-XJWT5X6T.mjs +276 -0
  81. package/dist/lib/node-esm/intent-resolver-XJWT5X6T.mjs.map +7 -0
  82. package/dist/lib/node-esm/markdown-6AQFDAW3.mjs +113 -0
  83. package/dist/lib/node-esm/markdown-6AQFDAW3.mjs.map +7 -0
  84. package/dist/lib/node-esm/meta.json +1 -1
  85. package/dist/lib/node-esm/react-surface-LAF3QIPB.mjs +413 -0
  86. package/dist/lib/node-esm/react-surface-LAF3QIPB.mjs.map +7 -0
  87. package/dist/lib/node-esm/settings-KEDRR7RM.mjs +23 -0
  88. package/dist/lib/node-esm/settings-KEDRR7RM.mjs.map +7 -0
  89. package/dist/lib/node-esm/state-7MLR27YG.mjs +34 -0
  90. package/dist/lib/node-esm/state-7MLR27YG.mjs.map +7 -0
  91. package/dist/lib/node-esm/types.mjs +6 -4
  92. package/dist/types/src/ThreadPlugin.d.ts +1 -3
  93. package/dist/types/src/ThreadPlugin.d.ts.map +1 -1
  94. package/dist/types/src/capabilities/app-graph-builder.d.ts +180 -0
  95. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
  96. package/dist/types/src/capabilities/capabilities.d.ts +15 -0
  97. package/dist/types/src/capabilities/capabilities.d.ts.map +1 -0
  98. package/dist/types/src/capabilities/index.d.ts +187 -0
  99. package/dist/types/src/capabilities/index.d.ts.map +1 -0
  100. package/dist/types/src/capabilities/intent-resolver.d.ts +4 -0
  101. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -0
  102. package/dist/types/src/capabilities/markdown.d.ts +4 -0
  103. package/dist/types/src/capabilities/markdown.d.ts.map +1 -0
  104. package/dist/types/src/capabilities/react-surface.d.ts +4 -0
  105. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
  106. package/dist/types/src/capabilities/settings.d.ts +4 -0
  107. package/dist/types/src/capabilities/settings.d.ts.map +1 -0
  108. package/dist/types/src/capabilities/state.d.ts +7 -0
  109. package/dist/types/src/capabilities/state.d.ts.map +1 -0
  110. package/dist/types/src/components/Chat.stories.d.ts.map +1 -1
  111. package/dist/types/src/components/ChatContainer.d.ts.map +1 -1
  112. package/dist/types/src/components/CommentContainer.d.ts +1 -1
  113. package/dist/types/src/components/CommentContainer.d.ts.map +1 -1
  114. package/dist/types/src/components/CommentsContainer.d.ts +2 -7
  115. package/dist/types/src/components/CommentsContainer.d.ts.map +1 -1
  116. package/dist/types/src/components/MessageContainer.d.ts.map +1 -1
  117. package/dist/types/src/components/ThreadComplementary.d.ts +1 -6
  118. package/dist/types/src/components/ThreadComplementary.d.ts.map +1 -1
  119. package/dist/types/src/components/ThreadContainer.d.ts +7 -0
  120. package/dist/types/src/components/ThreadContainer.d.ts.map +1 -0
  121. package/dist/types/src/components/index.d.ts +3 -15
  122. package/dist/types/src/components/index.d.ts.map +1 -1
  123. package/dist/types/src/components/testing.d.ts +50 -66
  124. package/dist/types/src/components/testing.d.ts.map +1 -1
  125. package/dist/types/src/components/types.d.ts +5 -5
  126. package/dist/types/src/components/types.d.ts.map +1 -1
  127. package/dist/types/src/extensions/threads.d.ts +2 -2
  128. package/dist/types/src/extensions/threads.d.ts.map +1 -1
  129. package/dist/types/src/hooks/analytics.d.ts.map +1 -1
  130. package/dist/types/src/index.d.ts +1 -3
  131. package/dist/types/src/index.d.ts.map +1 -1
  132. package/dist/types/src/meta.d.ts +1 -2
  133. package/dist/types/src/meta.d.ts.map +1 -1
  134. package/dist/types/src/translations.d.ts +3 -0
  135. package/dist/types/src/translations.d.ts.map +1 -1
  136. package/dist/types/src/types.d.ts +86 -22
  137. package/dist/types/src/types.d.ts.map +1 -1
  138. package/dist/types/tsconfig.tsbuildinfo +1 -0
  139. package/package.json +30 -38
  140. package/src/ThreadPlugin.tsx +109 -620
  141. package/src/capabilities/app-graph-builder.ts +120 -0
  142. package/src/capabilities/capabilities.ts +19 -0
  143. package/src/capabilities/index.ts +14 -0
  144. package/src/capabilities/intent-resolver.ts +223 -0
  145. package/src/capabilities/markdown.ts +18 -0
  146. package/src/capabilities/react-surface.tsx +61 -0
  147. package/src/capabilities/settings.ts +14 -0
  148. package/src/capabilities/state.ts +25 -0
  149. package/src/components/Chat.stories.tsx +26 -22
  150. package/src/components/ChatContainer.tsx +13 -11
  151. package/src/components/CommentContainer.tsx +21 -32
  152. package/src/components/CommentsContainer.tsx +1 -17
  153. package/src/components/MessageContainer.tsx +7 -5
  154. package/src/components/ThreadComplementary.tsx +88 -68
  155. package/src/components/ThreadContainer.tsx +22 -0
  156. package/src/components/index.ts +1 -2
  157. package/src/components/testing.ts +26 -22
  158. package/src/components/types.ts +5 -5
  159. package/src/extensions/threads.ts +16 -25
  160. package/src/hooks/analytics.ts +6 -10
  161. package/src/index.ts +1 -5
  162. package/src/meta.ts +1 -1
  163. package/src/translations.ts +1 -0
  164. package/src/types.ts +70 -38
  165. package/dist/lib/browser/ThreadArticle-6IXTL7CH.mjs +0 -18
  166. package/dist/lib/browser/ThreadArticle-6IXTL7CH.mjs.map +0 -7
  167. package/dist/lib/browser/ThreadMain-4IAS67KE.mjs +0 -26
  168. package/dist/lib/browser/ThreadMain-4IAS67KE.mjs.map +0 -7
  169. package/dist/lib/browser/chunk-52HWDLBR.mjs.map +0 -7
  170. package/dist/lib/browser/chunk-ENERBDYI.mjs.map +0 -7
  171. package/dist/lib/browser/chunk-XUHNZID5.mjs +0 -20
  172. package/dist/lib/browser/chunk-XUHNZID5.mjs.map +0 -7
  173. package/dist/lib/browser/meta.mjs +0 -11
  174. package/dist/lib/browser/meta.mjs.map +0 -7
  175. package/dist/lib/node/ThreadArticle-I7ADXDW3.cjs.map +0 -7
  176. package/dist/lib/node/ThreadMain-MRNJC3TI.cjs.map +0 -7
  177. package/dist/lib/node/chunk-IC2NICNC.cjs.map +0 -7
  178. package/dist/lib/node/chunk-XFO6D2LG.cjs +0 -39
  179. package/dist/lib/node/chunk-XFO6D2LG.cjs.map +0 -7
  180. package/dist/lib/node/chunk-YCDM2SZM.cjs.map +0 -7
  181. package/dist/lib/node/meta.cjs.map +0 -7
  182. package/dist/lib/node-esm/ThreadArticle-CJHYMF2W.mjs +0 -19
  183. package/dist/lib/node-esm/ThreadArticle-CJHYMF2W.mjs.map +0 -7
  184. package/dist/lib/node-esm/ThreadMain-VISGW4IF.mjs +0 -27
  185. package/dist/lib/node-esm/ThreadMain-VISGW4IF.mjs.map +0 -7
  186. package/dist/lib/node-esm/chunk-7QRGG25F.mjs.map +0 -7
  187. package/dist/lib/node-esm/chunk-I5MU54RT.mjs +0 -21
  188. package/dist/lib/node-esm/chunk-I5MU54RT.mjs.map +0 -7
  189. package/dist/lib/node-esm/chunk-JG7MXH6O.mjs.map +0 -7
  190. package/dist/lib/node-esm/meta.mjs +0 -12
  191. package/dist/lib/node-esm/meta.mjs.map +0 -7
  192. package/dist/types/src/components/ThreadArticle.d.ts +0 -5
  193. package/dist/types/src/components/ThreadArticle.d.ts.map +0 -1
  194. package/dist/types/src/components/ThreadMain.d.ts +0 -7
  195. package/dist/types/src/components/ThreadMain.d.ts.map +0 -1
  196. package/src/components/ThreadArticle.tsx +0 -18
  197. package/src/components/ThreadMain.tsx +0 -27
@@ -1,456 +1,35 @@
1
1
  import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
2
  import {
3
- ThreadAction
4
- } from "./chunk-I5MU54RT.mjs";
3
+ AppGraphBuilder,
4
+ IntentResolver,
5
+ Markdown,
6
+ ReactSurface,
7
+ ThreadSettings,
8
+ ThreadState
9
+ } from "./chunk-GS2OILYF.mjs";
10
+ import "./chunk-ZJITX3TO.mjs";
5
11
  import {
6
- ChatContainer,
7
- ChatHeading,
8
- MessageContainer,
9
- command,
10
- getMessageMetadata,
11
12
  useAnalyticsCallback,
12
13
  useOnEditAnalytics,
13
14
  useStatus
14
- } from "./chunk-JG7MXH6O.mjs";
15
+ } from "./chunk-HLWJTUWZ.mjs";
16
+ import {
17
+ ThreadAction
18
+ } from "./chunk-B3CF35MY.mjs";
15
19
  import {
16
20
  THREAD_ITEM,
17
21
  THREAD_PLUGIN,
18
- meta_default
19
- } from "./chunk-7QRGG25F.mjs";
22
+ meta
23
+ } from "./chunk-FXUATCLW.mjs";
20
24
 
21
25
  // packages/plugins/plugin-thread/src/ThreadPlugin.tsx
22
- import React5 from "react";
23
- import { isLayoutParts, LayoutAction as LayoutAction2, NavigationAction, parseIntentPlugin, parseMetadataResolverPlugin, parseNavigationPlugin, resolvePlugin } from "@dxos/app-framework";
24
- import { LocalStorageStore } from "@dxos/local-storage";
25
- import { log } from "@dxos/log";
26
- import { parseClientPlugin } from "@dxos/plugin-client";
27
- import { createExtension, isActionGroup, toSignal } from "@dxos/plugin-graph";
28
- import { ObservabilityAction } from "@dxos/plugin-observability/meta";
29
- import { memoizeQuery, SpaceAction } from "@dxos/plugin-space";
30
- import { ChannelType as ChannelType2, MessageType as MessageType2, ThreadType as ThreadType2 } from "@dxos/plugin-space/types";
31
- import { create as create2, fullyQualifiedId as fullyQualifiedId5, getSpace as getSpace3, getTypename, loadObjectReferences, parseId, SpaceState } from "@dxos/react-client/echo";
26
+ import { allOf, Capabilities, contributes, createIntent, defineModule, definePlugin, Events, oneOf } from "@dxos/app-framework";
27
+ import { ClientCapabilities, ClientEvents } from "@dxos/plugin-client";
28
+ import { DeckCapabilities } from "@dxos/plugin-deck";
29
+ import { ChannelType as ChannelType2, MessageType, ThreadType } from "@dxos/plugin-space/types";
30
+ import { RefArray } from "@dxos/react-client/echo";
32
31
  import { translations as threadTranslations } from "@dxos/react-ui-thread";
33
32
 
34
- // packages/plugins/plugin-thread/src/components/index.ts
35
- import { lazy } from "react";
36
-
37
- // packages/plugins/plugin-thread/src/components/CommentContainer.tsx
38
- import { CheckCircle, X } from "@phosphor-icons/react";
39
- import React, { useCallback, useMemo, useRef, useState } from "react";
40
- import { create } from "@dxos/live-object";
41
- import { MessageType } from "@dxos/plugin-space/types";
42
- import { fullyQualifiedId, getSpace, useMembers } from "@dxos/react-client/echo";
43
- import { useIdentity } from "@dxos/react-client/halo";
44
- import { Button, Tag, Tooltip, useThemeContext, useTranslation } from "@dxos/react-ui";
45
- import { createBasicExtensions, createThemeExtensions, listener } from "@dxos/react-ui-editor";
46
- import { getSize, hoverableControlItem, hoverableControls, hoverableFocusedWithinControls, mx } from "@dxos/react-ui-theme";
47
- import { MessageTextbox, Thread, ThreadFooter, ThreadHeading } from "@dxos/react-ui-thread";
48
- import { nonNullable } from "@dxos/util";
49
- var sizeClass = getSize(4);
50
- var commentControlClassNames = "!p-1 !min-bs-0 transition-opacity";
51
- var ToggleResolvedButton = ({ isResolved, onResolve }) => {
52
- const { t } = useTranslation(THREAD_PLUGIN);
53
- const label = t(isResolved ? "mark as unresolved label" : "mark as resolved label");
54
- return /* @__PURE__ */ React.createElement(Tooltip.Root, null, /* @__PURE__ */ React.createElement(Tooltip.Trigger, {
55
- asChild: true
56
- }, /* @__PURE__ */ React.createElement(Button, {
57
- variant: "ghost",
58
- "data-testid": "thread.toggle-resolved",
59
- onClick: onResolve,
60
- classNames: [
61
- commentControlClassNames,
62
- !isResolved && hoverableControlItem
63
- ]
64
- }, /* @__PURE__ */ React.createElement("span", {
65
- className: "sr-only"
66
- }, label), isResolved ? /* @__PURE__ */ React.createElement(CheckCircle, {
67
- className: sizeClass,
68
- weight: "fill"
69
- }) : /* @__PURE__ */ React.createElement(CheckCircle, {
70
- className: sizeClass
71
- }))), /* @__PURE__ */ React.createElement(Tooltip.Portal, null, /* @__PURE__ */ React.createElement(Tooltip.Content, {
72
- classNames: "z-[21]"
73
- }, label, /* @__PURE__ */ React.createElement(Tooltip.Arrow, null))));
74
- };
75
- var DeleteThreadButton = ({ onDelete }) => {
76
- const { t } = useTranslation(THREAD_PLUGIN);
77
- const label = t("delete thread label");
78
- return /* @__PURE__ */ React.createElement(Tooltip.Root, null, /* @__PURE__ */ React.createElement(Tooltip.Trigger, {
79
- asChild: true
80
- }, /* @__PURE__ */ React.createElement(Button, {
81
- variant: "ghost",
82
- "data-testid": "thread.delete",
83
- onClick: onDelete,
84
- classNames: [
85
- commentControlClassNames,
86
- hoverableControlItem
87
- ]
88
- }, /* @__PURE__ */ React.createElement("span", {
89
- className: "sr-only"
90
- }, label), /* @__PURE__ */ React.createElement(X, {
91
- className: sizeClass
92
- }))), /* @__PURE__ */ React.createElement(Tooltip.Portal, null, /* @__PURE__ */ React.createElement(Tooltip.Content, {
93
- classNames: "z-[21]"
94
- }, label, /* @__PURE__ */ React.createElement(Tooltip.Arrow, null))));
95
- };
96
- var CommentContainer = ({ thread, detached, context, current, onAttend, onThreadDelete, onMessageDelete, onResolve, onComment }) => {
97
- const identity = useIdentity();
98
- const space = getSpace(thread);
99
- const members = useMembers(space?.key);
100
- const activity = useStatus(space, fullyQualifiedId(thread));
101
- const { t } = useTranslation(THREAD_PLUGIN);
102
- const threadScrollRef = useRef(null);
103
- const { themeMode } = useThemeContext();
104
- const textboxMetadata = getMessageMetadata(fullyQualifiedId(thread), identity);
105
- const [_count, _setCount] = useState(0);
106
- const rerenderEditor = () => _setCount((count) => count + 1);
107
- const messageRef = useRef("");
108
- const extensions = useMemo(() => [
109
- createBasicExtensions({
110
- placeholder: t("message placeholder")
111
- }),
112
- createThemeExtensions({
113
- themeMode
114
- }),
115
- listener({
116
- onChange: (text) => messageRef.current = text
117
- }),
118
- command
119
- ], [
120
- _count
121
- ]);
122
- const scrollToEnd = (behavior) => setTimeout(() => threadScrollRef.current?.scrollIntoView({
123
- behavior,
124
- block: "end"
125
- }), 10);
126
- const handleCreate = useCallback(() => {
127
- if (!messageRef.current) {
128
- return false;
129
- }
130
- thread.messages.push(create(MessageType, {
131
- sender: {
132
- identityKey: identity.identityKey.toHex()
133
- },
134
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
135
- text: messageRef.current,
136
- context
137
- }));
138
- onComment?.(thread);
139
- messageRef.current = "";
140
- scrollToEnd("instant");
141
- rerenderEditor();
142
- return true;
143
- }, [
144
- thread,
145
- identity
146
- ]);
147
- return /* @__PURE__ */ React.createElement(Thread, {
148
- onClickCapture: onAttend,
149
- onFocusCapture: onAttend,
150
- current,
151
- id: fullyQualifiedId(thread)
152
- }, /* @__PURE__ */ React.createElement("div", {
153
- role: "none",
154
- className: mx("col-span-2 grid grid-cols-[var(--rail-size)_1fr_min-content]", hoverableControls, hoverableFocusedWithinControls)
155
- }, detached ? /* @__PURE__ */ React.createElement(Tooltip.Root, null, /* @__PURE__ */ React.createElement(Tooltip.Trigger, {
156
- asChild: true
157
- }, /* @__PURE__ */ React.createElement(ThreadHeading, {
158
- detached: true
159
- }, thread.name)), /* @__PURE__ */ React.createElement(Tooltip.Portal, null, /* @__PURE__ */ React.createElement(Tooltip.Content, {
160
- classNames: "z-[21]",
161
- side: "top"
162
- }, t("detached thread label"), /* @__PURE__ */ React.createElement(Tooltip.Arrow, null)))) : /* @__PURE__ */ React.createElement(ThreadHeading, null, thread.name), /* @__PURE__ */ React.createElement("div", {
163
- className: "flex flex-row items-center pli-1"
164
- }, thread.status === "staged" && /* @__PURE__ */ React.createElement(Tag, {
165
- palette: "neutral"
166
- }, t("draft button")), onResolve && !(thread?.status === "staged") && /* @__PURE__ */ React.createElement(ToggleResolvedButton, {
167
- isResolved: thread?.status === "resolved",
168
- onResolve
169
- }), onThreadDelete && /* @__PURE__ */ React.createElement(DeleteThreadButton, {
170
- onDelete: onThreadDelete
171
- }))), thread.messages.filter(nonNullable).map((message) => /* @__PURE__ */ React.createElement(MessageContainer, {
172
- key: message.id,
173
- message,
174
- members,
175
- onDelete: (id) => onMessageDelete?.(id)
176
- })), /* @__PURE__ */ React.createElement(MessageTextbox, {
177
- extensions,
178
- onSend: handleCreate,
179
- ...textboxMetadata
180
- }), /* @__PURE__ */ React.createElement(ThreadFooter, {
181
- activity
182
- }, t("activity message")), /* @__PURE__ */ React.createElement("div", {
183
- role: "none",
184
- className: "bs-px -mbs-px",
185
- ref: threadScrollRef
186
- }));
187
- };
188
-
189
- // packages/plugins/plugin-thread/src/components/CommentsContainer.tsx
190
- import { ChatText } from "@phosphor-icons/react";
191
- import React2, { useEffect } from "react";
192
- import { fullyQualifiedId as fullyQualifiedId2 } from "@dxos/react-client/echo";
193
- import { useTranslation as useTranslation2, Trans } from "@dxos/react-ui";
194
- import { descriptionText, mx as mx2 } from "@dxos/react-ui-theme";
195
- var CommentsContainer = ({ threads: threads2, detached = [], currentId, showResolvedThreads, onThreadAttend, onThreadDelete, onMessageDelete, onThreadToggleResolved, ...props }) => {
196
- const { t } = useTranslation2(THREAD_PLUGIN);
197
- const filteredThreads = showResolvedThreads ? threads2 : threads2.filter((thread) => !(thread?.status === "resolved"));
198
- useEffect(() => {
199
- if (currentId) {
200
- document.getElementById(currentId)?.scrollIntoView({
201
- behavior: "smooth",
202
- block: "end"
203
- });
204
- }
205
- }, [
206
- currentId
207
- ]);
208
- return /* @__PURE__ */ React2.createElement(React2.Fragment, null, filteredThreads.length > 0 ? filteredThreads.map((thread) => {
209
- const threadId = fullyQualifiedId2(thread);
210
- return /* @__PURE__ */ React2.createElement(CommentContainer, {
211
- key: threadId,
212
- thread,
213
- current: currentId === threadId,
214
- detached: detached.includes(threadId),
215
- ...onThreadAttend && {
216
- onAttend: () => onThreadAttend(thread)
217
- },
218
- ...onThreadDelete && {
219
- onThreadDelete: () => onThreadDelete(thread)
220
- },
221
- ...onMessageDelete && {
222
- onMessageDelete: (messageId) => onMessageDelete(thread, messageId)
223
- },
224
- ...onThreadToggleResolved && {
225
- onResolve: () => onThreadToggleResolved(thread)
226
- },
227
- ...props
228
- });
229
- }) : /* @__PURE__ */ React2.createElement("div", {
230
- role: "alert",
231
- className: mx2(descriptionText, "place-self-center border border-dashed border-unAccent rounded-lg text-center p-4 m-4")
232
- }, /* @__PURE__ */ React2.createElement("h2", {
233
- className: "mbe-2 font-medium text-baseText"
234
- }, t("no comments title")), /* @__PURE__ */ React2.createElement("p", null, /* @__PURE__ */ React2.createElement(Trans, {
235
- t,
236
- i18nKey: "no comments message",
237
- components: {
238
- commentIcon: /* @__PURE__ */ React2.createElement(ChatText, {
239
- className: "inline-block"
240
- })
241
- }
242
- }))));
243
- };
244
-
245
- // packages/plugins/plugin-thread/src/components/ThreadComplementary.tsx
246
- import React3, { useEffect as useEffect2, useMemo as useMemo2 } from "react";
247
- import { LayoutAction, useIntentDispatcher, useResolvePlugins } from "@dxos/app-framework";
248
- import { fullyQualifiedId as fullyQualifiedId3 } from "@dxos/react-client/echo";
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(CommentsContainer, {
289
- threads: threads2,
290
- detached: detachedIds,
291
- currentId: attended.includes(qualifiedSubjectId) ? current : void 0,
292
- showResolvedThreads,
293
- onThreadAttend: (thread) => {
294
- const threadId = fullyQualifiedId3(thread);
295
- if (current !== threadId) {
296
- current = threadId;
297
- void dispatch?.([
298
- {
299
- action: LayoutAction.SCROLL_INTO_VIEW,
300
- data: {
301
- id: fullyQualifiedId3(subject),
302
- thread: threadId,
303
- cursor: thread.anchor
304
- }
305
- }
306
- ]);
307
- }
308
- },
309
- onThreadDelete: (thread) => {
310
- return dispatch({
311
- plugin: THREAD_PLUGIN,
312
- action: ThreadAction.DELETE,
313
- data: {
314
- subject,
315
- thread
316
- }
317
- });
318
- },
319
- onMessageDelete: (thread, messageId) => dispatch({
320
- plugin: THREAD_PLUGIN,
321
- action: ThreadAction.DELETE_MESSAGE,
322
- data: {
323
- subject,
324
- thread,
325
- messageId
326
- }
327
- }),
328
- onThreadToggleResolved: (thread) => dispatch({
329
- plugin: THREAD_PLUGIN,
330
- action: ThreadAction.TOGGLE_RESOLVED,
331
- data: {
332
- thread
333
- }
334
- }),
335
- onComment: (thread) => {
336
- void dispatch({
337
- action: ThreadAction.ON_MESSAGE_ADD,
338
- data: {
339
- thread,
340
- subject
341
- }
342
- });
343
- }
344
- });
345
- };
346
-
347
- // packages/plugins/plugin-thread/src/components/ThreadSettings.tsx
348
- import React4 from "react";
349
- import { Input, useTranslation as useTranslation3 } from "@dxos/react-ui";
350
- import { DeprecatedFormInput } from "@dxos/react-ui-form";
351
- var ThreadSettings = ({ settings }) => {
352
- const { t } = useTranslation3(THREAD_PLUGIN);
353
- return /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(DeprecatedFormInput, {
354
- label: t("settings standalone label")
355
- }, /* @__PURE__ */ React4.createElement(Input.Switch, {
356
- checked: settings.standalone,
357
- onCheckedChange: (checked) => settings.standalone = !!checked
358
- })));
359
- };
360
-
361
- // packages/plugins/plugin-thread/src/components/index.ts
362
- var ThreadMain = lazy(() => import("./ThreadMain-VISGW4IF.mjs"));
363
- var ThreadArticle = lazy(() => import("./ThreadArticle-CJHYMF2W.mjs"));
364
-
365
- // packages/plugins/plugin-thread/src/extensions/threads.ts
366
- import { EditorView } from "@codemirror/view";
367
- import { computed, effect } from "@preact/signals-core";
368
- import { ThreadType } from "@dxos/plugin-space/types";
369
- import { getSpace as getSpace2, getTextInRange, createDocAccessor, fullyQualifiedId as fullyQualifiedId4 } from "@dxos/react-client/echo";
370
- import { comments, createExternalCommentSync } from "@dxos/react-ui-editor";
371
- import { nonNullable as nonNullable3 } from "@dxos/util";
372
- var getName = (doc, anchor) => {
373
- if (doc.content) {
374
- const [start, end] = anchor.split(":");
375
- return getTextInRange(createDocAccessor(doc.content, [
376
- "content"
377
- ]), start, end);
378
- }
379
- };
380
- var threads = (state, doc, dispatch) => {
381
- const space = doc && getSpace2(doc);
382
- if (!doc || !space || !dispatch) {
383
- return [
384
- comments()
385
- ];
386
- }
387
- const threads2 = computed(() => [
388
- ...doc.threads.filter(nonNullable3),
389
- ...state.drafts[fullyQualifiedId4(doc)] ?? []
390
- ].filter((thread) => !(thread?.status === "resolved")));
391
- return [
392
- EditorView.updateListener.of((update) => {
393
- if (update.docChanged) {
394
- doc.threads.forEach((thread) => {
395
- if (thread?.anchor) {
396
- const name = getName(doc, thread.anchor);
397
- if (name && name !== thread.name) {
398
- thread.name = name;
399
- }
400
- }
401
- });
402
- }
403
- }),
404
- createExternalCommentSync(fullyQualifiedId4(doc), (sink) => effect(() => sink()), () => threads2.value.filter((thread) => thread?.anchor).map((thread) => ({
405
- id: fullyQualifiedId4(thread),
406
- cursor: thread.anchor
407
- }))),
408
- comments({
409
- id: fullyQualifiedId4(doc),
410
- onCreate: ({ cursor }) => {
411
- const name = getName(doc, cursor);
412
- void dispatch({
413
- action: ThreadAction.CREATE,
414
- data: {
415
- cursor,
416
- name,
417
- subject: doc
418
- }
419
- });
420
- },
421
- onDelete: ({ id }) => {
422
- const draft = state.drafts[fullyQualifiedId4(doc)];
423
- if (draft) {
424
- const index = draft.findIndex((thread2) => fullyQualifiedId4(thread2) === id);
425
- if (index !== -1) {
426
- draft.splice(index, 1);
427
- }
428
- }
429
- const thread = doc.threads.find((thread2) => thread2?.id === id);
430
- if (thread) {
431
- thread.anchor = void 0;
432
- }
433
- },
434
- onUpdate: ({ id, cursor }) => {
435
- const thread = state.drafts[fullyQualifiedId4(doc)]?.find((thread2) => fullyQualifiedId4(thread2) === id) ?? doc.threads.find((thread2) => thread2?.id === id);
436
- if (thread instanceof ThreadType && thread.anchor) {
437
- thread.name = getName(doc, thread.anchor);
438
- thread.anchor = cursor;
439
- }
440
- },
441
- onSelect: ({ selection: { current, closest } }) => {
442
- void dispatch({
443
- action: ThreadAction.SELECT,
444
- data: {
445
- current: current ?? closest,
446
- skipOpen: true
447
- }
448
- });
449
- }
450
- })
451
- ];
452
- };
453
-
454
33
  // packages/plugins/plugin-thread/src/translations.ts
455
34
  import { ChannelType } from "@dxos/plugin-space/types";
456
35
  var translations_default = [
@@ -486,681 +65,155 @@ var translations_default = [
486
65
  "save message label": "Save",
487
66
  "edit message label": "Edit",
488
67
  "delete message label": "Delete message",
489
- "open comments panel label": "Show Comments"
68
+ "open comments panel label": "Show Comments",
69
+ "comments panel label": "Comments"
490
70
  }
491
71
  }
492
72
  }
493
73
  ];
494
74
 
495
75
  // packages/plugins/plugin-thread/src/ThreadPlugin.tsx
496
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/plugins/plugin-thread/src/ThreadPlugin.tsx";
497
- var initialViewState = {
498
- showResolvedThreads: false
499
- };
500
- var ThreadPlugin = () => {
501
- const settings = new LocalStorageStore(THREAD_PLUGIN);
502
- const state = create2({
503
- drafts: {}
504
- });
505
- const viewStore = create2({});
506
- const getViewState = (subjectId) => {
507
- if (!viewStore[subjectId]) {
508
- viewStore[subjectId] = {
509
- ...initialViewState
510
- };
511
- }
512
- return viewStore[subjectId];
513
- };
514
- let navigationPlugin;
515
- let intentPlugin;
516
- const unsubscribeCallbacks = [];
517
- return {
518
- meta: meta_default,
519
- initialize: async () => {
520
- settings.prop({
521
- key: "standalone",
522
- type: LocalStorageStore.bool({
523
- allowUndefined: true
524
- })
525
- });
526
- return {
527
- echo: {
528
- system: [
529
- ThreadType2,
530
- MessageType2
531
- ],
532
- // TODO(wittjosiah): Requires reload.
533
- ...settings.values.standalone ? {
534
- schema: [
535
- ChannelType2
536
- ]
537
- } : {}
538
- }
539
- };
540
- },
541
- ready: async (plugins) => {
542
- navigationPlugin = resolvePlugin(plugins, parseNavigationPlugin);
543
- intentPlugin = resolvePlugin(plugins, parseIntentPlugin);
544
- },
545
- unload: async () => {
546
- unsubscribeCallbacks.forEach((unsubscribe) => unsubscribe());
547
- },
548
- provides: {
549
- settings: settings.values,
550
- metadata: {
551
- records: {
552
- [ChannelType2.typename]: {
553
- createObject: ThreadAction.CREATE,
554
- placeholder: [
555
- "channel name placeholder",
556
- {
557
- ns: THREAD_PLUGIN
558
- }
559
- ],
560
- icon: "ph--chat--regular",
561
- // TODO(wittjosiah): Move out of metadata.
562
- loadReferences: (channel) => loadObjectReferences(channel, (channel2) => channel2.threads)
563
- },
564
- [ThreadType2.typename]: {
565
- // TODO(wittjosiah): Move out of metadata.
566
- loadReferences: (thread) => loadObjectReferences(thread, (thread2) => thread2.messages)
567
- },
568
- [MessageType2.typename]: {
569
- // TODO(wittjosiah): Move out of metadata.
570
- loadReferences: (message) => []
571
- },
572
- [THREAD_ITEM]: {
573
- parse: (item, type) => {
574
- switch (type) {
575
- case "node":
576
- return {
577
- id: item.id,
578
- label: item.title,
579
- data: item
580
- };
581
- case "object":
582
- return item;
583
- case "view-object":
584
- return {
585
- id: `${item.id}-view`,
586
- object: item
587
- };
588
- }
76
+ var ThreadPlugin = () => definePlugin(meta, [
77
+ defineModule({
78
+ id: `${meta.id}/module/settings`,
79
+ activatesOn: Events.SetupSettings,
80
+ activate: ThreadSettings
81
+ }),
82
+ defineModule({
83
+ id: `${meta.id}/module/state`,
84
+ activatesOn: Events.Startup,
85
+ activate: ThreadState
86
+ }),
87
+ defineModule({
88
+ id: `${meta.id}/module/translations`,
89
+ activatesOn: Events.SetupTranslations,
90
+ activate: () => contributes(Capabilities.Translations, [
91
+ ...translations_default,
92
+ ...threadTranslations
93
+ ])
94
+ }),
95
+ defineModule({
96
+ id: `${meta.id}/module/metadata`,
97
+ activatesOn: oneOf(Events.Startup, Events.SetupAppGraph),
98
+ activate: () => [
99
+ contributes(Capabilities.Metadata, {
100
+ id: ChannelType2.typename,
101
+ metadata: {
102
+ createObject: (props) => createIntent(ThreadAction.Create, props),
103
+ placeholder: [
104
+ "channel name placeholder",
105
+ {
106
+ ns: THREAD_PLUGIN
589
107
  }
590
- }
108
+ ],
109
+ icon: "ph--chat--regular",
110
+ // TODO(wittjosiah): Move out of metadata.
111
+ loadReferences: async (channel) => await RefArray.loadAll(channel.threads ?? [])
591
112
  }
592
- },
593
- translations: [
594
- ...translations_default,
595
- ...threadTranslations
596
- ],
597
- complementary: {
598
- panels: [
599
- {
600
- id: "comments",
601
- label: [
602
- "open comments panel label",
603
- {
604
- ns: THREAD_PLUGIN
605
- }
606
- ],
607
- icon: "ph--chat-text--regular"
608
- }
609
- ]
610
- },
611
- graph: {
612
- builder: (plugins) => {
613
- const client = resolvePlugin(plugins, parseClientPlugin)?.provides.client;
614
- const dispatch = resolvePlugin(plugins, parseIntentPlugin)?.provides.intent.dispatch;
615
- const metadataResolver = resolvePlugin(plugins, parseMetadataResolverPlugin)?.provides.metadata.resolver;
616
- if (!client || !dispatch || !metadataResolver) {
617
- return [];
618
- }
619
- const type = "orphan-comments-for-subject";
620
- const icon = "ph--chat-text--regular";
621
- return [
622
- createExtension({
623
- id: `${THREAD_PLUGIN}/comments-for-subject`,
624
- resolver: ({ id }) => {
625
- if (!id.endsWith("~comments")) {
626
- return;
627
- }
628
- const [subjectId] = id.split("~");
629
- const { spaceId, objectId } = parseId(subjectId);
630
- const spaces = toSignal((onChange) => client.spaces.subscribe(() => onChange()).unsubscribe, () => client.spaces.get());
631
- const space = spaces?.find((space2) => space2.id === spaceId && space2.state.get() === SpaceState.SPACE_READY);
632
- if (!objectId) {
633
- return {
634
- id,
635
- type,
636
- data: null,
637
- properties: {
638
- icon,
639
- label: [
640
- "unnamed object threads label",
641
- {
642
- ns: THREAD_PLUGIN
643
- }
644
- ],
645
- showResolvedThreads: false,
646
- object: null,
647
- space
648
- }
649
- };
650
- }
651
- const [object] = memoizeQuery(space, {
652
- id: objectId
653
- });
654
- if (!object || !subjectId) {
655
- return;
656
- }
657
- const meta = metadataResolver(getTypename(object) ?? "");
658
- const label = meta.label?.(object) || object.name || meta.placeholder || [
659
- "unnamed object threads label",
660
- {
661
- ns: THREAD_PLUGIN
662
- }
663
- ];
664
- const viewState = getViewState(subjectId);
665
- return {
666
- id,
667
- type,
668
- data: null,
669
- properties: {
670
- icon,
671
- label,
672
- showResolvedThreads: viewState.showResolvedThreads,
673
- object
674
- }
675
- };
676
- },
677
- actions: ({ node }) => {
678
- const dataId = node.id.split("~").at(0);
679
- if (!node.id.endsWith("~comments") || !dataId) {
680
- return;
681
- }
682
- const [spaceId, objectId] = dataId.split(":");
683
- const viewState = getViewState(dataId);
684
- const toggle = () => {
685
- const newToggleState = !viewState.showResolvedThreads;
686
- viewState.showResolvedThreads = newToggleState;
687
- void dispatch({
688
- action: ObservabilityAction.SEND_EVENT,
689
- data: {
690
- name: "threads.toggle-show-resolved",
691
- properties: {
692
- spaceId,
693
- threadId: objectId,
694
- showResolved: newToggleState
695
- }
696
- }
697
- });
698
- };
699
- return [
700
- {
701
- id: `${THREAD_PLUGIN}/toggle-show-resolved/${node.id}`,
702
- data: toggle,
703
- properties: {
704
- label: [
705
- "toggle show resolved",
706
- {
707
- ns: THREAD_PLUGIN
708
- }
709
- ],
710
- menuItemType: "toggle",
711
- isChecked: viewState.showResolvedThreads,
712
- testId: "threadPlugin.toggleShowResolved",
713
- icon: viewState.showResolvedThreads ? "ph--eye-slash--regular" : "ph--eye--regular"
714
- }
715
- }
716
- ];
717
- }
718
- }),
719
- createExtension({
720
- id: ThreadAction.CREATE,
721
- filter: (node) => !!settings.values.standalone && isActionGroup(node) && node.id.startsWith(SpaceAction.ADD_OBJECT),
722
- actions: ({ node }) => {
723
- const id = node.id.split("/").at(-1);
724
- const [spaceId, objectId] = id?.split(":") ?? [];
725
- const space = client.spaces.get().find((space2) => space2.id === spaceId);
726
- const object = objectId && space?.db.getObjectById(objectId);
727
- const target = objectId ? object : space;
728
- if (!target) {
729
- return;
730
- }
731
- return [
732
- {
733
- id: `${THREAD_PLUGIN}/create/${node.id}`,
734
- data: async () => {
735
- await dispatch([
736
- {
737
- plugin: THREAD_PLUGIN,
738
- action: ThreadAction.CREATE
739
- },
740
- {
741
- action: SpaceAction.ADD_OBJECT,
742
- data: {
743
- target
744
- }
745
- },
746
- {
747
- action: NavigationAction.OPEN
748
- }
749
- ]);
750
- },
751
- properties: {
752
- label: [
753
- "create channel label",
754
- {
755
- ns: THREAD_PLUGIN
756
- }
757
- ],
758
- icon: "ph--chat--regular",
759
- testId: "threadPlugin.createObject"
760
- }
761
- }
762
- ];
763
- }
764
- })
765
- ];
113
+ }),
114
+ contributes(Capabilities.Metadata, {
115
+ id: ThreadType.typename,
116
+ metadata: {
117
+ // TODO(wittjosiah): Move out of metadata.
118
+ loadReferences: async (thread) => await RefArray.loadAll(thread.messages ?? [])
766
119
  }
767
- },
768
- surface: {
769
- component: ({ data, role }) => {
770
- switch (role) {
771
- case "main": {
772
- return data.active instanceof ChannelType2 && data.active.threads[0] ? /* @__PURE__ */ React5.createElement(ThreadMain, {
773
- thread: data.active.threads[0]
774
- }) : null;
775
- }
776
- case "settings": {
777
- return data.plugin === meta_default.id ? /* @__PURE__ */ React5.createElement(ThreadSettings, {
778
- settings: settings.values
779
- }) : null;
780
- }
781
- case "article": {
782
- const location = navigationPlugin?.provides.location;
783
- if (data.object instanceof ChannelType2 && data.object.threads[0]) {
784
- const channel = data.object;
785
- if (isLayoutParts(location?.active) && location.active.main) {
786
- const layoutEntries = location.active.main;
787
- const currentPosition = layoutEntries.findIndex((entry) => channel.id === entry.id);
788
- if (currentPosition > 0) {
789
- const objectToTheLeft = layoutEntries[currentPosition - 1];
790
- const context = getSpace3(data.object)?.db.getObjectById(objectToTheLeft.id);
791
- return /* @__PURE__ */ React5.createElement(ThreadArticle, {
792
- thread: data.object.threads[0],
793
- context
794
- });
795
- }
796
- }
797
- return /* @__PURE__ */ React5.createElement(ThreadArticle, {
798
- thread: data.object.threads[0]
799
- });
800
- }
801
- if (data.subject instanceof ThreadType2) {
802
- return /* @__PURE__ */ React5.createElement(React5.Fragment, null, /* @__PURE__ */ React5.createElement(ChatHeading, {
803
- attendableId: data.subject.id
804
- }), /* @__PURE__ */ React5.createElement(ChatContainer, {
805
- thread: data.subject
806
- }));
807
- }
808
- break;
809
- }
810
- case "complementary--comments": {
811
- if (data.subject && typeof data.subject === "object" && "threads" in data.subject && Array.isArray(data.subject.threads) && !(data.subject instanceof ChannelType2)) {
812
- const { showResolvedThreads } = getViewState(fullyQualifiedId5(data.subject));
813
- return /* @__PURE__ */ React5.createElement(ThreadComplementary, {
814
- role,
815
- subject: data.subject,
816
- drafts: state.drafts[fullyQualifiedId5(data.subject)],
817
- current: state.current,
818
- showResolvedThreads
819
- });
820
- }
821
- break;
822
- }
823
- }
824
- return null;
120
+ }),
121
+ contributes(Capabilities.Metadata, {
122
+ id: MessageType.typename,
123
+ metadata: {
124
+ // TODO(wittjosiah): Move out of metadata.
125
+ loadReferences: (message) => []
825
126
  }
826
- },
827
- intent: {
828
- resolver: async (intent) => {
829
- switch (intent.action) {
830
- case ThreadAction.CREATE: {
831
- if (intent.data && intent.data.cursor !== void 0) {
832
- const { cursor, name, subject } = intent.data;
833
- if (subject?.threads === void 0) {
834
- try {
835
- subject.threads = [];
836
- } catch (err) {
837
- log.error("Subject does not support threads array", subject?.typename, {
838
- F: __dxlog_file,
839
- L: 371,
840
- S: void 0,
841
- C: (f, a) => f(...a)
842
- });
843
- return;
844
- }
845
- }
846
- const subjectId = fullyQualifiedId5(subject);
847
- const thread = create2(ThreadType2, {
848
- name,
849
- anchor: cursor,
850
- messages: [],
851
- status: "staged"
852
- });
853
- const draft = state.drafts[subjectId];
854
- if (draft) {
855
- draft.push(thread);
856
- } else {
857
- state.drafts[subjectId] = [
858
- thread
859
- ];
860
- }
127
+ }),
128
+ contributes(Capabilities.Metadata, {
129
+ id: THREAD_ITEM,
130
+ metadata: {
131
+ parse: (item, type) => {
132
+ switch (type) {
133
+ case "node":
861
134
  return {
862
- data: thread,
863
- intents: [
864
- [
865
- {
866
- action: ThreadAction.SELECT,
867
- data: {
868
- current: fullyQualifiedId5(thread)
869
- }
870
- }
871
- ],
872
- [
873
- {
874
- action: NavigationAction.OPEN,
875
- data: {
876
- activeParts: {
877
- complementary: "comments"
878
- }
879
- }
880
- }
881
- ],
882
- [
883
- {
884
- action: LayoutAction2.SET_LAYOUT,
885
- data: {
886
- element: "complementary",
887
- state: true
888
- }
889
- }
890
- ]
891
- ]
135
+ id: item.id,
136
+ label: item.title,
137
+ data: item
892
138
  };
893
- } else {
139
+ case "object":
140
+ return item;
141
+ case "view-object":
894
142
  return {
895
- data: create2(ChannelType2, {
896
- threads: [
897
- create2(ThreadType2, {
898
- messages: []
899
- })
900
- ]
901
- })
143
+ id: `${item.id}-view`,
144
+ object: item
902
145
  };
903
- }
904
- }
905
- case ThreadAction.SELECT: {
906
- state.current = intent.data?.current;
907
- return {
908
- data: true,
909
- intents: !intent.data?.skipOpen ? [
910
- [
911
- {
912
- action: NavigationAction.OPEN,
913
- data: {
914
- activeParts: {
915
- complementary: "comments"
916
- }
917
- }
918
- }
919
- ]
920
- ] : []
921
- };
922
- }
923
- case ThreadAction.TOGGLE_RESOLVED: {
924
- const { thread } = intent.data ?? {};
925
- if (!(thread instanceof ThreadType2)) {
926
- return;
927
- }
928
- if (thread.status === "active" || thread.status === void 0) {
929
- thread.status = "resolved";
930
- } else if (thread.status === "resolved") {
931
- thread.status = "active";
932
- }
933
- const space = getSpace3(thread);
934
- const spaceId = space?.id;
935
- return {
936
- data: true,
937
- intents: [
938
- [
939
- {
940
- action: ObservabilityAction.SEND_EVENT,
941
- data: {
942
- name: "threads.toggle-resolved",
943
- properties: {
944
- threadId: thread.id,
945
- spaceId
946
- }
947
- }
948
- }
949
- ]
950
- ]
951
- };
952
- }
953
- case ThreadAction.DELETE: {
954
- const { subject, thread } = intent.data ?? {};
955
- if (!(thread instanceof ThreadType2) || !(subject && typeof subject === "object" && "threads" in subject)) {
956
- return;
957
- }
958
- const subjectId = fullyQualifiedId5(subject);
959
- const draft = state.drafts[subjectId];
960
- if (draft) {
961
- const index = draft.findIndex((t) => t.id === thread.id);
962
- if (index !== -1) {
963
- draft.splice(index, 1);
964
- return {
965
- data: true
966
- };
967
- }
968
- }
969
- const space = getSpace3(thread);
970
- if (!space || !subject.threads) {
971
- return;
972
- }
973
- if (!intent.undo) {
974
- const index = subject.threads.findIndex((t) => t?.id === thread.id);
975
- const cursor = subject.threads[index]?.anchor;
976
- if (index !== -1) {
977
- subject.threads?.splice(index, 1);
978
- }
979
- space.db.remove(thread);
980
- return {
981
- undoable: {
982
- message: translations_default[0]["en-US"][THREAD_PLUGIN]["thread deleted label"],
983
- data: {
984
- cursor
985
- }
986
- },
987
- intents: [
988
- [
989
- {
990
- action: ObservabilityAction.SEND_EVENT,
991
- data: {
992
- name: "threads.delete",
993
- properties: {
994
- threadId: thread.id,
995
- spaceId: space.id
996
- }
997
- }
998
- }
999
- ]
1000
- ]
1001
- };
1002
- } else if (intent.undo) {
1003
- const savedThread = space.db.add(thread);
1004
- subject.threads.push(savedThread);
1005
- return {
1006
- data: true,
1007
- intents: [
1008
- [
1009
- {
1010
- action: ObservabilityAction.SEND_EVENT,
1011
- data: {
1012
- name: "threads.undo-delete",
1013
- properties: {
1014
- threadId: thread.id,
1015
- spaceId: space.id
1016
- }
1017
- }
1018
- }
1019
- ]
1020
- ]
1021
- };
1022
- }
1023
- break;
1024
- }
1025
- case ThreadAction.ON_MESSAGE_ADD: {
1026
- const { thread, subject } = intent.data ?? {};
1027
- if (!(thread instanceof ThreadType2) || !(subject && typeof subject === "object" && "threads" in subject && Array.isArray(subject.threads))) {
1028
- return;
1029
- }
1030
- const subjectId = fullyQualifiedId5(subject);
1031
- const space = getSpace3(subject);
1032
- const intents = [];
1033
- const analyticsProperties = {
1034
- threadId: thread.id,
1035
- spaceId: space?.id
1036
- };
1037
- if (state.drafts[subjectId]?.find((t) => t === thread)) {
1038
- thread.status = "active";
1039
- subject.threads ? subject.threads.push(thread) : subject.threads = [
1040
- thread
1041
- ];
1042
- state.drafts[subjectId] = state.drafts[subjectId]?.filter(({ id }) => id !== thread.id);
1043
- intents.push({
1044
- action: ObservabilityAction.SEND_EVENT,
1045
- data: {
1046
- name: "threads.thread-created",
1047
- properties: analyticsProperties
1048
- }
1049
- });
1050
- }
1051
- intents.push({
1052
- action: ObservabilityAction.SEND_EVENT,
1053
- data: {
1054
- name: "threads.message-added",
1055
- properties: {
1056
- ...analyticsProperties,
1057
- threadLength: thread.messages.length
1058
- }
1059
- }
1060
- });
1061
- return {
1062
- data: thread,
1063
- intents: [
1064
- intents
1065
- ]
1066
- };
1067
- }
1068
- case ThreadAction.DELETE_MESSAGE: {
1069
- const { subject, thread, messageId } = intent.data ?? {};
1070
- const space = getSpace3(subject);
1071
- if (!(thread instanceof ThreadType2) || !(subject && typeof subject === "object" && "threads" in subject)) {
1072
- return;
1073
- }
1074
- if (!intent.undo) {
1075
- const message = thread.messages.find((m) => m?.id === messageId);
1076
- const messageIndex = thread.messages.findIndex((m) => m?.id === messageId);
1077
- if (messageIndex === -1 || !message) {
1078
- return void 0;
1079
- }
1080
- if (messageIndex === 0 && thread.messages.length === 1) {
1081
- return {
1082
- intents: [
1083
- [
1084
- {
1085
- action: ThreadAction.DELETE,
1086
- data: {
1087
- subject,
1088
- thread
1089
- }
1090
- }
1091
- ]
1092
- ]
1093
- };
1094
- } else {
1095
- thread.messages.splice(messageIndex, 1);
1096
- }
1097
- return {
1098
- undoable: {
1099
- message: translations_default[0]["en-US"][THREAD_PLUGIN]["message deleted label"],
1100
- data: {
1101
- message,
1102
- messageIndex
1103
- }
1104
- },
1105
- intents: [
1106
- [
1107
- {
1108
- action: ObservabilityAction.SEND_EVENT,
1109
- data: {
1110
- name: "threads.message.delete",
1111
- properties: {
1112
- threadId: thread.id,
1113
- spaceId: space?.id
1114
- }
1115
- }
1116
- }
1117
- ]
1118
- ]
1119
- };
1120
- } else if (intent.undo) {
1121
- const message = intent.data?.message;
1122
- const messageIndex = intent.data?.messageIndex;
1123
- if (!(message instanceof MessageType2) || !(typeof messageIndex === "number")) {
1124
- return;
1125
- }
1126
- thread.messages.splice(messageIndex, 0, message);
1127
- return {
1128
- data: true,
1129
- intents: [
1130
- [
1131
- {
1132
- action: ObservabilityAction.SEND_EVENT,
1133
- data: {
1134
- name: "threads.message.undo-delete",
1135
- properties: {
1136
- threadId: thread.id,
1137
- spaceId: space?.id
1138
- }
1139
- }
1140
- }
1141
- ]
1142
- ]
1143
- };
1144
- }
1145
146
  }
1146
147
  }
1147
148
  }
1148
- },
1149
- markdown: {
1150
- extensions: ({ document: doc }) => {
1151
- return threads(state, doc, intentPlugin?.provides.intent.dispatch);
1152
- }
149
+ })
150
+ ]
151
+ }),
152
+ defineModule({
153
+ id: `${meta.id}/module/schema`,
154
+ activatesOn: ClientEvents.SetupClient,
155
+ activate: () => contributes(ClientCapabilities.SystemSchema, [
156
+ ThreadType,
157
+ MessageType
158
+ ])
159
+ }),
160
+ defineModule({
161
+ id: `${meta.id}/module/channel-schema`,
162
+ activatesOn: allOf(Events.SettingsReady, ClientEvents.ClientReady),
163
+ activate: (context) => {
164
+ const client = context.requestCapability(ClientCapabilities.Client);
165
+ const settings = context.requestCapability(Capabilities.SettingsStore).getStore(THREAD_PLUGIN).value;
166
+ if (settings.standalone) {
167
+ client.addTypes([
168
+ ChannelType2
169
+ ]);
170
+ return contributes(ClientCapabilities.Schema, [
171
+ ChannelType2
172
+ ]);
1153
173
  }
174
+ return [];
1154
175
  }
1155
- };
1156
- };
1157
-
1158
- // packages/plugins/plugin-thread/src/index.ts
1159
- var src_default = ThreadPlugin;
176
+ }),
177
+ defineModule({
178
+ id: `${meta.id}/module/complementary-panel`,
179
+ activatesOn: Events.Startup,
180
+ activate: () => contributes(DeckCapabilities.ComplementaryPanel, {
181
+ id: "comments",
182
+ label: [
183
+ "comments panel label",
184
+ {
185
+ ns: THREAD_PLUGIN
186
+ }
187
+ ],
188
+ icon: "ph--chat-text--regular"
189
+ })
190
+ }),
191
+ defineModule({
192
+ id: `${meta.id}/module/markdown`,
193
+ activatesOn: Events.Startup,
194
+ activate: Markdown
195
+ }),
196
+ defineModule({
197
+ id: `${meta.id}/module/react-surface`,
198
+ activatesOn: Events.Startup,
199
+ activate: ReactSurface
200
+ }),
201
+ defineModule({
202
+ id: `${meta.id}/module/intent-resolver`,
203
+ activatesOn: Events.SetupIntents,
204
+ activate: IntentResolver
205
+ }),
206
+ defineModule({
207
+ id: `${meta.id}/module/app-graph-builder`,
208
+ activatesOn: Events.SetupAppGraph,
209
+ activate: AppGraphBuilder
210
+ })
211
+ ]);
1160
212
  export {
1161
- ThreadAction,
213
+ THREAD_ITEM,
214
+ THREAD_PLUGIN,
1162
215
  ThreadPlugin,
1163
- src_default as default,
216
+ meta,
1164
217
  useAnalyticsCallback,
1165
218
  useOnEditAnalytics,
1166
219
  useStatus