@arbidocs/blocks 0.5.91 → 0.5.92

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 (238) hide show
  1. package/dist/{ConnectedCallDock-PJE7EZ6T.js → ConnectedCallDock-H5ABOXNR.js} +13 -13
  2. package/dist/{ConnectedCallDock-PJE7EZ6T.js.map → ConnectedCallDock-H5ABOXNR.js.map} +1 -1
  3. package/dist/{ConnectedCallDock-ZRSZYSLO.cjs → ConnectedCallDock-XF56C2JA.cjs} +22 -22
  4. package/dist/{ConnectedCallDock-ZRSZYSLO.cjs.map → ConnectedCallDock-XF56C2JA.cjs.map} +1 -1
  5. package/dist/{ConnectedCallRoom-XK2RPNO6.cjs → ConnectedCallRoom-EEI2ZVTS.cjs} +14 -14
  6. package/dist/{ConnectedCallRoom-XK2RPNO6.cjs.map → ConnectedCallRoom-EEI2ZVTS.cjs.map} +1 -1
  7. package/dist/{ConnectedCallRoom-S7DO2MP6.js → ConnectedCallRoom-N6DUEV4S.js} +13 -13
  8. package/dist/{ConnectedCallRoom-S7DO2MP6.js.map → ConnectedCallRoom-N6DUEV4S.js.map} +1 -1
  9. package/dist/{ConnectedMailInviteCard-YYPLRL6G.js → ConnectedMailInviteCard-2TXUPVV7.js} +4 -4
  10. package/dist/{ConnectedMailInviteCard-YYPLRL6G.js.map → ConnectedMailInviteCard-2TXUPVV7.js.map} +1 -1
  11. package/dist/{ConnectedMailInviteCard-OBDYWUFM.cjs → ConnectedMailInviteCard-RSNELYZX.cjs} +5 -5
  12. package/dist/{ConnectedMailInviteCard-OBDYWUFM.cjs.map → ConnectedMailInviteCard-RSNELYZX.cjs.map} +1 -1
  13. package/dist/{ConnectedNativeDocxComparison-2RIERXLW.js → ConnectedNativeDocxComparison-P6GG3ODF.js} +18 -18
  14. package/dist/ConnectedNativeDocxComparison-P6GG3ODF.js.map +1 -0
  15. package/dist/{ConnectedNativeDocxComparison-46C7LYGT.cjs → ConnectedNativeDocxComparison-QHAV3K7N.cjs} +19 -19
  16. package/dist/ConnectedNativeDocxComparison-QHAV3K7N.cjs.map +1 -0
  17. package/dist/{ConnectedNativeDocxEditor-6XMB2XT7.cjs → ConnectedNativeDocxEditor-6HQD3MHT.cjs} +19 -19
  18. package/dist/ConnectedNativeDocxEditor-6HQD3MHT.cjs.map +1 -0
  19. package/dist/{ConnectedNativeDocxEditor-K6X63CPL.js → ConnectedNativeDocxEditor-CWDRJHXN.js} +17 -17
  20. package/dist/ConnectedNativeDocxEditor-CWDRJHXN.js.map +1 -0
  21. package/dist/{ConnectedProductionSetDialog-JXQLGDIH.js → ConnectedProductionSetDialog-2SM3ZNBF.js} +3 -3
  22. package/dist/{ConnectedProductionSetDialog-JXQLGDIH.js.map → ConnectedProductionSetDialog-2SM3ZNBF.js.map} +1 -1
  23. package/dist/{ConnectedProductionSetDialog-T3Q32XPJ.cjs → ConnectedProductionSetDialog-XNGMUGB6.cjs} +3 -3
  24. package/dist/{ConnectedProductionSetDialog-T3Q32XPJ.cjs.map → ConnectedProductionSetDialog-XNGMUGB6.cjs.map} +1 -1
  25. package/dist/{ConnectedStreamedWordArtifact-6UMLSR3G.js → ConnectedStreamedWordArtifact-4SU4FVZE.js} +18 -18
  26. package/dist/ConnectedStreamedWordArtifact-4SU4FVZE.js.map +1 -0
  27. package/dist/{ConnectedStreamedWordArtifact-GFFLCGF7.cjs → ConnectedStreamedWordArtifact-5V7VRTEY.cjs} +19 -19
  28. package/dist/ConnectedStreamedWordArtifact-5V7VRTEY.cjs.map +1 -0
  29. package/dist/{DocumentReviewCard-SAKLHM4Y.js → DocumentReviewCard-LP33IGEL.js} +18 -18
  30. package/dist/{DocumentReviewCard-SAKLHM4Y.js.map → DocumentReviewCard-LP33IGEL.js.map} +1 -1
  31. package/dist/{DocumentReviewCard-XGYMO5YS.cjs → DocumentReviewCard-QV3CM7YP.cjs} +23 -23
  32. package/dist/{DocumentReviewCard-XGYMO5YS.cjs.map → DocumentReviewCard-QV3CM7YP.cjs.map} +1 -1
  33. package/dist/{FilesViewerDialog-HNBRY7RQ.js → FilesViewerDialog-FZYXO3MS.js} +29 -29
  34. package/dist/{FilesViewerDialog-HNBRY7RQ.js.map → FilesViewerDialog-FZYXO3MS.js.map} +1 -1
  35. package/dist/{FilesViewerDialog-3C6JUMVS.cjs → FilesViewerDialog-JKNA25Q3.cjs} +31 -31
  36. package/dist/{FilesViewerDialog-3C6JUMVS.cjs.map → FilesViewerDialog-JKNA25Q3.cjs.map} +1 -1
  37. package/dist/{WorkspaceTableView-DFN4WGRI.js → WorkspaceTableView-IFXCT6AJ.js} +10 -10
  38. package/dist/{WorkspaceTableView-DFN4WGRI.js.map → WorkspaceTableView-IFXCT6AJ.js.map} +1 -1
  39. package/dist/{WorkspaceTableView-UOP3EB2F.cjs → WorkspaceTableView-PZVCHSOP.cjs} +12 -12
  40. package/dist/{WorkspaceTableView-UOP3EB2F.cjs.map → WorkspaceTableView-PZVCHSOP.cjs.map} +1 -1
  41. package/dist/agents/index.cjs +353 -353
  42. package/dist/agents/index.js +14 -14
  43. package/dist/calendar/index.cjs +116 -116
  44. package/dist/calendar/index.js +1 -1
  45. package/dist/calls/index.cjs +154 -154
  46. package/dist/calls/index.js +13 -13
  47. package/dist/chat/index.cjs +18 -18
  48. package/dist/chat/index.js +2 -2
  49. package/dist/{chunk-B7RAN4DM.js → chunk-26RAAEFP.js} +3 -3
  50. package/dist/{chunk-B7RAN4DM.js.map → chunk-26RAAEFP.js.map} +1 -1
  51. package/dist/{chunk-GUGSUCIK.js → chunk-2A5QNDV2.js} +3 -3
  52. package/dist/{chunk-GUGSUCIK.js.map → chunk-2A5QNDV2.js.map} +1 -1
  53. package/dist/{chunk-WWMVVAA5.js → chunk-2AEWXS4X.js} +8 -8
  54. package/dist/{chunk-WWMVVAA5.js.map → chunk-2AEWXS4X.js.map} +1 -1
  55. package/dist/{chunk-HMS3GRMI.cjs → chunk-2Q7LETQX.cjs} +6 -6
  56. package/dist/{chunk-HMS3GRMI.cjs.map → chunk-2Q7LETQX.cjs.map} +1 -1
  57. package/dist/{chunk-OZS7THEB.js → chunk-2RDH5PVJ.js} +3 -3
  58. package/dist/{chunk-OZS7THEB.js.map → chunk-2RDH5PVJ.js.map} +1 -1
  59. package/dist/{chunk-6XOHTWDR.cjs → chunk-2XTU5H2U.cjs} +69 -69
  60. package/dist/{chunk-6XOHTWDR.cjs.map → chunk-2XTU5H2U.cjs.map} +1 -1
  61. package/dist/{chunk-JIFXHVO4.js → chunk-3BSFHBHY.js} +4 -4
  62. package/dist/{chunk-JIFXHVO4.js.map → chunk-3BSFHBHY.js.map} +1 -1
  63. package/dist/{chunk-SK6BAW7L.js → chunk-46IG4KY7.js} +103 -104
  64. package/dist/chunk-46IG4KY7.js.map +1 -0
  65. package/dist/{chunk-BLAWERIU.cjs → chunk-4P553YX2.cjs} +36 -36
  66. package/dist/{chunk-BLAWERIU.cjs.map → chunk-4P553YX2.cjs.map} +1 -1
  67. package/dist/{chunk-UAF2J7P7.cjs → chunk-5HEMXXHR.cjs} +103 -104
  68. package/dist/chunk-5HEMXXHR.cjs.map +1 -0
  69. package/dist/{chunk-A4MBPDLX.cjs → chunk-5S52732U.cjs} +6 -6
  70. package/dist/{chunk-A4MBPDLX.cjs.map → chunk-5S52732U.cjs.map} +1 -1
  71. package/dist/{chunk-4RFNQRUD.js → chunk-5SUIQS75.js} +16 -16
  72. package/dist/{chunk-4RFNQRUD.js.map → chunk-5SUIQS75.js.map} +1 -1
  73. package/dist/{chunk-Y2FPWPDB.js → chunk-5XB3H2TJ.js} +3 -3
  74. package/dist/{chunk-Y2FPWPDB.js.map → chunk-5XB3H2TJ.js.map} +1 -1
  75. package/dist/{chunk-NZQZ2HFU.cjs → chunk-64KZM3RZ.cjs} +3 -3
  76. package/dist/{chunk-NZQZ2HFU.cjs.map → chunk-64KZM3RZ.cjs.map} +1 -1
  77. package/dist/{chunk-YIJ4MFYM.js → chunk-6U6IY7DB.js} +3 -3
  78. package/dist/{chunk-YIJ4MFYM.js.map → chunk-6U6IY7DB.js.map} +1 -1
  79. package/dist/{chunk-K6UKLIRR.js → chunk-AS3HX7LL.js} +3 -3
  80. package/dist/{chunk-K6UKLIRR.js.map → chunk-AS3HX7LL.js.map} +1 -1
  81. package/dist/{chunk-LBRJA4ZJ.cjs → chunk-AZVKR4JO.cjs} +3 -3
  82. package/dist/{chunk-LBRJA4ZJ.cjs.map → chunk-AZVKR4JO.cjs.map} +1 -1
  83. package/dist/{chunk-RIBQCTBQ.js → chunk-B2NHC2KC.js} +3 -3
  84. package/dist/{chunk-RIBQCTBQ.js.map → chunk-B2NHC2KC.js.map} +1 -1
  85. package/dist/{chunk-IXA534S4.js → chunk-BCYFZIG6.js} +13 -13
  86. package/dist/{chunk-IXA534S4.js.map → chunk-BCYFZIG6.js.map} +1 -1
  87. package/dist/{chunk-VJLW3UPL.cjs → chunk-BDTPWXUW.cjs} +7 -7
  88. package/dist/{chunk-VJLW3UPL.cjs.map → chunk-BDTPWXUW.cjs.map} +1 -1
  89. package/dist/{chunk-EXZPKMMP.js → chunk-BSTVTI5G.js} +14 -14
  90. package/dist/{chunk-EXZPKMMP.js.map → chunk-BSTVTI5G.js.map} +1 -1
  91. package/dist/{chunk-OTODKLR3.cjs → chunk-C5CWKZ5D.cjs} +3 -3
  92. package/dist/{chunk-OTODKLR3.cjs.map → chunk-C5CWKZ5D.cjs.map} +1 -1
  93. package/dist/{chunk-LPGBRMYS.js → chunk-CHQMVIHR.js} +36 -36
  94. package/dist/chunk-CHQMVIHR.js.map +1 -0
  95. package/dist/{chunk-Z6NX57CU.js → chunk-CPOFZYKH.js} +4 -4
  96. package/dist/{chunk-Z6NX57CU.js.map → chunk-CPOFZYKH.js.map} +1 -1
  97. package/dist/{chunk-Q4ORI364.cjs → chunk-DBGN4M4F.cjs} +19 -19
  98. package/dist/{chunk-Q4ORI364.cjs.map → chunk-DBGN4M4F.cjs.map} +1 -1
  99. package/dist/{chunk-3TECBO75.cjs → chunk-DCYVHUSU.cjs} +54 -54
  100. package/dist/{chunk-3TECBO75.cjs.map → chunk-DCYVHUSU.cjs.map} +1 -1
  101. package/dist/{chunk-PZXEXHKB.cjs → chunk-DIE5ENQC.cjs} +28 -28
  102. package/dist/{chunk-PZXEXHKB.cjs.map → chunk-DIE5ENQC.cjs.map} +1 -1
  103. package/dist/{chunk-TVLY7FTU.js → chunk-DW7LSBIW.js} +3 -3
  104. package/dist/{chunk-TVLY7FTU.js.map → chunk-DW7LSBIW.js.map} +1 -1
  105. package/dist/{chunk-RCOJ7JG5.cjs → chunk-EBNY3RTL.cjs} +4 -4
  106. package/dist/{chunk-RCOJ7JG5.cjs.map → chunk-EBNY3RTL.cjs.map} +1 -1
  107. package/dist/{chunk-FEBLYTME.js → chunk-ER36PSS7.js} +5 -5
  108. package/dist/{chunk-FEBLYTME.js.map → chunk-ER36PSS7.js.map} +1 -1
  109. package/dist/{chunk-VIRQYEFL.cjs → chunk-F5T4W2R2.cjs} +140 -140
  110. package/dist/chunk-F5T4W2R2.cjs.map +1 -0
  111. package/dist/{chunk-RQNNHO44.cjs → chunk-GE2O6S44.cjs} +4 -4
  112. package/dist/{chunk-RQNNHO44.cjs.map → chunk-GE2O6S44.cjs.map} +1 -1
  113. package/dist/{chunk-4UMSQ67B.js → chunk-H57PBOFE.js} +3 -3
  114. package/dist/{chunk-4UMSQ67B.js.map → chunk-H57PBOFE.js.map} +1 -1
  115. package/dist/{chunk-7OPOPYV6.cjs → chunk-H5OLHP2U.cjs} +3 -3
  116. package/dist/{chunk-7OPOPYV6.cjs.map → chunk-H5OLHP2U.cjs.map} +1 -1
  117. package/dist/{chunk-VK5Q5JXU.cjs → chunk-HDPT7D6F.cjs} +3 -3
  118. package/dist/{chunk-VK5Q5JXU.cjs.map → chunk-HDPT7D6F.cjs.map} +1 -1
  119. package/dist/{chunk-HU7MB33Q.js → chunk-HLVLPDDD.js} +3 -3
  120. package/dist/{chunk-HU7MB33Q.js.map → chunk-HLVLPDDD.js.map} +1 -1
  121. package/dist/{chunk-CLPDKHSP.cjs → chunk-HYDIQEDT.cjs} +12 -12
  122. package/dist/{chunk-CLPDKHSP.cjs.map → chunk-HYDIQEDT.cjs.map} +1 -1
  123. package/dist/{chunk-HUE76NAI.cjs → chunk-I6SPGHFY.cjs} +2 -2
  124. package/dist/{chunk-HUE76NAI.cjs.map → chunk-I6SPGHFY.cjs.map} +1 -1
  125. package/dist/{chunk-M6XUGXCY.cjs → chunk-IHJ7BEI5.cjs} +741 -741
  126. package/dist/chunk-IHJ7BEI5.cjs.map +1 -0
  127. package/dist/{chunk-WLQAD6ZY.js → chunk-IL6OWGAU.js} +744 -744
  128. package/dist/chunk-IL6OWGAU.js.map +1 -0
  129. package/dist/{chunk-KXRGVY3M.cjs → chunk-ILLWGL7Q.cjs} +4 -4
  130. package/dist/{chunk-KXRGVY3M.cjs.map → chunk-ILLWGL7Q.cjs.map} +1 -1
  131. package/dist/{chunk-WFNEZT7S.cjs → chunk-IOCEKN44.cjs} +4 -4
  132. package/dist/{chunk-WFNEZT7S.cjs.map → chunk-IOCEKN44.cjs.map} +1 -1
  133. package/dist/{chunk-MFEJKCCZ.js → chunk-JGA2JJEL.js} +3 -3
  134. package/dist/{chunk-MFEJKCCZ.js.map → chunk-JGA2JJEL.js.map} +1 -1
  135. package/dist/{chunk-UCQ3VXRB.js → chunk-JM7Z3QNS.js} +5 -5
  136. package/dist/{chunk-UCQ3VXRB.js.map → chunk-JM7Z3QNS.js.map} +1 -1
  137. package/dist/{chunk-3KNKAZ5D.cjs → chunk-K3C4WECV.cjs} +5 -5
  138. package/dist/{chunk-3KNKAZ5D.cjs.map → chunk-K3C4WECV.cjs.map} +1 -1
  139. package/dist/{chunk-DGG35TPO.cjs → chunk-KB2FH26M.cjs} +4 -4
  140. package/dist/{chunk-DGG35TPO.cjs.map → chunk-KB2FH26M.cjs.map} +1 -1
  141. package/dist/{chunk-MB3IQLNN.cjs → chunk-L4USMBHU.cjs} +18 -18
  142. package/dist/chunk-L4USMBHU.cjs.map +1 -0
  143. package/dist/{chunk-XIEX3HO3.js → chunk-L4YGZJYR.js} +3 -3
  144. package/dist/{chunk-XIEX3HO3.js.map → chunk-L4YGZJYR.js.map} +1 -1
  145. package/dist/{chunk-KNC77LZZ.cjs → chunk-LMOLE5PS.cjs} +3 -3
  146. package/dist/{chunk-KNC77LZZ.cjs.map → chunk-LMOLE5PS.cjs.map} +1 -1
  147. package/dist/{chunk-PYLG3M6G.js → chunk-LTRFQ2IC.js} +2 -2
  148. package/dist/{chunk-PYLG3M6G.js.map → chunk-LTRFQ2IC.js.map} +1 -1
  149. package/dist/{chunk-636KUL53.js → chunk-NSJUMOLN.js} +5 -5
  150. package/dist/{chunk-636KUL53.js.map → chunk-NSJUMOLN.js.map} +1 -1
  151. package/dist/{chunk-7SJXYEZI.cjs → chunk-OAIOOVFN.cjs} +36 -36
  152. package/dist/chunk-OAIOOVFN.cjs.map +1 -0
  153. package/dist/{chunk-FKPFKSDT.js → chunk-PA2I7GLY.js} +6 -6
  154. package/dist/{chunk-FKPFKSDT.js.map → chunk-PA2I7GLY.js.map} +1 -1
  155. package/dist/{chunk-4KARJ4CC.js → chunk-PCAWLVHE.js} +3 -3
  156. package/dist/{chunk-4KARJ4CC.js.map → chunk-PCAWLVHE.js.map} +1 -1
  157. package/dist/{chunk-7QDLONHA.js → chunk-PPFTNP6J.js} +11 -11
  158. package/dist/chunk-PPFTNP6J.js.map +1 -0
  159. package/dist/{chunk-2FPBFLOX.cjs → chunk-Q4X5RK4A.cjs} +9 -3
  160. package/dist/chunk-Q4X5RK4A.cjs.map +1 -0
  161. package/dist/{chunk-4VUKYB32.cjs → chunk-Q5TOUT2C.cjs} +4 -4
  162. package/dist/{chunk-4VUKYB32.cjs.map → chunk-Q5TOUT2C.cjs.map} +1 -1
  163. package/dist/{chunk-DU3H4WC6.cjs → chunk-QIEUKIBH.cjs} +4 -4
  164. package/dist/{chunk-DU3H4WC6.cjs.map → chunk-QIEUKIBH.cjs.map} +1 -1
  165. package/dist/{chunk-5YBH5CQD.cjs → chunk-QJNHVQUQ.cjs} +26 -26
  166. package/dist/{chunk-5YBH5CQD.cjs.map → chunk-QJNHVQUQ.cjs.map} +1 -1
  167. package/dist/{chunk-C33VIPE2.js → chunk-QZ6XGYGW.js} +9 -3
  168. package/dist/chunk-QZ6XGYGW.js.map +1 -0
  169. package/dist/{chunk-YRVE6RX5.cjs → chunk-RB6MAAS7.cjs} +4 -4
  170. package/dist/{chunk-YRVE6RX5.cjs.map → chunk-RB6MAAS7.cjs.map} +1 -1
  171. package/dist/{chunk-KPD7WAXP.js → chunk-S6QBLVPP.js} +3 -3
  172. package/dist/{chunk-KPD7WAXP.js.map → chunk-S6QBLVPP.js.map} +1 -1
  173. package/dist/{chunk-TIQZ7CXZ.js → chunk-SOLSDXOZ.js} +83 -83
  174. package/dist/chunk-SOLSDXOZ.js.map +1 -0
  175. package/dist/{chunk-ZZE3ORJS.js → chunk-SOZIHPO2.js} +3 -3
  176. package/dist/{chunk-ZZE3ORJS.js.map → chunk-SOZIHPO2.js.map} +1 -1
  177. package/dist/{chunk-TSP5JJ56.js → chunk-VUXWBUZ7.js} +11 -11
  178. package/dist/{chunk-TSP5JJ56.js.map → chunk-VUXWBUZ7.js.map} +1 -1
  179. package/dist/{chunk-NZ26UYEQ.cjs → chunk-VWX36C4Y.cjs} +67 -67
  180. package/dist/{chunk-NZ26UYEQ.cjs.map → chunk-VWX36C4Y.cjs.map} +1 -1
  181. package/dist/{chunk-YACOI5ZU.cjs → chunk-WA2U4G43.cjs} +62 -62
  182. package/dist/{chunk-YACOI5ZU.cjs.map → chunk-WA2U4G43.cjs.map} +1 -1
  183. package/dist/{chunk-PSJAFPMH.js → chunk-WLWZAS7J.js} +4 -4
  184. package/dist/{chunk-PSJAFPMH.js.map → chunk-WLWZAS7J.js.map} +1 -1
  185. package/dist/{chunk-GNKQVCMW.cjs → chunk-WVEYUH6C.cjs} +6 -6
  186. package/dist/{chunk-GNKQVCMW.cjs.map → chunk-WVEYUH6C.cjs.map} +1 -1
  187. package/dist/{chunk-2F65OOU3.js → chunk-YB2P5Y52.js} +7 -7
  188. package/dist/{chunk-2F65OOU3.js.map → chunk-YB2P5Y52.js.map} +1 -1
  189. package/dist/collaboration/index.cjs +1 -1
  190. package/dist/collaboration/index.js +1 -1
  191. package/dist/connect/docx.cjs +22 -22
  192. package/dist/connect/docx.js +18 -18
  193. package/dist/connect/index.cjs +1176 -1176
  194. package/dist/connect/index.js +87 -87
  195. package/dist/connect/viewer.cjs +28 -28
  196. package/dist/connect/viewer.js +27 -27
  197. package/dist/dashboards/index.cjs +1 -1
  198. package/dist/dashboards/index.js +1 -1
  199. package/dist/embed/index.cjs +42 -42
  200. package/dist/embed/index.js +36 -36
  201. package/dist/facts/index.cjs +44 -44
  202. package/dist/facts/index.js +3 -3
  203. package/dist/files/index.cjs +226 -226
  204. package/dist/files/index.js +5 -5
  205. package/dist/index.cjs +1631 -1631
  206. package/dist/index.js +47 -47
  207. package/dist/settings/index.cjs +153 -153
  208. package/dist/settings/index.js +4 -4
  209. package/dist/shell/Sidebar.d.ts +4 -2
  210. package/dist/shell/index.cjs +89 -89
  211. package/dist/shell/index.js +10 -10
  212. package/dist/shell/use-sidebar-controller.d.ts +3 -3
  213. package/dist/studio/index.cjs +18 -18
  214. package/dist/studio/index.js +15 -15
  215. package/dist/workflow-canvas/index.cjs +66 -66
  216. package/dist/workflow-canvas/index.js +42 -42
  217. package/dist/workspaces/index.cjs +20 -20
  218. package/dist/workspaces/index.js +3 -3
  219. package/node_modules/@arbidocs/coedit/package.json +1 -1
  220. package/package.json +5 -5
  221. package/dist/ConnectedNativeDocxComparison-2RIERXLW.js.map +0 -1
  222. package/dist/ConnectedNativeDocxComparison-46C7LYGT.cjs.map +0 -1
  223. package/dist/ConnectedNativeDocxEditor-6XMB2XT7.cjs.map +0 -1
  224. package/dist/ConnectedNativeDocxEditor-K6X63CPL.js.map +0 -1
  225. package/dist/ConnectedStreamedWordArtifact-6UMLSR3G.js.map +0 -1
  226. package/dist/ConnectedStreamedWordArtifact-GFFLCGF7.cjs.map +0 -1
  227. package/dist/chunk-2FPBFLOX.cjs.map +0 -1
  228. package/dist/chunk-7QDLONHA.js.map +0 -1
  229. package/dist/chunk-7SJXYEZI.cjs.map +0 -1
  230. package/dist/chunk-C33VIPE2.js.map +0 -1
  231. package/dist/chunk-LPGBRMYS.js.map +0 -1
  232. package/dist/chunk-M6XUGXCY.cjs.map +0 -1
  233. package/dist/chunk-MB3IQLNN.cjs.map +0 -1
  234. package/dist/chunk-SK6BAW7L.js.map +0 -1
  235. package/dist/chunk-TIQZ7CXZ.js.map +0 -1
  236. package/dist/chunk-UAF2J7P7.cjs.map +0 -1
  237. package/dist/chunk-VIRQYEFL.cjs.map +0 -1
  238. package/dist/chunk-WLQAD6ZY.js.map +0 -1
