@dxos/plugin-thread 0.8.1-main.ae460ac → 0.8.1-staging.31c3ee1

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 (185) hide show
  1. package/dist/lib/browser/ChatContainer-IOOAQW6S.mjs +138 -0
  2. package/dist/lib/browser/ChatContainer-IOOAQW6S.mjs.map +7 -0
  3. package/dist/lib/browser/app-graph-builder-6W4UKJDI.mjs +41 -0
  4. package/dist/lib/browser/app-graph-builder-6W4UKJDI.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-NAO3LZMZ.mjs → chunk-EP6MRLY7.mjs} +2 -2
  6. package/dist/lib/browser/{chunk-BNEWNQBO.mjs → chunk-QDJ3Y6WF.mjs} +14 -19
  7. package/dist/lib/browser/{chunk-BNEWNQBO.mjs.map → chunk-QDJ3Y6WF.mjs.map} +3 -3
  8. package/dist/lib/browser/chunk-S5ZR4FYW.mjs +17 -0
  9. package/dist/lib/browser/chunk-S5ZR4FYW.mjs.map +7 -0
  10. package/dist/lib/browser/{chunk-UPKU23DA.mjs → chunk-TFVPUPOO.mjs} +35 -140
  11. package/dist/lib/browser/chunk-TFVPUPOO.mjs.map +7 -0
  12. package/dist/lib/browser/{chunk-636QDHE3.mjs → chunk-WBJLUUOK.mjs} +1 -1
  13. package/dist/lib/browser/{chunk-636QDHE3.mjs.map → chunk-WBJLUUOK.mjs.map} +2 -2
  14. package/dist/lib/browser/{chunk-YK3ICB7G.mjs → chunk-WOG72DWE.mjs} +25 -11
  15. package/dist/lib/browser/chunk-WOG72DWE.mjs.map +7 -0
  16. package/dist/lib/browser/index.mjs +47 -49
  17. package/dist/lib/browser/index.mjs.map +4 -4
  18. package/dist/lib/browser/{intent-resolver-FAFQ54NP.mjs → intent-resolver-QAY4FLLM.mjs} +134 -94
  19. package/dist/lib/browser/intent-resolver-QAY4FLLM.mjs.map +7 -0
  20. package/dist/lib/browser/{markdown-RPYOUBVR.mjs → markdown-7KXBXCUS.mjs} +9 -10
  21. package/dist/lib/browser/markdown-7KXBXCUS.mjs.map +7 -0
  22. package/dist/lib/browser/meta.json +1 -1
  23. package/dist/lib/browser/{react-surface-Y4MUSICN.mjs → react-surface-MT3OWULR.mjs} +55 -51
  24. package/dist/lib/browser/react-surface-MT3OWULR.mjs.map +7 -0
  25. package/dist/lib/browser/{settings-WQTE5AEZ.mjs → settings-4FEC7EAX.mjs} +3 -3
  26. package/dist/lib/browser/{state-GNFUURIC.mjs → state-PNMSLKAH.mjs} +4 -3
  27. package/dist/lib/browser/state-PNMSLKAH.mjs.map +7 -0
  28. package/dist/lib/browser/types.mjs +2 -2
  29. package/dist/lib/node/ChatContainer-4FNDRF3G.cjs +163 -0
  30. package/dist/lib/node/ChatContainer-4FNDRF3G.cjs.map +7 -0
  31. package/dist/lib/node/app-graph-builder-HZNWT4QU.cjs +57 -0
  32. package/dist/lib/node/app-graph-builder-HZNWT4QU.cjs.map +7 -0
  33. package/dist/lib/node/{chunk-CMEMMYDL.cjs → chunk-46BSFPBV.cjs} +29 -15
  34. package/dist/lib/node/chunk-46BSFPBV.cjs.map +7 -0
  35. package/dist/lib/node/{chunk-AWSTZ2KN.cjs → chunk-AKINTFBH.cjs} +17 -23
  36. package/dist/lib/node/chunk-AKINTFBH.cjs.map +7 -0
  37. package/dist/lib/node/chunk-E7Z3BKRQ.cjs +232 -0
  38. package/dist/lib/node/chunk-E7Z3BKRQ.cjs.map +7 -0
  39. package/dist/lib/node/{chunk-FPWNZ6TB.cjs → chunk-NQ5DTPOY.cjs} +7 -7
  40. package/dist/lib/node/{chunk-F735VMTN.cjs → chunk-ONLWOUYZ.cjs} +4 -4
  41. package/dist/lib/node/{chunk-F735VMTN.cjs.map → chunk-ONLWOUYZ.cjs.map} +2 -2
  42. package/dist/lib/node/{chunk-BHFHFTHO.cjs → chunk-S2A6BXEA.cjs} +12 -9
  43. package/dist/lib/node/chunk-S2A6BXEA.cjs.map +7 -0
  44. package/dist/lib/node/index.cjs +78 -83
  45. package/dist/lib/node/index.cjs.map +4 -4
  46. package/dist/lib/node/{intent-resolver-DVBEXJ33.cjs → intent-resolver-S6FE5OR7.cjs} +153 -113
  47. package/dist/lib/node/intent-resolver-S6FE5OR7.cjs.map +7 -0
  48. package/dist/lib/node/{markdown-ELRGISXE.cjs → markdown-L2WMCQKM.cjs} +13 -14
  49. package/dist/lib/node/markdown-L2WMCQKM.cjs.map +7 -0
  50. package/dist/lib/node/meta.json +1 -1
  51. package/dist/lib/node/{react-surface-7HLTN5XS.cjs → react-surface-Z45BYECE.cjs} +68 -64
  52. package/dist/lib/node/react-surface-Z45BYECE.cjs.map +7 -0
  53. package/dist/lib/node/{settings-7VQYARM5.cjs → settings-IXCPE55J.cjs} +8 -8
  54. package/dist/lib/node/{state-TQWEZ6B3.cjs → state-AT73KPGZ.cjs} +8 -7
  55. package/dist/lib/node/state-AT73KPGZ.cjs.map +7 -0
  56. package/dist/lib/node/types.cjs +4 -4
  57. package/dist/lib/node/types.cjs.map +1 -1
  58. package/dist/lib/node-esm/ChatContainer-NYLCL6QA.mjs +139 -0
  59. package/dist/lib/node-esm/ChatContainer-NYLCL6QA.mjs.map +7 -0
  60. package/dist/lib/node-esm/app-graph-builder-M3KK5QJH.mjs +42 -0
  61. package/dist/lib/node-esm/app-graph-builder-M3KK5QJH.mjs.map +7 -0
  62. package/dist/lib/node-esm/{chunk-FXUATCLW.mjs → chunk-42F2DTMM.mjs} +1 -1
  63. package/dist/lib/node-esm/{chunk-FXUATCLW.mjs.map → chunk-42F2DTMM.mjs.map} +2 -2
  64. package/dist/lib/node-esm/{chunk-CISLDOH7.mjs → chunk-ADTVMESP.mjs} +35 -140
  65. package/dist/lib/node-esm/chunk-ADTVMESP.mjs.map +7 -0
  66. package/dist/lib/node-esm/{chunk-33NDMQQQ.mjs → chunk-E446MGLP.mjs} +25 -11
  67. package/dist/lib/node-esm/chunk-E446MGLP.mjs.map +7 -0
  68. package/dist/lib/node-esm/{chunk-HLWJTUWZ.mjs → chunk-J56FORYF.mjs} +14 -19
  69. package/dist/lib/node-esm/{chunk-HLWJTUWZ.mjs.map → chunk-J56FORYF.mjs.map} +3 -3
  70. package/dist/lib/node-esm/{chunk-ZJITX3TO.mjs → chunk-WLY2HMDB.mjs} +2 -2
  71. package/dist/lib/node-esm/chunk-WSE23GSG.mjs +19 -0
  72. package/dist/lib/node-esm/chunk-WSE23GSG.mjs.map +7 -0
  73. package/dist/lib/node-esm/index.mjs +47 -49
  74. package/dist/lib/node-esm/index.mjs.map +4 -4
  75. package/dist/lib/node-esm/{intent-resolver-DHVLBNCC.mjs → intent-resolver-OURFRSSF.mjs} +134 -94
  76. package/dist/lib/node-esm/intent-resolver-OURFRSSF.mjs.map +7 -0
  77. package/dist/lib/node-esm/{markdown-23OB7EZG.mjs → markdown-ZKU23UVD.mjs} +9 -10
  78. package/dist/lib/node-esm/markdown-ZKU23UVD.mjs.map +7 -0
  79. package/dist/lib/node-esm/meta.json +1 -1
  80. package/dist/lib/node-esm/{react-surface-AZHTTR6J.mjs → react-surface-KIJ767JK.mjs} +55 -51
  81. package/dist/lib/node-esm/react-surface-KIJ767JK.mjs.map +7 -0
  82. package/dist/lib/node-esm/{settings-SGMM7UDT.mjs → settings-ZUJQ4LWI.mjs} +3 -3
  83. package/dist/lib/node-esm/{state-7MLR27YG.mjs → state-SSDX5O67.mjs} +4 -3
  84. package/dist/lib/node-esm/state-SSDX5O67.mjs.map +7 -0
  85. package/dist/lib/node-esm/types.mjs +2 -2
  86. package/dist/types/src/ThreadPlugin.d.ts.map +1 -1
  87. package/dist/types/src/capabilities/app-graph-builder.d.ts +181 -0
  88. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
  89. package/dist/types/src/capabilities/index.d.ts +177 -0
  90. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  91. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
  92. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  93. package/dist/types/src/components/Chat.stories.d.ts.map +1 -1
  94. package/dist/types/src/components/ChatContainer.d.ts +10 -2
  95. package/dist/types/src/components/ChatContainer.d.ts.map +1 -1
  96. package/dist/types/src/components/CommentContainer.d.ts +2 -1
  97. package/dist/types/src/components/CommentContainer.d.ts.map +1 -1
  98. package/dist/types/src/components/Comments.stories.d.ts.map +1 -1
  99. package/dist/types/src/components/CommentsContainer.d.ts +2 -1
  100. package/dist/types/src/components/CommentsContainer.d.ts.map +1 -1
  101. package/dist/types/src/components/MessageContainer.d.ts +5 -3
  102. package/dist/types/src/components/MessageContainer.d.ts.map +1 -1
  103. package/dist/types/src/components/ThreadComplementary.d.ts +2 -1
  104. package/dist/types/src/components/ThreadComplementary.d.ts.map +1 -1
  105. package/dist/types/src/components/ThreadSettings.d.ts +2 -1
  106. package/dist/types/src/components/ThreadSettings.d.ts.map +1 -1
  107. package/dist/types/src/components/index.d.ts +1 -4
  108. package/dist/types/src/components/index.d.ts.map +1 -1
  109. package/dist/types/src/components/testing.d.ts +45 -40
  110. package/dist/types/src/components/testing.d.ts.map +1 -1
  111. package/dist/types/src/events.d.ts +4 -0
  112. package/dist/types/src/events.d.ts.map +1 -0
  113. package/dist/types/src/hooks/analytics.d.ts +2 -2
  114. package/dist/types/src/hooks/analytics.d.ts.map +1 -1
  115. package/dist/types/src/index.d.ts +2 -0
  116. package/dist/types/src/index.d.ts.map +1 -1
  117. package/dist/types/src/meta.d.ts +2 -7
  118. package/dist/types/src/meta.d.ts.map +1 -1
  119. package/dist/types/src/translations.d.ts +5 -12
  120. package/dist/types/src/translations.d.ts.map +1 -1
  121. package/dist/types/src/types.d.ts +40 -9
  122. package/dist/types/src/types.d.ts.map +1 -1
  123. package/package.json +33 -30
  124. package/src/ThreadPlugin.tsx +17 -28
  125. package/src/capabilities/app-graph-builder.ts +34 -0
  126. package/src/capabilities/index.ts +1 -0
  127. package/src/capabilities/intent-resolver.ts +97 -61
  128. package/src/capabilities/react-surface.tsx +29 -27
  129. package/src/capabilities/state.ts +1 -1
  130. package/src/components/Chat.stories.tsx +19 -9
  131. package/src/components/ChatContainer.tsx +29 -29
  132. package/src/components/CommentContainer.tsx +8 -2
  133. package/src/components/Comments.stories.tsx +2 -1
  134. package/src/components/MessageContainer.tsx +23 -17
  135. package/src/components/ThreadComplementary.tsx +26 -32
  136. package/src/components/index.ts +1 -2
  137. package/src/components/testing.ts +6 -29
  138. package/src/events.ts +11 -0
  139. package/src/extensions/threads.ts +3 -3
  140. package/src/hooks/analytics.ts +23 -18
  141. package/src/index.ts +2 -0
  142. package/src/meta.ts +2 -2
  143. package/src/translations.ts +2 -4
  144. package/src/types.ts +22 -8
  145. package/src/util.ts +1 -1
  146. package/dist/lib/browser/ThreadContainer-6OP5AG2W.mjs +0 -19
  147. package/dist/lib/browser/ThreadContainer-6OP5AG2W.mjs.map +0 -7
  148. package/dist/lib/browser/chunk-UPKU23DA.mjs.map +0 -7
  149. package/dist/lib/browser/chunk-VOMIDDNO.mjs +0 -15
  150. package/dist/lib/browser/chunk-VOMIDDNO.mjs.map +0 -7
  151. package/dist/lib/browser/chunk-YK3ICB7G.mjs.map +0 -7
  152. package/dist/lib/browser/intent-resolver-FAFQ54NP.mjs.map +0 -7
  153. package/dist/lib/browser/markdown-RPYOUBVR.mjs.map +0 -7
  154. package/dist/lib/browser/react-surface-Y4MUSICN.mjs.map +0 -7
  155. package/dist/lib/browser/state-GNFUURIC.mjs.map +0 -7
  156. package/dist/lib/node/ThreadContainer-LTKKLPXX.cjs +0 -45
  157. package/dist/lib/node/ThreadContainer-LTKKLPXX.cjs.map +0 -7
  158. package/dist/lib/node/chunk-AWSTZ2KN.cjs.map +0 -7
  159. package/dist/lib/node/chunk-BHFHFTHO.cjs.map +0 -7
  160. package/dist/lib/node/chunk-CMEMMYDL.cjs.map +0 -7
  161. package/dist/lib/node/chunk-RQR5Z23G.cjs +0 -331
  162. package/dist/lib/node/chunk-RQR5Z23G.cjs.map +0 -7
  163. package/dist/lib/node/intent-resolver-DVBEXJ33.cjs.map +0 -7
  164. package/dist/lib/node/markdown-ELRGISXE.cjs.map +0 -7
  165. package/dist/lib/node/react-surface-7HLTN5XS.cjs.map +0 -7
  166. package/dist/lib/node/state-TQWEZ6B3.cjs.map +0 -7
  167. package/dist/lib/node-esm/ThreadContainer-SV74JFRH.mjs +0 -20
  168. package/dist/lib/node-esm/ThreadContainer-SV74JFRH.mjs.map +0 -7
  169. package/dist/lib/node-esm/chunk-33NDMQQQ.mjs.map +0 -7
  170. package/dist/lib/node-esm/chunk-CISLDOH7.mjs.map +0 -7
  171. package/dist/lib/node-esm/chunk-PJPVEO7E.mjs +0 -17
  172. package/dist/lib/node-esm/chunk-PJPVEO7E.mjs.map +0 -7
  173. package/dist/lib/node-esm/intent-resolver-DHVLBNCC.mjs.map +0 -7
  174. package/dist/lib/node-esm/markdown-23OB7EZG.mjs.map +0 -7
  175. package/dist/lib/node-esm/react-surface-AZHTTR6J.mjs.map +0 -7
  176. package/dist/lib/node-esm/state-7MLR27YG.mjs.map +0 -7
  177. package/dist/types/src/components/ThreadContainer.d.ts +0 -7
  178. package/dist/types/src/components/ThreadContainer.d.ts.map +0 -1
  179. package/src/components/ThreadContainer.tsx +0 -22
  180. /package/dist/lib/browser/{chunk-NAO3LZMZ.mjs.map → chunk-EP6MRLY7.mjs.map} +0 -0
  181. /package/dist/lib/browser/{settings-WQTE5AEZ.mjs.map → settings-4FEC7EAX.mjs.map} +0 -0
  182. /package/dist/lib/node/{chunk-FPWNZ6TB.cjs.map → chunk-NQ5DTPOY.cjs.map} +0 -0
  183. /package/dist/lib/node/{settings-7VQYARM5.cjs.map → settings-IXCPE55J.cjs.map} +0 -0
  184. /package/dist/lib/node-esm/{chunk-ZJITX3TO.mjs.map → chunk-WLY2HMDB.mjs.map} +0 -0
  185. /package/dist/lib/node-esm/{settings-SGMM7UDT.mjs.map → settings-ZUJQ4LWI.mjs.map} +0 -0
