@dxos/plugin-thread 0.8.3-staging.0fa589b → 0.8.4-main.f9ba587

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 (232) hide show
  1. package/dist/lib/browser/ChannelContainer-5YH4FTBL.mjs +16 -0
  2. package/dist/lib/browser/ChatContainer-2UYQ23KO.mjs +15 -0
  3. package/dist/lib/browser/{app-graph-builder-OY7R7EJP.mjs → app-graph-builder-Q5V3KXE3.mjs} +6 -6
  4. package/dist/lib/browser/{call-manager-APQAZWHT.mjs → call-manager-NIPDYUVD.mjs} +6 -5
  5. package/dist/lib/browser/chunk-5ZVJ4GAS.mjs +21 -0
  6. package/dist/lib/browser/chunk-6NSMBO3B.mjs +56 -0
  7. package/dist/lib/browser/chunk-6NSMBO3B.mjs.map +7 -0
  8. package/dist/lib/browser/{chunk-5P5BH5GE.mjs → chunk-ERWASUQK.mjs} +66 -5
  9. package/dist/lib/browser/chunk-ERWASUQK.mjs.map +7 -0
  10. package/dist/lib/browser/{chunk-IIUTBDVB.mjs → chunk-EV4JWI7L.mjs} +2 -2
  11. package/dist/lib/browser/{chunk-JKQUJOTX.mjs → chunk-GERVMFQW.mjs} +2 -2
  12. package/dist/lib/browser/{chunk-AEXWNS6Z.mjs → chunk-JVIKVYTI.mjs} +4 -4
  13. package/dist/lib/browser/{chunk-XZKBN3NS.mjs → chunk-LCJD3NOB.mjs} +32 -31
  14. package/dist/lib/browser/chunk-LCJD3NOB.mjs.map +7 -0
  15. package/dist/lib/browser/{chunk-R5MDLUPC.mjs → chunk-LGSDKXPF.mjs} +3 -3
  16. package/dist/lib/browser/chunk-NCSFNWBZ.mjs +479 -0
  17. package/dist/lib/browser/chunk-NCSFNWBZ.mjs.map +7 -0
  18. package/dist/lib/browser/chunk-YD57K2SL.mjs +367 -0
  19. package/dist/lib/browser/chunk-YD57K2SL.mjs.map +7 -0
  20. package/dist/lib/browser/{chunk-4H4A264L.mjs → chunk-ZE7KWN36.mjs} +85 -124
  21. package/dist/lib/browser/chunk-ZE7KWN36.mjs.map +7 -0
  22. package/dist/lib/browser/index.mjs +28 -22
  23. package/dist/lib/browser/index.mjs.map +3 -3
  24. package/dist/lib/browser/{intent-resolver-FK2MDVDT.mjs → intent-resolver-MWE6XLPY.mjs} +6 -6
  25. package/dist/lib/browser/{markdown-TE5SWWNJ.mjs → markdown-ZO34G7RM.mjs} +7 -7
  26. package/dist/lib/browser/meta.json +1 -1
  27. package/dist/lib/browser/react-root-YNDNPODD.mjs +28 -0
  28. package/dist/lib/browser/{react-surface-VXUJKSOG.mjs → react-surface-2AXRNTCA.mjs} +12 -11
  29. package/dist/lib/browser/{settings-RB2RSLXV.mjs → settings-XZGPZNAU.mjs} +4 -4
  30. package/dist/lib/browser/{state-RKL5MSDP.mjs → state-H6CYONWE.mjs} +4 -4
  31. package/dist/lib/browser/types/index.mjs +2 -2
  32. package/dist/lib/node-esm/ChannelContainer-O2LZKMRM.mjs +17 -0
  33. package/dist/lib/node-esm/{ChatContainer-F6CSADV7.mjs → ChatContainer-6N35MP5J.mjs} +6 -5
  34. package/dist/lib/node-esm/{app-graph-builder-BAHBHYWI.mjs → app-graph-builder-GAKBZNU3.mjs} +6 -6
  35. package/dist/lib/node-esm/{call-manager-UUYXLF4T.mjs → call-manager-D6O5ZJJ4.mjs} +6 -5
  36. package/dist/lib/{browser/call-manager-APQAZWHT.mjs.map → node-esm/call-manager-D6O5ZJJ4.mjs.map} +1 -1
  37. package/dist/lib/node-esm/{chunk-O3V45YJP.mjs → chunk-25ABSYP2.mjs} +65 -5
  38. package/dist/lib/node-esm/chunk-25ABSYP2.mjs.map +7 -0
  39. package/dist/lib/node-esm/{chunk-UJMPYKT3.mjs → chunk-3X3YKRM2.mjs} +4 -4
  40. package/dist/lib/node-esm/{chunk-PGRP3O4O.mjs → chunk-57XR3LEF.mjs} +2 -2
  41. package/dist/lib/node-esm/{chunk-2RNIPFDA.mjs → chunk-5UQ4KKDE.mjs} +32 -31
  42. package/dist/lib/node-esm/chunk-5UQ4KKDE.mjs.map +7 -0
  43. package/dist/lib/node-esm/{chunk-K4KAUOKT.mjs → chunk-75RJ5DJI.mjs} +3 -3
  44. package/dist/lib/node-esm/chunk-A6QLTZCY.mjs +480 -0
  45. package/dist/lib/node-esm/chunk-A6QLTZCY.mjs.map +7 -0
  46. package/dist/lib/node-esm/{chunk-ESQC6SYE.mjs → chunk-GRLRWTRU.mjs} +2 -2
  47. package/dist/lib/node-esm/{chunk-WXNPD542.mjs → chunk-IHDNQLLR.mjs} +84 -124
  48. package/dist/lib/node-esm/chunk-IHDNQLLR.mjs.map +7 -0
  49. package/dist/lib/node-esm/chunk-OU5BYIDO.mjs +58 -0
  50. package/dist/lib/node-esm/chunk-OU5BYIDO.mjs.map +7 -0
  51. package/dist/lib/node-esm/chunk-RGTWAVEE.mjs +368 -0
  52. package/dist/lib/node-esm/chunk-RGTWAVEE.mjs.map +7 -0
  53. package/dist/lib/node-esm/chunk-X62X3VOK.mjs +23 -0
  54. package/dist/lib/node-esm/index.mjs +28 -22
  55. package/dist/lib/node-esm/index.mjs.map +3 -3
  56. package/dist/lib/node-esm/{intent-resolver-BU73VYW3.mjs → intent-resolver-B6PNTMPY.mjs} +6 -6
  57. package/dist/lib/node-esm/{markdown-HJUWNBLS.mjs → markdown-ZJUFV2TA.mjs} +7 -7
  58. package/dist/lib/node-esm/meta.json +1 -1
  59. package/dist/lib/node-esm/{react-root-RUXOAQNW.mjs → react-root-ZUVVTKWG.mjs} +12 -11
  60. package/dist/lib/{browser/react-root-NK3A4VG7.mjs.map → node-esm/react-root-ZUVVTKWG.mjs.map} +1 -1
  61. package/dist/lib/node-esm/{react-surface-ELXFYKP6.mjs → react-surface-OMEZTOU6.mjs} +12 -11
  62. package/dist/lib/{browser/react-surface-VXUJKSOG.mjs.map → node-esm/react-surface-OMEZTOU6.mjs.map} +1 -1
  63. package/dist/lib/node-esm/{settings-EA7DFSM6.mjs → settings-XECBSD6Q.mjs} +4 -4
  64. package/dist/lib/node-esm/{state-6AUTNROZ.mjs → state-D7WNDT3N.mjs} +4 -4
  65. package/dist/lib/node-esm/types/index.mjs +2 -2
  66. package/dist/types/src/calls/call-manager.d.ts +1 -1
  67. package/dist/types/src/calls/call-manager.d.ts.map +1 -1
  68. package/dist/types/src/calls/media-manager.d.ts.map +1 -1
  69. package/dist/types/src/calls/util/calls-service.d.ts +4 -1
  70. package/dist/types/src/calls/util/calls-service.d.ts.map +1 -1
  71. package/dist/types/src/calls/util/stub-media-streams.d.ts.map +1 -1
  72. package/dist/types/src/calls-service.stories.d.ts +22 -0
  73. package/dist/types/src/calls-service.stories.d.ts.map +1 -0
  74. package/dist/types/src/components/ChannelContainer.d.ts.map +1 -1
  75. package/dist/types/src/components/ChannelContainer.stories.d.ts +2 -2
  76. package/dist/types/src/components/ChannelContainer.stories.d.ts.map +1 -1
  77. package/dist/types/src/components/Chat.stories.d.ts +3 -2
  78. package/dist/types/src/components/Chat.stories.d.ts.map +1 -1
  79. package/dist/types/src/components/ChatContainer.d.ts +2 -2
  80. package/dist/types/src/components/ChatContainer.d.ts.map +1 -1
  81. package/dist/types/src/components/Comments.stories.d.ts +1 -1
  82. package/dist/types/src/components/Comments.stories.d.ts.map +1 -1
  83. package/dist/types/src/components/CommentsContainer.d.ts +4 -4
  84. package/dist/types/src/components/CommentsContainer.d.ts.map +1 -1
  85. package/dist/types/src/components/CommentsThreadContainer.d.ts +14 -0
  86. package/dist/types/src/components/CommentsThreadContainer.d.ts.map +1 -0
  87. package/dist/types/src/components/Media/VideoObject.stories.d.ts +1 -1
  88. package/dist/types/src/components/Media/VideoObject.stories.d.ts.map +1 -1
  89. package/dist/types/src/components/MessageContainer.d.ts.map +1 -1
  90. package/dist/types/src/components/ResponsiveGrid/ResponsiveContainer.stories.d.ts +1 -1
  91. package/dist/types/src/components/ResponsiveGrid/ResponsiveContainer.stories.d.ts.map +1 -1
  92. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.stories.d.ts +1 -1
  93. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.stories.d.ts.map +1 -1
  94. package/dist/types/src/components/index.d.ts +1 -1
  95. package/dist/types/src/components/index.d.ts.map +1 -1
  96. package/dist/types/src/hooks/index.d.ts +2 -0
  97. package/dist/types/src/hooks/index.d.ts.map +1 -1
  98. package/dist/types/src/hooks/useInaudibleAudioStreamTrack.d.ts +2 -0
  99. package/dist/types/src/hooks/useInaudibleAudioStreamTrack.d.ts.map +1 -0
  100. package/dist/types/src/hooks/useVideoStreamTrack.d.ts +3 -0
  101. package/dist/types/src/hooks/useVideoStreamTrack.d.ts.map +1 -0
  102. package/dist/types/src/testing/stories.d.ts.map +1 -1
  103. package/dist/types/src/translations.d.ts +72 -194
  104. package/dist/types/src/translations.d.ts.map +1 -1
  105. package/dist/types/tsconfig.tsbuildinfo +1 -1
  106. package/package.json +47 -48
  107. package/src/ThreadPlugin.tsx +1 -1
  108. package/src/calls/call-manager.ts +6 -2
  109. package/src/calls/media-manager.ts +11 -4
  110. package/src/calls/util/calls-service.ts +8 -5
  111. package/src/calls/util/stub-media-streams.ts +3 -6
  112. package/src/calls-service.stories.tsx +216 -0
  113. package/src/components/Call/Call.tsx +1 -1
  114. package/src/components/Call/Toolbar.tsx +2 -2
  115. package/src/components/CallDebugPanel.tsx +2 -2
  116. package/src/components/ChannelContainer.stories.tsx +5 -5
  117. package/src/components/ChannelContainer.tsx +6 -5
  118. package/src/components/Chat.stories.tsx +4 -4
  119. package/src/components/ChatContainer.tsx +10 -9
  120. package/src/components/Comments.stories.tsx +22 -15
  121. package/src/components/CommentsContainer.tsx +16 -11
  122. package/src/components/{CommentContainer.tsx → CommentsThreadContainer.tsx} +49 -80
  123. package/src/components/Media/VideoObject.stories.tsx +1 -1
  124. package/src/components/MessageContainer.tsx +27 -43
  125. package/src/components/ResponsiveGrid/ResponsiveContainer.stories.tsx +2 -2
  126. package/src/components/ResponsiveGrid/ResponsiveGrid.stories.tsx +2 -2
  127. package/src/components/ResponsiveGrid/ResponsiveGridItem.tsx +2 -2
  128. package/src/components/ThreadComplementary.tsx +2 -2
  129. package/src/components/ThreadSettings.tsx +2 -2
  130. package/src/components/index.ts +1 -1
  131. package/src/hooks/index.ts +2 -0
  132. package/src/hooks/useInaudibleAudioStreamTrack.tsx +27 -0
  133. package/src/hooks/useVideoStreamTrack.tsx +33 -0
  134. package/src/testing/stories.ts +5 -1
  135. package/src/translations.ts +9 -8
  136. package/dist/lib/browser/ChannelContainer-PKFBVENP.mjs +0 -15
  137. package/dist/lib/browser/ChatContainer-RSOKYAMK.mjs +0 -14
  138. package/dist/lib/browser/chunk-4H4A264L.mjs.map +0 -7
  139. package/dist/lib/browser/chunk-5P5BH5GE.mjs.map +0 -7
  140. package/dist/lib/browser/chunk-6NBVNXTM.mjs +0 -21
  141. package/dist/lib/browser/chunk-PG5CTFKK.mjs +0 -550
  142. package/dist/lib/browser/chunk-PG5CTFKK.mjs.map +0 -7
  143. package/dist/lib/browser/chunk-TAFSCSUR.mjs +0 -351
  144. package/dist/lib/browser/chunk-TAFSCSUR.mjs.map +0 -7
  145. package/dist/lib/browser/chunk-XZKBN3NS.mjs.map +0 -7
  146. package/dist/lib/browser/react-root-NK3A4VG7.mjs +0 -27
  147. package/dist/lib/node/ChannelContainer-YS5YT2ML.cjs +0 -36
  148. package/dist/lib/node/ChannelContainer-YS5YT2ML.cjs.map +0 -7
  149. package/dist/lib/node/ChatContainer-GCOM3M56.cjs +0 -35
  150. package/dist/lib/node/ChatContainer-GCOM3M56.cjs.map +0 -7
  151. package/dist/lib/node/app-graph-builder-PBHJNDQY.cjs +0 -179
  152. package/dist/lib/node/app-graph-builder-PBHJNDQY.cjs.map +0 -7
  153. package/dist/lib/node/call-manager-HV2XJW5O.cjs +0 -37
  154. package/dist/lib/node/call-manager-HV2XJW5O.cjs.map +0 -7
  155. package/dist/lib/node/chunk-44I33JDT.cjs +0 -1731
  156. package/dist/lib/node/chunk-44I33JDT.cjs.map +0 -7
  157. package/dist/lib/node/chunk-4YSNVPWU.cjs +0 -37
  158. package/dist/lib/node/chunk-4YSNVPWU.cjs.map +0 -7
  159. package/dist/lib/node/chunk-E3WBZTTI.cjs +0 -371
  160. package/dist/lib/node/chunk-E3WBZTTI.cjs.map +0 -7
  161. package/dist/lib/node/chunk-ERG7G6FF.cjs +0 -59
  162. package/dist/lib/node/chunk-ERG7G6FF.cjs.map +0 -7
  163. package/dist/lib/node/chunk-FUXJAVFZ.cjs +0 -108
  164. package/dist/lib/node/chunk-FUXJAVFZ.cjs.map +0 -7
  165. package/dist/lib/node/chunk-HLMCEE5K.cjs +0 -41
  166. package/dist/lib/node/chunk-HLMCEE5K.cjs.map +0 -7
  167. package/dist/lib/node/chunk-IP533AMV.cjs +0 -554
  168. package/dist/lib/node/chunk-IP533AMV.cjs.map +0 -7
  169. package/dist/lib/node/chunk-LR5NENBE.cjs +0 -54
  170. package/dist/lib/node/chunk-LR5NENBE.cjs.map +0 -7
  171. package/dist/lib/node/chunk-UM36TPCT.cjs +0 -984
  172. package/dist/lib/node/chunk-UM36TPCT.cjs.map +0 -7
  173. package/dist/lib/node/chunk-ZGDN3XBR.cjs +0 -149
  174. package/dist/lib/node/chunk-ZGDN3XBR.cjs.map +0 -7
  175. package/dist/lib/node/index.cjs +0 -310
  176. package/dist/lib/node/index.cjs.map +0 -7
  177. package/dist/lib/node/intent-resolver-SYSJ5SJG.cjs +0 -363
  178. package/dist/lib/node/intent-resolver-SYSJ5SJG.cjs.map +0 -7
  179. package/dist/lib/node/markdown-GQIPJS2F.cjs +0 -178
  180. package/dist/lib/node/markdown-GQIPJS2F.cjs.map +0 -7
  181. package/dist/lib/node/meta.json +0 -1
  182. package/dist/lib/node/react-root-6HHDMULJ.cjs +0 -51
  183. package/dist/lib/node/react-root-6HHDMULJ.cjs.map +0 -7
  184. package/dist/lib/node/react-surface-NBH42NN2.cjs +0 -122
  185. package/dist/lib/node/react-surface-NBH42NN2.cjs.map +0 -7
  186. package/dist/lib/node/settings-4LQSFEDK.cjs +0 -36
  187. package/dist/lib/node/settings-4LQSFEDK.cjs.map +0 -7
  188. package/dist/lib/node/state-IY5XX3H2.cjs +0 -50
  189. package/dist/lib/node/state-IY5XX3H2.cjs.map +0 -7
  190. package/dist/lib/node/types/index.cjs +0 -38
  191. package/dist/lib/node/types/index.cjs.map +0 -7
  192. package/dist/lib/node-esm/ChannelContainer-O4QJII2P.mjs +0 -16
  193. package/dist/lib/node-esm/chunk-2RNIPFDA.mjs.map +0 -7
  194. package/dist/lib/node-esm/chunk-O3V45YJP.mjs.map +0 -7
  195. package/dist/lib/node-esm/chunk-O63QJPQX.mjs +0 -23
  196. package/dist/lib/node-esm/chunk-P6RLFCNT.mjs +0 -352
  197. package/dist/lib/node-esm/chunk-P6RLFCNT.mjs.map +0 -7
  198. package/dist/lib/node-esm/chunk-UZWVVFT3.mjs +0 -551
  199. package/dist/lib/node-esm/chunk-UZWVVFT3.mjs.map +0 -7
  200. package/dist/lib/node-esm/chunk-WXNPD542.mjs.map +0 -7
  201. package/dist/types/src/components/CommentContainer.d.ts +0 -13
  202. package/dist/types/src/components/CommentContainer.d.ts.map +0 -1
  203. package/dist/types/src/peers.stories.d.ts +0 -11
  204. package/dist/types/src/peers.stories.d.ts.map +0 -1
  205. package/src/peers.stories.tsx +0 -189
  206. /package/dist/lib/browser/{ChannelContainer-PKFBVENP.mjs.map → ChannelContainer-5YH4FTBL.mjs.map} +0 -0
  207. /package/dist/lib/browser/{ChatContainer-RSOKYAMK.mjs.map → ChatContainer-2UYQ23KO.mjs.map} +0 -0
  208. /package/dist/lib/browser/{app-graph-builder-OY7R7EJP.mjs.map → app-graph-builder-Q5V3KXE3.mjs.map} +0 -0
  209. /package/dist/lib/{node-esm/call-manager-UUYXLF4T.mjs.map → browser/call-manager-NIPDYUVD.mjs.map} +0 -0
  210. /package/dist/lib/browser/{chunk-6NBVNXTM.mjs.map → chunk-5ZVJ4GAS.mjs.map} +0 -0
  211. /package/dist/lib/browser/{chunk-IIUTBDVB.mjs.map → chunk-EV4JWI7L.mjs.map} +0 -0
  212. /package/dist/lib/browser/{chunk-JKQUJOTX.mjs.map → chunk-GERVMFQW.mjs.map} +0 -0
  213. /package/dist/lib/browser/{chunk-AEXWNS6Z.mjs.map → chunk-JVIKVYTI.mjs.map} +0 -0
  214. /package/dist/lib/browser/{chunk-R5MDLUPC.mjs.map → chunk-LGSDKXPF.mjs.map} +0 -0
  215. /package/dist/lib/browser/{intent-resolver-FK2MDVDT.mjs.map → intent-resolver-MWE6XLPY.mjs.map} +0 -0
  216. /package/dist/lib/browser/{markdown-TE5SWWNJ.mjs.map → markdown-ZO34G7RM.mjs.map} +0 -0
  217. /package/dist/lib/{node-esm/react-root-RUXOAQNW.mjs.map → browser/react-root-YNDNPODD.mjs.map} +0 -0
  218. /package/dist/lib/{node-esm/react-surface-ELXFYKP6.mjs.map → browser/react-surface-2AXRNTCA.mjs.map} +0 -0
  219. /package/dist/lib/browser/{settings-RB2RSLXV.mjs.map → settings-XZGPZNAU.mjs.map} +0 -0
  220. /package/dist/lib/browser/{state-RKL5MSDP.mjs.map → state-H6CYONWE.mjs.map} +0 -0
  221. /package/dist/lib/node-esm/{ChannelContainer-O4QJII2P.mjs.map → ChannelContainer-O2LZKMRM.mjs.map} +0 -0
  222. /package/dist/lib/node-esm/{ChatContainer-F6CSADV7.mjs.map → ChatContainer-6N35MP5J.mjs.map} +0 -0
  223. /package/dist/lib/node-esm/{app-graph-builder-BAHBHYWI.mjs.map → app-graph-builder-GAKBZNU3.mjs.map} +0 -0
  224. /package/dist/lib/node-esm/{chunk-UJMPYKT3.mjs.map → chunk-3X3YKRM2.mjs.map} +0 -0
  225. /package/dist/lib/node-esm/{chunk-PGRP3O4O.mjs.map → chunk-57XR3LEF.mjs.map} +0 -0
  226. /package/dist/lib/node-esm/{chunk-K4KAUOKT.mjs.map → chunk-75RJ5DJI.mjs.map} +0 -0
  227. /package/dist/lib/node-esm/{chunk-ESQC6SYE.mjs.map → chunk-GRLRWTRU.mjs.map} +0 -0
  228. /package/dist/lib/node-esm/{chunk-O63QJPQX.mjs.map → chunk-X62X3VOK.mjs.map} +0 -0
  229. /package/dist/lib/node-esm/{intent-resolver-BU73VYW3.mjs.map → intent-resolver-B6PNTMPY.mjs.map} +0 -0
  230. /package/dist/lib/node-esm/{markdown-HJUWNBLS.mjs.map → markdown-ZJUFV2TA.mjs.map} +0 -0
  231. /package/dist/lib/node-esm/{settings-EA7DFSM6.mjs.map → settings-XECBSD6Q.mjs.map} +0 -0
  232. /package/dist/lib/node-esm/{state-6AUTNROZ.mjs.map → state-D7WNDT3N.mjs.map} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/plugin-thread",
