@dxos/plugin-thread 0.8.4-main.422d1c7879 → 0.8.4-main.4f23b4e393

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 (397) hide show
  1. package/dist/lib/neutral/CallDebugPanel-CXWTCS7A.mjs +172 -0
  2. package/dist/lib/neutral/CallDebugPanel-CXWTCS7A.mjs.map +7 -0
  3. package/dist/lib/neutral/CallSidebar-4USJZ2SB.mjs +25 -0
  4. package/dist/lib/neutral/CallSidebar-4USJZ2SB.mjs.map +7 -0
  5. package/dist/lib/neutral/ChannelChat-6YTD5HWL.mjs +10 -0
  6. package/dist/lib/neutral/ChannelContainer-XHBF2NCK.mjs +9 -0
  7. package/dist/lib/neutral/ThreadCompanion-NQWPS2H6.mjs +208 -0
  8. package/dist/lib/neutral/ThreadCompanion-NQWPS2H6.mjs.map +7 -0
  9. package/dist/lib/neutral/ThreadContainer-XYEPEOSD.mjs +61 -0
  10. package/dist/lib/neutral/ThreadContainer-XYEPEOSD.mjs.map +7 -0
  11. package/dist/lib/neutral/ThreadPlugin.mjs +89 -0
  12. package/dist/lib/neutral/ThreadPlugin.mjs.map +7 -0
  13. package/dist/lib/neutral/ThreadPlugin.node.mjs +40 -0
  14. package/dist/lib/neutral/ThreadPlugin.node.mjs.map +7 -0
  15. package/dist/lib/neutral/ThreadSettings-5Z5XIHG3.mjs +15 -0
  16. package/dist/lib/neutral/ThreadSettings-5Z5XIHG3.mjs.map +7 -0
  17. package/dist/lib/{browser/add-message-VPPFFLFL.mjs → neutral/add-message-HV5R66K4.mjs} +12 -22
  18. package/dist/lib/neutral/add-message-HV5R66K4.mjs.map +7 -0
  19. package/dist/lib/neutral/app-graph-builder-JDLHZ4XO.mjs +173 -0
  20. package/dist/lib/neutral/app-graph-builder-JDLHZ4XO.mjs.map +7 -0
  21. package/dist/lib/neutral/append-channel-message-PO33DR5V.mjs +40 -0
  22. package/dist/lib/neutral/append-channel-message-PO33DR5V.mjs.map +7 -0
  23. package/dist/lib/neutral/blueprint-definition-S3EBOH4R.mjs +15 -0
  24. package/dist/lib/neutral/blueprint-definition-S3EBOH4R.mjs.map +7 -0
  25. package/dist/lib/neutral/blueprints/index.mjs +8 -0
  26. package/dist/lib/neutral/call-manager-JFA4DLWR.mjs +24 -0
  27. package/dist/lib/neutral/call-manager-JFA4DLWR.mjs.map +7 -0
  28. package/dist/lib/neutral/capabilities/index.mjs +29 -0
  29. package/dist/lib/neutral/capabilities/index.mjs.map +7 -0
  30. package/dist/lib/neutral/chunk-44D7D4ZX.mjs +20 -0
  31. package/dist/lib/neutral/chunk-44D7D4ZX.mjs.map +7 -0
  32. package/dist/lib/{browser/blueprints/index.mjs → neutral/chunk-5T5LPLBN.mjs} +5 -6
  33. package/dist/lib/neutral/chunk-5T5LPLBN.mjs.map +7 -0
  34. package/dist/lib/neutral/chunk-CROE4U4O.mjs +100 -0
  35. package/dist/lib/neutral/chunk-CROE4U4O.mjs.map +7 -0
  36. package/dist/lib/neutral/chunk-D5LGFCUY.mjs +55 -0
  37. package/dist/lib/neutral/chunk-D5LGFCUY.mjs.map +7 -0
  38. package/dist/lib/neutral/chunk-FWSMZWBO.mjs +178 -0
  39. package/dist/lib/neutral/chunk-FWSMZWBO.mjs.map +7 -0
  40. package/dist/lib/neutral/chunk-JLY4NVTA.mjs +38 -0
  41. package/dist/lib/neutral/chunk-JLY4NVTA.mjs.map +7 -0
  42. package/dist/lib/neutral/chunk-KRXHIW4P.mjs +164 -0
  43. package/dist/lib/neutral/chunk-KRXHIW4P.mjs.map +7 -0
  44. package/dist/lib/neutral/chunk-MXJYXUS2.mjs +8 -0
  45. package/dist/lib/neutral/chunk-MXJYXUS2.mjs.map +7 -0
  46. package/dist/lib/{browser/chunk-VPM44Z35.mjs → neutral/chunk-OZRSYMYO.mjs} +101 -85
  47. package/dist/lib/neutral/chunk-OZRSYMYO.mjs.map +7 -0
  48. package/dist/lib/{browser/index.mjs → neutral/chunk-PZ7WTAA2.mjs} +88 -900
  49. package/dist/lib/neutral/chunk-PZ7WTAA2.mjs.map +7 -0
  50. package/dist/lib/neutral/chunk-S2AKEA2K.mjs +202 -0
  51. package/dist/lib/neutral/chunk-S2AKEA2K.mjs.map +7 -0
  52. package/dist/lib/neutral/components/index.mjs +1230 -0
  53. package/dist/lib/neutral/components/index.mjs.map +7 -0
  54. package/dist/lib/neutral/containers/index.mjs +19 -0
  55. package/dist/lib/neutral/containers/index.mjs.map +7 -0
  56. package/dist/lib/{browser/create-UGT7V733.mjs → neutral/create-C3CICN35.mjs} +8 -11
  57. package/dist/lib/neutral/create-C3CICN35.mjs.map +7 -0
  58. package/dist/lib/neutral/create-channel-UEQESOFT.mjs +19 -0
  59. package/dist/lib/neutral/create-channel-UEQESOFT.mjs.map +7 -0
  60. package/dist/lib/neutral/create-object-HIEWSBZB.mjs +27 -0
  61. package/dist/lib/neutral/create-object-HIEWSBZB.mjs.map +7 -0
  62. package/dist/lib/{browser/create-proposals-CMK7S7VS.mjs → neutral/create-proposals-OZ4NCBBS.mjs} +5 -6
  63. package/dist/lib/neutral/create-proposals-OZ4NCBBS.mjs.map +7 -0
  64. package/dist/lib/{browser/delete-FSFVU6ZA.mjs → neutral/delete-AVFYFWMY.mjs} +8 -10
  65. package/dist/lib/neutral/delete-AVFYFWMY.mjs.map +7 -0
  66. package/dist/lib/{browser/delete-message-XL5M5J33.mjs → neutral/delete-message-EV2MKRTB.mjs} +9 -19
  67. package/dist/lib/neutral/delete-message-EV2MKRTB.mjs.map +7 -0
  68. package/dist/lib/neutral/hooks/index.mjs +19 -0
  69. package/dist/lib/neutral/hooks/index.mjs.map +7 -0
  70. package/dist/lib/neutral/index.mjs +68 -0
  71. package/dist/lib/neutral/index.mjs.map +7 -0
  72. package/dist/lib/neutral/markdown-BUORNCPG.mjs +83 -0
  73. package/dist/lib/neutral/markdown-BUORNCPG.mjs.map +7 -0
  74. package/dist/lib/neutral/meta.json +1 -0
  75. package/dist/lib/neutral/meta.mjs +10 -0
  76. package/dist/lib/neutral/meta.mjs.map +7 -0
  77. package/dist/lib/neutral/on-create-space-NQF7WGEB.mjs +23 -0
  78. package/dist/lib/neutral/on-create-space-NQF7WGEB.mjs.map +7 -0
  79. package/dist/lib/neutral/operation-handler-RU6K2S4L.mjs +13 -0
  80. package/dist/lib/neutral/operation-handler-RU6K2S4L.mjs.map +7 -0
  81. package/dist/lib/neutral/operations/index.mjs +8 -0
  82. package/dist/lib/neutral/operations/index.mjs.map +7 -0
  83. package/dist/lib/neutral/plugin.mjs +16 -0
  84. package/dist/lib/neutral/plugin.mjs.map +7 -0
  85. package/dist/lib/neutral/react-root-VMMNUSSL.mjs +18 -0
  86. package/dist/lib/neutral/react-root-VMMNUSSL.mjs.map +7 -0
  87. package/dist/lib/neutral/react-surface-WPSVOTVG.mjs +94 -0
  88. package/dist/lib/neutral/react-surface-WPSVOTVG.mjs.map +7 -0
  89. package/dist/lib/{browser/restore-2ZGMKUSD.mjs → neutral/restore-MGLYOJ3Y.mjs} +6 -7
  90. package/dist/lib/neutral/restore-MGLYOJ3Y.mjs.map +7 -0
  91. package/dist/lib/{browser/restore-message-OYEGWPII.mjs → neutral/restore-message-ZIOA2MQJ.mjs} +8 -17
  92. package/dist/lib/neutral/restore-message-ZIOA2MQJ.mjs.map +7 -0
  93. package/dist/lib/{browser/select-VG2XLULE.mjs → neutral/select-CVCGBDHA.mjs} +7 -9
  94. package/dist/lib/neutral/select-CVCGBDHA.mjs.map +7 -0
  95. package/dist/lib/neutral/settings-HK4EB6TF.mjs +30 -0
  96. package/dist/lib/neutral/settings-HK4EB6TF.mjs.map +7 -0
  97. package/dist/lib/neutral/state-UU7VEAKV.mjs +22 -0
  98. package/dist/lib/neutral/state-UU7VEAKV.mjs.map +7 -0
  99. package/dist/lib/neutral/testing/index.mjs +58 -0
  100. package/dist/lib/neutral/testing/index.mjs.map +7 -0
  101. package/dist/lib/{browser/toggle-resolved-MM6YC5BU.mjs → neutral/toggle-resolved-ZM4BHON5.mjs} +8 -17
  102. package/dist/lib/neutral/toggle-resolved-ZM4BHON5.mjs.map +7 -0
  103. package/dist/lib/neutral/translations.mjs +90 -0
  104. package/dist/lib/neutral/translations.mjs.map +7 -0
  105. package/dist/lib/neutral/types/index.mjs +12 -0
  106. package/dist/lib/neutral/types/index.mjs.map +7 -0
  107. package/dist/lib/neutral/undo-mappings-HOKL2L3M.mjs +54 -0
  108. package/dist/lib/neutral/undo-mappings-HOKL2L3M.mjs.map +7 -0
  109. package/dist/types/src/ThreadPlugin.d.ts +1 -0
  110. package/dist/types/src/ThreadPlugin.d.ts.map +1 -1
  111. package/dist/types/src/ThreadPlugin.node.d.ts +4 -0
  112. package/dist/types/src/ThreadPlugin.node.d.ts.map +1 -0
  113. package/dist/types/src/ThreadPlugin.test.d.ts +2 -0
  114. package/dist/types/src/ThreadPlugin.test.d.ts.map +1 -0
  115. package/dist/types/src/blueprints/thread-blueprint.d.ts +2 -2
  116. package/dist/types/src/blueprints/thread-blueprint.d.ts.map +1 -1
  117. package/dist/types/src/calls/call-manager.d.ts.map +1 -1
  118. package/dist/types/src/calls/call-swarm-synchronizer.d.ts.map +1 -1
  119. package/dist/types/src/calls/media-manager.d.ts.map +1 -1
  120. package/dist/types/src/calls/speaking-monitor.d.ts +0 -3
  121. package/dist/types/src/calls/speaking-monitor.d.ts.map +1 -1
  122. package/dist/types/src/calls/types.d.ts.map +1 -1
  123. package/dist/types/src/calls/util/audio.d.ts.map +1 -1
  124. package/dist/types/src/calls/util/calls-service.d.ts +2 -2
  125. package/dist/types/src/calls/util/calls-service.d.ts.map +1 -1
  126. package/dist/types/src/calls/util/history-cache.d.ts.map +1 -1
  127. package/dist/types/src/calls/util/media.d.ts.map +1 -1
  128. package/dist/types/src/calls/util/stub-media-streams.d.ts.map +1 -1
  129. package/dist/types/src/calls/util/task-scheduling.d.ts.map +1 -1
  130. package/dist/types/src/calls-service.stories.d.ts.map +1 -1
  131. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
  132. package/dist/types/src/capabilities/blueprint-definition.d.ts +2 -2
  133. package/dist/types/src/capabilities/blueprint-definition.d.ts.map +1 -1
  134. package/dist/types/src/capabilities/call-manager.d.ts.map +1 -1
  135. package/dist/types/src/capabilities/create-object.d.ts +11 -0
  136. package/dist/types/src/capabilities/create-object.d.ts.map +1 -0
  137. package/dist/types/src/capabilities/index.d.ts +9 -3
  138. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  139. package/dist/types/src/capabilities/markdown.d.ts.map +1 -1
  140. package/dist/types/src/capabilities/operation-handler.d.ts +1 -1
  141. package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -1
  142. package/dist/types/src/capabilities/react-root.d.ts.map +1 -1
  143. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  144. package/dist/types/src/capabilities/settings.d.ts.map +1 -1
  145. package/dist/types/src/capabilities/state.d.ts.map +1 -1
  146. package/dist/types/src/capabilities/undo-mappings.d.ts.map +1 -1
  147. package/dist/types/src/components/Call/Call.d.ts +32 -4
  148. package/dist/types/src/components/Call/Call.d.ts.map +1 -1
  149. package/dist/types/src/components/Call/Toolbar.d.ts +5 -5
  150. package/dist/types/src/components/Call/Toolbar.d.ts.map +1 -1
  151. package/dist/types/src/components/Chat/Chat.d.ts +51 -0
  152. package/dist/types/src/components/Chat/Chat.d.ts.map +1 -0
  153. package/dist/types/src/components/Chat/index.d.ts +2 -0
  154. package/dist/types/src/components/Chat/index.d.ts.map +1 -0
  155. package/dist/types/src/components/CommentsPanel/CommentsPanel.d.ts.map +1 -1
  156. package/dist/types/src/components/CommentsPanel/CommentsPanel.stories.d.ts +70 -70
  157. package/dist/types/src/components/CommentsPanel/CommentsPanel.stories.d.ts.map +1 -1
  158. package/dist/types/src/components/CommentsPanel/CommentsThread.d.ts.map +1 -1
  159. package/dist/types/src/components/Lobby/Lobby.d.ts +24 -3
  160. package/dist/types/src/components/Lobby/Lobby.d.ts.map +1 -1
  161. package/dist/types/src/components/Media/VideoObject.d.ts +1 -1
  162. package/dist/types/src/components/Media/VideoObject.stories.d.ts +1 -1
  163. package/dist/types/src/components/Media/VideoObject.stories.d.ts.map +1 -1
  164. package/dist/types/src/components/MessagePanel/MessagePanel.d.ts.map +1 -1
  165. package/dist/types/src/components/Participant/ParticipantGrid.d.ts.map +1 -1
  166. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.d.ts.map +1 -1
  167. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.stories.d.ts +70 -70
  168. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.stories.d.ts.map +1 -1
  169. package/dist/types/src/components/ResponsiveGrid/ResponsiveGridItem.d.ts.map +1 -1
  170. package/dist/types/src/components/ResponsiveGrid/ResponsivePanel.d.ts.map +1 -1
  171. package/dist/types/src/components/ResponsiveGrid/ResponsivePanel.stories.d.ts +70 -70
  172. package/dist/types/src/components/ResponsiveGrid/ResponsivePanel.stories.d.ts.map +1 -1
  173. package/dist/types/src/components/ThreadSettings/ThreadSettings.d.ts.map +1 -1
  174. package/dist/types/src/components/ThreadSettings/ThreadSettings.stories.d.ts +70 -70
  175. package/dist/types/src/components/ThreadSettings/ThreadSettings.stories.d.ts.map +1 -1
  176. package/dist/types/src/components/index.d.ts +1 -0
  177. package/dist/types/src/components/index.d.ts.map +1 -1
  178. package/dist/types/src/containers/CallDebugPanel/CallDebugPanel.d.ts.map +1 -1
  179. package/dist/types/src/containers/ChannelChat/ChannelChat.d.ts +20 -0
  180. package/dist/types/src/containers/ChannelChat/ChannelChat.d.ts.map +1 -0
  181. package/dist/types/src/containers/ChannelChat/index.d.ts +4 -0
  182. package/dist/types/src/containers/ChannelChat/index.d.ts.map +1 -0
  183. package/dist/types/src/containers/ChannelContainer/ChannelContainer.d.ts +1 -1
  184. package/dist/types/src/containers/ChannelContainer/ChannelContainer.d.ts.map +1 -1
  185. package/dist/types/src/containers/ChannelContainer/ChannelContainer.stories.d.ts +70 -70
  186. package/dist/types/src/containers/ChannelContainer/ChannelContainer.stories.d.ts.map +1 -1
  187. package/dist/types/src/containers/ThreadCompanion/ThreadCompanion.d.ts.map +1 -1
  188. package/dist/types/src/containers/ThreadContainer/ThreadContainer.d.ts +20 -0
  189. package/dist/types/src/containers/ThreadContainer/ThreadContainer.d.ts.map +1 -0
  190. package/dist/types/src/containers/{ChatContainer/ChatContainer.stories.d.ts → ThreadContainer/ThreadContainer.stories.d.ts} +71 -71
  191. package/dist/types/src/containers/ThreadContainer/ThreadContainer.stories.d.ts.map +1 -0
  192. package/dist/types/src/containers/ThreadContainer/index.d.ts +4 -0
  193. package/dist/types/src/containers/ThreadContainer/index.d.ts.map +1 -0
  194. package/dist/types/src/containers/index.d.ts +2 -1
  195. package/dist/types/src/containers/index.d.ts.map +1 -1
  196. package/dist/types/src/extensions/threads.d.ts +3 -3
  197. package/dist/types/src/extensions/threads.d.ts.map +1 -1
  198. package/dist/types/src/hooks/analytics.d.ts.map +1 -1
  199. package/dist/types/src/hooks/useStatus.d.ts.map +1 -1
  200. package/dist/types/src/hooks/useVideoStreamTrack.d.ts.map +1 -1
  201. package/dist/types/src/index.d.ts +2 -2
  202. package/dist/types/src/index.d.ts.map +1 -1
  203. package/dist/types/src/operations/add-message.d.ts +3 -3
  204. package/dist/types/src/operations/add-message.d.ts.map +1 -1
  205. package/dist/types/src/operations/append-channel-message.d.ts +5 -0
  206. package/dist/types/src/operations/append-channel-message.d.ts.map +1 -0
  207. package/dist/types/src/operations/create-channel.d.ts +3 -3
  208. package/dist/types/src/operations/create-channel.d.ts.map +1 -1
  209. package/dist/types/src/operations/create-proposals.d.ts +3 -3
  210. package/dist/types/src/operations/create-proposals.d.ts.map +1 -1
  211. package/dist/types/src/operations/create.d.ts +3 -3
  212. package/dist/types/src/operations/create.d.ts.map +1 -1
  213. package/dist/types/src/operations/delete-message.d.ts +3 -3
  214. package/dist/types/src/operations/delete-message.d.ts.map +1 -1
  215. package/dist/types/src/operations/delete.d.ts +3 -3
  216. package/dist/types/src/operations/delete.d.ts.map +1 -1
  217. package/dist/types/src/operations/index.d.ts +1 -2
  218. package/dist/types/src/operations/index.d.ts.map +1 -1
  219. package/dist/types/src/operations/on-create-space.d.ts +3 -3
  220. package/dist/types/src/operations/on-create-space.d.ts.map +1 -1
  221. package/dist/types/src/operations/restore-message.d.ts +3 -3
  222. package/dist/types/src/operations/restore-message.d.ts.map +1 -1
  223. package/dist/types/src/operations/restore.d.ts +3 -3
  224. package/dist/types/src/operations/restore.d.ts.map +1 -1
  225. package/dist/types/src/operations/select.d.ts +3 -3
  226. package/dist/types/src/operations/select.d.ts.map +1 -1
  227. package/dist/types/src/operations/toggle-resolved.d.ts +3 -3
  228. package/dist/types/src/operations/toggle-resolved.d.ts.map +1 -1
  229. package/dist/types/src/plugin.d.ts +4 -0
  230. package/dist/types/src/plugin.d.ts.map +1 -0
  231. package/dist/types/src/testing/data.d.ts.map +1 -1
  232. package/dist/types/src/testing/index.d.ts +1 -1
  233. package/dist/types/src/testing/index.d.ts.map +1 -1
  234. package/dist/types/src/translations.d.ts +70 -70
  235. package/dist/types/src/translations.d.ts.map +1 -1
  236. package/dist/types/src/types/ThreadCapabilities.d.ts +26 -0
  237. package/dist/types/src/types/ThreadCapabilities.d.ts.map +1 -0
  238. package/dist/types/src/{operations/definitions.d.ts → types/ThreadOperation.d.ts} +864 -1673
  239. package/dist/types/src/types/ThreadOperation.d.ts.map +1 -0
  240. package/dist/types/src/types/index.d.ts +3 -2
  241. package/dist/types/src/types/index.d.ts.map +1 -1
  242. package/dist/types/src/types/types.d.ts +1 -1
  243. package/dist/types/src/types/types.d.ts.map +1 -1
  244. package/dist/types/src/util.d.ts +6 -3
  245. package/dist/types/src/util.d.ts.map +1 -1
  246. package/dist/types/tsconfig.tsbuildinfo +1 -1
  247. package/package.json +124 -86
  248. package/src/ThreadPlugin.node.ts +39 -0
  249. package/src/ThreadPlugin.test.ts +37 -0
  250. package/src/ThreadPlugin.tsx +13 -57
  251. package/src/blueprints/thread-blueprint.ts +3 -4
  252. package/src/calls/util/calls-service.ts +3 -1
  253. package/src/calls/util/stub-media-streams.ts +3 -1
  254. package/src/capabilities/app-graph-builder.ts +21 -19
  255. package/src/capabilities/blueprint-definition.ts +2 -0
  256. package/src/capabilities/call-manager.ts +1 -1
  257. package/src/capabilities/create-object.ts +29 -0
  258. package/src/capabilities/index.ts +3 -1
  259. package/src/capabilities/markdown.ts +6 -2
  260. package/src/capabilities/operation-handler.ts +1 -1
  261. package/src/capabilities/react-surface.tsx +13 -7
  262. package/src/capabilities/settings.ts +1 -3
  263. package/src/capabilities/undo-mappings.ts +1 -1
  264. package/src/components/Call/Call.tsx +5 -5
  265. package/src/components/Call/Toolbar.tsx +1 -1
  266. package/src/components/Chat/Chat.tsx +258 -0
  267. package/src/components/Chat/index.ts +5 -0
  268. package/src/components/CommentsPanel/CommentsPanel.stories.tsx +6 -4
  269. package/src/components/CommentsPanel/CommentsPanel.tsx +4 -4
  270. package/src/components/CommentsPanel/CommentsThread.tsx +2 -3
  271. package/src/components/Lobby/Lobby.tsx +5 -4
  272. package/src/components/MessagePanel/MessagePanel.tsx +8 -9
  273. package/src/components/ResponsiveGrid/ResponsiveGrid.stories.tsx +2 -1
  274. package/src/components/ResponsiveGrid/ResponsivePanel.stories.tsx +2 -1
  275. package/src/components/ResponsiveGrid/ResponsivePanel.tsx +3 -5
  276. package/src/components/ThreadSettings/ThreadSettings.stories.tsx +2 -1
  277. package/src/components/index.ts +1 -0
  278. package/src/containers/ChannelChat/ChannelChat.tsx +75 -0
  279. package/src/containers/ChannelChat/index.ts +8 -0
  280. package/src/containers/ChannelContainer/ChannelContainer.stories.tsx +54 -10
  281. package/src/containers/ChannelContainer/ChannelContainer.tsx +4 -4
  282. package/src/containers/ThreadCompanion/ThreadCompanion.tsx +10 -12
  283. package/src/containers/{ChatContainer/ChatContainer.stories.tsx → ThreadContainer/ThreadContainer.stories.tsx} +10 -11
  284. package/src/containers/ThreadContainer/ThreadContainer.tsx +75 -0
  285. package/src/containers/ThreadContainer/index.ts +8 -0
  286. package/src/containers/index.ts +2 -1
  287. package/src/extensions/command.ts +1 -1
  288. package/src/extensions/threads.ts +9 -9
  289. package/src/hooks/analytics.ts +1 -1
  290. package/src/index.ts +4 -3
  291. package/src/operations/add-message.ts +7 -7
  292. package/src/operations/append-channel-message.ts +37 -0
  293. package/src/operations/create-channel.ts +4 -4
  294. package/src/operations/create-proposals.ts +3 -3
  295. package/src/operations/create.ts +4 -4
  296. package/src/operations/delete-message.ts +6 -6
  297. package/src/operations/delete.ts +4 -4
  298. package/src/operations/index.ts +2 -4
  299. package/src/operations/on-create-space.ts +4 -4
  300. package/src/operations/restore-message.ts +5 -5
  301. package/src/operations/restore.ts +4 -4
  302. package/src/operations/select.ts +3 -3
  303. package/src/operations/toggle-resolved.ts +5 -5
  304. package/src/plugin.ts +11 -0
  305. package/src/testing/index.ts +1 -1
  306. package/src/translations.ts +1 -1
  307. package/src/types/ThreadCapabilities.ts +41 -0
  308. package/src/{operations/definitions.ts → types/ThreadOperation.ts} +14 -13
  309. package/src/types/index.ts +4 -2
  310. package/src/types/types.ts +0 -2
  311. package/src/util.ts +36 -4
  312. package/dist/lib/browser/add-message-VPPFFLFL.mjs.map +0 -7
  313. package/dist/lib/browser/blueprints/index.mjs.map +0 -7
  314. package/dist/lib/browser/chunk-MESW3R4Q.mjs +0 -61
  315. package/dist/lib/browser/chunk-MESW3R4Q.mjs.map +0 -7
  316. package/dist/lib/browser/chunk-VPM44Z35.mjs.map +0 -7
  317. package/dist/lib/browser/create-UGT7V733.mjs.map +0 -7
  318. package/dist/lib/browser/create-channel-EF67LCS6.mjs +0 -21
  319. package/dist/lib/browser/create-channel-EF67LCS6.mjs.map +0 -7
  320. package/dist/lib/browser/create-channel-thread-CCZTSWQ6.mjs +0 -28
  321. package/dist/lib/browser/create-channel-thread-CCZTSWQ6.mjs.map +0 -7
  322. package/dist/lib/browser/create-proposals-CMK7S7VS.mjs.map +0 -7
  323. package/dist/lib/browser/delete-FSFVU6ZA.mjs.map +0 -7
  324. package/dist/lib/browser/delete-message-XL5M5J33.mjs.map +0 -7
  325. package/dist/lib/browser/index.mjs.map +0 -7
  326. package/dist/lib/browser/meta.json +0 -1
  327. package/dist/lib/browser/on-create-space-VYS2JGVT.mjs +0 -25
  328. package/dist/lib/browser/on-create-space-VYS2JGVT.mjs.map +0 -7
  329. package/dist/lib/browser/operations/index.mjs +0 -14
  330. package/dist/lib/browser/operations/index.mjs.map +0 -7
  331. package/dist/lib/browser/restore-2ZGMKUSD.mjs.map +0 -7
  332. package/dist/lib/browser/restore-message-OYEGWPII.mjs.map +0 -7
  333. package/dist/lib/browser/select-VG2XLULE.mjs.map +0 -7
  334. package/dist/lib/browser/toggle-resolved-MM6YC5BU.mjs.map +0 -7
  335. package/dist/lib/browser/types/index.mjs +0 -12
  336. package/dist/lib/node-esm/add-message-XWKHLNS6.mjs +0 -98
  337. package/dist/lib/node-esm/add-message-XWKHLNS6.mjs.map +0 -7
  338. package/dist/lib/node-esm/blueprints/index.mjs +0 -38
  339. package/dist/lib/node-esm/blueprints/index.mjs.map +0 -7
  340. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +0 -11
  341. package/dist/lib/node-esm/chunk-JTHXNWKJ.mjs +0 -260
  342. package/dist/lib/node-esm/chunk-JTHXNWKJ.mjs.map +0 -7
  343. package/dist/lib/node-esm/chunk-SDRAQNSQ.mjs +0 -62
  344. package/dist/lib/node-esm/chunk-SDRAQNSQ.mjs.map +0 -7
  345. package/dist/lib/node-esm/create-XAYNDVU2.mjs +0 -56
  346. package/dist/lib/node-esm/create-XAYNDVU2.mjs.map +0 -7
  347. package/dist/lib/node-esm/create-channel-UYWUNB3L.mjs +0 -22
  348. package/dist/lib/node-esm/create-channel-UYWUNB3L.mjs.map +0 -7
  349. package/dist/lib/node-esm/create-channel-thread-UQF2SBHS.mjs +0 -29
  350. package/dist/lib/node-esm/create-channel-thread-UQF2SBHS.mjs.map +0 -7
  351. package/dist/lib/node-esm/create-proposals-5FJNURKH.mjs +0 -58
  352. package/dist/lib/node-esm/create-proposals-5FJNURKH.mjs.map +0 -7
  353. package/dist/lib/node-esm/delete-WRODXR3E.mjs +0 -60
  354. package/dist/lib/node-esm/delete-WRODXR3E.mjs.map +0 -7
  355. package/dist/lib/node-esm/delete-message-TAHCYTW2.mjs +0 -65
  356. package/dist/lib/node-esm/delete-message-TAHCYTW2.mjs.map +0 -7
  357. package/dist/lib/node-esm/index.mjs +0 -2335
  358. package/dist/lib/node-esm/index.mjs.map +0 -7
  359. package/dist/lib/node-esm/meta.json +0 -1
  360. package/dist/lib/node-esm/on-create-space-XDY2YXPV.mjs +0 -26
  361. package/dist/lib/node-esm/on-create-space-XDY2YXPV.mjs.map +0 -7
  362. package/dist/lib/node-esm/operations/index.mjs +0 -15
  363. package/dist/lib/node-esm/operations/index.mjs.map +0 -7
  364. package/dist/lib/node-esm/restore-T3QA7TSL.mjs +0 -34
  365. package/dist/lib/node-esm/restore-T3QA7TSL.mjs.map +0 -7
  366. package/dist/lib/node-esm/restore-message-WFTEVBEV.mjs +0 -43
  367. package/dist/lib/node-esm/restore-message-WFTEVBEV.mjs.map +0 -7
  368. package/dist/lib/node-esm/select-Q4UDWJJF.mjs +0 -27
  369. package/dist/lib/node-esm/select-Q4UDWJJF.mjs.map +0 -7
  370. package/dist/lib/node-esm/toggle-resolved-33XTAK2H.mjs +0 -46
  371. package/dist/lib/node-esm/toggle-resolved-33XTAK2H.mjs.map +0 -7
  372. package/dist/lib/node-esm/types/index.mjs +0 -13
  373. package/dist/types/src/containers/ChatContainer/ChatContainer.d.ts +0 -16
  374. package/dist/types/src/containers/ChatContainer/ChatContainer.d.ts.map +0 -1
  375. package/dist/types/src/containers/ChatContainer/ChatContainer.stories.d.ts.map +0 -1
  376. package/dist/types/src/containers/ChatContainer/index.d.ts +0 -4
  377. package/dist/types/src/containers/ChatContainer/index.d.ts.map +0 -1
  378. package/dist/types/src/operations/create-channel-thread.d.ts +0 -5
  379. package/dist/types/src/operations/create-channel-thread.d.ts.map +0 -1
  380. package/dist/types/src/operations/definitions.d.ts.map +0 -1
  381. package/dist/types/src/testing/stories.d.ts +0 -3
  382. package/dist/types/src/testing/stories.d.ts.map +0 -1
  383. package/dist/types/src/types/Channel.d.ts +0 -715
  384. package/dist/types/src/types/Channel.d.ts.map +0 -1
  385. package/dist/types/src/types/capabilities.d.ts +0 -24
  386. package/dist/types/src/types/capabilities.d.ts.map +0 -1
  387. package/src/containers/ChatContainer/ChatContainer.tsx +0 -131
  388. package/src/containers/ChatContainer/index.ts +0 -8
  389. package/src/operations/create-channel-thread.ts +0 -26
  390. package/src/testing/stories.ts +0 -51
  391. package/src/types/Channel.ts +0 -37
  392. package/src/types/capabilities.ts +0 -36
  393. /package/dist/lib/{browser/chunk-J5LGTIGS.mjs.map → neutral/ChannelChat-6YTD5HWL.mjs.map} +0 -0
  394. /package/dist/lib/{browser/types/index.mjs.map → neutral/ChannelContainer-XHBF2NCK.mjs.map} +0 -0
  395. /package/dist/lib/{node-esm/types → neutral/blueprints}/index.mjs.map +0 -0
  396. /package/dist/lib/{browser → neutral}/chunk-J5LGTIGS.mjs +0 -0
  397. /package/dist/lib/{node-esm/chunk-HSLMI22Q.mjs.map → neutral/chunk-J5LGTIGS.mjs.map} +0 -0
