@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
@@ -15,9 +15,8 @@ import {
15
15
  MessageTextbox,
16
16
  type MessageTextboxProps,
17
17
  Thread,
18
- ThreadFooter,
18
+ type ThreadRootProps,
19
19
  threadLayout,
20
- type ThreadProps,
21
20
  } from '@dxos/react-ui-thread';
22
21
  import { DataType } from '@dxos/schema';
23
22
  import { isNonNullable } from '@dxos/util';
@@ -25,12 +24,12 @@ import { isNonNullable } from '@dxos/util';
25
24
  import { MessageContainer } from './MessageContainer';
26
25
  import { command } from './command-extension';
27
26
  import { useStatus } from '../hooks';
28
- import { THREAD_PLUGIN } from '../meta';
27
+ import { meta } from '../meta';
29
28
  import { type ThreadType } from '../types';
30
29
  import { getMessageMetadata } from '../util';
31
30
 
32
31
  export const ChatHeading = ({ attendableId }: { attendableId?: string }) => {
33
- const { t } = useTranslation(THREAD_PLUGIN);
32
+ const { t } = useTranslation(meta.id);
34
33
  return (
35
34
  <div role='none' className='flex items-center'>
36
35
  <StackItem.SigilButton attendableId={attendableId}>
@@ -46,14 +45,14 @@ export type ChatContainerProps = {
46
45
  thread: ThreadType;
47
46
  context?: Obj.Any;
48
47
  autoFocusTextbox?: boolean;
49
- } & Pick<ThreadProps, 'current'>;
48
+ } & Pick<ThreadRootProps, 'current'>;
50
49
 
51
50
  export const ChatContainer = ({ space, thread, context, current, autoFocusTextbox }: ChatContainerProps) => {
51
+ const { t } = useTranslation(meta.id);
52
52
  const id = fullyQualifiedId(thread);
53
53
  const identity = useIdentity()!;
54
54
  const members = useMembers(space?.key);
55
55
  const activity = useStatus(space, id);
56
- const { t } = useTranslation(THREAD_PLUGIN);
57
56
  // TODO(wittjosiah): This is a hack to reset the editor after a message is sent.
58
57
  const [_count, _setCount] = useState(0);
59
58
  const rerenderEditor = () => _setCount((count) => count + 1);
@@ -109,7 +108,7 @@ export const ChatContainer = ({ space, thread, context, current, autoFocusTextbo
109
108
  };
110
109
 
111
110
  return (
112
- <Thread
111
+ <Thread.Root
113
112
  current={current}
114
113
  id={id}
115
114
  classNames='bs-full grid-rows-[1fr_min-content_min-content] overflow-hidden transition-[padding-block-end] [[data-sidebar-inline-start-state=open]_&]:lg:pbe-0'
@@ -131,9 +130,11 @@ export const ChatContainer = ({ space, thread, context, current, autoFocusTextbo
131
130
  </ScrollArea.Scrollbar>
132
131
  </ScrollArea.Viewport>
133
132
  </ScrollArea.Root>
133
+
134
134
  <MessageTextbox extensions={extensions} autoFocus={autoFocus} onSend={handleCreate} {...textboxMetadata} />
135
- <ThreadFooter activity={activity}>{t('activity message')}</ThreadFooter>
136
- </Thread>
135
+
136
+ <Thread.Status activity={activity}>{t('activity message')}</Thread.Status>
137
+ </Thread.Root>
137
138
  );
138
139
  };
139
140
 
@@ -4,29 +4,29 @@
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 } from 'react';
9
9
 
10
10
  import { IntentPlugin } from '@dxos/app-framework';
11
11
  import { withPluginManager } from '@dxos/app-framework/testing';
12
12
  import { Obj, Query, Relation, Type } from '@dxos/echo';
13
+ import { ClientPlugin } from '@dxos/plugin-client';
13
14
  import { faker } from '@dxos/random';
14
15
  import { useQuery, useSpace } from '@dxos/react-client/echo';
15
16
  import { useIdentity } from '@dxos/react-client/halo';
16
- import { type ClientRepeatedComponentProps, ClientRepeater } from '@dxos/react-client/testing';
17
17
  import { AnchoredTo, DataType } from '@dxos/schema';
18
- import { withLayout, withTheme } from '@dxos/storybook-utils';
18
+ import { layoutCentered, render, withLayout, withTheme } from '@dxos/storybook-utils';
19
19
 
20
20
  import { CommentsContainer } from './CommentsContainer';
21
21
  import { createCommentThread } from './testing';
22
- import translations from '../translations';
22
+ import { translations } from '../translations';
23
23
  import { ThreadType } from '../types';
24
24
 
25
25
  faker.seed(1);
26
26
 
27
- const Story = ({ spaceKey }: ClientRepeatedComponentProps) => {
27
+ const DefaultStory = () => {
28
28
  const identity = useIdentity();
29
- const space = useSpace(spaceKey);
29
+ const space = useSpace();
30
30
  const anchors = useQuery(space, Query.type(AnchoredTo));
31
31
 
32
32
  useEffect(() => {
@@ -58,26 +58,33 @@ const Story = ({ spaceKey }: ClientRepeatedComponentProps) => {
58
58
  }
59
59
 
60
60
  return (
61
- <div className='flex justify-center overflow-y-auto bg-white dark:bg-black'>
62
- <div className='flex flex-col w-[30rem]'>
63
- <CommentsContainer anchors={anchors} onThreadDelete={console.log} />
64
- </div>
61
+ <div className='w-[30rem] overflow-y-auto bg-baseSurface'>
62
+ <CommentsContainer anchors={anchors} onThreadDelete={console.log} />
65
63
  </div>
66
64
  );
67
65
  };
68
66
 
69
67
  const meta: Meta = {
70
68
  title: 'plugins/plugin-thread/Comments',
71
- // TODO(wittjosiah): Use decorator.
72
- render: () => <ClientRepeater component={Story} createIdentity createSpace types={[ThreadType, DataType.Message]} />,
69
+ render: render(DefaultStory),
73
70
  decorators: [
74
71
  withTheme,
75
- withLayout({ fullscreen: true }),
72
+ withLayout({ fullscreen: true, classNames: layoutCentered }),
76
73
  withPluginManager({
77
- plugins: [IntentPlugin()],
74
+ plugins: [
75
+ IntentPlugin(),
76
+ ClientPlugin({
77
+ types: [DataType.Message, ThreadType, AnchoredTo],
78
+ onClientInitialized: async (_, client) => {
79
+ await client.halo.createIdentity();
80
+ },
81
+ }),
82
+ ],
78
83
  }),
79
84
  ],
80
- parameters: { translations },
85
+ parameters: {
86
+ translations,
87
+ },
81
88
  };
82
89
 
83
90
  export default meta;
@@ -9,21 +9,22 @@ import { fullyQualifiedId } from '@dxos/react-client/echo';
9
9
  import { Callout, Icon, Trans, useTranslation } from '@dxos/react-ui';
10
10
  import { type AnchoredTo } from '@dxos/schema';
11
11
 
12
- import { CommentContainer, type CommentContainerProps } from './CommentContainer';
13
- import { THREAD_PLUGIN } from '../meta';
12
+ import { CommentsThreadContainer, type CommentsThreadContainerProps } from './CommentsThreadContainer';
13
+ import { meta } from '../meta';
14
14
  import { type ThreadType } from '../types';
15
15
 
16
- export type ThreadsContainerProps = Omit<CommentContainerProps, 'anchor' | 'current'> & {
16
+ export type CommentsContainerProps = Omit<CommentsThreadContainerProps, 'anchor' | 'current'> & {
17
17
  anchors: AnchoredTo[];
18
18
  currentId?: string;
19
19
  showResolvedThreads?: boolean;
20
20
  };
21
21
 
22
22
  /**
23
- * Comment threads.
23
+ * Root container for collection of comment threads.
24
24
  */
25
- export const CommentsContainer = ({ anchors, currentId, showResolvedThreads, ...props }: ThreadsContainerProps) => {
26
- const { t } = useTranslation(THREAD_PLUGIN);
25
+ export const CommentsContainer = ({ anchors, currentId, showResolvedThreads, ...props }: CommentsContainerProps) => {
26
+ const { t } = useTranslation(meta.id);
27
+
27
28
  // TODO(wittjosiah): There seems to be a race between thread and anchor being deleted.
28
29
  const filteredAnchors = showResolvedThreads
29
30
  ? anchors.filter((anchor) => !!Relation.getSource(anchor))
@@ -58,9 +59,13 @@ export const CommentsContainer = ({ anchors, currentId, showResolvedThreads, ...
58
59
  );
59
60
  }
60
61
 
61
- return filteredAnchors.map((anchor) => {
62
- const thread = Relation.getSource(anchor) as ThreadType;
63
- const threadId = fullyQualifiedId(thread);
64
- return <CommentContainer key={threadId} anchor={anchor} current={currentId === threadId} {...props} />;
65
- });
62
+ return (
63
+ <div>
64
+ {filteredAnchors.map((anchor) => {
65
+ const thread = Relation.getSource(anchor) as ThreadType;
66
+ const threadId = fullyQualifiedId(thread);
67
+ return <CommentsThreadContainer key={threadId} anchor={anchor} current={currentId === threadId} {...props} />;
68
+ })}
69
+ </div>
70
+ );
66
71
  };
@@ -2,97 +2,38 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { CheckCircle, X } from '@phosphor-icons/react';
6
5
  import React, { useCallback, useMemo, useRef, useState } from 'react';
7
6
 
8
- import { Relation } from '@dxos/echo';
9
- import { RefArray } from '@dxos/live-object';
7
+ import { Ref, Relation } from '@dxos/echo';
10
8
  import { fullyQualifiedId, getSpace, useMembers } from '@dxos/react-client/echo';
11
9
  import { useIdentity } from '@dxos/react-client/halo';
12
- import { Button, Tag, Tooltip, useThemeContext, useTranslation } from '@dxos/react-ui';
10
+ import { IconButton, Tag, Tooltip, useThemeContext, useTranslation } from '@dxos/react-ui';
13
11
  import { createBasicExtensions, createThemeExtensions, listener } from '@dxos/react-ui-editor';
14
- import {
15
- getSize,
16
- hoverableControlItem,
17
- hoverableControls,
18
- hoverableFocusedWithinControls,
19
- mx,
20
- } from '@dxos/react-ui-theme';
21
- import {
22
- MessageTextbox,
23
- type MessageTextboxProps,
24
- Thread,
25
- ThreadFooter,
26
- ThreadHeading,
27
- type ThreadProps,
28
- } from '@dxos/react-ui-thread';
12
+ import { hoverableControlItem, hoverableControls, hoverableFocusedWithinControls, mx } from '@dxos/react-ui-theme';
13
+ import { MessageTextbox, type MessageTextboxProps, Thread, type ThreadRootProps } from '@dxos/react-ui-thread';
29
14
  import { type AnchoredTo } from '@dxos/schema';
30
15
  import { isNonNullable } from '@dxos/util';
31
16
 
32
17
  import { MessageContainer } from './MessageContainer';
33
18
  import { command } from './command-extension';
34
19
  import { useStatus } from '../hooks';
35
- import { THREAD_PLUGIN } from '../meta';
20
+ import { meta } from '../meta';
36
21
  import { type ThreadType } from '../types';
37
22
  import { getMessageMetadata } from '../util';
38
23
 
39
- const sizeClass = getSize(4);
24
+ // TODO(burdon): Remove need for p-1.
25
+ export const commentControlClassNames = '!p-1 transition-opacity';
40
26
 
41
- // TODO(thure): #8149
42
- const commentControlClassNames = '!p-1 !min-bs-0 transition-opacity';
43
-
44
- const ToggleResolvedButton = ({
45
- isResolved,
46
- onResolve,
47
- }: {
48
- isResolved: boolean | undefined;
49
- onResolve: () => void;
50
- }) => {
51
- const { t } = useTranslation(THREAD_PLUGIN);
52
- const label = t(isResolved ? 'mark as unresolved label' : 'mark as resolved label');
53
- return (
54
- <Tooltip.Trigger asChild content={label}>
55
- <Button
56
- variant='ghost'
57
- data-testid='thread.toggle-resolved'
58
- onClick={onResolve}
59
- classNames={[commentControlClassNames, !isResolved && hoverableControlItem]}
60
- >
61
- <span className='sr-only'>{label}</span>
62
- {isResolved ? <CheckCircle className={sizeClass} weight='fill' /> : <CheckCircle className={sizeClass} />}
63
- </Button>
64
- </Tooltip.Trigger>
65
- );
66
- };
67
-
68
- const DeleteThreadButton = ({ onDelete }: { onDelete: () => void }) => {
69
- const { t } = useTranslation(THREAD_PLUGIN);
70
- const label = t('delete thread label');
71
- return (
72
- <Tooltip.Trigger asChild content={label}>
73
- <Button
74
- variant='ghost'
75
- data-testid='thread.delete'
76
- onClick={onDelete}
77
- classNames={[commentControlClassNames, hoverableControlItem]}
78
- >
79
- <span className='sr-only'>{label}</span>
80
- <X className={sizeClass} />
81
- </Button>
82
- </Tooltip.Trigger>
83
- );
84
- };
85
-
86
- export type CommentContainerProps = {
27
+ export type CommentsThreadContainerProps = {
87
28
  anchor: AnchoredTo;
88
29
  onAttend?: (anchor: AnchoredTo) => void;
89
30
  onComment?: (anchor: AnchoredTo, message: string) => void;
90
31
  onResolve?: (anchor: AnchoredTo) => void;
91
32
  onMessageDelete?: (anchor: AnchoredTo, messageId: string) => void;
92
33
  onThreadDelete?: (anchor: AnchoredTo) => void;
93
- } & Pick<ThreadProps, 'current'>;
34
+ } & Pick<ThreadRootProps, 'current'>;
94
35
 
95
- export const CommentContainer = ({
36
+ export const CommentsThreadContainer = ({
96
37
  anchor,
97
38
  current,
98
39
  onAttend,
@@ -100,14 +41,14 @@ export const CommentContainer = ({
100
41
  onResolve,
101
42
  onMessageDelete,
102
43
  onThreadDelete,
103
- }: CommentContainerProps) => {
44
+ }: CommentsThreadContainerProps) => {
45
+ const { t } = useTranslation(meta.id);
104
46
  const identity = useIdentity()!;
105
47
  const space = getSpace(anchor);
106
48
  const members = useMembers(space?.key);
107
49
  const detached = !anchor.anchor;
108
50
  const thread = Relation.getSource(anchor) as ThreadType;
109
51
  const activity = useStatus(space, fullyQualifiedId(thread));
110
- const { t } = useTranslation(THREAD_PLUGIN);
111
52
  const threadScrollRef = useRef<HTMLDivElement | null>(null);
112
53
  const { themeMode } = useThemeContext();
113
54
 
@@ -149,7 +90,13 @@ export const CommentContainer = ({
149
90
  }, [anchor, identity]);
150
91
 
151
92
  return (
152
- <Thread onClickCapture={handleAttend} onFocusCapture={handleAttend} current={current} id={fullyQualifiedId(thread)}>
93
+ <Thread.Root
94
+ id={fullyQualifiedId(thread)}
95
+ classNames='pbs-2 border-be border-subduedSeparator last:border-none'
96
+ current={current}
97
+ onClickCapture={handleAttend}
98
+ onFocusCapture={handleAttend}
99
+ >
153
100
  <div
154
101
  role='none'
155
102
  className={mx(
@@ -160,21 +107,40 @@ export const CommentContainer = ({
160
107
  >
161
108
  {detached ? (
162
109
  <Tooltip.Trigger asChild content={t('detached thread label')} side='top'>
163
- <ThreadHeading detached>{thread.name}</ThreadHeading>
110
+ <Thread.Header detached>{thread.name}</Thread.Header>
164
111
  </Tooltip.Trigger>
165
112
  ) : (
166
- <ThreadHeading>{thread.name}</ThreadHeading>
113
+ <Thread.Header>{thread.name}</Thread.Header>
167
114
  )}
168
- <div className='flex flex-row items-center pli-1'>
115
+ <div className='flex flex-row items-center gap-0.5'>
169
116
  {thread.status === 'staged' && <Tag palette='neutral'>{t('draft button')}</Tag>}
170
117
  {onResolve && !(thread?.status === 'staged') && (
171
- <ToggleResolvedButton isResolved={thread?.status === 'resolved'} onResolve={handleResolve} />
118
+ <IconButton
119
+ data-testid='thread.resolve'
120
+ variant='ghost'
121
+ icon={thread?.status === 'resolved' ? 'ph--check--fill' : 'ph--check--regular'}
122
+ iconOnly
123
+ label={t('resolve thread label')}
124
+ classNames={[commentControlClassNames, thread?.status !== 'resolved' && hoverableControlItem]}
125
+ onClick={handleResolve}
126
+ />
127
+ )}
128
+ {onThreadDelete && (
129
+ <IconButton
130
+ data-testid='thread.delete'
131
+ variant='ghost'
132
+ icon='ph--x--regular'
133
+ iconOnly
134
+ label={t('delete thread label')}
135
+ classNames={[commentControlClassNames, hoverableControlItem]}
136
+ onClick={handleThreadDelete}
137
+ />
172
138
  )}
173
- {onThreadDelete && <DeleteThreadButton onDelete={handleThreadDelete} />}
174
139
  </div>
175
140
  </div>
141
+
176
142
  {/** TODO(dmaretskyi): How's `thread.messages` undefined? */}
177
- {RefArray.targets(thread.messages?.filter(isNonNullable) ?? []).map((message) => (
143
+ {Ref.Array.targets(thread.messages?.filter(isNonNullable) ?? []).map((message) => (
178
144
  <MessageContainer
179
145
  key={message.id}
180
146
  editable
@@ -183,6 +149,7 @@ export const CommentContainer = ({
183
149
  onDelete={handleMessageDelete}
184
150
  />
185
151
  ))}
152
+
186
153
  {/*
187
154
  TODO(wittjosiah): Can't autofocus this generally.
188
155
  There can be multiple threads with inputs and they can't all be focused.
@@ -190,9 +157,11 @@ export const CommentContainer = ({
190
157
  Need to find a way to autofocus in one scenario only: when a new thread is created.
191
158
  */}
192
159
  <MessageTextbox extensions={extensions} onSend={handleComment} {...textboxMetadata} />
193
- <ThreadFooter activity={activity}>{t('activity message')}</ThreadFooter>
160
+
161
+ <Thread.Status activity={activity}>{t('activity message')}</Thread.Status>
162
+
194
163
  {/* NOTE(thure): This can’t also be the `overflow-anchor` because `ScrollArea` injects an interceding node that contains this necessary ref’d element. */}
195
164
  <div role='none' className='bs-px -mbs-px' ref={threadScrollRef} />
196
- </Thread>
165
+ </Thread.Root>
197
166
  );
198
167
  };
@@ -4,7 +4,7 @@
4
4
 
5
5
  import '@dxos-theme';
6
6
 
7
- import { type StoryObj, type Meta } from '@storybook/react';
7
+ import { type StoryObj, type Meta } from '@storybook/react-vite';
8
8
  import React, { useEffect, useState } from 'react';
9
9
 
10
10
  import { scheduleTask } from '@dxos/async';
@@ -3,35 +3,25 @@
3
3
  //
4
4
 
5
5
  import { EditorView } from '@codemirror/view';
6
- import { Check, PencilSimple, X } from '@phosphor-icons/react';
7
6
  import React, { forwardRef, useCallback, useEffect, useRef, useState } from 'react';
8
7
 
9
8
  import { Surface } from '@dxos/app-framework';
10
- import { type Obj, type Type } from '@dxos/echo';
11
- import { RefArray } from '@dxos/live-object';
9
+ import { type Obj, Ref, type Type } from '@dxos/echo';
12
10
  import { PublicKey } from '@dxos/react-client';
13
11
  import { type SpaceMember } from '@dxos/react-client/echo';
14
12
  import { useIdentity, type Identity } from '@dxos/react-client/halo';
15
- import { Button, ButtonGroup, Tooltip, useOnTransition, useThemeContext, useTranslation } from '@dxos/react-ui';
13
+ import { IconButton, useOnTransition, useThemeContext, useTranslation } from '@dxos/react-ui';
16
14
  import { createBasicExtensions, createThemeExtensions, useTextEditor } from '@dxos/react-ui-editor';
17
- import {
18
- getSize,
19
- hoverableControlItem,
20
- hoverableControls,
21
- hoverableFocusedWithinControls,
22
- mx,
23
- } from '@dxos/react-ui-theme';
15
+ import { hoverableControlItem, hoverableControls, hoverableFocusedWithinControls, mx } from '@dxos/react-ui-theme';
24
16
  import { MessageHeading, MessageRoot } from '@dxos/react-ui-thread';
25
17
  import { type DataType } from '@dxos/schema';
26
18
 
19
+ import { commentControlClassNames } from './CommentsThreadContainer';
27
20
  import { command } from './command-extension';
28
21
  import { useOnEditAnalytics } from '../hooks';
29
- import { THREAD_PLUGIN } from '../meta';
22
+ import { meta } from '../meta';
30
23
  import { getMessageMetadata } from '../util';
31
24
 
32
- // TODO(thure): #8149
33
- const messageControlClassNames = ['!p-1 !min-bs-0 transition-opacity', hoverableControlItem];
34
-
35
25
  export type MessageContainerProps = {
36
26
  message: DataType.Message;
37
27
  members: SpaceMember[];
@@ -40,6 +30,7 @@ export type MessageContainerProps = {
40
30
  };
41
31
 
42
32
  export const MessageContainer = ({ message, members, editable = false, onDelete }: MessageContainerProps) => {
33
+ const { t } = useTranslation(meta.id);
43
34
  const senderIdentity = members.find(
44
35
  (member) =>
45
36
  (message.sender.identityDid && member.identity.did === message.sender.identityDid) ||
@@ -49,9 +40,6 @@ export const MessageContainer = ({ message, members, editable = false, onDelete
49
40
  const userIsAuthor = useIdentity()?.did === messageMetadata.authorId;
50
41
  const [editing, setEditing] = useState(false);
51
42
  const handleDelete = useCallback(() => onDelete?.(message.id), [message, onDelete]);
52
- const { t } = useTranslation(THREAD_PLUGIN);
53
- const editLabel = t(editing ? 'save message label' : 'edit message label');
54
- const deleteLabel = t('delete message label');
55
43
  const textBlock = message.blocks.find((block) => block.type === 'text');
56
44
  const references = message.blocks.filter((block) => block.type === 'reference').map((block) => block.reference);
57
45
 
@@ -60,37 +48,33 @@ export const MessageContainer = ({ message, members, editable = false, onDelete
60
48
  return (
61
49
  <MessageRoot {...messageMetadata} classNames={[hoverableControls, hoverableFocusedWithinControls]}>
62
50
  <MessageHeading authorName={messageMetadata.authorName} timestamp={messageMetadata.timestamp}>
63
- <ButtonGroup classNames='mie-1'>
51
+ <div className='flex flex-row items-center gap-0.5'>
64
52
  {userIsAuthor && editable && (
65
- <Tooltip.Trigger asChild content={editLabel}>
66
- <Button
67
- variant='ghost'
68
- data-testid={editing ? 'thread.message.save' : 'thread.message.edit'}
69
- classNames={messageControlClassNames}
70
- onClick={() => setEditing((editing) => !editing)}
71
- >
72
- <span className='sr-only'>{editLabel}</span>
73
- {editing ? <Check className={getSize(4)} /> : <PencilSimple className={getSize(4)} />}
74
- </Button>
75
- </Tooltip.Trigger>
53
+ <IconButton
54
+ data-testid={editing ? 'thread.message.save' : 'thread.message.edit'}
55
+ variant='ghost'
56
+ icon={editing ? 'ph--check--regular' : 'ph--pencil-simple--regular'}
57
+ iconOnly
58
+ label={t(editing ? 'save message label' : 'edit message label')}
59
+ classNames={[commentControlClassNames, hoverableControlItem]}
60
+ onClick={() => setEditing((editing) => !editing)}
61
+ />
76
62
  )}
77
63
  {onDelete && (
78
- <Tooltip.Trigger asChild content={deleteLabel}>
79
- <Button
80
- variant='ghost'
81
- data-testid='thread.message.delete'
82
- classNames={messageControlClassNames}
83
- onClick={() => handleDelete()}
84
- >
85
- <span className='sr-only'>{deleteLabel}</span>
86
- <X className={getSize(4)} />
87
- </Button>
88
- </Tooltip.Trigger>
64
+ <IconButton
65
+ data-testid='thread.message.delete'
66
+ variant='ghost'
67
+ icon='ph--x--regular'
68
+ iconOnly
69
+ label={t('delete message label')}
70
+ classNames={[commentControlClassNames, hoverableControlItem]}
71
+ onClick={() => handleDelete()}
72
+ />
89
73
  )}
90
- </ButtonGroup>
74
+ </div>
91
75
  </MessageHeading>
92
76
  {textBlock && <TextboxBlock block={textBlock} isAuthor={userIsAuthor} editing={editing} />}
93
- {RefArray.targets(references).map((reference, index) => (
77
+ {Ref.Array.targets(references).map((reference, index) => (
94
78
  <MessagePart key={index} part={reference} />
95
79
  ))}
96
80
  </MessageRoot>
@@ -4,13 +4,13 @@
4
4
 
5
5
  import '@dxos-theme';
6
6
 
7
- import { type StoryObj, type Meta } from '@storybook/react';
7
+ import { type StoryObj, type Meta } from '@storybook/react-vite';
8
8
  import React from 'react';
9
9
 
10
10
  import { withTheme, withLayout } from '@dxos/storybook-utils';
11
11
 
12
12
  import { ResponsiveContainer } from './ResponsiveContainer';
13
- import translations from '../../translations';
13
+ import { translations } from '../../translations';
14
14
  import { VideoObject as VideoObjectComponent } from '../Media';
15
15
 
16
16
  const meta: Meta<typeof ResponsiveContainer> = {
@@ -4,7 +4,7 @@
4
4
 
5
5
  import '@dxos-theme';
6
6
 
7
- import { type StoryObj, type Meta } from '@storybook/react';
7
+ import { type StoryObj, type Meta } from '@storybook/react-vite';
8
8
  import React, { useEffect, useState } from 'react';
9
9
 
10
10
  import { faker } from '@dxos/random';
@@ -12,7 +12,7 @@ import { withTheme, withLayout } from '@dxos/storybook-utils';
12
12
 
13
13
  import { ResponsiveGrid, type ResponsiveGridProps } from './ResponsiveGrid';
14
14
  import { ResponsiveGridItem, type ResponsiveGridItemProps } from './ResponsiveGridItem';
15
- import translations from '../../translations';
15
+ import { translations } from '../../translations';
16
16
 
17
17
  type TestItem = {
18
18
  id: string;
@@ -8,7 +8,7 @@ import { Icon, IconButton, useTranslation, type ThemedClassName } from '@dxos/re
8
8
  import { Waveform } from '@dxos/react-ui-sfx';
9
9
  import { groupHoverControlItemWithTransition, mx } from '@dxos/react-ui-theme';
10
10
 
11
- import { THREAD_PLUGIN } from '../../meta';
11
+ import { meta } from '../../meta';
12
12
 
13
13
  export type ResponsiveGridItemProps<T extends object = any> = PropsWithChildren<
14
14
  ThemedClassName<{
@@ -45,7 +45,7 @@ export const ResponsiveGridItem = <T extends object = any>({
45
45
  speaking,
46
46
  onClick,
47
47
  }: ResponsiveGridItemProps<T>) => {
48
- const { t } = useTranslation(THREAD_PLUGIN);
48
+ const { t } = useTranslation(meta.id);
49
49
  const iconProps: Record<string, { icon: string; label: string; classNames?: string }> = {
50
50
  wave: {
51
51
  icon: 'ph--hand-waving--duotone',
@@ -23,13 +23,13 @@ import { AnchoredTo } from '@dxos/schema';
23
23
 
24
24
  import { ThreadCapabilities } from '../capabilities';
25
25
  import { CommentsContainer } from '../components';
26
- import { THREAD_PLUGIN } from '../meta';
26
+ import { meta } from '../meta';
27
27
  import { ThreadAction, ThreadType } from '../types';
28
28
 
29
29
  export const ThreadComplementary = ({ subject }: { subject: any }) => {
30
+ const { t } = useTranslation(meta.id);
30
31
  const { dispatchPromise: dispatch } = useIntentDispatcher();
31
32
  const identity = useIdentity();
32
- const { t } = useTranslation(THREAD_PLUGIN);
33
33
  const { tx } = useThemeContext();
34
34
  const subjectId = fullyQualifiedId(subject);
35
35
 
@@ -7,11 +7,11 @@ import React from 'react';
7
7
  // import { useTranslation } from '@dxos/react-ui';
8
8
  import { DeprecatedFormContainer } from '@dxos/react-ui-form';
9
9
 
10
- // import { THREAD_PLUGIN } from '../meta';
10
+ // import { meta } from '../meta';
11
11
  import type { ThreadSettingsProps } from '../types';
12
12
 
13
13
  export const ThreadSettings = ({ settings }: { settings: ThreadSettingsProps }) => {
14
- // const { t } = useTranslation(THREAD_PLUGIN);
14
+ // const { t } = useTranslation(meta.id);
15
15
 
16
16
  return <DeprecatedFormContainer></DeprecatedFormContainer>;
17
17
  };
@@ -11,8 +11,8 @@ export const ChatContainer = lazy(() => import('./ChatContainer'));
11
11
  export * from './Call';
12
12
  export * from './CallDebugPanel';
13
13
  export * from './CallSidebar';
14
- export * from './CommentContainer';
15
14
  export * from './CommentsContainer';
15
+ export * from './CommentsThreadContainer';
16
16
  export * from './MessageContainer';
17
17
  export * from './ThreadComplementary';
18
18
  export * from './ThreadSettings';
@@ -5,3 +5,5 @@
5
5
  export * from './analytics';
6
6
  export * from './useDebugMode';
7
7
  export * from './useStatus';
8
+ export * from './useVideoStreamTrack';
9
+ export * from './useInaudibleAudioStreamTrack';
@@ -0,0 +1,27 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { useEffect, useState } from 'react';
6
+
7
+ import { scheduleTask } from '@dxos/async';
8
+ import { Context } from '@dxos/context';
9
+
10
+ import { createInaudibleAudioStreamTrack } from '../calls/util/stub-media-streams';
11
+
12
+ export const useInaudibleAudioStreamTrack = () => {
13
+ const [audioStreamTrack, setAudioStreamTrack] = useState<MediaStreamTrack | undefined>(undefined);
14
+ useEffect(() => {
15
+ const ctx = new Context();
16
+ scheduleTask(ctx, async () => {
17
+ const audioStreamTrack = await createInaudibleAudioStreamTrack({ ctx });
18
+ setAudioStreamTrack(audioStreamTrack);
19
+ });
20
+
21
+ return () => {
22
+ void ctx.dispose();
23
+ };
24
+ }, []);
25
+
26
+ return audioStreamTrack;
27
+ };