@dxos/plugin-thread 0.8.3 → 0.8.4-main.1068cf700f

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 (462) hide show
  1. package/dist/lib/browser/app-graph-builder-XFGLMIGK.mjs +189 -0
  2. package/dist/lib/browser/app-graph-builder-XFGLMIGK.mjs.map +7 -0
  3. package/dist/lib/browser/blueprint-definition-ACPH22F7.mjs +18 -0
  4. package/dist/lib/browser/blueprint-definition-ACPH22F7.mjs.map +7 -0
  5. package/dist/lib/browser/blueprints/index.mjs +8 -0
  6. package/dist/lib/browser/call-manager-GDGIKJKN.mjs +26 -0
  7. package/dist/lib/browser/call-manager-GDGIKJKN.mjs.map +7 -0
  8. package/dist/lib/browser/chunk-2FIHSX35.mjs +293 -0
  9. package/dist/lib/browser/chunk-2FIHSX35.mjs.map +7 -0
  10. package/dist/lib/browser/chunk-4EUEMHNI.mjs +1817 -0
  11. package/dist/lib/browser/chunk-4EUEMHNI.mjs.map +7 -0
  12. package/dist/lib/browser/{chunk-JKQUJOTX.mjs → chunk-CP7E2HRE.mjs} +3 -3
  13. package/dist/lib/browser/chunk-CP7E2HRE.mjs.map +7 -0
  14. package/dist/lib/browser/{chunk-4H4A264L.mjs → chunk-ERK254BS.mjs} +407 -305
  15. package/dist/lib/browser/chunk-ERK254BS.mjs.map +7 -0
  16. package/dist/lib/browser/chunk-ISCHODBV.mjs +106 -0
  17. package/dist/lib/browser/chunk-ISCHODBV.mjs.map +7 -0
  18. package/dist/lib/browser/chunk-J5LGTIGS.mjs +10 -0
  19. package/dist/lib/browser/chunk-JBB73URQ.mjs +184 -0
  20. package/dist/lib/browser/chunk-JBB73URQ.mjs.map +7 -0
  21. package/dist/lib/browser/chunk-RH7XTXSR.mjs +106 -0
  22. package/dist/lib/browser/chunk-RH7XTXSR.mjs.map +7 -0
  23. package/dist/lib/browser/index.mjs +164 -151
  24. package/dist/lib/browser/index.mjs.map +4 -4
  25. package/dist/lib/browser/markdown-YJCSOWXX.mjs +210 -0
  26. package/dist/lib/browser/markdown-YJCSOWXX.mjs.map +7 -0
  27. package/dist/lib/browser/meta.json +1 -1
  28. package/dist/lib/browser/operation-resolver-PROCP5L4.mjs +441 -0
  29. package/dist/lib/browser/operation-resolver-PROCP5L4.mjs.map +7 -0
  30. package/dist/lib/browser/react-root-FHK2SVPU.mjs +25 -0
  31. package/dist/lib/browser/react-root-FHK2SVPU.mjs.map +7 -0
  32. package/dist/lib/browser/react-surface-7MQA6VSH.mjs +111 -0
  33. package/dist/lib/browser/react-surface-7MQA6VSH.mjs.map +7 -0
  34. package/dist/lib/browser/repair-6OZ75AUU.mjs +38 -0
  35. package/dist/lib/browser/repair-6OZ75AUU.mjs.map +7 -0
  36. package/dist/lib/browser/settings-TWKOTGSU.mjs +33 -0
  37. package/dist/lib/browser/settings-TWKOTGSU.mjs.map +7 -0
  38. package/dist/lib/browser/state-SJR2GL5G.mjs +24 -0
  39. package/dist/lib/browser/state-SJR2GL5G.mjs.map +7 -0
  40. package/dist/lib/browser/types/index.mjs +10 -12
  41. package/dist/lib/node-esm/app-graph-builder-IN6VLJBO.mjs +190 -0
  42. package/dist/lib/node-esm/app-graph-builder-IN6VLJBO.mjs.map +7 -0
  43. package/dist/lib/node-esm/blueprint-definition-SXVKFUNV.mjs +19 -0
  44. package/dist/lib/node-esm/blueprint-definition-SXVKFUNV.mjs.map +7 -0
  45. package/dist/lib/node-esm/blueprints/index.mjs +9 -0
  46. package/dist/lib/node-esm/call-manager-36UAAQCJ.mjs +27 -0
  47. package/dist/lib/node-esm/call-manager-36UAAQCJ.mjs.map +7 -0
  48. package/dist/lib/node-esm/{chunk-PGRP3O4O.mjs → chunk-ABUFOZVX.mjs} +3 -3
  49. package/dist/lib/node-esm/chunk-ABUFOZVX.mjs.map +7 -0
  50. package/dist/lib/node-esm/chunk-G7PZNN3Z.mjs +185 -0
  51. package/dist/lib/node-esm/chunk-G7PZNN3Z.mjs.map +7 -0
  52. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
  53. package/dist/lib/node-esm/chunk-OKVE6CLS.mjs +107 -0
  54. package/dist/lib/node-esm/chunk-OKVE6CLS.mjs.map +7 -0
  55. package/dist/lib/node-esm/{chunk-WXNPD542.mjs → chunk-QP3KQOPQ.mjs} +406 -305
  56. package/dist/lib/node-esm/chunk-QP3KQOPQ.mjs.map +7 -0
  57. package/dist/lib/node-esm/chunk-RBRWHRHE.mjs +1818 -0
  58. package/dist/lib/node-esm/chunk-RBRWHRHE.mjs.map +7 -0
  59. package/dist/lib/node-esm/chunk-VBI32FGI.mjs +108 -0
  60. package/dist/lib/node-esm/chunk-VBI32FGI.mjs.map +7 -0
  61. package/dist/lib/node-esm/chunk-WMWUXWAS.mjs +294 -0
  62. package/dist/lib/node-esm/chunk-WMWUXWAS.mjs.map +7 -0
  63. package/dist/lib/node-esm/index.mjs +164 -151
  64. package/dist/lib/node-esm/index.mjs.map +4 -4
  65. package/dist/lib/node-esm/markdown-6LRP3PAP.mjs +211 -0
  66. package/dist/lib/node-esm/markdown-6LRP3PAP.mjs.map +7 -0
  67. package/dist/lib/node-esm/meta.json +1 -1
  68. package/dist/lib/node-esm/operation-resolver-LPEPV5BF.mjs +442 -0
  69. package/dist/lib/node-esm/operation-resolver-LPEPV5BF.mjs.map +7 -0
  70. package/dist/lib/node-esm/react-root-P5P4VGQJ.mjs +26 -0
  71. package/dist/lib/node-esm/react-root-P5P4VGQJ.mjs.map +7 -0
  72. package/dist/lib/node-esm/react-surface-M7VI5XG2.mjs +112 -0
  73. package/dist/lib/node-esm/react-surface-M7VI5XG2.mjs.map +7 -0
  74. package/dist/lib/node-esm/repair-6777EPOM.mjs +39 -0
  75. package/dist/lib/node-esm/repair-6777EPOM.mjs.map +7 -0
  76. package/dist/lib/node-esm/settings-5O254B3Z.mjs +34 -0
  77. package/dist/lib/node-esm/settings-5O254B3Z.mjs.map +7 -0
  78. package/dist/lib/node-esm/state-5R3TZJQE.mjs +25 -0
  79. package/dist/lib/node-esm/state-5R3TZJQE.mjs.map +7 -0
  80. package/dist/lib/node-esm/types/index.mjs +10 -12
  81. package/dist/types/src/ThreadPlugin.d.ts +2 -1
  82. package/dist/types/src/ThreadPlugin.d.ts.map +1 -1
  83. package/dist/types/src/blueprints/index.d.ts +2 -0
  84. package/dist/types/src/blueprints/index.d.ts.map +1 -0
  85. package/dist/types/src/blueprints/thread-blueprint.d.ts +21 -0
  86. package/dist/types/src/blueprints/thread-blueprint.d.ts.map +1 -0
  87. package/dist/types/src/calls/call-manager.d.ts +40 -30
  88. package/dist/types/src/calls/call-manager.d.ts.map +1 -1
  89. package/dist/types/src/calls/call-swarm-synchronizer.d.ts +2 -2
  90. package/dist/types/src/calls/call-swarm-synchronizer.d.ts.map +1 -1
  91. package/dist/types/src/calls/media-manager.d.ts +2 -2
  92. package/dist/types/src/calls/media-manager.d.ts.map +1 -1
  93. package/dist/types/src/calls/types.d.ts +1 -1
  94. package/dist/types/src/calls/types.d.ts.map +1 -1
  95. package/dist/types/src/calls/util/calls-service.d.ts +9 -4
  96. package/dist/types/src/calls/util/calls-service.d.ts.map +1 -1
  97. package/dist/types/src/calls/util/stub-media-streams.d.ts.map +1 -1
  98. package/dist/types/src/calls/util/task-scheduling.d.ts +2 -2
  99. package/dist/types/src/calls/util/task-scheduling.d.ts.map +1 -1
  100. package/dist/types/src/calls-service.stories.d.ts +23 -0
  101. package/dist/types/src/calls-service.stories.d.ts.map +1 -0
  102. package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts +6 -0
  103. package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts.map +1 -0
  104. package/dist/types/src/capabilities/app-graph-builder/index.d.ts +3 -0
  105. package/dist/types/src/capabilities/app-graph-builder/index.d.ts.map +1 -0
  106. package/dist/types/src/capabilities/blueprint-definition/blueprint-definition.d.ts +10 -0
  107. package/dist/types/src/capabilities/blueprint-definition/blueprint-definition.d.ts.map +1 -0
  108. package/dist/types/src/capabilities/blueprint-definition/index.d.ts +3 -0
  109. package/dist/types/src/capabilities/blueprint-definition/index.d.ts.map +1 -0
  110. package/dist/types/src/capabilities/call-manager/call-manager.d.ts +6 -0
  111. package/dist/types/src/capabilities/call-manager/call-manager.d.ts.map +1 -0
  112. package/dist/types/src/capabilities/call-manager/index.d.ts +3 -0
  113. package/dist/types/src/capabilities/call-manager/index.d.ts.map +1 -0
  114. package/dist/types/src/capabilities/index.d.ts +10 -15
  115. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  116. package/dist/types/src/capabilities/markdown/index.d.ts +3 -0
  117. package/dist/types/src/capabilities/markdown/index.d.ts.map +1 -0
  118. package/dist/types/src/capabilities/markdown/markdown.d.ts +5 -0
  119. package/dist/types/src/capabilities/markdown/markdown.d.ts.map +1 -0
  120. package/dist/types/src/capabilities/operation-resolver/index.d.ts +3 -0
  121. package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +1 -0
  122. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +5 -0
  123. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +1 -0
  124. package/dist/types/src/capabilities/react-root/index.d.ts +6 -0
  125. package/dist/types/src/capabilities/react-root/index.d.ts.map +1 -0
  126. package/dist/types/src/capabilities/react-root/react-root.d.ts +9 -0
  127. package/dist/types/src/capabilities/react-root/react-root.d.ts.map +1 -0
  128. package/dist/types/src/capabilities/react-surface/index.d.ts +3 -0
  129. package/dist/types/src/capabilities/react-surface/index.d.ts.map +1 -0
  130. package/dist/types/src/capabilities/react-surface/react-surface.d.ts +5 -0
  131. package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +1 -0
  132. package/dist/types/src/capabilities/repair/index.d.ts +3 -0
  133. package/dist/types/src/capabilities/repair/index.d.ts.map +1 -0
  134. package/dist/types/src/capabilities/repair/repair.d.ts +6 -0
  135. package/dist/types/src/capabilities/repair/repair.d.ts.map +1 -0
  136. package/dist/types/src/capabilities/settings/index.d.ts +3 -0
  137. package/dist/types/src/capabilities/settings/index.d.ts.map +1 -0
  138. package/dist/types/src/capabilities/settings/settings.d.ts +6 -0
  139. package/dist/types/src/capabilities/settings/settings.d.ts.map +1 -0
  140. package/dist/types/src/capabilities/state/index.d.ts +3 -0
  141. package/dist/types/src/capabilities/state/index.d.ts.map +1 -0
  142. package/dist/types/src/capabilities/state/state.d.ts +7 -0
  143. package/dist/types/src/capabilities/state/state.d.ts.map +1 -0
  144. package/dist/types/src/components/Call/Call.d.ts.map +1 -1
  145. package/dist/types/src/components/Call/Toolbar.d.ts +2 -2
  146. package/dist/types/src/components/Call/Toolbar.d.ts.map +1 -1
  147. package/dist/types/src/components/CallDebugPanel.d.ts +7 -0
  148. package/dist/types/src/components/CallDebugPanel.d.ts.map +1 -1
  149. package/dist/types/src/components/CallSidebar.d.ts.map +1 -1
  150. package/dist/types/src/components/ChannelContainer.d.ts +5 -6
  151. package/dist/types/src/components/ChannelContainer.d.ts.map +1 -1
  152. package/dist/types/src/components/ChannelContainer.stories.d.ts +159 -5
  153. package/dist/types/src/components/ChannelContainer.stories.d.ts.map +1 -1
  154. package/dist/types/src/components/Chat.stories.d.ts +162 -4
  155. package/dist/types/src/components/Chat.stories.d.ts.map +1 -1
  156. package/dist/types/src/components/ChatContainer.d.ts +8 -7
  157. package/dist/types/src/components/ChatContainer.d.ts.map +1 -1
  158. package/dist/types/src/components/Comments.stories.d.ts +160 -4
  159. package/dist/types/src/components/Comments.stories.d.ts.map +1 -1
  160. package/dist/types/src/components/CommentsContainer.d.ts +6 -6
  161. package/dist/types/src/components/CommentsContainer.d.ts.map +1 -1
  162. package/dist/types/src/components/CommentsThreadContainer.d.ts +14 -0
  163. package/dist/types/src/components/CommentsThreadContainer.d.ts.map +1 -0
  164. package/dist/types/src/components/Lobby/Lobby.d.ts.map +1 -1
  165. package/dist/types/src/components/Media/VideoObject.d.ts +3 -3
  166. package/dist/types/src/components/Media/VideoObject.d.ts.map +1 -1
  167. package/dist/types/src/components/Media/VideoObject.stories.d.ts +18 -4
  168. package/dist/types/src/components/Media/VideoObject.stories.d.ts.map +1 -1
  169. package/dist/types/src/components/MessageContainer.d.ts +7 -3
  170. package/dist/types/src/components/MessageContainer.d.ts.map +1 -1
  171. package/dist/types/src/components/Participant/Participant.d.ts.map +1 -1
  172. package/dist/types/src/components/Participant/ParticipantGrid.d.ts.map +1 -1
  173. package/dist/types/src/components/ResponsiveGrid/ResponsiveContainer.stories.d.ts +159 -3
  174. package/dist/types/src/components/ResponsiveGrid/ResponsiveContainer.stories.d.ts.map +1 -1
  175. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.stories.d.ts +161 -4
  176. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.stories.d.ts.map +1 -1
  177. package/dist/types/src/components/ResponsiveGrid/ResponsiveGridItem.d.ts.map +1 -1
  178. package/dist/types/src/components/ThreadCompanion.d.ts +5 -0
  179. package/dist/types/src/components/ThreadCompanion.d.ts.map +1 -0
  180. package/dist/types/src/components/ThreadSettings.d.ts +4 -2
  181. package/dist/types/src/components/ThreadSettings.d.ts.map +1 -1
  182. package/dist/types/src/components/command-extension.d.ts.map +1 -1
  183. package/dist/types/src/components/index.d.ts +4 -4
  184. package/dist/types/src/components/index.d.ts.map +1 -1
  185. package/dist/types/src/components/testing.d.ts +3 -2
  186. package/dist/types/src/components/testing.d.ts.map +1 -1
  187. package/dist/types/src/extensions/threads.d.ts +8 -3
  188. package/dist/types/src/extensions/threads.d.ts.map +1 -1
  189. package/dist/types/src/functions/create-proposals.d.ts +13 -0
  190. package/dist/types/src/functions/create-proposals.d.ts.map +1 -0
  191. package/dist/types/src/functions/index.d.ts +2 -0
  192. package/dist/types/src/functions/index.d.ts.map +1 -0
  193. package/dist/types/src/hooks/analytics.d.ts +2 -3
  194. package/dist/types/src/hooks/analytics.d.ts.map +1 -1
  195. package/dist/types/src/hooks/index.d.ts +3 -0
  196. package/dist/types/src/hooks/index.d.ts.map +1 -1
  197. package/dist/types/src/hooks/useBlackCanvasStreamTrack.d.ts +2 -0
  198. package/dist/types/src/hooks/useBlackCanvasStreamTrack.d.ts.map +1 -0
  199. package/dist/types/src/hooks/useInaudibleAudioStreamTrack.d.ts +2 -0
  200. package/dist/types/src/hooks/useInaudibleAudioStreamTrack.d.ts.map +1 -0
  201. package/dist/types/src/hooks/useVideoStreamTrack.d.ts +3 -0
  202. package/dist/types/src/hooks/useVideoStreamTrack.d.ts.map +1 -0
  203. package/dist/types/src/index.d.ts +1 -1
  204. package/dist/types/src/index.d.ts.map +1 -1
  205. package/dist/types/src/meta.d.ts +3 -4
  206. package/dist/types/src/meta.d.ts.map +1 -1
  207. package/dist/types/src/testing/stories.d.ts +2 -1
  208. package/dist/types/src/testing/stories.d.ts.map +1 -1
  209. package/dist/types/src/translations.d.ts +146 -194
  210. package/dist/types/src/translations.d.ts.map +1 -1
  211. package/dist/types/src/types/Channel.d.ts +695 -0
  212. package/dist/types/src/types/Channel.d.ts.map +1 -0
  213. package/dist/types/src/types/capabilities.d.ts +23 -0
  214. package/dist/types/src/types/capabilities.d.ts.map +1 -0
  215. package/dist/types/src/types/index.d.ts +2 -1
  216. package/dist/types/src/types/index.d.ts.map +1 -1
  217. package/dist/types/src/types/types.d.ts +3224 -320
  218. package/dist/types/src/types/types.d.ts.map +1 -1
  219. package/dist/types/src/util.d.ts +17 -2
  220. package/dist/types/src/util.d.ts.map +1 -1
  221. package/dist/types/tsconfig.tsbuildinfo +1 -1
  222. package/package.json +93 -67
  223. package/src/ThreadPlugin.tsx +107 -143
  224. package/src/blueprints/index.ts +5 -0
  225. package/src/blueprints/thread-blueprint.ts +32 -0
  226. package/src/calls/call-manager.ts +78 -50
  227. package/src/calls/call-swarm-synchronizer.ts +3 -3
  228. package/src/calls/media-manager.ts +77 -41
  229. package/src/calls/types.ts +8 -4
  230. package/src/calls/util/calls-service.ts +73 -19
  231. package/src/calls/util/stub-media-streams.ts +63 -9
  232. package/src/calls/util/task-scheduling.ts +4 -4
  233. package/src/calls-service.stories.tsx +229 -0
  234. package/src/capabilities/app-graph-builder/app-graph-builder.ts +202 -0
  235. package/src/capabilities/app-graph-builder/index.ts +7 -0
  236. package/src/capabilities/blueprint-definition/blueprint-definition.ts +24 -0
  237. package/src/capabilities/blueprint-definition/index.ts +7 -0
  238. package/src/capabilities/call-manager/call-manager.ts +26 -0
  239. package/src/capabilities/call-manager/index.ts +7 -0
  240. package/src/capabilities/index.ts +10 -12
  241. package/src/capabilities/markdown/index.ts +7 -0
  242. package/src/capabilities/markdown/markdown.ts +83 -0
  243. package/src/capabilities/operation-resolver/index.ts +7 -0
  244. package/src/capabilities/operation-resolver/operation-resolver.ts +400 -0
  245. package/src/capabilities/react-root/index.ts +7 -0
  246. package/src/capabilities/react-root/react-root.tsx +20 -0
  247. package/src/capabilities/react-surface/index.ts +7 -0
  248. package/src/capabilities/react-surface/react-surface.tsx +98 -0
  249. package/src/capabilities/repair/index.ts +7 -0
  250. package/src/capabilities/repair/repair.ts +51 -0
  251. package/src/capabilities/settings/index.ts +7 -0
  252. package/src/capabilities/settings/settings.ts +34 -0
  253. package/src/capabilities/state/index.ts +7 -0
  254. package/src/capabilities/state/state.ts +22 -0
  255. package/src/components/Call/Call.tsx +11 -6
  256. package/src/components/Call/Toolbar.tsx +42 -33
  257. package/src/components/CallDebugPanel.tsx +114 -57
  258. package/src/components/CallSidebar.tsx +6 -3
  259. package/src/components/ChannelContainer.stories.tsx +23 -21
  260. package/src/components/ChannelContainer.tsx +47 -38
  261. package/src/components/Chat.stories.tsx +37 -39
  262. package/src/components/ChatContainer.tsx +56 -44
  263. package/src/components/Comments.stories.tsx +63 -55
  264. package/src/components/CommentsContainer.tsx +20 -16
  265. package/src/components/CommentsThreadContainer.tsx +173 -0
  266. package/src/components/Lobby/Lobby.tsx +10 -8
  267. package/src/components/Media/AudioStream.tsx +2 -2
  268. package/src/components/Media/VideoObject.stories.tsx +36 -28
  269. package/src/components/Media/VideoObject.tsx +2 -2
  270. package/src/components/MessageContainer.tsx +117 -68
  271. package/src/components/Participant/Participant.tsx +34 -15
  272. package/src/components/Participant/ParticipantGrid.tsx +2 -1
  273. package/src/components/ResponsiveGrid/ResponsiveContainer.stories.tsx +9 -9
  274. package/src/components/ResponsiveGrid/ResponsiveContainer.tsx +3 -3
  275. package/src/components/ResponsiveGrid/ResponsiveGrid.stories.tsx +45 -43
  276. package/src/components/ResponsiveGrid/ResponsiveGrid.tsx +7 -7
  277. package/src/components/ResponsiveGrid/ResponsiveGridItem.tsx +10 -7
  278. package/src/components/ThreadCompanion.tsx +194 -0
  279. package/src/components/ThreadSettings.tsx +11 -6
  280. package/src/components/command-extension.ts +7 -4
  281. package/src/components/index.ts +5 -8
  282. package/src/components/testing.ts +28 -8
  283. package/src/extensions/threads.ts +88 -44
  284. package/src/functions/create-proposals.ts +57 -0
  285. package/src/functions/index.ts +5 -0
  286. package/src/hooks/analytics.ts +21 -21
  287. package/src/hooks/index.ts +4 -0
  288. package/src/hooks/useBlackCanvasStreamTrack.tsx +27 -0
  289. package/src/hooks/useDebugMode.ts +1 -1
  290. package/src/hooks/useInaudibleAudioStreamTrack.tsx +27 -0
  291. package/src/hooks/useVideoStreamTrack.tsx +36 -0
  292. package/src/index.ts +1 -1
  293. package/src/meta.ts +11 -7
  294. package/src/testing/stories.ts +23 -17
  295. package/src/translations.ts +18 -10
  296. package/src/types/Channel.ts +30 -0
  297. package/src/types/capabilities.ts +34 -0
  298. package/src/types/index.ts +2 -1
  299. package/src/types/types.ts +171 -75
  300. package/src/typings/peermetrics-webrtc-stats.d.ts +17 -1
  301. package/src/typings.d.ts +8 -0
  302. package/src/util.ts +1 -1
  303. package/dist/lib/browser/ChannelContainer-PKFBVENP.mjs +0 -15
  304. package/dist/lib/browser/ChatContainer-RSOKYAMK.mjs +0 -14
  305. package/dist/lib/browser/app-graph-builder-OY7R7EJP.mjs +0 -171
  306. package/dist/lib/browser/app-graph-builder-OY7R7EJP.mjs.map +0 -7
  307. package/dist/lib/browser/call-manager-APQAZWHT.mjs +0 -23
  308. package/dist/lib/browser/call-manager-APQAZWHT.mjs.map +0 -7
  309. package/dist/lib/browser/chunk-4H4A264L.mjs.map +0 -7
  310. package/dist/lib/browser/chunk-5P5BH5GE.mjs +0 -88
  311. package/dist/lib/browser/chunk-5P5BH5GE.mjs.map +0 -7
  312. package/dist/lib/browser/chunk-6NBVNXTM.mjs +0 -21
  313. package/dist/lib/browser/chunk-6NBVNXTM.mjs.map +0 -7
  314. package/dist/lib/browser/chunk-AEXWNS6Z.mjs +0 -128
  315. package/dist/lib/browser/chunk-AEXWNS6Z.mjs.map +0 -7
  316. package/dist/lib/browser/chunk-IIUTBDVB.mjs +0 -17
  317. package/dist/lib/browser/chunk-IIUTBDVB.mjs.map +0 -7
  318. package/dist/lib/browser/chunk-JKQUJOTX.mjs.map +0 -7
  319. package/dist/lib/browser/chunk-PG5CTFKK.mjs +0 -550
  320. package/dist/lib/browser/chunk-PG5CTFKK.mjs.map +0 -7
  321. package/dist/lib/browser/chunk-R5MDLUPC.mjs +0 -18
  322. package/dist/lib/browser/chunk-R5MDLUPC.mjs.map +0 -7
  323. package/dist/lib/browser/chunk-TAFSCSUR.mjs +0 -351
  324. package/dist/lib/browser/chunk-TAFSCSUR.mjs.map +0 -7
  325. package/dist/lib/browser/chunk-XZKBN3NS.mjs +0 -983
  326. package/dist/lib/browser/chunk-XZKBN3NS.mjs.map +0 -7
  327. package/dist/lib/browser/intent-resolver-FK2MDVDT.mjs +0 -353
  328. package/dist/lib/browser/intent-resolver-FK2MDVDT.mjs.map +0 -7
  329. package/dist/lib/browser/markdown-TE5SWWNJ.mjs +0 -169
  330. package/dist/lib/browser/markdown-TE5SWWNJ.mjs.map +0 -7
  331. package/dist/lib/browser/react-root-NK3A4VG7.mjs +0 -27
  332. package/dist/lib/browser/react-root-NK3A4VG7.mjs.map +0 -7
  333. package/dist/lib/browser/react-surface-VXUJKSOG.mjs +0 -108
  334. package/dist/lib/browser/react-surface-VXUJKSOG.mjs.map +0 -7
  335. package/dist/lib/browser/settings-RB2RSLXV.mjs +0 -22
  336. package/dist/lib/browser/settings-RB2RSLXV.mjs.map +0 -7
  337. package/dist/lib/browser/state-RKL5MSDP.mjs +0 -34
  338. package/dist/lib/browser/state-RKL5MSDP.mjs.map +0 -7
  339. package/dist/lib/node/ChannelContainer-YS5YT2ML.cjs +0 -36
  340. package/dist/lib/node/ChannelContainer-YS5YT2ML.cjs.map +0 -7
  341. package/dist/lib/node/ChatContainer-GCOM3M56.cjs +0 -35
  342. package/dist/lib/node/ChatContainer-GCOM3M56.cjs.map +0 -7
  343. package/dist/lib/node/app-graph-builder-PBHJNDQY.cjs +0 -179
  344. package/dist/lib/node/app-graph-builder-PBHJNDQY.cjs.map +0 -7
  345. package/dist/lib/node/call-manager-HV2XJW5O.cjs +0 -37
  346. package/dist/lib/node/call-manager-HV2XJW5O.cjs.map +0 -7
  347. package/dist/lib/node/chunk-44I33JDT.cjs +0 -1731
  348. package/dist/lib/node/chunk-44I33JDT.cjs.map +0 -7
  349. package/dist/lib/node/chunk-4YSNVPWU.cjs +0 -37
  350. package/dist/lib/node/chunk-4YSNVPWU.cjs.map +0 -7
  351. package/dist/lib/node/chunk-E3WBZTTI.cjs +0 -371
  352. package/dist/lib/node/chunk-E3WBZTTI.cjs.map +0 -7
  353. package/dist/lib/node/chunk-ERG7G6FF.cjs +0 -59
  354. package/dist/lib/node/chunk-ERG7G6FF.cjs.map +0 -7
  355. package/dist/lib/node/chunk-FUXJAVFZ.cjs +0 -108
  356. package/dist/lib/node/chunk-FUXJAVFZ.cjs.map +0 -7
  357. package/dist/lib/node/chunk-HLMCEE5K.cjs +0 -41
  358. package/dist/lib/node/chunk-HLMCEE5K.cjs.map +0 -7
  359. package/dist/lib/node/chunk-IP533AMV.cjs +0 -554
  360. package/dist/lib/node/chunk-IP533AMV.cjs.map +0 -7
  361. package/dist/lib/node/chunk-LR5NENBE.cjs +0 -54
  362. package/dist/lib/node/chunk-LR5NENBE.cjs.map +0 -7
  363. package/dist/lib/node/chunk-UM36TPCT.cjs +0 -984
  364. package/dist/lib/node/chunk-UM36TPCT.cjs.map +0 -7
  365. package/dist/lib/node/chunk-ZGDN3XBR.cjs +0 -149
  366. package/dist/lib/node/chunk-ZGDN3XBR.cjs.map +0 -7
  367. package/dist/lib/node/index.cjs +0 -310
  368. package/dist/lib/node/index.cjs.map +0 -7
  369. package/dist/lib/node/intent-resolver-SYSJ5SJG.cjs +0 -363
  370. package/dist/lib/node/intent-resolver-SYSJ5SJG.cjs.map +0 -7
  371. package/dist/lib/node/markdown-GQIPJS2F.cjs +0 -178
  372. package/dist/lib/node/markdown-GQIPJS2F.cjs.map +0 -7
  373. package/dist/lib/node/meta.json +0 -1
  374. package/dist/lib/node/react-root-6HHDMULJ.cjs +0 -51
  375. package/dist/lib/node/react-root-6HHDMULJ.cjs.map +0 -7
  376. package/dist/lib/node/react-surface-NBH42NN2.cjs +0 -122
  377. package/dist/lib/node/react-surface-NBH42NN2.cjs.map +0 -7
  378. package/dist/lib/node/settings-4LQSFEDK.cjs +0 -36
  379. package/dist/lib/node/settings-4LQSFEDK.cjs.map +0 -7
  380. package/dist/lib/node/state-IY5XX3H2.cjs +0 -50
  381. package/dist/lib/node/state-IY5XX3H2.cjs.map +0 -7
  382. package/dist/lib/node/types/index.cjs +0 -38
  383. package/dist/lib/node/types/index.cjs.map +0 -7
  384. package/dist/lib/node-esm/ChannelContainer-O4QJII2P.mjs +0 -16
  385. package/dist/lib/node-esm/ChatContainer-F6CSADV7.mjs +0 -15
  386. package/dist/lib/node-esm/app-graph-builder-BAHBHYWI.mjs +0 -172
  387. package/dist/lib/node-esm/app-graph-builder-BAHBHYWI.mjs.map +0 -7
  388. package/dist/lib/node-esm/call-manager-UUYXLF4T.mjs +0 -24
  389. package/dist/lib/node-esm/call-manager-UUYXLF4T.mjs.map +0 -7
  390. package/dist/lib/node-esm/chunk-2RNIPFDA.mjs +0 -984
  391. package/dist/lib/node-esm/chunk-2RNIPFDA.mjs.map +0 -7
  392. package/dist/lib/node-esm/chunk-ESQC6SYE.mjs +0 -19
  393. package/dist/lib/node-esm/chunk-ESQC6SYE.mjs.map +0 -7
  394. package/dist/lib/node-esm/chunk-K4KAUOKT.mjs +0 -19
  395. package/dist/lib/node-esm/chunk-K4KAUOKT.mjs.map +0 -7
  396. package/dist/lib/node-esm/chunk-O3V45YJP.mjs +0 -90
  397. package/dist/lib/node-esm/chunk-O3V45YJP.mjs.map +0 -7
  398. package/dist/lib/node-esm/chunk-O63QJPQX.mjs +0 -23
  399. package/dist/lib/node-esm/chunk-O63QJPQX.mjs.map +0 -7
  400. package/dist/lib/node-esm/chunk-P6RLFCNT.mjs +0 -352
  401. package/dist/lib/node-esm/chunk-P6RLFCNT.mjs.map +0 -7
  402. package/dist/lib/node-esm/chunk-PGRP3O4O.mjs.map +0 -7
  403. package/dist/lib/node-esm/chunk-UJMPYKT3.mjs +0 -129
  404. package/dist/lib/node-esm/chunk-UJMPYKT3.mjs.map +0 -7
  405. package/dist/lib/node-esm/chunk-UZWVVFT3.mjs +0 -551
  406. package/dist/lib/node-esm/chunk-UZWVVFT3.mjs.map +0 -7
  407. package/dist/lib/node-esm/chunk-WXNPD542.mjs.map +0 -7
  408. package/dist/lib/node-esm/intent-resolver-BU73VYW3.mjs +0 -354
  409. package/dist/lib/node-esm/intent-resolver-BU73VYW3.mjs.map +0 -7
  410. package/dist/lib/node-esm/markdown-HJUWNBLS.mjs +0 -170
  411. package/dist/lib/node-esm/markdown-HJUWNBLS.mjs.map +0 -7
  412. package/dist/lib/node-esm/react-root-RUXOAQNW.mjs +0 -28
  413. package/dist/lib/node-esm/react-root-RUXOAQNW.mjs.map +0 -7
  414. package/dist/lib/node-esm/react-surface-ELXFYKP6.mjs +0 -109
  415. package/dist/lib/node-esm/react-surface-ELXFYKP6.mjs.map +0 -7
  416. package/dist/lib/node-esm/settings-EA7DFSM6.mjs +0 -23
  417. package/dist/lib/node-esm/settings-EA7DFSM6.mjs.map +0 -7
  418. package/dist/lib/node-esm/state-6AUTNROZ.mjs +0 -35
  419. package/dist/lib/node-esm/state-6AUTNROZ.mjs.map +0 -7
  420. package/dist/types/src/capabilities/app-graph-builder.d.ts +0 -4
  421. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +0 -1
  422. package/dist/types/src/capabilities/call-manager.d.ts +0 -5
  423. package/dist/types/src/capabilities/call-manager.d.ts.map +0 -1
  424. package/dist/types/src/capabilities/capabilities.d.ts +0 -27
  425. package/dist/types/src/capabilities/capabilities.d.ts.map +0 -1
  426. package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
  427. package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
  428. package/dist/types/src/capabilities/markdown.d.ts +0 -4
  429. package/dist/types/src/capabilities/markdown.d.ts.map +0 -1
  430. package/dist/types/src/capabilities/react-root.d.ts +0 -7
  431. package/dist/types/src/capabilities/react-root.d.ts.map +0 -1
  432. package/dist/types/src/capabilities/react-surface.d.ts +0 -4
  433. package/dist/types/src/capabilities/react-surface.d.ts.map +0 -1
  434. package/dist/types/src/capabilities/settings.d.ts +0 -4
  435. package/dist/types/src/capabilities/settings.d.ts.map +0 -1
  436. package/dist/types/src/capabilities/state.d.ts +0 -7
  437. package/dist/types/src/capabilities/state.d.ts.map +0 -1
  438. package/dist/types/src/components/CommentContainer.d.ts +0 -13
  439. package/dist/types/src/components/CommentContainer.d.ts.map +0 -1
  440. package/dist/types/src/components/ThreadComplementary.d.ts +0 -5
  441. package/dist/types/src/components/ThreadComplementary.d.ts.map +0 -1
  442. package/dist/types/src/peers.stories.d.ts +0 -11
  443. package/dist/types/src/peers.stories.d.ts.map +0 -1
  444. package/dist/types/src/types/schema.d.ts +0 -133
  445. package/dist/types/src/types/schema.d.ts.map +0 -1
  446. package/src/capabilities/app-graph-builder.ts +0 -180
  447. package/src/capabilities/call-manager.ts +0 -19
  448. package/src/capabilities/capabilities.ts +0 -33
  449. package/src/capabilities/intent-resolver.ts +0 -296
  450. package/src/capabilities/markdown.ts +0 -68
  451. package/src/capabilities/react-root.tsx +0 -17
  452. package/src/capabilities/react-surface.tsx +0 -88
  453. package/src/capabilities/settings.ts +0 -19
  454. package/src/capabilities/state.ts +0 -25
  455. package/src/components/CommentContainer.tsx +0 -198
  456. package/src/components/ThreadComplementary.tsx +0 -151
  457. package/src/peers.stories.tsx +0 -189
  458. package/src/types/schema.ts +0 -33
  459. /package/dist/lib/browser/{ChannelContainer-PKFBVENP.mjs.map → blueprints/index.mjs.map} +0 -0
  460. /package/dist/lib/browser/{ChatContainer-RSOKYAMK.mjs.map → chunk-J5LGTIGS.mjs.map} +0 -0
  461. /package/dist/lib/node-esm/{ChannelContainer-O4QJII2P.mjs.map → blueprints/index.mjs.map} +0 -0
  462. /package/dist/lib/node-esm/{ChatContainer-F6CSADV7.mjs.map → chunk-HSLMI22Q.mjs.map} +0 -0