@@ -0,0 +1,138 @@
1
+ import {
2
+ MessageContainer,
3
+ command,
4
+ getMessageMetadata
5
+ } from "./chunk-TFVPUPOO.mjs";
6
+ import {
7
+ useStatus
8
+ } from "./chunk-QDJ3Y6WF.mjs";
9
+ import {
10
+ THREAD_PLUGIN
11
+ } from "./chunk-WBJLUUOK.mjs";
12
+
13
+ // packages/plugins/plugin-thread/src/components/ChatContainer.tsx
14
+ import React, { useLayoutEffect, useMemo, useRef, useState } from "react";
15
+ import { createStatic } from "@dxos/echo-schema";
16
+ import { makeRef } from "@dxos/live-object";
17
+ import { useMembers, useQueue } from "@dxos/react-client/echo";
18
+ import { useIdentity } from "@dxos/react-client/halo";
19
+ import { Icon, ScrollArea, useThemeContext, useTranslation } from "@dxos/react-ui";
20
+ import { createBasicExtensions, createThemeExtensions, listener } from "@dxos/react-ui-editor";
21
+ import { StackItem } from "@dxos/react-ui-stack";
22
+ import { mx } from "@dxos/react-ui-theme";
23
+ import { MessageTextbox, Thread, ThreadFooter, threadLayout } from "@dxos/react-ui-thread";
24
+ import { MessageType } from "@dxos/schema";
25
+ var ChatHeading = ({ attendableId }) => {
26
+ const { t } = useTranslation(THREAD_PLUGIN);
27
+ return /* @__PURE__ */ React.createElement("div", {
28
+ role: "none",
29
+ className: "flex items-center"
30
+ }, /* @__PURE__ */ React.createElement(StackItem.SigilButton, {
31
+ attendableId
32
+ }, /* @__PURE__ */ React.createElement(Icon, {
33
+ icon: "ph--chat--regular",
34
+ size: 5
35
+ })), /* @__PURE__ */ React.createElement(StackItem.HeadingLabel, {
36
+ attendableId
37
+ }, t("chat heading")));
38
+ };
39
+ var ChatContainer = ({ space, dxn, context, current, autoFocusTextbox }) => {
40
+ const id = dxn.toString();
41
+ const identity = useIdentity();
42
+ const members = useMembers(space?.key);
43
+ const queue = useQueue(dxn, {
44
+ pollInterval: 1e3
45
+ });
46
+ const activity = useStatus(space, id);
47
+ const { t } = useTranslation(THREAD_PLUGIN);
48
+ const [_count, _setCount] = useState(0);
49
+ const rerenderEditor = () => _setCount((count) => count + 1);
50
+ const [autoFocus, setAutoFocus] = useState(autoFocusTextbox);
51
+ const threadScrollRef = useRef(null);
52
+ const { themeMode } = useThemeContext();
53
+ const textboxMetadata = getMessageMetadata(id, identity);
54
+ const messageRef = useRef("");
55
+ const extensions = useMemo(() => [
56
+ createBasicExtensions({
57
+ placeholder: t("message placeholder")
58
+ }),
59
+ createThemeExtensions({
60
+ themeMode
61
+ }),
62
+ listener({
63
+ onChange: (text) => messageRef.current = text
64
+ }),
65
+ command
66
+ ], [
67
+ themeMode,
68
+ _count
69
+ ]);
70
+ const scrollToEnd = (behavior) => setTimeout(() => threadScrollRef.current?.scrollIntoView({
71
+ behavior,
72
+ block: "end"
73
+ }), 10);
74
+ useLayoutEffect(() => {
75
+ scrollToEnd("instant");
76
+ }, []);
77
+ const handleCreate = () => {
78
+ if (!messageRef.current?.length || !queue) {
79
+ return false;
80
+ }
81
+ queue.append([
82
+ createStatic(MessageType, {
83
+ sender: {
84
+ identityDid: identity.did
85
+ },
86
+ created: (/* @__PURE__ */ new Date()).toISOString(),
87
+ blocks: [
88
+ {
89
+ type: "text",
90
+ text: messageRef.current
91
+ }
92
+ ],
93
+ properties: context ? {
94
+ context: makeRef(context)
95
+ } : void 0
96
+ })
97
+ ]);
98
+ messageRef.current = "";
99
+ setAutoFocus(true);
100
+ scrollToEnd("smooth");
101
+ rerenderEditor();
102
+ return true;
103
+ };
104
+ return /* @__PURE__ */ React.createElement(Thread, {
105
+ current,
106
+ id,
107
+ classNames: "bs-full grid-rows-[1fr_min-content_min-content] overflow-hidden transition-[padding-block-end] [[data-sidebar-inline-start-state=open]_&]:lg:pbe-0"
108
+ }, /* @__PURE__ */ React.createElement(ScrollArea.Root, {
109
+ classNames: "col-span-2"
110
+ }, /* @__PURE__ */ React.createElement(ScrollArea.Viewport, {
111
+ classNames: "overflow-anchored after:overflow-anchor after:block after:bs-px after:-mbs-px [&>div]:min-bs-full [&>div]:!grid [&>div]:grid-rows-[1fr_0]"
112
+ }, /* @__PURE__ */ React.createElement("div", {
113
+ role: "none",
114
+ className: mx(threadLayout, "place-self-end")
115
+ }, (queue?.items ?? []).map((message) => /* @__PURE__ */ React.createElement(MessageContainer, {
116
+ key: message.id,
117
+ message,
118
+ members
119
+ }))), /* @__PURE__ */ React.createElement("div", {
120
+ role: "none",
121
+ className: "bs-px -mbs-px",
122
+ ref: threadScrollRef
123
+ }), /* @__PURE__ */ React.createElement(ScrollArea.Scrollbar, null, /* @__PURE__ */ React.createElement(ScrollArea.Thumb, null)))), /* @__PURE__ */ React.createElement(MessageTextbox, {
124
+ extensions,
125
+ autoFocus,
126
+ onSend: handleCreate,
127
+ ...textboxMetadata
128
+ }), /* @__PURE__ */ React.createElement(ThreadFooter, {
129
+ activity
130
+ }, t("activity message")));
131
+ };
132
+ var ChatContainer_default = ChatContainer;
133
+ export {
134
+ ChatContainer,
135
+ ChatHeading,
136
+ ChatContainer_default as default
137
+ };
138
+ //# sourceMappingURL=ChatContainer-IOOAQW6S.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/components/ChatContainer.tsx"],
4
+ "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport React, { useLayoutEffect, useMemo, useRef, useState } from 'react';\n\nimport { createStatic } from '@dxos/echo-schema';\nimport { type DXN } from '@dxos/keys';\nimport { makeRef } from '@dxos/live-object';\nimport { type Space, useMembers, useQueue } from '@dxos/react-client/echo';\nimport { useIdentity } from '@dxos/react-client/halo';\nimport { Icon, ScrollArea, useThemeContext, useTranslation } from '@dxos/react-ui';\nimport { createBasicExtensions, createThemeExtensions, listener } from '@dxos/react-ui-editor';\nimport { StackItem } from '@dxos/react-ui-stack';\nimport { mx } from '@dxos/react-ui-theme';\nimport { MessageTextbox, type MessageTextboxProps, Thread, ThreadFooter, threadLayout } from '@dxos/react-ui-thread';\nimport { MessageType } from '@dxos/schema';\n\nimport { MessageContainer } from './MessageContainer';\nimport { command } from './command-extension';\nimport { type ThreadContainerProps } from './types';\nimport { useStatus } from '../hooks';\nimport { THREAD_PLUGIN } from '../meta';\nimport { getMessageMetadata } from '../util';\n\nexport const ChatHeading = ({ attendableId }: { attendableId?: string }) => {\n const { t } = useTranslation(THREAD_PLUGIN);\n return (\n <div role='none' className='flex items-center'>\n <StackItem.SigilButton attendableId={attendableId}>\n <Icon icon='ph--chat--regular' size={5} />\n </StackItem.SigilButton>\n <StackItem.HeadingLabel attendableId={attendableId}>{t('chat heading')}</StackItem.HeadingLabel>\n </div>\n );\n};\n\nexport type ChatContainerProps = Omit<ThreadContainerProps, 'thread'> & {\n space: Space;\n dxn: DXN;\n};\n\nexport const ChatContainer = ({ space, dxn, context, current, autoFocusTextbox }: ChatContainerProps) => {\n const id = dxn.toString();\n const identity = useIdentity()!;\n const members = useMembers(space?.key);\n const queue = useQueue<MessageType>(dxn, { pollInterval: 1_000 });\n const activity = useStatus(space, id);\n const { t } = useTranslation(THREAD_PLUGIN);\n // TODO(wittjosiah): This is a hack to reset the editor after a message is sent.\n const [_count, _setCount] = useState(0);\n const rerenderEditor = () => _setCount((count) => count + 1);\n const [autoFocus, setAutoFocus] = useState(autoFocusTextbox);\n const threadScrollRef = useRef<HTMLDivElement | null>(null);\n const { themeMode } = useThemeContext();\n\n const textboxMetadata = getMessageMetadata(id, identity);\n const messageRef = useRef('');\n const extensions = useMemo(\n () => [\n createBasicExtensions({ placeholder: t('message placeholder') }),\n createThemeExtensions({ themeMode }),\n listener({ onChange: (text) => (messageRef.current = text) }),\n command,\n ],\n [themeMode, _count],\n );\n\n // TODO(thure): Factor out.\n // TODO(thure): `flex-col-reverse` does not work to start the container scrolled to the end while also using\n // `ScrollArea`. This is the least-bad way I found to scroll to the end on mount. Note that 0ms was insufficient\n // for the desired effect; this is likely hardware-dependent and should be reevaluated.\n const scrollToEnd = (behavior: ScrollBehavior) =>\n setTimeout(() => threadScrollRef.current?.scrollIntoView({ behavior, block: 'end' }), 10);\n\n useLayoutEffect(() => {\n scrollToEnd('instant');\n }, []);\n\n // TODO(burdon): Change to model.\n const handleCreate: MessageTextboxProps['onSend'] = () => {\n if (!messageRef.current?.length || !queue) {\n return false;\n }\n\n queue.append([\n createStatic(MessageType, {\n sender: { identityDid: identity.did },\n created: new Date().toISOString(),\n blocks: [{ type: 'text', text: messageRef.current }],\n properties: context ? { context: makeRef(context) } : undefined,\n }),\n ]);\n\n messageRef.current = '';\n setAutoFocus(true);\n scrollToEnd('smooth');\n rerenderEditor();\n return true;\n };\n\n return (\n <Thread\n current={current}\n id={id}\n classNames='bs-full grid-rows-[1fr_min-content_min-content] overflow-hidden transition-[padding-block-end] [[data-sidebar-inline-start-state=open]_&]:lg:pbe-0'\n >\n <ScrollArea.Root classNames='col-span-2'>\n <ScrollArea.Viewport classNames='overflow-anchored after:overflow-anchor after:block after:bs-px after:-mbs-px [&>div]:min-bs-full [&>div]:!grid [&>div]:grid-rows-[1fr_0]'>\n <div role='none' className={mx(threadLayout, 'place-self-end')}>\n {(queue?.items ?? []).map((message) => (\n <MessageContainer key={message.id} message={message} members={members} />\n ))}\n </div>\n {/* NOTE(thure): This can’t also be the `overflow-anchor` because `ScrollArea` injects an interceding node that contains this necessary ref’d element. */}\n <div role='none' className='bs-px -mbs-px' ref={threadScrollRef} />\n <ScrollArea.Scrollbar>\n <ScrollArea.Thumb />\n </ScrollArea.Scrollbar>\n </ScrollArea.Viewport>\n </ScrollArea.Root>\n <MessageTextbox extensions={extensions} autoFocus={autoFocus} onSend={handleCreate} {...textboxMetadata} />\n <ThreadFooter activity={activity}>{t('activity message')}</ThreadFooter>\n </Thread>\n );\n};\n\nexport default ChatContainer;\n"],
5
+ "mappings": "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",
6
+ "names": ["React", "useLayoutEffect", "useMemo", "useRef", "useState", "createStatic", "makeRef", "useMembers", "useQueue", "useIdentity", "Icon", "ScrollArea", "useThemeContext", "useTranslation", "createBasicExtensions", "createThemeExtensions", "listener", "StackItem", "mx", "MessageTextbox", "Thread", "ThreadFooter", "threadLayout", "MessageType", "ChatHeading", "attendableId", "t", "useTranslation", "THREAD_PLUGIN", "div", "role", "className", "StackItem", "SigilButton", "Icon", "icon", "size", "HeadingLabel", "ChatContainer", "space", "dxn", "context", "current", "autoFocusTextbox", "id", "toString", "identity", "useIdentity", "members", "useMembers", "key", "queue", "useQueue", "pollInterval", "activity", "useStatus", "_count", "_setCount", "useState", "rerenderEditor", "count", "autoFocus", "setAutoFocus", "threadScrollRef", "useRef", "themeMode", "useThemeContext", "textboxMetadata", "getMessageMetadata", "messageRef", "extensions", "useMemo", "createBasicExtensions", "placeholder", "createThemeExtensions", "listener", "onChange", "text", "command", "scrollToEnd", "behavior", "setTimeout", "scrollIntoView", "block", "useLayoutEffect", "handleCreate", "length", "append", "createStatic", "MessageType", "sender", "identityDid", "did", "created", "Date", "toISOString", "blocks", "type", "properties", "makeRef", "undefined", "Thread", "classNames", "ScrollArea", "Root", "Viewport", "mx", "threadLayout", "items", "map", "message", "MessageContainer", "ref", "Scrollbar", "Thumb", "MessageTextbox", "onSend", "ThreadFooter"]
7
+ }
@@ -0,0 +1,41 @@
1
+ import {
2
+ meta
3
+ } from "./chunk-WBJLUUOK.mjs";
4
+
5
+ // packages/plugins/plugin-thread/src/capabilities/app-graph-builder.ts
6
+ import { Capabilities, contributes } from "@dxos/app-framework";
7
+ import { PLANK_COMPANION_TYPE, ATTENDABLE_PATH_SEPARATOR } from "@dxos/plugin-deck/types";
8
+ import { createExtension } from "@dxos/plugin-graph";
9
+ var app_graph_builder_default = (context) => contributes(Capabilities.AppGraphBuilder, [
10
+ createExtension({
11
+ id: `${meta.id}/comments`,
12
+ // TODO(wittjosiah): Support comments on any object.
13
+ // filter: (node): node is Node<ReactiveEchoObject<any>> => isEchoObject(node.data),
14
+ filter: (node) => !!node.data && typeof node.data === "object" && "threads" in node.data && Array.isArray(node.data.threads),
15
+ connector: ({ node }) => [
16
+ {
17
+ id: [
18
+ node.id,
19
+ "comments"
20
+ ].join(ATTENDABLE_PATH_SEPARATOR),
21
+ type: PLANK_COMPANION_TYPE,
22
+ data: "comments",
23
+ properties: {
24
+ label: [
25
+ "comments label",
26
+ {
27
+ ns: meta.id
28
+ }
29
+ ],
30
+ icon: "ph--chat-text--regular",
31
+ disposition: "hidden",
32
+ position: "hoist"
33
+ }
34
+ }
35
+ ]
36
+ })
37
+ ]);
38
+ export {
39
+ app_graph_builder_default as default
40
+ };
41
+ //# sourceMappingURL=app-graph-builder-6W4UKJDI.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/capabilities/app-graph-builder.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { Capabilities, contributes, type PluginsContext } from '@dxos/app-framework';\nimport { type ReactiveEchoObject } from '@dxos/client/echo';\nimport { PLANK_COMPANION_TYPE, ATTENDABLE_PATH_SEPARATOR } from '@dxos/plugin-deck/types';\nimport { createExtension, type Node } from '@dxos/plugin-graph';\n\nimport { meta } from '../meta';\n\nexport default (context: PluginsContext) =>\n contributes(Capabilities.AppGraphBuilder, [\n createExtension({\n id: `${meta.id}/comments`,\n // TODO(wittjosiah): Support comments on any object.\n // filter: (node): node is Node<ReactiveEchoObject<any>> => isEchoObject(node.data),\n filter: (node): node is Node<ReactiveEchoObject<any>> =>\n !!node.data && typeof node.data === 'object' && 'threads' in node.data && Array.isArray(node.data.threads),\n connector: ({ node }) => [\n {\n id: [node.id, 'comments'].join(ATTENDABLE_PATH_SEPARATOR),\n type: PLANK_COMPANION_TYPE,\n data: 'comments',\n properties: {\n label: ['comments label', { ns: meta.id }],\n icon: 'ph--chat-text--regular',\n disposition: 'hidden',\n position: 'hoist',\n },\n },\n ],\n }),\n ]);\n"],
5
+ "mappings": ";;;;;AAIA,SAASA,cAAcC,mBAAwC;AAE/D,SAASC,sBAAsBC,iCAAiC;AAChE,SAASC,uBAAkC;AAI3C,IAAA,4BAAe,CAACC,YACdC,YAAYC,aAAaC,iBAAiB;EACxCC,gBAAgB;IACdC,IAAI,GAAGC,KAAKD,EAAE;;;IAGdE,QAAQ,CAACC,SACP,CAAC,CAACA,KAAKC,QAAQ,OAAOD,KAAKC,SAAS,YAAY,aAAaD,KAAKC,QAAQC,MAAMC,QAAQH,KAAKC,KAAKG,OAAO;IAC3GC,WAAW,CAAC,EAAEL,KAAI,MAAO;MACvB;QACEH,IAAI;UAACG,KAAKH;UAAI;UAAYS,KAAKC,yBAAAA;QAC/BC,MAAMC;QACNR,MAAM;QACNS,YAAY;UACVC,OAAO;YAAC;YAAkB;cAAEC,IAAId,KAAKD;YAAG;;UACxCgB,MAAM;UACNC,aAAa;UACbC,UAAU;QACZ;MACF;;EAEJ,CAAA;CACD;",
6
+ "names": ["Capabilities", "contributes", "PLANK_COMPANION_TYPE", "ATTENDABLE_PATH_SEPARATOR", "createExtension", "context", "contributes", "Capabilities", "AppGraphBuilder", "createExtension", "id", "meta", "filter", "node", "data", "Array", "isArray", "threads", "connector", "join", "ATTENDABLE_PATH_SEPARATOR", "type", "PLANK_COMPANION_TYPE", "properties", "label", "ns", "icon", "disposition", "position"]
7
+ }
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  THREAD_PLUGIN
3
- } from "./chunk-636QDHE3.mjs";
3
+ } from "./chunk-WBJLUUOK.mjs";
4
4
 
