@dxos/plugin-thread 0.7.5-main.9d26e3a → 0.7.5-main.b19bfc8

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 (186) hide show
  1. package/dist/lib/browser/ThreadContainer-6OP5AG2W.mjs +19 -0
  2. package/dist/lib/browser/ThreadContainer-6OP5AG2W.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-ENERBDYI.mjs → chunk-636QDHE3.mjs} +3 -3
  4. package/dist/lib/browser/chunk-636QDHE3.mjs.map +7 -0
  5. package/dist/lib/browser/chunk-BNEWNQBO.mjs +71 -0
  6. package/dist/lib/browser/chunk-BNEWNQBO.mjs.map +7 -0
  7. package/dist/lib/browser/chunk-MDOPJ2AL.mjs +15 -0
  8. package/dist/lib/browser/chunk-MDOPJ2AL.mjs.map +7 -0
  9. package/dist/lib/browser/chunk-NAO3LZMZ.mjs +16 -0
  10. package/dist/lib/browser/chunk-NAO3LZMZ.mjs.map +7 -0
  11. package/dist/lib/browser/{chunk-OD2IZKRP.mjs → chunk-UPKU23DA.mjs} +29 -105
  12. package/dist/lib/browser/chunk-UPKU23DA.mjs.map +7 -0
  13. package/dist/lib/browser/{chunk-6KTMQPL4.mjs → chunk-YK3ICB7G.mjs} +5 -3
  14. package/dist/lib/browser/chunk-YK3ICB7G.mjs.map +7 -0
  15. package/dist/lib/browser/index.mjs +147 -942
  16. package/dist/lib/browser/index.mjs.map +4 -4
  17. package/dist/lib/browser/intent-resolver-FAFQ54NP.mjs +287 -0
  18. package/dist/lib/browser/intent-resolver-FAFQ54NP.mjs.map +7 -0
  19. package/dist/lib/browser/markdown-RPYOUBVR.mjs +112 -0
  20. package/dist/lib/browser/markdown-RPYOUBVR.mjs.map +7 -0
  21. package/dist/lib/browser/meta.json +1 -1
  22. package/dist/lib/browser/react-surface-KXXLCZMW.mjs +407 -0
  23. package/dist/lib/browser/react-surface-KXXLCZMW.mjs.map +7 -0
  24. package/dist/lib/browser/settings-WQTE5AEZ.mjs +22 -0
  25. package/dist/lib/browser/settings-WQTE5AEZ.mjs.map +7 -0
  26. package/dist/lib/browser/state-GNFUURIC.mjs +33 -0
  27. package/dist/lib/browser/state-GNFUURIC.mjs.map +7 -0
  28. package/dist/lib/browser/types.mjs +6 -4
  29. package/dist/lib/node/{ThreadArticle-ZCNMFBAO.cjs → ThreadContainer-LTKKLPXX.cjs} +14 -13
  30. package/dist/lib/node/ThreadContainer-LTKKLPXX.cjs.map +7 -0
  31. package/dist/lib/node/chunk-AWSTZ2KN.cjs +93 -0
  32. package/dist/lib/node/chunk-AWSTZ2KN.cjs.map +7 -0
  33. package/dist/lib/node/{ThreadMain-5AYGCXXP.cjs → chunk-BT24JUE3.cjs} +21 -23
  34. package/dist/lib/node/chunk-BT24JUE3.cjs.map +7 -0
  35. package/dist/lib/node/{chunk-VW2P26MZ.cjs → chunk-CMEMMYDL.cjs} +11 -8
  36. package/dist/lib/node/chunk-CMEMMYDL.cjs.map +7 -0
  37. package/dist/lib/node/{chunk-IC2NICNC.cjs → chunk-F735VMTN.cjs} +7 -7
  38. package/dist/lib/node/chunk-F735VMTN.cjs.map +7 -0
  39. package/dist/lib/node/{meta.cjs → chunk-FPWNZ6TB.cjs} +13 -10
  40. package/dist/lib/node/chunk-FPWNZ6TB.cjs.map +7 -0
  41. package/dist/lib/node/{chunk-2CB5AVBL.cjs → chunk-RQR5Z23G.cjs} +74 -151
  42. package/dist/lib/node/chunk-RQR5Z23G.cjs.map +7 -0
  43. package/dist/lib/node/index.cjs +146 -935
  44. package/dist/lib/node/index.cjs.map +4 -4
  45. package/dist/lib/node/intent-resolver-DVBEXJ33.cjs +299 -0
  46. package/dist/lib/node/intent-resolver-DVBEXJ33.cjs.map +7 -0
  47. package/dist/lib/node/markdown-ELRGISXE.cjs +122 -0
  48. package/dist/lib/node/markdown-ELRGISXE.cjs.map +7 -0
  49. package/dist/lib/node/meta.json +1 -1
  50. package/dist/lib/node/react-surface-H5PDWLPO.cjs +409 -0
  51. package/dist/lib/node/react-surface-H5PDWLPO.cjs.map +7 -0
  52. package/dist/lib/node/settings-7VQYARM5.cjs +36 -0
  53. package/dist/lib/node/settings-7VQYARM5.cjs.map +7 -0
  54. package/dist/lib/node/state-TQWEZ6B3.cjs +49 -0
  55. package/dist/lib/node/state-TQWEZ6B3.cjs.map +7 -0
  56. package/dist/lib/node/types.cjs +6 -4
  57. package/dist/lib/node/types.cjs.map +2 -2
  58. package/dist/lib/node-esm/ThreadContainer-SV74JFRH.mjs +20 -0
  59. package/dist/lib/node-esm/ThreadContainer-SV74JFRH.mjs.map +7 -0
  60. package/dist/lib/node-esm/{chunk-RMYATBXM.mjs → chunk-33NDMQQQ.mjs} +5 -3
  61. package/dist/lib/node-esm/chunk-33NDMQQQ.mjs.map +7 -0
  62. package/dist/lib/node-esm/{chunk-AQ74G3GY.mjs → chunk-CISLDOH7.mjs} +29 -105
  63. package/dist/lib/node-esm/chunk-CISLDOH7.mjs.map +7 -0
  64. package/dist/lib/node-esm/{chunk-7QRGG25F.mjs → chunk-FXUATCLW.mjs} +3 -3
  65. package/dist/lib/node-esm/chunk-FXUATCLW.mjs.map +7 -0
  66. package/dist/lib/node-esm/chunk-HLWJTUWZ.mjs +73 -0
  67. package/dist/lib/node-esm/chunk-HLWJTUWZ.mjs.map +7 -0
  68. package/dist/lib/node-esm/chunk-UNLSWYA4.mjs +17 -0
  69. package/dist/lib/node-esm/chunk-UNLSWYA4.mjs.map +7 -0
  70. package/dist/lib/node-esm/chunk-ZJITX3TO.mjs +17 -0
  71. package/dist/lib/node-esm/chunk-ZJITX3TO.mjs.map +7 -0
  72. package/dist/lib/node-esm/index.mjs +147 -942
  73. package/dist/lib/node-esm/index.mjs.map +4 -4
  74. package/dist/lib/node-esm/intent-resolver-DHVLBNCC.mjs +288 -0
  75. package/dist/lib/node-esm/intent-resolver-DHVLBNCC.mjs.map +7 -0
  76. package/dist/lib/node-esm/markdown-23OB7EZG.mjs +113 -0
  77. package/dist/lib/node-esm/markdown-23OB7EZG.mjs.map +7 -0
  78. package/dist/lib/node-esm/meta.json +1 -1
  79. package/dist/lib/node-esm/react-surface-SNZ44ZXI.mjs +408 -0
  80. package/dist/lib/node-esm/react-surface-SNZ44ZXI.mjs.map +7 -0
  81. package/dist/lib/node-esm/settings-SGMM7UDT.mjs +23 -0
  82. package/dist/lib/node-esm/settings-SGMM7UDT.mjs.map +7 -0
  83. package/dist/lib/node-esm/state-7MLR27YG.mjs +34 -0
  84. package/dist/lib/node-esm/state-7MLR27YG.mjs.map +7 -0
  85. package/dist/lib/node-esm/types.mjs +6 -4
  86. package/dist/types/src/ThreadPlugin.d.ts +1 -3
  87. package/dist/types/src/ThreadPlugin.d.ts.map +1 -1
  88. package/dist/types/src/capabilities/capabilities.d.ts +15 -0
  89. package/dist/types/src/capabilities/capabilities.d.ts.map +1 -0
  90. package/dist/types/src/capabilities/index.d.ts +10 -0
  91. package/dist/types/src/capabilities/index.d.ts.map +1 -0
  92. package/dist/types/src/capabilities/intent-resolver.d.ts +4 -0
  93. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -0
  94. package/dist/types/src/capabilities/markdown.d.ts +4 -0
  95. package/dist/types/src/capabilities/markdown.d.ts.map +1 -0
  96. package/dist/types/src/capabilities/react-surface.d.ts +4 -0
  97. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
  98. package/dist/types/src/capabilities/settings.d.ts +4 -0
  99. package/dist/types/src/capabilities/settings.d.ts.map +1 -0
  100. package/dist/types/src/capabilities/state.d.ts +7 -0
  101. package/dist/types/src/capabilities/state.d.ts.map +1 -0
  102. package/dist/types/src/components/Chat.stories.d.ts.map +1 -1
  103. package/dist/types/src/components/ChatContainer.d.ts +2 -3
  104. package/dist/types/src/components/ChatContainer.d.ts.map +1 -1
  105. package/dist/types/src/components/CommentContainer.d.ts +1 -2
  106. package/dist/types/src/components/CommentContainer.d.ts.map +1 -1
  107. package/dist/types/src/components/CommentsContainer.d.ts +2 -8
  108. package/dist/types/src/components/CommentsContainer.d.ts.map +1 -1
  109. package/dist/types/src/components/MessageContainer.d.ts +1 -2
  110. package/dist/types/src/components/MessageContainer.d.ts.map +1 -1
  111. package/dist/types/src/components/ThreadComplementary.d.ts +2 -7
  112. package/dist/types/src/components/ThreadComplementary.d.ts.map +1 -1
  113. package/dist/types/src/components/ThreadContainer.d.ts +7 -0
  114. package/dist/types/src/components/ThreadContainer.d.ts.map +1 -0
  115. package/dist/types/src/components/ThreadSettings.d.ts +1 -2
  116. package/dist/types/src/components/ThreadSettings.d.ts.map +1 -1
  117. package/dist/types/src/components/command-extension.d.ts.map +1 -1
  118. package/dist/types/src/components/index.d.ts +3 -15
  119. package/dist/types/src/components/index.d.ts.map +1 -1
  120. package/dist/types/src/components/testing.d.ts +12 -12
  121. package/dist/types/src/components/testing.d.ts.map +1 -1
  122. package/dist/types/src/components/types.d.ts +5 -5
  123. package/dist/types/src/components/types.d.ts.map +1 -1
  124. package/dist/types/src/index.d.ts +1 -3
  125. package/dist/types/src/index.d.ts.map +1 -1
  126. package/dist/types/src/meta.d.ts +1 -2
  127. package/dist/types/src/meta.d.ts.map +1 -1
  128. package/dist/types/src/translations.d.ts +3 -3
  129. package/dist/types/src/types.d.ts +12 -18
  130. package/dist/types/src/types.d.ts.map +1 -1
  131. package/dist/types/tsconfig.tsbuildinfo +1 -1
  132. package/package.json +30 -38
  133. package/src/ThreadPlugin.tsx +105 -475
  134. package/src/capabilities/capabilities.ts +19 -0
  135. package/src/capabilities/index.ts +13 -0
  136. package/src/capabilities/intent-resolver.ts +239 -0
  137. package/src/capabilities/markdown.ts +18 -0
  138. package/src/capabilities/react-surface.tsx +61 -0
  139. package/src/capabilities/settings.ts +14 -0
  140. package/src/capabilities/state.ts +25 -0
  141. package/src/components/Chat.stories.tsx +22 -24
  142. package/src/components/ChatContainer.tsx +2 -2
  143. package/src/components/CommentContainer.tsx +18 -32
  144. package/src/components/Comments.stories.tsx +1 -1
  145. package/src/components/CommentsContainer.tsx +1 -17
  146. package/src/components/MessageContainer.tsx +6 -19
  147. package/src/components/ThreadComplementary.tsx +87 -50
  148. package/src/components/ThreadContainer.tsx +22 -0
  149. package/src/components/ThreadSettings.tsx +5 -11
  150. package/src/components/command-extension.ts +2 -5
  151. package/src/components/index.ts +1 -2
  152. package/src/components/types.ts +5 -5
  153. package/src/index.ts +1 -5
  154. package/src/meta.ts +1 -1
  155. package/src/translations.ts +1 -1
  156. package/src/types.ts +6 -29
  157. package/dist/lib/browser/ThreadArticle-EWLTNU6Z.mjs +0 -18
  158. package/dist/lib/browser/ThreadArticle-EWLTNU6Z.mjs.map +0 -7
  159. package/dist/lib/browser/ThreadMain-ABEDFWHC.mjs +0 -26
  160. package/dist/lib/browser/ThreadMain-ABEDFWHC.mjs.map +0 -7
  161. package/dist/lib/browser/chunk-6KTMQPL4.mjs.map +0 -7
  162. package/dist/lib/browser/chunk-ENERBDYI.mjs.map +0 -7
  163. package/dist/lib/browser/chunk-OD2IZKRP.mjs.map +0 -7
  164. package/dist/lib/browser/meta.mjs +0 -11
  165. package/dist/lib/browser/meta.mjs.map +0 -7
  166. package/dist/lib/node/ThreadArticle-ZCNMFBAO.cjs.map +0 -7
  167. package/dist/lib/node/ThreadMain-5AYGCXXP.cjs.map +0 -7
  168. package/dist/lib/node/chunk-2CB5AVBL.cjs.map +0 -7
  169. package/dist/lib/node/chunk-IC2NICNC.cjs.map +0 -7
  170. package/dist/lib/node/chunk-VW2P26MZ.cjs.map +0 -7
  171. package/dist/lib/node/meta.cjs.map +0 -7
  172. package/dist/lib/node-esm/ThreadArticle-F37HYTOU.mjs +0 -19
  173. package/dist/lib/node-esm/ThreadArticle-F37HYTOU.mjs.map +0 -7
  174. package/dist/lib/node-esm/ThreadMain-OL6ZHNZY.mjs +0 -27
  175. package/dist/lib/node-esm/ThreadMain-OL6ZHNZY.mjs.map +0 -7
  176. package/dist/lib/node-esm/chunk-7QRGG25F.mjs.map +0 -7
  177. package/dist/lib/node-esm/chunk-AQ74G3GY.mjs.map +0 -7
  178. package/dist/lib/node-esm/chunk-RMYATBXM.mjs.map +0 -7
  179. package/dist/lib/node-esm/meta.mjs +0 -12
  180. package/dist/lib/node-esm/meta.mjs.map +0 -7
  181. package/dist/types/src/components/ThreadArticle.d.ts +0 -5
  182. package/dist/types/src/components/ThreadArticle.d.ts.map +0 -1
  183. package/dist/types/src/components/ThreadMain.d.ts +0 -7
  184. package/dist/types/src/components/ThreadMain.d.ts.map +0 -1
  185. package/src/components/ThreadArticle.tsx +0 -18
  186. package/src/components/ThreadMain.tsx +0 -27