@@ -1,17 +1,17 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var chunk7SJXYEZI_cjs = require('./chunk-7SJXYEZI.cjs');
5
- var chunkWFNEZT7S_cjs = require('./chunk-WFNEZT7S.cjs');
6
- var chunkVIRQYEFL_cjs = require('./chunk-VIRQYEFL.cjs');
7
- var chunkUAF2J7P7_cjs = require('./chunk-UAF2J7P7.cjs');
4
+ var chunkOAIOOVFN_cjs = require('./chunk-OAIOOVFN.cjs');
5
+ var chunkIOCEKN44_cjs = require('./chunk-IOCEKN44.cjs');
6
+ var chunkF5T4W2R2_cjs = require('./chunk-F5T4W2R2.cjs');
7
+ var chunk5HEMXXHR_cjs = require('./chunk-5HEMXXHR.cjs');
8
8
  var chunkBFKTZUFT_cjs = require('./chunk-BFKTZUFT.cjs');
9
9
  var chunkWV65MJ43_cjs = require('./chunk-WV65MJ43.cjs');
10
+ var chunkZBP4ZSAJ_cjs = require('./chunk-ZBP4ZSAJ.cjs');
11
+ var chunkMOIZ2R5X_cjs = require('./chunk-MOIZ2R5X.cjs');
10
12
  var chunkZW6FPIFC_cjs = require('./chunk-ZW6FPIFC.cjs');