3
- "version": "0.8.3-staging.0fa589b",
3
+ "version": "0.8.4-main.f9ba587",
4
4
  "description": "DXOS Threads Surface plugin",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -45,66 +45,65 @@
45
45
  "md5-hex": "5.0.0",
46
46
  "react-resize-detector": "^12.0.2",
47
47
  "wavefile": "^11.0.0",
48
- "@dxos/app-framework": "0.8.3-staging.0fa589b",
49
- "@dxos/async": "0.8.3-staging.0fa589b",
50
- "@dxos/codec-protobuf": "0.8.3-staging.0fa589b",
51
- "@dxos/context": "0.8.3-staging.0fa589b",
52
- "@dxos/display-name": "0.8.3-staging.0fa589b",
53
- "@dxos/echo-schema": "0.8.3-staging.0fa589b",
54
- "@dxos/invariant": "0.8.3-staging.0fa589b",
55
- "@dxos/echo": "0.8.3-staging.0fa589b",
56
- "@dxos/devtools": "0.8.3-staging.0fa589b",
57
- "@dxos/live-object": "0.8.3-staging.0fa589b",
58
- "@dxos/keys": "0.8.3-staging.0fa589b",
59
- "@dxos/log": "0.8.3-staging.0fa589b",
60
- "@dxos/local-storage": "0.8.3-staging.0fa589b",
61
- "@dxos/plugin-client": "0.8.3-staging.0fa589b",
62
- "@dxos/plugin-attention": "0.8.3-staging.0fa589b",
63
- "@dxos/plugin-graph": "0.8.3-staging.0fa589b",
64
- "@dxos/plugin-markdown": "0.8.3-staging.0fa589b",
65
- "@dxos/plugin-deck": "0.8.3-staging.0fa589b",
66
- "@dxos/plugin-observability": "0.8.3-staging.0fa589b",
67
- "@dxos/plugin-space": "0.8.3-staging.0fa589b",
68
- "@dxos/protocols": "0.8.3-staging.0fa589b",
69
- "@dxos/react-client": "0.8.3-staging.0fa589b",
70
- "@dxos/react-ui-dnd": "0.8.3-staging.0fa589b",
71
- "@dxos/react-ui-attention": "0.8.3-staging.0fa589b",
72
- "@dxos/react-ui-form": "0.8.3-staging.0fa589b",
73
- "@dxos/react-ui-editor": "0.8.3-staging.0fa589b",
74
- "@dxos/react-ui-menu": "0.8.3-staging.0fa589b",
75
- "@dxos/react-ui-sfx": "0.8.3-staging.0fa589b",
76
- "@dxos/react-ui-stack": "0.8.3-staging.0fa589b",
77
- "@dxos/react-ui-tabs": "0.8.3-staging.0fa589b",
78
- "@dxos/react-ui-thread": "0.8.3-staging.0fa589b",
79
- "@dxos/schema": "0.8.3-staging.0fa589b",
80
- "@dxos/react-ui-syntax-highlighter": "0.8.3-staging.0fa589b",
81
- "@dxos/util": "0.8.3-staging.0fa589b"
48
+ "@dxos/app-framework": "0.8.4-main.f9ba587",
49
+ "@dxos/async": "0.8.4-main.f9ba587",
50
+ "@dxos/codec-protobuf": "0.8.4-main.f9ba587",
51
+ "@dxos/context": "0.8.4-main.f9ba587",
52
+ "@dxos/debug": "0.8.4-main.f9ba587",
53
+ "@dxos/devtools": "0.8.4-main.f9ba587",
54
+ "@dxos/display-name": "0.8.4-main.f9ba587",
55
+ "@dxos/echo": "0.8.4-main.f9ba587",
56
+ "@dxos/echo-schema": "0.8.4-main.f9ba587",
57
+ "@dxos/invariant": "0.8.4-main.f9ba587",
58
+ "@dxos/keys": "0.8.4-main.f9ba587",
59
+ "@dxos/live-object": "0.8.4-main.f9ba587",
60
+ "@dxos/local-storage": "0.8.4-main.f9ba587",
61
+ "@dxos/log": "0.8.4-main.f9ba587",
62
+ "@dxos/plugin-attention": "0.8.4-main.f9ba587",
63
+ "@dxos/plugin-client": "0.8.4-main.f9ba587",
64
+ "@dxos/plugin-deck": "0.8.4-main.f9ba587",
65
+ "@dxos/plugin-graph": "0.8.4-main.f9ba587",
66
+ "@dxos/plugin-markdown": "0.8.4-main.f9ba587",
67
+ "@dxos/plugin-observability": "0.8.4-main.f9ba587",
68
+ "@dxos/plugin-space": "0.8.4-main.f9ba587",
69
+ "@dxos/protocols": "0.8.4-main.f9ba587",
70
+ "@dxos/react-client": "0.8.4-main.f9ba587",
71
+ "@dxos/react-ui-dnd": "0.8.4-main.f9ba587",
72
+ "@dxos/react-ui-attention": "0.8.4-main.f9ba587",
73
+ "@dxos/react-ui-form": "0.8.4-main.f9ba587",
74
+ "@dxos/react-ui-editor": "0.8.4-main.f9ba587",
75
+ "@dxos/react-ui-menu": "0.8.4-main.f9ba587",
76
+ "@dxos/react-ui-sfx": "0.8.4-main.f9ba587",
77
+ "@dxos/react-ui-syntax-highlighter": "0.8.4-main.f9ba587",
78
+ "@dxos/react-ui-stack": "0.8.4-main.f9ba587",
79
+ "@dxos/react-ui-tabs": "0.8.4-main.f9ba587",
80
+ "@dxos/schema": "0.8.4-main.f9ba587",
81
+ "@dxos/react-ui-thread": "0.8.4-main.f9ba587",
82
+ "@dxos/util": "0.8.4-main.f9ba587"
82
83
  },
