@dxos/plugin-thread 0.8.4-main.fd6878d → 0.8.4-staging.60fe92afc8

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 (464) hide show
  1. package/LICENSE +102 -5
  2. package/PLUGIN.mdl +75 -0
  3. package/README.md +1 -1
  4. package/dist/lib/neutral/ChannelArticle-H633OM3U.mjs +57 -0
  5. package/dist/lib/neutral/ChannelArticle-H633OM3U.mjs.map +7 -0
  6. package/dist/lib/neutral/ChannelCreatePanel-NUXXKHZQ.mjs +38 -0
  7. package/dist/lib/neutral/ChannelCreatePanel-NUXXKHZQ.mjs.map +7 -0
  8. package/dist/lib/neutral/ThreadArticle-ROQXQLEZ.mjs +57 -0
  9. package/dist/lib/neutral/ThreadArticle-ROQXQLEZ.mjs.map +7 -0
  10. package/dist/lib/neutral/ThreadPlugin.mjs +67 -0
  11. package/dist/lib/neutral/ThreadPlugin.mjs.map +7 -0
  12. package/dist/lib/neutral/ThreadPlugin.node.mjs +29 -0
  13. package/dist/lib/neutral/ThreadPlugin.node.mjs.map +7 -0
  14. package/dist/lib/neutral/ThreadPlugin.workerd.mjs +27 -0
  15. package/dist/lib/neutral/ThreadPlugin.workerd.mjs.map +7 -0
  16. package/dist/lib/neutral/app-graph-builder-OLKN3VTB.mjs +50 -0
  17. package/dist/lib/neutral/app-graph-builder-OLKN3VTB.mjs.map +7 -0
  18. package/dist/lib/neutral/append-channel-message-J6DXDPBH.mjs +34 -0
  19. package/dist/lib/neutral/append-channel-message-J6DXDPBH.mjs.map +7 -0
  20. package/dist/lib/neutral/capabilities/index.mjs +19 -0
  21. package/dist/lib/neutral/capabilities/index.mjs.map +7 -0
  22. package/dist/lib/neutral/channel-backend-feed-FCXGAIEC.mjs +58 -0
  23. package/dist/lib/neutral/channel-backend-feed-FCXGAIEC.mjs.map +7 -0
  24. package/dist/lib/neutral/chunk-AWAQTEU6.mjs +10 -0
  25. package/dist/lib/neutral/chunk-AWAQTEU6.mjs.map +7 -0
  26. package/dist/lib/neutral/chunk-HJHK5O6F.mjs +109 -0
  27. package/dist/lib/neutral/chunk-HJHK5O6F.mjs.map +7 -0
  28. package/dist/lib/neutral/chunk-J5LGTIGS.mjs +10 -0
  29. package/dist/lib/neutral/chunk-OOC6EQ7X.mjs +36 -0
  30. package/dist/lib/neutral/chunk-OOC6EQ7X.mjs.map +7 -0
  31. package/dist/lib/neutral/chunk-P4RSGFS4.mjs +69 -0
  32. package/dist/lib/neutral/chunk-P4RSGFS4.mjs.map +7 -0
  33. package/dist/lib/neutral/chunk-SZXFLBZL.mjs +8 -0
  34. package/dist/lib/neutral/chunk-SZXFLBZL.mjs.map +7 -0
  35. package/dist/lib/neutral/components/index.mjs +93 -0
  36. package/dist/lib/neutral/components/index.mjs.map +7 -0
  37. package/dist/lib/neutral/containers/index.mjs +13 -0
  38. package/dist/lib/neutral/containers/index.mjs.map +7 -0
  39. package/dist/lib/neutral/create-channel-UW2LSL4G.mjs +41 -0
  40. package/dist/lib/neutral/create-channel-UW2LSL4G.mjs.map +7 -0
  41. package/dist/lib/neutral/create-object-RLCOUVAW.mjs +46 -0
  42. package/dist/lib/neutral/create-object-RLCOUVAW.mjs.map +7 -0
  43. package/dist/lib/neutral/hooks/index.mjs +11 -0
  44. package/dist/lib/neutral/index.mjs +34 -0
  45. package/dist/lib/neutral/meta.json +1 -0
  46. package/dist/lib/neutral/meta.mjs +10 -0
  47. package/dist/lib/neutral/navigation-resolver-4X4HCQYX.mjs +14 -0
  48. package/dist/lib/neutral/navigation-resolver-4X4HCQYX.mjs.map +7 -0
  49. package/dist/lib/neutral/operation-handler-RU6K2S4L.mjs +13 -0
  50. package/dist/lib/neutral/operation-handler-RU6K2S4L.mjs.map +7 -0
  51. package/dist/lib/neutral/operations/index.mjs +8 -0
  52. package/dist/lib/neutral/plugin.mjs +16 -0
  53. package/dist/lib/neutral/plugin.mjs.map +7 -0
  54. package/dist/lib/neutral/react-surface-G6KT7TSU.mjs +48 -0
  55. package/dist/lib/neutral/react-surface-G6KT7TSU.mjs.map +7 -0
  56. package/dist/lib/neutral/translations.mjs +91 -0
  57. package/dist/lib/neutral/translations.mjs.map +7 -0
  58. package/dist/lib/neutral/types/index.mjs +16 -0
  59. package/dist/types/src/ThreadPlugin.d.ts +3 -1
  60. package/dist/types/src/ThreadPlugin.d.ts.map +1 -1
  61. package/dist/types/src/ThreadPlugin.node.d.ts +4 -0
  62. package/dist/types/src/ThreadPlugin.node.d.ts.map +1 -0
  63. package/dist/types/src/ThreadPlugin.test.d.ts +2 -0
  64. package/dist/types/src/ThreadPlugin.test.d.ts.map +1 -0
  65. package/dist/types/src/ThreadPlugin.workerd.d.ts +4 -0
  66. package/dist/types/src/ThreadPlugin.workerd.d.ts.map +1 -0
  67. package/dist/types/src/capabilities/app-graph-builder.d.ts +4 -2
  68. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
  69. package/dist/types/src/capabilities/channel-backend-feed.d.ts +13 -0
  70. package/dist/types/src/capabilities/channel-backend-feed.d.ts.map +1 -0
  71. package/dist/types/src/capabilities/create-object.d.ts +11 -0
  72. package/dist/types/src/capabilities/create-object.d.ts.map +1 -0
  73. package/dist/types/src/capabilities/index.d.ts +12 -14
  74. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  75. package/dist/types/src/capabilities/navigation-resolver.d.ts +6 -0
  76. package/dist/types/src/capabilities/navigation-resolver.d.ts.map +1 -0
  77. package/dist/types/src/capabilities/operation-handler.d.ts +6 -0
  78. package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
  79. package/dist/types/src/capabilities/react-surface.d.ts +3 -2
  80. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  81. package/dist/types/src/components/Chat/Chat.d.ts +43 -0
  82. package/dist/types/src/components/Chat/Chat.d.ts.map +1 -0
  83. package/dist/types/src/components/Chat/index.d.ts +2 -0
  84. package/dist/types/src/components/Chat/index.d.ts.map +1 -0
  85. package/dist/types/src/components/index.d.ts +1 -10
  86. package/dist/types/src/components/index.d.ts.map +1 -1
  87. package/dist/types/src/containers/ChannelArticle/ChannelArticle.d.ts +19 -0
  88. package/dist/types/src/containers/ChannelArticle/ChannelArticle.d.ts.map +1 -0
  89. package/dist/types/src/containers/ChannelArticle/ChannelArticle.stories.d.ts +162 -0
  90. package/dist/types/src/containers/ChannelArticle/ChannelArticle.stories.d.ts.map +1 -0
  91. package/dist/types/src/containers/ChannelArticle/index.d.ts +2 -0
  92. package/dist/types/src/containers/ChannelArticle/index.d.ts.map +1 -0
  93. package/dist/types/src/containers/ChannelCreatePanel/ChannelCreatePanel.d.ts +11 -0
  94. package/dist/types/src/containers/ChannelCreatePanel/ChannelCreatePanel.d.ts.map +1 -0
  95. package/dist/types/src/containers/ChannelCreatePanel/index.d.ts +2 -0
  96. package/dist/types/src/containers/ChannelCreatePanel/index.d.ts.map +1 -0
  97. package/dist/types/src/containers/ThreadArticle/ThreadArticle.d.ts +20 -0
  98. package/dist/types/src/containers/ThreadArticle/ThreadArticle.d.ts.map +1 -0
  99. package/dist/types/src/containers/ThreadArticle/ThreadArticle.stories.d.ts +162 -0
  100. package/dist/types/src/containers/ThreadArticle/ThreadArticle.stories.d.ts.map +1 -0
  101. package/dist/types/src/containers/ThreadArticle/index.d.ts +2 -0
  102. package/dist/types/src/containers/ThreadArticle/index.d.ts.map +1 -0
  103. package/dist/types/src/containers/index.d.ts +5 -0
  104. package/dist/types/src/containers/index.d.ts.map +1 -0
  105. package/dist/types/src/hooks/index.d.ts +1 -4
  106. package/dist/types/src/hooks/index.d.ts.map +1 -1
  107. package/dist/types/src/hooks/useMessages.d.ts +4 -0
  108. package/dist/types/src/hooks/useMessages.d.ts.map +1 -0
  109. package/dist/types/src/hooks/useStatus.d.ts.map +1 -1
  110. package/dist/types/src/index.d.ts +2 -3
  111. package/dist/types/src/index.d.ts.map +1 -1
  112. package/dist/types/src/meta.d.ts +3 -4
  113. package/dist/types/src/meta.d.ts.map +1 -1
  114. package/dist/types/src/operations/append-channel-message.d.ts +5 -0
  115. package/dist/types/src/operations/append-channel-message.d.ts.map +1 -0
  116. package/dist/types/src/operations/create-channel.d.ts +5 -0
  117. package/dist/types/src/operations/create-channel.d.ts.map +1 -0
  118. package/dist/types/src/operations/index.d.ts +3 -0
  119. package/dist/types/src/operations/index.d.ts.map +1 -0
  120. package/dist/types/src/paths.d.ts +3 -0
  121. package/dist/types/src/paths.d.ts.map +1 -0
  122. package/dist/types/src/plugin.d.ts +4 -0
  123. package/dist/types/src/plugin.d.ts.map +1 -0
  124. package/dist/types/src/translations.d.ts +142 -72
  125. package/dist/types/src/translations.d.ts.map +1 -1
  126. package/dist/types/src/types/ThreadCapabilities.d.ts +37 -0
  127. package/dist/types/src/types/ThreadCapabilities.d.ts.map +1 -0
  128. package/dist/types/src/types/ThreadOperation.d.ts +91 -0
  129. package/dist/types/src/types/ThreadOperation.d.ts.map +1 -0
  130. package/dist/types/src/types/channel-backend.d.ts +16 -0
  131. package/dist/types/src/types/channel-backend.d.ts.map +1 -0
  132. package/dist/types/src/types/channel-backend.test.d.ts +2 -0
  133. package/dist/types/src/types/channel-backend.test.d.ts.map +1 -0
  134. package/dist/types/src/types/index.d.ts +3 -2
  135. package/dist/types/src/types/index.d.ts.map +1 -1
  136. package/dist/types/src/util.d.ts +4 -20
  137. package/dist/types/src/util.d.ts.map +1 -1
  138. package/dist/types/tsconfig.tsbuildinfo +1 -1
  139. package/package.json +108 -81
  140. package/src/ThreadPlugin.node.ts +26 -0
  141. package/src/ThreadPlugin.test.ts +27 -0
  142. package/src/ThreadPlugin.tsx +38 -144
  143. package/src/ThreadPlugin.workerd.ts +25 -0
  144. package/src/capabilities/app-graph-builder.ts +44 -174
  145. package/src/capabilities/channel-backend-feed.ts +60 -0
  146. package/src/capabilities/create-object.ts +46 -0
  147. package/src/capabilities/index.ts +11 -11
  148. package/src/capabilities/navigation-resolver.ts +18 -0
  149. package/src/capabilities/operation-handler.ts +16 -0
  150. package/src/capabilities/react-surface.tsx +39 -79
  151. package/src/components/Chat/Chat.tsx +119 -0
  152. package/src/components/Chat/index.ts +5 -0
  153. package/src/components/index.ts +1 -14
  154. package/src/containers/ChannelArticle/ChannelArticle.stories.tsx +108 -0
  155. package/src/containers/ChannelArticle/ChannelArticle.tsx +83 -0
  156. package/src/containers/ChannelArticle/index.ts +5 -0
  157. package/src/containers/ChannelCreatePanel/ChannelCreatePanel.tsx +52 -0
  158. package/src/containers/ChannelCreatePanel/index.ts +5 -0
  159. package/src/containers/ThreadArticle/ThreadArticle.stories.tsx +86 -0
  160. package/src/containers/ThreadArticle/ThreadArticle.tsx +75 -0
  161. package/src/containers/ThreadArticle/index.ts +5 -0
  162. package/src/containers/index.ts +9 -0
  163. package/src/hooks/index.ts +1 -4
  164. package/src/hooks/useMessages.ts +37 -0
  165. package/src/index.ts +4 -4
  166. package/src/meta.ts +27 -9
  167. package/src/operations/append-channel-message.ts +31 -0
  168. package/src/operations/create-channel.ts +30 -0
  169. package/src/operations/index.ts +10 -0
  170. package/src/paths.ts +10 -0
  171. package/src/plugin.ts +11 -0
  172. package/src/translations.ts +75 -73
  173. package/src/types/ThreadCapabilities.ts +47 -0
  174. package/src/types/ThreadOperation.ts +49 -0
  175. package/src/types/channel-backend.test.ts +48 -0
  176. package/src/types/channel-backend.ts +54 -0
  177. package/src/types/index.ts +3 -2
  178. package/src/util.ts +35 -18
  179. package/src/vite-env.d.ts +10 -0
  180. package/dist/lib/browser/ChannelContainer-O2SFQJU7.mjs +0 -16
  181. package/dist/lib/browser/ChatContainer-PVT3DUZJ.mjs +0 -15
  182. package/dist/lib/browser/app-graph-builder-AF3M7UWN.mjs +0 -171
  183. package/dist/lib/browser/app-graph-builder-AF3M7UWN.mjs.map +0 -7
  184. package/dist/lib/browser/call-manager-XRRCAVLI.mjs +0 -24
  185. package/dist/lib/browser/call-manager-XRRCAVLI.mjs.map +0 -7
  186. package/dist/lib/browser/chunk-2CWJBXBH.mjs +0 -21
  187. package/dist/lib/browser/chunk-2CWJBXBH.mjs.map +0 -7
  188. package/dist/lib/browser/chunk-4APCDRSH.mjs +0 -18
  189. package/dist/lib/browser/chunk-4APCDRSH.mjs.map +0 -7
  190. package/dist/lib/browser/chunk-DW7JD64V.mjs +0 -137
  191. package/dist/lib/browser/chunk-DW7JD64V.mjs.map +0 -7
  192. package/dist/lib/browser/chunk-EV4JWI7L.mjs +0 -17
  193. package/dist/lib/browser/chunk-EV4JWI7L.mjs.map +0 -7
  194. package/dist/lib/browser/chunk-FY4ZRD5X.mjs +0 -367
  195. package/dist/lib/browser/chunk-FY4ZRD5X.mjs.map +0 -7
  196. package/dist/lib/browser/chunk-GERVMFQW.mjs +0 -31
  197. package/dist/lib/browser/chunk-GERVMFQW.mjs.map +0 -7
  198. package/dist/lib/browser/chunk-J3JO5NWO.mjs +0 -477
  199. package/dist/lib/browser/chunk-J3JO5NWO.mjs.map +0 -7
  200. package/dist/lib/browser/chunk-JGKMMI65.mjs +0 -56
  201. package/dist/lib/browser/chunk-JGKMMI65.mjs.map +0 -7
  202. package/dist/lib/browser/chunk-TUFWPOVS.mjs +0 -1698
  203. package/dist/lib/browser/chunk-TUFWPOVS.mjs.map +0 -7
  204. package/dist/lib/browser/chunk-X5PIP5YR.mjs +0 -149
  205. package/dist/lib/browser/chunk-X5PIP5YR.mjs.map +0 -7
  206. package/dist/lib/browser/chunk-ZJ7QBXK6.mjs +0 -984
  207. package/dist/lib/browser/chunk-ZJ7QBXK6.mjs.map +0 -7
  208. package/dist/lib/browser/index.mjs +0 -302
  209. package/dist/lib/browser/index.mjs.map +0 -7
  210. package/dist/lib/browser/intent-resolver-DCY4P4OX.mjs +0 -369
  211. package/dist/lib/browser/intent-resolver-DCY4P4OX.mjs.map +0 -7
  212. package/dist/lib/browser/markdown-WZSXCEZJ.mjs +0 -169
  213. package/dist/lib/browser/markdown-WZSXCEZJ.mjs.map +0 -7
  214. package/dist/lib/browser/meta.json +0 -1
  215. package/dist/lib/browser/react-root-QXPALOUQ.mjs +0 -28
  216. package/dist/lib/browser/react-root-QXPALOUQ.mjs.map +0 -7
  217. package/dist/lib/browser/react-surface-PYAMIADB.mjs +0 -109
  218. package/dist/lib/browser/react-surface-PYAMIADB.mjs.map +0 -7
  219. package/dist/lib/browser/settings-AC6YSASL.mjs +0 -22
  220. package/dist/lib/browser/settings-AC6YSASL.mjs.map +0 -7
  221. package/dist/lib/browser/state-2T4KDWBX.mjs +0 -34
  222. package/dist/lib/browser/state-2T4KDWBX.mjs.map +0 -7
  223. package/dist/lib/browser/types/index.mjs +0 -16
  224. package/dist/lib/node-esm/ChannelContainer-B2ZGAE4P.mjs +0 -17
  225. package/dist/lib/node-esm/ChatContainer-2CT4PJ7I.mjs +0 -16
  226. package/dist/lib/node-esm/app-graph-builder-OLSJVCWY.mjs +0 -172
  227. package/dist/lib/node-esm/app-graph-builder-OLSJVCWY.mjs.map +0 -7
  228. package/dist/lib/node-esm/call-manager-EI7FXRAU.mjs +0 -25
  229. package/dist/lib/node-esm/call-manager-EI7FXRAU.mjs.map +0 -7
  230. package/dist/lib/node-esm/chunk-4TME3BR4.mjs +0 -1699
  231. package/dist/lib/node-esm/chunk-4TME3BR4.mjs.map +0 -7
  232. package/dist/lib/node-esm/chunk-57XR3LEF.mjs +0 -33
  233. package/dist/lib/node-esm/chunk-57XR3LEF.mjs.map +0 -7
  234. package/dist/lib/node-esm/chunk-6CRHHOST.mjs +0 -23
  235. package/dist/lib/node-esm/chunk-6CRHHOST.mjs.map +0 -7
  236. package/dist/lib/node-esm/chunk-BF4UKS55.mjs +0 -368
  237. package/dist/lib/node-esm/chunk-BF4UKS55.mjs.map +0 -7
  238. package/dist/lib/node-esm/chunk-GRLRWTRU.mjs +0 -19
  239. package/dist/lib/node-esm/chunk-GRLRWTRU.mjs.map +0 -7
  240. package/dist/lib/node-esm/chunk-PYTVBN5J.mjs +0 -19
  241. package/dist/lib/node-esm/chunk-PYTVBN5J.mjs.map +0 -7
  242. package/dist/lib/node-esm/chunk-QBHKLWGR.mjs +0 -58
  243. package/dist/lib/node-esm/chunk-QBHKLWGR.mjs.map +0 -7
  244. package/dist/lib/node-esm/chunk-SED3O2XO.mjs +0 -150
  245. package/dist/lib/node-esm/chunk-SED3O2XO.mjs.map +0 -7
  246. package/dist/lib/node-esm/chunk-VNG6M2IY.mjs +0 -478
  247. package/dist/lib/node-esm/chunk-VNG6M2IY.mjs.map +0 -7
  248. package/dist/lib/node-esm/chunk-XVKWHTH4.mjs +0 -138
  249. package/dist/lib/node-esm/chunk-XVKWHTH4.mjs.map +0 -7
  250. package/dist/lib/node-esm/chunk-YIDU3DXK.mjs +0 -985
  251. package/dist/lib/node-esm/chunk-YIDU3DXK.mjs.map +0 -7
  252. package/dist/lib/node-esm/index.mjs +0 -303
  253. package/dist/lib/node-esm/index.mjs.map +0 -7
  254. package/dist/lib/node-esm/intent-resolver-QGTPU6QB.mjs +0 -370
  255. package/dist/lib/node-esm/intent-resolver-QGTPU6QB.mjs.map +0 -7
  256. package/dist/lib/node-esm/markdown-3MZXUGUA.mjs +0 -170
  257. package/dist/lib/node-esm/markdown-3MZXUGUA.mjs.map +0 -7
  258. package/dist/lib/node-esm/meta.json +0 -1
  259. package/dist/lib/node-esm/react-root-7ZFJYVUZ.mjs +0 -29
  260. package/dist/lib/node-esm/react-root-7ZFJYVUZ.mjs.map +0 -7
  261. package/dist/lib/node-esm/react-surface-UJFCSFNO.mjs +0 -110
  262. package/dist/lib/node-esm/react-surface-UJFCSFNO.mjs.map +0 -7
  263. package/dist/lib/node-esm/settings-N52O7MLS.mjs +0 -23
  264. package/dist/lib/node-esm/settings-N52O7MLS.mjs.map +0 -7
  265. package/dist/lib/node-esm/state-62TQKQVB.mjs +0 -35
  266. package/dist/lib/node-esm/state-62TQKQVB.mjs.map +0 -7
  267. package/dist/lib/node-esm/types/index.mjs +0 -17
  268. package/dist/types/src/calls/call-manager.d.ts +0 -77
  269. package/dist/types/src/calls/call-manager.d.ts.map +0 -1
  270. package/dist/types/src/calls/call-swarm-synchronizer.d.ts +0 -66
  271. package/dist/types/src/calls/call-swarm-synchronizer.d.ts.map +0 -1
  272. package/dist/types/src/calls/index.d.ts +0 -7
  273. package/dist/types/src/calls/index.d.ts.map +0 -1
  274. package/dist/types/src/calls/media-manager.d.ts +0 -60
  275. package/dist/types/src/calls/media-manager.d.ts.map +0 -1
  276. package/dist/types/src/calls/speaking-monitor.d.ts +0 -24
  277. package/dist/types/src/calls/speaking-monitor.d.ts.map +0 -1
  278. package/dist/types/src/calls/types.d.ts +0 -45
  279. package/dist/types/src/calls/types.d.ts.map +0 -1
  280. package/dist/types/src/calls/util/audio.d.ts +0 -6
  281. package/dist/types/src/calls/util/audio.d.ts.map +0 -1
  282. package/dist/types/src/calls/util/calls-service.d.ts +0 -75
  283. package/dist/types/src/calls/util/calls-service.d.ts.map +0 -1
  284. package/dist/types/src/calls/util/history-cache.d.ts +0 -11
  285. package/dist/types/src/calls/util/history-cache.d.ts.map +0 -1
  286. package/dist/types/src/calls/util/index.d.ts +0 -5
  287. package/dist/types/src/calls/util/index.d.ts.map +0 -1
  288. package/dist/types/src/calls/util/media.d.ts +0 -6
  289. package/dist/types/src/calls/util/media.d.ts.map +0 -1
  290. package/dist/types/src/calls/util/stub-media-streams.d.ts +0 -18
  291. package/dist/types/src/calls/util/stub-media-streams.d.ts.map +0 -1
  292. package/dist/types/src/calls/util/task-scheduling.d.ts +0 -17
  293. package/dist/types/src/calls/util/task-scheduling.d.ts.map +0 -1
  294. package/dist/types/src/calls-service.stories.d.ts +0 -22
  295. package/dist/types/src/calls-service.stories.d.ts.map +0 -1
  296. package/dist/types/src/capabilities/call-manager.d.ts +0 -5
  297. package/dist/types/src/capabilities/call-manager.d.ts.map +0 -1
  298. package/dist/types/src/capabilities/capabilities.d.ts +0 -27
  299. package/dist/types/src/capabilities/capabilities.d.ts.map +0 -1
  300. package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
  301. package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
  302. package/dist/types/src/capabilities/markdown.d.ts +0 -4
  303. package/dist/types/src/capabilities/markdown.d.ts.map +0 -1
  304. package/dist/types/src/capabilities/react-root.d.ts +0 -7
  305. package/dist/types/src/capabilities/react-root.d.ts.map +0 -1
  306. package/dist/types/src/capabilities/settings.d.ts +0 -4
  307. package/dist/types/src/capabilities/settings.d.ts.map +0 -1
  308. package/dist/types/src/capabilities/state.d.ts +0 -7
  309. package/dist/types/src/capabilities/state.d.ts.map +0 -1
  310. package/dist/types/src/components/Call/Call.d.ts +0 -17
  311. package/dist/types/src/components/Call/Call.d.ts.map +0 -1
  312. package/dist/types/src/components/Call/Toolbar.d.ts +0 -16
  313. package/dist/types/src/components/Call/Toolbar.d.ts.map +0 -1
  314. package/dist/types/src/components/Call/index.d.ts +0 -3
  315. package/dist/types/src/components/Call/index.d.ts.map +0 -1
  316. package/dist/types/src/components/CallDebugPanel.d.ts +0 -8
  317. package/dist/types/src/components/CallDebugPanel.d.ts.map +0 -1
  318. package/dist/types/src/components/CallSidebar.d.ts +0 -4
  319. package/dist/types/src/components/CallSidebar.d.ts.map +0 -1
  320. package/dist/types/src/components/ChannelContainer.d.ts +0 -14
  321. package/dist/types/src/components/ChannelContainer.d.ts.map +0 -1
  322. package/dist/types/src/components/ChannelContainer.stories.d.ts +0 -10
  323. package/dist/types/src/components/ChannelContainer.stories.d.ts.map +0 -1
  324. package/dist/types/src/components/Chat.stories.d.ts +0 -7
  325. package/dist/types/src/components/Chat.stories.d.ts.map +0 -1
  326. package/dist/types/src/components/ChatContainer.d.ts +0 -17
  327. package/dist/types/src/components/ChatContainer.d.ts.map +0 -1
  328. package/dist/types/src/components/Comments.stories.d.ts +0 -6
  329. package/dist/types/src/components/Comments.stories.d.ts.map +0 -1
  330. package/dist/types/src/components/CommentsContainer.d.ts +0 -13
  331. package/dist/types/src/components/CommentsContainer.d.ts.map +0 -1
  332. package/dist/types/src/components/CommentsThreadContainer.d.ts +0 -14
  333. package/dist/types/src/components/CommentsThreadContainer.d.ts.map +0 -1
  334. package/dist/types/src/components/Lobby/Lobby.d.ts +0 -15
  335. package/dist/types/src/components/Lobby/Lobby.d.ts.map +0 -1
  336. package/dist/types/src/components/Lobby/index.d.ts +0 -2
  337. package/dist/types/src/components/Lobby/index.d.ts.map +0 -1
  338. package/dist/types/src/components/Media/AudioStream.d.ts +0 -6
  339. package/dist/types/src/components/Media/AudioStream.d.ts.map +0 -1
  340. package/dist/types/src/components/Media/VideoObject.d.ts +0 -15
  341. package/dist/types/src/components/Media/VideoObject.d.ts.map +0 -1
  342. package/dist/types/src/components/Media/VideoObject.stories.d.ts +0 -8
  343. package/dist/types/src/components/Media/VideoObject.stories.d.ts.map +0 -1
  344. package/dist/types/src/components/Media/index.d.ts +0 -3
  345. package/dist/types/src/components/Media/index.d.ts.map +0 -1
  346. package/dist/types/src/components/MessageContainer.d.ts +0 -11
  347. package/dist/types/src/components/MessageContainer.d.ts.map +0 -1
  348. package/dist/types/src/components/Participant/Participant.d.ts +0 -6
  349. package/dist/types/src/components/Participant/Participant.d.ts.map +0 -1
  350. package/dist/types/src/components/Participant/ParticipantGrid.d.ts +0 -11
  351. package/dist/types/src/components/Participant/ParticipantGrid.d.ts.map +0 -1
  352. package/dist/types/src/components/Participant/index.d.ts +0 -3
  353. package/dist/types/src/components/Participant/index.d.ts.map +0 -1
  354. package/dist/types/src/components/ResponsiveGrid/ResponsiveContainer.d.ts +0 -12
  355. package/dist/types/src/components/ResponsiveGrid/ResponsiveContainer.d.ts.map +0 -1
  356. package/dist/types/src/components/ResponsiveGrid/ResponsiveContainer.stories.d.ts +0 -10
  357. package/dist/types/src/components/ResponsiveGrid/ResponsiveContainer.stories.d.ts.map +0 -1
  358. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.d.ts +0 -32
  359. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.d.ts.map +0 -1
  360. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.stories.d.ts +0 -23
  361. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.stories.d.ts.map +0 -1
  362. package/dist/types/src/components/ResponsiveGrid/ResponsiveGridItem.d.ts +0 -21
  363. package/dist/types/src/components/ResponsiveGrid/ResponsiveGridItem.d.ts.map +0 -1
  364. package/dist/types/src/components/ResponsiveGrid/index.d.ts +0 -4
  365. package/dist/types/src/components/ResponsiveGrid/index.d.ts.map +0 -1
  366. package/dist/types/src/components/ThreadComplementary.d.ts +0 -5
  367. package/dist/types/src/components/ThreadComplementary.d.ts.map +0 -1
  368. package/dist/types/src/components/ThreadSettings.d.ts +0 -6
  369. package/dist/types/src/components/ThreadSettings.d.ts.map +0 -1
  370. package/dist/types/src/components/command-extension.d.ts +0 -3
  371. package/dist/types/src/components/command-extension.d.ts.map +0 -1
  372. package/dist/types/src/components/testing.d.ts +0 -4
  373. package/dist/types/src/components/testing.d.ts.map +0 -1
  374. package/dist/types/src/extensions/index.d.ts +0 -2
  375. package/dist/types/src/extensions/index.d.ts.map +0 -1
  376. package/dist/types/src/extensions/threads.d.ts +0 -9
  377. package/dist/types/src/extensions/threads.d.ts.map +0 -1
  378. package/dist/types/src/hooks/analytics.d.ts +0 -4
  379. package/dist/types/src/hooks/analytics.d.ts.map +0 -1
  380. package/dist/types/src/hooks/useDebugMode.d.ts +0 -2
  381. package/dist/types/src/hooks/useDebugMode.d.ts.map +0 -1
  382. package/dist/types/src/hooks/useInaudibleAudioStreamTrack.d.ts +0 -2
  383. package/dist/types/src/hooks/useInaudibleAudioStreamTrack.d.ts.map +0 -1
  384. package/dist/types/src/hooks/useVideoStreamTrack.d.ts +0 -3
  385. package/dist/types/src/hooks/useVideoStreamTrack.d.ts.map +0 -1
  386. package/dist/types/src/testing/index.d.ts +0 -2
  387. package/dist/types/src/testing/index.d.ts.map +0 -1
  388. package/dist/types/src/testing/stories.d.ts +0 -2
  389. package/dist/types/src/testing/stories.d.ts.map +0 -1
  390. package/dist/types/src/types/schema.d.ts +0 -164
  391. package/dist/types/src/types/schema.d.ts.map +0 -1
  392. package/dist/types/src/types/types.d.ts +0 -388
  393. package/dist/types/src/types/types.d.ts.map +0 -1
  394. package/src/calls/call-manager.ts +0 -246
  395. package/src/calls/call-swarm-synchronizer.ts +0 -350
  396. package/src/calls/index.ts +0 -10
  397. package/src/calls/media-manager.ts +0 -349
  398. package/src/calls/speaking-monitor.ts +0 -85
  399. package/src/calls/types.ts +0 -70
  400. package/src/calls/util/audio.ts +0 -58
  401. package/src/calls/util/calls-service.ts +0 -531
  402. package/src/calls/util/history-cache.ts +0 -27
  403. package/src/calls/util/index.ts +0 -8
  404. package/src/calls/util/media.ts +0 -52
  405. package/src/calls/util/stub-media-streams.ts +0 -70
  406. package/src/calls/util/task-scheduling.ts +0 -92
  407. package/src/calls-service.stories.tsx +0 -216
  408. package/src/capabilities/call-manager.ts +0 -20
  409. package/src/capabilities/capabilities.ts +0 -33
  410. package/src/capabilities/intent-resolver.ts +0 -315
  411. package/src/capabilities/markdown.ts +0 -69
  412. package/src/capabilities/react-root.tsx +0 -17
  413. package/src/capabilities/settings.ts +0 -19
  414. package/src/capabilities/state.ts +0 -26
  415. package/src/components/Call/Call.tsx +0 -89
  416. package/src/components/Call/Toolbar.tsx +0 -182
  417. package/src/components/Call/index.ts +0 -6
  418. package/src/components/CallDebugPanel.tsx +0 -115
  419. package/src/components/CallSidebar.tsx +0 -18
  420. package/src/components/ChannelContainer.stories.tsx +0 -59
  421. package/src/components/ChannelContainer.tsx +0 -201
  422. package/src/components/Chat.stories.tsx +0 -89
  423. package/src/components/ChatContainer.tsx +0 -142
  424. package/src/components/Comments.stories.tsx +0 -93
  425. package/src/components/CommentsContainer.tsx +0 -72
  426. package/src/components/CommentsThreadContainer.tsx +0 -168
  427. package/src/components/Lobby/Lobby.tsx +0 -119
  428. package/src/components/Lobby/index.ts +0 -5
  429. package/src/components/Media/AudioStream.tsx +0 -67
  430. package/src/components/Media/VideoObject.stories.tsx +0 -53
  431. package/src/components/Media/VideoObject.tsx +0 -58
  432. package/src/components/Media/index.ts +0 -6
  433. package/src/components/MessageContainer.tsx +0 -152
  434. package/src/components/Participant/Participant.tsx +0 -57
  435. package/src/components/Participant/ParticipantGrid.tsx +0 -89
  436. package/src/components/Participant/index.ts +0 -6
  437. package/src/components/ResponsiveGrid/ResponsiveContainer.stories.tsx +0 -55
  438. package/src/components/ResponsiveGrid/ResponsiveContainer.tsx +0 -31
  439. package/src/components/ResponsiveGrid/ResponsiveGrid.stories.tsx +0 -157
  440. package/src/components/ResponsiveGrid/ResponsiveGrid.tsx +0 -341
  441. package/src/components/ResponsiveGrid/ResponsiveGridItem.tsx +0 -131
  442. package/src/components/ResponsiveGrid/index.ts +0 -7
  443. package/src/components/ThreadComplementary.tsx +0 -151
  444. package/src/components/ThreadSettings.tsx +0 -17
  445. package/src/components/command-extension.ts +0 -33
  446. package/src/components/testing.ts +0 -29
  447. package/src/extensions/index.ts +0 -5
  448. package/src/extensions/threads.ts +0 -126
  449. package/src/hooks/analytics.ts +0 -40
  450. package/src/hooks/useDebugMode.ts +0 -25
  451. package/src/hooks/useInaudibleAudioStreamTrack.tsx +0 -27
  452. package/src/hooks/useVideoStreamTrack.tsx +0 -33
  453. package/src/testing/index.ts +0 -5
  454. package/src/testing/stories.ts +0 -54
  455. package/src/types/schema.ts +0 -33
  456. package/src/types/types.ts +0 -119
  457. package/src/typings/peermetrics-webrtc-stats.d.ts +0 -30
  458. package/src/typings.d.ts +0 -8
  459. /package/dist/lib/{browser/ChannelContainer-O2SFQJU7.mjs.map → neutral/chunk-J5LGTIGS.mjs.map} +0 -0
  460. /package/dist/lib/{browser/types → neutral/hooks}/index.mjs.map +0 -0
  461. /package/dist/lib/{node-esm/types → neutral}/index.mjs.map +0 -0
  462. /package/dist/lib/{browser/ChatContainer-PVT3DUZJ.mjs.map → neutral/meta.mjs.map} +0 -0
  463. /package/dist/lib/{node-esm/ChannelContainer-B2ZGAE4P.mjs.map → neutral/operations/index.mjs.map} +0 -0
  464. /package/dist/lib/{node-esm/ChatContainer-2CT4PJ7I.mjs.map → neutral/types/index.mjs.map} +0 -0