11
13
  var chunkZT5MIFLC_cjs = require('./chunk-ZT5MIFLC.cjs');
12
- var chunkZBP4ZSAJ_cjs = require('./chunk-ZBP4ZSAJ.cjs');
13
14
  var chunkUIXY4HKM_cjs = require('./chunk-UIXY4HKM.cjs');
14
- var chunkMOIZ2R5X_cjs = require('./chunk-MOIZ2R5X.cjs');
15
15
  var react = require('@arbidocs/react');
16
16
  var react$1 = require('react');
17
17
  var lucideReact = require('lucide-react');
@@ -19,553 +19,207 @@ var ui = require('@arbidocs/react/ui');
19
19
  var jsxRuntime = require('react/jsx-runtime');
20
20
  var browser = require('@arbidocs/sdk/browser');
21
21
 
22
- function ChatCallCard({
23
- callExtId,
24
- senderName,
25
- latest,
26
- name,
27
- time
22
+ function StartCallButton(props) {
23
+ const enabled = react.useCallsEnabled();
24
+ const canHost = react.useCanHostCalls();
25
+ return enabled && (canHost || props.isLive) ? /* @__PURE__ */ jsxRuntime.jsx(EnabledStartCallButton, { ...props }) : null;
26
+ }
27
+ function EnabledStartCallButton({
28
+ onStart,
29
+ isLive = false,
30
+ label = "Start call",
31
+ testId = "start-call-button"
28
32
  }) {
29
- const arbi = react.useArbi();
30
- const { data: call } = react.useCall(latest ? callExtId : null);
31
- const liveNow = react.useCallSession((s) => callExtId in s.liveCalls);
32
- const inThisCall = react.useCallSession((s) => s.active?.callExtId === callExtId);
33
- const inAnotherCall = react.useCallSession((s) => !!s.active && s.active.callExtId !== callExtId);
34
- const [busy, setBusy] = react$1.useState(false);
35
- const live = latest && chunkUAF2J7P7_cjs.isCallLive(call, liveNow);
36
- let summary;
37
- if (live) summary = senderName ? `${senderName} started a call` : "Call in progress";
38
- else if (latest && call?.started_at && call.ended_at) {
39
- const seconds = (Date.parse(call.ended_at) - Date.parse(call.started_at)) / 1e3;
40
- const joined = (call.last_participants ?? []).map(name);
41
- summary = [
42
- "Call",
43
- chunkUAF2J7P7_cjs.formatCallDuration(seconds),
44
- joined.length ? `joined ${joined.join(", ")}` : null
45
- ].filter(Boolean).join(" \xB7 ");
46
- } else summary = senderName ? `Call started by ${senderName}` : "Call";
47
- return /* @__PURE__ */ jsxRuntime.jsxs(
48
- "div",
33
+ const [isStarting, setIsStarting] = react$1.useState(false);
34
+ const inCall = react.useCallSession((s) => s.active !== null);
35
+ const text = inCall ? "Already in a call" : isLive ? "Join call" : label;
36
+ return /* @__PURE__ */ jsxRuntime.jsxs(ui.Tooltip, { children: [
37
+ /* @__PURE__ */ jsxRuntime.jsx(ui.TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
38
+ ui.Button,
39
+ {
40
+ type: "button",
41
+ variant: "ghost",
42
+ size: "icon",
43
+ "aria-label": isLive ? "Join call" : label,
44
+ "data-testid": testId,
45
+ "data-live": isLive || void 0,
46
+ disabled: isStarting || inCall,
47
+ onClick: () => {
48
+ setIsStarting(true);
49
+ void onStart().finally(() => setIsStarting(false));
50
+ },
51
+ className: ui.cn(
52
+ "text-muted-foreground hover:text-foreground",
53
+ isLive && "text-green-text hover:text-green-text"
54
+ ),
55
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Phone, { className: ui.cn("size-5", isLive && "animate-pulse") })
56
+ }
57
+ ) }),
58
+ /* @__PURE__ */ jsxRuntime.jsx(ui.TooltipContent, { children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: text }) })
59
+ ] });
60
+ }
61
+ var INVITE_LINK_HINT = "will get an invitation to create an ARBI account and join";
62
+ var NO_KEY_REASON = "Cannot receive encrypted calls yet";
63
+ var NO_EMAIL_REASON = "No e-mail address to send a link to";
64
+ function contactName(contact) {
65
+ return contact.card?.name?.trim() || [contact.card?.given_name, contact.card?.family_name].filter(Boolean).join(" ") || (contact.user ? ui.getUserDisplayName(contact.user) : "") || contactEmail(contact) || "Contact";
66
+ }
67
+ function contactEmail(contact) {
68
+ return contact.email ?? contact.user?.email ?? contact.card?.emails?.[0]?.email ?? null;
69
+ }
70
+ function callContactOf(contact) {
71
+ if (!contact.external_id || contact.status === "failed") return null;
72
+ if (contact.user && ui.isAgent(contact.user)) return null;
73
+ return {
74
+ contactExtId: contact.external_id,
75
+ user: contact.user ?? null,
76
+ name: contactName(contact),
77
+ email: contactEmail(contact)
78
+ };
79
+ }
80
+ function userCandidate(user, section, status, contactExtId = null) {
81
+ const ringable = status !== "ring" || !!user.encryption_public_key;
82
+ return {
83
+ id: user.external_id,
84
+ name: ui.getUserDisplayName(user) || user.email,
85
+ email: user.email ?? null,
86
+ section,
87
+ status: ringable ? status : "unavailable",
88
+ reason: ringable ? void 0 : NO_KEY_REASON,
89
+ user,
90
+ contactExtId
91
+ };
92
+ }
93
+ function buildCallCandidates(opts) {
94
+ const seen = /* @__PURE__ */ new Set();
95
+ const out = [];
96
+ const add = (c) => {
97
+ if (seen.has(c.id)) return;
98
+ seen.add(c.id);
99
+ out.push(c);
100
+ };
101
+ const people = (users) => users.filter((u) => !ui.isAgent(u) && u.external_id !== opts.me);
102
+ if (opts.scope !== "contacts") {
103
+ for (const u of people(opts.members)) add(userCandidate(u, "members", "ring"));
104
+ return out;
105
+ }
106
+ const contacts = (opts.contacts ?? []).filter((c) => !(c.user && ui.isAgent(c.user)));
107
+ const contactOf = new Map(
108
+ contacts.filter((c) => c.user).map((c) => [c.user.external_id, c.contactExtId])
109
+ );
110
+ for (const u of people(opts.members)) {
111
+ const contactId = contactOf.get(u.external_id) ?? opts.contactIdOf?.(u) ?? null;
112
+ add(userCandidate(u, "members", contactId ? "ring" : "add-contact", contactId));
113
+ }
114
+ for (const c of contacts) {
115
+ if (c.user) {
116
+ if (c.user.external_id === opts.me) continue;
117
+ add(userCandidate(c.user, "contacts", "ring", c.contactExtId));
118
+ continue;
119
+ }
120
+ const status = c.email ? "invite" : "unavailable";
121
+ add({
122
+ id: c.contactExtId,
123
+ name: c.name,
124
+ email: c.email,
125
+ section: "contacts",
126
+ status,
127
+ reason: c.email ? INVITE_LINK_HINT : NO_EMAIL_REASON,
128
+ user: null,
129
+ contactExtId: c.contactExtId
130
+ });
131
+ }
132
+ return out;
133
+ }
134
+ function isPickable(c) {
135
+ return c.status === "ring" || c.status === "invite";
136
+ }
137
+ function matchesQuery(c, query) {
138
+ const q = query.trim().toLowerCase();
139
+ if (!q) return true;
140
+ return c.name.toLowerCase().includes(q) || (c.email ?? "").toLowerCase().includes(q);
141
+ }
142
+ var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
143
+ var COPY = {
144
+ workspace: {
145
+ title: "Call thread members",
146
+ description: "Only members of this thread\u2019s workspace can join. Pick who to ring \u2014 or nobody, and share the call from the thread.",
147
+ action: "Start call"
148
+ },
149
+ chat: {
150
+ title: "Call the group",
151
+ description: "The people you pick are rung.",
152
+ action: "Start call"
153
+ },
154
+ contacts: {
155
+ title: "New call",
156
+ description: "Your contacts with an ARBI account are rung. Others get an invitation to create an account and join.",
157
+ action: "Start call"
158
+ }
159
+ };
160
+ function CandidateRow({
161
+ candidate,
162
+ checked,
163
+ onToggle,
164
+ onAddContact,
165
+ adding
166
+ }) {
167
+ const pickable = isPickable(candidate);
168
+ const hint = candidate.status === "invite" ? candidate.reason : candidate.status === "add-contact" ? "Not in your contacts" : void 0;
169
+ const row = /* @__PURE__ */ jsxRuntime.jsxs(
170
+ "li",
49
171
  {
50
- className: "mx-auto my-2 flex w-fit max-w-full flex-wrap items-center justify-center gap-2 rounded-md border border-border bg-card px-3 py-2 text-xs",
51
- "data-testid": "chat-call-card",
52
- "data-live": live || void 0,
172
+ className: ui.cn(
173
+ "flex items-center gap-3 rounded-md px-2 py-1.5",
174
+ pickable ? "hover:bg-muted" : "opacity-60"
175
+ ),
176
+ "data-testid": `call-picker-row-${candidate.id}`,
177
+ "data-status": candidate.status,
178
+ "aria-disabled": !pickable || void 0,
53
179
  children: [
54
- live ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Phone, { className: "size-4 animate-pulse text-green-text", "aria-hidden": true }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PhoneOff, { className: "size-4 text-muted-foreground", "aria-hidden": true }),
55
- /* @__PURE__ */ jsxRuntime.jsx("span", { "data-testid": "chat-call-card-summary", children: summary }),
56
- time && /* @__PURE__ */ jsxRuntime.jsx("time", { className: "text-muted-foreground", children: time }),
57
- live && /* @__PURE__ */ jsxRuntime.jsx(
180
+ /* @__PURE__ */ jsxRuntime.jsx(
181
+ ui.Checkbox,
182
+ {
183
+ checked,
184
+ disabled: !pickable,
185
+ onCheckedChange: onToggle,
186
+ "aria-label": `Invite ${candidate.name}`,
187
+ "data-testid": `call-picker-check-${candidate.id}`
188
+ }
189
+ ),
190
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "min-w-0 flex-1", children: [
191
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block truncate text-sm", children: candidate.name }),
192
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "block truncate text-xs text-muted-foreground", children: [
193
+ candidate.email,
194
+ hint && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "ml-1 inline-flex items-center gap-1", children: [
195
+ candidate.status === "invite" && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Mail, { className: "size-3", "aria-hidden": true }),
196
+ candidate.email ? `\xB7 ${hint}` : hint
197
+ ] })
198
+ ] })
199
+ ] }),
200
+ candidate.status === "add-contact" && /* @__PURE__ */ jsxRuntime.jsxs(
58
201
  ui.Button,
59
202
  {
60
203
  type: "button",
61
204
  size: "sm",
62
- className: "h-7 bg-green-600 text-white hover:bg-green-700",
63
- disabled: busy || inThisCall || inAnotherCall,
64
- title: inAnotherCall ? "You are already in a call" : void 0,
65
- onClick: () => {
66
- setBusy(true);
67
- void react.openCall(arbi, { callExtId }).finally(() => setBusy(false));
68
- },
69
- "data-testid": "chat-call-card-join",
70
- children: inThisCall ? "In call" : "Join"
205
+ variant: "outline",
206
+ disabled: adding,
207
+ onClick: onAddContact,
208
+ "data-testid": `call-picker-add-${candidate.id}`,
209
+ children: [
210
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.UserPlus, { className: "mr-1 size-3.5" }),
211
+ "Add contact"
212
+ ]
71
213
  }