@@ -1,429 +1,35 @@
1
1
  import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
2
  import {
3
- ThreadAction
4
- } from "./chunk-RMYATBXM.mjs";
3
+ IntentResolver,
4
+ Markdown,
5
+ ReactSurface,
6
+ ThreadState
7
+ } from "./chunk-UNLSWYA4.mjs";
5
8
  import {
6
- MessageContainer,
7
- command,
8
- getMessageMetadata,
9
9
  useAnalyticsCallback,
10
10
  useOnEditAnalytics,
11
11
  useStatus
12
- } from "./chunk-AQ74G3GY.mjs";
12
+ } from "./chunk-HLWJTUWZ.mjs";
13
+ import {
14
+ ThreadAction
15
+ } from "./chunk-33NDMQQQ.mjs";
16
+ import "./chunk-ZJITX3TO.mjs";
13
17
  import {
14
18
  THREAD_ITEM,
15
19
  THREAD_PLUGIN,
16
- meta_default
17
- } from "./chunk-7QRGG25F.mjs";
20
+ meta
21
+ } from "./chunk-FXUATCLW.mjs";
18
22
 
19
23
  // packages/plugins/plugin-thread/src/ThreadPlugin.tsx
20
- import React5 from "react";
21
- import { createIntent as createIntent3, createResolver, createSurface, isLayoutParts, LayoutAction as LayoutAction2, NavigationAction, parseIntentPlugin, parseMetadataResolverPlugin, parseNavigationPlugin, resolvePlugin } from "@dxos/app-framework";
22
- import { Ref as Ref2 } from "@dxos/echo-schema";
23
- import { LocalStorageStore } from "@dxos/local-storage";
24
- import { log } from "@dxos/log";
25
- import { parseClientPlugin } from "@dxos/plugin-client/types";
26
- import { createExtension, toSignal } from "@dxos/plugin-graph";
27
- import { ObservabilityAction } from "@dxos/plugin-observability/types";
28
- import { memoizeQuery } from "@dxos/plugin-space";
29
- import { ChannelType as ChannelType2, MessageType as MessageType2, ThreadType as ThreadType2 } from "@dxos/plugin-space/types";
30
- import { create as create2, fullyQualifiedId as fullyQualifiedId5, getSpace as getSpace3, getTypename, makeRef as makeRef2, parseId, RefArray as RefArray4, SpaceState } from "@dxos/react-client/echo";
24
+ import { Capabilities, contributes, createIntent, defineModule, definePlugin, Events } from "@dxos/app-framework";
25
+ import { ClientCapabilities, ClientEvents } from "@dxos/plugin-client";
26
+ import { DeckCapabilities, DeckEvents } from "@dxos/plugin-deck";
27
+ import { MarkdownEvents } from "@dxos/plugin-markdown";
28
+ import { SpaceCapabilities, ThreadEvents } from "@dxos/plugin-space";
29
+ import { ChannelType as ChannelType2, defineObjectForm, MessageType, ThreadType } from "@dxos/plugin-space/types";
30
+ import { RefArray } from "@dxos/react-client/echo";
31
31
  import { translations as threadTranslations } from "@dxos/react-ui-thread";