5
5
  // packages/plugins/plugin-thread/src/capabilities/capabilities.ts
6
6
  import { defineCapability } from "@dxos/app-framework";
@@ -13,4 +13,4 @@ var ThreadCapabilities;
13
13
  export {
14
14
  ThreadCapabilities
15
15
  };
16
- //# sourceMappingURL=chunk-NAO3LZMZ.mjs.map
16
+ //# sourceMappingURL=chunk-EP6MRLY7.mjs.map
@@ -36,36 +36,31 @@ import { createIntent, useIntentDispatcher } from "@dxos/app-framework";
36
36
  import { ObservabilityAction } from "@dxos/plugin-observability/types";
37
37
  import { getSpace } from "@dxos/react-client/echo";
38
38
  import { useOnTransition } from "@dxos/react-ui";
39
- var useAnalyticsCallback = (spaceId, name, meta) => {
39
+ var useOnEditAnalytics = (message, textBlock, editing) => {
40
40
  const { dispatchPromise: dispatch } = useIntentDispatcher();
41
- return useCallback((dynamicMeta) => {
41
+ const onEdit = useCallback(() => {
42
+ const space = getSpace(message);
43
+ if (!space || !textBlock) {
44
+ return;
45
+ }
42
46
  void dispatch(createIntent(ObservabilityAction.SendEvent, {
43
- name,
47
+ name: "threads.message.update",
44
48
  properties: {
45
- ...meta,
46
- ...dynamicMeta,
47
- spaceId
49
+ spaceId: space.id,
50
+ messageId: message.id,
51
+ messageLength: textBlock?.text.length
48
52
  }
49
53
  }));
50
54
  }, [
51
55
  dispatch,
52
- name,
53
- meta,
54
- spaceId
56
+ message,
57
+ textBlock
55
58
  ]);
56
- };
57
- var useOnEditAnalytics = (message, editing) => {
58
- const space = getSpace(message);
59
- const onEditAnalytics = useAnalyticsCallback(space?.id, "threads.comment-edited", {
60
- messageId: message.id,
61
- messageLength: message.text.length
62
- });
63
- useOnTransition(editing, true, false, onEditAnalytics);
59
+ useOnTransition(editing, true, false, onEdit);
64
60
  };
65
61
 
66
62
  export {
67
63
  useStatus,
68
- useAnalyticsCallback,
69
64
  useOnEditAnalytics
70
65
  };
71
- //# sourceMappingURL=chunk-BNEWNQBO.mjs.map
66
+ //# sourceMappingURL=chunk-QDJ3Y6WF.mjs.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/hooks/useStatus.ts", "../../../src/hooks/analytics.ts"],
4
- "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { useEffect, useState } from 'react';\n\nimport { type Space } from '@dxos/react-client/echo';\n\n// TODO(burdon): Generalize and factor out.\nexport const useStatus = (space?: Space, channel?: string) => {\n const [processing, setProcessing] = useState(false);\n useEffect(() => {\n if (!space || !channel) {\n return;\n }\n\n const unsubscribe = space.listen(`status/${channel}`, (status) => {\n const { event } = status.payload ?? {};\n setProcessing(event === 'processing');\n });\n\n const t = setInterval(() => {\n setProcessing((prev: any) => {\n if (typeof prev?.ts === 'number' && Date.now() - prev.ts > 30_000) {\n return undefined;\n } else {\n return prev;\n }\n });\n }, 1_000);\n\n return () => {\n unsubscribe();\n clearInterval(t);\n };\n }, [space, channel]);\n\n return processing;\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { useCallback } from 'react';\n\nimport { createIntent, useIntentDispatcher } from '@dxos/app-framework';\nimport { type ReactiveObject } from '@dxos/live-object';\nimport { ObservabilityAction } from '@dxos/plugin-observability/types';\nimport { getSpace } from '@dxos/react-client/echo';\nimport { useOnTransition } from '@dxos/react-ui';\n\nexport const useAnalyticsCallback = (spaceId: string | undefined, name: string, meta?: any) => {\n const { dispatchPromise: dispatch } = useIntentDispatcher();\n\n return useCallback(\n (dynamicMeta?: any) => {\n void dispatch(\n createIntent(ObservabilityAction.SendEvent, { name, properties: { ...meta, ...dynamicMeta, spaceId } }),\n );\n },\n [dispatch, name, meta, spaceId],\n );\n};\n\nexport const useOnEditAnalytics = (message: ReactiveObject<any>, editing: boolean) => {\n const space = getSpace(message);\n\n const onEditAnalytics = useAnalyticsCallback(space?.id, 'threads.comment-edited', {\n messageId: message.id,\n messageLength: message.text.length,\n });\n\n useOnTransition(editing, true, false, onEditAnalytics);\n};\n"],
5
- "mappings": ";AAIA,SAASA,WAAWC,gBAAgB;AAK7B,IAAMC,YAAY,CAACC,OAAeC,YAAAA;AACvC,QAAM,CAACC,YAAYC,aAAAA,IAAiBC,SAAS,KAAA;AAC7CC,YAAU,MAAA;AACR,QAAI,CAACL,SAAS,CAACC,SAAS;AACtB;IACF;AAEA,UAAMK,cAAcN,MAAMO,OAAO,UAAUN,OAAAA,IAAW,CAACO,WAAAA;AACrD,YAAM,EAAEC,MAAK,IAAKD,OAAOE,WAAW,CAAC;AACrCP,oBAAcM,UAAU,YAAA;IAC1B,CAAA;AAEA,UAAME,IAAIC,YAAY,MAAA;AACpBT,oBAAc,CAACU,SAAAA;AACb,YAAI,OAAOA,MAAMC,OAAO,YAAYC,KAAKC,IAAG,IAAKH,KAAKC,KAAK,KAAQ;AACjE,iBAAOG;QACT,OAAO;AACL,iBAAOJ;QACT;MACF,CAAA;IACF,GAAG,GAAA;AAEH,WAAO,MAAA;AACLP,kBAAAA;AACAY,oBAAcP,CAAAA;IAChB;EACF,GAAG;IAACX;IAAOC;GAAQ;AAEnB,SAAOC;AACT;;;AClCA,SAASiB,mBAAmB;AAE5B,SAASC,cAAcC,2BAA2B;AAElD,SAASC,2BAA2B;AACpC,SAASC,gBAAgB;AACzB,SAASC,uBAAuB;AAEzB,IAAMC,uBAAuB,CAACC,SAA6BC,MAAcC,SAAAA;AAC9E,QAAM,EAAEC,iBAAiBC,SAAQ,IAAKC,oBAAAA;AAEtC,SAAOC,YACL,CAACC,gBAAAA;AACC,SAAKH,SACHI,aAAaC,oBAAoBC,WAAW;MAAET;MAAMU,YAAY;QAAE,GAAGT;QAAM,GAAGK;QAAaP;MAAQ;IAAE,CAAA,CAAA;EAEzG,GACA;IAACI;IAAUH;IAAMC;IAAMF;GAAQ;AAEnC;AAEO,IAAMY,qBAAqB,CAACC,SAA8BC,YAAAA;AAC/D,QAAMC,QAAQC,SAASH,OAAAA;AAEvB,QAAMI,kBAAkBlB,qBAAqBgB,OAAOG,IAAI,0BAA0B;IAChFC,WAAWN,QAAQK;IACnBE,eAAeP,QAAQQ,KAAKC;EAC9B,CAAA;AAEAC,kBAAgBT,SAAS,MAAM,OAAOG,eAAAA;AACxC;",
6
- "names": ["useEffect", "useState", "useStatus", "space", "channel", "processing", "setProcessing", "useState", "useEffect", "unsubscribe", "listen", "status", "event", "payload", "t", "setInterval", "prev", "ts", "Date", "now", "undefined", "clearInterval", "useCallback", "createIntent", "useIntentDispatcher", "ObservabilityAction", "getSpace", "useOnTransition", "useAnalyticsCallback", "spaceId", "name", "meta", "dispatchPromise", "dispatch", "useIntentDispatcher", "useCallback", "dynamicMeta", "createIntent", "ObservabilityAction", "SendEvent", "properties", "useOnEditAnalytics", "message", "editing", "space", "getSpace", "onEditAnalytics", "id", "messageId", "messageLength", "text", "length", "useOnTransition"]
4
+ "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { useEffect, useState } from 'react';\n\nimport { type Space } from '@dxos/react-client/echo';\n\n// TODO(burdon): Generalize and factor out.\nexport const useStatus = (space?: Space, channel?: string) => {\n const [processing, setProcessing] = useState(false);\n useEffect(() => {\n if (!space || !channel) {\n return;\n }\n\n const unsubscribe = space.listen(`status/${channel}`, (status) => {\n const { event } = status.payload ?? {};\n setProcessing(event === 'processing');\n });\n\n const t = setInterval(() => {\n setProcessing((prev: any) => {\n if (typeof prev?.ts === 'number' && Date.now() - prev.ts > 30_000) {\n return undefined;\n } else {\n return prev;\n }\n });\n }, 1_000);\n\n return () => {\n unsubscribe();\n clearInterval(t);\n };\n }, [space, channel]);\n\n return processing;\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { useCallback } from 'react';\n\nimport { createIntent, useIntentDispatcher } from '@dxos/app-framework';\nimport { type ReactiveObject } from '@dxos/live-object';\nimport { ObservabilityAction } from '@dxos/plugin-observability/types';\nimport { getSpace } from '@dxos/react-client/echo';\nimport { useOnTransition } from '@dxos/react-ui';\nimport { type TextContentBlock } from '@dxos/schema';\n\nexport const useOnEditAnalytics = (\n message: ReactiveObject<any>,\n textBlock: TextContentBlock | undefined,\n editing: boolean,\n) => {\n const { dispatchPromise: dispatch } = useIntentDispatcher();\n\n const onEdit = useCallback(() => {\n const space = getSpace(message);\n if (!space || !textBlock) {\n return;\n }\n\n void dispatch(\n createIntent(ObservabilityAction.SendEvent, {\n name: 'threads.message.update',\n properties: {\n spaceId: space.id,\n messageId: message.id,\n messageLength: textBlock?.text.length,\n },\n }),\n );\n }, [dispatch, message, textBlock]);\n\n useOnTransition(editing, true, false, onEdit);\n};\n"],
5
+ "mappings": ";AAIA,SAASA,WAAWC,gBAAgB;AAK7B,IAAMC,YAAY,CAACC,OAAeC,YAAAA;AACvC,QAAM,CAACC,YAAYC,aAAAA,IAAiBC,SAAS,KAAA;AAC7CC,YAAU,MAAA;AACR,QAAI,CAACL,SAAS,CAACC,SAAS;AACtB;IACF;AAEA,UAAMK,cAAcN,MAAMO,OAAO,UAAUN,OAAAA,IAAW,CAACO,WAAAA;AACrD,YAAM,EAAEC,MAAK,IAAKD,OAAOE,WAAW,CAAC;AACrCP,oBAAcM,UAAU,YAAA;IAC1B,CAAA;AAEA,UAAME,IAAIC,YAAY,MAAA;AACpBT,oBAAc,CAACU,SAAAA;AACb,YAAI,OAAOA,MAAMC,OAAO,YAAYC,KAAKC,IAAG,IAAKH,KAAKC,KAAK,KAAQ;AACjE,iBAAOG;QACT,OAAO;AACL,iBAAOJ;QACT;MACF,CAAA;IACF,GAAG,GAAA;AAEH,WAAO,MAAA;AACLP,kBAAAA;AACAY,oBAAcP,CAAAA;IAChB;EACF,GAAG;IAACX;IAAOC;GAAQ;AAEnB,SAAOC;AACT;;;AClCA,SAASiB,mBAAmB;AAE5B,SAASC,cAAcC,2BAA2B;AAElD,SAASC,2BAA2B;AACpC,SAASC,gBAAgB;AACzB,SAASC,uBAAuB;AAGzB,IAAMC,qBAAqB,CAChCC,SACAC,WACAC,YAAAA;AAEA,QAAM,EAAEC,iBAAiBC,SAAQ,IAAKC,oBAAAA;AAEtC,QAAMC,SAASC,YAAY,MAAA;AACzB,UAAMC,QAAQC,SAAST,OAAAA;AACvB,QAAI,CAACQ,SAAS,CAACP,WAAW;AACxB;IACF;AAEA,SAAKG,SACHM,aAAaC,oBAAoBC,WAAW;MAC1CC,MAAM;MACNC,YAAY;QACVC,SAASP,MAAMQ;QACfC,WAAWjB,QAAQgB;QACnBE,eAAejB,WAAWkB,KAAKC;MACjC;IACF,CAAA,CAAA;EAEJ,GAAG;IAAChB;IAAUJ;IAASC;GAAU;AAEjCoB,kBAAgBnB,SAAS,MAAM,OAAOI,MAAAA;AACxC;",
6
+ "names": ["useEffect", "useState", "useStatus", "space", "channel", "processing", "setProcessing", "useState", "useEffect", "unsubscribe", "listen", "status", "event", "payload", "t", "setInterval", "prev", "ts", "Date", "now", "undefined", "clearInterval", "useCallback", "createIntent", "useIntentDispatcher", "ObservabilityAction", "getSpace", "useOnTransition", "useOnEditAnalytics", "message", "textBlock", "editing", "dispatchPromise", "dispatch", "useIntentDispatcher", "onEdit", "useCallback", "space", "getSpace", "createIntent", "ObservabilityAction", "SendEvent", "name", "properties", "spaceId", "id", "messageId", "messageLength", "text", "length", "useOnTransition"]
7
7
  }