72
214
  )
73
215
  ]
74
216
  }
75
217
  );
76
- }
77
- function useCallPersonName(identity, fallbackName) {
78
- const arbi = react.useArbi();
79
- const { byId } = react.usePeople();
80
- const me = arbi.isLoggedIn && arbi.user.identity()?.externalId === identity;
81
- const profile = me ? arbi.user.profile() : null;
82
- return react$1.useMemo(() => {
83
- if (profile)
84
- return ui.getUserDisplayName({ given_name: profile.givenName, family_name: profile.familyName });
85
- const user = byId(identity);
86
- if (user) return ui.getUserDisplayName(user);
87
- return (fallbackName || identity).trim().split(/\s+/).join(" ");
88
- }, [profile, byId, identity, fallbackName]);
89
- }
90
- function CallConversationEmpty({ callExtId }) {
91
- const { inCall, transcribing } = chunk7SJXYEZI_cjs.useMyCallStatus(callExtId);
92
- const live = react.useCallSession((s) => !!s.liveCalls[callExtId]) || inCall;
93
- if (!live) {
94
- return /* @__PURE__ */ jsxRuntime.jsx(
95
- chunkZW6FPIFC_cjs.EmptyState,
96
- {
97
- icon: lucideReact.AudioLines,
98
- title: "No transcript",
99
- description: "This call was not transcribed. When a call here is transcribed, what people say appears in this conversation.",
100
- className: "mx-auto my-8 max-w-xl",
101
- testId: "call-conversation-empty"
102
- }
103
- );
104
- }
105
- return /* @__PURE__ */ jsxRuntime.jsx(
106
- chunkZW6FPIFC_cjs.EmptyState,
107
- {
108
- icon: transcribing ? lucideReact.Captions : lucideReact.CaptionsOff,
109
- title: "Call in progress \u2014 the transcript will appear here",
110
- description: transcribing ? "Transcription is on: what people say shows up here as they speak." : "Transcription is off. The host can turn it on with CC in the call.",
111
- className: "mx-auto my-8 max-w-xl",
112
- testId: "call-conversation-empty"
113
- }
114
- );
115
- }
116
- function ProvisionalRow({ identity }) {
117
- const name = useCallPersonName(identity);
118
- return /* @__PURE__ */ jsxRuntime.jsx(
119
- chunkZBP4ZSAJ_cjs.ProvisionalTranscriptLine,
120
- {
121
- speakerId: identity,
122
- speakerName: name,
123
- speaker: /* @__PURE__ */ jsxRuntime.jsx(chunkUAF2J7P7_cjs.CallUserPill, { identity })
124
- }
125
- );
126
- }
127
- function ProvisionalSpeakers({ ids }) {
128
- if (!ids.length) return null;
129
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pb-2", "data-testid": "transcript-provisional-rows", children: ids.map((id) => /* @__PURE__ */ jsxRuntime.jsx(ProvisionalRow, { identity: id }, id)) });
130
- }
131
- var LINE_WAIT_MS = 1e4;
132
- var MIN_SPEECH_MS = 800;
133
- function useProvisionalSpeakers(callExtId, lines) {
134
- const { inCall, transcribing } = chunk7SJXYEZI_cjs.useMyCallStatus(callExtId);
135
- const speaking = chunk7SJXYEZI_cjs.useSpeakingIds();
136
- const pending = react$1.useRef(/* @__PURE__ */ new Map());
137
- const [, tick] = react$1.useState(0);
138
- const active = inCall && transcribing;
139
- const now = Date.now();
140
- if (active) {
141
- for (const id of speaking) {
142
- const p = pending.current.get(id);
143
- if (p) p.lastHeardAt = now;
144
- else pending.current.set(id, { startedAt: now, lastHeardAt: now });
145
- }
146
- } else if (pending.current.size) {
147
- pending.current.clear();
148
- }
149
- const latest = react$1.useMemo(() => {
150
- const m = /* @__PURE__ */ new Map();
151
- for (const l of lines) m.set(l.speakerId, Math.max(m.get(l.speakerId) ?? 0, l.at));
152
- return m;
153
- }, [lines]);
154
- for (const [id, p] of [...pending.current]) {
155
- const arrived = (latest.get(id) ?? 0) >= p.startedAt - 3e3;
156
- const stale = !speaking.includes(id) && now - p.lastHeardAt > LINE_WAIT_MS;
157
- if (arrived && !speaking.includes(id) || stale) pending.current.delete(id);
158
- else if (arrived) p.startedAt = now;
159
- }
160
- const waiting = pending.current.size > 0;
161
- react$1.useEffect(() => {
162
- if (!waiting) return;
163
- const id = setInterval(() => tick((n) => n + 1), 1e3);
164
- return () => clearInterval(id);
165
- }, [waiting]);
166
- return [...pending.current].filter(([, p]) => p.lastHeardAt - p.startedAt >= MIN_SPEECH_MS).map(([id]) => id);
167
- }
168
- var { isTranscriptMessage, parseTranscriptContent } = browser.chats;
169
- function ConnectedCallChatHistory({
170
- chat,
171
- messages,
172
- items,
173
- renderItem,
174
- loadOlder,
175
- memberById,
176
- senderName,
177
- myExtId,
178
- formatTime,
179
- formatDay
180
- }) {
181
- const arbi = react.useArbi();
182
- const [view, setView] = react$1.useState("all");
183
- react$1.useEffect(() => setView("all"), [chat?.external_id]);
184
- const recordingsCallExtId = chat?.call_ext_id ?? null;
185
- const pendingRecording = chunkZT5MIFLC_cjs.usePendingRecording();
186
- react$1.useEffect(() => {
187
- if (pendingRecording && recordingsCallExtId) setView("recordings");
188
- }, [pendingRecording, recordingsCallExtId]);
189
- const latestCallCards = react$1.useMemo(() => {
190
- const latest = /* @__PURE__ */ new Map();
191
- for (const m of messages)
192
- if (m.kind === "call" && m.call_ext_id && !m.deleted) latest.set(m.call_ext_id, m.external_id);
193
- return new Set(latest.values());
194
- }, [messages]);
195
- const hasRecTranscript = react$1.useMemo(
196
- () => react.hasRecordingTranscript(messages, react.chatTranscriptRef),
197
- [messages]
198
- );
199
- const recordingWindows = react.useRecordingWindows(recordingsCallExtId, hasRecTranscript);
200
- const supersededTranscript = react$1.useMemo(
201
- () => react.supersededTranscriptLines(messages, react.chatTranscriptRef, recordingWindows),
202
- [messages, recordingWindows]
203
- );
204
- const transcriptMessages = react$1.useMemo(
205
- () => react.sortTranscriptMessages(
206
- messages.filter((m) => isTranscriptMessage(m) && !m.deleted && !supersededTranscript.has(m))
207
- ),
208
- [messages, supersededTranscript]
209
- );
210
- const hasTranscript = transcriptMessages.length > 0;
211
- const { data: meetingCall } = react.useCall(hasTranscript ? chat?.call_ext_id : null);
212
- const isHost = !!meetingCall?.is_creator;
213
- const [meetingTitle, setMeetingTitle] = react$1.useState(null);
214
- react$1.useEffect(() => {
215
- if (!chat || !isHost && !recordingsCallExtId) return;
216
- let cancelled = false;
217
- arbi.chats.title(chat).then((t) => !cancelled && setMeetingTitle(t)).catch(() => void 0);
218
- return () => {
219
- cancelled = true;
220
- };
221
- }, [arbi, isHost, chat, recordingsCallExtId]);
222
- const transcriptSpeaker = (msg) => {
223
- const parsed = msg.decryptFailed ? null : parseTranscriptContent(msg.content);
224
- return { parsed, speakerId: parsed?.speaker_identity || msg.sender_ext_id || "" };
225
- };
226
- const transcriptExport = react$1.useMemo(
227
- () => transcriptMessages.filter((m) => !m.decryptFailed).map((m) => {
228
- const parsed = parseTranscriptContent(m.content);
229
- const speakerId = parsed?.speaker_identity || m.sender_ext_id || "";
230
- return {
231
- speaker: parsed?.speaker_name || (memberById(speakerId) ? senderName(speakerId) : "") || "Former member",
232
- at: parsed?.started_at ?? m.created_at,
233
- text: parsed?.text ?? m.content ?? ""
234
- };
235
- }),
236
- [transcriptMessages, memberById, senderName]
237
- );
238
- const transcriptLayout = react$1.useMemo(() => {
239
- const shown = view === "transcript" ? transcriptMessages : messages;
240
- const continued = chunkZBP4ZSAJ_cjs.transcriptRuns(
241
- shown,
242
- (m) => isTranscriptMessage(m) && !supersededTranscript.has(m) ? transcriptSpeaker(m).speakerId : null,
243
- (m) => Date.parse(transcriptSpeaker(m).parsed?.started_at ?? m.created_at ?? "") || 0
244
- );
245
- return { continued };
246
- }, [view, messages, transcriptMessages, supersededTranscript]);
247
- const transcriptEntry = (msg) => {
248
- const { parsed, speakerId } = transcriptSpeaker(msg);
249
- return /* @__PURE__ */ jsxRuntime.jsx(
250
- chunkWFNEZT7S_cjs.TranscriptEntry,
251
- {
252
- speakerId,
253
- speakerName: speakerId === myExtId ? "Me" : parsed?.speaker_name || (memberById(speakerId) ? senderName(speakerId) : senderName(msg.sender_ext_id)),
254
- text: parsed?.text ?? msg.content ?? "",
255
- at: parsed?.started_at ?? msg.created_at,
256
- continued: transcriptLayout.continued.has(msg)
257
- },
258
- msg.external_id
259
- );
260
- };
261
- const chatLines = react$1.useMemo(
262
- () => transcriptMessages.map((m) => {
263
- const { parsed, speakerId } = transcriptSpeaker(m);
264
- return { speakerId, at: Date.parse(parsed?.started_at ?? m.created_at ?? "") || 0 };
265
- }),
266
- [transcriptMessages]
267
- );
268
- const provisionalSpeakers = useProvisionalSpeakers(recordingsCallExtId, chatLines);
269
- const filterOptions = [
270
- { value: "all", label: "All" },
271
- { value: "chat", label: "Chat", testId: "chat-filter" },
272
- {
273
- value: "transcript",
274
- label: "Transcript",
275
- count: transcriptMessages.length,
276
- testId: "transcript-filter"
277
- },
278
- ...recordingsCallExtId ? [{ value: "recordings", label: "Recordings", testId: "recordings-filter" }] : []
279
- ];
280
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
281
- messages.length === 0 && recordingsCallExtId && /* @__PURE__ */ jsxRuntime.jsx(CallConversationEmpty, { callExtId: recordingsCallExtId }),
282
- (hasTranscript || recordingsCallExtId) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sticky top-0 z-10 flex justify-center py-1", children: /* @__PURE__ */ jsxRuntime.jsx(
283
- chunkZBP4ZSAJ_cjs.ConversationFilter,
284
- {
285
- value: view,
286
- options: filterOptions,
287
- onChange: setView
288
- }
289
- ) }),
290
- view === "recordings" && recordingsCallExtId && /* @__PURE__ */ jsxRuntime.jsx(chunkVIRQYEFL_cjs.RecordingsList, { callExtId: recordingsCallExtId, title: meetingTitle, className: "py-1" }),
291
- loadOlder,
292
- view === "transcript" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col py-1", "data-testid": "transcript-view", children: [
293
- isHost && /* @__PURE__ */ jsxRuntime.jsx(
294
- chunkVIRQYEFL_cjs.SaveTranscriptToThread,
295
- {
296
- title: meetingTitle,
297
- lines: transcriptExport,
298
- className: "mx-3 mb-2 self-start"
299
- }
300
- ),
301
- transcriptMessages.map((msg) => transcriptEntry(msg)),
302
- /* @__PURE__ */ jsxRuntime.jsx(ProvisionalSpeakers, { ids: provisionalSpeakers })
303
- ] }),
304
- (view === "all" || view === "chat") && items.map((item, i) => {
305
- const { message: msg, isFirstOfDay } = item;
306
- const deleted = !!msg.deleted;
307
- if (deleted && isTranscriptMessage(msg)) return null;
308
- const separator = isFirstOfDay && /* @__PURE__ */ jsxRuntime.jsx(react.DateSeparator, { children: formatDay(msg.created_at) });
309
- if (isTranscriptMessage(msg)) {
310
- if (view === "chat") return null;
311
- const superseded = supersededTranscript.has(msg);
312
- if (superseded && !isFirstOfDay) return null;
313
- return /* @__PURE__ */ jsxRuntime.jsxs(react$1.Fragment, { children: [
314
- separator,
315
- !superseded && transcriptEntry(msg)
316
- ] }, msg.external_id);
317
- }
318
- if (msg.kind === "recording" && msg.call_ext_id && !deleted) {
319
- return /* @__PURE__ */ jsxRuntime.jsxs(react$1.Fragment, { children: [
320
- separator,
321
- /* @__PURE__ */ jsxRuntime.jsx(
322
- chunkVIRQYEFL_cjs.RecordingCard,
323
- {
324
- callExtId: msg.call_ext_id,
325
- recordingExtId: msg.recording_ext_id ?? null,
326
- title: meetingTitle,
327
- time: formatTime(msg.created_at)
328
- }
329
- )
330
- ] }, msg.external_id);
331
- }
332
- if (msg.kind === "call" && msg.call_ext_id && !deleted) {
333
- return /* @__PURE__ */ jsxRuntime.jsxs(react$1.Fragment, { children: [
334
- separator,
335
- /* @__PURE__ */ jsxRuntime.jsx(
336
- ChatCallCard,
337
- {
338
- callExtId: msg.call_ext_id,
339
- senderName: msg.sender_ext_id ? senderName(msg.sender_ext_id) : null,
340
- latest: latestCallCards.has(msg.external_id),
341
- name: senderName,
342
- time: formatTime(msg.created_at)
343
- }
344
- )
345
- ] }, msg.external_id);
346
- }
347
- return renderItem(item, i);
348
- }),
349
- view === "all" && /* @__PURE__ */ jsxRuntime.jsx(ProvisionalSpeakers, { ids: provisionalSpeakers })
350
- ] });
351
- }
352
- function StartCallButton(props) {
353
- const enabled = react.useCallsEnabled();
354
- const canHost = react.useCanHostCalls();
355
- return enabled && (canHost || props.isLive) ? /* @__PURE__ */ jsxRuntime.jsx(EnabledStartCallButton, { ...props }) : null;
356
- }
357
- function EnabledStartCallButton({
358
- onStart,
359
- isLive = false,
360
- label = "Start call",
361
- testId = "start-call-button"
362
- }) {
363
- const [isStarting, setIsStarting] = react$1.useState(false);
364
- const inCall = react.useCallSession((s) => s.active !== null);
365
- const text = inCall ? "Already in a call" : isLive ? "Join call" : label;
366
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Tooltip, { children: [
367
- /* @__PURE__ */ jsxRuntime.jsx(ui.TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
368
- ui.Button,
369
- {
370
- type: "button",
371
- variant: "ghost",
372
- size: "icon",
373
- "aria-label": isLive ? "Join call" : label,
374
- "data-testid": testId,
375
- "data-live": isLive || void 0,
376
- disabled: isStarting || inCall,
377
- onClick: () => {
378
- setIsStarting(true);
379
- void onStart().finally(() => setIsStarting(false));
380
- },
381
- className: ui.cn(
382
- "text-muted-foreground hover:text-foreground",
383
- isLive && "text-green-text hover:text-green-text"
384
- ),
385
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Phone, { className: ui.cn("size-5", isLive && "animate-pulse") })
386
- }
387
- ) }),
388
- /* @__PURE__ */ jsxRuntime.jsx(ui.TooltipContent, { children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: text }) })
389
- ] });
390
- }
391
- function DmCallButton({ peer }) {
392
- const arbi = react.useArbi();
393
- const name = react.userDisplayName(peer);
394
- return /* @__PURE__ */ jsxRuntime.jsx(
395
- StartCallButton,
396
- {
397
- onStart: () => react.startDmCall(arbi, {
398
- external_id: peer.external_id,
399
- encryption_public_key: peer.encryption_public_key ?? null,
400
- name
401
- }),
402
- label: `Call ${name}`,
403
- testId: "dm-call-button"
404
- }
405
- );
406
- }
407
- var INVITE_LINK_HINT = "will get an invitation to create an ARBI account and join";
408
- var NO_KEY_REASON = "Cannot receive encrypted calls yet";
409
- var NO_EMAIL_REASON = "No e-mail address to send a link to";
410
- function contactName(contact) {
411
- return contact.card?.name?.trim() || [contact.card?.given_name, contact.card?.family_name].filter(Boolean).join(" ") || (contact.user ? ui.getUserDisplayName(contact.user) : "") || contactEmail(contact) || "Contact";
412
- }
413
- function contactEmail(contact) {
414
- return contact.email ?? contact.user?.email ?? contact.card?.emails?.[0]?.email ?? null;
415
- }
416
- function callContactOf(contact) {
417
- if (!contact.external_id || contact.status === "failed") return null;
418
- if (contact.user && ui.isAgent(contact.user)) return null;
419
- return {
420
- contactExtId: contact.external_id,
421
- user: contact.user ?? null,
422
- name: contactName(contact),
423
- email: contactEmail(contact)
424
- };
425
- }
426
- function userCandidate(user, section, status, contactExtId = null) {
427
- const ringable = status !== "ring" || !!user.encryption_public_key;
428
- return {
429
- id: user.external_id,
430
- name: ui.getUserDisplayName(user) || user.email,
431
- email: user.email ?? null,
432
- section,
433
- status: ringable ? status : "unavailable",
434
- reason: ringable ? void 0 : NO_KEY_REASON,
435
- user,
436
- contactExtId
437
- };
438
- }
439
- function buildCallCandidates(opts) {
440
- const seen = /* @__PURE__ */ new Set();
441
- const out = [];
442
- const add = (c) => {
443
- if (seen.has(c.id)) return;
444
- seen.add(c.id);
445
- out.push(c);
446
- };
447
- const people = (users) => users.filter((u) => !ui.isAgent(u) && u.external_id !== opts.me);
448
- if (opts.scope !== "contacts") {
449
- for (const u of people(opts.members)) add(userCandidate(u, "members", "ring"));
450
- return out;
451
- }
452
- const contacts = (opts.contacts ?? []).filter((c) => !(c.user && ui.isAgent(c.user)));
453
- const contactOf = new Map(
454
- contacts.filter((c) => c.user).map((c) => [c.user.external_id, c.contactExtId])
455
- );
456
- for (const u of people(opts.members)) {
457
- const contactId = contactOf.get(u.external_id) ?? opts.contactIdOf?.(u) ?? null;
458
- add(userCandidate(u, "members", contactId ? "ring" : "add-contact", contactId));
459
- }
460
- for (const c of contacts) {
461
- if (c.user) {
462
- if (c.user.external_id === opts.me) continue;
463
- add(userCandidate(c.user, "contacts", "ring", c.contactExtId));
464
- continue;
465
- }
466
- const status = c.email ? "invite" : "unavailable";
467
- add({
468
- id: c.contactExtId,
469
- name: c.name,
470
- email: c.email,
471
- section: "contacts",
472
- status,
473
- reason: c.email ? INVITE_LINK_HINT : NO_EMAIL_REASON,
474
- user: null,
475
- contactExtId: c.contactExtId
476
- });
477
- }
478
- return out;
479
- }
480
- function isPickable(c) {
481
- return c.status === "ring" || c.status === "invite";
482
- }
483
- function matchesQuery(c, query) {
484
- const q = query.trim().toLowerCase();
485
- if (!q) return true;
486
- return c.name.toLowerCase().includes(q) || (c.email ?? "").toLowerCase().includes(q);
487
- }
488
- var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
489
- var COPY = {
490
- workspace: {
491
- title: "Call thread members",
492
- description: "Only members of this thread\u2019s workspace can join. Pick who to ring \u2014 or nobody, and share the call from the thread.",
493
- action: "Start call"
494
- },
495
- chat: {
496
- title: "Call the group",
497
- description: "The people you pick are rung.",
498
- action: "Start call"
499
- },
500
- contacts: {
501
- title: "New call",
502
- description: "Your contacts with an ARBI account are rung. Others get an invitation to create an account and join.",
503
- action: "Start call"
504
- }
505
- };
506
- function CandidateRow({
507
- candidate,
508
- checked,
509
- onToggle,
510
- onAddContact,
511
- adding
512
- }) {
513
- const pickable = isPickable(candidate);
514
- const hint = candidate.status === "invite" ? candidate.reason : candidate.status === "add-contact" ? "Not in your contacts" : void 0;
515
- const row = /* @__PURE__ */ jsxRuntime.jsxs(
516
- "li",
517
- {
518
- className: ui.cn(
519
- "flex items-center gap-3 rounded-md px-2 py-1.5",
520
- pickable ? "hover:bg-muted" : "opacity-60"
521
- ),
522
- "data-testid": `call-picker-row-${candidate.id}`,
523
- "data-status": candidate.status,
524
- "aria-disabled": !pickable || void 0,
525
- children: [
526
- /* @__PURE__ */ jsxRuntime.jsx(
527
- ui.Checkbox,
528
- {
529
- checked,
530
- disabled: !pickable,
531
- onCheckedChange: onToggle,
532
- "aria-label": `Invite ${candidate.name}`,
533
- "data-testid": `call-picker-check-${candidate.id}`
534
- }
535
- ),
536
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "min-w-0 flex-1", children: [
537
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block truncate text-sm", children: candidate.name }),
538
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "block truncate text-xs text-muted-foreground", children: [
539
- candidate.email,
540
- hint && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "ml-1 inline-flex items-center gap-1", children: [
541
- candidate.status === "invite" && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Mail, { className: "size-3", "aria-hidden": true }),
542
- candidate.email ? `\xB7 ${hint}` : hint
543
- ] })
544
- ] })
545
- ] }),
546
- candidate.status === "add-contact" && /* @__PURE__ */ jsxRuntime.jsxs(
547
- ui.Button,
548
- {
549
- type: "button",
550
- size: "sm",
551
- variant: "outline",
552
- disabled: adding,
553
- onClick: onAddContact,
554
- "data-testid": `call-picker-add-${candidate.id}`,
555
- children: [
556
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.UserPlus, { className: "mr-1 size-3.5" }),
557
- "Add contact"
558
- ]
559
- }
560
- )
561
- ]
562
- }
563
- );
564
- if (candidate.status !== "unavailable" || !candidate.reason) return row;
565
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Tooltip, { children: [
566
- /* @__PURE__ */ jsxRuntime.jsx(ui.TooltipTrigger, { asChild: true, children: row }),
567
- /* @__PURE__ */ jsxRuntime.jsx(ui.TooltipContent, { children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: candidate.reason }) })
568
- ] });
218
+ if (candidate.status !== "unavailable" || !candidate.reason) return row;
219
+ return /* @__PURE__ */ jsxRuntime.jsxs(ui.Tooltip, { children: [
220
+ /* @__PURE__ */ jsxRuntime.jsx(ui.TooltipTrigger, { asChild: true, children: row }),
221
+ /* @__PURE__ */ jsxRuntime.jsx(ui.TooltipContent, { children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: candidate.reason }) })
222
+ ] });
569
223
  }