32
32
 
33
- // packages/plugins/plugin-thread/src/components/index.ts
34
- import { lazy } from "react";
35
-
36
- // packages/plugins/plugin-thread/src/components/CommentContainer.tsx
37
- import { CheckCircle, X } from "@phosphor-icons/react";
38
- import React, { useCallback, useMemo, useRef, useState } from "react";
39
- import { create, makeRef, RefArray } from "@dxos/live-object";
40
- import { MessageType } from "@dxos/plugin-space/types";
41
- import { fullyQualifiedId, getSpace, useMembers } from "@dxos/react-client/echo";
42
- import { useIdentity } from "@dxos/react-client/halo";
43
- import { Button, Tag, Tooltip, useThemeContext, useTranslation } from "@dxos/react-ui";
44
- import { createBasicExtensions, createThemeExtensions, listener } from "@dxos/react-ui-editor";
45
- import { getSize, hoverableControlItem, hoverableControls, hoverableFocusedWithinControls, mx } from "@dxos/react-ui-theme";
46
- import { MessageTextbox, Thread, ThreadFooter, ThreadHeading } from "@dxos/react-ui-thread";
47
- import { nonNullable } from "@dxos/util";
48
- var sizeClass = getSize(4);
49
- var commentControlClassNames = "!p-1 !min-bs-0 transition-opacity";
50
- var ToggleResolvedButton = ({ isResolved, onResolve }) => {
51
- const { t } = useTranslation(THREAD_PLUGIN);
52
- const label = t(isResolved ? "mark as unresolved label" : "mark as resolved label");
53
- return /* @__PURE__ */ React.createElement(Tooltip.Root, null, /* @__PURE__ */ React.createElement(Tooltip.Trigger, {
54
- asChild: true
55
- }, /* @__PURE__ */ React.createElement(Button, {
56
- variant: "ghost",
57
- "data-testid": "thread.toggle-resolved",
58
- onClick: onResolve,
59
- classNames: [
60
- commentControlClassNames,
61
- !isResolved && hoverableControlItem
62
- ]
63
- }, /* @__PURE__ */ React.createElement("span", {
64
- className: "sr-only"
65
- }, label), isResolved ? /* @__PURE__ */ React.createElement(CheckCircle, {
66
- className: sizeClass,
67
- weight: "fill"
68
- }) : /* @__PURE__ */ React.createElement(CheckCircle, {
69
- className: sizeClass
70
- }))), /* @__PURE__ */ React.createElement(Tooltip.Portal, null, /* @__PURE__ */ React.createElement(Tooltip.Content, null, label, /* @__PURE__ */ React.createElement(Tooltip.Arrow, null))));
71
- };
72
- var DeleteThreadButton = ({ onDelete }) => {
73
- const { t } = useTranslation(THREAD_PLUGIN);
74
- const label = t("delete thread label");
75
- return /* @__PURE__ */ React.createElement(Tooltip.Root, null, /* @__PURE__ */ React.createElement(Tooltip.Trigger, {
76
- asChild: true
77
- }, /* @__PURE__ */ React.createElement(Button, {
78
- variant: "ghost",
79
- "data-testid": "thread.delete",
80
- onClick: onDelete,
81
- classNames: [
82
- commentControlClassNames,
83
- hoverableControlItem
84
- ]
85
- }, /* @__PURE__ */ React.createElement("span", {
86
- className: "sr-only"
87
- }, label), /* @__PURE__ */ React.createElement(X, {
88
- className: sizeClass
89
- }))), /* @__PURE__ */ React.createElement(Tooltip.Portal, null, /* @__PURE__ */ React.createElement(Tooltip.Content, {
90
- classNames: "z-30"
91
- }, label, /* @__PURE__ */ React.createElement(Tooltip.Arrow, null))));
92
- };
93
- var CommentContainer = ({ thread, detached, context, current, onAttend, onThreadDelete, onMessageDelete, onResolve, onComment }) => {
94
- const identity = useIdentity();
95
- const space = getSpace(thread);
96
- const members = useMembers(space?.key);
97
- const activity = useStatus(space, fullyQualifiedId(thread));
98
- const { t } = useTranslation(THREAD_PLUGIN);
99
- const threadScrollRef = useRef(null);
100
- const { themeMode } = useThemeContext();
101
- const textboxMetadata = getMessageMetadata(fullyQualifiedId(thread), identity);
102
- const [_count, _setCount] = useState(0);
103
- const rerenderEditor = () => _setCount((count) => count + 1);
104
- const messageRef = useRef("");
105
- const extensions = useMemo(() => [
106
- createBasicExtensions({
107
- placeholder: t("message placeholder")
108
- }),
109
- createThemeExtensions({
110
- themeMode
111
- }),
112
- listener({
113
- onChange: (text) => messageRef.current = text
114
- }),
115
- command
116
- ], [
117
- _count
118
- ]);
119
- const scrollToEnd = (behavior) => setTimeout(() => threadScrollRef.current?.scrollIntoView({
120
- behavior,
121
- block: "end"
122
- }), 10);
123
- const handleCreate = useCallback(() => {
124
- if (!messageRef.current) {
125
- return false;
126
- }
127
- thread.messages.push(makeRef(create(MessageType, {
128
- sender: {
129
- identityKey: identity.identityKey.toHex()
130
- },
131
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
132
- text: messageRef.current,
133
- context: context ? makeRef(context) : void 0
134
- })));
135
- onComment?.(thread);
136
- messageRef.current = "";
137
- scrollToEnd("instant");
138
- rerenderEditor();
139
- return true;
140
- }, [
141
- thread,
142
- identity
143
- ]);
144
- return /* @__PURE__ */ React.createElement(Thread, {
145
- onClickCapture: onAttend,
146
- onFocusCapture: onAttend,
147
- current,
148
- id: fullyQualifiedId(thread)
149
- }, /* @__PURE__ */ React.createElement("div", {
150
- role: "none",
151
- className: mx("col-span-2 grid grid-cols-[var(--rail-size)_1fr_min-content]", hoverableControls, hoverableFocusedWithinControls)
152
- }, detached ? /* @__PURE__ */ React.createElement(Tooltip.Root, null, /* @__PURE__ */ React.createElement(Tooltip.Trigger, {
153
- asChild: true
154
- }, /* @__PURE__ */ React.createElement(ThreadHeading, {
155
- detached: true
156
- }, thread.name)), /* @__PURE__ */ React.createElement(Tooltip.Portal, null, /* @__PURE__ */ React.createElement(Tooltip.Content, {
157
- classNames: "z-30",
158
- side: "top"
159
- }, t("detached thread label"), /* @__PURE__ */ React.createElement(Tooltip.Arrow, null)))) : /* @__PURE__ */ React.createElement(ThreadHeading, null, thread.name), /* @__PURE__ */ React.createElement("div", {
160
- className: "flex flex-row items-center pli-1"
161
- }, thread.status === "staged" && /* @__PURE__ */ React.createElement(Tag, {
162
- palette: "neutral"
163
- }, t("draft button")), onResolve && !(thread?.status === "staged") && /* @__PURE__ */ React.createElement(ToggleResolvedButton, {
164
- isResolved: thread?.status === "resolved",
165
- onResolve
166
- }), onThreadDelete && /* @__PURE__ */ React.createElement(DeleteThreadButton, {
167
- onDelete: onThreadDelete
168
- }))), RefArray.allResolvedTargets(thread.messages?.filter(nonNullable) ?? []).map((message) => /* @__PURE__ */ React.createElement(MessageContainer, {
169
- key: message.id,
170
- message,
171
- members,
172
- onDelete: (id) => onMessageDelete?.(id)
173
- })), /* @__PURE__ */ React.createElement(MessageTextbox, {
174
- extensions,
175
- onSend: handleCreate,
176
- ...textboxMetadata
177
- }), /* @__PURE__ */ React.createElement(ThreadFooter, {
178
- activity
179
- }, t("activity message")), /* @__PURE__ */ React.createElement("div", {
180
- role: "none",
181
- className: "bs-px -mbs-px",
182
- ref: threadScrollRef
183
- }));
184
- };
185
-
186
- // packages/plugins/plugin-thread/src/components/CommentsContainer.tsx
187
- import { ChatText } from "@phosphor-icons/react";
188
- import React2, { useEffect } from "react";
189
- import { fullyQualifiedId as fullyQualifiedId2 } from "@dxos/react-client/echo";
190
- import { useTranslation as useTranslation2, Trans } from "@dxos/react-ui";
191
- import { descriptionText, mx as mx2 } from "@dxos/react-ui-theme";
192
- var CommentsContainer = ({ threads: threads2, detached = [], currentId, showResolvedThreads, onThreadAttend, onThreadDelete, onMessageDelete, onThreadToggleResolved, ...props }) => {
193
- const { t } = useTranslation2(THREAD_PLUGIN);
194
- const filteredThreads = showResolvedThreads ? threads2 : threads2.filter((thread) => !(thread?.status === "resolved"));
195
- useEffect(() => {
196
- if (currentId) {
197
- document.getElementById(currentId)?.scrollIntoView({
198
- behavior: "smooth",
199
- block: "end"
200
- });
201
- }
202
- }, [
203
- currentId
204
- ]);
205
- return /* @__PURE__ */ React2.createElement(React2.Fragment, null, filteredThreads.length > 0 ? filteredThreads.map((thread) => {
206
- const threadId = fullyQualifiedId2(thread);
207
- return /* @__PURE__ */ React2.createElement(CommentContainer, {
208
- key: threadId,
209
- thread,
210
- current: currentId === threadId,
211
- detached: detached.includes(threadId),
212
- ...onThreadAttend && {
213
- onAttend: () => onThreadAttend(thread)
214
- },
215
- ...onThreadDelete && {
216
- onThreadDelete: () => onThreadDelete(thread)
217
- },
218
- ...onMessageDelete && {
219
- onMessageDelete: (messageId) => onMessageDelete(thread, messageId)
220
- },
221
- ...onThreadToggleResolved && {
222
- onResolve: () => onThreadToggleResolved(thread)
223
- },
224
- ...props
225
- });
226
- }) : /* @__PURE__ */ React2.createElement("div", {
227
- role: "alert",
228
- className: mx2(descriptionText, "place-self-center border border-dashed border-unAccent rounded-lg text-center p-4 m-4")
229
- }, /* @__PURE__ */ React2.createElement("h2", {
230
- className: "mbe-2 font-medium text-baseText"
231
- }, t("no comments title")), /* @__PURE__ */ React2.createElement("p", null, /* @__PURE__ */ React2.createElement(Trans, {
232
- t,
233
- i18nKey: "no comments message",
234
- components: {
235
- commentIcon: /* @__PURE__ */ React2.createElement(ChatText, {
236
- className: "inline-block"
237
- })
238
- }
239
- }))));
240
- };
241
-
242
- // packages/plugins/plugin-thread/src/components/ThreadComplementary.tsx
243
- import React3, { useEffect as useEffect2, useMemo as useMemo2 } from "react";
244
- import { createIntent, LayoutAction, useIntentDispatcher, useResolvePlugins } from "@dxos/app-framework";
245
- import { fullyQualifiedId as fullyQualifiedId3, RefArray as RefArray2 } from "@dxos/react-client/echo";
246
- import { useAttended } from "@dxos/react-ui-attention";
247
- import { nonNullable as nonNullable2 } from "@dxos/util";
248
- var providesThreadsConfig = (plugin) => "thread" in plugin.provides ? plugin : void 0;
249
- var ThreadComplementary = ({ subject, drafts, current, showResolvedThreads }) => {
250
- const { dispatchPromise: dispatch } = useIntentDispatcher();
251
- const threadsIntegrators = useResolvePlugins(providesThreadsConfig);
252
- const threadProvides = useMemo2(() => threadsIntegrators.map((p) => p.provides.thread), [
253
- threadsIntegrators
254
- ]);
255
- const createSort = useMemo2(() => threadProvides.find((p) => p.predicate(subject))?.createSort, [
256
- threadProvides,
257
- subject
258
- ]);
259
- const sort = useMemo2(() => createSort?.(subject), [
260
- createSort,
261
- subject
262
- ]);
263
- const threadObjects = RefArray2.allResolvedTargets(subject.threads ?? []);
264
- const threads2 = useMemo2(() => {
265
- return threadObjects.concat(drafts ?? []).filter(nonNullable2);
266
- }, [
267
- JSON.stringify(threadObjects),
268
- JSON.stringify(drafts)
269
- ]);
270
- const detachedIds = useMemo2(() => {
271
- return threads2.filter(({ anchor }) => !anchor).map((thread) => fullyQualifiedId3(thread));
272
- }, [
273
- threads2
274
- ]);
275
- useEffect2(() => {
276
- if (!sort) {
277
- return;
278
- }
279
- threads2.sort((a, b) => sort(a?.anchor, b?.anchor));
280
- }, [
281
- sort,
282
- threads2
283
- ]);
284
- const attended = useAttended();
285
- const qualifiedSubjectId = fullyQualifiedId3(subject);
286
- return /* @__PURE__ */ React3.createElement(CommentsContainer, {
287
- threads: threads2,
288
- detached: detachedIds,
289
- currentId: attended.includes(qualifiedSubjectId) ? current : void 0,
290
- showResolvedThreads,
291
- onThreadAttend: (thread) => {
292
- const threadId = fullyQualifiedId3(thread);
293
- if (current !== threadId) {
294
- current = threadId;
295
- void dispatch?.(createIntent(LayoutAction.ScrollIntoView, {
296
- id: fullyQualifiedId3(subject),
297
- cursor: thread.anchor,
298
- ref: threadId
299
- }));
300
- }
301
- },
302
- onThreadDelete: (thread) => dispatch(createIntent(ThreadAction.Delete, {
303
- thread,
304
- subject
305
- })),
306
- onMessageDelete: (thread, messageId) => dispatch(createIntent(ThreadAction.DeleteMessage, {
307
- thread,
308
- subject,
309
- messageId
310
- })),
311
- onThreadToggleResolved: (thread) => dispatch(createIntent(ThreadAction.ToggleResolved, {
312
- thread
313
- })),
314
- onComment: (thread) => dispatch(createIntent(ThreadAction.OnMessageAdd, {
315
- thread,
316
- subject
317
- }))
318
- });
319
- };
320
-
321
- // packages/plugins/plugin-thread/src/components/ThreadSettings.tsx
322
- import React4 from "react";
323
- import { Input, useTranslation as useTranslation3 } from "@dxos/react-ui";
324
- import { DeprecatedFormInput } from "@dxos/react-ui-form";
325
- var ThreadSettings = ({ settings }) => {
326
- const { t } = useTranslation3(THREAD_PLUGIN);
327
- return /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(DeprecatedFormInput, {
328
- label: t("settings standalone label")
329
- }, /* @__PURE__ */ React4.createElement(Input.Switch, {
330
- checked: settings.standalone,
331
- onCheckedChange: (checked) => settings.standalone = !!checked
332
- })));
333
- };
334
-
335
- // packages/plugins/plugin-thread/src/components/index.ts
336
- var ThreadMain = lazy(() => import("./ThreadMain-OL6ZHNZY.mjs"));
337
- var ThreadArticle = lazy(() => import("./ThreadArticle-F37HYTOU.mjs"));
338
-
339
- // packages/plugins/plugin-thread/src/extensions/threads.ts
340
- import { EditorView } from "@codemirror/view";
341
- import { computed, effect } from "@preact/signals-core";
342
- import { createIntent as createIntent2 } from "@dxos/app-framework";
343
- import { Ref } from "@dxos/echo-schema";
344
- import { RefArray as RefArray3 } from "@dxos/live-object";
345
- import { ThreadType } from "@dxos/plugin-space/types";
346
- import { getSpace as getSpace2, getTextInRange, createDocAccessor, fullyQualifiedId as fullyQualifiedId4 } from "@dxos/react-client/echo";
347
- import { comments, createExternalCommentSync } from "@dxos/react-ui-editor";
348
- var getName = (doc, anchor) => {
349
- if (doc.content) {
350
- const [start, end] = anchor.split(":");
351
- return getTextInRange(createDocAccessor(doc.content.target, [
352
- "content"
353
- ]), start, end);
354
- }
355
- };
356
- var threads = (state, doc, dispatch) => {
357
- const space = doc && getSpace2(doc);
358
- if (!doc || !space || !dispatch) {
359
- return [
360
- comments()
361
- ];
362
- }
363
- const threads2 = computed(() => [
364
- ...RefArray3.allResolvedTargets(doc.threads),
365
- ...state.drafts[fullyQualifiedId4(doc)] ?? []
366
- ].filter((thread) => !(thread?.status === "resolved")));
367
- return [
368
- EditorView.updateListener.of((update) => {
369
- if (update.docChanged) {
370
- RefArray3.allResolvedTargets(doc.threads).forEach((thread) => {
371
- if (thread.anchor) {
372
- const name = getName(doc, thread.anchor);
373
- if (name && name !== thread.name) {
374
- thread.name = name;
375
- }
376
- }
377
- });
378
- }
379
- }),
380
- createExternalCommentSync(fullyQualifiedId4(doc), (sink) => effect(() => sink()), () => threads2.value.filter((thread) => thread?.anchor).map((thread) => ({
381
- id: fullyQualifiedId4(thread),
382
- cursor: thread.anchor
383
- }))),
384
- comments({
385
- id: fullyQualifiedId4(doc),
386
- onCreate: ({ cursor }) => {
387
- const name = getName(doc, cursor);
388
- void dispatch(createIntent2(ThreadAction.Create, {
389
- cursor,
390
- name,
391
- subject: doc
392
- }));
393
- },
394
- onDelete: ({ id }) => {
395
- const draft = state.drafts[fullyQualifiedId4(doc)];
396
- if (draft) {
397
- const index = draft.findIndex((thread2) => fullyQualifiedId4(thread2) === id);
398
- if (index !== -1) {
399
- draft.splice(index, 1);
400
- }
401
- }
402
- const thread = doc.threads.find(Ref.hasObjectId(id))?.target;
403
- if (thread) {
404
- thread.anchor = void 0;
405
- }
406
- },
407
- onUpdate: ({ id, cursor }) => {
408
- const thread = state.drafts[fullyQualifiedId4(doc)]?.find((thread2) => fullyQualifiedId4(thread2) === id) ?? doc.threads.find(Ref.hasObjectId(id))?.target;
409
- if (thread instanceof ThreadType && thread.anchor) {
410
- thread.name = getName(doc, thread.anchor);
411
- thread.anchor = cursor;
412
- }
413
- },
414
- onSelect: ({ selection }) => {
415
- const current = selection.current ?? selection.closest;
416
- if (current) {
417
- void dispatch(createIntent2(ThreadAction.Select, {
418
- current,
419
- skipOpen: true
420
- }));
421
- }
422
- }
423
- })
424
- ];
425
- };
426
-
427
33
  // packages/plugins/plugin-thread/src/translations.ts