83
84
  "devDependencies": {
84
- "@effect-rx/rx-react": "^0.34.1",
85
- "@effect/platform": "0.80.12",
86
- "@phosphor-icons/react": "^2.1.5",
85
+ "@effect-rx/rx-react": "0.38.0",
86
+ "@effect/platform": "0.88.0",
87
87
  "@types/react": "~18.2.0",
88
88
  "@types/react-dom": "~18.2.0",
89
- "effect": "3.14.21",
89
+ "effect": "3.16.13",
90
90
  "react": "~18.2.0",
91
91
  "react-dom": "~18.2.0",
92
92
  "vite": "5.4.7",
93
- "@dxos/random": "0.8.3-staging.0fa589b",
94
- "@dxos/plugin-theme": "0.8.3-staging.0fa589b",
95
- "@dxos/react-ui": "0.8.3-staging.0fa589b",
96
- "@dxos/storybook-utils": "0.8.3-staging.0fa589b",
97
- "@dxos/react-ui-theme": "0.8.3-staging.0fa589b"
93
+ "@dxos/plugin-theme": "0.8.4-main.f9ba587",
94
+ "@dxos/random": "0.8.4-main.f9ba587",
95
+ "@dxos/react-ui": "0.8.4-main.f9ba587",
96
+ "@dxos/react-ui-theme": "0.8.4-main.f9ba587",
97
+ "@dxos/storybook-utils": "0.8.4-main.f9ba587"
98
98
  },