570
224
  function InviteLinks({ callExtId }) {
571
225
  const { notify } = chunkUIXY4HKM_cjs.useBlocksEnvironment();
@@ -828,6 +482,48 @@ function CallPeoplePicker({
828
482
  ] })
829
483
  ] }) });
830
484
  }
485
+ function ThreadCallButton({
486
+ conversationId
487
+ }) {
488
+ const arbi = react.useArbi();
489
+ const { data: conversations } = chunkBFKTZUFT_cjs.useConnectedConversations();
490
+ const { workspaceId: workspaceExtId } = chunkWV65MJ43_cjs.useConnectedWorkspace();
491
+ const liveCallId = react.useCallSession((s) => react.threadLiveCallId(s, conversationId));
492
+ const isLive = liveCallId !== null;
493
+ const canHost = react.useCanHostCalls();
494
+ const [picking, setPicking] = react$1.useState(false);
495
+ const conversation = conversations.find((c) => c.external_id === conversationId);
496
+ if (!conversation?.is_shared) return null;
497
+ const title = conversation.title ?? null;
498
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
499
+ /* @__PURE__ */ jsxRuntime.jsx(
500
+ StartCallButton,
501
+ {
502
+ onStart: async () => {
503
+ if (liveCallId && !canHost) return react.openCall(arbi, { callExtId: liveCallId });
504
+ if (isLive) return react.startThreadCall(arbi, { threadExtId: conversationId, title, ring: [] });
505
+ setPicking(true);
506
+ return true;
507
+ },
508
+ isLive,
509
+ label: "Call thread members",
510
+ testId: "thread-call-button"
511
+ }
512
+ ),
513
+ picking && /* @__PURE__ */ jsxRuntime.jsx(
514
+ CallPeoplePicker,
515
+ {
516
+ open: true,
517
+ onOpenChange: setPicking,
518
+ scope: "workspace",
519
+ workspaceExtId,
520
+ onSubmit: async ({ ring }) => {
521
+ await react.startThreadCall(arbi, { threadExtId: conversationId, title, ring });
522
+ }
523
+ }
524
+ )
525
+ ] });
526
+ }
831
527
  function GroupCallButton({
832
528
  chatExtId,
833
529
  title,
@@ -870,6 +566,22 @@ function GroupCallButton({
870
566
  )
871
567
  ] });