@@ -1,89 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import React, { useEffect, useMemo, useState } from 'react';
6
-
7
- import { type ThemedClassName } from '@dxos/react-ui';
8
-
9
- import { type UserState } from '../../calls';
10
- import { ResponsiveGrid } from '../ResponsiveGrid';
11
-
12
- import { Participant, SCREENSHARE_SUFFIX } from './Participant';
13
-
14
- const getId = (user: UserState): string => user.id!;
15
-
16
- export type ParticipantGridProps = ThemedClassName<{
17
- self: UserState;
18
- users: UserState[];
19
- fullscreen?: boolean;
20
- debug?: boolean;
21
- }>;
22
-
23
- export const ParticipantGrid = ({ classNames, self, users, fullscreen, debug }: ParticipantGridProps) => {
24
- const [pinned, setPinned] = useState<string | undefined>();
25
-
26
- const allUsers = useMemo(() => {
27
- const allUsers: (UserState & { isSelf?: boolean })[] = [];
28
- users.forEach((user) => {
29
- if (!user.joined) {
30
- return;
31
- }
32
-
33
- allUsers.push({ ...user, isSelf: user.id === self.id });
34
- if (user.tracks?.screenshareEnabled) {
35
- const screenshare: UserState = {
36
- ...user,
37
- id: user.id + SCREENSHARE_SUFFIX,
38
- tracks: {
39
- ...user.tracks,
40
- video: user.tracks.screenshare,
41
- videoEnabled: user.tracks.screenshareEnabled,
42
- } as any, // TODO(burdon): Remove cast.
43
- };
44
-
45
- allUsers.push(screenshare);
46
- }
47
- });
48
-
49
- return allUsers;
50
- }, [self, users]);
51
-
52
- useEffect(() => {
53
- if (pinned) {
54
- // Check expanded user is still in call.
55
- if (!allUsers.find((user) => user.id === pinned)) {
56
- setPinned(undefined);
57
- }
58
- }
59
- }, [pinned, allUsers]);
60
-
61
- // TODO(burdon): Put self last.
62
- const sortedUsers: UserState[] = allUsers.sort((a, b) => {
63
- if (a.isSelf) {
64
- return 1;
65
- } else if (b.isSelf) {
66
- return -1;
67
- } else if (a.tracks?.screenshareEnabled) {
68
- return -1;
69
- } else if (b.tracks?.screenshareEnabled) {
70
- return 1;
71
- } else {
72
- return 0;
73
- }
74
- });
75
-
76
- // TODO(burdon): Show ghost view of user for a second before leaving.
77
- return (
78
- <ResponsiveGrid<UserState>
79
- classNames={classNames}
80
- Cell={Participant}
81
- debug={debug}
82
- getId={getId}
83
- items={sortedUsers}
84
- pinned={pinned}
85
- autoHideGallery={fullscreen}
86
- onPinnedChange={setPinned}
87
- />
88
- );
89
- };
@@ -1,6 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- export * from './Participant';
6
- export * from './ParticipantGrid';
@@ -1,55 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import '@dxos-theme';
6
-
7
- import { type Meta, type StoryObj } from '@storybook/react-vite';
8
- import React from 'react';
9
-
10
- import { withLayout, withTheme } from '@dxos/storybook-utils';
11
-
12
- import { translations } from '../../translations';
13
- import { VideoObject as VideoObjectComponent } from '../Media';
14
-
15
- import { ResponsiveContainer } from './ResponsiveContainer';
16
-
17
- const meta: Meta<typeof ResponsiveContainer> = {
18
- title: 'plugins/plugin-thread/ResponsiveContainer',
19
- component: ResponsiveContainer,
20
- decorators: [withTheme, withLayout({ fullscreen: true })],
21
- parameters: {
22
- translations,
23
- },
24
- };
25
-
26
- export default meta;
27
-
28
- type Story = StoryObj<typeof ResponsiveContainer>;
29
-
30
- export const Image: Story = {
31
- args: {
32
- children: <img src='https://placehold.co/3200x1800/333/999?font=roboto&text=X' />,
33
- },
34
- };
35
-
36
- export const Video: Story = {
37
- // NOTE: The video's max size is 1280x720.
38
- args: {
39
- children: (
40
- <video
41
- src='https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerFun.mp4'
42
- playsInline
43
- autoPlay
44
- muted
45
- loop
46
- />
47
- ),
48
- },
49
- };
50
-
51
- export const VideoObject: Story = {
52
- args: {
53
- children: <VideoObjectComponent classNames='rounded-md outline outline-primary-500' />,
54
- },
55
- };
@@ -1,31 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import React, { type PropsWithChildren } from 'react';
6
-
7
- import { mx } from '@dxos/react-ui-theme';
8
-
9
- /**
10
- * A container component that maintains the child's aspect ratio while centering its content.
11
- * The container will scale to fit within its parent's bounds while preserving the aspect ratio.
12
- *
13
- * @example
14
- * <ResponsiveContainer>
15
- * <VideoObject />
16
- * </ResponsiveContainer>
17
- */
18
- export const ResponsiveContainer = ({ children }: PropsWithChildren) => {
19
- return (
20
- // Outer container that takes full size of parent.
21
- <div role='none' className='relative flex w-full h-full'>
22
- {/* Absolute positioning layer for centering content. */}
23
- <div role='none' className='absolute inset-0 flex justify-center items-center'>
24
- {/* Content container that maintains given aspect ratio and proper scaling. */}
25
- <div role='none' className={mx('max-h-full max-w-full w-auto h-auto aspect-video')}>
26
- {children}
27
- </div>
28
- </div>
29
- </div>
30
- );
31
- };
@@ -1,157 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import '@dxos-theme';
6
-
7
- import { type Meta, type StoryObj } from '@storybook/react-vite';
8
- import React, { useEffect, useState } from 'react';
9
-
10
- import { faker } from '@dxos/random';
11
- import { withLayout, withTheme } from '@dxos/storybook-utils';
12
-
13
- import { translations } from '../../translations';
14
-
15
- import { ResponsiveGrid, type ResponsiveGridProps } from './ResponsiveGrid';
16
- import { ResponsiveGridItem, type ResponsiveGridItemProps } from './ResponsiveGridItem';
17
-
18
- type TestItem = {
19
- id: string;
20
- name: string;
21
- type?: 'image' | 'video';
22
- imageUrl?: string;
23
- videoUrl?: string;
24
- };
25
-
26
- const TestCell = ({ item, ...props }: ResponsiveGridItemProps<TestItem>) => {
27
- const [speaking, setSpeaking] = useState(false);
28
- const [wave, setWave] = useState(false);
29
- const [mute, setMute] = useState(false);
30
- useEffect(() => {
31
- const interval = setInterval(() => {
32
- const mute = Math.random() > 0.7;
33
- setMute(() => mute);
34
- setSpeaking(() => !mute && Math.random() > 0.5);
35
- setWave(() => Math.random() > 0.7);
36
- }, 3_000);
37
-
38
- return () => clearInterval(interval);
39
- }, []);
40
-
41
- return (
42
- <ResponsiveGridItem {...props} item={item} name={item.name} mute={mute} speaking={speaking} wave={wave}>
43
- {item.type === 'image' && <img className='aspect-video object-contain' src={item.imageUrl} />}
44
- {item.type === 'video' && (
45
- <video
46
- className='w-full aspect-video object-cover rounded-md'
47
- src={item.videoUrl}
48
- playsInline
49
- autoPlay
50
- loop
51
- muted
52
- />
53
- )}
54
- </ResponsiveGridItem>
55
- );
56
- };
57
-
58
- type StoryProps = ResponsiveGridProps<TestItem> & { random?: boolean; autoHideGallery?: boolean };
59
-
60
- const meta: Meta<StoryProps> = {
61
- title: 'plugins/plugin-thread/ResponsiveGrid',
62
- component: ResponsiveGrid,
63
- render: (args) => {
64
- const [pinned, setPinned] = useState<string | undefined>(
65
- (args.pinned ?? args.items.length > 1) ? args.items[0]?.id : undefined,
66
- );
67
- const [items, setItems] = useState<TestItem[]>(args.items);
68
- useEffect(() => {
69
- if (!args.random) {
70
- return;
71
- }
72
-
73
- const interval = setInterval(() => {
74
- setItems((items) => {
75
- const p = Math.random();
76
- if (p < 0.5) {
77
- return items;
78
- } else if (p < 0.99 && items.length > 1) {
79
- return items.slice(0, -1);
80
- } else {
81
- return [...items, createItem(items[0]?.type)];
82
- }
83
- });
84
- }, 3_000);
85
-
86
- return () => clearInterval(interval);
87
- }, []);
88
-
89
- return (
90
- <div className='grid grow p-4'>
91
- <ResponsiveGrid {...args} Cell={TestCell} items={items} pinned={pinned} onPinnedChange={setPinned} />
92
- </div>
93
- );
94
- },
95
- decorators: [withTheme, withLayout({ fullscreen: true, classNames: 'justify-center' })],
96
- parameters: {
97
- translations,
98
- },
99
- };
100
-
101
- const videoUrls = [
102
- 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4',
103
- 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerEscapes.mp4',
104
- 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerJoyrides.mp4',
105
- 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerMeltdowns.mp4',
106
- ];
107
-
108
- const createItem = (type?: 'image' | 'video') => {
109
- const id = faker.string.uuid();
110
- return {
111
- id,
112
- type,
113
- name: faker.person.fullName(),
114
- imageUrl: `https://placehold.co/3200x1800/333/999?font=roboto&text=${id.slice(0, 2)}`,
115
- videoUrl: faker.helpers.arrayElement(videoUrls),
116
- };
117
- };
118
-
119
- export default meta;
120
-
121
- type Story = StoryObj<StoryProps>;
122
-
123
- // TODO(burdon): Story to join/leave repeatedly to test stable position.
124
-
125
- export const Default: Story = {
126
- args: {
127
- random: true,
128
- items: Array.from({ length: 8 }, (_, i) => createItem('video')),
129
- },
130
- };
131
-
132
- export const Fullscreen: Story = {
133
- args: {
134
- random: true,
135
- autoHideGallery: true,
136
- items: Array.from({ length: 8 }, (_, i) => createItem('video')),
137
- },
138
- };
139
-
140
- export const Images: Story = {
141
- args: {
142
- debug: true,
143
- items: Array.from({ length: 8 }, (_, i) => createItem('image')),
144
- },
145
- };
146
-
147
- export const Solo: Story = {
148
- args: {
149
- items: Array.from({ length: 1 }, (_, i) => createItem('image')),
150
- },
151
- };
152
-
153
- export const TwoUp: Story = {
154
- args: {
155
- items: Array.from({ length: 2 }, (_, i) => createItem('image')),
156
- },
157
- };
@@ -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/react-ui-theme';
12
-
13
- import { ResponsiveContainer } from './ResponsiveContainer';
14
- import { type ResponsiveGridItemProps } from './ResponsiveGridItem';
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('relative w-full h-full', 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
- <ResponsiveContainer>
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
- </ResponsiveContainer>
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
- };