@dxos/plugin-thread 0.8.4-main.abd8ff62ef → 0.8.4-main.bc2380dfbc

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 (431) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +1 -1
  3. package/dist/lib/neutral/ChannelArticle-ACZD7YFT.mjs +28 -0
  4. package/dist/lib/neutral/ChannelArticle-ACZD7YFT.mjs.map +7 -0
  5. package/dist/lib/neutral/ChannelChat-6YTD5HWL.mjs +10 -0
  6. package/dist/lib/neutral/ThreadCompanion-NQWPS2H6.mjs +208 -0
  7. package/dist/lib/neutral/ThreadCompanion-NQWPS2H6.mjs.map +7 -0
  8. package/dist/lib/neutral/ThreadContainer-XYEPEOSD.mjs +61 -0
  9. package/dist/lib/neutral/ThreadContainer-XYEPEOSD.mjs.map +7 -0
  10. package/dist/lib/neutral/ThreadPlugin.mjs +80 -0
  11. package/dist/lib/neutral/ThreadPlugin.mjs.map +7 -0
  12. package/dist/lib/neutral/ThreadPlugin.node.mjs +40 -0
  13. package/dist/lib/neutral/ThreadPlugin.node.mjs.map +7 -0
  14. package/dist/lib/neutral/ThreadPlugin.workerd.mjs +24 -0
  15. package/dist/lib/neutral/ThreadPlugin.workerd.mjs.map +7 -0
  16. package/dist/lib/neutral/ThreadSettings-5MKTDK3A.mjs +15 -0
  17. package/dist/lib/neutral/ThreadSettings-5MKTDK3A.mjs.map +7 -0
  18. package/dist/lib/{browser/add-message-LRVGIHDH.mjs → neutral/add-message-FBIROBEZ.mjs} +8 -10
  19. package/dist/lib/neutral/add-message-FBIROBEZ.mjs.map +7 -0
  20. package/dist/lib/neutral/app-graph-builder-7Q6MA6RT.mjs +120 -0
  21. package/dist/lib/neutral/app-graph-builder-7Q6MA6RT.mjs.map +7 -0
  22. package/dist/lib/{browser/append-channel-message-CO3M6FSA.mjs → neutral/append-channel-message-FTFAD3PK.mjs} +5 -5
  23. package/dist/lib/neutral/append-channel-message-FTFAD3PK.mjs.map +7 -0
  24. package/dist/lib/neutral/blueprint-definition-S3EBOH4R.mjs +15 -0
  25. package/dist/lib/neutral/blueprint-definition-S3EBOH4R.mjs.map +7 -0
  26. package/dist/lib/neutral/blueprints/index.mjs +8 -0
  27. package/dist/lib/neutral/capabilities/index.mjs +25 -0
  28. package/dist/lib/neutral/capabilities/index.mjs.map +7 -0
  29. package/dist/lib/{browser/blueprints/index.mjs → neutral/chunk-5T5LPLBN.mjs} +4 -5
  30. package/dist/lib/neutral/chunk-5T5LPLBN.mjs.map +7 -0
  31. package/dist/lib/neutral/chunk-7GHUS3IX.mjs +20 -0
  32. package/dist/lib/neutral/chunk-7GHUS3IX.mjs.map +7 -0
  33. package/dist/lib/neutral/chunk-D5LGFCUY.mjs +55 -0
  34. package/dist/lib/neutral/chunk-D5LGFCUY.mjs.map +7 -0
  35. package/dist/lib/neutral/chunk-JLY4NVTA.mjs +38 -0
  36. package/dist/lib/neutral/chunk-JLY4NVTA.mjs.map +7 -0
  37. package/dist/lib/neutral/chunk-KRXHIW4P.mjs +164 -0
  38. package/dist/lib/neutral/chunk-KRXHIW4P.mjs.map +7 -0
  39. package/dist/lib/{browser/chunk-TPNZ43NB.mjs → neutral/chunk-PE7IH7EL.mjs} +86 -73
  40. package/dist/lib/neutral/chunk-PE7IH7EL.mjs.map +7 -0
  41. package/dist/lib/neutral/chunk-QFDT33VT.mjs +69 -0
  42. package/dist/lib/neutral/chunk-QFDT33VT.mjs.map +7 -0
  43. package/dist/lib/neutral/chunk-QMLVLKE3.mjs +8 -0
  44. package/dist/lib/neutral/chunk-QMLVLKE3.mjs.map +7 -0
  45. package/dist/lib/neutral/components/index.mjs +539 -0
  46. package/dist/lib/neutral/components/index.mjs.map +7 -0
  47. package/dist/lib/neutral/containers/index.mjs +15 -0
  48. package/dist/lib/neutral/containers/index.mjs.map +7 -0
  49. package/dist/lib/{browser/create-BTGLHLBA.mjs → neutral/create-OAQJ6LXN.mjs} +7 -10
  50. package/dist/lib/neutral/create-OAQJ6LXN.mjs.map +7 -0
  51. package/dist/lib/{browser/create-channel-ZXKSLHGN.mjs → neutral/create-channel-3E4FJ662.mjs} +4 -4
  52. package/dist/lib/neutral/create-channel-3E4FJ662.mjs.map +7 -0
  53. package/dist/lib/neutral/create-object-HIEWSBZB.mjs +27 -0
  54. package/dist/lib/neutral/create-object-HIEWSBZB.mjs.map +7 -0
  55. package/dist/lib/{browser/create-proposals-AV5CREPV.mjs → neutral/create-proposals-GRYZXRMV.mjs} +4 -4
  56. package/dist/lib/neutral/create-proposals-GRYZXRMV.mjs.map +7 -0
  57. package/dist/lib/{browser/delete-GLYEP7NE.mjs → neutral/delete-HCCG5RVR.mjs} +7 -9
  58. package/dist/lib/neutral/delete-HCCG5RVR.mjs.map +7 -0
  59. package/dist/lib/{browser/delete-message-RQ72ZY5D.mjs → neutral/delete-message-DHFRACB4.mjs} +6 -7
  60. package/dist/lib/neutral/delete-message-DHFRACB4.mjs.map +7 -0
  61. package/dist/lib/neutral/hooks/index.mjs +10 -0
  62. package/dist/lib/neutral/index.mjs +28 -0
  63. package/dist/lib/neutral/index.mjs.map +7 -0
  64. package/dist/lib/neutral/markdown-BUORNCPG.mjs +83 -0
  65. package/dist/lib/neutral/markdown-BUORNCPG.mjs.map +7 -0
  66. package/dist/lib/neutral/meta.json +1 -0
  67. package/dist/lib/neutral/meta.mjs +10 -0
  68. package/dist/lib/neutral/meta.mjs.map +7 -0
  69. package/dist/lib/{browser/on-create-space-SPE3QVFZ.mjs → neutral/on-create-space-OEBRKOAM.mjs} +5 -6
  70. package/dist/lib/neutral/on-create-space-OEBRKOAM.mjs.map +7 -0
  71. package/dist/lib/neutral/operation-handler-RU6K2S4L.mjs +13 -0
  72. package/dist/lib/neutral/operation-handler-RU6K2S4L.mjs.map +7 -0
  73. package/dist/lib/neutral/operations/index.mjs +8 -0
  74. package/dist/lib/neutral/operations/index.mjs.map +7 -0
  75. package/dist/lib/neutral/plugin.mjs +16 -0
  76. package/dist/lib/neutral/plugin.mjs.map +7 -0
  77. package/dist/lib/neutral/react-surface-XY23GVZH.mjs +76 -0
  78. package/dist/lib/neutral/react-surface-XY23GVZH.mjs.map +7 -0
  79. package/dist/lib/{browser/restore-VX7FLZOZ.mjs → neutral/restore-P4ZLXLF7.mjs} +5 -5
  80. package/dist/lib/neutral/restore-P4ZLXLF7.mjs.map +7 -0
  81. package/dist/lib/{browser/restore-message-D65NSWUA.mjs → neutral/restore-message-AUBOP2DF.mjs} +5 -5
  82. package/dist/lib/neutral/restore-message-AUBOP2DF.mjs.map +7 -0
  83. package/dist/lib/{browser/select-AT4L7EBU.mjs → neutral/select-LIVAMBCE.mjs} +6 -8
  84. package/dist/lib/neutral/select-LIVAMBCE.mjs.map +7 -0
  85. package/dist/lib/neutral/settings-HK4EB6TF.mjs +30 -0
  86. package/dist/lib/neutral/settings-HK4EB6TF.mjs.map +7 -0
  87. package/dist/lib/neutral/state-UU7VEAKV.mjs +22 -0
  88. package/dist/lib/neutral/state-UU7VEAKV.mjs.map +7 -0
  89. package/dist/lib/neutral/testing/index.mjs +58 -0
  90. package/dist/lib/neutral/testing/index.mjs.map +7 -0
  91. package/dist/lib/{browser/toggle-resolved-JD3D4WBZ.mjs → neutral/toggle-resolved-RQBDQZSV.mjs} +5 -5
  92. package/dist/lib/neutral/toggle-resolved-RQBDQZSV.mjs.map +7 -0
  93. package/dist/lib/{browser → neutral}/translations.mjs +2 -2
  94. package/dist/lib/neutral/translations.mjs.map +7 -0
  95. package/dist/lib/neutral/types/index.mjs +12 -0
  96. package/dist/lib/neutral/types/index.mjs.map +7 -0
  97. package/dist/lib/neutral/undo-mappings-HOKL2L3M.mjs +54 -0
  98. package/dist/lib/neutral/undo-mappings-HOKL2L3M.mjs.map +7 -0
  99. package/dist/types/src/ThreadPlugin.d.ts.map +1 -1
  100. package/dist/types/src/ThreadPlugin.node.d.ts.map +1 -1
  101. package/dist/types/src/ThreadPlugin.workerd.d.ts +4 -0
  102. package/dist/types/src/ThreadPlugin.workerd.d.ts.map +1 -0
  103. package/dist/types/src/capabilities/create-object.d.ts +11 -0
  104. package/dist/types/src/capabilities/create-object.d.ts.map +1 -0
  105. package/dist/types/src/capabilities/index.d.ts +7 -6
  106. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  107. package/dist/types/src/capabilities/markdown.d.ts +1 -1
  108. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  109. package/dist/types/src/capabilities/settings.d.ts.map +1 -1
  110. package/dist/types/src/components/Chat/Chat.d.ts +8 -1
  111. package/dist/types/src/components/Chat/Chat.d.ts.map +1 -1
  112. package/dist/types/src/components/CommentsPanel/CommentsThread.d.ts.map +1 -1
  113. package/dist/types/src/components/MessagePanel/MessagePanel.d.ts.map +1 -1
  114. package/dist/types/src/components/ThreadSettings/ThreadSettings.d.ts.map +1 -1
  115. package/dist/types/src/components/index.d.ts +0 -1
  116. package/dist/types/src/components/index.d.ts.map +1 -1
  117. package/dist/types/src/containers/ChannelArticle/ChannelArticle.d.ts +13 -0
  118. package/dist/types/src/containers/ChannelArticle/ChannelArticle.d.ts.map +1 -0
  119. package/dist/types/src/containers/{ChannelContainer/ChannelContainer.stories.d.ts → ChannelArticle/ChannelArticle.stories.d.ts} +4 -4
  120. package/dist/types/src/containers/ChannelArticle/ChannelArticle.stories.d.ts.map +1 -0
  121. package/dist/types/src/containers/ChannelArticle/index.d.ts +2 -0
  122. package/dist/types/src/containers/{CallDebugPanel → ChannelArticle}/index.d.ts.map +1 -1
  123. package/dist/types/src/containers/ChannelChat/ChannelChat.d.ts +4 -0
  124. package/dist/types/src/containers/ChannelChat/ChannelChat.d.ts.map +1 -1
  125. package/dist/types/src/containers/ThreadCompanion/ThreadCompanion.d.ts.map +1 -1
  126. package/dist/types/src/containers/index.d.ts +1 -3
  127. package/dist/types/src/containers/index.d.ts.map +1 -1
  128. package/dist/types/src/extensions/threads.d.ts +1 -1
  129. package/dist/types/src/extensions/threads.d.ts.map +1 -1
  130. package/dist/types/src/hooks/index.d.ts +0 -4
  131. package/dist/types/src/hooks/index.d.ts.map +1 -1
  132. package/dist/types/src/index.d.ts +3 -5
  133. package/dist/types/src/index.d.ts.map +1 -1
  134. package/dist/types/src/meta.d.ts.map +1 -1
  135. package/dist/types/src/operations/add-message.d.ts +2 -2
  136. package/dist/types/src/operations/add-message.d.ts.map +1 -1
  137. package/dist/types/src/operations/append-channel-message.d.ts +2 -2
  138. package/dist/types/src/operations/append-channel-message.d.ts.map +1 -1
  139. package/dist/types/src/operations/create-channel.d.ts +2 -2
  140. package/dist/types/src/operations/create-channel.d.ts.map +1 -1
  141. package/dist/types/src/operations/create-proposals.d.ts +2 -2
  142. package/dist/types/src/operations/create-proposals.d.ts.map +1 -1
  143. package/dist/types/src/operations/create.d.ts +2 -2
  144. package/dist/types/src/operations/create.d.ts.map +1 -1
  145. package/dist/types/src/operations/delete-message.d.ts +2 -2
  146. package/dist/types/src/operations/delete-message.d.ts.map +1 -1
  147. package/dist/types/src/operations/delete.d.ts +2 -2
  148. package/dist/types/src/operations/delete.d.ts.map +1 -1
  149. package/dist/types/src/operations/index.d.ts +0 -1
  150. package/dist/types/src/operations/index.d.ts.map +1 -1
  151. package/dist/types/src/operations/on-create-space.d.ts +2 -2
  152. package/dist/types/src/operations/on-create-space.d.ts.map +1 -1
  153. package/dist/types/src/operations/restore-message.d.ts +2 -2
  154. package/dist/types/src/operations/restore-message.d.ts.map +1 -1
  155. package/dist/types/src/operations/restore.d.ts +2 -2
  156. package/dist/types/src/operations/restore.d.ts.map +1 -1
  157. package/dist/types/src/operations/select.d.ts +2 -2
  158. package/dist/types/src/operations/select.d.ts.map +1 -1
  159. package/dist/types/src/operations/toggle-resolved.d.ts +2 -2
  160. package/dist/types/src/operations/toggle-resolved.d.ts.map +1 -1
  161. package/dist/types/src/plugin.d.ts +4 -0
  162. package/dist/types/src/plugin.d.ts.map +1 -0
  163. package/dist/types/src/translations.d.ts.map +1 -1
  164. package/dist/types/src/types/ThreadCapabilities.d.ts +13 -0
  165. package/dist/types/src/types/ThreadCapabilities.d.ts.map +1 -0
  166. package/dist/types/src/{operations/definitions.d.ts → types/ThreadOperation.d.ts} +1 -1
  167. package/dist/types/src/types/ThreadOperation.d.ts.map +1 -0
  168. package/dist/types/src/types/index.d.ts +3 -1
  169. package/dist/types/src/types/index.d.ts.map +1 -1
  170. package/dist/types/src/types/types.d.ts +1 -1
  171. package/dist/types/src/types/types.d.ts.map +1 -1
  172. package/dist/types/src/util.d.ts +4 -1
  173. package/dist/types/src/util.d.ts.map +1 -1
  174. package/dist/types/tsconfig.tsbuildinfo +1 -1
  175. package/package.json +123 -99
  176. package/src/ThreadPlugin.node.ts +5 -50
  177. package/src/ThreadPlugin.test.ts +3 -3
  178. package/src/ThreadPlugin.tsx +6 -59
  179. package/src/ThreadPlugin.workerd.ts +20 -0
  180. package/src/blueprints/thread-blueprint.ts +1 -1
  181. package/src/capabilities/app-graph-builder.ts +18 -69
  182. package/src/capabilities/create-object.ts +29 -0
  183. package/src/capabilities/index.ts +1 -2
  184. package/src/capabilities/markdown.ts +1 -1
  185. package/src/capabilities/react-surface.tsx +4 -26
  186. package/src/capabilities/settings.ts +1 -3
  187. package/src/capabilities/undo-mappings.ts +1 -1
  188. package/src/components/Chat/Chat.tsx +52 -12
  189. package/src/components/CommentsPanel/CommentsPanel.stories.tsx +1 -1
  190. package/src/components/CommentsPanel/CommentsPanel.tsx +4 -4
  191. package/src/components/CommentsPanel/CommentsThread.tsx +2 -3
  192. package/src/components/MessagePanel/MessagePanel.tsx +7 -8
  193. package/src/components/ThreadSettings/ThreadSettings.tsx +0 -1
  194. package/src/components/index.ts +0 -1
  195. package/src/containers/{ChannelContainer/ChannelContainer.stories.tsx → ChannelArticle/ChannelArticle.stories.tsx} +10 -10
  196. package/src/containers/ChannelArticle/ChannelArticle.tsx +42 -0
  197. package/src/containers/ChannelArticle/index.ts +5 -0
  198. package/src/containers/ChannelChat/ChannelChat.tsx +12 -2
  199. package/src/containers/ThreadCompanion/ThreadCompanion.tsx +10 -12
  200. package/src/containers/index.ts +1 -3
  201. package/src/extensions/command.ts +1 -1
  202. package/src/extensions/threads.ts +2 -2
  203. package/src/hooks/analytics.ts +1 -1
  204. package/src/hooks/index.ts +0 -5
  205. package/src/index.ts +3 -10
  206. package/src/meta.ts +1 -2
  207. package/src/operations/add-message.ts +4 -4
  208. package/src/operations/append-channel-message.ts +20 -19
  209. package/src/operations/create-channel.ts +2 -2
  210. package/src/operations/create-proposals.ts +2 -2
  211. package/src/operations/create.ts +3 -3
  212. package/src/operations/delete-message.ts +4 -4
  213. package/src/operations/delete.ts +3 -3
  214. package/src/operations/index.ts +0 -2
  215. package/src/operations/on-create-space.ts +3 -3
  216. package/src/operations/restore-message.ts +3 -3
  217. package/src/operations/restore.ts +3 -3
  218. package/src/operations/select.ts +2 -2
  219. package/src/operations/toggle-resolved.ts +3 -3
  220. package/src/plugin.ts +11 -0
  221. package/src/translations.ts +2 -2
  222. package/src/types/ThreadCapabilities.ts +26 -0
  223. package/src/{operations/definitions.ts → types/ThreadOperation.ts} +5 -4
  224. package/src/types/index.ts +4 -1
  225. package/src/types/types.ts +0 -2
  226. package/src/util.ts +36 -4
  227. package/dist/lib/browser/add-message-LRVGIHDH.mjs.map +0 -7
  228. package/dist/lib/browser/append-channel-message-CO3M6FSA.mjs.map +0 -7
  229. package/dist/lib/browser/blueprints/index.mjs.map +0 -7
  230. package/dist/lib/browser/chunk-E4GG3NX2.mjs +0 -29
  231. package/dist/lib/browser/chunk-E4GG3NX2.mjs.map +0 -7
  232. package/dist/lib/browser/chunk-TPNZ43NB.mjs.map +0 -7
  233. package/dist/lib/browser/create-BTGLHLBA.mjs.map +0 -7
  234. package/dist/lib/browser/create-channel-ZXKSLHGN.mjs.map +0 -7
  235. package/dist/lib/browser/create-proposals-AV5CREPV.mjs.map +0 -7
  236. package/dist/lib/browser/delete-GLYEP7NE.mjs.map +0 -7
  237. package/dist/lib/browser/delete-message-RQ72ZY5D.mjs.map +0 -7
  238. package/dist/lib/browser/index.mjs +0 -1821
  239. package/dist/lib/browser/index.mjs.map +0 -7
  240. package/dist/lib/browser/meta.json +0 -1
  241. package/dist/lib/browser/on-create-space-SPE3QVFZ.mjs.map +0 -7
  242. package/dist/lib/browser/operations/index.mjs +0 -13
  243. package/dist/lib/browser/operations/index.mjs.map +0 -7
  244. package/dist/lib/browser/restore-VX7FLZOZ.mjs.map +0 -7
  245. package/dist/lib/browser/restore-message-D65NSWUA.mjs.map +0 -7
  246. package/dist/lib/browser/select-AT4L7EBU.mjs.map +0 -7
  247. package/dist/lib/browser/toggle-resolved-JD3D4WBZ.mjs.map +0 -7
  248. package/dist/lib/browser/translations.mjs.map +0 -7
  249. package/dist/lib/browser/types/index.mjs +0 -10
  250. package/dist/lib/node-esm/add-message-4EAQ2ZPI.mjs +0 -90
  251. package/dist/lib/node-esm/add-message-4EAQ2ZPI.mjs.map +0 -7
  252. package/dist/lib/node-esm/append-channel-message-F7KGBSWP.mjs +0 -41
  253. package/dist/lib/node-esm/append-channel-message-F7KGBSWP.mjs.map +0 -7
  254. package/dist/lib/node-esm/blueprints/index.mjs +0 -38
  255. package/dist/lib/node-esm/blueprints/index.mjs.map +0 -7
  256. package/dist/lib/node-esm/chunk-BVEZBGIY.mjs +0 -30
  257. package/dist/lib/node-esm/chunk-BVEZBGIY.mjs.map +0 -7
  258. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +0 -11
  259. package/dist/lib/node-esm/chunk-XKUMDYGR.mjs +0 -259
  260. package/dist/lib/node-esm/chunk-XKUMDYGR.mjs.map +0 -7
  261. package/dist/lib/node-esm/create-DEZFPN2Y.mjs +0 -56
  262. package/dist/lib/node-esm/create-DEZFPN2Y.mjs.map +0 -7
  263. package/dist/lib/node-esm/create-channel-6VHTC2OR.mjs +0 -20
  264. package/dist/lib/node-esm/create-channel-6VHTC2OR.mjs.map +0 -7
  265. package/dist/lib/node-esm/create-proposals-P5O2ICOL.mjs +0 -57
  266. package/dist/lib/node-esm/create-proposals-P5O2ICOL.mjs.map +0 -7
  267. package/dist/lib/node-esm/delete-QG45QLPY.mjs +0 -60
  268. package/dist/lib/node-esm/delete-QG45QLPY.mjs.map +0 -7
  269. package/dist/lib/node-esm/delete-message-PGNLB6TL.mjs +0 -56
  270. package/dist/lib/node-esm/delete-message-PGNLB6TL.mjs.map +0 -7
  271. package/dist/lib/node-esm/index.mjs +0 -1822
  272. package/dist/lib/node-esm/index.mjs.map +0 -7
  273. package/dist/lib/node-esm/meta.json +0 -1
  274. package/dist/lib/node-esm/on-create-space-TFBSHWQ4.mjs +0 -25
  275. package/dist/lib/node-esm/on-create-space-TFBSHWQ4.mjs.map +0 -7
  276. package/dist/lib/node-esm/operations/index.mjs +0 -14
  277. package/dist/lib/node-esm/operations/index.mjs.map +0 -7
  278. package/dist/lib/node-esm/restore-E27OAIFJ.mjs +0 -33
  279. package/dist/lib/node-esm/restore-E27OAIFJ.mjs.map +0 -7
  280. package/dist/lib/node-esm/restore-message-J3CH6NGI.mjs +0 -34
  281. package/dist/lib/node-esm/restore-message-J3CH6NGI.mjs.map +0 -7
  282. package/dist/lib/node-esm/select-UU6Q2XAB.mjs +0 -27
  283. package/dist/lib/node-esm/select-UU6Q2XAB.mjs.map +0 -7
  284. package/dist/lib/node-esm/toggle-resolved-VS6NKXL3.mjs +0 -37
  285. package/dist/lib/node-esm/toggle-resolved-VS6NKXL3.mjs.map +0 -7
  286. package/dist/lib/node-esm/translations.mjs +0 -91
  287. package/dist/lib/node-esm/translations.mjs.map +0 -7
  288. package/dist/lib/node-esm/types/index.mjs +0 -11
  289. package/dist/types/src/calls/call-manager.d.ts +0 -87
  290. package/dist/types/src/calls/call-manager.d.ts.map +0 -1
  291. package/dist/types/src/calls/call-swarm-synchronizer.d.ts +0 -66
  292. package/dist/types/src/calls/call-swarm-synchronizer.d.ts.map +0 -1
  293. package/dist/types/src/calls/index.d.ts +0 -7
  294. package/dist/types/src/calls/index.d.ts.map +0 -1
  295. package/dist/types/src/calls/media-manager.d.ts +0 -60
  296. package/dist/types/src/calls/media-manager.d.ts.map +0 -1
  297. package/dist/types/src/calls/speaking-monitor.d.ts +0 -21
  298. package/dist/types/src/calls/speaking-monitor.d.ts.map +0 -1
  299. package/dist/types/src/calls/types.d.ts +0 -45
  300. package/dist/types/src/calls/types.d.ts.map +0 -1
  301. package/dist/types/src/calls/util/audio.d.ts +0 -6
  302. package/dist/types/src/calls/util/audio.d.ts.map +0 -1
  303. package/dist/types/src/calls/util/calls-service.d.ts +0 -77
  304. package/dist/types/src/calls/util/calls-service.d.ts.map +0 -1
  305. package/dist/types/src/calls/util/history-cache.d.ts +0 -11
  306. package/dist/types/src/calls/util/history-cache.d.ts.map +0 -1
  307. package/dist/types/src/calls/util/index.d.ts +0 -5
  308. package/dist/types/src/calls/util/index.d.ts.map +0 -1
  309. package/dist/types/src/calls/util/media.d.ts +0 -6
  310. package/dist/types/src/calls/util/media.d.ts.map +0 -1
  311. package/dist/types/src/calls/util/stub-media-streams.d.ts +0 -18
  312. package/dist/types/src/calls/util/stub-media-streams.d.ts.map +0 -1
  313. package/dist/types/src/calls/util/task-scheduling.d.ts +0 -17
  314. package/dist/types/src/calls/util/task-scheduling.d.ts.map +0 -1
  315. package/dist/types/src/calls-service.stories.d.ts +0 -23
  316. package/dist/types/src/calls-service.stories.d.ts.map +0 -1
  317. package/dist/types/src/capabilities/call-manager.d.ts +0 -6
  318. package/dist/types/src/capabilities/call-manager.d.ts.map +0 -1
  319. package/dist/types/src/capabilities/react-root.d.ts +0 -9
  320. package/dist/types/src/capabilities/react-root.d.ts.map +0 -1
  321. package/dist/types/src/components/Call/Call.d.ts +0 -45
  322. package/dist/types/src/components/Call/Call.d.ts.map +0 -1
  323. package/dist/types/src/components/Call/Toolbar.d.ts +0 -16
  324. package/dist/types/src/components/Call/Toolbar.d.ts.map +0 -1
  325. package/dist/types/src/components/Call/index.d.ts +0 -3
  326. package/dist/types/src/components/Call/index.d.ts.map +0 -1
  327. package/dist/types/src/components/Lobby/Lobby.d.ts +0 -36
  328. package/dist/types/src/components/Lobby/Lobby.d.ts.map +0 -1
  329. package/dist/types/src/components/Lobby/index.d.ts +0 -2
  330. package/dist/types/src/components/Lobby/index.d.ts.map +0 -1
  331. package/dist/types/src/components/Media/AudioStream.d.ts +0 -6
  332. package/dist/types/src/components/Media/AudioStream.d.ts.map +0 -1
  333. package/dist/types/src/components/Media/VideoObject.d.ts +0 -15
  334. package/dist/types/src/components/Media/VideoObject.d.ts.map +0 -1
  335. package/dist/types/src/components/Media/VideoObject.stories.d.ts +0 -22
  336. package/dist/types/src/components/Media/VideoObject.stories.d.ts.map +0 -1
  337. package/dist/types/src/components/Media/index.d.ts +0 -3
  338. package/dist/types/src/components/Media/index.d.ts.map +0 -1
  339. package/dist/types/src/components/Participant/Participant.d.ts +0 -6
  340. package/dist/types/src/components/Participant/Participant.d.ts.map +0 -1
  341. package/dist/types/src/components/Participant/ParticipantGrid.d.ts +0 -11
  342. package/dist/types/src/components/Participant/ParticipantGrid.d.ts.map +0 -1
  343. package/dist/types/src/components/Participant/index.d.ts +0 -3
  344. package/dist/types/src/components/Participant/index.d.ts.map +0 -1
  345. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.d.ts +0 -32
  346. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.d.ts.map +0 -1
  347. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.stories.d.ts +0 -178
  348. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.stories.d.ts.map +0 -1
  349. package/dist/types/src/components/ResponsiveGrid/ResponsiveGridItem.d.ts +0 -21
  350. package/dist/types/src/components/ResponsiveGrid/ResponsiveGridItem.d.ts.map +0 -1
  351. package/dist/types/src/components/ResponsiveGrid/ResponsivePanel.d.ts +0 -12
  352. package/dist/types/src/components/ResponsiveGrid/ResponsivePanel.d.ts.map +0 -1
  353. package/dist/types/src/components/ResponsiveGrid/ResponsivePanel.stories.d.ts +0 -164
  354. package/dist/types/src/components/ResponsiveGrid/ResponsivePanel.stories.d.ts.map +0 -1
  355. package/dist/types/src/components/ResponsiveGrid/index.d.ts +0 -4
  356. package/dist/types/src/components/ResponsiveGrid/index.d.ts.map +0 -1
  357. package/dist/types/src/containers/CallDebugPanel/CallDebugPanel.d.ts +0 -15
  358. package/dist/types/src/containers/CallDebugPanel/CallDebugPanel.d.ts.map +0 -1
  359. package/dist/types/src/containers/CallDebugPanel/index.d.ts +0 -2
  360. package/dist/types/src/containers/CallSidebar/CallSidebar.d.ts +0 -3
  361. package/dist/types/src/containers/CallSidebar/CallSidebar.d.ts.map +0 -1
  362. package/dist/types/src/containers/CallSidebar/index.d.ts +0 -2
  363. package/dist/types/src/containers/CallSidebar/index.d.ts.map +0 -1
  364. package/dist/types/src/containers/ChannelContainer/ChannelContainer.d.ts +0 -12
  365. package/dist/types/src/containers/ChannelContainer/ChannelContainer.d.ts.map +0 -1
  366. package/dist/types/src/containers/ChannelContainer/ChannelContainer.stories.d.ts.map +0 -1
  367. package/dist/types/src/containers/ChannelContainer/index.d.ts +0 -2
  368. package/dist/types/src/containers/ChannelContainer/index.d.ts.map +0 -1
  369. package/dist/types/src/hooks/useBlackCanvasStreamTrack.d.ts +0 -2
  370. package/dist/types/src/hooks/useBlackCanvasStreamTrack.d.ts.map +0 -1
  371. package/dist/types/src/hooks/useDebugMode.d.ts +0 -2
  372. package/dist/types/src/hooks/useDebugMode.d.ts.map +0 -1
  373. package/dist/types/src/hooks/useInaudibleAudioStreamTrack.d.ts +0 -2
  374. package/dist/types/src/hooks/useInaudibleAudioStreamTrack.d.ts.map +0 -1
  375. package/dist/types/src/hooks/useVideoStreamTrack.d.ts +0 -3
  376. package/dist/types/src/hooks/useVideoStreamTrack.d.ts.map +0 -1
  377. package/dist/types/src/operations/definitions.d.ts.map +0 -1
  378. package/dist/types/src/types/capabilities.d.ts +0 -25
  379. package/dist/types/src/types/capabilities.d.ts.map +0 -1
  380. package/src/calls/call-manager.ts +0 -270
  381. package/src/calls/call-swarm-synchronizer.ts +0 -350
  382. package/src/calls/index.ts +0 -10
  383. package/src/calls/media-manager.ts +0 -378
  384. package/src/calls/speaking-monitor.ts +0 -85
  385. package/src/calls/types.ts +0 -74
  386. package/src/calls/util/audio.ts +0 -58
  387. package/src/calls/util/calls-service.ts +0 -582
  388. package/src/calls/util/history-cache.ts +0 -27
  389. package/src/calls/util/index.ts +0 -8
  390. package/src/calls/util/media.ts +0 -52
  391. package/src/calls/util/stub-media-streams.ts +0 -129
  392. package/src/calls/util/task-scheduling.ts +0 -92
  393. package/src/calls-service.stories.tsx +0 -230
  394. package/src/capabilities/call-manager.ts +0 -27
  395. package/src/capabilities/react-root.tsx +0 -20
  396. package/src/components/Call/Call.tsx +0 -93
  397. package/src/components/Call/Toolbar.tsx +0 -199
  398. package/src/components/Call/index.ts +0 -6
  399. package/src/components/Lobby/Lobby.tsx +0 -123
  400. package/src/components/Lobby/index.ts +0 -5
  401. package/src/components/Media/AudioStream.tsx +0 -67
  402. package/src/components/Media/VideoObject.stories.tsx +0 -59
  403. package/src/components/Media/VideoObject.tsx +0 -58
  404. package/src/components/Media/index.ts +0 -6
  405. package/src/components/Participant/Participant.tsx +0 -77
  406. package/src/components/Participant/ParticipantGrid.tsx +0 -88
  407. package/src/components/Participant/index.ts +0 -6
  408. package/src/components/ResponsiveGrid/ResponsiveGrid.stories.tsx +0 -158
  409. package/src/components/ResponsiveGrid/ResponsiveGrid.tsx +0 -341
  410. package/src/components/ResponsiveGrid/ResponsiveGridItem.tsx +0 -134
  411. package/src/components/ResponsiveGrid/ResponsivePanel.stories.tsx +0 -54
  412. package/src/components/ResponsiveGrid/ResponsivePanel.tsx +0 -31
  413. package/src/components/ResponsiveGrid/index.ts +0 -7
  414. package/src/containers/CallDebugPanel/CallDebugPanel.tsx +0 -173
  415. package/src/containers/CallDebugPanel/index.ts +0 -5
  416. package/src/containers/CallSidebar/CallSidebar.tsx +0 -18
  417. package/src/containers/CallSidebar/index.ts +0 -5
  418. package/src/containers/ChannelContainer/ChannelContainer.tsx +0 -223
  419. package/src/containers/ChannelContainer/index.ts +0 -5
  420. package/src/hooks/useBlackCanvasStreamTrack.tsx +0 -27
  421. package/src/hooks/useDebugMode.ts +0 -25
  422. package/src/hooks/useInaudibleAudioStreamTrack.tsx +0 -27
  423. package/src/hooks/useVideoStreamTrack.tsx +0 -36
  424. package/src/types/capabilities.ts +0 -37
  425. package/src/typings/peermetrics-webrtc-stats.d.ts +0 -46
  426. package/src/typings.d.ts +0 -8
  427. /package/dist/lib/{browser/chunk-J5LGTIGS.mjs.map → neutral/ChannelChat-6YTD5HWL.mjs.map} +0 -0
  428. /package/dist/lib/{browser/types → neutral/blueprints}/index.mjs.map +0 -0
  429. /package/dist/lib/{browser → neutral}/chunk-J5LGTIGS.mjs +0 -0
  430. /package/dist/lib/{node-esm/chunk-HSLMI22Q.mjs.map → neutral/chunk-J5LGTIGS.mjs.map} +0 -0
  431. /package/dist/lib/{node-esm/types → neutral/hooks}/index.mjs.map +0 -0