872
568
  }
569
+ function DmCallButton({ peer }) {
570
+ const arbi = react.useArbi();
571
+ const name = react.userDisplayName(peer);
572
+ return /* @__PURE__ */ jsxRuntime.jsx(
573
+ StartCallButton,
574
+ {
575
+ onStart: () => react.startDmCall(arbi, {
576
+ external_id: peer.external_id,
577
+ encryption_public_key: peer.encryption_public_key ?? null,
578
+ name
579
+ }),
580
+ label: `Call ${name}`,
581
+ testId: "dm-call-button"
582
+ }
583
+ );
584
+ }
873
585
  function NewCallChip() {
874
586
  return react.useCanHostCalls() ? /* @__PURE__ */ jsxRuntime.jsx(EnabledNewCallChip, {}) : null;
875
587
  }
@@ -878,235 +590,523 @@ function EnabledNewCallChip() {
878
590
  const inCall = react.useCallSession((s) => s.active !== null);
879
591
  const [open, setOpen] = react$1.useState(false);
880
592
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
881
- /* @__PURE__ */ jsxRuntime.jsx(
882
- chunkMOIZ2R5X_cjs.DmInviteChip,
593
+ /* @__PURE__ */ jsxRuntime.jsx(
594
+ chunkMOIZ2R5X_cjs.DmInviteChip,
595
+ {
596
+ testId: "dm-new-call-chip",
597
+ title: "New call",
598
+ description: inCall ? "You are already in a call" : "Call people from your contacts",
599
+ onClick: () => !inCall && setOpen(true)
600
+ }
601
+ ),
602
+ open && /* @__PURE__ */ jsxRuntime.jsx(
603
+ CallPeoplePicker,
604
+ {
605
+ open: true,
606
+ onOpenChange: setOpen,
607
+ scope: "contacts",
608
+ onSubmit: async ({ ring, invites }) => {
609
+ await react.startContactsCall(arbi, {
610
+ title: chunk5HEMXXHR_cjs.contactsCallTitle([
611
+ ...ring.map((u) => ui.getUserDisplayName(u)),
612
+ ...invites.map((g) => g.name)
613
+ ]),
614
+ ring,
615
+ invites
616
+ });
617
+ }
618
+ }
619
+ )
620
+ ] });
621
+ }
622
+ function ScheduleCallButton({
623
+ conversationId,
624
+ peer,
625
+ variant = "icon",
626
+ className
627
+ }) {
628
+ const callsEnabled = react.useCanHostCalls();
629
+ const { conversations } = react.useConversationItems();
630
+ const { data: workspaces = [] } = react.useWorkspaces();
631
+ const { workspaceId: selectedWorkspaceId, userId: me } = chunkWV65MJ43_cjs.useConnectedWorkspace();
632
+ const { openCalendar } = chunkUIXY4HKM_cjs.useBlocksEnvironment();
633
+ if (!callsEnabled) return null;
634
+ const open = () => {
635
+ const conversation = conversationId ? conversations?.find((c) => c.external_id === conversationId) : void 0;
636
+ let people = [];
637
+ if (peer) people = [peer];
638
+ else if (conversation?.is_shared) {
639
+ const workspace = workspaces.find((w) => w.external_id === selectedWorkspaceId);
640
+ people = (workspace?.users ?? []).map((wu) => wu.user);
641
+ }
642
+ chunkUIXY4HKM_cjs.requestCalendarComposer({
643
+ title: peer ? `Call with ${ui.getUserDisplayName(peer) || peer.email}` : conversation?.title ?? "",
644
+ conversationId: conversationId ?? null,
645
+ attendees: people.filter((u) => !ui.isAgent(u) && u.external_id !== me).map((u) => ({
646
+ email: u.email,
647
+ user_id: u.external_id,
648
+ name: ui.getUserDisplayName(u) || null
649
+ })),
650
+ addCall: true
651
+ });
652
+ openCalendar();
653
+ };
654
+ return /* @__PURE__ */ jsxRuntime.jsxs(
655
+ ui.Button,
656
+ {
657
+ type: "button",
658
+ variant: "ghost",
659
+ size: variant === "icon" ? "icon" : "sm",
660
+ className: ui.cn(variant === "icon" && "size-8", className),
661
+ onClick: open,
662
+ "aria-label": "Schedule call",
663
+ title: "Schedule call",
664
+ "data-testid": "schedule-call-button",
665
+ children: [
666
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CalendarPlus, { className: "size-4" }),
667
+ variant === "label" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1.5", children: "Schedule call" })
668
+ ]
669
+ }
670
+ );
671
+ }
672
+ function useMeetingThreadMessages(meetingCallExtId, messageHistory) {
673
+ const hasRecTranscript = react$1.useMemo(
674
+ () => !!meetingCallExtId && react.hasRecordingTranscript(messageHistory, react.threadTranscriptRef),
675
+ [meetingCallExtId, messageHistory]
676
+ );
677
+ const recordingWindows = react.useRecordingWindows(meetingCallExtId, hasRecTranscript);
678
+ return react$1.useMemo(
679
+ () => hasRecTranscript ? react.supersedeLiveTranscript(messageHistory, react.threadTranscriptRef, recordingWindows) : messageHistory,
680
+ [hasRecTranscript, messageHistory, recordingWindows]
681
+ );
682
+ }
683
+ function MeetingThreadTranscriptAction({
684
+ conversationExtId,
685
+ meetingCallExtId,
686
+ title,
687
+ messages
688
+ }) {
689
+ const { data: call } = react.useCall(meetingCallExtId);
690
+ const { data: workspaceUsers = [] } = react.useWorkspaceUsers();
691
+ const lines = react$1.useMemo(
692
+ () => react.threadTranscriptLines(messages, (id) => {
693
+ const user = workspaceUsers.find((wu) => wu.user.external_id === id)?.user;
694
+ return user ? ui.getUserDisplayName(user) : null;
695
+ }),
696
+ [messages, workspaceUsers]
697
+ );
698
+ if (!meetingCallExtId || !call?.is_creator) return null;
699
+ return /* @__PURE__ */ jsxRuntime.jsx(
700
+ chunkF5T4W2R2_cjs.SaveTranscriptToThread,
701
+ {
702
+ title,
703
+ lines,
704
+ excludeConversationExtId: conversationExtId,
705
+ iconOnly: true
706
+ }
707
+ );
708
+ }
709
+ function MeetingThreadRecordingsAction({
710
+ meetingCallExtId,
711
+ title
712
+ }) {
713
+ const [open, setOpen] = react$1.useState(false);
714
+ const pending = chunkZT5MIFLC_cjs.usePendingRecording();
715
+ react$1.useEffect(() => {
716
+ if (pending) setOpen(true);
717
+ }, [pending]);
718
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
719
+ /* @__PURE__ */ jsxRuntime.jsx(
720
+ chunk5HEMXXHR_cjs.HeaderAction,
721
+ {
722
+ label: "Recordings",
723
+ icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Disc, { className: "size-3.5", "aria-hidden": true }),
724
+ iconOnly: true,
725
+ onClick: () => setOpen(true),
726
+ testId: "meeting-recordings"
727
+ }
728
+ ),
729
+ open && /* @__PURE__ */ jsxRuntime.jsx(ui.Dialog, { open: true, onOpenChange: (o) => !o && setOpen(false), children: /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogContent, { className: "sm:max-w-2xl", "data-testid": "meeting-recordings-dialog", children: [
730
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogHeader, { children: [
731
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DialogTitle, { children: "Recordings" }),
732
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DialogDescription, { children: "Recordings of this meeting, encrypted under the workspace key. Playing or downloading one decrypts it in this browser." })
733
+ ] }),
734
+ /* @__PURE__ */ jsxRuntime.jsx(
735
+ chunkF5T4W2R2_cjs.RecordingsList,
736
+ {
737
+ callExtId: meetingCallExtId,
738
+ title,
739
+ className: "max-h-[60vh] overflow-y-auto"
740
+ }
741
+ )
742
+ ] }) })
743
+ ] });
744
+ }
745
+ function ConnectedConversationCallActions() {
746
+ const conversationId = react.useArbiSessionState((state) => state.conversationId);
747
+ const { conversations } = react.useConversationItems();
748
+ const conversation = conversationId ? conversations.find((c) => c.external_id === conversationId) : void 0;
749
+ const meetingCallExtId = conversation?.meeting_call_ext_id ?? null;
750
+ const { messageHistory } = react.useConversationData();
751
+ const threadMessages = useMeetingThreadMessages(meetingCallExtId, messageHistory);
752
+ const meetingMessages = react$1.useMemo(
753
+ () => meetingCallExtId ? threadMessages.map((m) => ({
754
+ content: m.content,
755
+ created_at: m.created_at,
756
+ tools: m.tools ?? m.meta?.tools
757
+ })) : [],
758
+ [meetingCallExtId, threadMessages]
759
+ );
760
+ if (!conversationId) return null;
761
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
762
+ /* @__PURE__ */ jsxRuntime.jsx(ThreadCallButton, { conversationId }),
763
+ /* @__PURE__ */ jsxRuntime.jsx(ScheduleCallButton, { conversationId }),
764
+ meetingCallExtId && /* @__PURE__ */ jsxRuntime.jsx(
765
+ MeetingThreadTranscriptAction,
883
766
  {
884
- testId: "dm-new-call-chip",
885
- title: "New call",
886
- description: inCall ? "You are already in a call" : "Call people from your contacts",
887
- onClick: () => !inCall && setOpen(true)
767
+ conversationExtId: conversationId,
768
+ meetingCallExtId,
769
+ title: conversation?.title,
770
+ messages: meetingMessages
888
771
  }
889
772
  ),
890
- open && /* @__PURE__ */ jsxRuntime.jsx(
891
- CallPeoplePicker,
773
+ meetingCallExtId && /* @__PURE__ */ jsxRuntime.jsx(
774
+ MeetingThreadRecordingsAction,
892
775
  {
893
- open: true,
894
- onOpenChange: setOpen,
895
- scope: "contacts",
896
- onSubmit: async ({ ring, invites }) => {
897
- await react.startContactsCall(arbi, {
898
- title: chunkUAF2J7P7_cjs.contactsCallTitle([
899
- ...ring.map((u) => ui.getUserDisplayName(u)),
900
- ...invites.map((g) => g.name)
901
- ]),
902
- ring,
903
- invites
904
- });
905
- }
776
+ meetingCallExtId,
777
+ title: conversation?.title
906
778
  }
907
779
  )
908
780
  ] });
909
781
  }