@@ -0,0 +1,17 @@
1
+ // packages/plugins/plugin-thread/src/capabilities/index.ts
2
+ import { lazy } from "@dxos/app-framework";
3
+ var AppGraphBuilder = lazy(() => import("./app-graph-builder-6W4UKJDI.mjs"));
4
+ var IntentResolver = lazy(() => import("./intent-resolver-QAY4FLLM.mjs"));
5
+ var Markdown = lazy(() => import("./markdown-7KXBXCUS.mjs"));
6
+ var ReactSurface = lazy(() => import("./react-surface-MT3OWULR.mjs"));
7
+ var ThreadSettings = lazy(() => import("./settings-4FEC7EAX.mjs"));
8
+ var ThreadState = lazy(() => import("./state-PNMSLKAH.mjs"));
9
+
10
+ export {
11
+ AppGraphBuilder,
12
+ IntentResolver,
13
+ Markdown,
14
+ ReactSurface,
15
+ ThreadState
16
+ };
17
+ //# sourceMappingURL=chunk-S5ZR4FYW.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/capabilities/index.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { lazy } from '@dxos/app-framework';\n\nexport const AppGraphBuilder = lazy(() => import('./app-graph-builder'));\nexport const IntentResolver = lazy(() => import('./intent-resolver'));\nexport const Markdown = lazy(() => import('./markdown'));\nexport const ReactSurface = lazy(() => import('./react-surface'));\nexport const ThreadSettings = lazy(() => import('./settings'));\nexport const ThreadState = lazy(() => import('./state'));\n\nexport * from './capabilities';\n"],
5
+ "mappings": ";AAIA,SAASA,YAAY;AAEd,IAAMC,kBAAkBC,KAAK,MAAM,OAAO,kCAAA,CAAA;AAC1C,IAAMC,iBAAiBD,KAAK,MAAM,OAAO,gCAAA,CAAA;AACzC,IAAME,WAAWF,KAAK,MAAM,OAAO,yBAAA,CAAA;AACnC,IAAMG,eAAeH,KAAK,MAAM,OAAO,8BAAA,CAAA;AACvC,IAAMI,iBAAiBJ,KAAK,MAAM,OAAO,yBAAA,CAAA;AACzC,IAAMK,cAAcL,KAAK,MAAM,OAAO,sBAAA,CAAA;",
6
+ "names": ["lazy", "AppGraphBuilder", "lazy", "IntentResolver", "Markdown", "ReactSurface", "ThreadSettings", "ThreadState"]
7
+ }
@@ -1,36 +1,9 @@
1
1
  import {
2
- useOnEditAnalytics,
3
- useStatus
4
- } from "./chunk-BNEWNQBO.mjs";
2
+ useOnEditAnalytics
3
+ } from "./chunk-QDJ3Y6WF.mjs";
5
4
  import {
6
5
  THREAD_PLUGIN
7
- } from "./chunk-636QDHE3.mjs";
8
-
9
- // packages/plugins/plugin-thread/src/components/ChatContainer.tsx
10
- import React2, { useLayoutEffect, useMemo, useRef as useRef2, useState as useState2 } from "react";
11
- import { Ref } from "@dxos/echo-schema";
12
- import { create, makeRef, RefArray as RefArray2 } from "@dxos/live-object";
13
- import { MessageType } from "@dxos/plugin-space/types";
14
- import { fullyQualifiedId, getSpace, useMembers } from "@dxos/react-client/echo";
15
- import { useIdentity as useIdentity2 } from "@dxos/react-client/halo";
16
- import { Icon, ScrollArea, useThemeContext as useThemeContext2, useTranslation as useTranslation2 } from "@dxos/react-ui";
17
- import { createBasicExtensions as createBasicExtensions2, createThemeExtensions as createThemeExtensions2, listener } from "@dxos/react-ui-editor";
18
- import { StackItem } from "@dxos/react-ui-stack";
19
- import { mx as mx3 } from "@dxos/react-ui-theme";
20
- import { MessageTextbox, Thread, ThreadFooter, threadLayout } from "@dxos/react-ui-thread";
21
-
22
- // packages/plugins/plugin-thread/src/components/MessageContainer.tsx
23
- import { EditorView } from "@codemirror/view";
24
- import { Check, PencilSimple, X } from "@phosphor-icons/react";
25
- import React, { forwardRef, useCallback, useEffect, useRef, useState } from "react";
26
- import { Surface } from "@dxos/app-framework";
27
- import { RefArray } from "@dxos/live-object";
28
- import { PublicKey } from "@dxos/react-client";
29
- import { useIdentity } from "@dxos/react-client/halo";
30
- import { Button, ButtonGroup, Tooltip, useOnTransition, useThemeContext, useTranslation } from "@dxos/react-ui";
31
- import { createBasicExtensions, createThemeExtensions, useTextEditor } from "@dxos/react-ui-editor";
32
- import { getSize, hoverableControlItem, hoverableControls, hoverableFocusedWithinControls, mx as mx2 } from "@dxos/react-ui-theme";
33
- import { MessageHeading, MessageRoot } from "@dxos/react-ui-thread";
6
+ } from "./chunk-WBJLUUOK.mjs";
34
7
 