@@ -1,158 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import { type Meta, type StoryObj } from '@storybook/react-vite';
6
- import React, { useEffect, useState } from 'react';
7
-
8
- import { random } from '@dxos/random';
9
- import { withLayout, withTheme } from '@dxos/react-ui/testing';
10
-
11
- import { translations } from '#translations';
12
-
13
- import { ResponsiveGrid, type ResponsiveGridProps } from './ResponsiveGrid';
14
- import { ResponsiveGridItem, type ResponsiveGridItemProps } from './ResponsiveGridItem';
15
-
16
- type TestItem = {
17
- id: string;
18
- name: string;
19
- type?: 'image' | 'video';
20
- imageUrl?: string;
21
- videoUrl?: string;
22
- };
23
-
24
- const TestCell = ({ item, ...props }: ResponsiveGridItemProps<TestItem>) => {
25
- const [speaking, setSpeaking] = useState(false);
26
- const [wave, setWave] = useState(false);
27
- const [mute, setMute] = useState(false);
28
- useEffect(() => {
29
- const interval = setInterval(() => {
30
- const mute = Math.random() > 0.7;
31
- setMute(() => mute);
32
- setSpeaking(() => !mute && Math.random() > 0.5);
33
- setWave(() => Math.random() > 0.7);
34
- }, 3_000);
35
-
36
- return () => clearInterval(interval);
37
- }, []);
38
-
39
- return (
40
- <ResponsiveGridItem {...props} item={item} name={item.name} mute={mute} speaking={speaking} wave={wave}>
41
- {item.type === 'image' && <img className='aspect-video object-contain' src={item.imageUrl} />}
42
- {item.type === 'video' && (
43
- <video
44
- className='w-full aspect-video object-cover rounded-md'
45
- src={item.videoUrl}
46
- playsInline
47
- autoPlay
48
- loop
49
- muted
50
- />
51
- )}
52
- </ResponsiveGridItem>
53
- );
54
- };
55
-
56
- type DefaultStoryProps = ResponsiveGridProps<TestItem> & { random?: boolean; autoHideGallery?: boolean };
57
-
58
- const DefaultStory = (props: DefaultStoryProps) => {
59
- const [pinned, setPinned] = useState<string | undefined>(
60
- (props.pinned ?? props.items.length > 1) ? props.items[0]?.id : undefined,
61
- );
62
- const [items, setItems] = useState<TestItem[]>(props.items);
63
- useEffect(() => {
64
- if (!props.random) {
65
- return;
66
- }
67
-
68
- const interval = setInterval(() => {
69
- setItems((items) => {
70
- const p = Math.random();
71
- if (p < 0.5) {
72
- return items;
73
- } else if (p < 0.99 && items.length > 1) {
74
- return items.slice(0, -1);
75
- } else {
76
- return [...items, createItem(items[0]?.type)];
77
- }
78
- });
79
- }, 3_000);
80
-
81
- return () => clearInterval(interval);
82
- }, []);
83
-
84
- return (
85
- <div className='grid grow p-4'>
86
- <ResponsiveGrid {...props} Cell={TestCell} items={items} pinned={pinned} onPinnedChange={setPinned} />
87
- </div>
88
- );
89
- };
90
-
91
- const meta = {
92
- title: 'plugins/plugin-thread/components/ResponsiveGrid',
93
- component: ResponsiveGrid as any,
94
- render: DefaultStory,
95
- decorators: [withTheme(), withLayout({ layout: 'fullscreen' })],
96
- parameters: {
97
- layout: 'fullscreen',
98
- translations,
99
- },
100
- } satisfies Meta<typeof DefaultStory>;
101
-
102
- const videoUrls = [
103
- 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4',
104
- 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerEscapes.mp4',
105
- 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerJoyrides.mp4',
106
- 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerMeltdowns.mp4',
107
- ];
108
-
109
- const createItem = (type?: 'image' | 'video') => {
110
- const id = random.string.uuid();
111
- return {
112
- id,
113
- type,
114
- name: random.person.fullName(),
115
- imageUrl: `https://placehold.co/3200x1800/333/999?font=roboto&text=${id.slice(0, 2)}`,
116
- videoUrl: random.helpers.arrayElement(videoUrls),
117
- };
118
- };
119
-
120
- export default meta;
121
-
122
- type Story = StoryObj<typeof meta>;
123
-
124
- // TODO(burdon): Story to join/leave repeatedly to test stable position.
125
-
126
- export const Default: Story = {
127
- args: {
128
- random: true,
129
- items: Array.from({ length: 8 }, (_, i) => createItem('video')),
130
- },
131
- };
132
-
133
- export const Fullscreen: Story = {
134
- args: {
135
- random: true,
136
- autoHideGallery: true,
137
- items: Array.from({ length: 8 }, (_, i) => createItem('video')),
138
- },
139
- };
140
-
141
- export const Images: Story = {
142
- args: {
143
- debug: true,
144
- items: Array.from({ length: 8 }, (_, i) => createItem('image')),
145
- },
146
- };
147
-
148
- export const Solo: Story = {
149
- args: {
150
- items: Array.from({ length: 1 }, (_, i) => createItem('image')),
151
- },
152
- };
153
-
154
- export const TwoUp: Story = {
155
- args: {
156
- items: Array.from({ length: 2 }, (_, i) => createItem('image')),
157
- },
158
- };
@@ -1,341 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import React, { type ComponentType, type FC, useCallback, useEffect, useLayoutEffect, useMemo, useState } from 'react';
6
- import { useResizeDetector } from 'react-resize-detector';
7
-
8
- import { invariant } from '@dxos/invariant';
9
- import { type ThemedClassName } from '@dxos/react-ui';
10
- import { type Size } from '@dxos/react-ui-dnd';
11
- import { mx } from '@dxos/ui-theme';
12
-
13
- import { type ResponsiveGridItemProps } from './ResponsiveGridItem';
14
- import { ResponsivePanel } from './ResponsivePanel';
15
-
16
- const ASPECT_RATIO = 16 / 9;
17
- const MIN_GALLERY_HEIGHT = 250;
18
-
19
- const DEFAULT_GAP = 8;
20
-
21
- const maxImageSize = 'w-[2560px] h-[1440px]';
22
-
23
- /**
24
- * Props for the ResponsiveGrid component.
25
- */
26
- export type ResponsiveGridProps<T extends object = any> = ThemedClassName<{
27
- /** Cell component. */
28
- Cell: ComponentType<ResponsiveGridItemProps<T>>;
29
-
30
- /** Space between grid items in pixels. */
31
- gap?: number;
32
-
33
- /** Function to get the ID of an item. */
34
- getId?: (item: T) => string;
35
-
36
- /** Array of items to display in the grid. */
37
- items: T[];
38
-
39
- /** ID of the pinned item. */
40
- pinned?: string;
41
-
42
- /** Whether to hide the gallery (unpinned items) when an item is pinned. */
43
- autoHideGallery?: boolean;
44
-
45
- /** Whether the divider is resizable. */
46
- resizable?: boolean;
47
-
48
- /** Debug mode. */
49
- debug?: boolean;
50
-
51
- /** Callback when the pinned item changes. */
52
- onPinnedChange?: (pinned: string | undefined) => void;
53
- }>;
54
-
55
- const defaultGetId: ResponsiveGridProps<any>['getId'] = (item: any) => item.id;
56
-
57
- /**
58
- * A responsive grid component that automatically adjusts its layout to optimize space usage.
59
- * Maintains aspect ratio of items while ensuring uniform gaps between them.
60
- */
61
- export const ResponsiveGrid = <T extends object = any>({
62
- classNames,
63
- Cell,
64
- gap = DEFAULT_GAP,
65
- getId = defaultGetId,
66
- items,
67
- pinned,
68
- autoHideGallery = false,
69
- debug,
70
- onPinnedChange,
71
- }: ResponsiveGridProps<T>) => {
72
- const {
73
- width: containerWidth = 0,
74
- height: containerHeight = 0,
75
- ref: containerRef,
76
- } = useResizeDetector<HTMLDivElement>({ refreshRate: 100 });
77
- const [dividerHeight, setDividerHeight] = useState<Size>(0);
78
- useEffect(() => {
79
- if (containerWidth && containerHeight) {
80
- const { height } = fitAspectRatio(containerWidth, containerHeight, ASPECT_RATIO);
81
- setDividerHeight(Math.min(height, containerHeight - MIN_GALLERY_HEIGHT));
82
- }
83
- }, [containerWidth, containerHeight]);
84
-
85
- const pinnedItem = useMemo(() => items.find((item) => getId(item) === pinned), [items, pinned]);
86
- const mainItems = useMemo(() => items.filter((item) => getId(item) !== pinned), [items, pinned]);
87
- const hideGallery = autoHideGallery && pinnedItem !== undefined;
88
-
89
- //
90
- // Recalculate optimal layout when container size or items change.
91
- //
92
- const [{ time, columns, cellWidth }, setLayout] = useState<Layout>({ time: 0, columns: 0, cellWidth: 0 });
93
- const { width = 0, height = 0, ref: gridContainerRef } = useResizeDetector<HTMLDivElement>({ refreshRate: 200 });
94
- useEffect(() => {
95
- if (containerHeight && width && height) {
96
- const layout = calculateLayout(width, height, mainItems.length, gap);
97
- setLayout({ time: Date.now(), ...layout });
98
- }
99
- }, [containerHeight, width, height, mainItems.length, gap, pinned]);
100
-
101
- //
102
- // We use the browser to layout invisible divs and then calculate the absolute position of these items,
103
- // which are animated into position.
104
- //
105
- const [bounds, setBounds] = useState<[T, DOMRectBounds][]>([]);
106
- useLayoutEffect(() => {
107
- if ((!hideGallery && !gridContainerRef.current) || !containerHeight) {
108
- return;
109
- }
110
-
111
- // TODO(burdon): Consider directly setting bounds on DOM elementsinstead of state update?
112
- const t = setTimeout(() => {
113
- setBounds(
114
- items
115
- .filter((item) => !hideGallery || item === pinnedItem)
116
- .map((item) => {
117
- invariant(containerRef.current);
118
- const el = containerRef.current.querySelector(`[data-grid-item="${getId(item)}"]`);
119
- if (!el) {
120
- return null;
121
- }
122
-
123
- const bounds = getRelativeBounds(containerRef.current, el as HTMLElement);
124
- return [item, bounds];
125
- })
126
- .filter((item): item is [T, DOMRectBounds] => item !== null),
127
- );
128
- });
129
-
130
- return () => clearTimeout(t);
131
- }, [containerHeight, items, pinnedItem, hideGallery, time]);
132
-
133
- const handleClick = useCallback(
134
- (item: T) => onPinnedChange?.(getId(item) === pinned ? undefined : getId(item)),
135
- [pinned, onPinnedChange],
136
- );
137
-
138
- return (
139
- <div ref={containerRef} className={mx('dx-expander relative', classNames)}>
140
- {/* Placeholder elements to calculate layout. */}
141
- <div className='absolute inset-0 flex flex-col grow gap-2'>
142
- {/* Pinned item. */}
143
- {pinnedItem && (
144
- <div
145
- className={mx('flex grow-[2] shrink overflow-hidden justify-center items-center', hideGallery && 'h-full')}
146
- style={hideGallery ? {} : { height: dividerHeight }}
147
- >
148
- <SoloItem id={getId(pinnedItem)} debug={debug} />
149
- </div>
150
- )}
151
-
152
- {/* Gallery. */}
153
- {!hideGallery && (
154
- <div
155
- ref={gridContainerRef}
156
- className='flex grow-[1] overflow-hidden justify-center items-center'
157
- style={hideGallery ? {} : { minHeight: MIN_GALLERY_HEIGHT }}
158
- >
159
- {mainItems.length === 1 && (
160
- <div style={{ width: cellWidth }} className='flex h-full'>
161
- <SoloItem id={getId(mainItems[0])} debug={debug} />
162
- </div>
163
- )}
164
-
165
- {mainItems.length > 1 && columns > 0 && (
166
- <div
167
- role='grid'
168
- style={{
169
- display: 'grid',
170
- gridTemplateColumns: `repeat(${columns}, ${cellWidth}px)`,
171
- gap: `${gap}px`,
172
- }}
173
- >
174
- {mainItems.map((item) => (
175
- <div
176
- key={getId(item)}
177
- {...{ 'data-grid-item': getId(item) }}
178
- className={mx(
179
- 'aspect-video max-h-full max-w-full w-auto h-auto',
180
- debug && 'border border-primary-500',
181
- )}
182
- />
183
- ))}
184
- </div>
185
- )}
186
- </div>
187
- )}
188
- </div>
189
-
190
- {/* Absolutely positioned items. */}
191
- <div className={mx(debug && 'opacity-10')}>
192
- {bounds.map(([item, bounds]) => (
193
- <Cell
194
- key={getId(item)}
195
- classNames='absolute transition-all duration-500'
196
- item={item}
197
- style={bounds}
198
- pinned={getId(item) === pinned}
199
- onClick={items.length > 1 ? handleClick : undefined}
200
- />
201
- ))}
202
- </div>
203
- </div>
204
- );
205
- };
206
-
207
- const SoloItem: FC<Pick<ResponsiveGridProps, 'debug'> & { id: string }> = ({ debug, id }) => {
208
- return (
209
- <ResponsivePanel>
210
- <div
211
- {...{ 'data-grid-item': id }}
212
- className={mx('aspect-video overflow-hidden', debug && 'z-20 border-2 border-primary-500')}
213
- >
214
- {/* Maximum size placeholder image forces aspect ratio. */}
215
- <img alt='placeholder video' className={mx('opacity-0', maxImageSize)} />
216
- </div>
217
- </ResponsivePanel>
218
- );
219
- };
220
-
221
- type DOMRectBounds = Pick<DOMRect, 'top' | 'left' | 'width' | 'height'>;
222
-
223
- // TODO(burdon): Reconcile with react-ui-gameboard.
224
- const getRelativeBounds = (container: HTMLElement, el: HTMLElement): DOMRectBounds => {
225
- const containerRect = container.getBoundingClientRect();
226
- const elementRect = el.getBoundingClientRect();
227
- return {
228
- top: elementRect.top - containerRect.top,
229
- left: elementRect.left - containerRect.left,
230
- width: elementRect.width,
231
- height: elementRect.height,
232
- };
233
- };
234
-
235
- type Layout = {
236
- time?: number;
237
- columns: number;
238
- cellWidth: number;
239
- };
240
-
241
- /**
242
- * Calculates the optimal number of columns for a grid layout that minimizes wasted space.
243
- * @param containerWidth - Width of the container in pixels.
244
- * @param containerHeight - Height of the container in pixels.
245
- * @param count - Total number of items to display.
246
- * @param gap - Space between items in pixels.
247
- * @param aspectRatio - Desired aspect ratio of items (width/height).
248
- * @returns The optimal number of columns.
249
- */
250
- const calculateLayout = (
251
- containerWidth: number,
252
- containerHeight: number,
253
- count: number,
254
- gap: number,
255
- aspectRatio = ASPECT_RATIO,
256
- ): Layout => {
257
- if (count === 0) {
258
- return { columns: 1, cellWidth: 1 };
259
- }
260
-
261
- let minWastedSpace = Infinity;
262
- let bestColumns = 1;
263
- let cellWidth = 0;
264
-
265
- // Try different rows counts to find the optimal layout that minimizes wasted space.
266
- for (let rows = 1; rows <= count; rows++) {
267
- const cols = Math.ceil(count / rows);
268
-
269
- // Calculate available space accounting for gaps.
270
- const { width: itemWidth, height: itemHeight } = fitItemsToGrid(
271
- containerWidth,
272
- containerHeight,
273
- cols,
274
- rows,
275
- aspectRatio,
276
- gap,
277
- );
278
-
279
- // Calculate total wasted space for this configuration.
280
- const usedWidth = itemWidth * cols + gap * cols - 1;
281
- const usedHeight = itemHeight * rows + gap * rows - 1;
282
-
283
- // Determine if optimal.
284
- const wastedSpace = containerWidth * containerHeight - usedWidth * usedHeight;
285
- if (wastedSpace < minWastedSpace) {
286
- minWastedSpace = wastedSpace;
287
- bestColumns = cols;
288
- cellWidth = itemWidth;
289
- }
290
- }
291
-
292
- return { columns: bestColumns, cellWidth };
293
- };
294
-
295
- /**
296
- * Returns the size of the largest rectangle with the given aspect ration that fits within the grid.
297
- */
298
- const fitItemsToGrid = (
299
- outerWidth: number,
300
- outerHeight: number,
301
- numCols: number,
302
- numRows: number,
303
- aspectRatio: number,
304
- gap: number,
305
- ): { width: number; height: number } => {
306
- // Calculate available space accounting for gaps.
307
- const availableWidth = outerWidth - gap * (numCols - 1);
308
- const availableHeight = outerHeight - gap * (numRows - 1);
309
-
310
- // Calculate max dimensions.
311
- const maxCellWidth = availableWidth / numCols;
312
- const maxCellHeight = availableHeight / numRows;
313
-
314
- // Use fitAspectRatio to get dimensions that fit within max cell size while maintaining the desired aspect ratio
315
- return fitAspectRatio(maxCellWidth, maxCellHeight, aspectRatio);
316
- };
317
-
318
- /**
319
- * Returns the size of the largest rectangle the given aspect ratio that fits within the outer rectangle.
320
- */
321
- const fitAspectRatio = (
322
- outerWidth: number,
323
- outerHeight: number,
324
- aspectRatio: number,
325
- ): { width: number; height: number } => {
326
- if (outerWidth <= 0 || outerHeight <= 0 || aspectRatio <= 0) {
327
- return { width: 0, height: 0 };
328
- }
329
-
330
- // First try fitting to width.
331
- let width = outerWidth;
332
- let height = width / aspectRatio;
333
-
334
- // If too tall, fit to height instead.
335
- if (height > outerHeight) {
336
- height = outerHeight;
337
- width = height * aspectRatio;
338
- }
339
-
340
- return { width, height };
341
- };
@@ -1,134 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import React, { type CSSProperties, type PropsWithChildren, useEffect, useState } from 'react';
6
-
7
- import { Icon, IconButton, type ThemedClassName, useTranslation } from '@dxos/react-ui';
8
- import { Waveform } from '@dxos/react-ui-sfx';
9
- import { groupHoverControlItemWithTransition, mx } from '@dxos/ui-theme';
10
-
11
- import { meta } from '#meta';
12
-
13
- export type ResponsiveGridItemProps<T extends object = any> = PropsWithChildren<
14
- ThemedClassName<{
15
- item: T;
16
- style?: CSSProperties;
17
- pinned?: boolean;
18
- name?: string;
19
- self?: boolean;
20
- screenshare?: boolean;
21
- video?: boolean;
22
- mute?: boolean;
23
- wave?: boolean;
24
- speaking?: boolean;
25
- debug?: boolean;
26
- onClick?: (item: T) => void;
27
- }>
28
- >;
29
-
30
- /**
31
- * Cell container.
32
- */
33
- export const ResponsiveGridItem = <T extends object = any>({
34
- children,
35
- classNames,
36
- item,
37
- style,
38
- name,
39
- self,
40
- pinned,
41
- screenshare,
42
- video,
43
- mute,
44
- wave,
45
- speaking,
46
- onClick,
47
- }: ResponsiveGridItemProps<T>) => {
48
- const { t } = useTranslation(meta.id);
49
- const iconProps: Record<string, { icon: string; label: string; classNames?: string }> = {
50
- wave: {
51
- icon: 'ph--hand-waving--duotone',
52
- label: t('icon-wave.label'),
53
- classNames: 'animate-pulse bg-orange-500',
54
- },
55
- mute: {
56
- icon: 'ph--microphone-slash--regular',
57
- label: t('icon-muted.label'),
58
- },
59
- };
60
-
61
- const props = wave && !pinned ? iconProps.wave : mute ? iconProps.mute : speaking ? iconProps.speaking : undefined;
62
-
63
- // Debounce speaking indicator.
64
- const [speakingIndicator, setSpeakingIndicator] = useState(speaking);
65
- useEffect(() => {
66
- if (speaking) {
67
- setSpeakingIndicator(true);
68
- } else {
69
- const timeout = setTimeout(() => {
70
- setSpeakingIndicator(false);
71
- }, 1_000);
72
- return () => clearTimeout(timeout);
73
- }
74
- }, [speaking]);
75
-
76
- return (
77
- <div
78
- className={mx(
79
- 'dx-expander relative group',
80
- 'rounded-md outline outline-2 outline-neutral-900 transition-[outline-color] duration-500',
81
- speakingIndicator ? 'outline-green-500' : !video && 'outline-separator',
82
- classNames,
83
- )}
84
- style={style}
85
- >
86
- {children}
87
-
88
- {/* Action. */}
89
- {onClick && (
90
- <div className='z-10 absolute top-1 right-1 flex'>
91
- <IconButton
92
- classNames={mx('p-1 min-h-1 rounded-sm', groupHoverControlItemWithTransition)}
93
- iconOnly
94
- icon={pinned ? 'ph--x--regular' : 'ph--arrows-out--regular'}
95
- size={pinned ? 5 : 4}
96
- label={pinned ? t('icon-unpin.label') : t('icon-pin.label')}
97
- onClick={() => onClick?.(item)}
98
- />
99
- </div>
100
- )}
101
-
102
- {/* Name. */}
103
- {name && (
104
- <div className='z-10 absolute bottom-1 left-8 right-1 flex justify-end gap-1 items-center'>
105
- {/* TODO(burdon): Replace with avatar for everyone. */}
106
- {/* {self && <Icon icon='ph--asterisk--regular' size={pinned ? 5 : 4} />} */}
107
- {screenshare && <Icon icon='ph--broadcast--regular' size={pinned ? 5 : 4} />}
108
- <div
109
- className={mx(
110
- 'bg-neutral-800 text-neutral-100 py-0.5 truncate rounded-sm',
111
- pinned ? 'px-2' : 'px-1 text-xs',
112
- )}
113
- >
114
- {name}
115
- </div>
116
- </div>
117
- )}
118
-
119
- {/* Activity. */}
120
- <div className='z-10 absolute bottom-1 left-1 flex'>
121
- {(speaking && <Waveform active size={pinned ? 5 : 4} />) ||
122
- (props && (
123
- <IconButton
124
- classNames={mx('p-1 min-h-1 rounded-sm', props?.classNames)}
125
- icon={props?.icon}
126
- label={props?.label}
127
- size={pinned ? 5 : 4}
128
- iconOnly
129
- />
130
- ))}
131
- </div>
132
- </div>
133
- );
134
- };
@@ -1,54 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import { type Meta, type StoryObj } from '@storybook/react-vite';
6
- import React from 'react';
7
-
8
- import { withLayout, withTheme } from '@dxos/react-ui/testing';
9
-
10
- import { translations } from '#translations';
11
-
12
- import { VideoObject as VideoObjectComponent } from '../Media';
13
- import { ResponsivePanel } from './ResponsivePanel';
14
-
15
- const meta = {
16
- title: 'plugins/plugin-thread/components/ResponsivePanel',
17
- component: ResponsivePanel,
18
- decorators: [withTheme(), withLayout({ layout: 'fullscreen' })],
19
- parameters: {
20
- layout: 'fullscreen',
21
- translations,
22
- },
23
- } satisfies Meta<typeof ResponsivePanel>;
24
-
25
- export default meta;
26
-
27
- type Story = StoryObj<typeof ResponsivePanel>;
28
-
29
- export const Image: Story = {
30
- args: {
31
- children: <img src='https://placehold.co/3200x1800/333/999?font=roboto&text=X' />,
32
- },
33
- };
34
-
35
- export const Video: Story = {
36
- // NOTE: The video's max size is 1280x720.
37
- args: {
38
- children: (
39
- <video
40
- src='https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerFun.mp4'
41
- playsInline
42
- autoPlay
43
- muted
44
- loop
45
- />
46
- ),
47
- },
48
- };
49
-
50
- export const VideoObject: Story = {
51
- args: {
52
- children: <VideoObjectComponent classNames='rounded-md outline outline-primary-500' />,
53
- },
54
- };