910
- function ScheduleCallButton({
911
- conversationId,
912
- peer,
913
- variant = "icon",
914
- className
782
+ function ChatCallCard({
783
+ callExtId,
784
+ senderName,
785
+ latest,
786
+ name,
787
+ time
915
788
  }) {
916
- const callsEnabled = react.useCanHostCalls();
917
- const { conversations } = react.useConversationItems();
918
- const { data: workspaces = [] } = react.useWorkspaces();
919
- const { workspaceId: selectedWorkspaceId, userId: me } = chunkWV65MJ43_cjs.useConnectedWorkspace();
920
- const { openCalendar } = chunkUIXY4HKM_cjs.useBlocksEnvironment();
921
- if (!callsEnabled) return null;
922
- const open = () => {
923
- const conversation = conversationId ? conversations?.find((c) => c.external_id === conversationId) : void 0;
924
- let people = [];
925
- if (peer) people = [peer];
926
- else if (conversation?.is_shared) {
927
- const workspace = workspaces.find((w) => w.external_id === selectedWorkspaceId);
928
- people = (workspace?.users ?? []).map((wu) => wu.user);
929
- }
930
- chunkUIXY4HKM_cjs.requestCalendarComposer({
931
- title: peer ? `Call with ${ui.getUserDisplayName(peer) || peer.email}` : conversation?.title ?? "",
932
- conversationId: conversationId ?? null,
933
- attendees: people.filter((u) => !ui.isAgent(u) && u.external_id !== me).map((u) => ({
934
- email: u.email,
935
- user_id: u.external_id,
936
- name: ui.getUserDisplayName(u) || null
937
- })),
938
- addCall: true
939
- });
940
- openCalendar();
941
- };
789
+ const arbi = react.useArbi();
790
+ const { data: call } = react.useCall(latest ? callExtId : null);
791
+ const liveNow = react.useCallSession((s) => callExtId in s.liveCalls);
792
+ const inThisCall = react.useCallSession((s) => s.active?.callExtId === callExtId);
793
+ const inAnotherCall = react.useCallSession((s) => !!s.active && s.active.callExtId !== callExtId);
794
+ const [busy, setBusy] = react$1.useState(false);
795
+ const live = latest && chunk5HEMXXHR_cjs.isCallLive(call, liveNow);
796
+ let summary;
797
+ if (live) summary = senderName ? `${senderName} started a call` : "Call in progress";
798
+ else if (latest && call?.started_at && call.ended_at) {
799
+ const seconds = (Date.parse(call.ended_at) - Date.parse(call.started_at)) / 1e3;
800
+ const joined = (call.last_participants ?? []).map(name);
801
+ summary = [
802
+ "Call",
803
+ chunk5HEMXXHR_cjs.formatCallDuration(seconds),
804
+ joined.length ? `joined ${joined.join(", ")}` : null
805
+ ].filter(Boolean).join(" \xB7 ");
806
+ } else summary = senderName ? `Call started by ${senderName}` : "Call";
942
807
  return /* @__PURE__ */ jsxRuntime.jsxs(
943
- ui.Button,
808
+ "div",
944
809
  {
945
- type: "button",
946
- variant: "ghost",
947
- size: variant === "icon" ? "icon" : "sm",
948
- className: ui.cn(variant === "icon" && "size-8", className),
949
- onClick: open,
950
- "aria-label": "Schedule call",
951
- title: "Schedule call",
952
- "data-testid": "schedule-call-button",
810
+ className: "mx-auto my-2 flex w-fit max-w-full flex-wrap items-center justify-center gap-2 rounded-md border border-border bg-card px-3 py-2 text-xs",
811
+ "data-testid": "chat-call-card",
812
+ "data-live": live || void 0,
953
813
  children: [
954
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CalendarPlus, { className: "size-4" }),
955
- variant === "label" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1.5", children: "Schedule call" })
814
+ live ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Phone, { className: "size-4 animate-pulse text-green-text", "aria-hidden": true }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PhoneOff, { className: "size-4 text-muted-foreground", "aria-hidden": true }),
815
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-testid": "chat-call-card-summary", children: summary }),
816
+ time && /* @__PURE__ */ jsxRuntime.jsx("time", { className: "text-muted-foreground", children: time }),
817
+ live && /* @__PURE__ */ jsxRuntime.jsx(
818
+ ui.Button,
819
+ {
820
+ type: "button",
821
+ size: "sm",
822
+ className: "h-7 bg-green-600 text-white hover:bg-green-700",
823
+ disabled: busy || inThisCall || inAnotherCall,
824
+ title: inAnotherCall ? "You are already in a call" : void 0,
825
+ onClick: () => {
826
+ setBusy(true);
827
+ void react.openCall(arbi, { callExtId }).finally(() => setBusy(false));
828
+ },
829
+ "data-testid": "chat-call-card-join",
830
+ children: inThisCall ? "In call" : "Join"
831
+ }
832
+ )
956
833
  ]
957
834
  }
958
835
  );
959
836
  }