428
34
  import { ChannelType } from "@dxos/plugin-space/types";
429
35
  var translations_default = [
@@ -439,7 +45,6 @@ var translations_default = [
439
45
  "delete channel label": "Delete channel",
440
46
  "create channel label": "Create channel",
441
47
  "message placeholder": "Reply\u2026",
442
- "settings standalone label": "Enable channel creation (experimental)",
443
48
  "activity message": "Processing\u2026",
444
49
  "anonymous label": "Anonymous",
445
50
  "delete message block label": "Delete message block",
@@ -459,551 +64,151 @@ var translations_default = [
459
64
  "save message label": "Save",
460
65
  "edit message label": "Edit",
461
66
  "delete message label": "Delete message",
462
- "open comments panel label": "Show Comments"
67
+ "open comments panel label": "Show Comments",
68
+ "comments panel label": "Comments"
463
69
  }
464
70
  }
465
71
  }
466
72
  ];
467
73
 
468
74
  // packages/plugins/plugin-thread/src/ThreadPlugin.tsx
469
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/plugins/plugin-thread/src/ThreadPlugin.tsx";
470
- var initialViewState = {
471
- showResolvedThreads: false
472
- };
473
- var ThreadPlugin = () => {
474
- const settings = new LocalStorageStore(THREAD_PLUGIN);
475
- const state = create2({
476
- drafts: {}
477
- });
478
- const viewStore = create2({});
479
- const getViewState = (subjectId) => {
480
- if (!viewStore[subjectId]) {
481
- viewStore[subjectId] = {
482
- ...initialViewState
483
- };
484
- }
485
- return viewStore[subjectId];
486
- };
487
- let intentPlugin;
488
- const unsubscribeCallbacks = [];
489
- return {
490
- meta: meta_default,
491
- initialize: async () => {
492
- settings.prop({
493
- key: "standalone",
494
- type: LocalStorageStore.bool({
495
- allowUndefined: true
496
- })
497
- });
498
- return {
499
- echo: {
500
- system: [
501
- ThreadType2,
502
- MessageType2
75
+ var ThreadPlugin = () => definePlugin(meta, [
76
+ // TODO(wittjosiah): Currently not used but leaving because there will likely be settings for threads again.
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
+ // TODO(wittjosiah): Does not integrate with settings store.
85
+ // Should this be a different event?
86
+ // Should settings store be renamed to be more generic?
87
+ activatesOn: Events.SetupSettings,
88
+ activate: ThreadState
89
+ }),
90
+ defineModule({
91
+ id: `${meta.id}/module/translations`,
92
+ activatesOn: Events.SetupTranslations,
93
+ activate: () => contributes(Capabilities.Translations, [
94
+ ...translations_default,
95
+ ...threadTranslations
96
+ ])
97
+ }),
98
+ defineModule({
99
+ id: `${meta.id}/module/metadata`,
100
+ activatesOn: Events.SetupMetadata,
101
+ activate: () => [
102
+ contributes(Capabilities.Metadata, {
103
+ id: ChannelType2.typename,
104
+ metadata: {
105
+ placeholder: [
106
+ "channel name placeholder",
107
+ {
108
+ ns: THREAD_PLUGIN
109
+ }
503
110
  ],
504
- // TODO(wittjosiah): Requires reload.
505
- ...settings.values.standalone ? {
506
- schema: [
507
- ChannelType2
508
- ]
509
- } : {}
111
+ icon: "ph--chat--regular",
112
+ // TODO(wittjosiah): Move out of metadata.
113
+ loadReferences: async (channel) => await RefArray.loadAll(channel.threads ?? [])
510
114
  }
511
- };
512
- },
513
- ready: async ({ plugins }) => {
514
- intentPlugin = resolvePlugin(plugins, parseIntentPlugin);
515
- },
516
- unload: async () => {
517
- unsubscribeCallbacks.forEach((unsubscribe) => unsubscribe());
518
- },
519
- provides: {
520
- settings: settings.values,
521
- metadata: {
522
- records: {
523
- [ChannelType2.typename]: {
524
- createObject: (props) => createIntent3(ThreadAction.Create, props),
525
- placeholder: [
526
- "channel name placeholder",
527
- {
528
- ns: THREAD_PLUGIN
529
- }
530
- ],
531
- icon: "ph--chat--regular",
532
- // TODO(wittjosiah): Move out of metadata.
533
- loadReferences: async (channel) => await RefArray4.loadAll(channel.threads ?? [])
534
- },
535
- [ThreadType2.typename]: {
536
- // TODO(wittjosiah): Move out of metadata.
537
- loadReferences: async (thread) => await RefArray4.loadAll(thread.messages ?? [])
538
- },
539
- [MessageType2.typename]: {
540
- // TODO(wittjosiah): Move out of metadata.
541
- loadReferences: (message) => []
542
- },
543
- [THREAD_ITEM]: {
544
- parse: (item, type) => {
545
- switch (type) {
546
- case "node":
547
- return {
548
- id: item.id,
549
- label: item.title,
550
- data: item
551
- };
552
- case "object":
553
- return item;
554
- case "view-object":
555
- return {
556
- id: `${item.id}-view`,
557
- object: item
558
- };
559
- }
560
- }
561
- }
115
+ }),
116
+ contributes(Capabilities.Metadata, {
117
+ id: ThreadType.typename,
118
+ metadata: {
119
+ // TODO(wittjosiah): Move out of metadata.
120
+ loadReferences: async (thread) => await RefArray.loadAll(thread.messages ?? [])
562
121
  }
563
- },
564
- translations: [
565
- ...translations_default,
566
- ...threadTranslations
567
- ],
568
- complementary: {
569
- panels: [
570
- {
571
- id: "comments",
572
- label: [
573
- "open comments panel label",
574
- {
575
- ns: THREAD_PLUGIN
576
- }
577
- ],
578
- icon: "ph--chat-text--regular"
579
- }
580
- ]
581
- },
582
- graph: {
583
- builder: (plugins) => {
584
- const client = resolvePlugin(plugins, parseClientPlugin)?.provides.client;
585
- const dispatch = resolvePlugin(plugins, parseIntentPlugin)?.provides.intent.dispatchPromise;
586
- const metadataResolver = resolvePlugin(plugins, parseMetadataResolverPlugin)?.provides.metadata.resolver;
587
- if (!client || !dispatch || !metadataResolver) {
588
- return [];
589
- }
590
- const type = "orphan-comments-for-subject";
591
- const icon = "ph--chat-text--regular";
592
- return [
593
- createExtension({
594
- id: `${THREAD_PLUGIN}/comments-for-subject`,
595
- resolver: ({ id }) => {
596
- if (!id.endsWith("~comments")) {
597
- return;
598
- }
599
- const [subjectId] = id.split("~");
600
- const { spaceId, objectId } = parseId(subjectId);
601
- const spaces = toSignal((onChange) => client.spaces.subscribe(() => onChange()).unsubscribe, () => client.spaces.get());
602
- const space = spaces?.find((space2) => space2.id === spaceId && space2.state.get() === SpaceState.SPACE_READY);
603
- if (!objectId) {
604
- return {
605
- id,
606
- type,
607
- data: null,
608
- properties: {
609
- icon,
610
- label: [
611
- "unnamed object threads label",
612
- {
613
- ns: THREAD_PLUGIN
614
- }
615
- ],
616
- showResolvedThreads: false,
617
- object: null,
618
- space
619
- }
620
- };
621
- }
622
- const [object] = memoizeQuery(space, {
623
- id: objectId
624
- });
625
- if (!object || !subjectId) {
626
- return;
627
- }
628
- const meta = metadataResolver(getTypename(object) ?? "");
629
- const label = meta.label?.(object) || object.name || meta.placeholder || [
630
- "unnamed object threads label",
631
- {
632
- ns: THREAD_PLUGIN
633
- }
634
- ];
635
- const viewState = getViewState(subjectId);
122
+ }),
123
+ contributes(Capabilities.Metadata, {
124
+ id: MessageType.typename,
125
+ metadata: {
126
+ // TODO(wittjosiah): Move out of metadata.
127
+ loadReferences: (message) => []
128
+ }
129
+ }),
130
+ contributes(Capabilities.Metadata, {
131
+ id: THREAD_ITEM,
132
+ metadata: {
133
+ parse: (item, type) => {
134
+ switch (type) {
135
+ case "node":
636
136
  return {
637
- id,
638
- type,
639
- data: null,
640
- properties: {
641
- icon,
642
- label,
643
- showResolvedThreads: viewState.showResolvedThreads,
644
- object
645
- }
137
+ id: item.id,
138
+ label: item.title,
139
+ data: item
646
140
  };
647
- },
648
- actions: ({ node }) => {
649
- const dataId = node.id.split("~").at(0);
650
- if (!node.id.endsWith("~comments") || !dataId) {
651
- return;
652
- }
653
- const [spaceId, objectId] = dataId.split(":");
654
- const viewState = getViewState(dataId);
655
- const toggle = async () => {
656
- const newToggleState = !viewState.showResolvedThreads;
657
- viewState.showResolvedThreads = newToggleState;
658
- await dispatch(createIntent3(ObservabilityAction.SendEvent, {
659
- name: "threads.toggle-show-resolved",
660
- properties: {
661
- spaceId,
662
- threadId: objectId,
663
- showResolved: newToggleState
664
- }
665
- }));
666
- };
667
- return [
668
- {
669
- id: `${THREAD_PLUGIN}/toggle-show-resolved/${node.id}`,
670
- data: toggle,
671
- properties: {
672
- label: [
673
- "toggle show resolved",
674
- {
675
- ns: THREAD_PLUGIN
676
- }
677
- ],
678
- menuItemType: "toggle",
679
- isChecked: viewState.showResolvedThreads,
680
- testId: "threadPlugin.toggleShowResolved",
681
- icon: viewState.showResolvedThreads ? "ph--eye-slash--regular" : "ph--eye--regular"
682
- }
683
- }
684
- ];
685
- }
686
- })
687
- ];
688
- }
689
- },
690
- surface: {
691
- definitions: ({ plugins }) => {
692
- const location = resolvePlugin(plugins, parseNavigationPlugin)?.provides.location;
693
- return [
694
- createSurface({
695
- id: `${THREAD_PLUGIN}/channel`,
696
- role: "article",
697
- filter: (data) => data.subject instanceof ChannelType2 && !!data.subject.threads[0],
698
- component: ({ data }) => {
699
- const channel = data.subject;
700
- const thread = channel.threads[0].target;
701
- if (isLayoutParts(location?.active) && location.active.main) {
702
- const layoutEntries = location.active.main;
703
- const currentPosition = layoutEntries.findIndex((entry) => channel.id === entry.id);
704
- if (currentPosition > 0) {
705
- const objectToTheLeft = layoutEntries[currentPosition - 1];
706
- const context = getSpace3(channel)?.db.getObjectById(objectToTheLeft.id);
707
- return /* @__PURE__ */ React5.createElement(ThreadArticle, {
708
- thread,
709
- context
710
- });
711
- }
712
- }
713
- return /* @__PURE__ */ React5.createElement(ThreadArticle, {
714
- thread
715
- });
716
- }
717
- }),
718
- createSurface({
719
- id: `${THREAD_PLUGIN}/thread`,
720
- role: "complementary--comments",
721
- filter: (data) => !!data.subject && typeof data.subject === "object" && "threads" in data.subject && Array.isArray(data.subject.threads) && !(data.subject instanceof ChannelType2),
722
- component: ({ data }) => {
723
- const { showResolvedThreads } = getViewState(fullyQualifiedId5(data.subject));
724
- return /* @__PURE__ */ React5.createElement(ThreadComplementary, {
725
- subject: data.subject,
726
- drafts: state.drafts[fullyQualifiedId5(data.subject)],
727
- current: state.current,
728
- showResolvedThreads
729
- });
730
- }
731
- }),
732
- createSurface({
733
- id: `${THREAD_PLUGIN}/settings`,
734
- role: "settings",
735
- filter: (data) => data.plugin === THREAD_PLUGIN,
736
- component: () => /* @__PURE__ */ React5.createElement(ThreadSettings, {
737
- settings: settings.values
738
- })
739
- })
740
- ];
741
- }
742
- },
743
- intent: {
744
- resolvers: () => [
745
- createResolver(ThreadAction.Create, ({ name, cursor, subject }) => {
746
- if (cursor && subject) {
747
- if (subject?.threads === void 0) {
748
- try {
749
- subject.threads = [];
750
- } catch (err) {
751
- log.error("Subject does not support threads array", subject?.typename, {
752
- F: __dxlog_file,
753
- L: 314,
754
- S: void 0,
755
- C: (f, a) => f(...a)
756
- });
757
- return;
758
- }
759
- }
760
- const subjectId = fullyQualifiedId5(subject);
761
- const thread = create2(ThreadType2, {
762
- name,
763
- anchor: cursor,
764
- messages: [],
765
- status: "staged"
766
- });
767
- const draft = state.drafts[subjectId];
768
- if (draft) {
769
- draft.push(thread);
770
- } else {
771
- state.drafts[subjectId] = [
772
- thread
773
- ];
774
- }
775
- return {
776
- data: {
777
- object: thread
778
- },
779
- intents: [
780
- createIntent3(ThreadAction.Select, {
781
- current: fullyQualifiedId5(thread)
782
- }),
783
- createIntent3(NavigationAction.Open, {
784
- activeParts: {
785
- complementary: "comments"
786
- }
787
- }),
788
- createIntent3(LayoutAction2.SetLayout, {
789
- element: "complementary",
790
- state: true
791
- })
792
- ]
793
- };
794
- } else {
795
- return {
796
- data: {
797
- object: create2(ChannelType2, {
798
- threads: [
799
- makeRef2(create2(ThreadType2, {
800
- messages: []
801
- }))
802
- ]
803
- })
804
- }
805
- };
806
- }
807
- }),
808
- createResolver(ThreadAction.Select, ({ current, skipOpen }) => {
809
- state.current = current;
810
- return {
811
- intents: !skipOpen ? [
812
- createIntent3(NavigationAction.Open, {
813
- activeParts: {
814
- complementary: "comments"
815
- }
816
- })
817
- ] : void 0
818
- };
819
- }),
820
- createResolver(ThreadAction.ToggleResolved, ({ thread }) => {
821
- if (thread.status === "active" || thread.status === void 0) {
822
- thread.status = "resolved";
823
- } else if (thread.status === "resolved") {
824
- thread.status = "active";
825
- }
826
- const space = getSpace3(thread);
827
- const spaceId = space?.id;
828
- return {
829
- intents: [
830
- createIntent3(ObservabilityAction.SendEvent, {
831
- name: "threads.toggle-resolved",
832
- properties: {
833
- threadId: thread.id,
834
- spaceId
835
- }
836
- })
837
- ]
838
- };
839
- }),
840
- createResolver(ThreadAction.Delete, ({ subject, thread }, undo) => {
841
- const subjectId = fullyQualifiedId5(subject);
842
- const draft = state.drafts[subjectId];
843
- if (draft) {
844
- const index = draft.findIndex((t) => t.id === thread.id);
845
- if (index !== -1) {
846
- draft.splice(index, 1);
847
- return;
848
- }
849
- }
850
- const space = getSpace3(thread);
851
- if (!space || !subject.threads) {
852
- return;
853
- }
854
- if (!undo) {
855
- const index = subject.threads.findIndex((t) => t?.id === thread.id);
856
- const cursor = subject.threads[index]?.anchor;
857
- if (index !== -1) {
858
- subject.threads?.splice(index, 1);
859
- }
860
- space.db.remove(thread);
861
- return {
862
- undoable: {
863
- message: [
864
- "thread deleted label",
865
- {
866
- ns: THREAD_PLUGIN
867
- }
868
- ],
869
- data: {
870
- cursor
871
- }
872
- },
873
- intents: [
874
- createIntent3(ObservabilityAction.SendEvent, {
875
- name: "threads.delete",
876
- properties: {
877
- threadId: thread.id,
878
- spaceId: space.id
879
- }
880
- })
881
- ]
882
- };
883
- } else {
884
- const savedThread = space.db.add(thread);
885
- subject.threads.push(savedThread);
886
- return {
887
- intents: [
888
- createIntent3(ObservabilityAction.SendEvent, {
889
- name: "threads.undo-delete",
890
- properties: {
891
- threadId: thread.id,
892
- spaceId: space.id
893
- }
894
- })
895
- ]
896
- };
897
- }
898
- }),
899
- createResolver(ThreadAction.OnMessageAdd, ({ thread, subject }) => {
900
- const subjectId = fullyQualifiedId5(subject);
901
- const space = getSpace3(subject);
902
- const intents = [];
903
- const analyticsProperties = {
904
- threadId: thread.id,
905
- spaceId: space?.id
906
- };
907
- if (state.drafts[subjectId]?.find((t) => t === thread)) {
908
- thread.status = "active";
909
- subject.threads ? subject.threads.push(makeRef2(thread)) : subject.threads = [
910
- makeRef2(thread)
911
- ];
912
- state.drafts[subjectId] = state.drafts[subjectId]?.filter(({ id }) => id !== thread.id);
913
- intents.push(createIntent3(ObservabilityAction.SendEvent, {
914
- name: "threads.thread-created",
915
- properties: analyticsProperties
916
- }));
917
- }
918
- intents.push(createIntent3(ObservabilityAction.SendEvent, {
919
- name: "threads.message-added",
920
- properties: {
921
- ...analyticsProperties,
922
- threadLength: thread.messages.length
923
- }
924
- }));
925
- return {
926
- intents
927
- };
928
- }),
929
- createResolver(ThreadAction.DeleteMessage, ({ subject, thread, messageId, message, messageIndex }, undo) => {
930
- const space = getSpace3(subject);
931
- if (!undo) {
932
- const messageIndex2 = thread.messages.findIndex(Ref2.hasObjectId(messageId));
933
- const message2 = thread.messages[messageIndex2]?.target;
934
- if (!message2) {
935
- return;
936
- }
937
- if (messageIndex2 === 0 && thread.messages.length === 1) {
141
+ case "object":
142
+ return item;
143
+ case "view-object":
938
144
  return {
939
- intents: [
940
- createIntent3(ThreadAction.Delete, {
941
- subject,
942
- thread
943
- })
944
- ]
145
+ id: `${item.id}-view`,
146
+ object: item
945
147
  };
946
- } else {
947
- thread.messages.splice(messageIndex2, 1);
948
- }
949
- return {
950
- undoable: {
951
- message: [
952
- "message deleted label",
953
- {
954
- ns: THREAD_PLUGIN
955
- }
956
- ],
957
- data: {
958
- message: message2,
959
- messageIndex: messageIndex2
960
- }
961
- },
962
- intents: [
963
- createIntent3(ObservabilityAction.SendEvent, {
964
- name: "threads.message.delete",
965
- properties: {
966
- threadId: thread.id,
967
- spaceId: space?.id
968
- }
969
- })
970
- ]
971
- };
972
- } else {
973
- if (!messageIndex || !message) {
974
- return;
975
- }
976
- thread.messages.splice(messageIndex, 0, makeRef2(message));
977
- return {
978
- intents: [
979
- createIntent3(ObservabilityAction.SendEvent, {
980
- name: "threads.message.undo-delete",
981
- properties: {
982
- threadId: thread.id,
983
- spaceId: space?.id
984
- }
985
- })
986
- ]
987
- };
988
148
  }
989
- })
990
- ]
991
- },
992
- markdown: {
993
- extensions: ({ document: doc }) => {
994
- return threads(state, doc, intentPlugin?.provides.intent.dispatchPromise);
149
+ }
995
150
  }
996
- }
997
- }
998
- };
999
- };
1000
-
1001
- // packages/plugins/plugin-thread/src/index.ts
1002
- var src_default = ThreadPlugin;
151
+ })
152
+ ]
153
+ }),
154
+ defineModule({
155
+ id: `${meta.id}/module/object-form`,
156
+ activatesOn: ClientEvents.SetupSchema,
157
+ activate: () => contributes(SpaceCapabilities.ObjectForm, defineObjectForm({
158
+ objectSchema: ChannelType2,
159
+ getIntent: () => createIntent(ThreadAction.Create)
160
+ }))
161
+ }),
162
+ defineModule({
163
+ id: `${meta.id}/module/schema`,
164
+ activatesOn: ClientEvents.SetupSchema,
165
+ activate: () => contributes(ClientCapabilities.Schema, [
166
+ ThreadType,
167
+ MessageType
168
+ ])
169
+ }),
170
+ defineModule({
171
+ id: `${meta.id}/module/complementary-panel`,
172
+ activatesOn: DeckEvents.SetupComplementaryPanels,
173
+ activate: () => contributes(DeckCapabilities.ComplementaryPanel, {
174
+ id: "comments",
175
+ label: [
176
+ "comments panel label",
177
+ {
178
+ ns: THREAD_PLUGIN
179
+ }
180
+ ],
181
+ icon: "ph--chat-text--regular",
182
+ // TODO(wittjosiah): Support comments on any object.
183
+ // filter: (node) => isEchoObject(node.data) && !!getSpace(node.data),
184
+ filter: (node) => !!node.data && typeof node.data === "object" && "threads" in node.data && Array.isArray(node.data.threads) && !(node.data instanceof ChannelType2)
185
+ })
186
+ }),
187
+ defineModule({
188
+ id: `${meta.id}/module/markdown`,
189
+ activatesOn: MarkdownEvents.SetupExtensions,
190
+ activate: Markdown
191
+ }),
192
+ defineModule({
193
+ id: `${meta.id}/module/react-surface`,
194
+ activatesOn: Events.SetupReactSurface,
195
+ // TODO(wittjosiah): Should occur before the comments thread is loaded when surfaces activation is more granular.
196
+ activatesBefore: [
197
+ ThreadEvents.SetupThread
198
+ ],
199
+ activate: ReactSurface
200
+ }),
201
+ defineModule({
202
+ id: `${meta.id}/module/intent-resolver`,
203
+ activatesOn: Events.SetupIntentResolver,
204
+ activate: IntentResolver
205
+ })
206
+ ]);
1003
207
  export {
1004
- ThreadAction,
208
+ THREAD_ITEM,
209
+ THREAD_PLUGIN,
1005
210
  ThreadPlugin,
1006
- src_default as default,
211
+ meta,
1007
212
  useAnalyticsCallback,
1008
213
  useOnEditAnalytics,
1009
214
  useStatus