35
8
  // packages/plugins/plugin-thread/src/components/command-extension.ts
36
9
  import { StreamLanguage, HighlightStyle, syntaxHighlighting } from "@codemirror/language";
@@ -70,7 +43,7 @@ var getMessageMetadata = (id, identity) => {
70
43
  const fallback = hexToFallback(identity?.identityKey.toHex() ?? "0");
71
44
  return {
72
45
  id,
73
- authorId: identity?.identityKey.toHex(),
46
+ authorId: identity?.did,
74
47
  authorName: identity?.profile?.displayName ?? (identity?.identityKey ? generateName(identity.identityKey.toHex()) : void 0),
75
48
  authorAvatarProps: {
76
49
  hue: identity?.profile?.data?.hue ?? fallback.hue,
@@ -80,14 +53,25 @@ var getMessageMetadata = (id, identity) => {
80
53
  };
81
54
 
82
55
  // packages/plugins/plugin-thread/src/components/MessageContainer.tsx
56
+ import { EditorView } from "@codemirror/view";
57
+ import { Check, PencilSimple, X } from "@phosphor-icons/react";
58
+ import React, { forwardRef, useCallback, useEffect, useRef, useState } from "react";
59
+ import { Surface } from "@dxos/app-framework";
60
+ import { RefArray } from "@dxos/live-object";
61
+ import { PublicKey } from "@dxos/react-client";
62
+ import { useIdentity } from "@dxos/react-client/halo";
63
+ import { Button, ButtonGroup, Tooltip, useOnTransition, useThemeContext, useTranslation } from "@dxos/react-ui";
64
+ import { createBasicExtensions, createThemeExtensions, useTextEditor } from "@dxos/react-ui-editor";
65
+ import { getSize, hoverableControlItem, hoverableControls, hoverableFocusedWithinControls, mx as mx2 } from "@dxos/react-ui-theme";
66
+ import { MessageHeading, MessageRoot } from "@dxos/react-ui-thread";
83
67
  var messageControlClassNames = [
84
68
  "!p-1 !min-bs-0 transition-opacity",
85
69
  hoverableControlItem
86
70
  ];
87
- var MessageContainer = ({ message, members, onDelete }) => {
88
- const senderIdentity = members.find((member) => message.sender.identityKey && PublicKey.equals(member.identity.identityKey, message.sender.identityKey))?.identity;
71
+ var MessageContainer = ({ message, members, editable = false, onDelete }) => {
72
+ const senderIdentity = members.find((member) => message.sender.identityDid && member.identity.did === message.sender.identityDid || message.sender.identityKey && PublicKey.equals(member.identity.identityKey, message.sender.identityKey))?.identity;
89
73
  const messageMetadata = getMessageMetadata(message.id, senderIdentity);
90
- const userIsAuthor = useIdentity()?.identityKey.toHex() === messageMetadata.authorId;
74
+ const userIsAuthor = useIdentity()?.did === messageMetadata.authorId;
91
75
  const [editing, setEditing] = useState(false);
92
76
  const handleDelete = useCallback(() => onDelete?.(message.id), [
93
77
  message,
@@ -96,6 +80,9 @@ var MessageContainer = ({ message, members, onDelete }) => {
96
80
  const { t } = useTranslation(THREAD_PLUGIN);
97
81
  const editLabel = t(editing ? "save message label" : "edit message label");
98
82
  const deleteLabel = t("delete message label");
83
+ const textBlock = message.blocks.find((block) => block.type === "text");
84
+ const references = message.blocks.filter((block) => block.type === "reference").map((block) => block.reference);
85
+ useOnEditAnalytics(message, textBlock, !!editing);
99
86
  return /* @__PURE__ */ React.createElement(MessageRoot, {
100
87
  ...messageMetadata,
101
88
  classNames: [
@@ -107,7 +94,7 @@ var MessageContainer = ({ message, members, onDelete }) => {
107
94
  timestamp: messageMetadata.timestamp
108
95
  }, /* @__PURE__ */ React.createElement(ButtonGroup, {
109
96
  classNames: "mie-1"
110
- }, userIsAuthor && /* @__PURE__ */ React.createElement(Tooltip.Root, null, /* @__PURE__ */ React.createElement(Tooltip.Trigger, {
97
+ }, userIsAuthor && editable && /* @__PURE__ */ React.createElement(Tooltip.Root, null, /* @__PURE__ */ React.createElement(Tooltip.Trigger, {
111
98
  asChild: true
112
99
  }, /* @__PURE__ */ React.createElement(Button, {
113
100
  variant: "ghost",
@@ -131,13 +118,13 @@ var MessageContainer = ({ message, members, onDelete }) => {
131
118
  className: "sr-only"
132
119
  }, deleteLabel), /* @__PURE__ */ React.createElement(X, {
133
120
  className: getSize(4)
134
- }))), /* @__PURE__ */ React.createElement(Tooltip.Portal, null, /* @__PURE__ */ React.createElement(Tooltip.Content, null, deleteLabel, /* @__PURE__ */ React.createElement(Tooltip.Arrow, null)))))), /* @__PURE__ */ React.createElement(TextboxBlock, {
135
- message,
121
+ }))), /* @__PURE__ */ React.createElement(Tooltip.Portal, null, /* @__PURE__ */ React.createElement(Tooltip.Content, null, deleteLabel, /* @__PURE__ */ React.createElement(Tooltip.Arrow, null)))))), textBlock && /* @__PURE__ */ React.createElement(TextboxBlock, {
122
+ block: textBlock,
136
123
  isAuthor: userIsAuthor,
137
124
  editing
138
- }), RefArray.allResolvedTargets(message.parts ?? []).map((part, index) => /* @__PURE__ */ React.createElement(MessagePart, {
125
+ }), RefArray.targets(references).map((reference, index) => /* @__PURE__ */ React.createElement(MessagePart, {
139
126
  key: index,
140
- part
127
+ part: reference
141
128
  })));
142
129
  };
143
130
  var MessagePart = ({ part }) => {
@@ -145,23 +132,23 @@ var MessagePart = ({ part }) => {
145
132
  subject: part
146
133
  });
147
134
  };
148
- var TextboxBlock = ({ message, isAuthor, editing }) => {
135
+ var TextboxBlock = ({ block, isAuthor, editing }) => {
149
136
  const { themeMode } = useThemeContext();
150
- const inMemoryContentRef = useRef(message.text);
137
+ const inMemoryContentRef = useRef(block.text);
151
138
  const handleDocumentChange = useCallback((newState) => {
152
139
  inMemoryContentRef.current = newState;
153
140
  }, []);
154
141
  const saveDocumentChange = useCallback(() => {
155
- message.text = inMemoryContentRef.current;
142
+ block.text = inMemoryContentRef.current;
156
143
  }, [
157
- message
144
+ block
158
145
  ]);
159
146
  useOnTransition(editing, true, false, saveDocumentChange);
160
147
  const { parentRef, focusAttributes, view } = useTextEditor(() => ({
161
- initialValue: message.text,
148
+ initialValue: block.text,
162
149
  extensions: [
163
150
  createBasicExtensions({
164
- readonly: !isAuthor || !editing
151
+ readOnly: !isAuthor || !editing
165
152
  }),
166
153
  createThemeExtensions({
167
154
  themeMode
@@ -174,7 +161,7 @@ var TextboxBlock = ({ message, isAuthor, editing }) => {
174
161
  })
175
162
  ]
176
163
  }), [
177
- message.text,
164
+ block.text,
178
165
  editing,
179
166
  isAuthor,
180
167
  themeMode,
@@ -186,7 +173,6 @@ var TextboxBlock = ({ message, isAuthor, editing }) => {
186
173
  editing,
187
174
  view
188
175
  ]);
189
- useOnEditAnalytics(message, !!editing);
190
176
  return /* @__PURE__ */ React.createElement("div", {
191
177
  role: "none",
192
178
  ref: parentRef,
@@ -213,100 +199,9 @@ var MessageBlockObjectTile = /* @__PURE__ */ forwardRef(({ subject }, forwardedR
213
199
  }));
214
200
  });
215
201
 
216
- // packages/plugins/plugin-thread/src/components/ChatContainer.tsx
217
- var ChatContainer = ({ thread, context, current, autoFocusTextbox }) => {
218
- const identity = useIdentity2();
219
- const space = getSpace(thread);
220
- const members = useMembers(space?.key);
221
- const activity = useStatus(space, fullyQualifiedId(thread));
222
- const { t } = useTranslation2(THREAD_PLUGIN);
223
- const [_count, _setCount] = useState2(0);
224
- const rerenderEditor = () => _setCount((count) => count + 1);
225
- const [autoFocus, setAutoFocus] = useState2(autoFocusTextbox);
226
- const threadScrollRef = useRef2(null);
227
- const { themeMode } = useThemeContext2();
228
- const textboxMetadata = getMessageMetadata(fullyQualifiedId(thread), identity);
229
- const messageRef = useRef2("");
230
- const extensions = useMemo(() => [
231
- createBasicExtensions2({
232
- placeholder: t("message placeholder")
233
- }),
234
- createThemeExtensions2({
235
- themeMode
236
- }),
237
- listener({
238
- onChange: (text) => messageRef.current = text
239
- }),
240
- command
241
- ], [
242
- themeMode,
243
- _count
244
- ]);
245
- const scrollToEnd = (behavior) => setTimeout(() => threadScrollRef.current?.scrollIntoView({
246
- behavior,
247
- block: "end"
248
- }), 10);
249
- useLayoutEffect(() => {
250
- scrollToEnd("instant");
251
- }, []);
252
- const handleCreate = () => {
253
- if (!messageRef.current?.length) {
254
- return false;
255
- }
256
- thread.messages.push(makeRef(create(MessageType, {
257
- sender: {
258
- identityKey: identity.identityKey.toHex()
259
- },
260
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
261
- text: messageRef.current,
262
- context: context ? makeRef(context) : void 0
263
- })));
264
- messageRef.current = "";
265
- setAutoFocus(true);
266
- scrollToEnd("smooth");
267
- rerenderEditor();
268
- return true;
269
- };
270
- const handleDelete = (id) => {
271
- const messageIndex = thread.messages.findIndex(Ref.hasObjectId(id));
272
- if (messageIndex !== -1) {
273
- thread.messages.splice(messageIndex, 1);
274
- }
275
- };
276
- return /* @__PURE__ */ React2.createElement(Thread, {
277
- current,
278
- id: fullyQualifiedId(thread),
279
- classNames: "bs-full grid-rows-[1fr_min-content_min-content] overflow-hidden transition-[padding-block-end] [[data-sidebar-inline-start-state=open]_&]:lg:pbe-0"
280
- }, /* @__PURE__ */ React2.createElement(ScrollArea.Root, {
281
- classNames: "col-span-2"
282
- }, /* @__PURE__ */ React2.createElement(ScrollArea.Viewport, {
283
- classNames: "overflow-anchored after:overflow-anchor after:block after:bs-px after:-mbs-px [&>div]:min-bs-full [&>div]:!grid [&>div]:grid-rows-[1fr_0]"
284
- }, /* @__PURE__ */ React2.createElement("div", {
285
- role: "none",
286
- className: mx3(threadLayout, "place-self-end")
287
- }, RefArray2.allResolvedTargets(thread.messages ?? []).map((message) => /* @__PURE__ */ React2.createElement(MessageContainer, {
288
- key: message.id,
289
- message,
290
- members,
291
- onDelete: handleDelete
292
- }))), /* @__PURE__ */ React2.createElement("div", {
293
- role: "none",
294
- className: "bs-px -mbs-px",
295
- ref: threadScrollRef
296
- }), /* @__PURE__ */ React2.createElement(ScrollArea.Scrollbar, null, /* @__PURE__ */ React2.createElement(ScrollArea.Thumb, null)))), /* @__PURE__ */ React2.createElement(MessageTextbox, {
297
- extensions,
298
- autoFocus,
299
- onSend: handleCreate,
300
- ...textboxMetadata
301
- }), /* @__PURE__ */ React2.createElement(ThreadFooter, {
302
- activity
303
- }, t("activity message")));
304
- };
305
-
306
202
  export {
307
203
  command,
308
204
  getMessageMetadata,
309
- MessageContainer,
310
- ChatContainer
205
+ MessageContainer
311
206
  };
312
- //# sourceMappingURL=chunk-UPKU23DA.mjs.map
207
+ //# sourceMappingURL=chunk-TFVPUPOO.mjs.map