960
- function useMeetingThreadMessages(meetingCallExtId, messageHistory) {
837
+ function useCallPersonName(identity, fallbackName) {
838
+ const arbi = react.useArbi();
839
+ const { byId } = react.usePeople();
840
+ const me = arbi.isLoggedIn && arbi.user.identity()?.externalId === identity;
841
+ const profile = me ? arbi.user.profile() : null;
842
+ return react$1.useMemo(() => {
843
+ if (profile)
844
+ return ui.getUserDisplayName({ given_name: profile.givenName, family_name: profile.familyName });
845
+ const user = byId(identity);
846
+ if (user) return ui.getUserDisplayName(user);
847
+ return (fallbackName || identity).trim().split(/\s+/).join(" ");
848
+ }, [profile, byId, identity, fallbackName]);
849
+ }
850
+ function CallConversationEmpty({ callExtId }) {
851
+ const { inCall, transcribing } = chunkOAIOOVFN_cjs.useMyCallStatus(callExtId);
852
+ const live = react.useCallSession((s) => !!s.liveCalls[callExtId]) || inCall;
853
+ if (!live) {
854
+ return /* @__PURE__ */ jsxRuntime.jsx(
855
+ chunkZW6FPIFC_cjs.EmptyState,
856
+ {
857
+ icon: lucideReact.AudioLines,
858
+ title: "No transcript",
859
+ description: "This call was not transcribed. When a call here is transcribed, what people say appears in this conversation.",
860
+ className: "mx-auto my-8 max-w-xl",
861
+ testId: "call-conversation-empty"
862
+ }
863
+ );
864
+ }
865
+ return /* @__PURE__ */ jsxRuntime.jsx(
866
+ chunkZW6FPIFC_cjs.EmptyState,
867
+ {
868
+ icon: transcribing ? lucideReact.Captions : lucideReact.CaptionsOff,
869
+ title: "Call in progress \u2014 the transcript will appear here",
870
+ description: transcribing ? "Transcription is on: what people say shows up here as they speak." : "Transcription is off. The host can turn it on with CC in the call.",
871
+ className: "mx-auto my-8 max-w-xl",
872
+ testId: "call-conversation-empty"
873
+ }
874
+ );
875
+ }
876
+ function ProvisionalRow({ identity }) {
877
+ const name = useCallPersonName(identity);
878
+ return /* @__PURE__ */ jsxRuntime.jsx(
879
+ chunkZBP4ZSAJ_cjs.ProvisionalTranscriptLine,
880
+ {
881
+ speakerId: identity,
882
+ speakerName: name,
883
+ speaker: /* @__PURE__ */ jsxRuntime.jsx(chunk5HEMXXHR_cjs.CallUserPill, { identity })
884
+ }
885
+ );
886
+ }
887
+ function ProvisionalSpeakers({ ids }) {
888
+ if (!ids.length) return null;
889
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pb-2", "data-testid": "transcript-provisional-rows", children: ids.map((id) => /* @__PURE__ */ jsxRuntime.jsx(ProvisionalRow, { identity: id }, id)) });
890
+ }
891
+ var LINE_WAIT_MS = 1e4;
892
+ var MIN_SPEECH_MS = 800;
893
+ function useProvisionalSpeakers(callExtId, lines) {
894
+ const { inCall, transcribing } = chunkOAIOOVFN_cjs.useMyCallStatus(callExtId);
895
+ const speaking = chunkOAIOOVFN_cjs.useSpeakingIds();
896
+ const pending = react$1.useRef(/* @__PURE__ */ new Map());
897
+ const [, tick] = react$1.useState(0);
898
+ const active = inCall && transcribing;
899
+ const now = Date.now();
900
+ if (active) {
901
+ for (const id of speaking) {
902
+ const p = pending.current.get(id);
903
+ if (p) p.lastHeardAt = now;
904
+ else pending.current.set(id, { startedAt: now, lastHeardAt: now });
905
+ }
906
+ } else if (pending.current.size) {
907
+ pending.current.clear();
908
+ }
909
+ const latest = react$1.useMemo(() => {
910
+ const m = /* @__PURE__ */ new Map();
911
+ for (const l of lines) m.set(l.speakerId, Math.max(m.get(l.speakerId) ?? 0, l.at));
912
+ return m;
913
+ }, [lines]);
914
+ for (const [id, p] of [...pending.current]) {
915
+ const arrived = (latest.get(id) ?? 0) >= p.startedAt - 3e3;
916
+ const stale = !speaking.includes(id) && now - p.lastHeardAt > LINE_WAIT_MS;
917
+ if (arrived && !speaking.includes(id) || stale) pending.current.delete(id);
918
+ else if (arrived) p.startedAt = now;
919
+ }
920
+ const waiting = pending.current.size > 0;
921
+ react$1.useEffect(() => {
922
+ if (!waiting) return;
923
+ const id = setInterval(() => tick((n) => n + 1), 1e3);
924
+ return () => clearInterval(id);
925
+ }, [waiting]);
926
+ return [...pending.current].filter(([, p]) => p.lastHeardAt - p.startedAt >= MIN_SPEECH_MS).map(([id]) => id);
927
+ }
928
+ var { isTranscriptMessage, parseTranscriptContent } = browser.chats;
929
+ function ConnectedCallChatHistory({
930
+ chat,
931
+ messages,
932
+ items,
933
+ renderItem,
934
+ loadOlder,
935
+ memberById,
936
+ senderName,
937
+ myExtId,
938
+ formatTime,
939
+ formatDay
940
+ }) {
941
+ const arbi = react.useArbi();
942
+ const [view, setView] = react$1.useState("all");
943
+ react$1.useEffect(() => setView("all"), [chat?.external_id]);
944
+ const recordingsCallExtId = chat?.call_ext_id ?? null;
945
+ const pendingRecording = chunkZT5MIFLC_cjs.usePendingRecording();
946
+ react$1.useEffect(() => {
947
+ if (pendingRecording && recordingsCallExtId) setView("recordings");
948
+ }, [pendingRecording, recordingsCallExtId]);
949
+ const latestCallCards = react$1.useMemo(() => {
950
+ const latest = /* @__PURE__ */ new Map();
951
+ for (const m of messages)
952
+ if (m.kind === "call" && m.call_ext_id && !m.deleted) latest.set(m.call_ext_id, m.external_id);
953
+ return new Set(latest.values());
954
+ }, [messages]);
961
955
  const hasRecTranscript = react$1.useMemo(
962
- () => !!meetingCallExtId && react.hasRecordingTranscript(messageHistory, react.threadTranscriptRef),
963
- [meetingCallExtId, messageHistory]
956
+ () => react.hasRecordingTranscript(messages, react.chatTranscriptRef),
957
+ [messages]
964
958
  );
965
- const recordingWindows = react.useRecordingWindows(meetingCallExtId, hasRecTranscript);
966
- return react$1.useMemo(
967
- () => hasRecTranscript ? react.supersedeLiveTranscript(messageHistory, react.threadTranscriptRef, recordingWindows) : messageHistory,
968
- [hasRecTranscript, messageHistory, recordingWindows]
959
+ const recordingWindows = react.useRecordingWindows(recordingsCallExtId, hasRecTranscript);
960
+ const supersededTranscript = react$1.useMemo(
961
+ () => react.supersededTranscriptLines(messages, react.chatTranscriptRef, recordingWindows),
962
+ [messages, recordingWindows]
969
963
  );
970
- }
971
- function ThreadCallButton({
972
- conversationId
973
- }) {
974
- const arbi = react.useArbi();
975
- const { data: conversations } = chunkBFKTZUFT_cjs.useConnectedConversations();
976
- const { workspaceId: workspaceExtId } = chunkWV65MJ43_cjs.useConnectedWorkspace();
977
- const liveCallId = react.useCallSession((s) => react.threadLiveCallId(s, conversationId));
978
- const isLive = liveCallId !== null;
979
- const canHost = react.useCanHostCalls();
980
- const [picking, setPicking] = react$1.useState(false);
981
- const conversation = conversations.find((c) => c.external_id === conversationId);
982
- if (!conversation?.is_shared) return null;
983
- const title = conversation.title ?? null;
984
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
985
- /* @__PURE__ */ jsxRuntime.jsx(
986
- StartCallButton,
987
- {
988
- onStart: async () => {
989
- if (liveCallId && !canHost) return react.openCall(arbi, { callExtId: liveCallId });
990
- if (isLive) return react.startThreadCall(arbi, { threadExtId: conversationId, title, ring: [] });
991
- setPicking(true);
992
- return true;
993
- },
994
- isLive,
995
- label: "Call thread members",
996
- testId: "thread-call-button"
997
- }
964
+ const transcriptMessages = react$1.useMemo(
965
+ () => react.sortTranscriptMessages(
966
+ messages.filter((m) => isTranscriptMessage(m) && !m.deleted && !supersededTranscript.has(m))
998
967
  ),
999
- picking && /* @__PURE__ */ jsxRuntime.jsx(
1000
- CallPeoplePicker,
968
+ [messages, supersededTranscript]
969
+ );
970
+ const hasTranscript = transcriptMessages.length > 0;
971
+ const { data: meetingCall } = react.useCall(hasTranscript ? chat?.call_ext_id : null);
972
+ const isHost = !!meetingCall?.is_creator;
973
+ const [meetingTitle, setMeetingTitle] = react$1.useState(null);
974
+ react$1.useEffect(() => {
975
+ if (!chat || !isHost && !recordingsCallExtId) return;
976
+ let cancelled = false;
977
+ arbi.chats.title(chat).then((t) => !cancelled && setMeetingTitle(t)).catch(() => void 0);
978
+ return () => {
979
+ cancelled = true;
980
+ };
981
+ }, [arbi, isHost, chat, recordingsCallExtId]);
982
+ const transcriptSpeaker = (msg) => {
983
+ const parsed = msg.decryptFailed ? null : parseTranscriptContent(msg.content);
984
+ return { parsed, speakerId: parsed?.speaker_identity || msg.sender_ext_id || "" };
985
+ };
986
+ const transcriptExport = react$1.useMemo(
987
+ () => transcriptMessages.filter((m) => !m.decryptFailed).map((m) => {
988
+ const parsed = parseTranscriptContent(m.content);
989
+ const speakerId = parsed?.speaker_identity || m.sender_ext_id || "";
990
+ return {
991
+ speaker: parsed?.speaker_name || (memberById(speakerId) ? senderName(speakerId) : "") || "Former member",
992
+ at: parsed?.started_at ?? m.created_at,
993
+ text: parsed?.text ?? m.content ?? ""
994
+ };
995
+ }),
996
+ [transcriptMessages, memberById, senderName]
997
+ );
998
+ const transcriptLayout = react$1.useMemo(() => {
999
+ const shown = view === "transcript" ? transcriptMessages : messages;
1000
+ const continued = chunkZBP4ZSAJ_cjs.transcriptRuns(
1001
+ shown,
1002
+ (m) => isTranscriptMessage(m) && !supersededTranscript.has(m) ? transcriptSpeaker(m).speakerId : null,
1003
+ (m) => Date.parse(transcriptSpeaker(m).parsed?.started_at ?? m.created_at ?? "") || 0
1004
+ );
1005
+ return { continued };
1006
+ }, [view, messages, transcriptMessages, supersededTranscript]);
1007
+ const transcriptEntry = (msg) => {
1008
+ const { parsed, speakerId } = transcriptSpeaker(msg);
1009
+ return /* @__PURE__ */ jsxRuntime.jsx(
1010
+ chunkIOCEKN44_cjs.TranscriptEntry,
1001
1011
  {
1002
- open: true,
1003
- onOpenChange: setPicking,
1004
- scope: "workspace",
1005
- workspaceExtId,
1006
- onSubmit: async ({ ring }) => {
1007
- await react.startThreadCall(arbi, { threadExtId: conversationId, title, ring });
1008
- }
1009
- }
1010
- )
1011
- ] });
1012
- }
1013
- function MeetingThreadTranscriptAction({
1014
- conversationExtId,
1015
- meetingCallExtId,
1016
- title,
1017
- messages
1018
- }) {
1019
- const { data: call } = react.useCall(meetingCallExtId);
1020
- const { data: workspaceUsers = [] } = react.useWorkspaceUsers();
1021
- const lines = react$1.useMemo(
1022
- () => react.threadTranscriptLines(messages, (id) => {
1023
- const user = workspaceUsers.find((wu) => wu.user.external_id === id)?.user;
1024
- return user ? ui.getUserDisplayName(user) : null;
1012
+ speakerId,
1013
+ speakerName: speakerId === myExtId ? "Me" : parsed?.speaker_name || (memberById(speakerId) ? senderName(speakerId) : senderName(msg.sender_ext_id)),
1014
+ text: parsed?.text ?? msg.content ?? "",
1015
+ at: parsed?.started_at ?? msg.created_at,
1016
+ continued: transcriptLayout.continued.has(msg)
1017
+ },
1018
+ msg.external_id
1019
+ );
1020
+ };
1021
+ const chatLines = react$1.useMemo(
1022
+ () => transcriptMessages.map((m) => {
1023
+ const { parsed, speakerId } = transcriptSpeaker(m);
1024
+ return { speakerId, at: Date.parse(parsed?.started_at ?? m.created_at ?? "") || 0 };
1025
1025
  }),
1026
- [messages, workspaceUsers]
1026
+ [transcriptMessages]
1027
1027
  );
1028
- if (!meetingCallExtId || !call?.is_creator) return null;
1029
- return /* @__PURE__ */ jsxRuntime.jsx(
1030
- chunkVIRQYEFL_cjs.SaveTranscriptToThread,
1028
+ const provisionalSpeakers = useProvisionalSpeakers(recordingsCallExtId, chatLines);
1029
+ const filterOptions = [
1030
+ { value: "all", label: "All" },
1031
+ { value: "chat", label: "Chat", testId: "chat-filter" },
1031
1032
  {
1032
- title,
1033
- lines,
1034
- excludeConversationExtId: conversationExtId,
1035
- iconOnly: true
1036
- }
1037
- );
1038
- }
1039
- function MeetingThreadRecordingsAction({
1040
- meetingCallExtId,
1041
- title
1042
- }) {
1043
- const [open, setOpen] = react$1.useState(false);
1044
- const pending = chunkZT5MIFLC_cjs.usePendingRecording();
1045
- react$1.useEffect(() => {
1046
- if (pending) setOpen(true);
1047
- }, [pending]);
1033
+ value: "transcript",
1034
+ label: "Transcript",
1035
+ count: transcriptMessages.length,
1036
+ testId: "transcript-filter"
1037
+ },
1038
+ ...recordingsCallExtId ? [{ value: "recordings", label: "Recordings", testId: "recordings-filter" }] : []
1039
+ ];
1048
1040
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1049
- /* @__PURE__ */ jsxRuntime.jsx(
1050
- chunkUAF2J7P7_cjs.HeaderAction,
1041
+ messages.length === 0 && recordingsCallExtId && /* @__PURE__ */ jsxRuntime.jsx(CallConversationEmpty, { callExtId: recordingsCallExtId }),
1042
+ (hasTranscript || recordingsCallExtId) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sticky top-0 z-10 flex justify-center py-1", children: /* @__PURE__ */ jsxRuntime.jsx(
1043
+ chunkZBP4ZSAJ_cjs.ConversationFilter,
1051
1044
  {
1052
- label: "Recordings",
1053
- icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Disc, { className: "size-3.5", "aria-hidden": true }),
1054
- iconOnly: true,
1055
- onClick: () => setOpen(true),
1056
- testId: "meeting-recordings"
1045
+ value: view,
1046
+ options: filterOptions,
1047
+ onChange: setView
1057
1048
  }
1058
- ),
1059
- open && /* @__PURE__ */ jsxRuntime.jsx(ui.Dialog, { open: true, onOpenChange: (o) => !o && setOpen(false), children: /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogContent, { className: "sm:max-w-2xl", "data-testid": "meeting-recordings-dialog", children: [
1060
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogHeader, { children: [
1061
- /* @__PURE__ */ jsxRuntime.jsx(ui.DialogTitle, { children: "Recordings" }),
1062
- /* @__PURE__ */ jsxRuntime.jsx(ui.DialogDescription, { children: "Recordings of this meeting, encrypted under the workspace key. Playing or downloading one decrypts it in this browser." })
1063
- ] }),
1064
- /* @__PURE__ */ jsxRuntime.jsx(
1065
- chunkVIRQYEFL_cjs.RecordingsList,
1049
+ ) }),
1050
+ view === "recordings" && recordingsCallExtId && /* @__PURE__ */ jsxRuntime.jsx(chunkF5T4W2R2_cjs.RecordingsList, { callExtId: recordingsCallExtId, title: meetingTitle, className: "py-1" }),
1051
+ loadOlder,
1052
+ view === "transcript" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col py-1", "data-testid": "transcript-view", children: [
1053
+ isHost && /* @__PURE__ */ jsxRuntime.jsx(
1054
+ chunkF5T4W2R2_cjs.SaveTranscriptToThread,
1066
1055
  {
1067
- callExtId: meetingCallExtId,
1068
- title,
1069
- className: "max-h-[60vh] overflow-y-auto"
1056
+ title: meetingTitle,
1057
+ lines: transcriptExport,
1058
+ className: "mx-3 mb-2 self-start"
1070
1059
  }
1071
- )
1072
- ] }) })
1073
- ] });
1074
- }
1075
- function ConnectedConversationCallActions() {
1076
- const conversationId = react.useArbiSessionState((state) => state.conversationId);
1077
- const { conversations } = react.useConversationItems();
1078
- const conversation = conversationId ? conversations.find((c) => c.external_id === conversationId) : void 0;
1079
- const meetingCallExtId = conversation?.meeting_call_ext_id ?? null;
1080
- const { messageHistory } = react.useConversationData();
1081
- const threadMessages = useMeetingThreadMessages(meetingCallExtId, messageHistory);
1082
- const meetingMessages = react$1.useMemo(
1083
- () => meetingCallExtId ? threadMessages.map((m) => ({
1084
- content: m.content,
1085
- created_at: m.created_at,
1086
- tools: m.tools ?? m.meta?.tools
1087
- })) : [],
1088
- [meetingCallExtId, threadMessages]
1089
- );
1090
- if (!conversationId) return null;
1091
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1092
- /* @__PURE__ */ jsxRuntime.jsx(ThreadCallButton, { conversationId }),
1093
- /* @__PURE__ */ jsxRuntime.jsx(ScheduleCallButton, { conversationId }),
1094
- meetingCallExtId && /* @__PURE__ */ jsxRuntime.jsx(
1095
- MeetingThreadTranscriptAction,
1096
- {
1097
- conversationExtId: conversationId,
1098
- meetingCallExtId,
1099
- title: conversation?.title,
1100
- messages: meetingMessages
1060
+ ),
1061
+ transcriptMessages.map((msg) => transcriptEntry(msg)),
1062
+ /* @__PURE__ */ jsxRuntime.jsx(ProvisionalSpeakers, { ids: provisionalSpeakers })
1063
+ ] }),
1064
+ (view === "all" || view === "chat") && items.map((item, i) => {
1065
+ const { message: msg, isFirstOfDay } = item;
1066
+ const deleted = !!msg.deleted;
1067
+ if (deleted && isTranscriptMessage(msg)) return null;
1068
+ const separator = isFirstOfDay && /* @__PURE__ */ jsxRuntime.jsx(react.DateSeparator, { children: formatDay(msg.created_at) });
1069
+ if (isTranscriptMessage(msg)) {
1070
+ if (view === "chat") return null;
1071
+ const superseded = supersededTranscript.has(msg);
1072
+ if (superseded && !isFirstOfDay) return null;
1073
+ return /* @__PURE__ */ jsxRuntime.jsxs(react$1.Fragment, { children: [
1074
+ separator,
1075
+ !superseded && transcriptEntry(msg)
1076
+ ] }, msg.external_id);
1101
1077
  }
1102
- ),
1103
- meetingCallExtId && /* @__PURE__ */ jsxRuntime.jsx(
1104
- MeetingThreadRecordingsAction,
1105
- {
1106
- meetingCallExtId,
1107
- title: conversation?.title
1078
+ if (msg.kind === "recording" && msg.call_ext_id && !deleted) {
1079
+ return /* @__PURE__ */ jsxRuntime.jsxs(react$1.Fragment, { children: [
1080
+ separator,
1081
+ /* @__PURE__ */ jsxRuntime.jsx(
1082
+ chunkF5T4W2R2_cjs.RecordingCard,
1083
+ {
1084
+ callExtId: msg.call_ext_id,
1085
+ recordingExtId: msg.recording_ext_id ?? null,
1086
+ title: meetingTitle,
1087
+ time: formatTime(msg.created_at)
1088
+ }
1089
+ )
1090
+ ] }, msg.external_id);
1108
1091
  }
1109
- )
1092
+ if (msg.kind === "call" && msg.call_ext_id && !deleted) {
1093
+ return /* @__PURE__ */ jsxRuntime.jsxs(react$1.Fragment, { children: [
1094
+ separator,
1095
+ /* @__PURE__ */ jsxRuntime.jsx(
1096
+ ChatCallCard,
1097
+ {
1098
+ callExtId: msg.call_ext_id,
1099
+ senderName: msg.sender_ext_id ? senderName(msg.sender_ext_id) : null,
1100
+ latest: latestCallCards.has(msg.external_id),
1101
+ name: senderName,
1102
+ time: formatTime(msg.created_at)
1103
+ }
1104
+ )
1105
+ ] }, msg.external_id);
1106
+ }
1107
+ return renderItem(item, i);
1108
+ }),
1109
+ view === "all" && /* @__PURE__ */ jsxRuntime.jsx(ProvisionalSpeakers, { ids: provisionalSpeakers })
1110
1110
  ] });
1111
1111
  }
1112
1112
 
@@ -1131,5 +1131,5 @@ exports.matchesQuery = matchesQuery;
1131
1131
  exports.useCallPersonName = useCallPersonName;
1132
1132
  exports.useMeetingThreadMessages = useMeetingThreadMessages;
1133
1133
  exports.useProvisionalSpeakers = useProvisionalSpeakers;
1134
- //# sourceMappingURL=chunk-M6XUGXCY.cjs.map
1135
- //# sourceMappingURL=chunk-M6XUGXCY.cjs.map
1134
+ //# sourceMappingURL=chunk-IHJ7BEI5.cjs.map
1135
+ //# sourceMappingURL=chunk-IHJ7BEI5.cjs.map