@@ -0,0 +1,1230 @@
1
+ import {
2
+ command
3
+ } from "../chunk-KRXHIW4P.mjs";
4
+ import {
5
+ getMessageMetadata
6
+ } from "../chunk-JLY4NVTA.mjs";
7
+ import "../chunk-J5LGTIGS.mjs";
8
+
9
+ // src/components/index.ts
10
+ import { lazy } from "react";
11
+
12
+ // src/components/Call/Call.tsx
13
+ import { useAtomValue as useAtomValue3 } from "@effect-atom/atom-react";
14
+ import React9 from "react";
15
+ import { useCapability as useCapability3 } from "@dxos/app-framework/ui";
16
+ import { useDebugMode } from "#hooks";
17
+ import { ThreadCapabilities as ThreadCapabilities3 } from "#types";
18
+
19
+ // src/components/Media/AudioStream.tsx
20
+ import React, { useEffect, useRef } from "react";
21
+ var AudioStream = ({ tracks }) => {
22
+ const mediaStreamRef = useRef(new MediaStream());
23
+ const ref = useRef(null);
24
+ useEffect(() => {
25
+ const audio = ref.current;
26
+ if (!audio) {
27
+ return;
28
+ }
29
+ const mediaStream = mediaStreamRef.current;
30
+ audio.srcObject = mediaStream;
31
+ }, []);
32
+ const resetSrcObject = () => {
33
+ const audio = ref.current;
34
+ const mediaStream = mediaStreamRef.current;
35
+ if (!audio || !mediaStream) {
36
+ return;
37
+ }
38
+ audio.addEventListener("canplay", () => audio.play(), {
39
+ once: true
40
+ });
41
+ audio.srcObject = mediaStream;
42
+ };
43
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("audio", {
44
+ ref,
45
+ autoPlay: true
46
+ }), tracks.map((track) => /* @__PURE__ */ React.createElement(AudioTrack, {
47
+ key: track.id,
48
+ track,
49
+ mediaStream: mediaStreamRef.current,
50
+ resetSrcObject
51
+ })));
52
+ };
53
+ var AudioTrack = ({ track, mediaStream, resetSrcObject }) => {
54
+ useEffect(() => {
55
+ const currentTrack = track;
56
+ mediaStream.addTrack(currentTrack);
57
+ resetSrcObject();
58
+ return () => {
59
+ mediaStream.removeTrack(currentTrack);
60
+ resetSrcObject();
61
+ };
62
+ }, [
63
+ track,
64
+ mediaStream
65
+ ]);
66
+ return null;
67
+ };
68
+
69
+ // src/components/Media/VideoObject.tsx
70
+ import React2, { forwardRef, memo, useEffect as useEffect2, useRef as useRef2 } from "react";
71
+ import { mx } from "@dxos/ui-theme";
72
+ var VideoObject = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef(({ videoStream, classNames, flip, contain, ...rest }, ref) => {
73
+ const internalRef = useRef2(null);
74
+ useEffect2(() => {
75
+ const video = internalRef.current;
76
+ if (video && videoStream) {
77
+ video.srcObject = videoStream;
78
+ video.setAttribute("autoplay", "true");
79
+ video.setAttribute("playsinline", "true");
80
+ }
81
+ }, [
82
+ videoStream,
83
+ internalRef.current
84
+ ]);
85
+ return /* @__PURE__ */ React2.createElement("video", {
86
+ className: mx("w-full aspect-video", flip && "scale-x-[-1]", contain ? "object-contain" : "object-cover", classNames),
87
+ ref: (v) => {
88
+ internalRef.current = v;
89
+ if (ref === null) {
90
+ return;
91
+ }
92
+ if (typeof ref === "function") {
93
+ ref(v);
94
+ } else {
95
+ ref.current = v;
96
+ }
97
+ },
98
+ ...rest
99
+ });
100
+ }));
101
+ VideoObject.displayName = "VideoObject";
102
+
103
+ // src/components/Participant/Participant.tsx
104
+ import { useAtomValue } from "@effect-atom/atom-react";
105
+ import React6, { memo as memo2, useMemo as useMemo2 } from "react";
106
+ import { useCapability } from "@dxos/app-framework/ui";
107
+ import { ThreadCapabilities } from "#types";
108
+
109
+ // src/components/ResponsiveGrid/ResponsivePanel.tsx
110
+ import React3 from "react";
111
+ import { mx as mx2 } from "@dxos/ui-theme";
112
+ var ResponsivePanel = ({ children }) => {
113
+ return (
114
+ // Outer container that takes full size of parent.
115
+ /* @__PURE__ */ React3.createElement("div", {
116
+ className: "dx-expander relative flex"
117
+ }, /* @__PURE__ */ React3.createElement("div", {
118
+ className: "absolute inset-0 flex justify-center items-center"
119
+ }, /* @__PURE__ */ React3.createElement("div", {
120
+ className: mx2("max-h-full max-w-full w-auto h-auto aspect-video")
121
+ }, children)))
122
+ );
123
+ };
124
+
125
+ // src/components/ResponsiveGrid/ResponsiveGrid.tsx
126
+ import React4, { useCallback, useEffect as useEffect3, useLayoutEffect, useMemo, useState } from "react";
127
+ import { useResizeDetector } from "react-resize-detector";
128
+ import { invariant } from "@dxos/invariant";
129
+ import { mx as mx3 } from "@dxos/ui-theme";
130
+ var __dxlog_file = "/__w/dxos/dxos/packages/plugins/plugin-thread/src/components/ResponsiveGrid/ResponsiveGrid.tsx";
131
+ var ASPECT_RATIO = 16 / 9;
132
+ var MIN_GALLERY_HEIGHT = 250;
133
+ var DEFAULT_GAP = 8;
134
+ var maxImageSize = "w-[2560px] h-[1440px]";
135
+ var defaultGetId = (item) => item.id;
136
+ var ResponsiveGrid = ({ classNames, Cell, gap = DEFAULT_GAP, getId: getId2 = defaultGetId, items, pinned, autoHideGallery = false, debug, onPinnedChange }) => {
137
+ const { width: containerWidth = 0, height: containerHeight = 0, ref: containerRef } = useResizeDetector({
138
+ refreshRate: 100
139
+ });
140
+ const [dividerHeight, setDividerHeight] = useState(0);
141
+ useEffect3(() => {
142
+ if (containerWidth && containerHeight) {
143
+ const { height: height2 } = fitAspectRatio(containerWidth, containerHeight, ASPECT_RATIO);
144
+ setDividerHeight(Math.min(height2, containerHeight - MIN_GALLERY_HEIGHT));
145
+ }
146
+ }, [
147
+ containerWidth,
148
+ containerHeight
149
+ ]);
150
+ const pinnedItem = useMemo(() => items.find((item) => getId2(item) === pinned), [
151
+ items,
152
+ pinned
153
+ ]);
154
+ const mainItems = useMemo(() => items.filter((item) => getId2(item) !== pinned), [
155
+ items,
156
+ pinned
157
+ ]);
158
+ const hideGallery = autoHideGallery && pinnedItem !== void 0;
159
+ const [{ time, columns, cellWidth }, setLayout] = useState({
160
+ time: 0,
161
+ columns: 0,
162
+ cellWidth: 0
163
+ });
164
+ const { width = 0, height = 0, ref: gridContainerRef } = useResizeDetector({
165
+ refreshRate: 200
166
+ });
167
+ useEffect3(() => {
168
+ if (containerHeight && width && height) {
169
+ const layout = calculateLayout(width, height, mainItems.length, gap);
170
+ setLayout({
171
+ time: Date.now(),
172
+ ...layout
173
+ });
174
+ }
175
+ }, [
176
+ containerHeight,
177
+ width,
178
+ height,
179
+ mainItems.length,
180
+ gap,
181
+ pinned
182
+ ]);
183
+ const [bounds, setBounds] = useState([]);
184
+ useLayoutEffect(() => {
185
+ if (!hideGallery && !gridContainerRef.current || !containerHeight) {
186
+ return;
187
+ }
188
+ const t = setTimeout(() => {
189
+ setBounds(items.filter((item) => !hideGallery || item === pinnedItem).map((item) => {
190
+ invariant(containerRef.current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 79, S: void 0, A: ["containerRef.current", ""] });
191
+ const el = containerRef.current.querySelector(`[data-grid-item="${getId2(item)}"]`);
192
+ if (!el) {
193
+ return null;
194
+ }
195
+ const bounds2 = getRelativeBounds(containerRef.current, el);
196
+ return [
197
+ item,
198
+ bounds2
199
+ ];
200
+ }).filter((item) => item !== null));
201
+ });
202
+ return () => clearTimeout(t);
203
+ }, [
204
+ containerHeight,
205
+ items,
206
+ pinnedItem,
207
+ hideGallery,
208
+ time
209
+ ]);
210
+ const handleClick = useCallback((item) => onPinnedChange?.(getId2(item) === pinned ? void 0 : getId2(item)), [
211
+ pinned,
212
+ onPinnedChange
213
+ ]);
214
+ return /* @__PURE__ */ React4.createElement("div", {
215
+ ref: containerRef,
216
+ className: mx3("dx-expander relative", classNames)
217
+ }, /* @__PURE__ */ React4.createElement("div", {
218
+ className: "absolute inset-0 flex flex-col grow gap-2"
219
+ }, pinnedItem && /* @__PURE__ */ React4.createElement("div", {
220
+ className: mx3("flex grow-[2] shrink overflow-hidden justify-center items-center", hideGallery && "h-full"),
221
+ style: hideGallery ? {} : {
222
+ height: dividerHeight
223
+ }
224
+ }, /* @__PURE__ */ React4.createElement(SoloItem, {
225
+ id: getId2(pinnedItem),
226
+ debug
227
+ })), !hideGallery && /* @__PURE__ */ React4.createElement("div", {
228
+ ref: gridContainerRef,
229
+ className: "flex grow-[1] overflow-hidden justify-center items-center",
230
+ style: hideGallery ? {} : {
231
+ minHeight: MIN_GALLERY_HEIGHT
232
+ }
233
+ }, mainItems.length === 1 && /* @__PURE__ */ React4.createElement("div", {
234
+ style: {
235
+ width: cellWidth
236
+ },
237
+ className: "flex h-full"
238
+ }, /* @__PURE__ */ React4.createElement(SoloItem, {
239
+ id: getId2(mainItems[0]),
240
+ debug
241
+ })), mainItems.length > 1 && columns > 0 && /* @__PURE__ */ React4.createElement("div", {
242
+ role: "grid",
243
+ style: {
244
+ display: "grid",
245
+ gridTemplateColumns: `repeat(${columns}, ${cellWidth}px)`,
246
+ gap: `${gap}px`
247
+ }
248
+ }, mainItems.map((item) => /* @__PURE__ */ React4.createElement("div", {
249
+ key: getId2(item),
250
+ "data-grid-item": getId2(item),
251
+ className: mx3("aspect-video max-h-full max-w-full w-auto h-auto", debug && "border border-primary-500")
252
+ }))))), /* @__PURE__ */ React4.createElement("div", {
253
+ className: mx3(debug && "opacity-10")
254
+ }, bounds.map(([item, bounds2]) => /* @__PURE__ */ React4.createElement(Cell, {
255
+ key: getId2(item),
256
+ classNames: "absolute transition-all duration-500",
257
+ item,
258
+ style: bounds2,
259
+ pinned: getId2(item) === pinned,
260
+ onClick: items.length > 1 ? handleClick : void 0
261
+ }))));
262
+ };
263
+ var SoloItem = ({ debug, id }) => {
264
+ return /* @__PURE__ */ React4.createElement(ResponsivePanel, null, /* @__PURE__ */ React4.createElement("div", {
265
+ "data-grid-item": id,
266
+ className: mx3("aspect-video overflow-hidden", debug && "z-20 border-2 border-primary-500")
267
+ }, /* @__PURE__ */ React4.createElement("img", {
268
+ alt: "placeholder video",
269
+ className: mx3("opacity-0", maxImageSize)
270
+ })));
271
+ };
272
+ var getRelativeBounds = (container, el) => {
273
+ const containerRect = container.getBoundingClientRect();
274
+ const elementRect = el.getBoundingClientRect();
275
+ return {
276
+ top: elementRect.top - containerRect.top,
277
+ left: elementRect.left - containerRect.left,
278
+ width: elementRect.width,
279
+ height: elementRect.height
280
+ };
281
+ };
282
+ var calculateLayout = (containerWidth, containerHeight, count, gap, aspectRatio = ASPECT_RATIO) => {
283
+ if (count === 0) {
284
+ return {
285
+ columns: 1,
286
+ cellWidth: 1
287
+ };
288
+ }
289
+ let minWastedSpace = Infinity;
290
+ let bestColumns = 1;
291
+ let cellWidth = 0;
292
+ for (let rows = 1; rows <= count; rows++) {
293
+ const cols = Math.ceil(count / rows);
294
+ const { width: itemWidth, height: itemHeight } = fitItemsToGrid(containerWidth, containerHeight, cols, rows, aspectRatio, gap);
295
+ const usedWidth = itemWidth * cols + gap * cols - 1;
296
+ const usedHeight = itemHeight * rows + gap * rows - 1;
297
+ const wastedSpace = containerWidth * containerHeight - usedWidth * usedHeight;
298
+ if (wastedSpace < minWastedSpace) {
299
+ minWastedSpace = wastedSpace;
300
+ bestColumns = cols;
301
+ cellWidth = itemWidth;
302
+ }
303
+ }
304
+ return {
305
+ columns: bestColumns,
306
+ cellWidth
307
+ };
308
+ };
309
+ var fitItemsToGrid = (outerWidth, outerHeight, numCols, numRows, aspectRatio, gap) => {
310
+ const availableWidth = outerWidth - gap * (numCols - 1);
311
+ const availableHeight = outerHeight - gap * (numRows - 1);
312
+ const maxCellWidth = availableWidth / numCols;
313
+ const maxCellHeight = availableHeight / numRows;
314
+ return fitAspectRatio(maxCellWidth, maxCellHeight, aspectRatio);
315
+ };
316
+ var fitAspectRatio = (outerWidth, outerHeight, aspectRatio) => {
317
+ if (outerWidth <= 0 || outerHeight <= 0 || aspectRatio <= 0) {
318
+ return {
319
+ width: 0,
320
+ height: 0
321
+ };
322
+ }
323
+ let width = outerWidth;
324
+ let height = width / aspectRatio;
325
+ if (height > outerHeight) {
326
+ height = outerHeight;
327
+ width = height * aspectRatio;
328
+ }
329
+ return {
330
+ width,
331
+ height
332
+ };
333
+ };
334
+
335
+ // src/components/ResponsiveGrid/ResponsiveGridItem.tsx
336
+ import React5, { useEffect as useEffect4, useState as useState2 } from "react";
337
+ import { Icon, IconButton, useTranslation } from "@dxos/react-ui";
338
+ import { Waveform } from "@dxos/react-ui-sfx";
339
+ import { groupHoverControlItemWithTransition, mx as mx4 } from "@dxos/ui-theme";
340
+ import { meta } from "#meta";
341
+ var ResponsiveGridItem = ({ children, classNames, item, style, name, self, pinned, screenshare, video, mute, wave, speaking, onClick }) => {
342
+ const { t } = useTranslation(meta.id);
343
+ const iconProps = {
344
+ wave: {
345
+ icon: "ph--hand-waving--duotone",
346
+ label: t("icon-wave.label"),
347
+ classNames: "animate-pulse bg-orange-500"
348
+ },
349
+ mute: {
350
+ icon: "ph--microphone-slash--regular",
351
+ label: t("icon-muted.label")
352
+ }
353
+ };
354
+ const props = wave && !pinned ? iconProps.wave : mute ? iconProps.mute : speaking ? iconProps.speaking : void 0;
355
+ const [speakingIndicator, setSpeakingIndicator] = useState2(speaking);
356
+ useEffect4(() => {
357
+ if (speaking) {
358
+ setSpeakingIndicator(true);
359
+ } else {
360
+ const timeout = setTimeout(() => {
361
+ setSpeakingIndicator(false);
362
+ }, 1e3);
363
+ return () => clearTimeout(timeout);
364
+ }
365
+ }, [
366
+ speaking
367
+ ]);
368
+ return /* @__PURE__ */ React5.createElement("div", {
369
+ className: mx4("dx-expander relative group", "rounded-md outline outline-2 outline-neutral-900 transition-[outline-color] duration-500", speakingIndicator ? "outline-green-500" : !video && "outline-separator", classNames),
370
+ style
371
+ }, children, onClick && /* @__PURE__ */ React5.createElement("div", {
372
+ className: "z-10 absolute top-1 right-1 flex"
373
+ }, /* @__PURE__ */ React5.createElement(IconButton, {
374
+ classNames: mx4("p-1 min-h-1 rounded-sm", groupHoverControlItemWithTransition),
375
+ iconOnly: true,
376
+ icon: pinned ? "ph--x--regular" : "ph--arrows-out--regular",
377
+ size: pinned ? 5 : 4,
378
+ label: pinned ? t("icon-unpin.label") : t("icon-pin.label"),
379
+ onClick: () => onClick?.(item)
380
+ })), name && /* @__PURE__ */ React5.createElement("div", {
381
+ className: "z-10 absolute bottom-1 left-8 right-1 flex justify-end gap-1 items-center"
382
+ }, screenshare && /* @__PURE__ */ React5.createElement(Icon, {
383
+ icon: "ph--broadcast--regular",
384
+ size: pinned ? 5 : 4
385
+ }), /* @__PURE__ */ React5.createElement("div", {
386
+ className: mx4("bg-neutral-800 text-neutral-100 py-0.5 truncate rounded-sm", pinned ? "px-2" : "px-1 text-xs")
387
+ }, name)), /* @__PURE__ */ React5.createElement("div", {
388
+ className: "z-10 absolute bottom-1 left-1 flex"
389
+ }, speaking && /* @__PURE__ */ React5.createElement(Waveform, {
390
+ active: true,
391
+ size: pinned ? 5 : 4
392
+ }) || props && /* @__PURE__ */ React5.createElement(IconButton, {
393
+ classNames: mx4("p-1 min-h-1 rounded-sm", props?.classNames),
394
+ icon: props?.icon,
395
+ label: props?.label,
396
+ size: pinned ? 5 : 4,
397
+ iconOnly: true
398
+ })));
399
+ };
400
+
401
+ // src/components/Participant/Participant.tsx
402
+ var SCREENSHARE_SUFFIX = "_screenshare";
403
+ var Participant = /* @__PURE__ */ memo2(({ item: user, debug, ...props }) => {
404
+ const call = useCapability(ThreadCapabilities.CallManager);
405
+ const self = useAtomValue(call.selfAtom);
406
+ const media = useAtomValue(call.mediaAtom);
407
+ const isSelf = self.id !== void 0 && user.id !== void 0 && user.id.startsWith(self.id);
408
+ const isScreenshare = user.id?.endsWith(SCREENSHARE_SUFFIX);
409
+ const pulledVideoStream = useMemo2(() => {
410
+ if (isSelf) {
411
+ return void 0;
412
+ }
413
+ const trackName = isScreenshare && user.tracks?.screenshareEnabled ? user.tracks?.screenshare : !isScreenshare && user.tracks?.videoEnabled ? user.tracks?.video : void 0;
414
+ return trackName ? media.pulledVideoStreams[trackName]?.stream : void 0;
415
+ }, [
416
+ isSelf,
417
+ isScreenshare,
418
+ media.pulledVideoStreams,
419
+ user.tracks?.screenshare,
420
+ user.tracks?.video,
421
+ user.tracks?.screenshareEnabled,
422
+ user.tracks?.videoEnabled
423
+ ]);
424
+ const videoStream = useMemo2(() => {
425
+ if (isSelf) {
426
+ return isScreenshare ? media.screenshareVideoStream : media.videoStream;
427
+ }
428
+ return pulledVideoStream;
429
+ }, [
430
+ isSelf,
431
+ isScreenshare,
432
+ media.videoStream,
433
+ media.screenshareVideoStream,
434
+ pulledVideoStream
435
+ ]);
436
+ return /* @__PURE__ */ React6.createElement(ResponsiveGridItem, {
437
+ ...props,
438
+ item: user,
439
+ name: user.name,
440
+ self: isSelf,
441
+ screenshare: !!media.screenshareVideoStream,
442
+ video: media.videoEnabled,
443
+ mute: user ? !user.tracks?.audioEnabled : false,
444
+ wave: user.raisedHand,
445
+ speaking: user.speaking,
446
+ debug
447
+ }, /* @__PURE__ */ React6.createElement(VideoObject, {
448
+ videoStream,
449
+ flip: isSelf && !isScreenshare,
450
+ contain: !!isScreenshare,
451
+ classNames: "rounded-md"
452
+ }));
453
+ });
454
+ Participant.displayName = "Participant";
455
+
456
+ // src/components/Participant/ParticipantGrid.tsx
457
+ import React7, { useEffect as useEffect5, useMemo as useMemo3, useState as useState3 } from "react";
458
+ var getId = (user) => user.id;
459
+ var ParticipantGrid = ({ classNames, self, users, fullscreen, debug }) => {
460
+ const [pinned, setPinned] = useState3();
461
+ const allUsers = useMemo3(() => {
462
+ const allUsers2 = [];
463
+ users.forEach((user) => {
464
+ if (!user.joined) {
465
+ return;
466
+ }
467
+ allUsers2.push({
468
+ ...user,
469
+ isSelf: user.id === self.id
470
+ });
471
+ if (user.tracks?.screenshareEnabled) {
472
+ const screenshare = {
473
+ ...user,
474
+ id: user.id + SCREENSHARE_SUFFIX,
475
+ tracks: {
476
+ ...user.tracks,
477
+ video: user.tracks.screenshare,
478
+ videoEnabled: user.tracks.screenshareEnabled
479
+ }
480
+ };
481
+ allUsers2.push(screenshare);
482
+ }
483
+ });
484
+ return allUsers2;
485
+ }, [
486
+ self,
487
+ users
488
+ ]);
489
+ useEffect5(() => {
490
+ if (pinned) {
491
+ if (!allUsers.find((user) => user.id === pinned)) {
492
+ setPinned(void 0);
493
+ }
494
+ }
495
+ }, [
496
+ pinned,
497
+ allUsers
498
+ ]);
499
+ const sortedUsers = allUsers.sort((a, b) => {
500
+ if (a.isSelf) {
501
+ return 1;
502
+ } else if (b.isSelf) {
503
+ return -1;
504
+ } else if (a.tracks?.screenshareEnabled) {
505
+ return -1;
506
+ } else if (b.tracks?.screenshareEnabled) {
507
+ return 1;
508
+ } else {
509
+ return 0;
510
+ }
511
+ });
512
+ return /* @__PURE__ */ React7.createElement(ResponsiveGrid, {
513
+ classNames,
514
+ Cell: Participant,
515
+ debug,
516
+ getId,
517
+ items: sortedUsers,
518
+ pinned,
519
+ autoHideGallery: fullscreen,
520
+ onPinnedChange: setPinned
521
+ });
522
+ };
523
+
524
+ // src/components/Call/Toolbar.tsx
525
+ import { useAtomValue as useAtomValue2 } from "@effect-atom/atom-react";
526
+ import React8 from "react";
527
+ import { useCapability as useCapability2 } from "@dxos/app-framework/ui";
528
+ import { useAppGraph } from "@dxos/app-toolkit/ui";
529
+ import { Obj } from "@dxos/echo";
530
+ import { Node, useActionRunner } from "@dxos/plugin-graph";
531
+ import { useActions, useNode } from "@dxos/plugin-graph";
532
+ import { Icon as Icon2, IconButton as IconButton2, Toolbar as NaturalToolbar, toLocalizedString, useTranslation as useTranslation2 } from "@dxos/react-ui";
533
+ import { groupHoverControlItemWithTransition as groupHoverControlItemWithTransition2, mx as mx5 } from "@dxos/ui-theme";
534
+ import { meta as meta2 } from "#meta";
535
+ import { ThreadCapabilities as ThreadCapabilities2 } from "#types";
536
+ var Toolbar = ({ classNames, channel, participants, autoHideControls = true, onJoin, onLeave }) => {
537
+ const { t } = useTranslation2(meta2.id);
538
+ const { graph } = useAppGraph();
539
+ const runAction = useActionRunner();
540
+ const call = useCapability2(ThreadCapabilities2.CallManager);
541
+ const media = useAtomValue2(call.mediaAtom);
542
+ const joined = useAtomValue2(call.joinedAtom);
543
+ const raisedHand = useAtomValue2(call.raisedHandAtom);
544
+ const node = useNode(graph, channel && Obj.getDXN(channel).toString());
545
+ const actions = useActions(graph, node?.id).filter((action) => action.properties.disposition === "toolbar");
546
+ const isScreensharing = media.screenshareTrack !== void 0;
547
+ const canSharescreen = typeof navigator.mediaDevices !== "undefined" && navigator.mediaDevices.getDisplayMedia !== void 0;
548
+ return /* @__PURE__ */ React8.createElement("div", {
549
+ className: mx5("z-20 flex justify-center m-8", autoHideControls && groupHoverControlItemWithTransition2)
550
+ }, /* @__PURE__ */ React8.createElement(NaturalToolbar.Root, {
551
+ classNames: [
552
+ "p-2 bg-modal-surface rounded-md shadow-md",
553
+ classNames
554
+ ]
555
+ }, /* @__PURE__ */ React8.createElement(ToggleButton, {
556
+ active: media.audioEnabled,
557
+ state: {
558
+ on: {
559
+ icon: "ph--microphone--regular",
560
+ label: t("mic-off.button"),
561
+ onClick: () => call.turnAudioOff(),
562
+ classNames: "bg-call-active"
563
+ },
564
+ off: {
565
+ icon: "ph--microphone-slash--duotone",
566
+ label: t("mic-on.button"),
567
+ onClick: () => call.turnAudioOn()
568
+ }
569
+ }
570
+ }), /* @__PURE__ */ React8.createElement(ToggleButton, {
571
+ active: media.videoEnabled,
572
+ state: {
573
+ on: {
574
+ icon: "ph--video-camera--regular",
575
+ label: t("camera-off.button"),
576
+ onClick: () => call.turnVideoOff()
577
+ },
578
+ off: {
579
+ icon: "ph--video-camera-slash--duotone",
580
+ label: t("camera-on.button"),
581
+ onClick: () => call.turnVideoOn()
582
+ }
583
+ }
584
+ }), participants !== void 0 && /* @__PURE__ */ React8.createElement("div", {
585
+ className: "flex justify-center items-center gap-2 w-[5rem] text-xs text-subdued"
586
+ }, /* @__PURE__ */ React8.createElement(Icon2, {
587
+ icon: "ph--users--regular"
588
+ }), /* @__PURE__ */ React8.createElement("div", null, participants)) || /* @__PURE__ */ React8.createElement(NaturalToolbar.Separator, {
589
+ variant: "gap"
590
+ }), joined && /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(ToggleButton, {
591
+ disabled: !canSharescreen,
592
+ active: isScreensharing,
593
+ state: {
594
+ on: {
595
+ icon: "ph--monitor--regular",
596
+ label: t("screenshare-off.button"),
597
+ onClick: () => call.turnScreenshareOff()
598
+ },
599
+ off: {
600
+ icon: "ph--monitor-arrow-up--duotone",
601
+ label: t("screenshare-on.button"),
602
+ onClick: () => call.turnScreenshareOn()
603
+ }
604
+ }
605
+ }), actions.filter((action) => Node.isAction(action)).map((action) => /* @__PURE__ */ React8.createElement(IconButton2, {
606
+ key: action.id,
607
+ ...defaultButtonProps,
608
+ icon: action.properties.icon,
609
+ label: toLocalizedString(action.properties.label, t),
610
+ classNames: action.properties.classNames,
611
+ onClick: () => node && void runAction(action, {
612
+ parent: node
613
+ })
614
+ })), /* @__PURE__ */ React8.createElement(ToggleButton, {
615
+ active: raisedHand,
616
+ state: {
617
+ on: {
618
+ icon: "ph--hand-waving--regular",
619
+ label: t("lower-hand.button"),
620
+ onClick: () => call.setRaisedHand(false)
621
+ },
622
+ off: {
623
+ icon: "ph--hand-palm--duotone",
624
+ label: t("raise-hand.button"),
625
+ onClick: () => call.setRaisedHand(true)
626
+ }
627
+ }
628
+ })), joined ? /* @__PURE__ */ React8.createElement(IconButton2, {
629
+ variant: "destructive",
630
+ icon: "ph--phone-x--regular",
631
+ label: t("leave-call.button"),
632
+ onClick: onLeave
633
+ }) : /* @__PURE__ */ React8.createElement(IconButton2, {
634
+ variant: "primary",
635
+ icon: "ph--phone-incoming--regular",
636
+ label: t("join-call.button"),
637
+ onClick: onJoin
638
+ })));
639
+ };
640
+ Toolbar.displayName = "MeetingToolbar";
641
+ var defaultButtonProps = {
642
+ size: 5,
643
+ iconOnly: true
644
+ };
645
+ var ToggleButton = ({ active, state }) => /* @__PURE__ */ React8.createElement(IconButton2, {
646
+ ...defaultButtonProps,
647
+ classNames: [
648
+ active ? state.on.classNames ?? "bg-call-active" : state.off.classNames
649
+ ],
650
+ icon: active ? state.on.icon : state.off.icon,
651
+ label: active ? state.on.label : state.off.label,
652
+ onClick: active ? state.on.onClick : state.off.onClick
653
+ });
654
+
655
+ // src/components/Call/Call.tsx
656
+ var CallRoot = ({ children }) => {
657
+ return /* @__PURE__ */ React9.createElement("div", {
658
+ className: "relative dx-container flex flex-col"
659
+ }, children);
660
+ };
661
+ CallRoot.displayName = "CallRoot";
662
+ var CallAudio = (_props) => {
663
+ const call = useCapability3(ThreadCapabilities3.CallManager);
664
+ const audioTracksToPlay = useAtomValue3(call.audioTracksToPlayAtom);
665
+ return /* @__PURE__ */ React9.createElement(AudioStream, {
666
+ tracks: audioTracksToPlay
667
+ });
668
+ };
669
+ CallAudio.displayName = "CallAudio";
670
+ var CallGrid = ({ fullscreen }) => {
671
+ const debug = useDebugMode();
672
+ const call = useCapability3(ThreadCapabilities3.CallManager);
673
+ const self = useAtomValue3(call.selfAtom);
674
+ const users = useAtomValue3(call.usersAtom);
675
+ return /* @__PURE__ */ React9.createElement("div", {
676
+ className: "grid grow p-4 dark:bg-neutral-900"
677
+ }, /* @__PURE__ */ React9.createElement(ParticipantGrid, {
678
+ self,
679
+ users,
680
+ debug,
681
+ fullscreen
682
+ }));
683
+ };
684
+ CallGrid.displayName = "CallGrid";
685
+ var CallToolbar = (props) => {
686
+ return /* @__PURE__ */ React9.createElement("div", {
687
+ className: "absolute bottom-0 left-0 right-0 flex justify-center"
688
+ }, /* @__PURE__ */ React9.createElement(Toolbar, {
689
+ isInRoom: true,
690
+ ...props
691
+ }));
692
+ };
693
+ CallToolbar.displayName = "CallToolbar";
694
+ var Call = {
695
+ Root: CallRoot,
696
+ Grid: CallGrid,
697
+ Audio: CallAudio,
698
+ Toolbar: CallToolbar
699
+ };
700
+
701
+ // src/components/Chat/Chat.tsx
702
+ import React11, { useLayoutEffect as useLayoutEffect2, useMemo as useMemo4, useRef as useRef4, useState as useState5 } from "react";
703
+ import { ScrollArea, useThemeContext as useThemeContext2, useTranslation as useTranslation4 } from "@dxos/react-ui";
704
+ import { MessageTextbox, Thread as ThreadComponent, threadLayout } from "@dxos/react-ui-thread";
705
+ import { createBasicExtensions as createBasicExtensions2, createThemeExtensions as createThemeExtensions2, listener } from "@dxos/ui-editor";
706
+ import { composable, composableProps, mx as mx7 } from "@dxos/ui-theme";
707
+ import { isNonNullable } from "@dxos/util";
708
+ import { meta as meta4 } from "#meta";
709
+
710
+ // src/components/MessagePanel/MessagePanel.tsx
711
+ import { EditorView } from "@codemirror/view";
712
+ import React10, { forwardRef as forwardRef2, useCallback as useCallback2, useEffect as useEffect6, useRef as useRef3, useState as useState4 } from "react";
713
+ import { Surface } from "@dxos/app-framework/ui";
714
+ import { AppSurface } from "@dxos/app-toolkit/ui";
715
+ import { Ref } from "@dxos/echo";
716
+ import { useObject } from "@dxos/echo-react";
717
+ import { PublicKey } from "@dxos/react-client";
718
+ import { useIdentity } from "@dxos/react-client/halo";
719
+ import { IconButton as IconButton3, useOnTransition, useThemeContext, useTranslation as useTranslation3 } from "@dxos/react-ui";
720
+ import { Card } from "@dxos/react-ui";
721
+ import { useTextEditor } from "@dxos/react-ui-editor";
722
+ import { MessageHeading, MessageRoot } from "@dxos/react-ui-thread";
723
+ import { createBasicExtensions, createThemeExtensions } from "@dxos/ui-editor";
724
+ import { hoverableControlItem, hoverableControls, hoverableFocusedWithinControls, mx as mx6 } from "@dxos/ui-theme";
725
+ import { useOnEditAnalytics } from "#hooks";
726
+ import { meta as meta3 } from "#meta";
727
+ var buttonGroupClassNames = "flex flex-row items-center gap-0.5 pe-2";
728
+ var buttonClassNames = "p-1! transition-opacity";
729
+ var MessagePanel = ({ message: messageOrRef, members, editable = false, onDelete, onAcceptProposal }) => {
730
+ const { t } = useTranslation3(meta3.id);
731
+ const [message, updateMessage] = useObject(messageOrRef);
732
+ const identity = useIdentity();
733
+ const [editing, setEditing] = useState4(false);
734
+ const textBlockIndex = message?.blocks.findIndex((block) => block._tag === "text") ?? -1;
735
+ const handleEdit = useCallback2(() => setEditing((editing2) => !editing2), []);
736
+ const handleDelete = useCallback2(() => message && onDelete?.(message.id), [
737
+ message,
738
+ onDelete
739
+ ]);
740
+ const handleAcceptProposal = useCallback2(() => message && onAcceptProposal?.(message.id), [
741
+ message,
742
+ onAcceptProposal
743
+ ]);
744
+ const handleTextBlockChange = useCallback2((newText) => {
745
+ updateMessage((m) => {
746
+ const targetBlock = m.blocks[textBlockIndex];
747
+ if (targetBlock && targetBlock._tag === "text") {
748
+ targetBlock.text = newText;
749
+ }
750
+ });
751
+ }, [
752
+ updateMessage,
753
+ textBlockIndex
754
+ ]);
755
+ const textBlock = message && textBlockIndex !== -1 ? message.blocks[textBlockIndex] : void 0;
756
+ useOnEditAnalytics(message, textBlock, !!editing);
757
+ if (!message) {
758
+ return null;
759
+ }
760
+ 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;
761
+ const messageMetadata = getMessageMetadata(message.id, senderIdentity, message.sender);
762
+ const userIsAuthor = identity?.did === messageMetadata.authorId;
763
+ const proposalBlock = message.blocks.find((block) => block._tag === "proposal");
764
+ const references = message.blocks.filter((block) => block._tag === "reference").map((block) => block.reference);
765
+ return /* @__PURE__ */ React10.createElement(MessageRoot, {
766
+ ...messageMetadata,
767
+ classNames: [
768
+ hoverableControls,
769
+ hoverableFocusedWithinControls
770
+ ]
771
+ }, /* @__PURE__ */ React10.createElement(MessageHeading, {
772
+ authorName: messageMetadata.authorName,
773
+ timestamp: messageMetadata.timestamp
774
+ }, /* @__PURE__ */ React10.createElement("div", {
775
+ className: buttonGroupClassNames
776
+ }, userIsAuthor && editable && /* @__PURE__ */ React10.createElement(IconButton3, {
777
+ "data-testid": editing ? "thread.message.save" : "thread.message.edit",
778
+ variant: "ghost",
779
+ icon: editing ? "ph--check--regular" : "ph--pencil-simple--regular",
780
+ iconOnly: true,
781
+ label: t(editing ? "save-message.label" : "edit-message.label"),
782
+ classNames: [
783
+ buttonClassNames,
784
+ hoverableControlItem
785
+ ],
786
+ onClick: handleEdit
787
+ }), proposalBlock && onAcceptProposal && /* @__PURE__ */ React10.createElement(IconButton3, {
788
+ "data-testid": "thread.message.accept",
789
+ variant: "ghost",
790
+ icon: "ph--check--regular",
791
+ iconOnly: true,
792
+ label: t("accept-proposal.label"),
793
+ classNames: [
794
+ buttonClassNames,
795
+ hoverableControlItem
796
+ ],
797
+ onClick: handleAcceptProposal
798
+ }), onDelete && /* @__PURE__ */ React10.createElement(IconButton3, {
799
+ "data-testid": "thread.message.delete",
800
+ variant: "ghost",
801
+ icon: "ph--x--regular",
802
+ iconOnly: true,
803
+ label: t("delete-message.label"),
804
+ classNames: [
805
+ buttonClassNames,
806
+ hoverableControlItem
807
+ ],
808
+ onClick: handleDelete
809
+ }))), textBlock && /* @__PURE__ */ React10.createElement(TextboxBlock, {
810
+ block: textBlock,
811
+ isAuthor: userIsAuthor,
812
+ editing,
813
+ onSave: handleTextBlockChange
814
+ }), proposalBlock && /* @__PURE__ */ React10.createElement(ProposalBlock, {
815
+ block: proposalBlock
816
+ }), Ref.Array.targets(references).map((reference, index) => /* @__PURE__ */ React10.createElement(MessagePart, {
817
+ key: index,
818
+ part: reference
819
+ })));
820
+ };
821
+ var MessagePart = ({ part }) => {
822
+ return /* @__PURE__ */ React10.createElement(MessageBlockObjectTile, {
823
+ subject: part
824
+ });
825
+ };
826
+ var TextboxBlock = ({ block, isAuthor, editing, onSave }) => {
827
+ const { themeMode } = useThemeContext();
828
+ const inMemoryContentRef = useRef3(block.text);
829
+ const handleDocumentChange = useCallback2((newState) => {
830
+ inMemoryContentRef.current = newState;
831
+ }, []);
832
+ const saveDocumentChange = useCallback2(() => {
833
+ onSave?.(inMemoryContentRef.current);
834
+ }, [
835
+ onSave
836
+ ]);
837
+ useOnTransition(editing, true, false, saveDocumentChange);
838
+ const { parentRef, focusAttributes, view } = useTextEditor(() => ({
839
+ initialValue: block.text,
840
+ extensions: [
841
+ createBasicExtensions({
842
+ readOnly: !isAuthor || !editing
843
+ }),
844
+ createThemeExtensions({
845
+ themeMode
846
+ }),
847
+ command,
848
+ EditorView.updateListener.of((update) => {
849
+ if (update.docChanged) {
850
+ handleDocumentChange(update.state.doc.toString());
851
+ }
852
+ })
853
+ ]
854
+ }), [
855
+ block.text,
856
+ editing,
857
+ isAuthor,
858
+ themeMode,
859
+ handleDocumentChange
860
+ ]);
861
+ useEffect6(() => {
862
+ editing && view?.focus();
863
+ }, [
864
+ editing,
865
+ view
866
+ ]);
867
+ return /* @__PURE__ */ React10.createElement("div", {
868
+ ref: parentRef,
869
+ className: "me-4",
870
+ ...focusAttributes
871
+ });
872
+ };
873
+ var ProposalBlock = ({ block }) => {
874
+ return /* @__PURE__ */ React10.createElement("div", {
875
+ className: "me-4 italic"
876
+ }, block.text);
877
+ };
878
+ var MessageBlockObjectTile = /* @__PURE__ */ forwardRef2(({ subject }, forwardedRef) => {
879
+ let title = subject.name ?? subject.title ?? subject.type ?? "Object";
880
+ if (typeof title !== "string") {
881
+ title = title?.content ?? "";
882
+ }
883
+ return /* @__PURE__ */ React10.createElement(Card.Root, {
884
+ className: mx6("grid col-span-3 py-1 pr-4", hoverableControls, hoverableFocusedWithinControls),
885
+ ref: forwardedRef
886
+ }, /* @__PURE__ */ React10.createElement(Surface.Surface, {
887
+ type: AppSurface.Card,
888
+ limit: 1,
889
+ data: {
890
+ subject
891
+ },
892
+ fallback: title
893
+ }));
894
+ });
895
+
896
+ // src/components/Chat/Chat.tsx
897
+ var Chat = composable(({ id, identity, members, messages, activity, onSend, autoFocusTextbox, current, orientation = "top", readOnly, ...props }, forwardedRef) => {
898
+ const { t } = useTranslation4(meta4.id);
899
+ const { themeMode } = useThemeContext2();
900
+ const scrollRef = useRef4(null);
901
+ const sentinelRef = useRef4(null);
902
+ const [autoFocus, setAutoFocus] = useState5(autoFocusTextbox);
903
+ const [_count, _setCount] = useState5(0);
904
+ const textboxMetadata = getMessageMetadata(id, identity);
905
+ const messageRef = useRef4("");
906
+ const extensions = useMemo4(() => [
907
+ createBasicExtensions2({
908
+ placeholder: t("message.placeholder")
909
+ }),
910
+ createThemeExtensions2({
911
+ themeMode
912
+ }),
913
+ listener({
914
+ onChange: ({ text }) => messageRef.current = text
915
+ }),
916
+ command
917
+ ], [
918
+ themeMode,
919
+ _count
920
+ ]);
921
+ const scrollToEnd = (behavior) => setTimeout(() => sentinelRef.current?.scrollIntoView({
922
+ behavior,
923
+ block: "end"
924
+ }), 10);
925
+ useLayoutEffect2(() => {
926
+ scrollToEnd("instant");
927
+ }, []);
928
+ const handleSend = () => {
929
+ const text = messageRef.current;
930
+ if (!text?.length) {
931
+ return false;
932
+ }
933
+ const accepted = onSend(text);
934
+ if (!accepted) {
935
+ return false;
936
+ }
937
+ messageRef.current = "";
938
+ setAutoFocus(true);
939
+ scrollToEnd("smooth");
940
+ _setCount((count) => count + 1);
941
+ return true;
942
+ };
943
+ const filteredMessages = messages.filter(isNonNullable);
944
+ const renderState = {
945
+ messages: filteredMessages,
946
+ members,
947
+ activity,
948
+ extensions,
949
+ autoFocus,
950
+ handleSend,
951
+ textboxMetadata,
952
+ scrollRef,
953
+ sentinelRef,
954
+ readOnly
955
+ };
956
+ return orientation === "bottom" ? /* @__PURE__ */ React11.createElement(ChannelLayout, {
957
+ ...composableProps(props, {
958
+ classNames: "flex flex-col bs-full min-h-0"
959
+ }),
960
+ id,
961
+ ref: forwardedRef,
962
+ state: renderState
963
+ }) : /* @__PURE__ */ React11.createElement(ThreadLayout, {
964
+ ...composableProps(props, {
965
+ classNames: "dx-container grid-rows-[1fr_min-content_min-content]"
966
+ }),
967
+ id,
968
+ current,
969
+ ref: forwardedRef,
970
+ state: renderState
971
+ });
972
+ });
973
+ var ThreadLayout = /* @__PURE__ */ React11.forwardRef(({ id, current, state, ...props }, ref) => {
974
+ const { t } = useTranslation4(meta4.id);
975
+ const { messages, members, activity, extensions, autoFocus, handleSend, textboxMetadata, sentinelRef, readOnly } = state;
976
+ return /* @__PURE__ */ React11.createElement(ThreadComponent.Root, {
977
+ ...props,
978
+ id,
979
+ current,
980
+ ref
981
+ }, /* @__PURE__ */ React11.createElement(ScrollArea.Root, {
982
+ classNames: "col-span-2",
983
+ orientation: "vertical"
984
+ }, /* @__PURE__ */ React11.createElement(ScrollArea.Viewport, {
985
+ ref: sentinelRef
986
+ }, /* @__PURE__ */ React11.createElement("div", {
987
+ className: mx7(threadLayout, "place-self-end")
988
+ }, messages.map((message) => /* @__PURE__ */ React11.createElement(MessagePanel, {
989
+ key: message.id,
990
+ message,
991
+ members
992
+ }))))), !readOnly && /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement(MessageTextbox, {
993
+ extensions,
994
+ autoFocus,
995
+ onSend: handleSend,
996
+ ...textboxMetadata
997
+ }), /* @__PURE__ */ React11.createElement(ThreadComponent.Status, {
998
+ activity
999
+ }, t("activity.message"))));
1000
+ });
1001
+ var ChannelLayout = /* @__PURE__ */ React11.forwardRef(({ id, state, ...props }, ref) => {
1002
+ const { t } = useTranslation4(meta4.id);
1003
+ const { messages, members, activity, extensions, autoFocus, handleSend, textboxMetadata, scrollRef, sentinelRef, readOnly } = state;
1004
+ return /* @__PURE__ */ React11.createElement("div", {
1005
+ ...props,
1006
+ id,
1007
+ ref
1008
+ }, /* @__PURE__ */ React11.createElement("div", {
1009
+ ref: scrollRef,
1010
+ className: "flex-1 min-h-0 overflow-y-auto"
1011
+ }, messages.map((message) => /* @__PURE__ */ React11.createElement("div", {
1012
+ key: message.id,
1013
+ className: "grid grid-cols-[var(--dx-rail-size)_1fr] w-full"
1014
+ }, /* @__PURE__ */ React11.createElement(MessagePanel, {
1015
+ message,
1016
+ members
1017
+ }))), /* @__PURE__ */ React11.createElement("div", {
1018
+ ref: sentinelRef
1019
+ })), !readOnly && /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement("div", {
1020
+ className: "shrink-0 grid grid-cols-[var(--dx-rail-size)_1fr]"
1021
+ }, /* @__PURE__ */ React11.createElement(MessageTextbox, {
1022
+ extensions,
1023
+ autoFocus,
1024
+ onSend: handleSend,
1025
+ ...textboxMetadata
1026
+ })), /* @__PURE__ */ React11.createElement("div", {
1027
+ className: "shrink-0 px-2 pb-1 text-xs text-description"
1028
+ }, activity ? t("activity.message") : null)));
1029
+ });
1030
+
1031
+ // src/components/CommentsPanel/CommentsPanel.tsx
1032
+ import React13, { useEffect as useEffect7 } from "react";
1033
+ import { Obj as Obj3, Relation as Relation2 } from "@dxos/echo";
1034
+ import { Icon as Icon3, Message, Trans, useTranslation as useTranslation6 } from "@dxos/react-ui";
1035
+ import { meta as meta6 } from "#meta";
1036
+
1037
+ // src/components/CommentsPanel/CommentsThread.tsx
1038
+ import React12, { useCallback as useCallback3, useMemo as useMemo5, useRef as useRef5, useState as useState6 } from "react";
1039
+ import { Obj as Obj2, Relation } from "@dxos/echo";
1040
+ import { useObject as useObject2 } from "@dxos/echo-react";
1041
+ import { getSpace, useMembers } from "@dxos/react-client/echo";
1042
+ import { useIdentity as useIdentity2 } from "@dxos/react-client/halo";
1043
+ import { IconButton as IconButton4, Tag, Tooltip, useThemeContext as useThemeContext3, useTranslation as useTranslation5 } from "@dxos/react-ui";
1044
+ import { MessageTextbox as MessageTextbox2, Thread as ThreadComponent2 } from "@dxos/react-ui-thread";
1045
+ import { createBasicExtensions as createBasicExtensions3, createThemeExtensions as createThemeExtensions3, listener as listener2 } from "@dxos/ui-editor";
1046
+ import { hoverableControlItem as hoverableControlItem2, hoverableControls as hoverableControls2, hoverableFocusedWithinControls as hoverableFocusedWithinControls2, mx as mx8 } from "@dxos/ui-theme";
1047
+ import { useStatus } from "#hooks";
1048
+ import { meta as meta5 } from "#meta";
1049
+ var CommentsThread = ({ anchor, current, onAttend, onComment, onResolve, onMessageDelete, onThreadDelete, onAcceptProposal }) => {
1050
+ const { themeMode } = useThemeContext3();
1051
+ const { t } = useTranslation5(meta5.id);
1052
+ const identity = useIdentity2();
1053
+ const space = getSpace(anchor);
1054
+ const members = useMembers(space?.id);
1055
+ const detached = !anchor.anchor;
1056
+ const thread = Relation.getSource(anchor);
1057
+ const [messages] = useObject2(thread, "messages");
1058
+ const activity = useStatus(space, Obj2.getDXN(thread).toString());
1059
+ const threadScrollRef = useRef5(null);
1060
+ const textboxMetadata = getMessageMetadata(Obj2.getDXN(thread).toString(), identity);
1061
+ const [state, setState] = useState6({});
1062
+ const messageRef = useRef5("");
1063
+ const extensions = useMemo5(() => [
1064
+ createBasicExtensions3({
1065
+ placeholder: t("message.placeholder")
1066
+ }),
1067
+ createThemeExtensions3({
1068
+ themeMode
1069
+ }),
1070
+ listener2({
1071
+ onChange: ({ text }) => messageRef.current = text
1072
+ }),
1073
+ command
1074
+ ], [
1075
+ state
1076
+ ]);
1077
+ const scrollToEnd = (behavior) => setTimeout(() => threadScrollRef.current?.scrollIntoView({
1078
+ behavior,
1079
+ block: "end"
1080
+ }), 10);
1081
+ const handleAttend = useCallback3(() => onAttend?.(anchor), [
1082
+ onAttend,
1083
+ anchor
1084
+ ]);
1085
+ const handleResolve = useCallback3(() => onResolve?.(anchor), [
1086
+ onResolve,
1087
+ anchor
1088
+ ]);
1089
+ const handleMessageDelete = useCallback3((id) => onMessageDelete?.(anchor, id), [
1090
+ onMessageDelete,
1091
+ anchor
1092
+ ]);
1093
+ const handleThreadDelete = useCallback3(() => onThreadDelete?.(anchor), [
1094
+ onThreadDelete,
1095
+ anchor
1096
+ ]);
1097
+ const handleAcceptProposal = useCallback3((id) => onAcceptProposal?.(anchor, id), [
1098
+ onAcceptProposal,
1099
+ anchor
1100
+ ]);
1101
+ const handleComment = useCallback3(() => {
1102
+ if (!messageRef.current) {
1103
+ return false;
1104
+ }
1105
+ onComment?.(anchor, messageRef.current);
1106
+ messageRef.current = "";
1107
+ scrollToEnd("instant");
1108
+ setState({});
1109
+ return true;
1110
+ }, [
1111
+ anchor,
1112
+ identity
1113
+ ]);
1114
+ return /* @__PURE__ */ React12.createElement(ThreadComponent2.Root, {
1115
+ id: Obj2.getDXN(thread).toString(),
1116
+ classNames: "pt-2 border-b border-subdued-separator last:border-none",
1117
+ current,
1118
+ onClickCapture: handleAttend,
1119
+ onFocusCapture: handleAttend
1120
+ }, /* @__PURE__ */ React12.createElement("div", {
1121
+ className: mx8("col-span-2 grid grid-cols-[var(--dx-rail-size)_1fr_min-content]", hoverableControls2, hoverableFocusedWithinControls2)
1122
+ }, detached ? /* @__PURE__ */ React12.createElement(Tooltip.Trigger, {
1123
+ asChild: true,
1124
+ content: t("detached-thread.label"),
1125
+ side: "top"
1126
+ }, /* @__PURE__ */ React12.createElement(ThreadComponent2.Header, {
1127
+ detached: true
1128
+ }, thread.name)) : /* @__PURE__ */ React12.createElement(ThreadComponent2.Header, null, thread.name), /* @__PURE__ */ React12.createElement("div", {
1129
+ className: buttonGroupClassNames
1130
+ }, thread.status === "staged" && /* @__PURE__ */ React12.createElement(Tag, {
1131
+ palette: "neutral"
1132
+ }, t("draft.button")), onResolve && !(thread?.status === "staged") && /* @__PURE__ */ React12.createElement(IconButton4, {
1133
+ "data-testid": "thread.resolve",
1134
+ variant: "ghost",
1135
+ icon: thread?.status === "resolved" ? "ph--check--fill" : "ph--check--regular",
1136
+ iconOnly: true,
1137
+ label: t("resolve-thread.label"),
1138
+ classNames: [
1139
+ buttonClassNames,
1140
+ thread?.status !== "resolved" && hoverableControlItem2
1141
+ ],
1142
+ onClick: handleResolve
1143
+ }), onThreadDelete && /* @__PURE__ */ React12.createElement(IconButton4, {
1144
+ "data-testid": "thread.delete",
1145
+ variant: "ghost",
1146
+ icon: "ph--x--regular",
1147
+ iconOnly: true,
1148
+ label: t("delete-thread.label"),
1149
+ classNames: [
1150
+ buttonClassNames,
1151
+ hoverableControlItem2
1152
+ ],
1153
+ onClick: handleThreadDelete
1154
+ }))), messages?.map((ref) => /* @__PURE__ */ React12.createElement(MessagePanel, {
1155
+ key: ref.dxn.toString(),
1156
+ editable: true,
1157
+ message: ref,
1158
+ members,
1159
+ onDelete: handleMessageDelete,
1160
+ onAcceptProposal: handleAcceptProposal
1161
+ })), /* @__PURE__ */ React12.createElement(MessageTextbox2, {
1162
+ extensions,
1163
+ onSend: handleComment,
1164
+ ...textboxMetadata
1165
+ }), /* @__PURE__ */ React12.createElement(ThreadComponent2.Status, {
1166
+ activity
1167
+ }, t("activity.message")), /* @__PURE__ */ React12.createElement("div", {
1168
+ className: "h-px -mt-px",
1169
+ ref: threadScrollRef
1170
+ }));
1171
+ };
1172
+
1173
+ // src/components/CommentsPanel/CommentsPanel.tsx
1174
+ var CommentsPanel = ({ anchors, currentId, showResolvedThreads, ...props }) => {
1175
+ const { t } = useTranslation6(meta6.id);
1176
+ const filteredAnchors = showResolvedThreads ? anchors.filter((anchor) => !!Relation2.getSource(anchor)) : anchors.filter((anchor) => {
1177
+ const thread = Relation2.getSource(anchor);
1178
+ return thread && thread.status !== "resolved";
1179
+ });
1180
+ useEffect7(() => {
1181
+ if (currentId) {
1182
+ document.getElementById(currentId)?.scrollIntoView({
1183
+ behavior: "smooth",
1184
+ block: "end"
1185
+ });
1186
+ }
1187
+ }, [
1188
+ currentId
1189
+ ]);
1190
+ if (filteredAnchors.length === 0) {
1191
+ return /* @__PURE__ */ React13.createElement("div", {
1192
+ className: "p-form-padding"
1193
+ }, /* @__PURE__ */ React13.createElement(Message.Root, null, /* @__PURE__ */ React13.createElement(Message.Content, null, /* @__PURE__ */ React13.createElement(Trans, {
1194
+ t,
1195
+ i18nKey: "no-comments.message",
1196
+ components: {
1197
+ commentIcon: /* @__PURE__ */ React13.createElement(Icon3, {
1198
+ icon: "ph--chat-text--regular",
1199
+ size: 4,
1200
+ classNames: "dx-icon-inline"
1201
+ })
1202
+ }
1203
+ }))));
1204
+ }
1205
+ return /* @__PURE__ */ React13.createElement("div", null, filteredAnchors.map((anchor) => {
1206
+ const thread = Relation2.getSource(anchor);
1207
+ const threadId = Obj3.getDXN(thread).toString();
1208
+ return /* @__PURE__ */ React13.createElement(CommentsThread, {
1209
+ key: threadId,
1210
+ anchor,
1211
+ current: currentId === threadId,
1212
+ ...props
1213
+ });
1214
+ }));
1215
+ };
1216
+
1217
+ // src/components/index.ts
1218
+ var ThreadSettings = lazy(() => import("../ThreadSettings-5Z5XIHG3.mjs"));
1219
+ export {
1220
+ Call,
1221
+ Chat,
1222
+ CommentsPanel,
1223
+ CommentsThread,
1224
+ MessagePanel,
1225
+ ThreadSettings,
1226
+ Toolbar,
1227
+ buttonClassNames,
1228
+ buttonGroupClassNames
1229
+ };
1230
+ //# sourceMappingURL=index.mjs.map