99
99
  "peerDependencies": {
100
100
  "@effect-rx/rx-react": "^0.34.1",
101
- "@effect/platform": "0.80.12",
102
- "@phosphor-icons/react": "^2.1.5",
101
+ "@effect/platform": "^0.80.12",
103
102
  "effect": "^3.13.3",
104
103
  "react": "~18.2.0",
105
104
  "react-dom": "~18.2.0",
106
- "@dxos/react-ui": "0.8.3-staging.0fa589b",
107
- "@dxos/react-ui-theme": "0.8.3-staging.0fa589b"
105
+ "@dxos/react-ui": "0.8.4-main.f9ba587",
106
+ "@dxos/react-ui-theme": "0.8.4-main.f9ba587"
108
107
  },
109
108
  "publishConfig": {
110
109
  "access": "public"
@@ -23,7 +23,7 @@ import {
23
23
  ThreadState,
24
24
  } from './capabilities';
25
25
  import { meta, THREAD_ITEM } from './meta';
26
- import translations from './translations';
26
+ import { translations } from './translations';
27
27
  import { ChannelType, ThreadAction, ThreadType } from './types';
28
28
 
29
29
  // TODO(Zan): Every instance of `cursor` should be replaced with `anchor`.
@@ -88,8 +88,12 @@ export class CallManager extends Resource {
88
88
  }
89
89
 
90
90
  /** @reactive */
91
- get pulledAudioTracks() {
92
- return Object.values(this._state.media.pulledAudioTracks).map((track) => track.track);
91
+ get audioTracksToPlay(): MediaStreamTrack[] {
92
+ return (this._state.call.users ?? [])
93
+ .map((user) => (user.tracks?.audioEnabled ? user.tracks?.audio : undefined))
94
+ .filter(isNonNullable)
95
+ .map((track) => this._state.media.pulledAudioTracks[track as EncodedTrackName]?.track)
96
+ .filter(isNonNullable);
93
97
  }
94
98
 
95
99
  /** @reactive */
@@ -54,6 +54,8 @@ export type MediaManagerParams = {
54
54
  serviceConfig: CallsServiceConfig;
55
55
  };
56
56
 
57
+ const USE_INAUDIBLE_AUDIO = false;
58
+
57
59
  export class MediaManager extends Resource {
58
60
  public readonly stateUpdated = new Event<MediaState>();
59
61
  private readonly _state: MediaState = { pulledVideoStreams: {}, pulledAudioTracks: {} };
@@ -86,8 +88,10 @@ export class MediaManager extends Resource {
86
88
  this._state.videoStream = new MediaStream();
87
89
  this._state.videoStream.addTrack(this._state.videoTrack);
88
90
 
89
- this._inaudibleAudioStreamTrack = await createInaudibleAudioStreamTrack({ ctx: this._ctx });
90
- this._state.audioTrack = this._inaudibleAudioStreamTrack;
91
+ if (USE_INAUDIBLE_AUDIO) {
92
+ this._inaudibleAudioStreamTrack = await createInaudibleAudioStreamTrack({ ctx: this._ctx });
93
+ this._state.audioTrack = this._inaudibleAudioStreamTrack;
94
+ }
91
95
 
92
96
  this._pushTracksTask = new DeferredTask(this._ctx, async () => {
93
97
  await this._pushTracks();
@@ -170,11 +174,14 @@ export class MediaManager extends Resource {
170
174
  async turnAudioOff(): Promise<void> {
171
175
  void this._speakingMonitor?.close();
172
176
  this._speakingMonitor = undefined;
173
- if (this._state.audioTrack !== this._inaudibleAudioStreamTrack) {
177
+ this._state.audioEnabled = false;
178
+ if (USE_INAUDIBLE_AUDIO && this._state.audioTrack !== this._inaudibleAudioStreamTrack) {
174
179
  this._state.audioTrack?.stop();
175
180
  this._state.audioTrack = this._inaudibleAudioStreamTrack;
181
+ } else {
182
+ this._state.audioTrack?.stop();
183
+ this._state.audioTrack = undefined;
176
184
  }
177
- this._state.audioEnabled = false;
178
185
  this.stateUpdated.emit(this._state);
179
186
  this._pushTracksTask!.schedule();
180
187
  }
@@ -73,7 +73,10 @@ export class CallsServicePeer extends Resource {
73
73
  pullTrackDispatcher = new BulkRequestDispatcher<
74
74
  TrackObject,
75
75
  {
76
- trackMap: Map<TrackObject, { resolvedTrack: Promise<MediaStreamTrack>; mid: string }>;
76
+ /**
77
+ * trackName -> { resolvedTrack, mid }
78
+ */
79
+ trackMap: Map<string, { resolvedTrack: Promise<MediaStreamTrack>; mid: string }>;
77
80
  }
78
81
  >(32);
79
82
 
@@ -354,14 +357,14 @@ export class CallsServicePeer extends Resource {
354
357
  );
355
358
 
356
359
  if (pulledTrackData && pulledTrackData.mid) {
357
- acc.set(track, {
360
+ acc.set(track.trackName!, {
358
361
  mid: pulledTrackData.mid,
359
362
  resolvedTrack: resolveTrack(peerConnection, (t) => t.mid === pulledTrackData.mid),
360
363
  });
361
364
  }
362
365
 
363
366
  return acc;
364
- }, new Map<TrackObject, { resolvedTrack: Promise<MediaStreamTrack>; mid: string }>());
367
+ }, new Map<string, { resolvedTrack: Promise<MediaStreamTrack>; mid: string }>());
365
368
 
366
369
  if (newTrackResponse.requiresImmediateRenegotiation) {
367
370
  await peerConnection.setRemoteDescription(new RTCSessionDescription(newTrackResponse.sessionDescription));
@@ -392,7 +395,7 @@ export class CallsServicePeer extends Resource {
392
395
  }),
393
396
  )
394
397
  .then(({ trackMap }) => {
395
- const trackInfo = trackMap.get(trackData);
398
+ const trackInfo = trackMap.get(trackData.trackName!);
396
399
  if (trackInfo) {
397
400
  return trackInfo.resolvedTrack
398
401
  .then((track) => {
@@ -401,7 +404,7 @@ export class CallsServicePeer extends Resource {
401
404
  })
402
405
  .catch((err) => log.catch(err));
403
406
  } else {
404
- log.error('missing track info');
407
+ log.warn('missing track info', { trackData, availableTracks: Array.from(trackMap.keys()) });
405
408
  }
406
409
  });
407
410
 
@@ -48,19 +48,16 @@ export const createInaudibleAudioStreamTrack = async ({ ctx }: { ctx: Context })
48
48
  const audioContext = new window.AudioContext();
49
49
  const oscillator = audioContext.createOscillator();
50
50
  oscillator.type = 'triangle';
51
-
52
- // set to 0.1 to make inaudible
53
- oscillator.frequency.setValueAtTime(0.1, audioContext.currentTime);
51
+ // roughly sounds like a box fan
52
+ oscillator.frequency.setValueAtTime(20, audioContext.currentTime);
54
53
 
55
54
  const gainNode = audioContext.createGain();
56
55
  // even w/ gain at 0 some packets are sent
57
- gainNode.gain.setValueAtTime(0, audioContext.currentTime);
58
-
56
+ gainNode.gain.setValueAtTime(0.02, audioContext.currentTime);
59
57
  oscillator.connect(gainNode);
60
58
 
61
59
  const destination = audioContext.createMediaStreamDestination();
62
60
  gainNode.connect(destination);
63
-
64
61
  oscillator.start();
65
62
 
66
63
  ctx.onDispose(async () => {
@@ -0,0 +1,216 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import '@dxos-theme';
6
+
7
+ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
8
+
9
+ import { scheduleTask, sleep } from '@dxos/async';
10
+ import { Context } from '@dxos/context';
11
+ import { invariant } from '@dxos/invariant';
12
+ import { log } from '@dxos/log';
13
+ import { Config, useConfig } from '@dxos/react-client';
14
+ import { withClientProvider } from '@dxos/react-client/testing';
15
+ import { Button } from '@dxos/react-ui';
16
+ import { Json } from '@dxos/react-ui-syntax-highlighter';
17
+ import { withLayout, withTheme } from '@dxos/storybook-utils';
18
+
19
+ import { type TrackObject, CallsServicePeer, CALLS_URL } from './calls';
20
+ import { useInaudibleAudioStreamTrack, useVideoStreamTrack } from './hooks';
21
+ // @ts-ignore
22
+ import video from '../testing/video.mp4';
23
+
24
+ const pushAndPullTrack = (mediaStreamTrack?: MediaStreamTrack) => {
25
+ const config = useConfig();
26
+ const callsConfig = {
27
+ iceServers: config.get('runtime.services.ice'),
28
+ apiBase: `${CALLS_URL}/api/calls`,
29
+ };
30
+ const peerPush = useMemo(() => new CallsServicePeer(callsConfig), []);
31
+ const peerPull = useMemo(() => new CallsServicePeer(callsConfig), []);
32
+ const [metrics, setMetrics] = useState<Record<string, any>>({});
33
+ const trackInfo = useRef<TrackObject | undefined>(undefined);
34
+ const pullCtx = useRef<Context | undefined>(undefined);
35
+ const [pulledTrack, setPulledTrack] = useState<MediaStreamTrack | undefined>(undefined);
36
+ const hadRun = useRef(false);
37
+
38
+ // Push/pull video stream track to cloudflare.
39
+ useEffect(() => {
40
+ if (hadRun.current || !mediaStreamTrack || !peerPush || !peerPull) {
41
+ log.info('not running', { hadRun: hadRun.current, mediaStreamTrack, peerPush, peerPull });
42
+ return;
43
+ }
44
+ hadRun.current = true;
45
+ const ctx = Context.default();
46
+ ctx.onDispose(() => {
47
+ log.info('disposing ctx', { ctx });
48
+ });
49
+ scheduleTask(
50
+ ctx,
51
+ async () => {
52
+ log.info('starting push/pull', { mediaStreamTrack });
53
+ await peerPush.open();
54
+ await peerPull.open();
55
+ ctx.onDispose(() => {
56
+ void peerPush.close();
57
+ void peerPull.close();
58
+ });
59
+
60
+ // Push track to cloudflare.
61
+ performance.mark('push:begin');
62
+ log.info('pushing track', { track: mediaStreamTrack });
63
+ trackInfo.current = await peerPush.pushTrack({ track: mediaStreamTrack });
64
+ performance.mark('push:end');
65
+ const pushTime = performance.measure('push', 'push:begin', 'push:end').duration;
66
+ log.info('successfully pushed track', { pushTime, trackInfo: trackInfo.current });
67
+ setMetrics((prev) => ({ ...prev, 'time to push track [ms]': Math.round(pushTime) }));
68
+
69
+ // Wait for cloudflare to process the track.
70
+ await sleep(1000);
71
+
72
+ // Pull track from cloudflare.
73
+ performance.mark('pullTrack:begin');
74
+ pullCtx.current = Context.default();
75
+ let retries = 0;
76
+ let pulledTrack: MediaStreamTrack | undefined;
77
+ while (!pulledTrack && retries < 3) {
78
+ retries++;
79
+ log.info('pulling track', {
80
+ trackData: { ...trackInfo.current!, mid: undefined },
81
+ retries,
82
+ pulledTrack,
83
+ });
84
+ pulledTrack = await peerPull.pullTrack({
85
+ trackData: { ...trackInfo.current!, mid: undefined },
86
+ ctx: pullCtx.current,
87
+ });
88
+ await sleep(200);
89
+ }
90
+ invariant(pulledTrack);
91
+ setPulledTrack(pulledTrack);
92
+ performance.mark('pullTrack:end');
93
+ const pullTime = performance.measure('pullTrack', 'pullTrack:begin', 'pullTrack:end').duration;
94
+ setMetrics((prev) => ({ ...prev, 'time to pull track [ms]': Math.round(pullTime) }));
95
+ log.info('successfully pulled track', { pullTime, pulledTrack });
96
+ },
97
+ 1000,
98
+ );
99
+
100
+ return () => {
101
+ void ctx.dispose();
102
+ };
103
+ }, [mediaStreamTrack, peerPush, peerPull]);
104
+
105
+ const rePullTrack = useCallback(async () => {
106
+ performance.mark('rePullVideo:begin');
107
+ invariant(pulledTrack);
108
+ pulledTrack.stop();
109
+ await pullCtx.current!.dispose();
110
+ pullCtx.current = Context.default();
111
+ const newPulledTrack = await peerPull.pullTrack({
112
+ trackData: { ...trackInfo.current!, mid: undefined },
113
+ ctx: pullCtx.current,
114
+ });
115
+ invariant(newPulledTrack);
116
+ setPulledTrack(newPulledTrack);
117
+ performance.mark('rePullVideo:end');
118
+ const rePullTime = performance.measure('rePullVideo', 'rePullVideo:begin', 'rePullVideo:end').duration;
119
+ setMetrics((prev) => ({ ...prev, 'time to re-pull video [ms]': Math.round(rePullTime) }));
120
+ }, [peerPull, trackInfo.current, pullCtx.current, pulledTrack]);
121
+
122
+ return {
123
+ pulledTrack,
124
+ rePullTrack,
125
+ metrics,
126
+ };
127
+ };
128
+
129
+ const meta = {
130
+ title: 'plugins/plugin-thread/calls-service',
131
+ decorators: [
132
+ withClientProvider({
133
+ config: new Config({
134
+ runtime: {
135
+ services: {
136
+ iceProviders: [{ urls: 'https://edge.dxos.workers.dev/ice' }],
137
+ },
138
+ },
139
+ }),
140
+ }),
141
+ withTheme,
142
+ withLayout(),
143
+ ],
144
+ parameters: {
145
+ layout: 'centered',
146
+ },
147
+ };
148
+
149
+ export default meta;
150
+
151
+ export const Default = {
152
+ render: ({ videoSrc }: { videoSrc: string }) => {
153
+ const pushVideoElement = useRef<HTMLVideoElement>(null);
154
+ const pullVideoElement = useRef<HTMLVideoElement>(null);
155
+ // Get video stream track.
156
+ const videoStreamTrack = useVideoStreamTrack(pushVideoElement, videoSrc);
157
+ const { pulledTrack, rePullTrack, metrics } = pushAndPullTrack(videoStreamTrack);
158
+ const hadRun = useRef(false);
159
+
160
+ // Push/pull video stream track to cloudflare.
161
+ useEffect(() => {
162
+ if (!pulledTrack || hadRun.current) {
163
+ return;
164
+ }
165
+ hadRun.current = true;
166
+ const ctx = Context.default();
167
+ scheduleTask(ctx, async () => {
168
+ pullVideoElement.current!.srcObject = new MediaStream([pulledTrack]);
169
+ await pullVideoElement.current!.play();
170
+ });
171
+
172
+ return () => {
173
+ void ctx.dispose();
174
+ };
175
+ }, [pulledTrack]);
176
+
177
+ return (
178
+ <div className='grid grid-rows-3 gap-4 items-center'>
179
+ <video ref={pushVideoElement} muted autoPlay loop />
180
+ <div className='flex flex-col gap-4'>
181
+ <video ref={pullVideoElement} muted />
182
+ <Button
183
+ disabled={
184
+ !(
185
+ pullVideoElement?.current?.srcObject instanceof MediaStream &&
186
+ pullVideoElement.current.srcObject.getTracks()[0]
187
+ )
188
+ }
189
+ onClick={rePullTrack}
190
+ >
191
+ Re-pull video
192
+ </Button>
193
+ </div>
194
+ <Json data={metrics} />
195
+ </div>
196
+ );
197
+ },
198
+ args: {
199
+ videoSrc: video,
200
+ },
201
+ };
202
+
203
+ export const InaudibleAudioStreamTrack = {
204
+ render: () => {
205
+ const audioStreamTrack = useInaudibleAudioStreamTrack();
206
+
207
+ const { rePullTrack, metrics } = pushAndPullTrack(audioStreamTrack);
208
+
209
+ return (
210
+ <div className='flex flex-col gap-4 items-center'>
211
+ <Json data={metrics} />
212
+ <Button onClick={rePullTrack}>Re-pull audio</Button>
213
+ </div>
214
+ );
215
+ },
216
+ };
@@ -34,7 +34,7 @@ type CallAudioProps = {};
34
34
  const CallAudio: FC<CallAudioProps> = () => {
35
35
  const call = useCapability(ThreadCapabilities.CallManager);
36
36
 
37
- return <AudioStream tracks={call.pulledAudioTracks} />;
37
+ return <AudioStream tracks={call.audioTracksToPlay} />;
38
38
  };
39
39
 
40
40
  CallAudio.displayName = 'CallAudio';
@@ -19,7 +19,7 @@ import {
19
19
  import { groupHoverControlItemWithTransition, mx } from '@dxos/react-ui-theme';
20
20
 
21
21
  import { ThreadCapabilities } from '../../capabilities';
22
- import { THREAD_PLUGIN } from '../../meta';
22
+ import { meta } from '../../meta';
23
23
  import { type ChannelType } from '../../types';
24
24
 
25
25
  export type ToolbarProps = ThemedClassName<{
@@ -40,7 +40,7 @@ export const Toolbar = ({
40
40
  onJoin,
41
41
  onLeave,
42
42
  }: ToolbarProps) => {
43
- const { t } = useTranslation(THREAD_PLUGIN);
43
+ const { t } = useTranslation(meta.id);
44
44
  const { graph } = useAppGraph();
45
45
  const call = useCapability(ThreadCapabilities.CallManager);
46
46
 
@@ -11,16 +11,16 @@ import { Input, useTranslation, type ThemedClassName } from '@dxos/react-ui';
11
11
  import { Json } from '@dxos/react-ui-syntax-highlighter';
12
12
 
13
13
  import { type GlobalState } from '../calls';
14
- import { THREAD_PLUGIN } from '../meta';
14
+ import { meta } from '../meta';
15
15
 
16
16
  export type CallDebugPanelProps = ThemedClassName<{
17
17
  state?: GlobalState;
18
18
  }>;
19
19
 
20
20
  export const CallDebugPanel = ({ state }: CallDebugPanelProps) => {
21
+ const { t } = useTranslation(meta.id);
21
22
  const users = state?.call?.users;
22
23
  const self = state?.call?.self;
23
- const { t } = useTranslation(THREAD_PLUGIN);
24
24
 
25
25
  const [open, setOpen] = useState(false);
26
26
  const handleToggle = () => setOpen(!open);
@@ -4,7 +4,7 @@
4
4
 
5
5
  import '@dxos-theme';
6
6
 
7
- import { type Meta, type StoryObj } from '@storybook/react';
7
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
8
8
  import React from 'react';
9
9
 
10
10
  import { contributes } from '@dxos/app-framework';
@@ -16,24 +16,24 @@ import { withLayout, ColumnContainer } from '@dxos/storybook-utils';
16
16
 
17
17
  import { ChannelContainer, type ChannelContainerProps } from './ChannelContainer';
18
18
  import { createThreadPlugins } from '../testing';
19
- import translations from '../translations';
19
+ import { translations } from '../translations';
20
20
  import { ChannelType, ThreadType } from '../types';
21
21
 
22
22
  // TODO(wittjosiah): Channel doesn't render full height.
23
- const Story = () => {
23
+ const Story = ({ roomId }: ChannelContainerProps) => {
24
24
  const space = useSpace();
25
25
  const [channel] = useQuery(space, Query.type(ChannelType));
26
26
  if (!channel) {
27
27
  return null;
28
28
  }
29
29
 
30
- return <ChannelContainer channel={channel} />;
30
+ return <ChannelContainer channel={channel} roomId={roomId} />;
31
31
  };
32
32
 
33
33
  const meta: Meta<ChannelContainerProps> = {
34
34
  title: 'plugins/plugin-thread/ChannelContainer',
35
35
  component: ChannelContainer,
36
- render: () => <Story />,
36
+ render: (args) => <Story {...args} />,
37
37
  decorators: [
38
38
  withPluginManager({
39
39
  plugins: [...(await createThreadPlugins())],
@@ -7,6 +7,7 @@ import React, { useCallback, useEffect, useMemo, useState, type ChangeEvent } fr
7
7
 
8
8
  import { useCapabilities, useCapability } from '@dxos/app-framework';
9
9
  import { Context } from '@dxos/context';
10
+ import { failUndefined } from '@dxos/debug';
10
11
  import { log } from '@dxos/log';
11
12
  import { useClient } from '@dxos/react-client';
12
13
  import { fullyQualifiedId, getSpace } from '@dxos/react-client/echo';
@@ -20,7 +21,7 @@ import { StackItem } from '@dxos/react-ui-stack';
20
21
  import { Call } from './Call';
21
22
  import ChatContainer from './ChatContainer';
22
23
  import { ThreadCapabilities } from '../capabilities';
23
- import { THREAD_PLUGIN } from '../meta';
24
+ import { meta } from '../meta';
24
25
  import { type ChannelType } from '../types';
25
26
 
26
27
  export type ChannelContainerProps = {
@@ -36,7 +37,7 @@ export type ChannelContainerProps = {
36
37
  export const ChannelContainer = ({ channel, roomId: _roomId, role, fullscreen }: ChannelContainerProps) => {
37
38
  const space = getSpace(channel);
38
39
  const callManager = useCapability(ThreadCapabilities.CallManager);
39
- const roomId = channel ? fullyQualifiedId(channel) : _roomId;
40
+ const roomId = _roomId ?? (channel ? fullyQualifiedId(channel) : failUndefined());
40
41
  const identity = useIdentity();
41
42
  const isNamed = !!identity?.profile?.displayName;
42
43
  const joinSound = useSoundEffect('JoinCall');
@@ -133,7 +134,7 @@ export const ChannelContainer = ({ channel, roomId: _roomId, role, fullscreen }:
133
134
  export default ChannelContainer;
134
135
 
135
136
  const DisplayNameMissing = () => {
136
- const { t } = useTranslation(THREAD_PLUGIN);
137
+ const { t } = useTranslation(meta.id);
137
138
  const client = useClient();
138
139
  const [displayName, setDisplayName] = useState('');
139
140
  const handleChange = useCallback((event: ChangeEvent<HTMLInputElement>) => setDisplayName(event.target.value), []);
@@ -163,10 +164,10 @@ const useChannelToolbarActions = (onJoinCall?: () => void) => {
163
164
  return {
164
165
  nodes: [
165
166
  createMenuItemGroup('root', {
166
- label: ['channel toolbar title', { ns: THREAD_PLUGIN }],
167
+ label: ['channel toolbar title', { ns: meta.id }],
167
168
  }),
168
169
  createMenuAction('video-call', () => onJoinCall?.(), {
169
- label: ['start video call label', { ns: THREAD_PLUGIN }],
170
+ label: ['start video call label', { ns: meta.id }],
170
171
  icon: 'ph--video-camera--regular',
171
172
  type: 'video-call',
172
173
  }),
@@ -4,7 +4,7 @@
4
4
 
5
5
  import '@dxos-theme';
6
6
 
7
- import { type Meta } from '@storybook/react';
7
+ import { type Meta } from '@storybook/react-vite';
8
8
  import React, { useEffect, useState } from 'react';
9
9
 
10
10
  import { Capabilities, contributes, createSurface, IntentPlugin } from '@dxos/app-framework';
@@ -20,7 +20,7 @@ import { DataType } from '@dxos/schema';
20
20
  import { withLayout, withTheme } from '@dxos/storybook-utils';
21
21
 
22
22
  import { ChatContainer } from './ChatContainer';
23
- import translations from '../translations';
23
+ import { translations } from '../translations';
24
24
  import { ChannelType, ThreadType } from '../types';
25
25
 
26
26
  faker.seed(1);
@@ -60,9 +60,9 @@ const Story = () => {
60
60
 
61
61
  export const Default = {};
62
62
 
63
- const meta: Meta = {
63
+ const meta: Meta<typeof Thread.Root> = {
64
64
  title: 'plugins/plugin-thread/Chat',
65
- component: Thread,
65
+ component: Thread.Root,
66
66
  render: () => <Story />,
67
67
  decorators: [
68
68
  withPluginManager({