@@ -0,0 +1,1818 @@
1
+ import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
+ import {
3
+ useDebugMode,
4
+ useOnEditAnalytics,
5
+ useStatus
6
+ } from "./chunk-G7PZNN3Z.mjs";
7
+ import {
8
+ getMessageMetadata
9
+ } from "./chunk-ABUFOZVX.mjs";
10
+ import {
11
+ ThreadCapabilities,
12
+ ThreadOperation,
13
+ meta
14
+ } from "./chunk-WMWUXWAS.mjs";
15
+
16
+ // src/components/Call/Call.tsx
17
+ import { useAtomValue as useAtomValue3 } from "@effect-atom/atom-react";
18
+ import React9 from "react";
19
+ import { useCapability as useCapability3 } from "@dxos/app-framework/ui";
20
+
21
+ // src/components/Media/AudioStream.tsx
22
+ import React, { useEffect, useRef } from "react";
23
+ var AudioStream = ({ tracks }) => {
24
+ const mediaStreamRef = useRef(new MediaStream());
25
+ const ref = useRef(null);
26
+ useEffect(() => {
27
+ const audio = ref.current;
28
+ if (!audio) {
29
+ return;
30
+ }
31
+ const mediaStream = mediaStreamRef.current;
32
+ audio.srcObject = mediaStream;
33
+ }, []);
34
+ const resetSrcObject = () => {
35
+ const audio = ref.current;
36
+ const mediaStream = mediaStreamRef.current;
37
+ if (!audio || !mediaStream) {
38
+ return;
39
+ }
40
+ audio.addEventListener("canplay", () => audio.play(), {
41
+ once: true
42
+ });
43
+ audio.srcObject = mediaStream;
44
+ };
45
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("audio", {
46
+ ref,
47
+ autoPlay: true
48
+ }), tracks.map((track) => /* @__PURE__ */ React.createElement(AudioTrack, {
49
+ key: track.id,
50
+ track,
51
+ mediaStream: mediaStreamRef.current,
52
+ resetSrcObject
53
+ })));
54
+ };
55
+ var AudioTrack = ({ track, mediaStream, resetSrcObject }) => {
56
+ useEffect(() => {
57
+ const currentTrack = track;
58
+ mediaStream.addTrack(currentTrack);
59
+ resetSrcObject();
60
+ return () => {
61
+ mediaStream.removeTrack(currentTrack);
62
+ resetSrcObject();
63
+ };
64
+ }, [
65
+ track,
66
+ mediaStream
67
+ ]);
68
+ return null;
69
+ };
70
+
71
+ // src/components/Media/VideoObject.tsx
72
+ import React2, { forwardRef, memo, useEffect as useEffect2, useRef as useRef2 } from "react";
73
+ import { mx } from "@dxos/ui-theme";
74
+ var VideoObject = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef(({ videoStream, classNames, flip, contain, ...rest }, ref) => {
75
+ const internalRef = useRef2(null);
76
+ useEffect2(() => {
77
+ const video = internalRef.current;
78
+ if (video && videoStream) {
79
+ video.srcObject = videoStream;
80
+ video.setAttribute("autoplay", "true");
81
+ video.setAttribute("playsinline", "true");
82
+ }
83
+ }, [
84
+ videoStream,
85
+ internalRef.current
86
+ ]);
87
+ return /* @__PURE__ */ React2.createElement("video", {
88
+ className: mx("is-full aspect-video", flip && "scale-x-[-1]", contain ? "object-contain" : "object-cover", classNames),
89
+ ref: (v) => {
90
+ internalRef.current = v;
91
+ if (ref === null) {
92
+ return;
93
+ }
94
+ if (typeof ref === "function") {
95
+ ref(v);
96
+ } else {
97
+ ref.current = v;
98
+ }
99
+ },
100
+ ...rest
101
+ });
102
+ }));
103
+ VideoObject.displayName = "VideoObject";
104
+
105
+ // src/components/Participant/Participant.tsx
106
+ import { useAtomValue } from "@effect-atom/atom-react";
107
+ import React6, { memo as memo2, useMemo as useMemo2 } from "react";
108
+ import { useCapability } from "@dxos/app-framework/ui";
109
+
110
+ // src/components/ResponsiveGrid/ResponsiveContainer.tsx
111
+ import React3 from "react";
112
+ import { mx as mx2 } from "@dxos/ui-theme";
113
+ var ResponsiveContainer = ({ children }) => {
114
+ return (
115
+ // Outer container that takes full size of parent.
116
+ /* @__PURE__ */ React3.createElement("div", {
117
+ role: "none",
118
+ className: "relative flex is-full bs-full"
119
+ }, /* @__PURE__ */ React3.createElement("div", {
120
+ role: "none",
121
+ className: "absolute inset-0 flex justify-center items-center"
122
+ }, /* @__PURE__ */ React3.createElement("div", {
123
+ role: "none",
124
+ className: mx2("max-bs-full max-is-full is-auto bs-auto aspect-video")
125
+ }, children)))
126
+ );
127
+ };
128
+
129
+ // src/components/ResponsiveGrid/ResponsiveGrid.tsx
130
+ import React4, { useCallback, useEffect as useEffect3, useLayoutEffect, useMemo, useState } from "react";
131
+ import { useResizeDetector } from "react-resize-detector";
132
+ import { invariant } from "@dxos/invariant";
133
+ import { mx as mx3 } from "@dxos/ui-theme";
134
+ var __dxlog_file = "/__w/dxos/dxos/packages/plugins/plugin-thread/src/components/ResponsiveGrid/ResponsiveGrid.tsx";
135
+ var ASPECT_RATIO = 16 / 9;
136
+ var MIN_GALLERY_HEIGHT = 250;
137
+ var DEFAULT_GAP = 8;
138
+ var maxImageSize = "is-[2560px] bs-[1440px]";
139
+ var defaultGetId = (item) => item.id;
140
+ var ResponsiveGrid = ({ classNames, Cell, gap = DEFAULT_GAP, getId: getId2 = defaultGetId, items, pinned, autoHideGallery = false, debug, onPinnedChange }) => {
141
+ const { width: containerWidth = 0, height: containerHeight = 0, ref: containerRef } = useResizeDetector({
142
+ refreshRate: 100
143
+ });
144
+ const [dividerHeight, setDividerHeight] = useState(0);
145
+ useEffect3(() => {
146
+ if (containerWidth && containerHeight) {
147
+ const { height: height2 } = fitAspectRatio(containerWidth, containerHeight, ASPECT_RATIO);
148
+ setDividerHeight(Math.min(height2, containerHeight - MIN_GALLERY_HEIGHT));
149
+ }
150
+ }, [
151
+ containerWidth,
152
+ containerHeight
153
+ ]);
154
+ const pinnedItem = useMemo(() => items.find((item) => getId2(item) === pinned), [
155
+ items,
156
+ pinned
157
+ ]);
158
+ const mainItems = useMemo(() => items.filter((item) => getId2(item) !== pinned), [
159
+ items,
160
+ pinned
161
+ ]);
162
+ const hideGallery = autoHideGallery && pinnedItem !== void 0;
163
+ const [{ time, columns, cellWidth }, setLayout] = useState({
164
+ time: 0,
165
+ columns: 0,
166
+ cellWidth: 0
167
+ });
168
+ const { width = 0, height = 0, ref: gridContainerRef } = useResizeDetector({
169
+ refreshRate: 200
170
+ });
171
+ useEffect3(() => {
172
+ if (containerHeight && width && height) {
173
+ const layout = calculateLayout(width, height, mainItems.length, gap);
174
+ setLayout({
175
+ time: Date.now(),
176
+ ...layout
177
+ });
178
+ }
179
+ }, [
180
+ containerHeight,
181
+ width,
182
+ height,
183
+ mainItems.length,
184
+ gap,
185
+ pinned
186
+ ]);
187
+ const [bounds, setBounds] = useState([]);
188
+ useLayoutEffect(() => {
189
+ if (!hideGallery && !gridContainerRef.current || !containerHeight) {
190
+ return;
191
+ }
192
+ const t = setTimeout(() => {
193
+ setBounds(items.filter((item) => !hideGallery || item === pinnedItem).map((item) => {
194
+ invariant(containerRef.current, void 0, {
195
+ F: __dxlog_file,
196
+ L: 117,
197
+ S: void 0,
198
+ A: [
199
+ "containerRef.current",
200
+ ""
201
+ ]
202
+ });
203
+ const el = containerRef.current.querySelector(`[data-grid-item="${getId2(item)}"]`);
204
+ if (!el) {
205
+ return null;
206
+ }
207
+ const bounds2 = getRelativeBounds(containerRef.current, el);
208
+ return [
209
+ item,
210
+ bounds2
211
+ ];
212
+ }).filter((item) => item !== null));
213
+ });
214
+ return () => clearTimeout(t);
215
+ }, [
216
+ containerHeight,
217
+ items,
218
+ pinnedItem,
219
+ hideGallery,
220
+ time
221
+ ]);
222
+ const handleClick = useCallback((item) => onPinnedChange?.(getId2(item) === pinned ? void 0 : getId2(item)), [
223
+ pinned,
224
+ onPinnedChange
225
+ ]);
226
+ return /* @__PURE__ */ React4.createElement("div", {
227
+ ref: containerRef,
228
+ className: mx3("relative is-full bs-full", classNames)
229
+ }, /* @__PURE__ */ React4.createElement("div", {
230
+ className: "absolute inset-0 flex flex-col grow gap-2"
231
+ }, pinnedItem && /* @__PURE__ */ React4.createElement("div", {
232
+ className: mx3("flex grow-[2] shrink overflow-hidden justify-center items-center", hideGallery && "bs-full"),
233
+ style: hideGallery ? {} : {
234
+ height: dividerHeight
235
+ }
236
+ }, /* @__PURE__ */ React4.createElement(SoloItem, {
237
+ id: getId2(pinnedItem),
238
+ debug
239
+ })), !hideGallery && /* @__PURE__ */ React4.createElement("div", {
240
+ ref: gridContainerRef,
241
+ className: "flex grow-[1] overflow-hidden justify-center items-center",
242
+ style: hideGallery ? {} : {
243
+ minHeight: MIN_GALLERY_HEIGHT
244
+ }
245
+ }, mainItems.length === 1 && /* @__PURE__ */ React4.createElement("div", {
246
+ style: {
247
+ width: cellWidth
248
+ },
249
+ className: "flex bs-full"
250
+ }, /* @__PURE__ */ React4.createElement(SoloItem, {
251
+ id: getId2(mainItems[0]),
252
+ debug
253
+ })), mainItems.length > 1 && columns > 0 && /* @__PURE__ */ React4.createElement("div", {
254
+ role: "grid",
255
+ style: {
256
+ display: "grid",
257
+ gridTemplateColumns: `repeat(${columns}, ${cellWidth}px)`,
258
+ gap: `${gap}px`
259
+ }
260
+ }, mainItems.map((item) => /* @__PURE__ */ React4.createElement("div", {
261
+ key: getId2(item),
262
+ "data-grid-item": getId2(item),
263
+ className: mx3("aspect-video max-bs-full max-is-full is-auto bs-auto", debug && "border border-primary-500")
264
+ }))))), /* @__PURE__ */ React4.createElement("div", {
265
+ className: mx3(debug && "opacity-10")
266
+ }, bounds.map(([item, bounds2]) => /* @__PURE__ */ React4.createElement(Cell, {
267
+ key: getId2(item),
268
+ classNames: "absolute transition-all duration-500",
269
+ item,
270
+ style: bounds2,
271
+ pinned: getId2(item) === pinned,
272
+ onClick: items.length > 1 ? handleClick : void 0
273
+ }))));
274
+ };
275
+ var SoloItem = ({ debug, id }) => {
276
+ return /* @__PURE__ */ React4.createElement(ResponsiveContainer, null, /* @__PURE__ */ React4.createElement("div", {
277
+ "data-grid-item": id,
278
+ className: mx3("aspect-video overflow-hidden", debug && "z-20 border-2 border-primary-500")
279
+ }, /* @__PURE__ */ React4.createElement("img", {
280
+ alt: "placeholder video",
281
+ className: mx3("opacity-0", maxImageSize)
282
+ })));
283
+ };
284
+ var getRelativeBounds = (container, el) => {
285
+ const containerRect = container.getBoundingClientRect();
286
+ const elementRect = el.getBoundingClientRect();
287
+ return {
288
+ top: elementRect.top - containerRect.top,
289
+ left: elementRect.left - containerRect.left,
290
+ width: elementRect.width,
291
+ height: elementRect.height
292
+ };
293
+ };
294
+ var calculateLayout = (containerWidth, containerHeight, count, gap, aspectRatio = ASPECT_RATIO) => {
295
+ if (count === 0) {
296
+ return {
297
+ columns: 1,
298
+ cellWidth: 1
299
+ };
300
+ }
301
+ let minWastedSpace = Infinity;
302
+ let bestColumns = 1;
303
+ let cellWidth = 0;
304
+ for (let rows = 1; rows <= count; rows++) {
305
+ const cols = Math.ceil(count / rows);
306
+ const { width: itemWidth, height: itemHeight } = fitItemsToGrid(containerWidth, containerHeight, cols, rows, aspectRatio, gap);
307
+ const usedWidth = itemWidth * cols + gap * cols - 1;
308
+ const usedHeight = itemHeight * rows + gap * rows - 1;
309
+ const wastedSpace = containerWidth * containerHeight - usedWidth * usedHeight;
310
+ if (wastedSpace < minWastedSpace) {
311
+ minWastedSpace = wastedSpace;
312
+ bestColumns = cols;
313
+ cellWidth = itemWidth;
314
+ }
315
+ }
316
+ return {
317
+ columns: bestColumns,
318
+ cellWidth
319
+ };
320
+ };
321
+ var fitItemsToGrid = (outerWidth, outerHeight, numCols, numRows, aspectRatio, gap) => {
322
+ const availableWidth = outerWidth - gap * (numCols - 1);
323
+ const availableHeight = outerHeight - gap * (numRows - 1);
324
+ const maxCellWidth = availableWidth / numCols;
325
+ const maxCellHeight = availableHeight / numRows;
326
+ return fitAspectRatio(maxCellWidth, maxCellHeight, aspectRatio);
327
+ };
328
+ var fitAspectRatio = (outerWidth, outerHeight, aspectRatio) => {
329
+ if (outerWidth <= 0 || outerHeight <= 0 || aspectRatio <= 0) {
330
+ return {
331
+ width: 0,
332
+ height: 0
333
+ };
334
+ }
335
+ let width = outerWidth;
336
+ let height = width / aspectRatio;
337
+ if (height > outerHeight) {
338
+ height = outerHeight;
339
+ width = height * aspectRatio;
340
+ }
341
+ return {
342
+ width,
343
+ height
344
+ };
345
+ };
346
+
347
+ // src/components/ResponsiveGrid/ResponsiveGridItem.tsx
348
+ import React5, { useEffect as useEffect4, useState as useState2 } from "react";
349
+ import { Icon, IconButton, useTranslation } from "@dxos/react-ui";
350
+ import { Waveform } from "@dxos/react-ui-sfx";
351
+ import { groupHoverControlItemWithTransition, mx as mx4 } from "@dxos/ui-theme";
352
+ var ResponsiveGridItem = ({ children, classNames, item, style, name, self, pinned, screenshare, video, mute, wave, speaking, onClick }) => {
353
+ const { t } = useTranslation(meta.id);
354
+ const iconProps = {
355
+ wave: {
356
+ icon: "ph--hand-waving--duotone",
357
+ label: t("icon wave"),
358
+ classNames: "animate-pulse bg-orange-500"
359
+ },
360
+ mute: {
361
+ icon: "ph--microphone-slash--regular",
362
+ label: t("icon muted")
363
+ }
364
+ };
365
+ const props = wave && !pinned ? iconProps.wave : mute ? iconProps.mute : speaking ? iconProps.speaking : void 0;
366
+ const [speakingIndicator, setSpeakingIndicator] = useState2(speaking);
367
+ useEffect4(() => {
368
+ if (speaking) {
369
+ setSpeakingIndicator(true);
370
+ } else {
371
+ const timeout = setTimeout(() => {
372
+ setSpeakingIndicator(false);
373
+ }, 1e3);
374
+ return () => clearTimeout(timeout);
375
+ }
376
+ }, [
377
+ speaking
378
+ ]);
379
+ return /* @__PURE__ */ React5.createElement("div", {
380
+ className: mx4("relative is-full bs-full group", "rounded-md outline outline-2 outline-neutral-900 transition-[outline-color] duration-500", speakingIndicator ? "outline-green-500" : !video && "outline-separator", classNames),
381
+ style
382
+ }, children, onClick && /* @__PURE__ */ React5.createElement("div", {
383
+ className: "z-10 absolute top-1 right-1 flex"
384
+ }, /* @__PURE__ */ React5.createElement(IconButton, {
385
+ classNames: mx4("p-1 min-bs-1 rounded", groupHoverControlItemWithTransition),
386
+ iconOnly: true,
387
+ icon: pinned ? "ph--x--regular" : "ph--arrows-out--regular",
388
+ size: pinned ? 5 : 4,
389
+ label: pinned ? t("icon unpin") : t("icon pin"),
390
+ onClick: () => onClick?.(item)
391
+ })), name && /* @__PURE__ */ React5.createElement("div", {
392
+ className: "z-10 absolute bottom-1 left-8 right-1 flex justify-end gap-1 items-center"
393
+ }, screenshare && /* @__PURE__ */ React5.createElement(Icon, {
394
+ icon: "ph--broadcast--regular",
395
+ size: pinned ? 5 : 4
396
+ }), /* @__PURE__ */ React5.createElement("div", {
397
+ className: mx4("bg-neutral-800 text-neutral-100 plb-0.5 truncate rounded", pinned ? "pli-2" : "pli-1 text-xs")
398
+ }, name)), /* @__PURE__ */ React5.createElement("div", {
399
+ className: "z-10 absolute bottom-1 left-1 flex"
400
+ }, speaking && /* @__PURE__ */ React5.createElement(Waveform, {
401
+ active: true,
402
+ size: pinned ? 5 : 4
403
+ }) || props && /* @__PURE__ */ React5.createElement(IconButton, {
404
+ classNames: mx4("p-1 min-bs-1 rounded", props?.classNames),
405
+ icon: props?.icon,
406
+ label: props?.label,
407
+ size: pinned ? 5 : 4,
408
+ iconOnly: true
409
+ })));
410
+ };
411
+
412
+ // src/components/Participant/Participant.tsx
413
+ var SCREENSHARE_SUFFIX = "_screenshare";
414
+ var Participant = /* @__PURE__ */ memo2(({ item: user, debug, ...props }) => {
415
+ const call = useCapability(ThreadCapabilities.CallManager);
416
+ const self = useAtomValue(call.selfAtom);
417
+ const media = useAtomValue(call.mediaAtom);
418
+ const isSelf = self.id !== void 0 && user.id !== void 0 && user.id.startsWith(self.id);
419
+ const isScreenshare = user.id?.endsWith(SCREENSHARE_SUFFIX);
420
+ const pulledVideoStream = useMemo2(() => {
421
+ if (isSelf) {
422
+ return void 0;
423
+ }
424
+ const trackName = isScreenshare && user.tracks?.screenshareEnabled ? user.tracks?.screenshare : !isScreenshare && user.tracks?.videoEnabled ? user.tracks?.video : void 0;
425
+ return trackName ? media.pulledVideoStreams[trackName]?.stream : void 0;
426
+ }, [
427
+ isSelf,
428
+ isScreenshare,
429
+ media.pulledVideoStreams,
430
+ user.tracks?.screenshare,
431
+ user.tracks?.video,
432
+ user.tracks?.screenshareEnabled,
433
+ user.tracks?.videoEnabled
434
+ ]);
435
+ const videoStream = useMemo2(() => {
436
+ if (isSelf) {
437
+ return isScreenshare ? media.screenshareVideoStream : media.videoStream;
438
+ }
439
+ return pulledVideoStream;
440
+ }, [
441
+ isSelf,
442
+ isScreenshare,
443
+ media.videoStream,
444
+ media.screenshareVideoStream,
445
+ pulledVideoStream
446
+ ]);
447
+ return /* @__PURE__ */ React6.createElement(ResponsiveGridItem, {
448
+ ...props,
449
+ item: user,
450
+ name: user.name,
451
+ self: isSelf,
452
+ screenshare: !!media.screenshareVideoStream,
453
+ video: media.videoEnabled,
454
+ mute: user ? !user.tracks?.audioEnabled : false,
455
+ wave: user.raisedHand,
456
+ speaking: user.speaking,
457
+ debug
458
+ }, /* @__PURE__ */ React6.createElement(VideoObject, {
459
+ videoStream,
460
+ flip: isSelf && !isScreenshare,
461
+ contain: !!isScreenshare,
462
+ classNames: "rounded-md"
463
+ }));
464
+ });
465
+ Participant.displayName = "Participant";
466
+
467
+ // src/components/Participant/ParticipantGrid.tsx
468
+ import React7, { useEffect as useEffect5, useMemo as useMemo3, useState as useState3 } from "react";
469
+ var getId = (user) => user.id;
470
+ var ParticipantGrid = ({ classNames, self, users, fullscreen, debug }) => {
471
+ const [pinned, setPinned] = useState3();
472
+ const allUsers = useMemo3(() => {
473
+ const allUsers2 = [];
474
+ users.forEach((user) => {
475
+ if (!user.joined) {
476
+ return;
477
+ }
478
+ allUsers2.push({
479
+ ...user,
480
+ isSelf: user.id === self.id
481
+ });
482
+ if (user.tracks?.screenshareEnabled) {
483
+ const screenshare = {
484
+ ...user,
485
+ id: user.id + SCREENSHARE_SUFFIX,
486
+ tracks: {
487
+ ...user.tracks,
488
+ video: user.tracks.screenshare,
489
+ videoEnabled: user.tracks.screenshareEnabled
490
+ }
491
+ };
492
+ allUsers2.push(screenshare);
493
+ }
494
+ });
495
+ return allUsers2;
496
+ }, [
497
+ self,
498
+ users
499
+ ]);
500
+ useEffect5(() => {
501
+ if (pinned) {
502
+ if (!allUsers.find((user) => user.id === pinned)) {
503
+ setPinned(void 0);
504
+ }
505
+ }
506
+ }, [
507
+ pinned,
508
+ allUsers
509
+ ]);
510
+ const sortedUsers = allUsers.sort((a, b) => {
511
+ if (a.isSelf) {
512
+ return 1;
513
+ } else if (b.isSelf) {
514
+ return -1;
515
+ } else if (a.tracks?.screenshareEnabled) {
516
+ return -1;
517
+ } else if (b.tracks?.screenshareEnabled) {
518
+ return 1;
519
+ } else {
520
+ return 0;
521
+ }
522
+ });
523
+ return /* @__PURE__ */ React7.createElement(ResponsiveGrid, {
524
+ classNames,
525
+ Cell: Participant,
526
+ debug,
527
+ getId,
528
+ items: sortedUsers,
529
+ pinned,
530
+ autoHideGallery: fullscreen,
531
+ onPinnedChange: setPinned
532
+ });
533
+ };
534
+
535
+ // src/components/Call/Toolbar.tsx
536
+ import { useAtomValue as useAtomValue2 } from "@effect-atom/atom-react";
537
+ import React8 from "react";
538
+ import { useCapability as useCapability2 } from "@dxos/app-framework/ui";
539
+ import { useAppGraph } from "@dxos/app-toolkit/ui";
540
+ import { Obj } from "@dxos/echo";
541
+ import { Node, useActionRunner } from "@dxos/plugin-graph";
542
+ import { useActions, useNode } from "@dxos/plugin-graph";
543
+ import { Icon as Icon2, IconButton as IconButton2, Toolbar as NaturalToolbar, toLocalizedString, useTranslation as useTranslation2 } from "@dxos/react-ui";
544
+ import { groupHoverControlItemWithTransition as groupHoverControlItemWithTransition2, mx as mx5 } from "@dxos/ui-theme";
545
+ var Toolbar = ({ classNames, channel, participants, autoHideControls = true, onJoin, onLeave }) => {
546
+ const { t } = useTranslation2(meta.id);
547
+ const { graph } = useAppGraph();
548
+ const runAction = useActionRunner();
549
+ const call = useCapability2(ThreadCapabilities.CallManager);
550
+ const media = useAtomValue2(call.mediaAtom);
551
+ const joined = useAtomValue2(call.joinedAtom);
552
+ const raisedHand = useAtomValue2(call.raisedHandAtom);
553
+ const node = useNode(graph, channel && Obj.getDXN(channel).toString());
554
+ const actions = useActions(graph, node?.id).filter((action) => action.properties.disposition === "toolbar");
555
+ const isScreensharing = media.screenshareTrack !== void 0;
556
+ const canSharescreen = typeof navigator.mediaDevices !== "undefined" && navigator.mediaDevices.getDisplayMedia !== void 0;
557
+ return /* @__PURE__ */ React8.createElement("div", {
558
+ className: mx5("z-20 flex justify-center m-8", autoHideControls && groupHoverControlItemWithTransition2)
559
+ }, /* @__PURE__ */ React8.createElement(NaturalToolbar.Root, {
560
+ classNames: [
561
+ "p-2 bg-modalSurface rounded-md shadow-md",
562
+ classNames
563
+ ]
564
+ }, /* @__PURE__ */ React8.createElement(ToggleButton, {
565
+ active: media.audioEnabled,
566
+ state: {
567
+ on: {
568
+ icon: "ph--microphone--regular",
569
+ label: t("mic off"),
570
+ onClick: () => call.turnAudioOff(),
571
+ classNames: "bg-callActive"
572
+ },
573
+ off: {
574
+ icon: "ph--microphone-slash--duotone",
575
+ label: t("mic on"),
576
+ onClick: () => call.turnAudioOn(),
577
+ classNames: [
578
+ joined && "bg-callAlert"
579
+ ]
580
+ }
581
+ }
582
+ }), /* @__PURE__ */ React8.createElement(ToggleButton, {
583
+ active: media.videoEnabled,
584
+ state: {
585
+ on: {
586
+ icon: "ph--video-camera--regular",
587
+ label: t("camera off"),
588
+ onClick: () => call.turnVideoOff()
589
+ },
590
+ off: {
591
+ icon: "ph--video-camera-slash--duotone",
592
+ label: t("camera on"),
593
+ onClick: () => call.turnVideoOn()
594
+ }
595
+ }
596
+ }), participants !== void 0 && /* @__PURE__ */ React8.createElement("div", {
597
+ className: "flex justify-center items-center gap-2 is-[5rem] text-xs text-subdued"
598
+ }, /* @__PURE__ */ React8.createElement(Icon2, {
599
+ icon: "ph--users--regular",
600
+ size: 4
601
+ }), /* @__PURE__ */ React8.createElement("div", null, participants)) || /* @__PURE__ */ React8.createElement(NaturalToolbar.Separator, {
602
+ variant: "gap"
603
+ }), joined && /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(ToggleButton, {
604
+ disabled: !canSharescreen,
605
+ active: isScreensharing,
606
+ state: {
607
+ on: {
608
+ icon: "ph--monitor--regular",
609
+ label: t("screenshare off"),
610
+ onClick: () => call.turnScreenshareOff()
611
+ },
612
+ off: {
613
+ icon: "ph--monitor-arrow-up--duotone",
614
+ label: t("screenshare on"),
615
+ onClick: () => call.turnScreenshareOn()
616
+ }
617
+ }
618
+ }), actions.filter((action) => Node.isAction(action)).map((action) => /* @__PURE__ */ React8.createElement(IconButton2, {
619
+ key: action.id,
620
+ ...defaultButtonProps,
621
+ icon: action.properties.icon,
622
+ label: toLocalizedString(action.properties.label, t),
623
+ classNames: action.properties.classNames,
624
+ onClick: () => node && void runAction(action, {
625
+ parent: node
626
+ })
627
+ })), /* @__PURE__ */ React8.createElement(ToggleButton, {
628
+ active: raisedHand,
629
+ state: {
630
+ on: {
631
+ icon: "ph--hand-waving--regular",
632
+ label: t("lower hand"),
633
+ onClick: () => call.setRaisedHand(false),
634
+ classNames: [
635
+ joined && "bg-callAlert"
636
+ ]
637
+ },
638
+ off: {
639
+ icon: "ph--hand-palm--duotone",
640
+ label: t("raise hand"),
641
+ onClick: () => call.setRaisedHand(true)
642
+ }
643
+ }
644
+ })), joined ? /* @__PURE__ */ React8.createElement(IconButton2, {
645
+ variant: "destructive",
646
+ icon: "ph--phone-x--regular",
647
+ label: t("leave call"),
648
+ onClick: onLeave
649
+ }) : /* @__PURE__ */ React8.createElement(IconButton2, {
650
+ variant: "primary",
651
+ icon: "ph--phone-incoming--regular",
652
+ label: t("join call"),
653
+ onClick: onJoin
654
+ })));
655
+ };
656
+ Toolbar.displayName = "MeetingToolbar";
657
+ var defaultButtonProps = {
658
+ size: 5,
659
+ iconOnly: true
660
+ };
661
+ var ToggleButton = ({ active, state }) => /* @__PURE__ */ React8.createElement(IconButton2, {
662
+ ...defaultButtonProps,
663
+ classNames: [
664
+ active ? state.on.classNames ?? "bg-callActive" : state.off.classNames
665
+ ],
666
+ icon: active ? state.on.icon : state.off.icon,
667
+ label: active ? state.on.label : state.off.label,
668
+ onClick: active ? state.on.onClick : state.off.onClick
669
+ });
670
+
671
+ // src/components/Call/Call.tsx
672
+ var CallRoot = ({ children }) => {
673
+ return /* @__PURE__ */ React9.createElement("div", {
674
+ className: "relative flex flex-col grow overflow-hidden"
675
+ }, children);
676
+ };
677
+ CallRoot.displayName = "CallRoot";
678
+ var CallAudio = () => {
679
+ const call = useCapability3(ThreadCapabilities.CallManager);
680
+ const audioTracksToPlay = useAtomValue3(call.audioTracksToPlayAtom);
681
+ return /* @__PURE__ */ React9.createElement(AudioStream, {
682
+ tracks: audioTracksToPlay
683
+ });
684
+ };
685
+ CallAudio.displayName = "CallAudio";
686
+ var CallGrid = ({ fullscreen }) => {
687
+ const debug = useDebugMode();
688
+ const call = useCapability3(ThreadCapabilities.CallManager);
689
+ const self = useAtomValue3(call.selfAtom);
690
+ const users = useAtomValue3(call.usersAtom);
691
+ return /* @__PURE__ */ React9.createElement("div", {
692
+ className: "grid grow p-4 dark:bg-neutral-900"
693
+ }, /* @__PURE__ */ React9.createElement(ParticipantGrid, {
694
+ self,
695
+ users,
696
+ debug,
697
+ fullscreen
698
+ }));
699
+ };
700
+ CallGrid.displayName = "CallGrid";
701
+ var CallToolbar = (props) => {
702
+ return /* @__PURE__ */ React9.createElement("div", {
703
+ className: "absolute bottom-0 left-0 right-0 flex justify-center"
704
+ }, /* @__PURE__ */ React9.createElement(Toolbar, {
705
+ isInRoom: true,
706
+ ...props
707
+ }));
708
+ };
709
+ CallToolbar.displayName = "CallToolbar";
710
+ var Call = {
711
+ Root: CallRoot,
712
+ Grid: CallGrid,
713
+ Audio: CallAudio,
714
+ Toolbar: CallToolbar
715
+ };
716
+
717
+ // src/components/CallDebugPanel.tsx
718
+ import { WebRTCStats } from "@peermetrics/webrtc-stats";
719
+ import React10, { useEffect as useEffect6, useMemo as useMemo4, useState as useState4 } from "react";
720
+ import { truncateKey } from "@dxos/debug";
721
+ import { JsonView, Panel } from "@dxos/devtools";
722
+ import { log } from "@dxos/log";
723
+ import { IconButton as IconButton3, Input, useTranslation as useTranslation3 } from "@dxos/react-ui";
724
+ var __dxlog_file2 = "/__w/dxos/dxos/packages/plugins/plugin-thread/src/components/CallDebugPanel.tsx";
725
+ var CallDebugPanel = ({ state }) => {
726
+ const { t } = useTranslation3(meta.id);
727
+ const [open, setOpen] = useState4(false);
728
+ const handleToggle = () => setOpen(!open);
729
+ const [showServiceHistory, setShowServiceHistory] = useState4(false);
730
+ const handleToggleServiceHistory = () => setShowServiceHistory(!showServiceHistory);
731
+ const handleCopyRaw = async () => {
732
+ await navigator.clipboard.writeText(JSON.stringify({
733
+ users: state?.call?.users,
734
+ stats
735
+ }, null, 2));
736
+ };
737
+ const [showDetailedWebRTCStats, setShowDetailedWebRTCStats] = useState4(false);
738
+ const handleShowDetailedWebRTCStats = () => setShowDetailedWebRTCStats(!showDetailedWebRTCStats);
739
+ const webrtcStats = useMemo4(() => new WebRTCStats({
740
+ getStatsInterval: 1e3
741
+ }), []);
742
+ const [stats, setStats] = useState4();
743
+ useEffect6(() => {
744
+ const pc = state?.media.peer?.session?.peerConnection;
745
+ const handleStats = (stats2) => {
746
+ setStats(stats2.data);
747
+ };
748
+ let added = false;
749
+ if (pc && showDetailedWebRTCStats) {
750
+ webrtcStats.addConnection({
751
+ pc,
752
+ peerId: 1,
753
+ connectionId: "1"
754
+ });
755
+ webrtcStats.on("stats", handleStats);
756
+ added = true;
757
+ }
758
+ return () => {
759
+ try {
760
+ if (pc && added) {
761
+ webrtcStats.removeConnection({
762
+ pc
763
+ });
764
+ webrtcStats.removeListener("stats", handleStats);
765
+ }
766
+ } catch (error) {
767
+ log.error("error removing webrtc stats", {
768
+ error,
769
+ pc,
770
+ peerId: 1,
771
+ connectionId: "1"
772
+ }, {
773
+ F: __dxlog_file2,
774
+ L: 60,
775
+ S: void 0,
776
+ C: (f, a) => f(...a)
777
+ });
778
+ }
779
+ };
780
+ }, [
781
+ state?.media.peer?.session?.peerConnection,
782
+ showDetailedWebRTCStats
783
+ ]);
784
+ const rows = useMemo4(() => getCallStatusTable(state), [
785
+ state?.call.users,
786
+ state?.media.pulledAudioTracks
787
+ ]);
788
+ return /* @__PURE__ */ React10.createElement(Panel, {
789
+ id: "meeting-status",
790
+ icon: "ph--video-conference--regular",
791
+ open,
792
+ onToggle: handleToggle,
793
+ title: t("meeting status title"),
794
+ info: /* @__PURE__ */ React10.createElement("div", {
795
+ className: "flex items-center gap-2"
796
+ }, " ", state?.call.joined ? "Active" : "Inactive"),
797
+ maxHeight: 0
798
+ }, /* @__PURE__ */ React10.createElement("div", {
799
+ className: "flex flex-col is-full text-xs"
800
+ }, /* @__PURE__ */ React10.createElement("div", {
801
+ className: "flex items-center gap-2 items-center"
802
+ }, /* @__PURE__ */ React10.createElement(Input.Root, null, /* @__PURE__ */ React10.createElement(Input.Switch, {
803
+ checked: showDetailedWebRTCStats,
804
+ onCheckedChange: handleShowDetailedWebRTCStats
805
+ }), /* @__PURE__ */ React10.createElement(Input.Label, null, t("show webrtc stats title")))), /* @__PURE__ */ React10.createElement("div", {
806
+ className: "flex items-center gap-2 items-center"
807
+ }, /* @__PURE__ */ React10.createElement(Input.Root, null, /* @__PURE__ */ React10.createElement(Input.Switch, {
808
+ checked: showServiceHistory,
809
+ onCheckedChange: handleToggleServiceHistory
810
+ }), /* @__PURE__ */ React10.createElement(Input.Label, null, t("show calls history title")))), /* @__PURE__ */ React10.createElement("div", {
811
+ className: "flex items-center gap-2 items-center"
812
+ }, /* @__PURE__ */ React10.createElement(IconButton3, {
813
+ icon: "ph--copy--regular",
814
+ label: "copy raw",
815
+ onClick: handleCopyRaw
816
+ })), /* @__PURE__ */ React10.createElement(Table, {
817
+ rows
818
+ }), showDetailedWebRTCStats && /* @__PURE__ */ React10.createElement(JsonView, {
819
+ data: {
820
+ stats
821
+ }
822
+ }), showServiceHistory && /* @__PURE__ */ React10.createElement(JsonView, {
823
+ data: {
824
+ history: state?.media.peer?.history.get()
825
+ }
826
+ })));
827
+ };
828
+ var getCallStatusTable = (state) => {
829
+ if (!state || !state.call?.users) {
830
+ return [];
831
+ }
832
+ const self = state.call.self;
833
+ const users = state.call.users.filter((user) => user.id !== self.id).map((user) => {
834
+ const isOk = {
835
+ audio: user.tracks?.audio && state.media.pulledAudioTracks[user.tracks?.audio]?.ctx.disposed === false,
836
+ video: user.tracks?.video && state.media.pulledVideoStreams[user.tracks?.video]?.ctx.disposed === false,
837
+ screenshare: user.tracks?.screenshare && state.media.pulledVideoStreams[user.tracks?.screenshare]?.ctx.disposed === false
838
+ };
839
+ return {
840
+ ...user,
841
+ isOk
842
+ };
843
+ });
844
+ return [
845
+ [
846
+ "users",
847
+ state.call.users.length ?? 0
848
+ ],
849
+ [
850
+ "*self* " + (self?.name ?? truncateKey(self.id, 8)),
851
+ self?.tracks?.audio && state.media.pushedAudioTrack ? "AUD \u2705" : "AUD \u274C",
852
+ self?.tracks?.video && state.media.pushedVideoTrack ? "VID \u2705" : "VID \u274C",
853
+ self?.tracks?.screenshareEnabled ? self.tracks.screenshareEnabled && state.media.pushedScreenshareTrack ? "SCR \u2705" : "SCR \u274C" : void 0
854
+ ],
855
+ ...users.map((user) => [
856
+ user.name ?? truncateKey(user.id, 8),
857
+ user.isOk.audio ? "AUD \u2705" : "AUD \u274C",
858
+ user.isOk.video ? "VID \u2705" : "VID \u274C",
859
+ user.tracks?.screenshareEnabled ? user.isOk.screenshare ? "SCR \u2705" : "SCR \u274C" : void 0
860
+ ]),
861
+ [
862
+ "ICE",
863
+ state.media.peer?.session?.peerConnection.iceConnectionState ?? "no connection"
864
+ ]
865
+ ];
866
+ };
867
+ (function(Unit2) {
868
+ Unit2.KB = (n) => ((n ?? 0) / 1e3).toFixed(2);
869
+ })(Unit || (Unit = {}));
870
+ var Table = ({ rows }) => {
871
+ return /* @__PURE__ */ React10.createElement("div", {
872
+ className: "is-full text-xs font-mono"
873
+ }, rows.map(([prefix, label, value, unit], i) => /* @__PURE__ */ React10.createElement("div", {
874
+ key: i,
875
+ className: "grid grid-cols-[3fr_1fr_1fr_1fr]"
876
+ }, /* @__PURE__ */ React10.createElement("div", {
877
+ className: "p-1"
878
+ }, prefix), /* @__PURE__ */ React10.createElement("div", {
879
+ className: "p-1"
880
+ }, label), /* @__PURE__ */ React10.createElement("div", {
881
+ className: "p-1"
882
+ }, value), /* @__PURE__ */ React10.createElement("div", {
883
+ className: "p-1"
884
+ }, unit))));
885
+ };
886
+ var Unit;
887
+
888
+ // src/components/ChatContainer.tsx
889
+ import React12, { useLayoutEffect as useLayoutEffect2, useMemo as useMemo5, useRef as useRef4, useState as useState6 } from "react";
890
+ import { Obj as Obj2, Ref as Ref2 } from "@dxos/echo";
891
+ import { useMembers } from "@dxos/react-client/echo";
892
+ import { useIdentity as useIdentity2 } from "@dxos/react-client/halo";
893
+ import { Icon as Icon3, ScrollArea, useThemeContext as useThemeContext2, useTranslation as useTranslation5 } from "@dxos/react-ui";
894
+ import { StackItem } from "@dxos/react-ui-stack";
895
+ import { MessageTextbox, Thread as ThreadComponent, threadLayout } from "@dxos/react-ui-thread";
896
+ import { Message } from "@dxos/types";
897
+ import { createBasicExtensions as createBasicExtensions2, createThemeExtensions as createThemeExtensions2, listener } from "@dxos/ui-editor";
898
+ import { mx as mx8 } from "@dxos/ui-theme";
899
+ import { isNonNullable } from "@dxos/util";
900
+
901
+ // src/components/command-extension.ts
902
+ import { HighlightStyle, StreamLanguage, syntaxHighlighting } from "@codemirror/language";
903
+ import { tags } from "@dxos/ui-editor";
904
+ import { mx as mx6 } from "@dxos/ui-theme";
905
+ var parser = StreamLanguage.define({
906
+ startState: () => ({
907
+ count: 0
908
+ }),
909
+ token: (stream, state) => {
910
+ state.count++;
911
+ if (stream.eatSpace()) {
912
+ return null;
913
+ }
914
+ if (state.count === 1 && stream.match(/^(\/\w+)/)) {
915
+ return "tagName";
916
+ }
917
+ stream.next();
918
+ return null;
919
+ }
920
+ });
921
+ var styles = HighlightStyle.define([
922
+ {
923
+ tag: tags.tagName,
924
+ class: mx6("dx-tag dx-tag--indigo text-baseText font-medium")
925
+ }
926
+ ]);
927
+ var command = [
928
+ parser,
929
+ syntaxHighlighting(styles)
930
+ ];
931
+
932
+ // src/components/MessageContainer.tsx
933
+ import { EditorView } from "@codemirror/view";
934
+ import React11, { forwardRef as forwardRef2, useCallback as useCallback2, useEffect as useEffect7, useRef as useRef3, useState as useState5 } from "react";
935
+ import { Surface } from "@dxos/app-framework/ui";
936
+ import { Ref } from "@dxos/echo";
937
+ import { useObject } from "@dxos/echo-react";
938
+ import { PublicKey } from "@dxos/react-client";
939
+ import { useIdentity } from "@dxos/react-client/halo";
940
+ import { IconButton as IconButton4, useOnTransition, useThemeContext, useTranslation as useTranslation4 } from "@dxos/react-ui";
941
+ import { useTextEditor } from "@dxos/react-ui-editor";
942
+ import { Card } from "@dxos/react-ui-mosaic";
943
+ import { MessageHeading, MessageRoot } from "@dxos/react-ui-thread";
944
+ import { createBasicExtensions, createThemeExtensions } from "@dxos/ui-editor";
945
+ import { hoverableControlItem, hoverableControls, hoverableFocusedWithinControls, mx as mx7 } from "@dxos/ui-theme";
946
+ var buttonGroupClassNames = "flex flex-row items-center gap-0.5 pie-2";
947
+ var buttonClassNames = "!p-1 transition-opacity";
948
+ var MessageContainer = ({ message: messageOrRef, members, editable = false, onDelete, onAcceptProposal }) => {
949
+ const { t } = useTranslation4(meta.id);
950
+ const [message, updateMessage] = useObject(messageOrRef);
951
+ const identity = useIdentity();
952
+ const [editing, setEditing] = useState5(false);
953
+ const textBlockIndex = message?.blocks.findIndex((block) => block._tag === "text") ?? -1;
954
+ const handleEdit = useCallback2(() => setEditing((editing2) => !editing2), []);
955
+ const handleDelete = useCallback2(() => message && onDelete?.(message.id), [
956
+ message,
957
+ onDelete
958
+ ]);
959
+ const handleAcceptProposal = useCallback2(() => message && onAcceptProposal?.(message.id), [
960
+ message,
961
+ onAcceptProposal
962
+ ]);
963
+ const handleTextBlockChange = useCallback2((newText) => {
964
+ updateMessage((m) => {
965
+ const targetBlock = m.blocks[textBlockIndex];
966
+ if (targetBlock && targetBlock._tag === "text") {
967
+ targetBlock.text = newText;
968
+ }
969
+ });
970
+ }, [
971
+ updateMessage,
972
+ textBlockIndex
973
+ ]);
974
+ const textBlock = message && textBlockIndex !== -1 ? message.blocks[textBlockIndex] : void 0;
975
+ useOnEditAnalytics(message, textBlock, !!editing);
976
+ if (!message) {
977
+ return null;
978
+ }
979
+ 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;
980
+ const messageMetadata = getMessageMetadata(message.id, senderIdentity);
981
+ const userIsAuthor = identity?.did === messageMetadata.authorId;
982
+ const proposalBlock = message.blocks.find((block) => block._tag === "proposal");
983
+ const references = message.blocks.filter((block) => block._tag === "reference").map((block) => block.reference);
984
+ return /* @__PURE__ */ React11.createElement(MessageRoot, {
985
+ ...messageMetadata,
986
+ classNames: [
987
+ hoverableControls,
988
+ hoverableFocusedWithinControls
989
+ ]
990
+ }, /* @__PURE__ */ React11.createElement(MessageHeading, {
991
+ authorName: messageMetadata.authorName,
992
+ timestamp: messageMetadata.timestamp
993
+ }, /* @__PURE__ */ React11.createElement("div", {
994
+ role: "none",
995
+ className: buttonGroupClassNames
996
+ }, userIsAuthor && editable && /* @__PURE__ */ React11.createElement(IconButton4, {
997
+ "data-testid": editing ? "thread.message.save" : "thread.message.edit",
998
+ variant: "ghost",
999
+ icon: editing ? "ph--check--regular" : "ph--pencil-simple--regular",
1000
+ iconOnly: true,
1001
+ label: t(editing ? "save message label" : "edit message label"),
1002
+ classNames: [
1003
+ buttonClassNames,
1004
+ hoverableControlItem
1005
+ ],
1006
+ onClick: handleEdit
1007
+ }), proposalBlock && onAcceptProposal && /* @__PURE__ */ React11.createElement(IconButton4, {
1008
+ "data-testid": "thread.message.accept",
1009
+ variant: "ghost",
1010
+ icon: "ph--check--regular",
1011
+ iconOnly: true,
1012
+ label: t("accept proposal label"),
1013
+ classNames: [
1014
+ buttonClassNames,
1015
+ hoverableControlItem
1016
+ ],
1017
+ onClick: handleAcceptProposal
1018
+ }), onDelete && /* @__PURE__ */ React11.createElement(IconButton4, {
1019
+ "data-testid": "thread.message.delete",
1020
+ variant: "ghost",
1021
+ icon: "ph--x--regular",
1022
+ iconOnly: true,
1023
+ label: t("delete message label"),
1024
+ classNames: [
1025
+ buttonClassNames,
1026
+ hoverableControlItem
1027
+ ],
1028
+ onClick: handleDelete
1029
+ }))), textBlock && /* @__PURE__ */ React11.createElement(TextboxBlock, {
1030
+ block: textBlock,
1031
+ isAuthor: userIsAuthor,
1032
+ editing,
1033
+ onSave: handleTextBlockChange
1034
+ }), proposalBlock && /* @__PURE__ */ React11.createElement(ProposalBlock, {
1035
+ block: proposalBlock
1036
+ }), Ref.Array.targets(references).map((reference, index) => /* @__PURE__ */ React11.createElement(MessagePart, {
1037
+ key: index,
1038
+ part: reference
1039
+ })));
1040
+ };
1041
+ var MessagePart = ({ part }) => {
1042
+ return /* @__PURE__ */ React11.createElement(MessageBlockObjectTile, {
1043
+ subject: part
1044
+ });
1045
+ };
1046
+ var TextboxBlock = ({ block, isAuthor, editing, onSave }) => {
1047
+ const { themeMode } = useThemeContext();
1048
+ const inMemoryContentRef = useRef3(block.text);
1049
+ const handleDocumentChange = useCallback2((newState) => {
1050
+ inMemoryContentRef.current = newState;
1051
+ }, []);
1052
+ const saveDocumentChange = useCallback2(() => {
1053
+ onSave?.(inMemoryContentRef.current);
1054
+ }, [
1055
+ onSave
1056
+ ]);
1057
+ useOnTransition(editing, true, false, saveDocumentChange);
1058
+ const { parentRef, focusAttributes, view } = useTextEditor(() => ({
1059
+ initialValue: block.text,
1060
+ extensions: [
1061
+ createBasicExtensions({
1062
+ readOnly: !isAuthor || !editing
1063
+ }),
1064
+ createThemeExtensions({
1065
+ themeMode
1066
+ }),
1067
+ command,
1068
+ EditorView.updateListener.of((update) => {
1069
+ if (update.docChanged) {
1070
+ handleDocumentChange(update.state.doc.toString());
1071
+ }
1072
+ })
1073
+ ]
1074
+ }), [
1075
+ block.text,
1076
+ editing,
1077
+ isAuthor,
1078
+ themeMode,
1079
+ handleDocumentChange
1080
+ ]);
1081
+ useEffect7(() => {
1082
+ editing && view?.focus();
1083
+ }, [
1084
+ editing,
1085
+ view
1086
+ ]);
1087
+ return /* @__PURE__ */ React11.createElement("div", {
1088
+ role: "none",
1089
+ ref: parentRef,
1090
+ className: "mie-4",
1091
+ ...focusAttributes
1092
+ });
1093
+ };
1094
+ var ProposalBlock = ({ block }) => {
1095
+ return /* @__PURE__ */ React11.createElement("div", {
1096
+ role: "none",
1097
+ className: "mie-4 italic"
1098
+ }, block.text);
1099
+ };
1100
+ var MessageBlockObjectTile = /* @__PURE__ */ forwardRef2(({ subject }, forwardedRef) => {
1101
+ let title = subject.name ?? subject.title ?? subject.type ?? "Object";
1102
+ if (typeof title !== "string") {
1103
+ title = title?.content ?? "";
1104
+ }
1105
+ return /* @__PURE__ */ React11.createElement(Card.Root, {
1106
+ className: mx7("grid col-span-3 plb-1 pr-4", hoverableControls, hoverableFocusedWithinControls),
1107
+ ref: forwardedRef
1108
+ }, /* @__PURE__ */ React11.createElement(Surface.Surface, {
1109
+ role: "card-content",
1110
+ limit: 1,
1111
+ data: {
1112
+ subject
1113
+ },
1114
+ fallback: title
1115
+ }));
1116
+ });
1117
+
1118
+ // src/components/ChatContainer.tsx
1119
+ var ChatContainer = ({ classNames, space, thread, context, current, autoFocusTextbox }) => {
1120
+ const { t } = useTranslation5(meta.id);
1121
+ const id = Obj2.getDXN(thread).toString();
1122
+ const identity = useIdentity2();
1123
+ const members = useMembers(space?.id);
1124
+ const activity = useStatus(space, id);
1125
+ const [_count, _setCount] = useState6(0);
1126
+ const rerenderEditor = () => _setCount((count) => count + 1);
1127
+ const [autoFocus, setAutoFocus] = useState6(autoFocusTextbox);
1128
+ const threadScrollRef = useRef4(null);
1129
+ const { themeMode } = useThemeContext2();
1130
+ const textboxMetadata = getMessageMetadata(id, identity);
1131
+ const messageRef = useRef4("");
1132
+ const extensions = useMemo5(() => [
1133
+ createBasicExtensions2({
1134
+ placeholder: t("message placeholder")
1135
+ }),
1136
+ createThemeExtensions2({
1137
+ themeMode
1138
+ }),
1139
+ listener({
1140
+ onChange: ({ text }) => messageRef.current = text
1141
+ }),
1142
+ command
1143
+ ], [
1144
+ themeMode,
1145
+ _count
1146
+ ]);
1147
+ const scrollToEnd = (behavior) => setTimeout(() => threadScrollRef.current?.scrollIntoView({
1148
+ behavior,
1149
+ block: "end"
1150
+ }), 10);
1151
+ useLayoutEffect2(() => {
1152
+ scrollToEnd("instant");
1153
+ }, []);
1154
+ const handleCreate = () => {
1155
+ if (!messageRef.current?.length) {
1156
+ return false;
1157
+ }
1158
+ Obj2.change(thread, (t2) => {
1159
+ t2.messages.push(Ref2.make(Obj2.make(Message.Message, {
1160
+ created: (/* @__PURE__ */ new Date()).toISOString(),
1161
+ sender: {
1162
+ identityDid: identity.did
1163
+ },
1164
+ blocks: [
1165
+ {
1166
+ _tag: "text",
1167
+ text: messageRef.current
1168
+ }
1169
+ ],
1170
+ properties: context ? {
1171
+ context: Ref2.make(context)
1172
+ } : void 0
1173
+ })));
1174
+ });
1175
+ messageRef.current = "";
1176
+ setAutoFocus(true);
1177
+ scrollToEnd("smooth");
1178
+ rerenderEditor();
1179
+ return true;
1180
+ };
1181
+ return /* @__PURE__ */ React12.createElement(ThreadComponent.Root, {
1182
+ current,
1183
+ id,
1184
+ classNames: [
1185
+ "bs-full grid-rows-[1fr_min-content_min-content] overflow-hidden",
1186
+ "transition-[padding-block-end] [[data-sidebar-inline-start-state=open]_&]:lg:pbe-0",
1187
+ classNames
1188
+ ]
1189
+ }, /* @__PURE__ */ React12.createElement(ScrollArea.Root, {
1190
+ orientation: "vertical"
1191
+ }, /* @__PURE__ */ React12.createElement(ScrollArea.Viewport, {
1192
+ classNames: "col-span-2"
1193
+ }, /* @__PURE__ */ React12.createElement("div", {
1194
+ role: "none",
1195
+ className: mx8(threadLayout, "place-self-end")
1196
+ }, thread.messages.map((message) => message.target).filter(isNonNullable).map((message) => /* @__PURE__ */ React12.createElement(MessageContainer, {
1197
+ key: message.id,
1198
+ message,
1199
+ members
1200
+ }))), /* @__PURE__ */ React12.createElement("div", {
1201
+ role: "none",
1202
+ className: "bs-px -mbs-px",
1203
+ ref: threadScrollRef
1204
+ }))), /* @__PURE__ */ React12.createElement(MessageTextbox, {
1205
+ extensions,
1206
+ autoFocus,
1207
+ onSend: handleCreate,
1208
+ ...textboxMetadata
1209
+ }), /* @__PURE__ */ React12.createElement(ThreadComponent.Status, {
1210
+ activity
1211
+ }, t("activity message")));
1212
+ };
1213
+ var ChatContainer_default = ChatContainer;
1214
+
1215
+ // src/components/ChannelContainer.tsx
1216
+ import { Atom, useAtomValue as useAtomValue4 } from "@effect-atom/atom-react";
1217
+ import React13, { useCallback as useCallback3, useEffect as useEffect8, useMemo as useMemo6, useState as useState7 } from "react";
1218
+ import { useCapabilities, useCapability as useCapability4 } from "@dxos/app-framework/ui";
1219
+ import { Context } from "@dxos/context";
1220
+ import { failUndefined } from "@dxos/debug";
1221
+ import { Obj as Obj3 } from "@dxos/echo";
1222
+ import { log as log2 } from "@dxos/log";
1223
+ import { useClient } from "@dxos/react-client";
1224
+ import { getSpace } from "@dxos/react-client/echo";
1225
+ import { useIdentity as useIdentity3 } from "@dxos/react-client/halo";
1226
+ import { ElevationProvider, Input as Input2, useTranslation as useTranslation6 } from "@dxos/react-ui";
1227
+ import { Settings } from "@dxos/react-ui-form";
1228
+ import { MenuProvider, ToolbarMenu, createMenuAction, createMenuItemGroup, useMenuActions } from "@dxos/react-ui-menu";
1229
+ import { useSoundEffect } from "@dxos/react-ui-sfx";
1230
+ import { StackItem as StackItem2 } from "@dxos/react-ui-stack";
1231
+ var __dxlog_file3 = "/__w/dxos/dxos/packages/plugins/plugin-thread/src/components/ChannelContainer.tsx";
1232
+ var ChannelContainer = ({ role, subject: channel, roomId: roomIdProp, fullscreen }) => {
1233
+ const space = getSpace(channel);
1234
+ const callManager = useCapability4(ThreadCapabilities.CallManager);
1235
+ const joined = useAtomValue4(callManager.joinedAtom);
1236
+ const currentRoomId = useAtomValue4(callManager.roomIdAtom);
1237
+ const attendableId = channel ? Obj3.getDXN(channel).toString() : void 0;
1238
+ const roomId = roomIdProp ?? attendableId ?? failUndefined();
1239
+ const identity = useIdentity3();
1240
+ const isNamed = !!identity?.profile?.displayName;
1241
+ const joinSound = useSoundEffect("JoinCall");
1242
+ const leaveSound = useSoundEffect("LeaveCall");
1243
+ const extensions = useCapabilities(ThreadCapabilities.CallExtension);
1244
+ useEffect8(() => {
1245
+ const ctx = new Context(void 0, {
1246
+ F: __dxlog_file3,
1247
+ L: 56
1248
+ });
1249
+ callManager.left.on(ctx, (roomId2) => {
1250
+ extensions.forEach((extension) => {
1251
+ void extension.onLeave?.(roomId2);
1252
+ });
1253
+ });
1254
+ callManager.callStateUpdated.on(ctx, (state) => {
1255
+ extensions.forEach((extension) => {
1256
+ void extension.onCallStateUpdated?.(state);
1257
+ });
1258
+ });
1259
+ callManager.mediaStateUpdated.on(ctx, (state) => {
1260
+ extensions.forEach((extension) => {
1261
+ void extension.onMediaStateUpdated?.(state);
1262
+ });
1263
+ });
1264
+ return () => {
1265
+ void ctx.dispose();
1266
+ };
1267
+ }, [
1268
+ callManager,
1269
+ extensions
1270
+ ]);
1271
+ const handleJoin = useCallback3(async () => {
1272
+ if (!roomId || !channel) {
1273
+ return;
1274
+ }
1275
+ if (joined) {
1276
+ await callManager.leave();
1277
+ }
1278
+ try {
1279
+ void joinSound.play();
1280
+ callManager.setRoomId(roomId);
1281
+ await callManager.join();
1282
+ await Promise.all(extensions.map((extension) => extension.onJoin?.({
1283
+ channel,
1284
+ roomId
1285
+ })));
1286
+ } catch (err) {
1287
+ log2.catch(err, void 0, {
1288
+ F: __dxlog_file3,
1289
+ L: 100,
1290
+ S: void 0,
1291
+ C: (f, a) => f(...a)
1292
+ });
1293
+ }
1294
+ }, [
1295
+ extensions,
1296
+ channel,
1297
+ roomId,
1298
+ joined
1299
+ ]);
1300
+ const handleLeave = useCallback3(async () => {
1301
+ try {
1302
+ void leaveSound.play();
1303
+ } catch (err) {
1304
+ log2.catch(err, void 0, {
1305
+ F: __dxlog_file3,
1306
+ L: 112,
1307
+ S: void 0,
1308
+ C: (f, a) => f(...a)
1309
+ });
1310
+ } finally {
1311
+ void callManager.turnAudioOff();
1312
+ void callManager.turnVideoOff();
1313
+ void callManager.turnScreenshareOff();
1314
+ void callManager.leave();
1315
+ }
1316
+ }, [
1317
+ extensions,
1318
+ roomId
1319
+ ]);
1320
+ const isJoined = joined && currentRoomId === roomId;
1321
+ return /* @__PURE__ */ React13.createElement(StackItem2.Content, {
1322
+ classNames: isJoined && "bs-full",
1323
+ toolbar: !isJoined
1324
+ }, isJoined && !isNamed && /* @__PURE__ */ React13.createElement(DisplayNameMissing, null), isJoined && isNamed && /* @__PURE__ */ React13.createElement(Call.Root, null, /* @__PURE__ */ React13.createElement(Call.Grid, {
1325
+ fullscreen
1326
+ }), /* @__PURE__ */ React13.createElement(Call.Toolbar, {
1327
+ channel,
1328
+ onLeave: handleLeave
1329
+ })), !isJoined && channel && channel.defaultThread.target && space && /* @__PURE__ */ React13.createElement(React13.Fragment, null, /* @__PURE__ */ React13.createElement(ChannelToolbar, {
1330
+ attendableId,
1331
+ role,
1332
+ onJoinCall: handleJoin
1333
+ }), /* @__PURE__ */ React13.createElement(ChatContainer_default, {
1334
+ space,
1335
+ thread: channel.defaultThread.target,
1336
+ classNames: "container-max-width"
1337
+ })));
1338
+ };
1339
+ var DisplayNameMissing = () => {
1340
+ const { t } = useTranslation6(meta.id);
1341
+ const client = useClient();
1342
+ const [displayName, setDisplayName] = useState7("");
1343
+ const handleChange = useCallback3((event) => setDisplayName(event.target.value), []);
1344
+ const handleSave = useCallback3(() => client.halo.updateProfile({
1345
+ displayName
1346
+ }), [
1347
+ client,
1348
+ displayName
1349
+ ]);
1350
+ return /* @__PURE__ */ React13.createElement(Settings.Group, {
1351
+ classNames: "p-4 place-content-center"
1352
+ }, /* @__PURE__ */ React13.createElement(Settings.ItemInput, {
1353
+ title: t("display name label"),
1354
+ description: t("display name description")
1355
+ }, /* @__PURE__ */ React13.createElement(Input2.TextInput, {
1356
+ value: displayName,
1357
+ onChange: handleChange,
1358
+ placeholder: t("display name input placeholder"),
1359
+ classNames: "md:min-is-64"
1360
+ })), /* @__PURE__ */ React13.createElement(Settings.GroupButton, {
1361
+ disabled: !displayName,
1362
+ onClick: handleSave
1363
+ }, t("set display name label")));
1364
+ };
1365
+ var useChannelToolbarActions = (onJoinCall) => {
1366
+ const creator = useMemo6(() => Atom.make(() => {
1367
+ return {
1368
+ nodes: [
1369
+ createMenuItemGroup("root", {
1370
+ label: [
1371
+ "channel toolbar title",
1372
+ {
1373
+ ns: meta.id
1374
+ }
1375
+ ]
1376
+ }),
1377
+ createMenuAction("video-call", () => onJoinCall?.(), {
1378
+ label: [
1379
+ "start video call label",
1380
+ {
1381
+ ns: meta.id
1382
+ }
1383
+ ],
1384
+ icon: "ph--video-camera--regular",
1385
+ type: "video-call"
1386
+ })
1387
+ ],
1388
+ edges: [
1389
+ {
1390
+ source: "root",
1391
+ target: "video-call"
1392
+ }
1393
+ ]
1394
+ };
1395
+ }), []);
1396
+ return useMenuActions(creator);
1397
+ };
1398
+ var ChannelToolbar = ({ attendableId, role, onJoinCall }) => {
1399
+ const menuProps = useChannelToolbarActions(onJoinCall);
1400
+ return /* @__PURE__ */ React13.createElement(ElevationProvider, {
1401
+ elevation: role === "section" ? "positioned" : "base"
1402
+ }, /* @__PURE__ */ React13.createElement(MenuProvider, {
1403
+ ...menuProps,
1404
+ attendableId
1405
+ }, /* @__PURE__ */ React13.createElement(ToolbarMenu, {
1406
+ textBlockWidth: true
1407
+ })));
1408
+ };
1409
+
1410
+ // src/components/CallSidebar.tsx
1411
+ import { useAtomValue as useAtomValue5 } from "@effect-atom/atom-react";
1412
+ import React14 from "react";
1413
+ import { useCapability as useCapability5 } from "@dxos/app-framework/ui";
1414
+ var CallSidebar = () => {
1415
+ const call = useCapability5(ThreadCapabilities.CallManager);
1416
+ const roomId = useAtomValue5(call.roomIdAtom);
1417
+ return /* @__PURE__ */ React14.createElement(ChannelContainer, {
1418
+ subject: void 0,
1419
+ roomId
1420
+ });
1421
+ };
1422
+
1423
+ // src/components/ThreadCompanion.tsx
1424
+ import { useAtomValue as useAtomValue6 } from "@effect-atom/atom-react";
1425
+ import React18, { useCallback as useCallback5, useMemo as useMemo8 } from "react";
1426
+ import { Capabilities } from "@dxos/app-framework";
1427
+ import { useCapabilities as useCapabilities2, useCapability as useCapability6, useOperationInvoker } from "@dxos/app-framework/ui";
1428
+ import { AppCapabilities, CollaborationOperation, LayoutOperation } from "@dxos/app-toolkit";
1429
+ import { Filter, Obj as Obj6, Query, Relation as Relation3 } from "@dxos/echo";
1430
+ import { Ref as Ref3, useQuery } from "@dxos/react-client/echo";
1431
+ import { useIdentity as useIdentity5 } from "@dxos/react-client/halo";
1432
+ import { useTranslation as useTranslation10 } from "@dxos/react-ui";
1433
+ import { Layout } from "@dxos/react-ui";
1434
+ import { useAttended } from "@dxos/react-ui-attention";
1435
+ import { Tabs } from "@dxos/react-ui-tabs";
1436
+ import { AnchoredTo, Thread } from "@dxos/types";
1437
+ import { mx as mx10 } from "@dxos/ui-theme";
1438
+
1439
+ // src/components/CommentsContainer.tsx
1440
+ import React16, { useEffect as useEffect9 } from "react";
1441
+ import { Obj as Obj5, Relation as Relation2 } from "@dxos/echo";
1442
+ import { Callout, Icon as Icon4, Trans, useTranslation as useTranslation8 } from "@dxos/react-ui";
1443
+
1444
+ // src/components/CommentsThreadContainer.tsx
1445
+ import React15, { useCallback as useCallback4, useMemo as useMemo7, useRef as useRef5, useState as useState8 } from "react";
1446
+ import { Obj as Obj4, Relation } from "@dxos/echo";
1447
+ import { useObject as useObject2 } from "@dxos/echo-react";
1448
+ import { getSpace as getSpace2, useMembers as useMembers2 } from "@dxos/react-client/echo";
1449
+ import { useIdentity as useIdentity4 } from "@dxos/react-client/halo";
1450
+ import { IconButton as IconButton5, Tag, Tooltip, useThemeContext as useThemeContext3, useTranslation as useTranslation7 } from "@dxos/react-ui";
1451
+ import { MessageTextbox as MessageTextbox2, Thread as ThreadComponent2 } from "@dxos/react-ui-thread";
1452
+ import { createBasicExtensions as createBasicExtensions3, createThemeExtensions as createThemeExtensions3, listener as listener2 } from "@dxos/ui-editor";
1453
+ import { hoverableControlItem as hoverableControlItem2, hoverableControls as hoverableControls2, hoverableFocusedWithinControls as hoverableFocusedWithinControls2, mx as mx9 } from "@dxos/ui-theme";
1454
+ var CommentsThreadContainer = ({ anchor, current, onAttend, onComment, onResolve, onMessageDelete, onThreadDelete, onAcceptProposal }) => {
1455
+ const { themeMode } = useThemeContext3();
1456
+ const { t } = useTranslation7(meta.id);
1457
+ const identity = useIdentity4();
1458
+ const space = getSpace2(anchor);
1459
+ const members = useMembers2(space?.id);
1460
+ const detached = !anchor.anchor;
1461
+ const thread = Relation.getSource(anchor);
1462
+ const [messages] = useObject2(thread, "messages");
1463
+ const activity = useStatus(space, Obj4.getDXN(thread).toString());
1464
+ const threadScrollRef = useRef5(null);
1465
+ const textboxMetadata = getMessageMetadata(Obj4.getDXN(thread).toString(), identity);
1466
+ const [state, setState] = useState8({});
1467
+ const messageRef = useRef5("");
1468
+ const extensions = useMemo7(() => [
1469
+ createBasicExtensions3({
1470
+ placeholder: t("message placeholder")
1471
+ }),
1472
+ createThemeExtensions3({
1473
+ themeMode
1474
+ }),
1475
+ listener2({
1476
+ onChange: ({ text }) => messageRef.current = text
1477
+ }),
1478
+ command
1479
+ ], [
1480
+ state
1481
+ ]);
1482
+ const scrollToEnd = (behavior) => setTimeout(() => threadScrollRef.current?.scrollIntoView({
1483
+ behavior,
1484
+ block: "end"
1485
+ }), 10);
1486
+ const handleAttend = useCallback4(() => onAttend?.(anchor), [
1487
+ onAttend,
1488
+ anchor
1489
+ ]);
1490
+ const handleResolve = useCallback4(() => onResolve?.(anchor), [
1491
+ onResolve,
1492
+ anchor
1493
+ ]);
1494
+ const handleMessageDelete = useCallback4((id) => onMessageDelete?.(anchor, id), [
1495
+ onMessageDelete,
1496
+ anchor
1497
+ ]);
1498
+ const handleThreadDelete = useCallback4(() => onThreadDelete?.(anchor), [
1499
+ onThreadDelete,
1500
+ anchor
1501
+ ]);
1502
+ const handleAcceptProposal = useCallback4((id) => onAcceptProposal?.(anchor, id), [
1503
+ onAcceptProposal,
1504
+ anchor
1505
+ ]);
1506
+ const handleComment = useCallback4(() => {
1507
+ if (!messageRef.current) {
1508
+ return false;
1509
+ }
1510
+ onComment?.(anchor, messageRef.current);
1511
+ messageRef.current = "";
1512
+ scrollToEnd("instant");
1513
+ setState({});
1514
+ return true;
1515
+ }, [
1516
+ anchor,
1517
+ identity
1518
+ ]);
1519
+ return /* @__PURE__ */ React15.createElement(ThreadComponent2.Root, {
1520
+ id: Obj4.getDXN(thread).toString(),
1521
+ classNames: "pbs-2 border-be border-subduedSeparator last:border-none",
1522
+ current,
1523
+ onClickCapture: handleAttend,
1524
+ onFocusCapture: handleAttend
1525
+ }, /* @__PURE__ */ React15.createElement("div", {
1526
+ role: "none",
1527
+ className: mx9("col-span-2 grid grid-cols-[var(--rail-size)_1fr_min-content]", hoverableControls2, hoverableFocusedWithinControls2)
1528
+ }, detached ? /* @__PURE__ */ React15.createElement(Tooltip.Trigger, {
1529
+ asChild: true,
1530
+ content: t("detached thread label"),
1531
+ side: "top"
1532
+ }, /* @__PURE__ */ React15.createElement(ThreadComponent2.Header, {
1533
+ detached: true
1534
+ }, thread.name)) : /* @__PURE__ */ React15.createElement(ThreadComponent2.Header, null, thread.name), /* @__PURE__ */ React15.createElement("div", {
1535
+ role: "none",
1536
+ className: buttonGroupClassNames
1537
+ }, thread.status === "staged" && /* @__PURE__ */ React15.createElement(Tag, {
1538
+ palette: "neutral"
1539
+ }, t("draft button")), onResolve && !(thread?.status === "staged") && /* @__PURE__ */ React15.createElement(IconButton5, {
1540
+ "data-testid": "thread.resolve",
1541
+ variant: "ghost",
1542
+ icon: thread?.status === "resolved" ? "ph--check--fill" : "ph--check--regular",
1543
+ iconOnly: true,
1544
+ label: t("resolve thread label"),
1545
+ classNames: [
1546
+ buttonClassNames,
1547
+ thread?.status !== "resolved" && hoverableControlItem2
1548
+ ],
1549
+ onClick: handleResolve
1550
+ }), onThreadDelete && /* @__PURE__ */ React15.createElement(IconButton5, {
1551
+ "data-testid": "thread.delete",
1552
+ variant: "ghost",
1553
+ icon: "ph--x--regular",
1554
+ iconOnly: true,
1555
+ label: t("delete thread label"),
1556
+ classNames: [
1557
+ buttonClassNames,
1558
+ hoverableControlItem2
1559
+ ],
1560
+ onClick: handleThreadDelete
1561
+ }))), messages?.map((ref) => /* @__PURE__ */ React15.createElement(MessageContainer, {
1562
+ key: ref.dxn.toString(),
1563
+ editable: true,
1564
+ message: ref,
1565
+ members,
1566
+ onDelete: handleMessageDelete,
1567
+ onAcceptProposal: handleAcceptProposal
1568
+ })), /* @__PURE__ */ React15.createElement(MessageTextbox2, {
1569
+ extensions,
1570
+ onSend: handleComment,
1571
+ ...textboxMetadata
1572
+ }), /* @__PURE__ */ React15.createElement(ThreadComponent2.Status, {
1573
+ activity
1574
+ }, t("activity message")), /* @__PURE__ */ React15.createElement("div", {
1575
+ role: "none",
1576
+ className: "bs-px -mbs-px",
1577
+ ref: threadScrollRef
1578
+ }));
1579
+ };
1580
+
1581
+ // src/components/CommentsContainer.tsx
1582
+ var CommentsContainer = ({ anchors, currentId, showResolvedThreads, ...props }) => {
1583
+ const { t } = useTranslation8(meta.id);
1584
+ const filteredAnchors = showResolvedThreads ? anchors.filter((anchor) => !!Relation2.getSource(anchor)) : anchors.filter((anchor) => {
1585
+ const thread = Relation2.getSource(anchor);
1586
+ return thread && thread.status !== "resolved";
1587
+ });
1588
+ useEffect9(() => {
1589
+ if (currentId) {
1590
+ document.getElementById(currentId)?.scrollIntoView({
1591
+ behavior: "smooth",
1592
+ block: "end"
1593
+ });
1594
+ }
1595
+ }, [
1596
+ currentId
1597
+ ]);
1598
+ if (filteredAnchors.length === 0) {
1599
+ return /* @__PURE__ */ React16.createElement("div", {
1600
+ role: "none",
1601
+ className: "plb-cardSpacingBlock pli-cardSpacingInline"
1602
+ }, /* @__PURE__ */ React16.createElement(Callout.Root, null, /* @__PURE__ */ React16.createElement(Callout.Title, null, /* @__PURE__ */ React16.createElement(Trans, {
1603
+ t,
1604
+ i18nKey: "no comments message",
1605
+ components: {
1606
+ commentIcon: /* @__PURE__ */ React16.createElement(Icon4, {
1607
+ icon: "ph--chat-text--regular",
1608
+ size: 4,
1609
+ classNames: "inline-block"
1610
+ })
1611
+ }
1612
+ }))));
1613
+ }
1614
+ return /* @__PURE__ */ React16.createElement("div", null, filteredAnchors.map((anchor) => {
1615
+ const thread = Relation2.getSource(anchor);
1616
+ const threadId = Obj5.getDXN(thread).toString();
1617
+ return /* @__PURE__ */ React16.createElement(CommentsThreadContainer, {
1618
+ key: threadId,
1619
+ anchor,
1620
+ current: currentId === threadId,
1621
+ ...props
1622
+ });
1623
+ }));
1624
+ };
1625
+
1626
+ // src/components/ThreadSettings.tsx
1627
+ import React17 from "react";
1628
+ import { useTranslation as useTranslation9 } from "@dxos/react-ui";
1629
+ import { Settings as Settings2 } from "@dxos/react-ui-form";
1630
+ var ThreadSettings = ({ settings: _settings }) => {
1631
+ const { t: _t } = useTranslation9(meta.id);
1632
+ return /* @__PURE__ */ React17.createElement(Settings2.Root, null);
1633
+ };
1634
+
1635
+ // src/components/ThreadCompanion.tsx
1636
+ var initialViewState = {
1637
+ showResolvedThreads: false
1638
+ };
1639
+ var ThreadCompanion = ({ subject }) => {
1640
+ const { t } = useTranslation10(meta.id);
1641
+ const { invokePromise } = useOperationInvoker();
1642
+ const identity = useIdentity5();
1643
+ const subjectId = Obj6.getDXN(subject).toString();
1644
+ const registry = useCapability6(Capabilities.AtomRegistry);
1645
+ const stateAtom = useCapability6(ThreadCapabilities.State);
1646
+ const viewStoreAtom = useCapability6(ThreadCapabilities.ViewState);
1647
+ const state = useAtomValue6(stateAtom);
1648
+ const viewStore = useAtomValue6(viewStoreAtom);
1649
+ const drafts = state.drafts[subjectId];
1650
+ const viewState = useMemo8(() => {
1651
+ if (!viewStore[subjectId]) {
1652
+ registry.set(viewStoreAtom, {
1653
+ ...viewStore,
1654
+ [subjectId]: {
1655
+ ...initialViewState
1656
+ }
1657
+ });
1658
+ return initialViewState;
1659
+ }
1660
+ return viewStore[subjectId];
1661
+ }, [
1662
+ viewStore,
1663
+ subjectId,
1664
+ registry,
1665
+ viewStoreAtom
1666
+ ]);
1667
+ const { showResolvedThreads } = viewState;
1668
+ const onChangeViewState = useCallback5((nextValue) => {
1669
+ registry.set(viewStoreAtom, {
1670
+ ...registry.get(viewStoreAtom),
1671
+ [subjectId]: {
1672
+ ...registry.get(viewStoreAtom)[subjectId],
1673
+ showResolvedThreads: nextValue === "all"
1674
+ }
1675
+ });
1676
+ }, [
1677
+ registry,
1678
+ viewStoreAtom,
1679
+ subjectId
1680
+ ]);
1681
+ const anchorSorts = useCapabilities2(AppCapabilities.AnchorSort);
1682
+ const sort = useMemo8(() => anchorSorts.find(({ key }) => key === Obj6.getTypename(subject))?.sort, [
1683
+ anchorSorts,
1684
+ subject
1685
+ ]);
1686
+ const db = Obj6.getDatabase(subject);
1687
+ const objectsAnchoredTo = useQuery(db, Query.select(Filter.id(subject.id)).targetOf(AnchoredTo.AnchoredTo));
1688
+ const anchors = objectsAnchoredTo.toSorted((a, b) => sort?.(a, b) ?? 0).filter((anchor) => Obj6.instanceOf(Thread.Thread, Relation3.getSource(anchor))).concat(drafts ?? []);
1689
+ const attended = useAttended();
1690
+ const handleAttend = useCallback5((anchor) => {
1691
+ const thread = Relation3.getSource(anchor);
1692
+ const threadId = Obj6.getDXN(thread).toString();
1693
+ if (state.current !== threadId) {
1694
+ registry.set(stateAtom, {
1695
+ ...registry.get(stateAtom),
1696
+ current: threadId
1697
+ });
1698
+ void invokePromise(LayoutOperation.ScrollIntoView, {
1699
+ subject: Obj6.getDXN(subject).toString(),
1700
+ cursor: anchor.anchor,
1701
+ ref: threadId
1702
+ });
1703
+ }
1704
+ }, [
1705
+ state.current,
1706
+ invokePromise,
1707
+ subject,
1708
+ registry,
1709
+ stateAtom
1710
+ ]);
1711
+ const handleComment = useCallback5(async (anchor, text) => {
1712
+ await invokePromise(ThreadOperation.AddMessage, {
1713
+ anchor,
1714
+ subject,
1715
+ sender: {
1716
+ identityDid: identity?.did
1717
+ },
1718
+ text
1719
+ });
1720
+ const thread = Relation3.getSource(anchor);
1721
+ registry.set(stateAtom, {
1722
+ ...registry.get(stateAtom),
1723
+ current: Obj6.getDXN(thread).toString()
1724
+ });
1725
+ }, [
1726
+ invokePromise,
1727
+ identity,
1728
+ subject,
1729
+ registry,
1730
+ stateAtom
1731
+ ]);
1732
+ const handleResolve = useCallback5((anchor) => invokePromise(ThreadOperation.ToggleResolved, {
1733
+ thread: Relation3.getSource(anchor)
1734
+ }), [
1735
+ invokePromise
1736
+ ]);
1737
+ const handleThreadDelete = useCallback5((anchor) => invokePromise(ThreadOperation.Delete, {
1738
+ anchor,
1739
+ subject
1740
+ }), [
1741
+ invokePromise,
1742
+ subject
1743
+ ]);
1744
+ const handleMessageDelete = useCallback5((anchor, messageId) => invokePromise(ThreadOperation.DeleteMessage, {
1745
+ anchor,
1746
+ subject,
1747
+ messageId
1748
+ }), [
1749
+ invokePromise,
1750
+ subject
1751
+ ]);
1752
+ const handleAcceptProposal = useCallback5(async (anchor, messageId) => {
1753
+ const thread = Relation3.getSource(anchor);
1754
+ const messageIndex = thread.messages.findIndex(Ref3.hasObjectId(messageId));
1755
+ const message = thread.messages[messageIndex]?.target;
1756
+ const proposal = message?.blocks.find((block) => block._tag === "proposal");
1757
+ if (!proposal || !anchor.anchor) {
1758
+ return;
1759
+ }
1760
+ await invokePromise(CollaborationOperation.AcceptProposal, {
1761
+ subject,
1762
+ anchor: anchor.anchor,
1763
+ proposal
1764
+ });
1765
+ await invokePromise(ThreadOperation.ToggleResolved, {
1766
+ thread
1767
+ });
1768
+ }, [
1769
+ invokePromise,
1770
+ subject
1771
+ ]);
1772
+ const comments = /* @__PURE__ */ React18.createElement(CommentsContainer, {
1773
+ anchors,
1774
+ currentId: attended.includes(subjectId) ? state.current : void 0,
1775
+ showResolvedThreads,
1776
+ onAttend: handleAttend,
1777
+ onComment: handleComment,
1778
+ onResolve: handleResolve,
1779
+ onMessageDelete: handleMessageDelete,
1780
+ onThreadDelete: handleThreadDelete,
1781
+ onAcceptProposal: handleAcceptProposal
1782
+ });
1783
+ return /* @__PURE__ */ React18.createElement(Layout.Main, {
1784
+ toolbar: true
1785
+ }, /* @__PURE__ */ React18.createElement(Tabs.Root, {
1786
+ value: showResolvedThreads ? "all" : "unresolved",
1787
+ orientation: "horizontal",
1788
+ classNames: [
1789
+ 'contents [&_[role="tabpanel"]]:min-bs-0 [&_[role="tabpanel"]]:overflow-y-auto [&_[role="tabpanel"]]:scrollbar-thin'
1790
+ ],
1791
+ onValueChange: onChangeViewState
1792
+ }, /* @__PURE__ */ React18.createElement(Tabs.Tablist, {
1793
+ classNames: mx10("bg-toolbarSurface border-be border-subduedSeparator")
1794
+ }, /* @__PURE__ */ React18.createElement(Tabs.Tab, {
1795
+ value: "unresolved",
1796
+ classNames: "text-sm"
1797
+ }, t("show unresolved label")), /* @__PURE__ */ React18.createElement(Tabs.Tab, {
1798
+ value: "all",
1799
+ classNames: "text-sm"
1800
+ }, t("show all label"))), /* @__PURE__ */ React18.createElement("div", {
1801
+ className: "overflow-y-auto"
1802
+ }, /* @__PURE__ */ React18.createElement(Tabs.Tabpanel, {
1803
+ value: "all"
1804
+ }, showResolvedThreads && comments), /* @__PURE__ */ React18.createElement(Tabs.Tabpanel, {
1805
+ value: "unresolved"
1806
+ }, !showResolvedThreads && comments))));
1807
+ };
1808
+
1809
+ export {
1810
+ Call,
1811
+ CallDebugPanel,
1812
+ ChatContainer,
1813
+ ChannelContainer,
1814
+ CallSidebar,
1815
+ ThreadCompanion,
1816
+ ThreadSettings
1817
+ };
1818
+ //# sourceMappingURL=chunk-RBRWHRHE.mjs.map